|
|
|
@ -380,27 +380,6 @@ type nodeMeta struct {
|
|
|
|
|
|
|
|
|
|
type measureFn func(conn io.ReadWriteCloser, hostname string, dst netip.AddrPort) (rtt time.Duration, err error)
|
|
|
|
|
|
|
|
|
|
// probe measures round trip time for the node described by meta over cf against
|
|
|
|
|
// dstPort. It may return a nil duration and nil error in the event of a
|
|
|
|
|
// timeout. A non-nil error indicates an unrecoverable or non-temporary error.
|
|
|
|
|
func probe(meta nodeMeta, cf *connAndMeasureFn, dstPort int) (*time.Duration, error) {
|
|
|
|
|
ua := &net.UDPAddr{
|
|
|
|
|
IP: net.IP(meta.addr.AsSlice()),
|
|
|
|
|
Port: dstPort,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
time.Sleep(rand.N(maxTXJitter)) // jitter across tx
|
|
|
|
|
rtt, err := cf.fn(cf.conn, meta.hostname, netip.AddrPortFrom(meta.addr, uint16(dstPort)))
|
|
|
|
|
if err != nil {
|
|
|
|
|
if isTemporaryOrTimeoutErr(err) {
|
|
|
|
|
log.Printf("temp error measuring RTT to %s(%s): %v", meta.hostname, ua.String(), err)
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return &rtt, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// nodeMetaFromDERPMap parses the provided DERP map in order to update nodeMeta
|
|
|
|
|
// in the provided nodeMetaByAddr. It returns a slice of nodeMeta containing
|
|
|
|
|
// the nodes that are no longer seen in the DERP map, but were previously held
|
|
|
|
@ -620,16 +599,24 @@ func probeNodes(nodeMetaByAddr map[netip.Addr]nodeMeta, stableConns map[stableCo
|
|
|
|
|
},
|
|
|
|
|
at: at,
|
|
|
|
|
}
|
|
|
|
|
rtt, err := probe(meta, cf, dstPort)
|
|
|
|
|
time.Sleep(rand.N(maxTXJitter)) // jitter across tx
|
|
|
|
|
addrPort := netip.AddrPortFrom(meta.addr, uint16(dstPort))
|
|
|
|
|
rtt, err := cf.fn(cf.conn, meta.hostname, addrPort)
|
|
|
|
|
if err != nil {
|
|
|
|
|
select {
|
|
|
|
|
case <-doneCh:
|
|
|
|
|
return
|
|
|
|
|
case errCh <- err:
|
|
|
|
|
return
|
|
|
|
|
if isTemporaryOrTimeoutErr(err) {
|
|
|
|
|
r.rtt = nil
|
|
|
|
|
log.Printf("%s: temp error measuring RTT to %s(%s): %v", protocol, meta.hostname, addrPort, err)
|
|
|
|
|
} else {
|
|
|
|
|
select {
|
|
|
|
|
case <-doneCh:
|
|
|
|
|
return
|
|
|
|
|
case errCh <- fmt.Errorf("%s: %v", protocol, err):
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
r.rtt = &rtt
|
|
|
|
|
}
|
|
|
|
|
r.rtt = rtt
|
|
|
|
|
select {
|
|
|
|
|
case <-doneCh:
|
|
|
|
|
case resultsCh <- r:
|
|
|
|
|