mirror of
https://github.com/tailscale/tailscale.git
synced 2026-09-22 19:45:15 -04:00
Historically, when DERP regions were switched away from strings to numeric identifiers in PR #14641, tailcfg.Node.HomeDERP was declared as an int instead of its own type. This PR declares a new tailcfg.DERPRegionID type, represented by an int64, and converts the following fields to use this type: - netcheck.Report.PreferredDERP - netcheck.Report.RegionLatency - netcheck.Report.RegionV4Latency - netcheck.Report.RegionV6Latency - tailcfg.DERPHomeParams.RegionScore - tailcfg.DERPMap.Regions - tailcfg.DERPNode.RegionID - tailcfg.DERPRegion.RegionID - tailcfg.NetInfo.PreferredDERP - tailcfg.Node.HomeDERP - tailcfg.PeerChange.DERPRegion - tailcfg.PingResponse.DERPRegionID Note that the original field was an int, while the new field is backed by an int64. This change makes DERPRegionID the same size on both 32-bit and 64-bit architectures. Fixes: #20165 Change-Id: Ic6f795a6d791dd16f756f246d5a02085443e212f Signed-off-by: Simon Law <sfllaw@tailscale.com>
68 lines
1.9 KiB
Go
68 lines
1.9 KiB
Go
// Copyright (c) Tailscale Inc & contributors
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
// Package netcheckhook makes netcheck probe for captive portals during
|
|
// full reports. It does so as a side effect of being imported, by
|
|
// installing a netcheck hook from init.
|
|
package netcheckhook
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"time"
|
|
|
|
"tailscale.com/net/captivedetection"
|
|
"tailscale.com/net/netcheck"
|
|
"tailscale.com/tailcfg"
|
|
)
|
|
|
|
func init() {
|
|
netcheck.HookStartCaptivePortalDetection.Set(startCaptivePortalDetection)
|
|
}
|
|
|
|
// captivePortalDelay is the duration to wait after starting a netcheck before
|
|
// also probing for a captive portal, to let UDP STUN finish first and avoid
|
|
// the probe if it's unnecessary. Chosen semi-arbitrarily.
|
|
const captivePortalDelay = 200 * time.Millisecond
|
|
|
|
func startCaptivePortalDetection(ctx context.Context, c *netcheck.Client, dm *tailcfg.DERPMap, preferredDERP tailcfg.DERPRegionID, setCaptivePortal func(bool)) (done <-chan struct{}, stop func()) {
|
|
logf := c.Logf
|
|
if logf == nil {
|
|
logf = log.Printf
|
|
}
|
|
|
|
// This goroutine can't be tracked by the wait group that
|
|
// netcheck.GetReport uses for its probes, since GetReport doesn't
|
|
// wait for that group to finish before returning and we'd get a
|
|
// data race. Instead, completion is signaled by closing ch, which
|
|
// GetReport receives as the done channel.
|
|
ch := make(chan struct{})
|
|
|
|
tmr := time.AfterFunc(captivePortalDelay, func() {
|
|
defer close(ch)
|
|
d := captivedetection.NewDetector(logf)
|
|
found := d.Detect(ctx, c.NetMon, dm, preferredDERP)
|
|
setCaptivePortal(found)
|
|
})
|
|
|
|
if c.Verbose {
|
|
// Don't cancel our captive portal check if we're
|
|
// explicitly doing a verbose netcheck.
|
|
return ch, func() {}
|
|
}
|
|
|
|
stop = func() {
|
|
if tmr.Stop() {
|
|
// Stopped successfully; need to close the
|
|
// signal channel ourselves.
|
|
close(ch)
|
|
return
|
|
}
|
|
|
|
// Did not stop; do nothing and it'll finish by itself
|
|
// and close the signal channel.
|
|
}
|
|
|
|
return ch, stop
|
|
}
|