@@ -70,24 +70,28 @@ type Client struct {
7070 mtuAddedServerLogFormat string
7171 mtuOutputMu sync.Mutex
7272
73- exchangeQueryFn func (Connection , []byte , time.Duration ) ([]byte , error )
74- sendOneWayPacketFn func (Connection , []byte , time.Time ) error
75- fragmentLimits sync.Map
76- stream0Runtime * stream0Runtime
77- streamsMu sync.RWMutex
78- streams map [uint16 ]* clientStream
79- mtuTestRetries int
80- mtuTestTimeout time.Duration
81- streamTXWindow int
82- streamTXQueueLimit int
83- streamTXMaxRetries int
84- streamTXTTL time.Duration
85- resolverHealthMu sync.Mutex
86- resolverHealth map [string ]* resolverHealthState
87- resolverRecheck map [string ]resolverRecheckState
88- runtimeDisabled map [string ]resolverDisabledState
89- healthRuntimeRun bool
90- recheckConnectionFn func (* Connection ) bool
73+ exchangeQueryFn func (Connection , []byte , time.Duration ) ([]byte , error )
74+ sendOneWayPacketFn func (Connection , []byte , time.Time ) error
75+ fragmentLimits sync.Map
76+ stream0Runtime * stream0Runtime
77+ streamsMu sync.RWMutex
78+ streams map [uint16 ]* clientStream
79+ mtuTestRetries int
80+ mtuTestTimeout time.Duration
81+ packetDuplicationCount int
82+ setupPacketDuplicationCount int
83+ streamResolverFailoverResendThreshold int
84+ streamResolverFailoverCooldown time.Duration
85+ streamTXWindow int
86+ streamTXQueueLimit int
87+ streamTXMaxRetries int
88+ streamTXTTL time.Duration
89+ resolverHealthMu sync.Mutex
90+ resolverHealth map [string ]* resolverHealthState
91+ resolverRecheck map [string ]resolverRecheckState
92+ runtimeDisabled map [string ]resolverDisabledState
93+ healthRuntimeRun bool
94+ recheckConnectionFn func (* Connection ) bool
9195
9296 reconnectSignal chan struct {}
9397 reconnectPending atomic.Bool
@@ -113,27 +117,30 @@ type Connection struct {
113117}
114118
115119type clientStream struct {
116- mu sync.Mutex
117- ID uint16
118- Conn net.Conn
119- NextSequence uint16
120- LocalFinSent bool
121- RemoteFinRecv bool
122- ResetSent bool
123- Closed bool
124- LastActivityAt time.Time
125- InboundDataSeq uint16
126- InboundDataSet bool
127- RemoteFinSeq uint16
128- RemoteFinSet bool
129- TXQueue []clientStreamTXPacket
130- TXInFlight []clientStreamTXPacket
131- TXWake chan struct {}
132- StopCh chan struct {}
133- stopOnce sync.Once
134- retryBase time.Duration
135- srtt time.Duration
136- rttVar time.Duration
120+ mu sync.Mutex
121+ ID uint16
122+ Conn net.Conn
123+ NextSequence uint16
124+ LocalFinSent bool
125+ RemoteFinRecv bool
126+ ResetSent bool
127+ Closed bool
128+ LastActivityAt time.Time
129+ InboundDataSeq uint16
130+ InboundDataSet bool
131+ RemoteFinSeq uint16
132+ RemoteFinSet bool
133+ PreferredServerKey string
134+ ResolverResendStreak int
135+ LastResolverFailover time.Time
136+ TXQueue []clientStreamTXPacket
137+ TXInFlight []clientStreamTXPacket
138+ TXWake chan struct {}
139+ StopCh chan struct {}
140+ stopOnce sync.Once
141+ retryBase time.Duration
142+ srtt time.Duration
143+ rttVar time.Duration
137144}
138145
139146type clientStreamTXPacket struct {
@@ -185,13 +192,17 @@ func New(cfg config.ClientConfig, log *logger.Logger, codec *security.Codec) *Cl
185192 localDNSCacheFlushTick : time .Duration (
186193 cfg .LocalDNSCacheFlushSec * float64 (time .Second ),
187194 ),
188- localDNSFragTTL : time .Duration (cfg .LocalDNSFragmentTimeoutSec * float64 (time .Second )),
189- streams : make (map [uint16 ]* clientStream , 16 ),
190- mtuTestRetries : cfg .MTUTestRetries ,
191- mtuTestTimeout : time .Duration (cfg .MTUTestTimeout * float64 (time .Second )),
192- mtuCryptoOverhead : mtuCryptoOverhead (cfg .DataEncryptionMethod ),
193- mtuSaveToFile : cfg .SaveMTUServersToFile ,
194- mtuServersFileName : strings .TrimSpace (cfg .MTUServersFileName ),
195+ localDNSFragTTL : time .Duration (cfg .LocalDNSFragmentTimeoutSec * float64 (time .Second )),
196+ streams : make (map [uint16 ]* clientStream , 16 ),
197+ mtuTestRetries : cfg .MTUTestRetries ,
198+ mtuTestTimeout : time .Duration (cfg .MTUTestTimeout * float64 (time .Second )),
199+ packetDuplicationCount : cfg .PacketDuplicationCount ,
200+ setupPacketDuplicationCount : cfg .SetupPacketDuplicationCount ,
201+ streamResolverFailoverResendThreshold : cfg .StreamResolverFailoverResendThreshold ,
202+ streamResolverFailoverCooldown : time .Duration (cfg .StreamResolverFailoverCooldownSec * float64 (time .Second )),
203+ mtuCryptoOverhead : mtuCryptoOverhead (cfg .DataEncryptionMethod ),
204+ mtuSaveToFile : cfg .SaveMTUServersToFile ,
205+ mtuServersFileName : strings .TrimSpace (cfg .MTUServersFileName ),
195206 mtuServersFileFormat : strings .TrimSpace (
196207 cfg .MTUServersFileFormat ,
197208 ),
@@ -229,6 +240,18 @@ func New(cfg config.ClientConfig, log *logger.Logger, codec *security.Codec) *Cl
229240 if c .mtuTestTimeout <= 0 {
230241 c .mtuTestTimeout = time .Second
231242 }
243+ if c .packetDuplicationCount < 1 {
244+ c .packetDuplicationCount = 1
245+ }
246+ if c .setupPacketDuplicationCount < c .packetDuplicationCount {
247+ c .setupPacketDuplicationCount = c .packetDuplicationCount
248+ }
249+ if c .streamResolverFailoverResendThreshold < 1 {
250+ c .streamResolverFailoverResendThreshold = 1
251+ }
252+ if c .streamResolverFailoverCooldown <= 0 {
253+ c .streamResolverFailoverCooldown = time .Second
254+ }
232255
233256 c .ResetRuntimeState (true )
234257 c .uploadCompression = uint8 (cfg .UploadCompressionType )
0 commit comments