Fix session state poisoning panic, harden session state access

handle_session_ack() had a bug where take_state() followed by
a non-Initiating match would re-insert the entry with state=None,
causing panics on subsequent .state()/.state_mut() calls. Fix by
checking is_initiating() before take_state().

Add safe is_initiating()/is_responding() to SessionEntry (matching
existing is_established()) and convert all production .state() callers
to use these None-safe methods. Gate .state() with #[cfg(test)].
This commit is contained in:
Johnathan Corgan
2026-02-19 20:56:00 +00:00
parent a8d3627072
commit 12db6f561a
2 changed files with 47 additions and 40 deletions
+11
View File
@@ -112,6 +112,7 @@ impl SessionEntry {
}
/// Get the current session state.
#[cfg(test)]
pub(crate) fn state(&self) -> &EndToEndState {
self.state.as_ref().expect("session state taken but not restored")
}
@@ -147,6 +148,16 @@ impl SessionEntry {
self.state.as_ref().is_some_and(|s| s.is_established())
}
/// Check if we are the initiator (waiting for ack).
pub(crate) fn is_initiating(&self) -> bool {
self.state.as_ref().is_some_and(|s| s.is_initiating())
}
/// Check if we are the responder (sent ack, waiting for data).
pub(crate) fn is_responding(&self) -> bool {
self.state.as_ref().is_some_and(|s| s.is_responding())
}
/// Get creation time.
#[cfg(test)]
pub(crate) fn created_at(&self) -> u64 {