mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-05 11:08:25 +00:00
A PathBroken signal carries no end-to-end authentication, yet one admitted signal deleted the destination's cached coordinates even when a lookup had verified them. That removed the only thing refusing the next forged coordinate warm, so one forged PathBroken followed by one forged SessionSetup moved a node's route to any destination it had a session with. An admitted PathBroken now treats a verified entry differently from a hint: - A hint, or a verification that has aged out, is still removed. - A verified entry is kept while the lookup re-validates it. It is demoted to a hint, keeping its value, only when signals naming the destination arrive over two different links within 15 seconds. - The re-lookup now runs on every admitted PathBroken, not only when the destination's identity is cached. The vote is the authenticated link peer a signal arrived over, not the reporter it names: the reporter is plaintext the sender chooses, so every signal from one neighbour, forged or relayed, is one vote however many reporters it names. A node whose signals all arrive over one link, such as a leaf with a single peer, never reaches the quorum; a stale verified entry there lasts until the lookup each signal starts answers and replaces it, or at most until its verification ages out after five minutes, when the next signal removes it as it would a hint. The link quorum is a new sans-IO module with an injected clock. A lookup that verifies a destination again clears its quorum, so a report about the old path cannot combine with one about the new. When the path-MTU release fires, a kept entry also forgets the path MTU stored with it, as the removed entry used to; when the release is rate limited, a kept entry keeps it. New error-signal counters broken_below_quorum and broken_demoted count the two outcomes for a verified entry. Two advisory counters measure how often an admitted PathBroken looks implausible, without refusing anything: - broken_link_mismatch: the signal arrived over a link other than the one this node would forward to the destination on. The check uses the non-touching next-hop preview, so it does not refresh the cache entry. - broken_reporter_mismatch: the reporter is this node or the destination, or its known coordinates (a direct peer's from the tree, otherwise the coordinate cache) are not strictly closer to the destination than this node's. Both have a non-zero healthy floor: a genuine report can arrive off the forward link, and a reporter's view of the destination can differ from this node's. Most reporters' coordinates are not known here and are not counted. They size the forged-signal problem; they are not alarms, and the signal is acted on in full either way. The handler now receives the authenticated link peer the datagram arrived over, which the quorum and the link check need. The source-recovery steps in the mesh operation design described a PathBroken as removing the destination's cached coordinates and discovery as depending on a cached identity; they now describe the behaviour above.
126 lines
3.5 KiB
JSON
126 lines
3.5 KiB
JSON
{
|
|
"data": {
|
|
"congestion": {
|
|
"ce_forwarded": 0,
|
|
"ce_received": 0,
|
|
"congestion_detected": 0,
|
|
"kernel_drop_events": 0
|
|
},
|
|
"coord_cache_entries": 0,
|
|
"discovery": {
|
|
"req_backoff_suppressed": 0,
|
|
"req_bloom_miss": 0,
|
|
"req_decode_error": 0,
|
|
"req_dedup_cache_full": 0,
|
|
"req_dedup_evicted": 0,
|
|
"req_deduplicated": 0,
|
|
"req_duplicate": 0,
|
|
"req_fallback_forwarded": 0,
|
|
"req_forward_rate_limited": 0,
|
|
"req_forwarded": 0,
|
|
"req_initiated": 0,
|
|
"req_no_tree_peer": 0,
|
|
"req_own_loopback": 0,
|
|
"req_received": 0,
|
|
"req_sign_rate_limited": 0,
|
|
"req_target_is_us": 0,
|
|
"req_ttl_exhausted": 0,
|
|
"resp_accepted": 0,
|
|
"resp_decode_error": 0,
|
|
"resp_forwarded": 0,
|
|
"resp_identity_miss": 0,
|
|
"resp_no_route": 0,
|
|
"resp_proof_failed": 0,
|
|
"resp_received": 0,
|
|
"resp_timed_out": 0,
|
|
"resp_unsolicited": 0
|
|
},
|
|
"error_signals": {
|
|
"broken_below_quorum": 0,
|
|
"broken_demoted": 0,
|
|
"broken_link_mismatch": 0,
|
|
"broken_reporter_mismatch": 0,
|
|
"coords_required": 0,
|
|
"emit_limiter_at_capacity": 0,
|
|
"emit_over_dest_interval": 0,
|
|
"emit_over_peer_budget": 0,
|
|
"lookup_resp_mtu_below_floor": 0,
|
|
"mtu_exceeded": 0,
|
|
"mtu_exceeded_below_floor": 0,
|
|
"mtu_exceeded_uncorroborated": 0,
|
|
"path_broken": 0,
|
|
"path_mtu_notif_below_floor": 0,
|
|
"unbound_broken": 0,
|
|
"unbound_coords": 0,
|
|
"unbound_forged": 0,
|
|
"unbound_mtu": 0
|
|
},
|
|
"forwarding": {
|
|
"coord_hint_changed": 0,
|
|
"coord_hint_rejected": 0,
|
|
"coord_warm_foreign_root": 0,
|
|
"coord_warm_key_mismatch": 0,
|
|
"decode_error_bytes": 0,
|
|
"decode_error_packets": 0,
|
|
"delivered_bytes": 0,
|
|
"delivered_packets": 0,
|
|
"drop_mtu_exceeded_bytes": 0,
|
|
"drop_mtu_exceeded_packets": 0,
|
|
"drop_no_route_bytes": 0,
|
|
"drop_no_route_packets": 0,
|
|
"drop_send_error_bytes": 0,
|
|
"drop_send_error_packets": 0,
|
|
"forwarded_bytes": 0,
|
|
"forwarded_packets": 0,
|
|
"originated_bytes": 0,
|
|
"originated_packets": 0,
|
|
"received_bytes": 0,
|
|
"received_packets": 0,
|
|
"route_crosslink_ascend": 0,
|
|
"route_crosslink_descend": 0,
|
|
"route_direct_peer": 0,
|
|
"route_tree_down": 0,
|
|
"route_tree_down_cross": 0,
|
|
"route_tree_up": 0,
|
|
"ttl_exhausted_bytes": 0,
|
|
"ttl_exhausted_packets": 0,
|
|
"warm_malformed_bytes": 0,
|
|
"warm_malformed_packets": 0
|
|
},
|
|
"identity_cache_entries": 0,
|
|
"lookup": {
|
|
"req_backoff_suppressed": 0,
|
|
"req_bloom_miss": 0,
|
|
"req_decode_error": 0,
|
|
"req_dedup_cache_full": 0,
|
|
"req_dedup_evicted": 0,
|
|
"req_deduplicated": 0,
|
|
"req_duplicate": 0,
|
|
"req_fallback_forwarded": 0,
|
|
"req_forward_rate_limited": 0,
|
|
"req_forwarded": 0,
|
|
"req_initiated": 0,
|
|
"req_no_tree_peer": 0,
|
|
"req_own_loopback": 0,
|
|
"req_received": 0,
|
|
"req_sign_rate_limited": 0,
|
|
"req_target_is_us": 0,
|
|
"req_ttl_exhausted": 0,
|
|
"resp_accepted": 0,
|
|
"resp_decode_error": 0,
|
|
"resp_forwarded": 0,
|
|
"resp_identity_miss": 0,
|
|
"resp_no_route": 0,
|
|
"resp_proof_failed": 0,
|
|
"resp_received": 0,
|
|
"resp_timed_out": 0,
|
|
"resp_unsolicited": 0
|
|
},
|
|
"pending_lookups": [],
|
|
"pending_tun_destinations": 0,
|
|
"pending_tun_packets": 0,
|
|
"recent_requests": 0,
|
|
"retries": []
|
|
},
|
|
"status": "ok"
|
|
} |