mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-06 11:38:24 +00:00
The path_mtu field is an unsigned per-hop transit annotation carried outside the signed proof, and the MtuExceeded and PathBroken signals arrive unencrypted with no sender check, so any forwarder could lower it and it was accepted with no minimum. A single MtuExceeded carrying a very small value drove a session's path MTU to zero, after which every packet to that destination was answered with an ICMPv6 Packet Too Big instead of being sent: a blackhole lasting until the daemon restarted. The same value reached the SYN-time TCP MSS clamp, where anything at or below 137 saturates to a segment size of zero and the band just above it yields single digits. Ignore values below an actionable minimum rather than applying or storing them, at the three places a remote value is acted on: the path MTU state machine, the reactive MtuExceeded write, and the discovery response, whose coordinates are still cached so refusing the annotation cannot become a way to deny discovery. The MSS clamp additionally refuses to write a zero. Ignoring rather than clamping is deliberate: a clamp would fabricate an estimate the node has no basis for. Release a stored per-destination path MTU when the path is invalidated by a PathBroken report, by session idle expiry, or by handshake timeout, and reseed the link MTU read from local configuration in its place, so a directly connected peer does not lose its own measurement along with the remote claim. Locally derived MTUs are not subject to the minimum, and adaptation to hops well below the IPv6 minimum continues to work. Count and name the path MTU values ignored as below the floor Three sites ignore a remote-supplied path MTU below the actionable floor and one releases a stale entry, and an operator had no way to see any of it happening. Count each site and log the value seen with the destination, so a node being fed poison is distinguishable from a node on a quiet link. Clamp on the degenerate case, not on the remote floor The floor guard at the MSS clamp site tested the stored value alone, with no test of where it came from, so it also rejected the link MTU the node seeds from its own transport. That contradicts the contract the constant's own doc states, and it bites hardest on BLE, where the seeded value is negotiated with the peer rather than read from config: a peer whose effective MTU negotiated to 240 lost a correct 103-byte clamp and got the 1143-byte conservative ceiling, after which every full-size segment was refused by the transport with no signal and no feedback to the application. Every remote value is already refused at the three ingress guards, so a sub-floor value reaching the clamp is by construction a local one. The clamp therefore needs only to refuse the degenerate case it was really about, where no payload byte survives the arithmetic at all. Also retarget the seed-site warning, which fired on the same wrong threshold and advised checking a transport setting that a negotiated link does not have, and correct the constant's doc, which contradicted its own formula about where the single-digit band ends.