mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-11 13:18:53 +00:00
wgengine/magicsock: use learned DERP route as send path of last resort
If we get a packet in over some DERP and don't otherwise know how to reply (no known DERP home or UDP endpoint), this makes us use the DERP connection on which we received the packet to reply. This will almost always be our own home DERP region. This is particularly useful for large one-way nodes (such as hello.ts.net) that don't actively reach out to other nodes, so don't need to be told the DERP home of peers. They can instead learn the DERP home upon getting the first connection. This can also help nodes from a slow or misbehaving control plane. Updates tailscale/corp#26438 Change-Id: I6241ec92828bf45982e0eb83ad5c7404df5968bc Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:

committed by
Brad Fitzpatrick

parent
7fac0175c0
commit
75a03fc719
@@ -236,6 +236,22 @@ func hard(c *vnet.Config) *vnet.Node {
|
||||
fmt.Sprintf("10.0.%d.1/24", n), vnet.HardNAT))
|
||||
}
|
||||
|
||||
func hardNoDERPOrEndoints(c *vnet.Config) *vnet.Node {
|
||||
n := c.NumNodes() + 1
|
||||
return c.AddNode(c.AddNetwork(
|
||||
fmt.Sprintf("2.%d.%d.%d", n, n, n), // public IP
|
||||
fmt.Sprintf("10.0.%d.1/24", n), vnet.HardNAT),
|
||||
vnet.TailscaledEnv{
|
||||
Key: "TS_DEBUG_STRIP_ENDPOINTS",
|
||||
Value: "1",
|
||||
},
|
||||
vnet.TailscaledEnv{
|
||||
Key: "TS_DEBUG_STRIP_HOME_DERP",
|
||||
Value: "1",
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func hardPMP(c *vnet.Config) *vnet.Node {
|
||||
n := c.NumNodes() + 1
|
||||
return c.AddNode(c.AddNetwork(
|
||||
@@ -510,6 +526,26 @@ func TestEasyEasy(t *testing.T) {
|
||||
nt.want(routeDirect)
|
||||
}
|
||||
|
||||
// Issue tailscale/corp#26438: use learned DERP route as send path of last
|
||||
// resort
|
||||
//
|
||||
// See (*magicsock.Conn).fallbackDERPRegionForPeer and its comment for
|
||||
// background.
|
||||
//
|
||||
// This sets up a test with two nodes that must use DERP to communicate but the
|
||||
// target of the ping (the second node) additionally is not getting DERP or
|
||||
// Endpoint updates from the control plane. (Or rather, it's getting them but is
|
||||
// configured to scrub them right when they come off the network before being
|
||||
// processed) This then tests whether node2, upon receiving a packet, will be
|
||||
// able to reply to node1 since it knows neither node1's endpoints nor its home
|
||||
// DERP. The only reply route it can use is that fact that it just received a
|
||||
// packet over a particular DERP from that peer.
|
||||
func TestFallbackDERPRegionForPeer(t *testing.T) {
|
||||
nt := newNatTest(t)
|
||||
nt.runTest(hard, hardNoDERPOrEndoints)
|
||||
nt.want(routeDERP)
|
||||
}
|
||||
|
||||
func TestSingleJustIPv6(t *testing.T) {
|
||||
nt := newNatTest(t)
|
||||
nt.runTest(just6)
|
||||
|
Reference in New Issue
Block a user