github.com/database64128/shadowsocks-go@v1.10.2-0.20240315062903-143a773533f1/service/udp.go (about) 1 package service 2 3 import ( 4 "errors" 5 "fmt" 6 "net" 7 "time" 8 9 "github.com/database64128/shadowsocks-go/conn" 10 "go.uber.org/zap" 11 ) 12 13 const ( 14 // minimumMTU is the minimum allowed MTU. 15 minimumMTU = 1280 16 17 // defaultRelayBatchSize is the default batch size of recvmmsg(2) and sendmmsg(2) calls in relay sessions. 18 // 19 // On an i9-13900K, the average number of messages received in a single recvmmsg(2) call is 20 // around 100 in iperf3 tests. Bumping the msgvec size to greater than 256 does not seem to 21 // yield any performance improvement. 22 // 23 // Note that the mainline iperf3 does not use sendmmsg(2) or io_uring for batch sending at the 24 // time of writing. So this value is still subject to change in the future. 25 defaultRelayBatchSize = 256 26 27 // defaultServerRecvBatchSize is the default batch size of a UDP relay's main receive routine. 28 defaultServerRecvBatchSize = 64 29 30 // defaultSendChannelCapacity is the default capacity of a UDP relay session's uplink send channel. 31 defaultSendChannelCapacity = 1024 32 33 // defaultNatTimeout is the default duration after which an inactive NAT entry is evicted. 34 defaultNatTimeout = 5 * time.Minute 35 ) 36 37 var ErrMTUTooSmall = errors.New("MTU must be at least 1280") 38 39 // UDPPerfConfig exposes performance tuning parameters for UDP relays. 40 type UDPPerfConfig struct { 41 // BatchMode controls the mode of batch receiving and sending. 42 // 43 // Available values: 44 // - "": Platform default. 45 // - "no": Do not receive or send packets in batches. 46 // - "sendmmsg": Use recvmmsg(2) and sendmmsg(2) calls. This is the default on Linux and NetBSD. 47 BatchMode string `json:"batchMode"` 48 49 // RelayBatchSize is the batch size of recvmmsg(2) and sendmmsg(2) calls in relay sessions. 50 // 51 // The default value is 256. 52 RelayBatchSize int `json:"relayBatchSize"` 53 54 // ServerRecvBatchSize is the batch size of a UDP relay's main receive routine. 55 // 56 // The default value is 64. 57 ServerRecvBatchSize int `json:"serverRecvBatchSize"` 58 59 // SendChannelCapacity is the capacity of a UDP relay session's uplink send channel. 60 // 61 // The default value is 1024. 62 SendChannelCapacity int `json:"sendChannelCapacity"` 63 } 64 65 // CheckAndApplyDefaults checks the validity of the configuration and applies default values. 66 func (c *UDPPerfConfig) CheckAndApplyDefaults() error { 67 switch c.BatchMode { 68 case "", "no", "sendmmsg": 69 default: 70 return fmt.Errorf("unknown batch mode: %s", c.BatchMode) 71 } 72 73 switch { 74 case c.RelayBatchSize > 0 && c.RelayBatchSize <= 1024: 75 case c.RelayBatchSize == 0: 76 c.RelayBatchSize = defaultRelayBatchSize 77 default: 78 return fmt.Errorf("relay batch size out of range [0, 1024]: %d", c.RelayBatchSize) 79 } 80 81 switch { 82 case c.ServerRecvBatchSize > 0 && c.ServerRecvBatchSize <= 1024: 83 case c.ServerRecvBatchSize == 0: 84 c.ServerRecvBatchSize = defaultServerRecvBatchSize 85 default: 86 return fmt.Errorf("server recv batch size out of range [0, 1024]: %d", c.ServerRecvBatchSize) 87 } 88 89 switch { 90 case c.SendChannelCapacity >= 64: 91 case c.SendChannelCapacity == 0: 92 c.SendChannelCapacity = defaultSendChannelCapacity 93 default: 94 return fmt.Errorf("send channel capacity must be at least 64: %d", c.SendChannelCapacity) 95 } 96 97 return nil 98 } 99 100 // udpRelayServerConn configures the server socket for a UDP relay. 101 type udpRelayServerConn struct { 102 logger *zap.Logger 103 serverConn *net.UDPConn 104 listenConfig conn.ListenConfig 105 network string 106 address string 107 batchMode string 108 relayBatchSize int 109 serverRecvBatchSize int 110 sendChannelCapacity int 111 natTimeout time.Duration 112 }