mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-20 20:52:33 +02:00
149 lines
3.6 KiB
Go
Executable file
149 lines
3.6 KiB
Go
Executable file
package route
|
|
|
|
// import (
|
|
// "errors"
|
|
// "fmt"
|
|
// "io"
|
|
// "net"
|
|
|
|
// "github.com/yusing/go-proxy/internal/net/types"
|
|
// T "github.com/yusing/go-proxy/internal/proxy/fields"
|
|
// U "github.com/yusing/go-proxy/internal/utils"
|
|
// F "github.com/yusing/go-proxy/internal/utils/functional"
|
|
// )
|
|
|
|
// type (
|
|
// UDPRoute struct {
|
|
// *StreamRoute
|
|
|
|
// connMap UDPConnMap
|
|
|
|
// listeningConn net.PacketConn
|
|
// targetAddr *net.UDPAddr
|
|
// }
|
|
// UDPConn struct {
|
|
// key string
|
|
// src net.Conn
|
|
// dst net.Conn
|
|
// U.BidirectionalPipe
|
|
// }
|
|
// UDPConnMap = F.Map[string, *UDPConn]
|
|
// )
|
|
|
|
// var NewUDPConnMap = F.NewMap[UDPConnMap]
|
|
|
|
// const udpBufferSize = 8192
|
|
|
|
// func NewUDPRoute(base *StreamRoute) *UDPRoute {
|
|
// return &UDPRoute{
|
|
// StreamRoute: base,
|
|
// connMap: NewUDPConnMap(),
|
|
// }
|
|
// }
|
|
|
|
// func (route *UDPRoute) Setup() error {
|
|
// var cfg net.ListenConfig
|
|
// source, err := cfg.ListenPacket(route.task.Context(), string(route.Scheme.ListeningScheme), fmt.Sprintf(":%v", route.Port.ListeningPort))
|
|
// if err != nil {
|
|
// return err
|
|
// }
|
|
// raddr, err := net.ResolveUDPAddr(string(route.Scheme.ProxyScheme), fmt.Sprintf("%s:%v", route.Host, route.Port.ProxyPort))
|
|
// if err != nil {
|
|
// source.Close()
|
|
// return err
|
|
// }
|
|
|
|
// //! this read the allocated listeningPort from original ':0'
|
|
// route.Port.ListeningPort = T.Port(source.LocalAddr().(*net.UDPAddr).Port)
|
|
|
|
// route.listeningConn = source
|
|
// route.targetAddr = raddr
|
|
|
|
// return nil
|
|
// }
|
|
|
|
// func (route *UDPRoute) Accept() (types.StreamConn, error) {
|
|
// in := route.listeningConn
|
|
|
|
// buffer := make([]byte, udpBufferSize)
|
|
// nRead, srcAddr, err := in.ReadFrom(buffer)
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
|
|
// if nRead == 0 {
|
|
// return nil, io.ErrShortBuffer
|
|
// }
|
|
|
|
// key := srcAddr.String()
|
|
// conn, ok := route.connMap.Load(key)
|
|
|
|
// if !ok {
|
|
// srcConn, err := net.Dial(srcAddr.Network(), srcAddr.String())
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
// dstConn, err := net.Dial(route.targetAddr.Network(), route.targetAddr.String())
|
|
// if err != nil {
|
|
// srcConn.Close()
|
|
// return nil, err
|
|
// }
|
|
// conn = &UDPConn{
|
|
// key,
|
|
// srcConn,
|
|
// dstConn,
|
|
// U.NewBidirectionalPipe(route.task.Context(), sourceRWCloser{in, dstConn}, sourceRWCloser{in, srcConn}),
|
|
// }
|
|
// route.connMap.Store(key, conn)
|
|
// }
|
|
|
|
// _, err = conn.dst.Write(buffer[:nRead])
|
|
// return conn, err
|
|
// }
|
|
|
|
// func (route *UDPRoute) Handle(c types.StreamConn) error {
|
|
// switch c := c.(type) {
|
|
// case *UDPConn:
|
|
// err := c.Start()
|
|
// route.connMap.Delete(c.key)
|
|
// c.Close()
|
|
// return err
|
|
// case *net.TCPConn:
|
|
// in := route.listeningConn
|
|
// srcConn, err := net.DialTCP("tcp", nil, c.RemoteAddr().(*net.TCPAddr))
|
|
// if err != nil {
|
|
// return err
|
|
// }
|
|
// err = U.NewBidirectionalPipe(route.task.Context(), sourceRWCloser{in, c}, sourceRWCloser{in, srcConn}).Start()
|
|
// c.Close()
|
|
// return err
|
|
// }
|
|
// return fmt.Errorf("unknown conn type: %T", c)
|
|
// }
|
|
|
|
// func (route *UDPRoute) Close() error {
|
|
// route.connMap.RangeAllParallel(func(k string, v *UDPConn) {
|
|
// v.Close()
|
|
// })
|
|
// route.connMap.Clear()
|
|
// return route.listeningConn.Close()
|
|
// }
|
|
|
|
// // Close implements types.StreamConn
|
|
// func (conn *UDPConn) Close() error {
|
|
// return errors.Join(conn.src.Close(), conn.dst.Close())
|
|
// }
|
|
|
|
// // RemoteAddr implements types.StreamConn
|
|
// func (conn *UDPConn) RemoteAddr() net.Addr {
|
|
// return conn.src.RemoteAddr()
|
|
// }
|
|
|
|
// type sourceRWCloser struct {
|
|
// server net.PacketConn
|
|
// net.Conn
|
|
// }
|
|
|
|
// func (w sourceRWCloser) Write(p []byte) (int, error) {
|
|
// return w.server.WriteTo(p, w.RemoteAddr().(*net.UDPAddr))
|
|
// }
|