diff --git a/flake.lock b/flake.lock index 7a5770d..8eb84e1 100644 --- a/flake.lock +++ b/flake.lock @@ -5,11 +5,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1681202837, - "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "lastModified": 1685518550, + "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", "owner": "numtide", "repo": "flake-utils", - "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", "type": "github" }, "original": { @@ -38,11 +38,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1684922889, - "narHash": "sha256-l0WZAmln8959O7RdYUJ3gnAIM9OPKFLKHKGX4q+Blrk=", + "lastModified": 1686921029, + "narHash": "sha256-J1bX9plPCFhTSh6E3TWn9XSxggBh/zDD4xigyaIQBy8=", "owner": "nixos", "repo": "nixpkgs", - "rev": "04aaf8511678a0d0f347fdf1e8072fe01e4a509e", + "rev": "c7ff1b9b95620ce8728c0d7bd501c458e6da9e04", "type": "github" }, "original": { @@ -54,11 +54,11 @@ }, "nixpkgs-unstable": { "locked": { - "lastModified": 1684844536, - "narHash": "sha256-M7HhXYVqAuNb25r/d3FOO0z4GxPqDIZp5UjHFbBgw0Q=", + "lastModified": 1686960236, + "narHash": "sha256-AYCC9rXNLpUWzD9hm+askOfpliLEC9kwAo7ITJc4HIw=", "owner": "nixos", "repo": "nixpkgs", - "rev": "d30264c2691128adc261d7c9388033645f0e742b", + "rev": "04af42f3b31dba0ef742d254456dc4c14eedac86", "type": "github" }, "original": { @@ -98,11 +98,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1684894917, - "narHash": "sha256-kwKCfmliHIxKuIjnM95TRcQxM/4AAEIZ+4A9nDJ6cJs=", + "lastModified": 1687055571, + "narHash": "sha256-UvLoO6u5n9TzY80BpM4DaacxvyJl7u9mm9CA72d309g=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "9ea38d547100edcf0da19aaebbdffa2810585495", + "rev": "2de557c780dcb127128ae987fca9d6c2b0d7dc0f", "type": "github" }, "original": { diff --git a/src/connection/handshake/tracker.rs b/src/connection/handshake/tracker.rs index aaa1163..5da29bb 100644 --- a/src/connection/handshake/tracker.rs +++ b/src/connection/handshake/tracker.rs @@ -5,7 +5,7 @@ use crate::{ connection::{ self, handshake::{self, Error, Handshake}, - Connection, IDRecv, IDSend, + Conn, IDRecv, IDSend, }, enc::{ self, @@ -29,7 +29,7 @@ pub(crate) type ConnectAnswer = Result<(KeyID, IDSend), crate::Error>; pub(crate) struct HandshakeClient { pub service_id: ServiceID, pub service_conn_id: IDRecv, - pub connection: Connection, + pub connection: Conn, pub timeout: Option<::tokio::task::JoinHandle<()>>, pub answer: oneshot::Sender, pub srv_key_id: KeyID, @@ -79,7 +79,7 @@ impl HandshakeClientList { pub_key: PubKey, service_id: ServiceID, service_conn_id: IDRecv, - connection: Connection, + connection: Conn, answer: oneshot::Sender, srv_key_id: KeyID, ) -> Result<(KeyID, &mut HandshakeClient), oneshot::Sender> @@ -144,8 +144,8 @@ pub(crate) struct ClientConnectInfo { pub service_connection_id: IDRecv, /// Parsed handshake packet pub handshake: Handshake, - /// Connection - pub connection: Connection, + /// Conn + pub connection: Conn, /// where to wake up the waiting client pub answer: oneshot::Sender, /// server public key id that we used on the handshake @@ -233,7 +233,7 @@ impl HandshakeTracker { pub_key: PubKey, service_id: ServiceID, service_conn_id: IDRecv, - connection: Connection, + connection: Conn, answer: oneshot::Sender, srv_key_id: KeyID, ) -> Result<(KeyID, &mut HandshakeClient), oneshot::Sender> diff --git a/src/connection/mod.rs b/src/connection/mod.rs index 45a50e9..2889381 100644 --- a/src/connection/mod.rs +++ b/src/connection/mod.rs @@ -3,13 +3,11 @@ pub mod handshake; pub mod packet; pub mod socket; +pub mod stream; use ::std::{rc::Rc, vec::Vec}; -pub use crate::connection::{ - handshake::Handshake, - packet::{ConnectionID as ID, Packet, PacketData}, -}; +pub use crate::connection::{handshake::Handshake, packet::Packet}; use crate::{ dnssec, @@ -21,12 +19,93 @@ use crate::{ }, inner::ThreadTracker, }; +use ::std::rc; + +/// Fenrir Connection ID +/// +/// 0 is special as it represents the handshake +/// Connection IDs are to be considered u64 little endian +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub enum ID { + /// Connection id 0 represent the handshake + Handshake, + /// Non-zero id can represent any connection + ID(::core::num::NonZeroU64), +} + +impl ID { + /// Set the conenction id to handshake + pub fn new_handshake() -> Self { + Self::Handshake + } + /// New id from u64. PLZ NON ZERO + pub(crate) fn new_u64(raw: u64) -> Self { + #[allow(unsafe_code)] + unsafe { + ID::ID(::core::num::NonZeroU64::new_unchecked(raw)) + } + } + pub(crate) fn as_u64(&self) -> u64 { + match self { + ID::Handshake => 0, + ID::ID(id) => id.get(), + } + } + /// New random service ID + pub fn new_rand(rand: &Random) -> Self { + let mut raw = [0; 8]; + let mut num = 0; + while num == 0 { + rand.fill(&mut raw); + num = u64::from_le_bytes(raw); + } + #[allow(unsafe_code)] + unsafe { + ID::ID(::core::num::NonZeroU64::new_unchecked(num)) + } + } + /// Quick check to know if this is an handshake + pub fn is_handshake(&self) -> bool { + *self == ID::Handshake + } + /// length if the connection ID in bytes + pub const fn len() -> usize { + 8 + } + /// write the ID to a buffer + pub fn serialize(&self, out: &mut [u8]) { + match self { + ID::Handshake => out[..8].copy_from_slice(&[0; 8]), + ID::ID(id) => out[..8].copy_from_slice(&id.get().to_le_bytes()), + } + } +} + +impl From for ID { + fn from(raw: u64) -> Self { + if raw == 0 { + ID::Handshake + } else { + #[allow(unsafe_code)] + unsafe { + ID::ID(::core::num::NonZeroU64::new_unchecked(raw)) + } + } + } +} + +impl From<[u8; 8]> for ID { + fn from(raw: [u8; 8]) -> Self { + let raw_u64 = u64::from_le_bytes(raw); + raw_u64.into() + } +} /// strong typedef for receiving connection id -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct IDRecv(pub ID); /// strong typedef for sending connection id -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct IDSend(pub ID); /// Version of the fenrir protocol in use @@ -47,12 +126,16 @@ impl ProtocolVersion { } } +/// The connection, as seen from a user of libFenrir +#[derive(Debug)] +pub struct Connection(rc::Weak); + /// A single connection and its data #[derive(Debug)] -pub struct Connection { - /// Receiving Connection ID +pub(crate) struct Conn { + /// Receiving Conn ID pub id_recv: IDRecv, - /// Sending Connection ID + /// Sending Conn ID pub id_send: IDSend, /// The main hkdf used for all secrets in this connection pub hkdf: Hkdf, @@ -62,9 +145,12 @@ pub struct Connection { pub cipher_send: CipherSend, } -/// Role: used to set the correct secrets -/// * Server: Connection is Incoming -/// * Client: Connection is Outgoing +/// Role: track the connection direction +/// +/// The Role is used to select the correct secrets, and track the direction +/// of the connection +/// * Server: Conn is Incoming +/// * Client: Conn is Outgoing #[derive(Debug, Copy, Clone)] #[repr(u8)] pub enum Role { @@ -74,7 +160,7 @@ pub enum Role { Client, } -impl Connection { +impl Conn { pub(crate) fn new( hkdf: Hkdf, cipher: CipherKind, @@ -102,11 +188,9 @@ impl Connection { } } -// PERF: Arc> loks a bit too much, need to find -// faster ways to do this pub(crate) struct ConnList { thread_id: ThreadTracker, - connections: Vec>>, + connections: Vec>>, /// Bitmap to track which connection ids are used or free ids_used: Vec<::bitmaps::Bitmap<1024>>, } @@ -177,7 +261,7 @@ impl ConnList { new_id } /// NOTE: does NOT check if the connection has been previously reserved! - pub(crate) fn track(&mut self, conn: Rc) -> Result<(), ()> { + pub(crate) fn track(&mut self, conn: Rc) -> Result<(), ()> { let conn_id = match conn.id_recv { IDRecv(ID::Handshake) => { return Err(()); diff --git a/src/connection/packet.rs b/src/connection/packet.rs index 925460c..545c882 100644 --- a/src/connection/packet.rs +++ b/src/connection/packet.rs @@ -1,107 +1,26 @@ // //! Raw packet handling, encryption, decryption, parsing -use crate::enc::{ - sym::{HeadLen, TagLen}, - Random, +use crate::{ + connection, + enc::sym::{HeadLen, TagLen}, }; -/// Fenrir Connection id -/// 0 is special as it represents the handshake -/// Connection IDs are to be considered u64 little endian -#[derive(Debug, Copy, Clone, PartialEq)] -pub enum ConnectionID { - /// Connection id 0 represent the handshake - Handshake, - /// Non-zero id can represent any connection - ID(::core::num::NonZeroU64), -} - -impl ConnectionID { - /// Set the conenction id to handshake - pub fn new_handshake() -> Self { - Self::Handshake - } - /// New id from u64. PLZ NON ZERO - pub(crate) fn new_u64(raw: u64) -> Self { - #[allow(unsafe_code)] - unsafe { - ConnectionID::ID(::core::num::NonZeroU64::new_unchecked(raw)) - } - } - pub(crate) fn as_u64(&self) -> u64 { - match self { - ConnectionID::Handshake => 0, - ConnectionID::ID(id) => id.get(), - } - } - /// New random service ID - pub fn new_rand(rand: &Random) -> Self { - let mut raw = [0; 8]; - let mut num = 0; - while num == 0 { - rand.fill(&mut raw); - num = u64::from_le_bytes(raw); - } - #[allow(unsafe_code)] - unsafe { - ConnectionID::ID(::core::num::NonZeroU64::new_unchecked(num)) - } - } - /// Quick check to know if this is an handshake - pub fn is_handshake(&self) -> bool { - *self == ConnectionID::Handshake - } - /// length if the connection ID in bytes - pub const fn len() -> usize { - 8 - } - /// write the ID to a buffer - pub fn serialize(&self, out: &mut [u8]) { - match self { - ConnectionID::Handshake => out[..8].copy_from_slice(&[0; 8]), - ConnectionID::ID(id) => { - out[..8].copy_from_slice(&id.get().to_le_bytes()) - } - } - } -} - -impl From for ConnectionID { - fn from(raw: u64) -> Self { - if raw == 0 { - ConnectionID::Handshake - } else { - #[allow(unsafe_code)] - unsafe { - ConnectionID::ID(::core::num::NonZeroU64::new_unchecked(raw)) - } - } - } -} - -impl From<[u8; 8]> for ConnectionID { - fn from(raw: [u8; 8]) -> Self { - let raw_u64 = u64::from_le_bytes(raw); - raw_u64.into() - } -} - /// Enumerate the possible data in a fenrir packet #[derive(Debug, Clone)] -pub enum PacketData { +pub enum Data { /// A parsed handshake packet Handshake(super::Handshake), /// Raw packet. we only have the connection ID and packet length Raw(usize), } -impl PacketData { +impl Data { /// total length of the data in bytes pub fn len(&self, head_len: HeadLen, tag_len: TagLen) -> usize { match self { - PacketData::Handshake(h) => h.len(head_len, tag_len), - PacketData::Raw(len) => *len, + Data::Handshake(h) => h.len(head_len, tag_len), + Data::Raw(len) => *len, } } /// serialize data into bytes @@ -114,12 +33,12 @@ impl PacketData { ) { assert!( self.len(head_len, tag_len) == out.len(), - "PacketData: wrong buffer length" + "Data: wrong buffer length" ); match self { - PacketData::Handshake(h) => h.serialize(head_len, tag_len, out), - PacketData::Raw(_) => { - ::tracing::error!("Tried to serialize a raw PacketData!"); + Data::Handshake(h) => h.serialize(head_len, tag_len, out), + Data::Raw(_) => { + ::tracing::error!("Tried to serialize a raw Data!"); } } } @@ -131,9 +50,9 @@ const MIN_PACKET_BYTES: usize = 16; #[derive(Debug, Clone)] pub struct Packet { /// Id of the Fenrir connection. - pub id: ConnectionID, + pub id: connection::ID, /// actual data inside the packet - pub data: PacketData, + pub data: Data, } impl Packet { @@ -146,12 +65,12 @@ impl Packet { let raw_id: [u8; 8] = (raw[..8]).try_into().expect("unreachable"); Ok(Packet { id: raw_id.into(), - data: PacketData::Raw(raw.len()), + data: Data::Raw(raw.len()), }) } /// get the total length of the packet pub fn len(&self, head_len: HeadLen, tag_len: TagLen) -> usize { - ConnectionID::len() + self.data.len(head_len, tag_len) + connection::ID::len() + self.data.len(head_len, tag_len) } /// serialize packet into buffer /// NOTE: assumes that there is exactly asa much buffer as needed @@ -162,11 +81,14 @@ impl Packet { out: &mut [u8], ) { assert!( - out.len() > ConnectionID::len(), + out.len() > connection::ID::len(), "Packet: not enough buffer to serialize" ); - self.id.serialize(&mut out[0..ConnectionID::len()]); - self.data - .serialize(head_len, tag_len, &mut out[ConnectionID::len()..]); + self.id.serialize(&mut out[0..connection::ID::len()]); + self.data.serialize( + head_len, + tag_len, + &mut out[connection::ID::len()..], + ); } } diff --git a/src/connection/stream/errors.rs b/src/connection/stream/errors.rs new file mode 100644 index 0000000..133d976 --- /dev/null +++ b/src/connection/stream/errors.rs @@ -0,0 +1,10 @@ +//! Errors while parsing streams + + +/// Crypto errors +#[derive(::thiserror::Error, Debug, Copy, Clone)] +pub enum Error { + /// Error while parsing key material + #[error("Not enough data for stream chunk: {0}")] + NotEnoughData(usize), +} diff --git a/src/connection/stream/mod.rs b/src/connection/stream/mod.rs new file mode 100644 index 0000000..1b56a2b --- /dev/null +++ b/src/connection/stream/mod.rs @@ -0,0 +1,183 @@ +//! Here we implement the multiplexing stream feature of Fenrir +//! +//! For now we will only have the TCP-like, reliable, in-order delivery + +mod errors; +mod rob; +pub use errors::Error; + +use crate::{connection::stream::rob::ReliableOrderedBytestream, enc::Random}; + +/// Kind of stream. any combination of: +/// reliable/unreliable ordered/unordered, bytestream/datagram +#[derive(Debug, Copy, Clone)] +#[repr(u8)] +pub enum Kind { + /// ROB: Reliable, Ordered, Bytestream + /// AKA: TCP-like + ROB = 0, +} + +/// Id of the stream +#[derive(Debug, Copy, Clone)] +pub struct ID(pub u16); + +impl ID { + /// Length of the serialized field + pub const fn len() -> usize { + 2 + } +} + +/// length of the chunk +#[derive(Debug, Copy, Clone)] +pub struct ChunkLen(pub u16); + +impl ChunkLen { + /// Length of the serialized field + pub const fn len() -> usize { + 2 + } +} + +/// Sequence number to rebuild the stream correctly +#[derive(Debug, Copy, Clone)] +pub struct Sequence(pub ::core::num::Wrapping); + +impl Sequence { + const SEQ_NOFLAG: u32 = 0x3FFFFFFF; + /// return a new sequence number, starting at random + pub fn new(rand: &Random) -> Self { + let seq: u32 = 0; + rand.fill(&mut seq.to_le_bytes()); + Self(::core::num::Wrapping(seq & Self::SEQ_NOFLAG)) + } + /// Length of the serialized field + pub const fn len() -> usize { + 4 + } +} + +/// Chunk of data representing a stream +/// Every chunk is as follows: +/// | id (2 bytes) | length (2 bytes) | +/// | flag_start (1 BIT) | flag_end (1 BIT) | sequence (30 bits) | +#[derive(Debug, Clone)] +pub struct Chunk<'a> { + /// Id of the stream this chunk is part of + pub id: ID, + /// Is this the beginning of a message? + pub flag_start: bool, + /// Is this the end of a message? + pub flag_end: bool, + /// Sequence number to reconstruct the Stream + pub sequence: Sequence, + data: &'a [u8], +} + +impl<'a> Chunk<'a> { + const FLAGS_EXCLUDED_BITMASK: u8 = 0x3F; + const FLAG_START_BITMASK: u8 = 0x80; + const FLAG_END_BITMASK: u8 = 0x40; + /// Returns the total length of the chunk, including headers + pub fn len(&self) -> usize { + ID::len() + ChunkLen::len() + Sequence::len() + self.data.len() + } + /// deserialize a chunk of a stream + pub fn deserialize(raw: &'a [u8]) -> Result { + if raw.len() <= ID::len() + ChunkLen::len() + Sequence::len() { + return Err(Error::NotEnoughData(0)); + } + + let id = ID(u16::from_le_bytes(raw[0..ID::len()].try_into().unwrap())); + + let mut bytes_next = ID::len() + ChunkLen::len(); + let length = ChunkLen(u16::from_le_bytes( + raw[ID::len()..bytes_next].try_into().unwrap(), + )); + if ID::len() + ChunkLen::len() + Sequence::len() + length.0 as usize + > raw.len() + { + return Err(Error::NotEnoughData(4)); + } + + let flag_start = (raw[bytes_next] & Self::FLAG_START_BITMASK) != 0; + let flag_end = (raw[bytes_next] & Self::FLAG_END_BITMASK) != 0; + + let bytes = bytes_next + 1; + bytes_next = bytes + Sequence::len(); + let mut sequence_bytes: [u8; Sequence::len()] = + raw[bytes..bytes_next].try_into().unwrap(); + sequence_bytes[0] = sequence_bytes[0] & Self::FLAGS_EXCLUDED_BITMASK; + let sequence = + Sequence(::core::num::Wrapping(u32::from_le_bytes(sequence_bytes))); + + Ok(Self { + id, + flag_start, + flag_end, + sequence, + data: &raw[bytes_next..(bytes_next + length.0 as usize)], + }) + } + /// serialize a chunk of a stream + pub fn serialize(&self, raw_out: &mut [u8]) { + raw_out[0..ID::len()].copy_from_slice(&self.id.0.to_le_bytes()); + let mut bytes_next = ID::len() + ChunkLen::len(); + raw_out[ID::len()..bytes_next] + .copy_from_slice(&(self.data.len() as u16).to_le_bytes()); + let bytes = bytes_next; + bytes_next = bytes_next + Sequence::len(); + raw_out[bytes..bytes_next] + .copy_from_slice(&self.sequence.0 .0.to_le_bytes()); + let mut flag_byte = raw_out[bytes] & Self::FLAGS_EXCLUDED_BITMASK; + if self.flag_start { + flag_byte = flag_byte | Self::FLAG_START_BITMASK; + } + if self.flag_end { + flag_byte = flag_byte | Self::FLAG_END_BITMASK; + } + raw_out[bytes] = flag_byte; + let bytes = bytes_next; + bytes_next = bytes_next + self.data.len(); + raw_out[bytes..bytes_next].copy_from_slice(&self.data); + } +} + +/// Kind of stream. any combination of: +/// reliable/unreliable ordered/unordered, bytestream/datagram +/// differences from Kind: +/// * not public +/// * has actual data +#[derive(Debug, Clone)] +pub(crate) enum Tracker { + /// ROB: Reliable, Ordered, Bytestream + /// AKA: TCP-like + ROB(ReliableOrderedBytestream), +} + +impl Tracker { + pub(crate) fn new(kind: Kind, rand: &Random) -> Self { + match kind { + Kind::ROB => Tracker::ROB(ReliableOrderedBytestream::new(rand)), + } + } +} + +/// Actual stream-tracking structure +#[derive(Debug, Clone)] +pub(crate) struct Stream { + id: ID, + data: Tracker, +} + +impl Stream { + pub(crate) fn new(kind: Kind, rand: &Random) -> Self { + let id: u16 = 0; + rand.fill(&mut id.to_le_bytes()); + Self { + id: ID(id), + data: Tracker::new(kind, rand), + } + } +} diff --git a/src/connection/stream/rob.rs b/src/connection/stream/rob.rs new file mode 100644 index 0000000..5d28f59 --- /dev/null +++ b/src/connection/stream/rob.rs @@ -0,0 +1,29 @@ +//! Implementation of the Reliable, Ordered, Bytestream transmission model +//! AKA: TCP-like + +use crate::{ + connection::stream::{Chunk, Error, Sequence}, + enc::Random, +}; + +/// Reliable, Ordered, Bytestream stream tracker +/// AKA: TCP-like +#[derive(Debug, Clone)] +pub(crate) struct ReliableOrderedBytestream { + window_start: Sequence, + window_len: usize, + data: Vec, +} + +impl ReliableOrderedBytestream { + pub(crate) fn new(rand: &Random) -> Self { + Self { + window_start: Sequence::new(rand), + window_len: 1048576, // 1MB. should be enough for anybody. (lol) + data: Vec::new(), + } + } + pub(crate) fn recv(&mut self, chunk: Chunk) -> Result<(), Error> { + todo!() + } +} diff --git a/src/inner/worker.rs b/src/inner/worker.rs index 083a9ac..cdd5d75 100644 --- a/src/inner/worker.rs +++ b/src/inner/worker.rs @@ -10,8 +10,9 @@ use crate::{ tracker::{HandshakeAction, HandshakeTracker}, Handshake, HandshakeData, }, + packet::{self, Packet}, socket::{UdpClient, UdpServer}, - ConnList, Connection, IDSend, Packet, + Conn, ConnList, IDSend, }, dnssec, enc::{ @@ -125,6 +126,7 @@ impl Worker { handshakes, }) } + /// Continuously loop and process work as needed pub async fn work_loop(&mut self) { 'mainloop: loop { @@ -292,7 +294,7 @@ impl Worker { // are PubKey::Exchange unreachable!() } - let mut conn = Connection::new( + let mut conn = Conn::new( hkdf, cipher_selected, connection::Role::Client, @@ -345,7 +347,8 @@ impl Worker { exchange_key: pub_key, data: dirsync::ReqInner::ClearText(req_data), }; - let encrypt_start = ID::len() + req.encrypted_offset(); + let encrypt_start = + connection::ID::len() + req.encrypted_offset(); let encrypt_end = encrypt_start + req.encrypted_length( cipher_selected.nonce_len(), @@ -354,10 +357,9 @@ impl Worker { let h_req = Handshake::new(HandshakeData::DirSync( DirSync::Req(req), )); - use connection::{PacketData, ID}; let packet = Packet { - id: ID::Handshake, - data: PacketData::Handshake(h_req), + id: connection::ID::Handshake, + data: packet::Data::Handshake(h_req), }; let tot_len = packet.len( @@ -510,12 +512,12 @@ impl Worker { // Client has correctly authenticated // TODO: contact the service, get the key and // connection ID - let srv_conn_id = ID::new_rand(&self.rand); + let srv_conn_id = connection::ID::new_rand(&self.rand); let srv_secret = Secret::new_rand(&self.rand); let head_len = req.cipher.nonce_len(); let tag_len = req.cipher.tag_len(); - let mut auth_conn = Connection::new( + let mut auth_conn = Conn::new( authinfo.hkdf, req.cipher, connection::Role::Server, @@ -541,16 +543,16 @@ impl Worker { client_key_id: req_data.client_key_id, data: RespInner::ClearText(resp_data), }; - let encrypt_from = ID::len() + resp.encrypted_offset(); + let encrypt_from = + connection::ID::len() + resp.encrypted_offset(); let encrypt_until = encrypt_from + resp.encrypted_length(head_len, tag_len); let resp_handshake = Handshake::new( HandshakeData::DirSync(DirSync::Resp(resp)), ); - use connection::{PacketData, ID}; let packet = Packet { - id: ID::new_handshake(), - data: PacketData::Handshake(resp_handshake), + id: connection::ID::new_handshake(), + data: packet::Data::Handshake(resp_handshake), }; let tot_len = packet.len(head_len, tag_len); let mut raw_out = Vec::::with_capacity(tot_len); @@ -611,7 +613,7 @@ impl Worker { cci.service_id.as_bytes(), resp_data.service_key, ); - let mut service_connection = Connection::new( + let mut service_connection = Conn::new( hkdf, cipher, connection::Role::Client, diff --git a/src/lib.rs b/src/lib.rs index fbca09a..57da614 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,6 +39,7 @@ use crate::{ }, }; pub use config::Config; +pub use connection::Connection; /// Main fenrir library errors #[derive(::thiserror::Error, Debug)] @@ -332,7 +333,7 @@ impl Fenrir { let data: Vec = buffer[..bytes].to_vec(); // we very likely have multiple threads, pinned to different cpus. - // use the ConnectionID to send the same connection + // use the connection::ID to send the same connection // to the same thread. // Handshakes have connection ID 0, so we use the sender's UDP port @@ -341,13 +342,12 @@ impl Fenrir { Err(_) => continue, // packet way too short, ignore. }; let thread_idx: usize = { - use connection::packet::ConnectionID; match packet.id { - ConnectionID::Handshake => { + connection::ID::Handshake => { let send_port = sock_sender.0.port() as u64; (send_port % queues_num) as usize } - ConnectionID::ID(id) => (id.get() % queues_num) as usize, + connection::ID::ID(id) => (id.get() % queues_num) as usize, } }; let _ = work_queues[thread_idx]