You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The first non-keepalive MapResponse initializes Netmap even when the control server omits this machine's Node or supplies one that fails key/routing validation. Instead of returning an error or leaving the client uninitialized, Netmap::from_full_response manufactures a zero-value node with ID 0, empty key, empty name, and no routing data.
Later malformed self-node deltas are rejected while preserving the prior valid identity. The initial path therefore has a uniquely weaker contract: malformed identity becomes successful initialization.
Verified against main9aa9a56223afdd47d7723104cd16a5c07d5fc722.
Evidence
crates/dictyon/src/control/netmap.rs:47-67 filters the initial resp.node through node_is_valid, then calls unwrap_or_else(zero_value_node) for both absent and invalid values.
netmap.rs:229-247 constructs that fallback with id: 0, an empty node key and name, empty addresses, and no endpoint, DERP, disco-key, or expiry state.
netmap.rs:92-99 treats later malformed resp.node values differently: it warns and preserves the existing self node rather than installing a fabricated replacement.
crates/dictyon/src/control/mod.rs:384-403 makes first-response initialization infallible: apply_map_response returns () and stores Netmap::from_full_response(resp). recv_map_update at :294-312 consequently reports Ok(false) after accepting the fabricated identity.
control/mod.rs:414-417 exposes self_node() as Some(&Node) whenever the netmap exists, so callers cannot distinguish a real self record from the placeholder by the option state.
The regression test at crates/dictyon/src/control/tests/netmap_tests.rs:400-424 explicitly locks this behavior: a malformed self key must still initialize the netmap and produce self_node.key == "".
The self node is the local identity and routing anchor for every later stage: assigned addresses, capability level, key expiry, endpoint publication, and eventual data-plane configuration. A zero-value record is not a degraded but meaningful identity; it is the absence of identity represented as success.
Downstream code can therefore observe “netmap initialized” and Some(self_node) while operating on ID 0 and an empty key. That allows later state transitions, UI/status reporting, persistence, or data-plane preparation to proceed from a condition that should have blocked initialization.
The fallback also hides protocol regressions. A reference-server field omission or a validation rule that becomes too strict produces a warning and synthetic state instead of a testable interoperability failure.
Desired correction
Make initial netmap construction fallible and require one valid self node before publishing initialized state. An absent or malformed initial Node should return a typed control/netmap error and leave the previous state unchanged; on a client with no previous state, self_node() must remain None.
Keep delta semantics distinct: a malformed later self update may be ignored while preserving a previously validated identity, with an observable warning/metric.
Done when:
Netmap::from_full_response returns a Result or equivalent validated domain type;
absent and malformed initial self nodes fail the map update without creating a netmap;
recv_map_update propagates the typed failure rather than returning successful modification;
no production zero_value_node identity remains;
malformed later deltas preserve an existing valid self node; and
Finding
The first non-keepalive
MapResponseinitializesNetmapeven when the control server omits this machine'sNodeor supplies one that fails key/routing validation. Instead of returning an error or leaving the client uninitialized,Netmap::from_full_responsemanufactures a zero-value node with ID0, empty key, empty name, and no routing data.Later malformed self-node deltas are rejected while preserving the prior valid identity. The initial path therefore has a uniquely weaker contract: malformed identity becomes successful initialization.
Verified against
main9aa9a56223afdd47d7723104cd16a5c07d5fc722.Evidence
crates/dictyon/src/control/netmap.rs:47-67filters the initialresp.nodethroughnode_is_valid, then callsunwrap_or_else(zero_value_node)for both absent and invalid values.netmap.rs:229-247constructs that fallback withid: 0, an empty node key and name, empty addresses, and no endpoint, DERP, disco-key, or expiry state.netmap.rs:92-99treats later malformedresp.nodevalues differently: it warns and preserves the existing self node rather than installing a fabricated replacement.crates/dictyon/src/control/mod.rs:384-403makes first-response initialization infallible:apply_map_responsereturns()and storesNetmap::from_full_response(resp).recv_map_updateat:294-312consequently reportsOk(false)after accepting the fabricated identity.control/mod.rs:414-417exposesself_node()asSome(&Node)whenever the netmap exists, so callers cannot distinguish a real self record from the placeholder by the option state.crates/dictyon/src/control/tests/netmap_tests.rs:400-424explicitly locks this behavior: a malformed self key must still initialize the netmap and produceself_node.key == "".Why this matters
The self node is the local identity and routing anchor for every later stage: assigned addresses, capability level, key expiry, endpoint publication, and eventual data-plane configuration. A zero-value record is not a degraded but meaningful identity; it is the absence of identity represented as success.
Downstream code can therefore observe “netmap initialized” and
Some(self_node)while operating on ID0and an empty key. That allows later state transitions, UI/status reporting, persistence, or data-plane preparation to proceed from a condition that should have blocked initialization.The fallback also hides protocol regressions. A reference-server field omission or a validation rule that becomes too strict produces a warning and synthetic state instead of a testable interoperability failure.
Desired correction
Make initial netmap construction fallible and require one valid self node before publishing initialized state. An absent or malformed initial
Nodeshould return a typed control/netmap error and leave the previous state unchanged; on a client with no previous state,self_node()must remainNone.Keep delta semantics distinct: a malformed later self update may be ignored while preserving a previously validated identity, with an observable warning/metric.
Done when:
Netmap::from_full_responsereturns aResultor equivalent validated domain type;recv_map_updatepropagates the typed failure rather than returning successful modification;zero_value_nodeidentity remains;