diff --git a/config_quic.go b/config_quic.go index 3f397cb..5103231 100644 --- a/config_quic.go +++ b/config_quic.go @@ -10,13 +10,10 @@ import ( "net/http" "runtime" "sync" - "time" "github.com/miekg/dns" "github.com/quic-go/quic-go" "github.com/quic-go/quic-go/http3" - - ctrldnet "github.com/Control-D-Inc/ctrld/internal/net" ) func (uc *UpstreamConfig) setupDOH3Transport() { @@ -29,9 +26,7 @@ func (uc *UpstreamConfig) setupDOH3Transport() { uc.http3RoundTripper = uc.newDOH3Transport(uc.bootstrapIPs6) case IpStackSplit: uc.http3RoundTripper4 = uc.newDOH3Transport(uc.bootstrapIPs4) - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) - defer cancel() - if ctrldnet.IPv6Available(ctx) { + if hasIPv6() { uc.http3RoundTripper6 = uc.newDOH3Transport(uc.bootstrapIPs6) } else { uc.http3RoundTripper6 = uc.http3RoundTripper4 diff --git a/net.go b/net.go index 110d67e..3ae3bb5 100644 --- a/net.go +++ b/net.go @@ -2,13 +2,10 @@ package ctrld import ( "context" - "errors" "sync" "sync/atomic" "time" - "tailscale.com/logtail/backoff" - ctrldnet "github.com/Control-D-Inc/ctrld/internal/net" ) @@ -17,30 +14,36 @@ var ( ipv6Available atomic.Bool ) +const ipv6ProbingInterval = 10 * time.Second + func hasIPv6() bool { hasIPv6Once.Do(func() { ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() val := ctrldnet.IPv6Available(ctx) ipv6Available.Store(val) - go probingIPv6(val) + go probingIPv6(context.TODO(), val) }) return ipv6Available.Load() } // TODO(cuonglm): doing poll check natively for supported platforms. -func probingIPv6(old bool) { - b := backoff.NewBackoff("probingIPv6", func(format string, args ...any) {}, 30*time.Second) - bCtx := context.Background() +func probingIPv6(ctx context.Context, old bool) { + ticker := time.NewTicker(ipv6ProbingInterval) + defer ticker.Stop() for { - func() { - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) - defer cancel() - cur := ctrldnet.IPv6Available(ctx) - if ipv6Available.CompareAndSwap(old, cur) { - old = cur - } - }() - b.BackOff(bCtx, errors.New("no change")) + select { + case <-ctx.Done(): + return + case <-ticker.C: + func() { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + cur := ctrldnet.IPv6Available(ctx) + if ipv6Available.CompareAndSwap(old, cur) { + old = cur + } + }() + } } }