summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Hall-Andersen <mathias@hall-andersen.dk>2019-08-10 17:09:02 +0200
committerMathias Hall-Andersen <mathias@hall-andersen.dk>2019-08-10 17:09:02 +0200
commit0e169012616a9b347a4e946fd4486c03ceb05658 (patch)
treee98e5d49d576dac7ed129b1a69ca766e6e83a5bd
parentKill GC thread on Ratelimiter drop (diff)
downloadwireguard-rs-0e169012616a9b347a4e946fd4486c03ceb05658.tar.xz
wireguard-rs-0e169012616a9b347a4e946fd4486c03ceb05658.zip
Work on sketching router interface
-rw-r--r--src/mod.rs1
-rw-r--r--src/router/buffer.rs76
-rw-r--r--src/router/device.rs104
-rw-r--r--src/router/mod.rs2
4 files changed, 183 insertions, 0 deletions
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<T> {
+ buf : [ Option<T> ; BUFFER_SIZE],
+ idx : usize,
+ next : usize
+}
+
+impl <T>DiscardingRingBuffer<T> 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<T> {
+ 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<usize>) {
+ let mut buf = DiscardingRingBuffer<usize>::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<PeerRef> {
+ 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