use super::*;
impl ActivePeer {
pub fn session_established_at(&self) -> Instant {
self.session_established_at
}
#[cfg(test)]
pub(crate) fn set_session_established_at_for_test(&mut self, instant: Instant) {
self.session_established_at = instant;
}
pub fn rekey_jitter_secs(&self) -> i64 {
self.rekey_jitter_secs
}
pub fn current_k_bit(&self) -> bool {
self.current_k_bit
}
pub fn rekey_in_progress(&self) -> bool {
self.rekey_in_progress
}
pub fn set_rekey_in_progress(&mut self) {
self.rekey_in_progress = true;
}
pub fn is_rekey_dampened(&self, dampening_secs: u64) -> bool {
match self.last_peer_rekey {
Some(t) => t.elapsed().as_secs() < dampening_secs,
None => false,
}
}
pub fn record_peer_rekey(&mut self) {
self.last_peer_rekey = Some(Instant::now());
}
pub fn pending_our_index(&self) -> Option<SessionIndex> {
self.pending_our_index
}
pub fn pending_their_index(&self) -> Option<SessionIndex> {
self.pending_their_index
}
pub fn previous_our_index(&self) -> Option<SessionIndex> {
self.previous_our_index
}
pub fn previous_session(&self) -> Option<&NoiseSession> {
self.previous_session.as_ref()
}
pub fn previous_session_mut(&mut self) -> Option<&mut NoiseSession> {
self.previous_session.as_mut()
}
pub fn pending_new_session(&self) -> Option<&NoiseSession> {
self.pending_new_session.as_ref()
}
pub fn pending_rekey_initiator(&self) -> bool {
self.pending_rekey_initiator
}
pub fn pending_rekey_cutover_due(&self, delay: Duration) -> bool {
self.pending_rekey_initiator
&& self
.pending_rekey_completed_at
.is_some_and(|completed| completed.elapsed() >= delay)
}
pub fn set_pending_session(
&mut self,
session: NoiseSession,
our_index: SessionIndex,
their_index: SessionIndex,
initiated_by_local: bool,
) {
self.pending_new_session = Some(session);
self.pending_our_index = Some(our_index);
self.pending_their_index = Some(their_index);
self.pending_rekey_initiator = initiated_by_local;
self.pending_rekey_completed_at = Some(Instant::now());
self.rekey_in_progress = false;
self.rekey_our_index = None;
self.rekey_handshake = None;
self.rekey_msg1 = None;
self.rekey_msg1_next_resend = 0;
self.rekey_msg1_resend_count = 0;
}
pub fn cutover_to_new_session(&mut self) -> Option<SessionIndex> {
let new_session = self.pending_new_session.take()?;
let new_our_index = self.pending_our_index.take();
let new_their_index = self.pending_their_index.take();
self.previous_session = self.noise_session.take();
self.previous_our_index = self.our_index;
self.drain_started = Some(Instant::now());
self.noise_session = Some(new_session);
self.our_index = new_our_index;
self.their_index = new_their_index;
self.pending_rekey_initiator = false;
self.pending_rekey_completed_at = None;
self.current_k_bit = !self.current_k_bit;
self.session_established_at = Instant::now();
self.session_start = Instant::now();
self.session_generation = self.session_generation.wrapping_add(1).max(1);
self.rekey_in_progress = false;
self.rekey_msg1_resend_count = 0;
self.rekey_jitter_secs = draw_rekey_jitter();
self.last_heartbeat_sent = None;
self.reset_replay_suppressed();
self.previous_our_index
}
pub fn handle_peer_kbit_flip(&mut self) -> Option<SessionIndex> {
let new_session = self.pending_new_session.take()?;
let new_our_index = self.pending_our_index.take();
let new_their_index = self.pending_their_index.take();
self.previous_session = self.noise_session.take();
self.previous_our_index = self.our_index;
self.drain_started = Some(Instant::now());
self.noise_session = Some(new_session);
self.our_index = new_our_index;
self.their_index = new_their_index;
self.pending_rekey_initiator = false;
self.pending_rekey_completed_at = None;
self.current_k_bit = !self.current_k_bit;
self.session_established_at = Instant::now();
self.session_start = Instant::now();
self.session_generation = self.session_generation.wrapping_add(1).max(1);
self.rekey_in_progress = false;
self.rekey_msg1_resend_count = 0;
self.rekey_jitter_secs = draw_rekey_jitter();
self.last_heartbeat_sent = None;
self.reset_replay_suppressed();
self.previous_our_index
}
pub fn drain_expired(&self, drain_secs: u64) -> bool {
match self.drain_started {
Some(t) => t.elapsed().as_secs() >= drain_secs,
None => false,
}
}
pub fn is_draining(&self) -> bool {
self.drain_started.is_some()
}
pub fn complete_drain(&mut self) -> Option<SessionIndex> {
self.previous_session = None;
self.drain_started = None;
self.previous_our_index.take()
}
pub fn abandon_rekey(&mut self) -> Option<SessionIndex> {
self.rekey_handshake = None;
self.rekey_msg1 = None;
self.rekey_msg1_next_resend = 0;
self.rekey_msg1_resend_count = 0;
self.rekey_in_progress = false;
self.rekey_our_index.take().or_else(|| {
self.pending_new_session = None;
self.pending_their_index = None;
self.pending_rekey_initiator = false;
self.pending_rekey_completed_at = None;
self.pending_our_index.take()
})
}
pub fn set_rekey_state(
&mut self,
handshake: NoiseHandshakeState,
our_index: SessionIndex,
wire_msg1: Vec<u8>,
next_resend_ms: u64,
) {
self.rekey_handshake = Some(handshake);
self.rekey_our_index = Some(our_index);
self.rekey_msg1 = Some(wire_msg1);
self.rekey_msg1_next_resend = next_resend_ms;
self.rekey_msg1_resend_count = 0;
self.rekey_in_progress = true;
}
pub fn rekey_our_index(&self) -> Option<SessionIndex> {
self.rekey_our_index
}
pub fn complete_rekey_msg2(
&mut self,
msg2_bytes: &[u8],
) -> Result<(NoiseSession, Option<[u8; 8]>), NoiseError> {
let mut hs = self
.rekey_handshake
.take()
.ok_or_else(|| NoiseError::WrongState {
expected: "rekey handshake in progress".to_string(),
got: "no handshake state".to_string(),
})?;
hs.read_message_2(msg2_bytes)?;
let remote_epoch = hs.remote_epoch();
let session = hs.into_session()?;
self.rekey_msg1 = None;
self.rekey_msg1_next_resend = 0;
self.rekey_msg1_resend_count = 0;
Ok((session, remote_epoch))
}
pub fn needs_msg1_resend(&self, now_ms: u64) -> bool {
self.rekey_in_progress && self.rekey_msg1.is_some() && now_ms >= self.rekey_msg1_next_resend
}
pub fn rekey_msg1(&self) -> Option<&[u8]> {
self.rekey_msg1.as_deref()
}
pub fn set_msg1_next_resend(&mut self, next_ms: u64) {
self.rekey_msg1_next_resend = next_ms;
}
pub fn rekey_msg1_resend_count(&self) -> u32 {
self.rekey_msg1_resend_count
}
pub fn record_rekey_msg1_resend(&mut self, next_ms: u64) {
self.rekey_msg1_resend_count = self.rekey_msg1_resend_count.saturating_add(1);
self.rekey_msg1_next_resend = next_ms;
}
}