mirror of
https://github.com/jmcorgan/fips.git
synced 2026-08-12 09:33:23 +00:00
peer: source the handshake identity and index family from the control machine
The pending connection and the per-peer control machine have carried duplicate copies of the handshake-phase fields since the machine gained its own connection state. Read them from the machine and drop the connection's projections. The peer identity is the sharp one. The connection learned it from msg1 and the machine's carrier did not, so the two views genuinely disagreed for inbound connections until the Noise operations moved onto the machine and began recording each result on both. That is now in place, so every reader can take the machine's copy unchanged: the establish snapshot, the promotion sweep for competing connections, the dial and path in-progress checks, the peering observations and per-peer in-flight budget, and the stale-connection sweep's retry address. Also repointed: our_index, their_index, transport_id, started_at, the stored handshake message bytes, and the idle-timeout check. Two duplicate index writes on the connection are dropped, both immediately preceded by the machine-side write of the same value. Reads that previously came off a connection detached just before its machine was disposed now capture the machine's value first. Test seeding follows the establish paths: the seed builders write our_index to the carrier, which promotion now reads. A new test pins the inbound identity learn on the carrier and the retry address a failed inbound connection reports to the sweep, so a silent regression to a blank identity cannot pass. ConnectionState::duration loses its last non-test caller with the connection accessor and is marked test-only.
This commit is contained in:
+22
-15
@@ -2444,7 +2444,7 @@ impl Node {
|
||||
}
|
||||
|
||||
let machine = self.peer_machines.entry(link_id).or_insert_with(|| {
|
||||
let now = connection.started_at();
|
||||
let now = connection.state().started_at();
|
||||
match connection.state().expected_identity() {
|
||||
Some(identity) if connection.state().is_outbound() => {
|
||||
PeerMachine::new_outbound(link_id, *identity, now)
|
||||
@@ -2455,10 +2455,13 @@ impl Node {
|
||||
// Seed the surviving carrier's peer index and transport from the
|
||||
// pre-built leg so the promotion hand-off reads them from the machine,
|
||||
// matching the establish paths that write them on the machine directly.
|
||||
if let Some(their) = connection.their_index() {
|
||||
if let Some(ours) = connection.state().our_index() {
|
||||
machine.set_conn_our_index(ours);
|
||||
}
|
||||
if let Some(their) = connection.state().their_index() {
|
||||
machine.set_conn_their_index(their);
|
||||
}
|
||||
if let Some(tid) = connection.transport_id() {
|
||||
if let Some(tid) = connection.state().transport_id() {
|
||||
machine.set_conn_transport_id(tid);
|
||||
}
|
||||
if let Some(addr) = connection.state().source_addr() {
|
||||
@@ -2473,12 +2476,13 @@ impl Node {
|
||||
/// free-standing leg first.
|
||||
///
|
||||
/// The carrier seeding below is a verbatim copy of `add_connection`'s: the
|
||||
/// two conditional writes (`their_index`, `transport_id`) and `set_leg`,
|
||||
/// built through the same `entry(..).or_insert_with(..)` so an existing
|
||||
/// leg-less machine keeps its constructor-side fields. Nothing else is
|
||||
/// written to the carrier — `our_index`, `source_addr`, post-construction
|
||||
/// `started_at`, and the stored handshake bytes stay leg-only, exactly as
|
||||
/// they do for a test that goes through `add_connection` today.
|
||||
/// conditional writes (`our_index`, `their_index`, `transport_id`,
|
||||
/// `source_addr`) and `set_leg`, built through the same
|
||||
/// `entry(..).or_insert_with(..)` so an existing leg-less machine keeps its
|
||||
/// constructor-side fields. The seeded carrier matches what the establish
|
||||
/// paths write: every field a promotion reads is present. Post-construction
|
||||
/// `started_at` and the stored handshake bytes are not seeded here, exactly
|
||||
/// as they are not for a test that goes through `add_connection` today.
|
||||
///
|
||||
/// The duplication is deliberate: keeping the carrier writes visible here
|
||||
/// is what lets each later step of the leg dissolution revise them at a
|
||||
@@ -2494,14 +2498,14 @@ impl Node {
|
||||
None => PeerConnection::inbound(link_id, seed.started_at_ms),
|
||||
};
|
||||
if let Some(id) = seed.transport_id {
|
||||
connection.set_transport_id(id);
|
||||
connection.state_mut().set_transport_id(id);
|
||||
}
|
||||
let seeded_source_addr = seed.source_addr.clone();
|
||||
if let Some(index) = seed.our_index {
|
||||
connection.set_our_index(index);
|
||||
connection.state_mut().set_our_index(index);
|
||||
}
|
||||
if let Some(index) = seed.their_index {
|
||||
connection.set_their_index(index);
|
||||
connection.state_mut().set_their_index(index);
|
||||
}
|
||||
|
||||
if self
|
||||
@@ -2519,7 +2523,7 @@ impl Node {
|
||||
}
|
||||
|
||||
let machine = self.peer_machines.entry(link_id).or_insert_with(|| {
|
||||
let now = connection.started_at();
|
||||
let now = connection.state().started_at();
|
||||
match connection.state().expected_identity() {
|
||||
Some(identity) if connection.state().is_outbound() => {
|
||||
PeerMachine::new_outbound(link_id, *identity, now)
|
||||
@@ -2527,10 +2531,13 @@ impl Node {
|
||||
_ => PeerMachine::new_inbound(link_id, now),
|
||||
}
|
||||
});
|
||||
if let Some(their) = connection.their_index() {
|
||||
if let Some(ours) = connection.state().our_index() {
|
||||
machine.set_conn_our_index(ours);
|
||||
}
|
||||
if let Some(their) = connection.state().their_index() {
|
||||
machine.set_conn_their_index(their);
|
||||
}
|
||||
if let Some(tid) = connection.transport_id() {
|
||||
if let Some(tid) = connection.state().transport_id() {
|
||||
machine.set_conn_transport_id(tid);
|
||||
}
|
||||
if let Some(addr) = seeded_source_addr {
|
||||
|
||||
Reference in New Issue
Block a user