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 }