github.com/yaling888/clash@v1.53.0/adapter/outbound/direct.go (about)

     1  package outbound
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  	"net/netip"
     7  
     8  	"github.com/yaling888/clash/component/dialer"
     9  	C "github.com/yaling888/clash/constant"
    10  )
    11  
    12  var _ C.ProxyAdapter = (*Direct)(nil)
    13  
    14  type Direct struct {
    15  	*Base
    16  }
    17  
    18  // DialContext implements C.ProxyAdapter
    19  func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.Conn, error) {
    20  	opts = append(opts, dialer.WithDirect())
    21  	c, err := dialer.DialContext(ctx, "tcp", metadata.RemoteAddress(), d.Base.DialOptions(opts...)...)
    22  	if err != nil {
    23  		return nil, err
    24  	}
    25  
    26  	tcpKeepAlive(c)
    27  
    28  	if !metadata.Resolved() && c.RemoteAddr() != nil {
    29  		if h, _, err := net.SplitHostPort(c.RemoteAddr().String()); err == nil {
    30  			metadata.DstIP = netip.MustParseAddr(h)
    31  		}
    32  	}
    33  
    34  	return NewConn(c, d), nil
    35  }
    36  
    37  // ListenPacketContext implements C.ProxyAdapter
    38  func (d *Direct) ListenPacketContext(ctx context.Context, _ *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
    39  	opts = append(opts, dialer.WithDirect())
    40  	pc, err := dialer.ListenPacket(ctx, "udp", "", d.Base.DialOptions(opts...)...)
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  	return NewPacketConn(&directPacketConn{pc}, d), nil
    45  }
    46  
    47  // DisableDnsResolve implements C.DisableDnsResolve
    48  func (d *Direct) DisableDnsResolve() bool {
    49  	return true
    50  }
    51  
    52  type directPacketConn struct {
    53  	net.PacketConn
    54  }
    55  
    56  func NewDirect() *Direct {
    57  	return &Direct{
    58  		Base: &Base{
    59  			name: "DIRECT",
    60  			tp:   C.Direct,
    61  			udp:  true,
    62  		},
    63  	}
    64  }