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  }