Skip to content

Commit 0dabbce

Browse files
committed
tun: race connections
1 parent bca5b26 commit 0dabbce

1 file changed

Lines changed: 38 additions & 0 deletions

File tree

tun.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,21 @@ func DefaultTunSettings() *TunSettings {
4545
ChannelSize: 64,
4646
ProxySequenceSize: 64,
4747
Mtu: 1440,
48+
49+
DialRace: 4,
50+
DialRaceTimeout: 2 * time.Second,
51+
DialTimeout: 15 * time.Second,
4852
}
4953
}
5054

5155
type TunSettings struct {
5256
ChannelSize int
5357
ProxySequenceSize int
5458
Mtu int
59+
60+
DialRace int
61+
DialRaceTimeout time.Duration
62+
DialTimeout time.Duration
5563
}
5664

5765
var tunStack = sync.OnceValue(func() *stack.Stack {
@@ -274,7 +282,37 @@ func (self *Tun) ListenUDP(laddr *net.UDPAddr) (*gonet.UDPConn, error) {
274282

275283
// safe to call from multiple goroutines
276284
func (self *Tun) DialContext(ctx context.Context, network string, address string) (net.Conn, error) {
285+
raceCtx, raceCancel := context.WithCancel(ctx)
286+
defer raceCancel()
287+
raceOut := make(chan net.Conn)
288+
for range self.settings.DialRace {
289+
go connect.HandleError(func() {
290+
conn, err := self.dialContext(raceCtx, network, address)
291+
if err == nil {
292+
select {
293+
case <-raceCtx.Done():
294+
case raceOut <- conn:
295+
}
296+
}
297+
})
298+
select {
299+
case conn := <-raceOut:
300+
return conn, nil
301+
case <-time.After(self.settings.DialRaceTimeout):
302+
}
303+
}
304+
select {
305+
case <-raceCtx.Done():
306+
return nil, fmt.Errorf("Done.")
307+
case conn := <-raceOut:
308+
return conn, nil
309+
case <-time.After(self.settings.DialTimeout - self.settings.DialRaceTimeout):
310+
return nil, fmt.Errorf("Timeout.")
311+
}
312+
}
277313

314+
// safe to call from multiple goroutines
315+
func (self *Tun) dialContext(ctx context.Context, network string, address string) (net.Conn, error) {
278316
dialCtx := self.dialCtx(ctx)
279317

280318
host, portStr, err := net.SplitHostPort(address)

0 commit comments

Comments
 (0)