From c1dfc848c48978603fe801737a07b16cb0a9c1a3 Mon Sep 17 00:00:00 2001 From: Mathias Hall-Andersen Date: Sun, 14 Jun 2020 21:57:35 +0200 Subject: [PATCH] Added architecture illustration. --- README.md | 24 +++++++++++---- architecture.svg | 3 ++ src/wireguard/router/device.rs | 24 +++++++-------- src/wireguard/router/peer.rs | 55 ++++++++++++++++------------------ 4 files changed, 58 insertions(+), 48 deletions(-) create mode 100644 architecture.svg diff --git a/README.md b/README.md index fc84364..86863c2 100644 --- a/README.md +++ b/README.md @@ -32,11 +32,25 @@ Coming soon. Coming soon. -# Building +## Building -The wireguard-rs project is targeting the current nightly. -To build this project obtain nightly `cargo` and `rustc` through [rustup](https://rustup.rs/), then simply run: +The wireguard-rs project is targeting the current nightly (although it should also build with stable Rust). - cargo build --release +To build wireguard-rs (on supported platforms): -To compile wireguard-rs to your current platform. +1. Obtain nightly `cargo` and `rustc` through [rustup](https://rustup.rs/) +2. Clone the repository: `git clone https://git.zx2c4.com/wireguard-rs`. +3. Run `cargo build --release` from inside the `wireguard-rs` directory. + +## Architecture + +This section is intended for those wishing to read/contribute to the code. + +WireGuard Rust has a similar separation of concerns as many other implementations of various cryptographic transports: +separating the handshake code from the packet protector. +The handshake module implements an authenticated key-exchange (NoiseIK), +which provides key-material, which is then consumed by the router module (packet protector) +responsible for the actual encapsulation of transport messages (IP packets). +This is illustrated below: + +![Structure](architecture.svg) diff --git a/architecture.svg b/architecture.svg new file mode 100644 index 0000000..f62ca07 --- /dev/null +++ b/architecture.svg @@ -0,0 +1,3 @@ + + +
Handshake Module
Handshake Module
Router Module
Router Module
Timers
Timers
Key Material
Key Material
Request New Handshake
Request New Ha...
Send / Recv Events
Send / Recv Even...
WireGuard Module
WireGuard Module
Packet Demultiplexer
Packet Demultiplexer
Hanshake Messages
Hanshake Messa...
Transport Messages
Transport Mess...
TUN Device
TUN Device
Internet
Internet
Read UDP Datagram
Read UDP Datagram
Write IP Packet
Write IP Pa...
Internet
Internet
Internet
Internet
Write UDP Datagram
Write UDP D...
Write UDP Datagram
Write UDP D...
Read IP Packet
Read IP Pac...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/src/wireguard/router/device.rs b/src/wireguard/router/device.rs index 7c90f22..1a12abb 100644 --- a/src/wireguard/router/device.rs +++ b/src/wireguard/router/device.rs @@ -26,31 +26,29 @@ use super::ParallelQueue; pub struct DeviceInner> { // inbound writer (TUN) - pub inbound: T, + pub(super) inbound: T, // outbound writer (Bind) - pub outbound: RwLock<(bool, Option)>, + pub(super) outbound: RwLock<(bool, Option)>, // routing - pub recv: RwLock>>>, // receiver id -> decryption state - pub table: RoutingTable>, + pub(super) recv: RwLock>>>, // receiver id -> decryption state + pub(super) table: RoutingTable>, // work queue - pub work: ParallelQueue>, + pub(super) work: ParallelQueue>, } pub struct EncryptionState { - pub keypair: Arc, // keypair - pub nonce: u64, // next available nonce - pub death: Instant, // (birth + reject-after-time - keepalive-timeout - rekey-timeout) + pub(super) keypair: Arc, // keypair + pub(super) nonce: u64, // next available nonce } pub struct DecryptionState> { - pub keypair: Arc, - pub confirmed: AtomicBool, - pub protector: Mutex, - pub peer: Peer, - pub death: Instant, // time when the key can no longer be used for decryption + pub(super) keypair: Arc, + pub(super) confirmed: AtomicBool, + pub(super) protector: Mutex, + pub(super) peer: Peer, } pub struct Device> { diff --git a/src/wireguard/router/peer.rs b/src/wireguard/router/peer.rs index 8248a55..d960da0 100644 --- a/src/wireguard/router/peer.rs +++ b/src/wireguard/router/peer.rs @@ -37,16 +37,22 @@ pub struct KeyWheel { } pub struct PeerInner> { - pub device: Device, - pub opaque: C::Opaque, - pub outbound: Queue>, - pub inbound: Queue>, - pub staged_packets: Mutex; MAX_QUEUED_PACKETS], Wrapping>>, - pub keys: Mutex, - pub enc_key: Mutex>, - pub endpoint: Mutex>, + pub(super) device: Device, + pub(super) opaque: C::Opaque, + pub(super) outbound: Queue>, + pub(super) inbound: Queue>, + pub(super) staged_packets: Mutex; MAX_QUEUED_PACKETS], Wrapping>>, + pub(super) keys: Mutex, + pub(super) enc_key: Mutex>, + pub(super) endpoint: Mutex>, } +/// A Peer dereferences to its opaque type: +/// This allows the router code to take ownership of the opaque type +/// used for callback events, while still enabling the rest of the code to access the opaque type +/// (which might expose other functionality in their scope) from a Peer pointer. +/// +/// e.g. it can take ownership of the timer state of a peer. impl> Deref for PeerInner { type Target = C::Opaque; @@ -55,10 +61,20 @@ impl> Deref for Pee } } +/// A Peer represents a reference to the router state associated with a peer pub struct Peer> { inner: Arc>, } +/// A PeerHandle is a specially designated reference to the peer +/// which removes the peer from the device when dropped. +/// +/// A PeerHandle cannot be cloned (unlike the wrapped type). +/// A PeerHandle dereferences to a Peer (meaning you can use it like a Peer struct) +pub struct PeerHandle> { + peer: Peer, +} + impl> Clone for Peer { fn clone(&self) -> Self { Peer { @@ -67,7 +83,7 @@ impl> Clone for Pee } } -/* Equality of peers is defined as pointer equality +/* Equality of peers is defined as pointer equality of * the atomic reference counted pointer. */ impl> PartialEq for Peer { @@ -89,25 +105,6 @@ impl> Deref for Pee } } -/* A peer handle is a specially designated peer pointer - * which removes the peer from the device when dropped. - */ -pub struct PeerHandle> { - peer: Peer, -} - -/* -impl> Clone - for PeerHandle -{ - fn clone(&self) -> Self { - PeerHandle { - peer: self.peer.clone(), - } - } -} -*/ - impl> Deref for PeerHandle { @@ -130,7 +127,6 @@ impl EncryptionState { EncryptionState { nonce: 0, keypair: keypair.clone(), - death: keypair.birth + REJECT_AFTER_TIME, } } } @@ -141,7 +137,6 @@ impl> DecryptionSta confirmed: AtomicBool::new(keypair.initiator), keypair: keypair.clone(), protector: spin::Mutex::new(AntiReplay::new()), - death: keypair.birth + REJECT_AFTER_TIME, peer, } }