mirror of
https://github.com/jmcorgan/fips.git
synced 2026-08-11 09:07:44 +00:00
node: drive net-new outbound establish through the per-peer machine
Cut the net-new outbound handshake completion (a received msg2 that promotes a fresh outbound leg to a new peer) over to the per-peer control machine, mirroring the inbound cutover. handle_msg2 still runs the msg2 prologue, the ACL check, and the cross-connection swap/keep arms inline; for the net-new promote it now builds a transient machine, steps it, and drives promote_connection through the executor. The session index was already allocated at dial, so there is no two-phase authorize here. The wire, index sequence, and peer registry state after promote are byte-neutral. To keep the promote-failure path neutral, the executor's cleanup now distinguishes inbound from outbound: an outbound promote failure records the reject only, matching the prior handler, rather than the inbound path's link and index teardown. Cross-connection swap/keep, rekey-msg2, and the dial path stay inline; the loser-link surgery for the currently unreachable driven cross-connection case lands with the register relocation next.
This commit is contained in:
@@ -54,6 +54,14 @@ pub(in crate::node) struct PeerActionCtx {
|
||||
pub(in crate::node) their_index: Option<SessionIndex>,
|
||||
/// The wire timestamp driving this step (promotion ts / loss-report clock).
|
||||
pub(in crate::node) now_ms: u64,
|
||||
/// Establish direction for this exchange. Discriminates the
|
||||
/// `PromoteToActive` failure cleanup: the pre-refactor inbound
|
||||
/// (`handle_msg1`) and outbound (`handle_msg2`) promote-Err arms were NOT
|
||||
/// byte-identical, so the executor must reproduce each. `false` = inbound
|
||||
/// (drop link + reverse map + free index), `true` = outbound (record the
|
||||
/// reject only; leave the dead link/`addr_to_link` for the stale-connection
|
||||
/// reaper, matching old `handle_msg2`).
|
||||
pub(in crate::node) is_outbound: bool,
|
||||
}
|
||||
|
||||
impl Node {
|
||||
@@ -179,22 +187,48 @@ impl Node {
|
||||
}
|
||||
Err(e) => {
|
||||
// GAP-4: promotion failed. `promote_connection` already
|
||||
// removed `connections[link]`; mirror the pre-refactor
|
||||
// cleanup (`handle_msg1` L587-591): drop the link +
|
||||
// reverse map, free our index, discard the machine, and
|
||||
// record the reject. The queue is drained (PromoteToActive
|
||||
// is the last establish action), so no explicit abort.
|
||||
//
|
||||
// Restored pre-refactor promote-failure warn!
|
||||
// (`handle_msg1` L757).
|
||||
warn!(link_id = %promote_link, error = %e, "Failed to promote inbound connection");
|
||||
self.remove_link(&promote_link);
|
||||
if let Some(idx) = ambient.our_index {
|
||||
let _ = self.index_allocator.free(idx);
|
||||
// removed `connections[link]` and (on error) handled its
|
||||
// own index internally. The pre-refactor inbound and
|
||||
// outbound promote-Err arms were NOT byte-identical, so
|
||||
// discriminate on `ambient.is_outbound`. The queue is
|
||||
// drained (PromoteToActive is the last establish action),
|
||||
// so no explicit abort.
|
||||
if ambient.is_outbound {
|
||||
// OLD outbound (`handle_msg2` promote-Err): warn +
|
||||
// record_reject ONLY. NO `remove_link`, NO
|
||||
// `index_allocator.free`, NO `addr_to_link` removal —
|
||||
// the dead link/addr_to_link/pending_outbound were
|
||||
// left for the 30s stale-connection reaper
|
||||
// (`promote_connection` already handled
|
||||
// `connections[link]`/its index on error). Restored
|
||||
// pre-refactor outbound warn! ("Failed to promote
|
||||
// connection").
|
||||
//
|
||||
// The transient outbound machine was inserted BEFORE
|
||||
// execute (Model A); it is additive C3-1 state that
|
||||
// did not exist pre-refactor, so removing the just-
|
||||
// inserted machine on failure is neutral vs old and
|
||||
// prevents a leak.
|
||||
warn!(link_id = %promote_link, error = %e, "Failed to promote connection");
|
||||
self.stats_mut().record_reject(RejectReason::Handshake(
|
||||
HandshakeReject::BadState,
|
||||
));
|
||||
self.peer_machines.remove(&promote_link);
|
||||
} else {
|
||||
// OLD inbound (`handle_msg1` L587-591): drop the link
|
||||
// + reverse map, free our index, discard the machine,
|
||||
// and record the reject. Restored pre-refactor inbound
|
||||
// promote-failure warn! (`handle_msg1` L757).
|
||||
warn!(link_id = %promote_link, error = %e, "Failed to promote inbound connection");
|
||||
self.remove_link(&promote_link);
|
||||
if let Some(idx) = ambient.our_index {
|
||||
let _ = self.index_allocator.free(idx);
|
||||
}
|
||||
self.peer_machines.remove(&promote_link);
|
||||
self.stats_mut().record_reject(RejectReason::Handshake(
|
||||
HandshakeReject::BadState,
|
||||
));
|
||||
}
|
||||
self.peer_machines.remove(&promote_link);
|
||||
self.stats_mut()
|
||||
.record_reject(RejectReason::Handshake(HandshakeReject::BadState));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user