use crate::layer::ip;
use crate::managed::{Map, SlotMap, slotmap::Key};
use crate::wire::{ip::Address, tcp::SeqNumber, tcp::Packet as TcpPacket};
use crate::wire::PayloadMut;
use crate::time::{Duration, Expiration, Instant};
use super::connection::{
Connection,
Flow,
Send,
State,
Receive};
use super::packet::{In, Raw};
use super::siphash::IsnGenerator;
pub struct Endpoint<'a> {
ports: Map<'a, FourTuple, Key>,
states: SlotMap<'a, Slot>,
isn_generator: IsnGenerator,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FourTuple {
pub local: Address,
pub remote: Address,
pub local_port: u16,
pub remote_port: u16,
}
#[derive(Clone, Copy, Debug, Hash)]
pub struct Slot {
addr: FourTuple,
connection: Connection,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct SlotKey {
key: Key,
}
pub struct Receiver<'a, 'e, H> {
endpoint: Borrow<'a, 'e>,
handler: H,
}
pub struct Sender<'a, 'e, H> {
endpoint: Borrow<'a, 'e>,
handler: H,
}
struct Borrow<'a, 'e> {
inner: &'a mut Endpoint<'e>,
}
pub struct Entry<'a> {
key: SlotKey,
ports: &'a mut dyn PortMap,
isn: &'a IsnGenerator,
slot: &'a mut Slot,
}
pub struct EntryKey<'a> {
ports: &'a mut dyn PortMap,
isn: &'a IsnGenerator,
key_in_slot: &'a mut FourTuple,
}
pub(crate) trait PortMap {
fn remap(&mut self, old: FourTuple, new: FourTuple);
}
impl Endpoint<'_> {
pub fn get(&self, index: SlotKey)
-> Option<&Slot>
{
self.states.get(index.key)
}
pub fn get_mut(&mut self, index: SlotKey)
-> Option<&mut Slot>
{
self.states.get_mut(index.key)
}
pub(crate) fn entry(&mut self, index: SlotKey)
-> Option<Entry>
{
let slot = self.states.get_mut(index.key)?;
Some(Entry {
key: SlotKey { key: index.key },
ports: &mut self.ports,
isn: &mut self.isn_generator,
slot,
})
}
pub fn key_from_tuple(&mut self, tuple: FourTuple)
-> Option<SlotKey>
{
let key = self.ports.get(&tuple).cloned()?;
Some(SlotKey { key })
}
pub(crate) fn entry_from_tuple(&mut self, tuple: FourTuple)
-> Option<Entry>
{
let key = self.key_from_tuple(tuple)?;
self.entry(key)
}
pub fn remove(&mut self, index: SlotKey) {
let addr = match self.get_mut(index) {
Some(connection) => {
connection.connection.change_state(State::Closed);
connection.addr
},
None => return,
};
self.ports.entry(addr).remove();
let _ = self.states.remove(index.key);
}
fn listen(&mut self, ip: Address, port: u16)
-> Option<SlotKey>
{
let key = FourTuple {
local: ip,
local_port: port,
remote: Address::Unspecified,
remote_port: 0,
};
let (key, state) = self.create_state(key)?;
state.connection.current = State::Listen;
Some(key)
}
fn open(&mut self, tuple: FourTuple)
-> Option<SlotKey>
{
let (key, _) = self.create_state(tuple)?;
Some(key)
}
fn create_state(&mut self, addr: FourTuple)
-> Option<(SlotKey, &mut Slot)>
{
let connection = self.create_connection();
let vacant = self.ports
.entry(addr)
.vacant()?;
let (key, slot) = self.states
.reserve()?;
slot.connection = connection;
slot.addr = addr;
vacant.insert(key);
let key = SlotKey {
key,
};
Some((key, slot))
}
fn create_connection(&mut self) -> Connection {
Connection {
current: State::Closed,
previous: State::Closed,
flow_control: Flow {
congestion_window: 0,
ssthresh: u32::max_value(),
recover: SeqNumber::default(),
},
receive_window: 0,
sender_maximum_segment_size: 0,
receiver_maximum_segment_size: 0,
last_ack_receive_offset: SeqNumber::default(),
ack_timer: Expiration::Never,
ack_timeout: Duration::from_millis(500),
retransmission_timer: Instant::from_millis(0),
retransmission_timeout: Duration::from_millis(3000),
restart_timeout: Duration::from_millis(30000),
selective_acknowledgements: false,
duplicate_ack: 0,
send: Send {
unacked: SeqNumber::default(),
next: SeqNumber::default(),
last_time: Instant::from_millis(0),
unsent: 0,
window: 0,
window_scale: 0,
initial_seq: SeqNumber::default(),
},
recv: Receive {
acked: SeqNumber::default(),
next: SeqNumber::default(),
last_time: Instant::from_millis(0),
window: 0,
window_scale: 0,
initial_seq: SeqNumber::default(),
},
}
}
fn initial_seq_num(&mut self, id: FourTuple, time: Instant) -> SeqNumber {
self.isn_generator.get_isn(id, time)
}
}
impl Slot {
pub fn four_tuple(&self) -> FourTuple {
self.addr
}
pub(crate) fn connection(&self) -> &Connection {
&self.connection
}
}
impl<'ep> Endpoint<'ep> {
pub fn new(
ports: Map<'ep, FourTuple, Key>,
states: SlotMap<'ep, Slot>,
isn_generator: IsnGenerator,
) -> Self {
Endpoint {
ports,
states,
isn_generator,
}
}
pub fn recv<H>(&mut self, handler: H) -> Receiver<'_, 'ep, H> {
Receiver { endpoint: self.borrow(), handler }
}
pub fn send<H>(&mut self, handler: H) -> Sender<'_, 'ep, H> {
Sender { endpoint: self.borrow(), handler }
}
fn borrow(&mut self) -> Borrow<'_, 'ep> {
Borrow { inner: self, }
}
}
impl<'a> Entry<'a> {
pub fn into_key_value(self) -> (EntryKey<'a>, &'a mut Connection) {
let entry_key = EntryKey {
ports: self.ports,
isn: self.isn,
key_in_slot: &mut self.slot.addr,
};
let connection = &mut self.slot.connection;
(entry_key, connection)
}
pub fn slot_key(&self) -> SlotKey {
self.key
}
pub fn connection(&mut self) -> &mut Connection {
&mut self.slot.connection
}
}
impl EntryKey<'_> {
pub fn initial_seq_num(&self, time: Instant) -> SeqNumber {
self.isn.get_isn(*self.key_in_slot, time)
}
pub fn four_tuple(&self) -> FourTuple {
*self.key_in_slot
}
pub fn set_four_tuple(&mut self, new: FourTuple) {
self.ports.remap(*self.key_in_slot, new);
*self.key_in_slot = new;
}
}
#[cfg(test)]
impl<'a> EntryKey<'a> {
pub(crate) fn fake(
ports: &'a mut dyn PortMap,
isn: &'a IsnGenerator,
key_in_slot: &'a mut FourTuple,
) -> EntryKey<'a> {
EntryKey { ports, isn, key_in_slot, }
}
}
impl Default for Slot {
fn default() -> Self {
Slot {
addr: FourTuple::default(),
connection: Connection::zeroed(),
}
}
}
impl super::connection::Endpoint for Endpoint<'_> {
fn get(&self, index: SlotKey) -> Option<&Slot> {
Endpoint::get(self, index)
}
fn get_mut(&mut self, index: SlotKey) -> Option<&mut Slot> {
Endpoint::get_mut(self, index)
}
fn remove(&mut self, index: SlotKey) {
Endpoint::remove(self, index)
}
fn entry(&mut self, index: SlotKey) -> Option<Entry> {
Endpoint::entry(self, index)
}
fn find_tuple(&mut self, tuple: FourTuple) -> Option<Entry> {
if self.ports.entry(tuple).occupied().is_some() {
Endpoint::entry_from_tuple(self, tuple)
} else {
Endpoint::entry_from_tuple(self, FourTuple {
local: tuple.local,
local_port: tuple.local_port,
remote: Address::Unspecified,
remote_port: 0,
})
}
}
fn source_port(&mut self, _: Address) -> Option<u16> {
Some(80)
}
fn listen(&mut self, ip: Address, port: u16) -> Option<SlotKey> {
Endpoint::listen(self, ip, port)
}
fn open(&mut self, tuple: FourTuple) -> Option<SlotKey> {
Endpoint::open(self, tuple)
}
fn initial_seq_num(&mut self, id: FourTuple, time: Instant) -> SeqNumber {
Endpoint::initial_seq_num(self, id, time)
}
}
impl PortMap for Map<'_, FourTuple, Key> {
fn remap(&mut self, old: FourTuple, new: FourTuple) {
let old = self.entry(old)
.occupied()
.unwrap();
let value = *old.get();
old.remove();
self.entry(new)
.vacant()
.unwrap()
.insert(value);
}
}
impl<H, P> ip::Recv<P> for Receiver<'_, '_, H>
where
P: PayloadMut,
H: super::Recv<P>,
{
fn receive(&mut self, ip_packet: ip::InPacket<P>) {
let ip::InPacket { mut control, packet } = ip_packet;
let repr = packet.repr();
let capabilities = control.info().capabilities();
let checksum = capabilities.tcp().rx_checksum(repr);
let packet = match TcpPacket::new_checked(packet, checksum) {
Ok(packet) => packet,
Err(_) => return (),
};
let arrived = match In::from_arriving(self.endpoint.inner, control.borrow_mut(), packet) {
Ok(arrived) => arrived,
Err(_) => return (),
};
self.handler.receive(arrived)
}
}
impl<H, P> ip::Send<P> for Sender<'_, '_, H>
where
P: PayloadMut,
H: super::Send<P>,
{
fn send(&mut self, ip_raw: ip::RawPacket<P>) {
let ip::RawPacket { mut control, payload } = ip_raw;
let raw = Raw {
ip: ip::RawPacket { control: control.borrow_mut(), payload },
endpoint: self.endpoint.inner,
};
self.handler.send(raw)
}
}