github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/net/proxy/direct/direct.go (about) 1 package direct 2 3 import ( 4 "context" 5 "fmt" 6 "net" 7 8 "github.com/Asutorufa/yuhaiin/pkg/net/dialer" 9 "github.com/Asutorufa/yuhaiin/pkg/net/netapi" 10 "github.com/Asutorufa/yuhaiin/pkg/protos/node/point" 11 "github.com/Asutorufa/yuhaiin/pkg/protos/node/protocol" 12 ) 13 14 type direct struct{ netapi.EmptyDispatch } 15 16 func init() { 17 point.RegisterProtocol(func(p *protocol.Protocol_Direct) point.WrapProxy { 18 return func(netapi.Proxy) (netapi.Proxy, error) { 19 return Default, nil 20 } 21 }) 22 23 point.SetBootstrap(Default) 24 } 25 26 var Default netapi.Proxy = NewDirect() 27 28 func NewDirect() netapi.Proxy { 29 return &direct{} 30 } 31 32 func (d *direct) Conn(ctx context.Context, s netapi.Address) (net.Conn, error) { 33 return netapi.DialHappyEyeballs(ctx, s) 34 } 35 36 func (d *direct) PacketConn(context.Context, netapi.Address) (net.PacketConn, error) { 37 p, err := dialer.ListenPacket("udp", "") 38 if err != nil { 39 return nil, fmt.Errorf("listen packet failed: %w", err) 40 } 41 42 return &PacketConn{p}, nil 43 } 44 45 type PacketConn struct{ net.PacketConn } 46 47 func (p *PacketConn) WriteTo(b []byte, addr net.Addr) (_ int, err error) { 48 udpAddr, ok := addr.(*net.UDPAddr) 49 if !ok { 50 a, err := netapi.ParseSysAddr(addr) 51 if err != nil { 52 return 0, err 53 } 54 55 ur := a.UDPAddr(context.TODO()) 56 if ur.Err != nil { 57 return 0, ur.Err 58 } 59 60 udpAddr = ur.V 61 } 62 63 return p.PacketConn.WriteTo(b, udpAddr) 64 }