mirror of
https://github.com/tailscale/tailscale.git
synced 2025-01-07 08:07:42 +00:00
probing
This commit is contained in:
parent
c3b5ae55e6
commit
4684272ae0
@ -5920,19 +5920,24 @@ func (b *LocalBackend) SuggestExitNode() (*tailcfg.StableNodeID, error) {
|
||||
return nil, errors.New("no netmap")
|
||||
}
|
||||
peers := netMap.Peers
|
||||
lastReport := b.MagicConn().GetLastNetcheckReport()
|
||||
lastReport := b.MagicConn().GetLastNetcheckReport(b.ctx)
|
||||
var fastestRegionLatency = time.Duration(math.MaxInt64)
|
||||
var preferredExitNodeID tailcfg.StableNodeID
|
||||
peerRegionMap := make(map[int][]tailcfg.NodeView)
|
||||
b.logf("preferred self node derp %v", lastReport.PreferredDERP)
|
||||
b.logf("preferred self node derp name %v", netMap.DERPMap.Regions[lastReport.PreferredDERP])
|
||||
var mullvadCandidates []*tailcfg.NodeView
|
||||
for _, peer := range peers {
|
||||
if online := peer.Online(); online != nil && !*online {
|
||||
continue
|
||||
}
|
||||
if peer.Hostinfo().Location() != nil {
|
||||
b.logf("location %v %v", peer.Hostinfo().Location().Longitude, peer.Hostinfo().Location().Latitude)
|
||||
}
|
||||
if tsaddr.ContainsExitRoutes(peer.AllowedIPs()) {
|
||||
ipp, _ := netip.ParseAddrPort(peer.DERP())
|
||||
if peer.DERP() == "" {
|
||||
if peer.Hostinfo().Location().Country == "USA" {
|
||||
mullvadCandidates = append(mullvadCandidates, &peer)
|
||||
}
|
||||
}
|
||||
regionID := int(ipp.Port())
|
||||
regionLatency, ok := lastReport.RegionLatency[regionID]
|
||||
peerRegionMap[regionID] = append(peerRegionMap[regionID], peer)
|
||||
@ -5948,6 +5953,8 @@ func (b *LocalBackend) SuggestExitNode() (*tailcfg.StableNodeID, error) {
|
||||
}
|
||||
}
|
||||
b.logf("self derp %v", b.netMap.SelfNode.DERP())
|
||||
result := b.MagicConn().MeasureNodeICMPLatency(b.ctx, mullvadCandidates)
|
||||
b.logf("result %v", result)
|
||||
ipp, _ := netip.ParseAddrPort(netMap.SelfNode.DERP())
|
||||
selfDerpRegionID := int(ipp.Port())
|
||||
b.logf("self derp region id %v", selfDerpRegionID)
|
||||
|
@ -1730,3 +1730,48 @@ func conciseOptBool(b opt.Bool, trueVal string) string {
|
||||
metricSTUNRecv6 = clientmetric.NewCounter("netcheck_stun_recv_ipv6")
|
||||
metricHTTPSend = clientmetric.NewCounter("netcheck_https_measure")
|
||||
)
|
||||
|
||||
func (c *Client) MeasureICMPLatency(ctx context.Context, candidates []*tailcfg.NodeView) map[*tailcfg.NodeView]time.Duration {
|
||||
p := ping.New(ctx, c.logf, netns.Listener(c.logf, c.NetMon))
|
||||
defer p.Close()
|
||||
var wg sync.WaitGroup
|
||||
var results map[*tailcfg.NodeView]time.Duration
|
||||
wg.Add(len(candidates))
|
||||
for _, candidate := range candidates {
|
||||
go func(candidate *tailcfg.NodeView) {
|
||||
defer wg.Done()
|
||||
if d, err := c.measureNodeICMPLatency(ctx, candidate, p); err != nil {
|
||||
c.logf("error %v node %v", err, candidate.Name())
|
||||
} else {
|
||||
results[candidate] = d
|
||||
c.logf("results %v", results)
|
||||
}
|
||||
}(candidate)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
return results
|
||||
}
|
||||
|
||||
func (c *Client) measureNodeICMPLatency(ctx context.Context, node *tailcfg.NodeView, p *ping.Pinger) (time.Duration, error) {
|
||||
// Get the IPAddr by asking for the UDP address that we would use for
|
||||
// STUN and then using that IP.
|
||||
//
|
||||
// TODO(andrew-d): this is a bit ugly
|
||||
var nodeAddr netip.Addr
|
||||
for i := range node.Addresses().LenIter() {
|
||||
p := node.Addresses().At(i)
|
||||
if p.Addr().Is4() {
|
||||
nodeAddr = p.Addr()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
addr := &net.IPAddr{
|
||||
IP: net.IP(nodeAddr.AsSlice()),
|
||||
Zone: nodeAddr.Zone(),
|
||||
}
|
||||
// Use the unique node.Name field as the packet data to reduce the
|
||||
// likelihood that we get a mismatched echo response.
|
||||
return p.Send(ctx, addr, []byte(node.Name()))
|
||||
}
|
||||
|
@ -3009,7 +3009,15 @@ func getPeerMTUsProbedMetric(mtu tstun.WireMTU) *clientmetric.Metric {
|
||||
return mm
|
||||
}
|
||||
|
||||
func (c *Conn) GetLastNetcheckReport() *netcheck.Report {
|
||||
report, _ := c.updateNetInfo(c.connCtx)
|
||||
return report
|
||||
func (c *Conn) GetLastNetcheckReport(ctx context.Context) *netcheck.Report {
|
||||
nr, err := c.updateNetInfo(ctx)
|
||||
if err != nil {
|
||||
c.logf("magicsock.Conn.determineEndpoints: updateNetInfo: %v", err)
|
||||
return nil
|
||||
}
|
||||
return nr
|
||||
}
|
||||
|
||||
func (c *Conn) MeasureNodeICMPLatency(ctx context.Context, candidates []*tailcfg.NodeView) map[*tailcfg.NodeView]time.Duration {
|
||||
return c.netChecker.MeasureICMPLatency(ctx, candidates)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user