use crate::error::CloseReason;
use std::collections::BTreeMap;
use std::time::{Duration, Instant};
pub const MAX_RELIABLE_IN_FLIGHT: usize = 256;
pub const MAX_REORDER_BUFFER: usize = 512;
pub const MAX_HANDSHAKE_MESSAGES: u8 = 5;
pub const MAX_PACKET_SIZE: usize = 2048;
pub const MAX_CONNECTIONS: usize = 10000;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ConnState {
Init,
Active,
Closed,
}
pub struct ReliablePacket {
pub bytes: Vec<u8>,
pub sent_at: Instant,
pub retries: u8,
}
pub struct Connection {
pub conn_id: u32,
pub state: ConnState,
pub next_seq: u32,
pub last_acked: u32,
pub rtt: Duration,
pub reliable: BTreeMap<u32, ReliablePacket>,
pub closed: bool,
pub close_reason: Option<CloseReason>,
pub reorder_buffer_size: usize,
pub handshake_msg_count: u8,
pub violation_strikes: u8,
pub last_activity: Instant,
pub ack_seq_counter: u32,
pub wraparound_warned: bool,
}
impl Connection {
pub fn new(conn_id: u32) -> Self {
Self {
conn_id,
state: ConnState::Init,
next_seq: 1,
last_acked: 0,
rtt: Duration::from_millis(100),
reliable: BTreeMap::new(),
closed: false,
close_reason: None,
reorder_buffer_size: 0,
handshake_msg_count: 0,
violation_strikes: 0,
last_activity: Instant::now(),
ack_seq_counter: 0,
wraparound_warned: false,
}
}
pub fn close(&mut self, reason: CloseReason) {
self.closed = true;
self.close_reason = Some(reason);
self.state = ConnState::Closed;
}
pub fn check_counter_wraparound(&mut self) -> bool {
const WRAPAROUND_THRESHOLD: u32 = u32::MAX - 1000;
if self.next_seq >= WRAPAROUND_THRESHOLD {
if !self.wraparound_warned {
eprintln!("WARNING: next_seq approaching u32::MAX ({}), closing connection to prevent nonce reuse", self.next_seq);
self.wraparound_warned = true;
}
self.close(CloseReason::ProtocolViolation);
return true;
}
if self.ack_seq_counter >= WRAPAROUND_THRESHOLD {
if !self.wraparound_warned {
eprintln!("WARNING: ack_seq_counter approaching u32::MAX ({}), closing connection to prevent nonce reuse", self.ack_seq_counter);
self.wraparound_warned = true;
}
self.close(CloseReason::ProtocolViolation);
return true;
}
false
}
}