The mesh's interface takes over the found tunnel's MTU
Carries MTU from the reported tunnel (mesh-host#28) through inventory, the overlay graph's TakeOver, into the generated config's [Interface]. A tuned path keeps its MTU across the takeover instead of regressing to 1420 and hanging transfers no ping would reveal. Two emit tests; a tunnel with no MTU writes no line.
This commit is contained in:
@@ -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, Port: t.Port}
|
n.TakesOver = &overlay.TakeOver{Interface: t.Interface, Unit: t.Unit, Config: t.Config, Port: t.Port, MTU: t.MTU}
|
||||||
}
|
}
|
||||||
if p.Hub {
|
if p.Hub {
|
||||||
for _, c := range carried {
|
for _, c := range carried {
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ type Tunnel struct {
|
|||||||
// Port is the port the found interface listened on — one the hosting provider already lets
|
// Port is the port the found interface listened on — one the hosting provider already lets
|
||||||
// through, which is why it is worth taking.
|
// through, which is why it is worth taking.
|
||||||
Port int `json:"port"`
|
Port int `json:"port"`
|
||||||
|
// MTU is the found interface's, when it set one; the mesh's interface takes it over so a
|
||||||
|
// tuned path does not silently regress to the default (novox/hq: a taken tunnel carries its MTU).
|
||||||
|
MTU int `json:"mtu,omitempty"`
|
||||||
// Address is the interface's own address with its prefix length, 192.0.2.1/24; Range is the
|
// Address is the interface's own address with its prefix length, 192.0.2.1/24; Range is the
|
||||||
// network that prefix names, 192.0.2.0/24.
|
// network that prefix names, 192.0.2.0/24.
|
||||||
Address string `json:"address"`
|
Address string `json:"address"`
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ func (e Enrolment) Enrol(ctx context.Context, request EnrolRequest) (reply Enrol
|
|||||||
}
|
}
|
||||||
if err := e.Inventory.RecordTunnel(ctx, node.ID, inventory.Tunnel{
|
if err := e.Inventory.RecordTunnel(ctx, node.ID, inventory.Tunnel{
|
||||||
Interface: request.Tunnel.Interface, Unit: request.Tunnel.Unit,
|
Interface: request.Tunnel.Interface, Unit: request.Tunnel.Unit,
|
||||||
Config: request.Tunnel.Config, Port: request.Tunnel.Port,
|
Config: request.Tunnel.Config, Port: request.Tunnel.Port, MTU: request.Tunnel.MTU,
|
||||||
Address: request.Tunnel.Address, Range: request.Tunnel.Range,
|
Address: request.Tunnel.Address, Range: request.Tunnel.Range,
|
||||||
PublicKey: request.Tunnel.PublicKey, Peers: peers,
|
PublicKey: request.Tunnel.PublicKey, Peers: peers,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@@ -199,7 +199,7 @@ func (e Enrolment) rekey(ctx context.Context, node inventory.Node, r Rekey) erro
|
|||||||
peers = append(peers, inventory.TunnelPeer{PublicKey: p.PublicKey, Address: p.Address})
|
peers = append(peers, inventory.TunnelPeer{PublicKey: p.PublicKey, Address: p.Address})
|
||||||
}
|
}
|
||||||
err := e.Inventory.Rekey(ctx, node.ID, r.Previous, r.OverlayKey, inventory.Tunnel{
|
err := e.Inventory.Rekey(ctx, node.ID, r.Previous, r.OverlayKey, inventory.Tunnel{
|
||||||
Interface: r.Tunnel.Interface, Unit: r.Tunnel.Unit, Config: r.Tunnel.Config, Port: r.Tunnel.Port,
|
Interface: r.Tunnel.Interface, Unit: r.Tunnel.Unit, Config: r.Tunnel.Config, Port: r.Tunnel.Port, MTU: r.Tunnel.MTU,
|
||||||
Address: r.Tunnel.Address, Range: r.Tunnel.Range, PublicKey: r.Tunnel.PublicKey, Peers: peers,
|
Address: r.Tunnel.Address, Range: r.Tunnel.Range, PublicKey: r.Tunnel.PublicKey, Peers: peers,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ type Tunnel struct {
|
|||||||
Unit string `json:"unit"`
|
Unit string `json:"unit"`
|
||||||
Config string `json:"config"`
|
Config string `json:"config"`
|
||||||
Port int `json:"port"`
|
Port int `json:"port"`
|
||||||
|
MTU int `json:"mtu,omitempty"`
|
||||||
Address string `json:"address"`
|
Address string `json:"address"`
|
||||||
Range string `json:"range"`
|
Range string `json:"range"`
|
||||||
PublicKey string `json:"public_key"`
|
PublicKey string `json:"public_key"`
|
||||||
|
|||||||
@@ -130,6 +130,12 @@ func config(node Node, peers []Peer, keyPath string) string {
|
|||||||
// with an endpoint — the guard's suggested remedy — breaks a NAT'd node's path.
|
// with an endpoint — the guard's suggested remedy — breaks a NAT'd node's path.
|
||||||
fmt.Fprintf(&b, "ListenPort = %d\n", node.TakesOver.Port)
|
fmt.Fprintf(&b, "ListenPort = %d\n", node.TakesOver.Port)
|
||||||
}
|
}
|
||||||
|
// The MTU the found tunnel carried, when it set one: a path tuned to 1380 (say) stalls TLS
|
||||||
|
// and hangs transfers if the mesh's interface comes up at the 1420 default, and no ping shows
|
||||||
|
// it (novox/hq: a taken tunnel carries its MTU).
|
||||||
|
if node.TakesOver != nil && node.TakesOver.MTU != 0 {
|
||||||
|
fmt.Fprintf(&b, "MTU = %d\n", node.TakesOver.MTU)
|
||||||
|
}
|
||||||
// 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.
|
||||||
fmt.Fprintf(&b, "PostUp = wg set %%i private-key %s\n", keyPath)
|
fmt.Fprintf(&b, "PostUp = wg set %%i private-key %s\n", keyPath)
|
||||||
|
|||||||
@@ -286,3 +286,26 @@ func TestANodeWithNoTunnelAndNoEndpointStillListensOnNothing(t *testing.T) {
|
|||||||
t.Fatalf("a dial-only node needs no ListenPort:\n%s", config)
|
t.Fatalf("a dial-only node needs no ListenPort:\n%s", config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestATakenTunnelCarriesItsMTU(t *testing.T) {
|
||||||
|
// A path tuned to a smaller MTU (1380 here) must survive the takeover — the mesh interface
|
||||||
|
// comes up with the same MTU, or transfers hang silently (novox/hq: a taken tunnel carries
|
||||||
|
// its MTU).
|
||||||
|
config, _ := declarationFor(t, Node{
|
||||||
|
Name: "shanks", Key: "SPOKE", Address: "10.10.0.3",
|
||||||
|
TakesOver: &TakeOver{Interface: "wg0", Port: 51820, MTU: 1380},
|
||||||
|
}, nil)
|
||||||
|
if !strings.Contains(config, "MTU = 1380") {
|
||||||
|
t.Fatalf("the tuned MTU was dropped:\n%s", config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNoMTULineWhenTheTunnelSetNone(t *testing.T) {
|
||||||
|
config, _ := declarationFor(t, Node{
|
||||||
|
Name: "shanks", Key: "SPOKE", Address: "10.10.0.3",
|
||||||
|
TakesOver: &TakeOver{Interface: "wg0", Port: 51820},
|
||||||
|
}, nil)
|
||||||
|
if strings.Contains(config, "MTU") {
|
||||||
|
t.Fatalf("no MTU was found, so none should be written:\n%s", config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ type TakeOver struct {
|
|||||||
Interface string
|
Interface string
|
||||||
Unit string
|
Unit string
|
||||||
Config string
|
Config string
|
||||||
|
// MTU is the found tunnel's, when it set one — emitted so a tuned path keeps its MTU.
|
||||||
|
MTU int
|
||||||
// Port is the port the found tunnel listened on. The mesh's interface must listen on it too,
|
// 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
|
// 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
|
// (novox/hq: a taken tunnel brings its port). Listening is "a peer dials me here"; it is not
|
||||||
|
|||||||
Reference in New Issue
Block a user