From 0e169012616a9b347a4e946fd4486c03ceb05658 Mon Sep 17 00:00:00 2001 From: Mathias Hall-Andersen Date: Sat, 10 Aug 2019 17:09:02 +0200 Subject: Work on sketching router interface --- src/mod.rs | 1 + src/router/buffer.rs | 76 +++++++++++++++++++++++++++++++++++++ src/router/device.rs | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/router/mod.rs | 2 + 4 files changed, 183 insertions(+) create mode 100644 src/router/buffer.rs create mode 100644 src/router/device.rs create mode 100644 src/router/mod.rs (limited to 'src') diff --git a/src/mod.rs b/src/mod.rs index dd3d99f..1829e6e 100644 --- a/src/mod.rs +++ b/src/mod.rs @@ -1,2 +1,3 @@ mod noise; mod types; +mod router; \ No newline at end of file diff --git a/src/router/buffer.rs b/src/router/buffer.rs new file mode 100644 index 0000000..3f348ea --- /dev/null +++ b/src/router/buffer.rs @@ -0,0 +1,76 @@ +/* Ring buffer implementing the WireGuard queuing semantics: + * + * 1. A fixed sized buffer + * 2. Inserting into the buffer always succeeds, but might overwrite the oldest item + */ + +const BUFFER_SIZE : usize = 1024; + +pub struct DiscardingRingBuffer { + buf : [ Option ; BUFFER_SIZE], + idx : usize, + next : usize +} + +impl DiscardingRingBuffer where T: Copy { + pub fn new() -> Self { + DiscardingRingBuffer{ + buf : [None; BUFFER_SIZE], + idx : 0, + next : 0 + } + } + + pub fn empty(&mut self) { + self.next = 0; + self.idx = 0; + for i in 1..BUFFER_SIZE { + self.buf[i] = None; + } + } + + pub fn push(&mut self, val : T) { + // assign next slot (free / oldest) + self.buf[self.idx] = Some(val); + self.idx += 1; + self.idx %= BUFFER_SIZE; + + // check for wrap-around + if self.idx == self.next { + self.next += 1; + self.next %= BUFFER_SIZE; + } + } + + pub fn consume(&mut self) -> Option { + match self.buf[self.next] { + None => None, + some => { + self.buf[self.next] = None; + self.next += 1; + self.next %= BUFFER_SIZE; + some + } + } + } + + pub fn has_element(&self) -> bool { + match self.buf[self.next] { + None => true, + _ => false + } + } +} + + +proptest! { + #[test] + fn test_order(elems: Vec) { + let mut buf = DiscardingRingBuffer::new(); + + for e in &elems { + buf.push(e); + } + + } +} \ No newline at end of file diff --git a/src/router/device.rs b/src/router/device.rs new file mode 100644 index 0000000..67702cd --- /dev/null +++ b/src/router/device.rs @@ -0,0 +1,104 @@ +use std::net::SocketAddr; +use super::super::types::KeyPair; + +pub struct Device { + +} + +pub struct Peer { + +} + +pub struct PeerRef {} + +impl Device { + + pub fn new() -> Device { + unimplemented!(); + } + + /// Adds a new peer to the device + /// + /// # Returns + /// + /// An opaque value representing the peer. + pub fn add(&self) -> PeerRef { + unimplemented!(); + } + + /// Cryptkey routes and sends a plaintext message (IP packet) + /// + /// # Arguments + /// + /// - pt_msg: IP packet to cryptkey route + /// + /// # Returns + /// + /// A peer reference for the peer if no key-pair is currently valid for the destination. + /// This indicates that a handshake should be initated (see the handshake module). + /// If this occurs the packet is copied to an internal buffer + /// and retransmission can be attempted using send_run_queue + pub fn send(&self, pt_msg: &mut [u8]) -> Option { + unimplemented!(); + } + + /// Sends a message directly to the peer. + /// The router device takes care of discovering/managing the endpoint. + /// This is used for handshake initiation/response messages + /// + /// # Arguments + /// + /// - peer: Reference to the destination peer + /// - msg: Message to transmit + pub fn send_raw(&self, peer: PeerRef, msg: &mut [u8]) { + unimplemented!(); + } + + + /// Flush the queue of buffered messages awaiting transmission + /// + /// # Arguments + /// + /// - peer: Reference for the peer to flush + pub fn flush_queue(&self, peer: PeerRef) { + unimplemented!(); + } + + /// Attempt to route, encrypt and send all elements buffered in the queue + /// + /// # Arguments + /// + /// # Returns + /// + /// A boolean indicating whether packages where sent. + /// Note: This is used for implicit confirmation of handshakes. + pub fn send_run_queue(&self, peer: PeerRef) -> bool { + unimplemented!(); + } + + /// Receive an encrypted transport message + /// + /// # Arguments + /// + /// - ct_msg: Encrypted transport message + pub fn recv(&self, ct_msg: &mut [u8]) { + unimplemented!(); + } + + /// Returns the current endpoint known for the peer + /// + /// # Arguments + /// + /// - peer: The peer to retrieve the endpoint for + pub fn get_endpoint(&self, peer: PeerRef) -> SocketAddr { + unimplemented!(); + } + + pub fn set_endpoint(&self, peer: PeerRef, endpoint: SocketAddr) { + unimplemented!(); + } + + pub fn new_keypair(&self, peer: PeerRef, keypair: KeyPair) { + unimplemented!(); + } +} \ No newline at end of file diff --git a/src/router/mod.rs b/src/router/mod.rs new file mode 100644 index 0000000..4d29220 --- /dev/null +++ b/src/router/mod.rs @@ -0,0 +1,2 @@ +mod buffer; +pub mod device; \ No newline at end of file -- cgit v1.2.3-59-g8ed1b