github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/net/dialer/dialer.go (about)

     1  package dialer
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  	"syscall"
     7  )
     8  
     9  // UDP socket read/write buffer size (7MB). The value of 7MB is chosen as it is
    10  // the max supported by a default configuration of macOS. Some platforms will
    11  // silently clamp the value to other maximums, such as linux clamping to
    12  // net.core.{r,w}mem_max (see _linux.go for additional implementation that works
    13  // around this limitation)
    14  const SocketBufferSize = 7 << 20
    15  
    16  func ListenContext(ctx context.Context, network string, address string) (net.Listener, error) {
    17  	return ListenContextWithOptions(ctx, network, address, &Options{
    18  		InterfaceName:  DefaultInterfaceName,
    19  		InterfaceIndex: DefaultInterfaceIndex,
    20  		MarkSymbol:     DefaultMarkSymbol,
    21  	})
    22  }
    23  
    24  func ListenContextWithOptions(ctx context.Context, network string, address string, opts *Options) (net.Listener, error) {
    25  	opts.listener = true
    26  
    27  	config := &net.ListenConfig{
    28  		Control: func(network, address string, c syscall.RawConn) error {
    29  			return setSocketOptions(network, address, c, opts)
    30  		},
    31  	}
    32  	config.SetMultipathTCP(true)
    33  	return config.Listen(ctx, network, address)
    34  }
    35  
    36  func DialContext(ctx context.Context, network, address string) (net.Conn, error) {
    37  	return DialContextWithOptions(ctx, network, address, &Options{
    38  		InterfaceName:  DefaultInterfaceName,
    39  		InterfaceIndex: DefaultInterfaceIndex,
    40  		MarkSymbol:     DefaultMarkSymbol,
    41  	})
    42  }
    43  
    44  func DialContextWithOptions(ctx context.Context, network, address string, opts *Options) (net.Conn, error) {
    45  	d := &net.Dialer{
    46  		// Setting a negative value here prevents the Go stdlib from overriding
    47  		// the values of TCP keepalive time and interval. It also prevents the
    48  		// Go stdlib from enabling TCP keepalives by default.
    49  		KeepAlive: -1,
    50  		// This method is called after the underlying network socket is created,
    51  		// but before dialing the socket (or calling its connect() method). The
    52  		// combination of unconditionally enabling TCP keepalives here, and
    53  		// disabling the overriding of TCP keepalive parameters by setting the
    54  		// KeepAlive field to a negative value above, results in OS defaults for
    55  		// the TCP keealive interval and time parameters.
    56  		Control: func(network, address string, c syscall.RawConn) error {
    57  			return setSocketOptions(network, address, c, opts)
    58  		},
    59  	}
    60  	d.SetMultipathTCP(true)
    61  	return d.DialContext(ctx, network, address)
    62  }
    63  
    64  func ListenPacket(network, address string) (net.PacketConn, error) {
    65  	return ListenPacketWithOptions(network, address, &Options{
    66  		InterfaceName:  DefaultInterfaceName,
    67  		InterfaceIndex: DefaultInterfaceIndex,
    68  		MarkSymbol:     DefaultMarkSymbol,
    69  		listener:       true,
    70  	})
    71  }
    72  
    73  func ListenPacketWithOptions(network, address string, opts *Options) (net.PacketConn, error) {
    74  	lc := &net.ListenConfig{
    75  		// Setting a negative value here prevents the Go stdlib from overriding
    76  		// the values of TCP keepalive time and interval. It also prevents the
    77  		// Go stdlib from enabling TCP keepalives by default.
    78  		KeepAlive: -1,
    79  		// This method is called after the underlying network socket is created,
    80  		// but before dialing the socket (or calling its connect() method). The
    81  		// combination of unconditionally enabling TCP keepalives here, and
    82  		// disabling the overriding of TCP keepalive parameters by setting the
    83  		// KeepAlive field to a negative value above, results in OS defaults for
    84  		// the TCP keealive interval and time parameters.
    85  		Control: func(network, address string, c syscall.RawConn) error {
    86  			return setSocketOptions(network, address, c, opts)
    87  		},
    88  	}
    89  	lc.SetMultipathTCP(true)
    90  	return lc.ListenPacket(context.Background(), network, address)
    91  }
    92  
    93  var (
    94  	DefaultInterfaceName  = ""
    95  	DefaultInterfaceIndex = 0
    96  	DefaultRoutingMark    = 0 // maybe need root permission
    97  	DefaultMarkSymbol     func(socket int32) bool
    98  )
    99  
   100  type Options struct {
   101  	// InterfaceName is the name of interface/device to bind.
   102  	// If a socket is bound to an interface, only packets received
   103  	// from that particular interface are processed by the socket.
   104  	InterfaceName string
   105  
   106  	// InterfaceIndex is the index of interface/device to bind.
   107  	// It is almost the same as InterfaceName except it uses the
   108  	// index of the interface instead of the name.
   109  	InterfaceIndex int
   110  
   111  	// RoutingMark is the mark for each packet sent through this
   112  	// socket. Changing the mark can be used for mark-based routing
   113  	// without netfilter or for packet filtering.
   114  	MarkSymbol func(socket int32) bool
   115  
   116  	listener bool
   117  }
   118  
   119  func isTCPSocket(network string) bool {
   120  	switch network {
   121  	case "tcp", "tcp4", "tcp6":
   122  		return true
   123  	default:
   124  		return false
   125  	}
   126  }
   127  
   128  func isUDPSocket(network string) bool {
   129  	switch network {
   130  	case "udp", "udp4", "udp6":
   131  		return true
   132  	default:
   133  		return false
   134  	}
   135  }