A taken tunnel brings its ListenPort, even on a node the hub cannot dial #75
@@ -256,7 +256,7 @@ func network(ctx context.Context, inv *inventory.Inventory, on map[string]bool,
|
|||||||
"Re-place it — `overlay place %s --hub --endpoint <host>:%d …` — and push again; "+
|
"Re-place it — `overlay place %s --hub --endpoint <host>:%d …` — and push again; "+
|
||||||
"nothing was composed", p.Name, t.Interface, wrong, p.Name, t.Port)
|
"nothing was composed", p.Name, t.Interface, wrong, p.Name, t.Port)
|
||||||
}
|
}
|
||||||
n.TakesOver = &overlay.TakeOver{Interface: t.Interface, Unit: t.Unit, Config: t.Config}
|
n.TakesOver = &overlay.TakeOver{Interface: t.Interface, Unit: t.Unit, Config: t.Config, Port: t.Port}
|
||||||
}
|
}
|
||||||
if p.Hub {
|
if p.Hub {
|
||||||
for _, c := range carried {
|
for _, c := range carried {
|
||||||
|
|||||||
@@ -123,6 +123,12 @@ func config(node Node, peers []Peer, keyPath string) string {
|
|||||||
if port := portOf(node.Endpoint); port != "" {
|
if port := portOf(node.Endpoint); port != "" {
|
||||||
fmt.Fprintf(&b, "ListenPort = %s\n", port)
|
fmt.Fprintf(&b, "ListenPort = %s\n", port)
|
||||||
}
|
}
|
||||||
|
} else if node.TakesOver != nil && node.TakesOver.Port != 0 {
|
||||||
|
// Not dialable from the hub, but a LAN peer dials this node on the tunnel it took over,
|
||||||
|
// so the mesh's interface must listen on that same port (novox/hq: a taken tunnel brings
|
||||||
|
// its port). Without this the takeover guard refuses overlay-up, and re-placing the node
|
||||||
|
// with an endpoint — the guard's suggested remedy — breaks a NAT'd node's path.
|
||||||
|
fmt.Fprintf(&b, "ListenPort = %d\n", node.TakesOver.Port)
|
||||||
}
|
}
|
||||||
// The private key is set from a file the node wrote, so it never appears here and never
|
// The private key is set from a file the node wrote, so it never appears here and never
|
||||||
// travelled. Everything else in this file came from the mesh; this one line is the node's.
|
// travelled. Everything else in this file came from the mesh; this one line is the node's.
|
||||||
|
|||||||
@@ -260,3 +260,29 @@ func TestTakingOverAFoundTunnelIsSaidOnTheInterfacesService(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestATakenTunnelBringsItsListenPortEvenWhenNotDialable(t *testing.T) {
|
||||||
|
// A home node behind NAT (no Endpoint, so not Reachable) that took over a tunnel must still
|
||||||
|
// listen on that tunnel's port, because its LAN peers dial it there (novox/hq: a taken tunnel
|
||||||
|
// brings its port). Without this the takeover guard refuses overlay-up.
|
||||||
|
config, _ := declarationFor(t, Node{
|
||||||
|
Name: "shanks", Key: "SPOKE", Address: "10.10.0.3",
|
||||||
|
TakesOver: &TakeOver{Interface: "wg0", Unit: "wg-quick@wg0", Port: 51820},
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
if !strings.Contains(config, "ListenPort = 51820") {
|
||||||
|
t.Fatalf("a taken tunnel's port must be the mesh interface's ListenPort:\n%s", config)
|
||||||
|
}
|
||||||
|
if strings.Contains(config, "Endpoint =") {
|
||||||
|
t.Error("a node that only listens for LAN peers must not advertise an endpoint")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestANodeWithNoTunnelAndNoEndpointStillListensOnNothing(t *testing.T) {
|
||||||
|
// The guard against over-emitting: a plain spoke with neither an endpoint nor a taken tunnel
|
||||||
|
// writes no ListenPort — it purely dials out.
|
||||||
|
config, _ := declarationFor(t, Node{Name: "laptop", Key: "K", Address: "10.10.0.9"}, nil)
|
||||||
|
if strings.Contains(config, "ListenPort") {
|
||||||
|
t.Fatalf("a dial-only node needs no ListenPort:\n%s", config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -50,6 +50,11 @@ type TakeOver struct {
|
|||||||
Interface string
|
Interface string
|
||||||
Unit string
|
Unit string
|
||||||
Config string
|
Config string
|
||||||
|
// Port is the port the found tunnel listened on. The mesh's interface must listen on it too,
|
||||||
|
// even on a node that is not dialable from the hub: a home node's LAN peers dial it there
|
||||||
|
// (novox/hq: a taken tunnel brings its port). Listening is "a peer dials me here"; it is not
|
||||||
|
// "the hub can dial me", which is Reachable — the two were conflated.
|
||||||
|
Port int
|
||||||
}
|
}
|
||||||
|
|
||||||
// HostPrefix is one address as a route: /32 for IPv4, /128 for IPv6.
|
// HostPrefix is one address as a route: /32 for IPv4, /128 for IPv6.
|
||||||
|
|||||||
Reference in New Issue
Block a user