mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-13 22:47:30 +00:00
cmd/{derp,derpprobe},prober,derp: add mesh support to derpprobe (#15414)
Add mesh key support to derpprobe for probing derpers with verify set to true. Move MeshKey checking to central point for code reuse. Fix a bad error fmt msg. Fixes tailscale/corp#27294 Fixes tailscale/corp#25756 Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
This commit is contained in:
@@ -47,6 +47,7 @@ import (
|
||||
type derpProber struct {
|
||||
p *Prober
|
||||
derpMapURL string // or "local"
|
||||
meshKey key.DERPMesh
|
||||
udpInterval time.Duration
|
||||
meshInterval time.Duration
|
||||
tlsInterval time.Duration
|
||||
@@ -71,7 +72,7 @@ type derpProber struct {
|
||||
udpProbeFn func(string, int) ProbeClass
|
||||
meshProbeFn func(string, string) ProbeClass
|
||||
bwProbeFn func(string, string, int64) ProbeClass
|
||||
qdProbeFn func(string, string, int, time.Duration) ProbeClass
|
||||
qdProbeFn func(string, string, int, time.Duration, key.DERPMesh) ProbeClass
|
||||
|
||||
sync.Mutex
|
||||
lastDERPMap *tailcfg.DERPMap
|
||||
@@ -143,6 +144,12 @@ func WithRegionCodeOrID(regionCode string) DERPOpt {
|
||||
}
|
||||
}
|
||||
|
||||
func WithMeshKey(meshKey key.DERPMesh) DERPOpt {
|
||||
return func(d *derpProber) {
|
||||
d.meshKey = meshKey
|
||||
}
|
||||
}
|
||||
|
||||
// DERP creates a new derpProber.
|
||||
//
|
||||
// If derpMapURL is "local", the DERPMap is fetched via
|
||||
@@ -250,7 +257,7 @@ func (d *derpProber) probeMapFn(ctx context.Context) error {
|
||||
wantProbes[n] = true
|
||||
if d.probes[n] == nil {
|
||||
log.Printf("adding DERP queuing delay probe for %s->%s (%s)", server.Name, to.Name, region.RegionName)
|
||||
d.probes[n] = d.p.Run(n, -10*time.Second, labels, d.qdProbeFn(server.Name, to.Name, d.qdPacketsPerSecond, d.qdPacketTimeout))
|
||||
d.probes[n] = d.p.Run(n, -10*time.Second, labels, d.qdProbeFn(server.Name, to.Name, d.qdPacketsPerSecond, d.qdPacketTimeout, d.meshKey))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -284,7 +291,7 @@ func (d *derpProber) probeMesh(from, to string) ProbeClass {
|
||||
}
|
||||
|
||||
dm := d.lastDERPMap
|
||||
return derpProbeNodePair(ctx, dm, fromN, toN)
|
||||
return derpProbeNodePair(ctx, dm, fromN, toN, d.meshKey)
|
||||
},
|
||||
Class: "derp_mesh",
|
||||
Labels: Labels{"derp_path": derpPath},
|
||||
@@ -308,7 +315,7 @@ func (d *derpProber) probeBandwidth(from, to string, size int64) ProbeClass {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return derpProbeBandwidth(ctx, d.lastDERPMap, fromN, toN, size, &transferTimeSeconds, &totalBytesTransferred, d.bwTUNIPv4Prefix)
|
||||
return derpProbeBandwidth(ctx, d.lastDERPMap, fromN, toN, size, &transferTimeSeconds, &totalBytesTransferred, d.bwTUNIPv4Prefix, d.meshKey)
|
||||
},
|
||||
Class: "derp_bw",
|
||||
Labels: Labels{
|
||||
@@ -336,7 +343,7 @@ func (d *derpProber) probeBandwidth(from, to string, size int64) ProbeClass {
|
||||
// to the queuing delay measurement and are recorded as dropped. 'from' and 'to' are
|
||||
// expected to be names (DERPNode.Name) of two DERP servers in the same region,
|
||||
// and may refer to the same server.
|
||||
func (d *derpProber) probeQueuingDelay(from, to string, packetsPerSecond int, packetTimeout time.Duration) ProbeClass {
|
||||
func (d *derpProber) probeQueuingDelay(from, to string, packetsPerSecond int, packetTimeout time.Duration, meshKey key.DERPMesh) ProbeClass {
|
||||
derpPath := "mesh"
|
||||
if from == to {
|
||||
derpPath = "single"
|
||||
@@ -349,7 +356,7 @@ func (d *derpProber) probeQueuingDelay(from, to string, packetsPerSecond int, pa
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return derpProbeQueuingDelay(ctx, d.lastDERPMap, fromN, toN, packetsPerSecond, packetTimeout, &packetsDropped, qdh)
|
||||
return derpProbeQueuingDelay(ctx, d.lastDERPMap, fromN, toN, packetsPerSecond, packetTimeout, &packetsDropped, qdh, meshKey)
|
||||
},
|
||||
Class: "derp_qd",
|
||||
Labels: Labels{"derp_path": derpPath},
|
||||
@@ -368,15 +375,15 @@ func (d *derpProber) probeQueuingDelay(from, to string, packetsPerSecond int, pa
|
||||
// derpProbeQueuingDelay continuously sends data between two local DERP clients
|
||||
// connected to two DERP servers in order to measure queuing delays. From and to
|
||||
// can be the same server.
|
||||
func derpProbeQueuingDelay(ctx context.Context, dm *tailcfg.DERPMap, from, to *tailcfg.DERPNode, packetsPerSecond int, packetTimeout time.Duration, packetsDropped *expvar.Float, qdh *histogram) (err error) {
|
||||
func derpProbeQueuingDelay(ctx context.Context, dm *tailcfg.DERPMap, from, to *tailcfg.DERPNode, packetsPerSecond int, packetTimeout time.Duration, packetsDropped *expvar.Float, qdh *histogram, meshKey key.DERPMesh) (err error) {
|
||||
// This probe uses clients with isProber=false to avoid spamming the derper
|
||||
// logs with every packet sent by the queuing delay probe.
|
||||
fromc, err := newConn(ctx, dm, from, false)
|
||||
fromc, err := newConn(ctx, dm, from, false, meshKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fromc.Close()
|
||||
toc, err := newConn(ctx, dm, to, false)
|
||||
toc, err := newConn(ctx, dm, to, false, meshKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -674,15 +681,15 @@ func derpProbeUDP(ctx context.Context, ipStr string, port int) error {
|
||||
// DERP clients connected to two DERP servers.If tunIPv4Address is specified,
|
||||
// probes will use a TCP connection over a TUN device at this address in order
|
||||
// to exercise TCP-in-TCP in similar fashion to TCP over Tailscale via DERP.
|
||||
func derpProbeBandwidth(ctx context.Context, dm *tailcfg.DERPMap, from, to *tailcfg.DERPNode, size int64, transferTimeSeconds, totalBytesTransferred *expvar.Float, tunIPv4Prefix *netip.Prefix) (err error) {
|
||||
func derpProbeBandwidth(ctx context.Context, dm *tailcfg.DERPMap, from, to *tailcfg.DERPNode, size int64, transferTimeSeconds, totalBytesTransferred *expvar.Float, tunIPv4Prefix *netip.Prefix, meshKey key.DERPMesh) (err error) {
|
||||
// This probe uses clients with isProber=false to avoid spamming the derper logs with every packet
|
||||
// sent by the bandwidth probe.
|
||||
fromc, err := newConn(ctx, dm, from, false)
|
||||
fromc, err := newConn(ctx, dm, from, false, meshKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fromc.Close()
|
||||
toc, err := newConn(ctx, dm, to, false)
|
||||
toc, err := newConn(ctx, dm, to, false, meshKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -712,13 +719,13 @@ func derpProbeBandwidth(ctx context.Context, dm *tailcfg.DERPMap, from, to *tail
|
||||
|
||||
// derpProbeNodePair sends a small packet between two local DERP clients
|
||||
// connected to two DERP servers.
|
||||
func derpProbeNodePair(ctx context.Context, dm *tailcfg.DERPMap, from, to *tailcfg.DERPNode) (err error) {
|
||||
fromc, err := newConn(ctx, dm, from, true)
|
||||
func derpProbeNodePair(ctx context.Context, dm *tailcfg.DERPMap, from, to *tailcfg.DERPNode, meshKey key.DERPMesh) (err error) {
|
||||
fromc, err := newConn(ctx, dm, from, true, meshKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fromc.Close()
|
||||
toc, err := newConn(ctx, dm, to, true)
|
||||
toc, err := newConn(ctx, dm, to, true, meshKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1116,7 +1123,7 @@ func derpProbeBandwidthTUN(ctx context.Context, transferTimeSeconds, totalBytesT
|
||||
return nil
|
||||
}
|
||||
|
||||
func newConn(ctx context.Context, dm *tailcfg.DERPMap, n *tailcfg.DERPNode, isProber bool) (*derphttp.Client, error) {
|
||||
func newConn(ctx context.Context, dm *tailcfg.DERPMap, n *tailcfg.DERPNode, isProber bool, meshKey key.DERPMesh) (*derphttp.Client, error) {
|
||||
// To avoid spamming the log with regular connection messages.
|
||||
l := logger.Filtered(log.Printf, func(s string) bool {
|
||||
return !strings.Contains(s, "derphttp.Client.Connect: connecting to")
|
||||
@@ -1132,6 +1139,7 @@ func newConn(ctx context.Context, dm *tailcfg.DERPMap, n *tailcfg.DERPNode, isPr
|
||||
}
|
||||
})
|
||||
dc.IsProber = isProber
|
||||
dc.MeshKey = meshKey
|
||||
err := dc.Connect(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1165,7 +1173,7 @@ func newConn(ctx context.Context, dm *tailcfg.DERPMap, n *tailcfg.DERPNode, isPr
|
||||
case derp.ServerInfoMessage:
|
||||
errc <- nil
|
||||
default:
|
||||
errc <- fmt.Errorf("unexpected first message type %T", errc)
|
||||
errc <- fmt.Errorf("unexpected first message type %T", m)
|
||||
}
|
||||
}()
|
||||
select {
|
||||
|
Reference in New Issue
Block a user