diff --git a/internal/net/net.go b/internal/net/net.go index a155f2c..888a2d6 100644 --- a/internal/net/net.go +++ b/internal/net/net.go @@ -28,6 +28,13 @@ var Dialer = &net.Dialer{ }, } +const probeStackTimeout = 2 * time.Second + +var probeStackDialer = &net.Dialer{ + Resolver: Dialer.Resolver, + Timeout: probeStackTimeout, +} + var ( stackOnce atomic.Pointer[sync.Once] ipv4Enabled bool @@ -41,12 +48,12 @@ func init() { } func supportIPv4() bool { - _, err := Dialer.Dial("tcp4", net.JoinHostPort(controldIPv4Test, "80")) + _, err := probeStackDialer.Dial("tcp4", net.JoinHostPort(controldIPv4Test, "80")) return err == nil } func supportIPv6(ctx context.Context) bool { - _, err := Dialer.DialContext(ctx, "tcp6", net.JoinHostPort(controldIPv6Test, "80")) + _, err := probeStackDialer.DialContext(ctx, "tcp6", net.JoinHostPort(controldIPv6Test, "80")) return err == nil } @@ -61,7 +68,7 @@ func supportListenIPv6Local() bool { func probeStack() { b := backoff.NewBackoff("probeStack", func(format string, args ...any) {}, time.Minute) for { - if _, err := Dialer.Dial("udp", bootstrapDNS); err == nil { + if _, err := probeStackDialer.Dial("udp", bootstrapDNS); err == nil { hasNetworkUp = true break } else { diff --git a/internal/net/net_test.go b/internal/net/net_test.go new file mode 100644 index 0000000..d28dbed --- /dev/null +++ b/internal/net/net_test.go @@ -0,0 +1,24 @@ +package net + +import ( + "context" + "testing" + "time" +) + +func TestProbeStackTimeout(t *testing.T) { + done := make(chan struct{}) + started := make(chan struct{}) + go func() { + defer close(done) + close(started) + supportIPv6(context.Background()) + }() + + <-started + select { + case <-time.After(probeStackTimeout + time.Second): + t.Error("probeStack timeout is not enforce") + case <-done: + } +}