Added architecture illustration.
This commit is contained in:
24
README.md
24
README.md
@@ -32,11 +32,25 @@ Coming soon.
|
|||||||
|
|
||||||
Coming soon.
|
Coming soon.
|
||||||
|
|
||||||
# Building
|
## Building
|
||||||
|
|
||||||
The wireguard-rs project is targeting the current nightly.
|
The wireguard-rs project is targeting the current nightly (although it should also build with stable Rust).
|
||||||
To build this project obtain nightly `cargo` and `rustc` through [rustup](https://rustup.rs/), then simply run:
|
|
||||||
|
|
||||||
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:
|
||||||
|
|
||||||
|

|
||||||
|
|||||||
3
architecture.svg
Normal file
3
architecture.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 23 KiB |
@@ -26,31 +26,29 @@ use super::ParallelQueue;
|
|||||||
|
|
||||||
pub struct DeviceInner<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> {
|
pub struct DeviceInner<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> {
|
||||||
// inbound writer (TUN)
|
// inbound writer (TUN)
|
||||||
pub inbound: T,
|
pub(super) inbound: T,
|
||||||
|
|
||||||
// outbound writer (Bind)
|
// outbound writer (Bind)
|
||||||
pub outbound: RwLock<(bool, Option<B>)>,
|
pub(super) outbound: RwLock<(bool, Option<B>)>,
|
||||||
|
|
||||||
// routing
|
// routing
|
||||||
pub recv: RwLock<HashMap<u32, Arc<DecryptionState<E, C, T, B>>>>, // receiver id -> decryption state
|
pub(super) recv: RwLock<HashMap<u32, Arc<DecryptionState<E, C, T, B>>>>, // receiver id -> decryption state
|
||||||
pub table: RoutingTable<Peer<E, C, T, B>>,
|
pub(super) table: RoutingTable<Peer<E, C, T, B>>,
|
||||||
|
|
||||||
// work queue
|
// work queue
|
||||||
pub work: ParallelQueue<JobUnion<E, C, T, B>>,
|
pub(super) work: ParallelQueue<JobUnion<E, C, T, B>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EncryptionState {
|
pub struct EncryptionState {
|
||||||
pub keypair: Arc<KeyPair>, // keypair
|
pub(super) keypair: Arc<KeyPair>, // keypair
|
||||||
pub nonce: u64, // next available nonce
|
pub(super) nonce: u64, // next available nonce
|
||||||
pub death: Instant, // (birth + reject-after-time - keepalive-timeout - rekey-timeout)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DecryptionState<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> {
|
pub struct DecryptionState<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> {
|
||||||
pub keypair: Arc<KeyPair>,
|
pub(super) keypair: Arc<KeyPair>,
|
||||||
pub confirmed: AtomicBool,
|
pub(super) confirmed: AtomicBool,
|
||||||
pub protector: Mutex<AntiReplay>,
|
pub(super) protector: Mutex<AntiReplay>,
|
||||||
pub peer: Peer<E, C, T, B>,
|
pub(super) peer: Peer<E, C, T, B>,
|
||||||
pub death: Instant, // time when the key can no longer be used for decryption
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Device<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> {
|
pub struct Device<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> {
|
||||||
|
|||||||
@@ -37,16 +37,22 @@ pub struct KeyWheel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct PeerInner<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> {
|
pub struct PeerInner<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> {
|
||||||
pub device: Device<E, C, T, B>,
|
pub(super) device: Device<E, C, T, B>,
|
||||||
pub opaque: C::Opaque,
|
pub(super) opaque: C::Opaque,
|
||||||
pub outbound: Queue<SendJob<E, C, T, B>>,
|
pub(super) outbound: Queue<SendJob<E, C, T, B>>,
|
||||||
pub inbound: Queue<ReceiveJob<E, C, T, B>>,
|
pub(super) inbound: Queue<ReceiveJob<E, C, T, B>>,
|
||||||
pub staged_packets: Mutex<ArrayDeque<[Vec<u8>; MAX_QUEUED_PACKETS], Wrapping>>,
|
pub(super) staged_packets: Mutex<ArrayDeque<[Vec<u8>; MAX_QUEUED_PACKETS], Wrapping>>,
|
||||||
pub keys: Mutex<KeyWheel>,
|
pub(super) keys: Mutex<KeyWheel>,
|
||||||
pub enc_key: Mutex<Option<EncryptionState>>,
|
pub(super) enc_key: Mutex<Option<EncryptionState>>,
|
||||||
pub endpoint: Mutex<Option<E>>,
|
pub(super) endpoint: Mutex<Option<E>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> Deref for PeerInner<E, C, T, B> {
|
impl<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> Deref for PeerInner<E, C, T, B> {
|
||||||
type Target = C::Opaque;
|
type Target = C::Opaque;
|
||||||
|
|
||||||
@@ -55,10 +61,20 @@ impl<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> Deref for Pee
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A Peer represents a reference to the router state associated with a peer
|
||||||
pub struct Peer<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> {
|
pub struct Peer<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> {
|
||||||
inner: Arc<PeerInner<E, C, T, B>>,
|
inner: Arc<PeerInner<E, C, T, B>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> {
|
||||||
|
peer: Peer<E, C, T, B>,
|
||||||
|
}
|
||||||
|
|
||||||
impl<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> Clone for Peer<E, C, T, B> {
|
impl<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> Clone for Peer<E, C, T, B> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Peer {
|
Peer {
|
||||||
@@ -67,7 +83,7 @@ impl<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> 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.
|
* the atomic reference counted pointer.
|
||||||
*/
|
*/
|
||||||
impl<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> PartialEq for Peer<E, C, T, B> {
|
impl<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> PartialEq for Peer<E, C, T, B> {
|
||||||
@@ -89,25 +105,6 @@ impl<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> Deref for Pee
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A peer handle is a specially designated peer pointer
|
|
||||||
* which removes the peer from the device when dropped.
|
|
||||||
*/
|
|
||||||
pub struct PeerHandle<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> {
|
|
||||||
peer: Peer<E, C, T, B>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
impl<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> Clone
|
|
||||||
for PeerHandle<E, C, T, B>
|
|
||||||
{
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
PeerHandle {
|
|
||||||
peer: self.peer.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
impl<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> Deref
|
impl<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> Deref
|
||||||
for PeerHandle<E, C, T, B>
|
for PeerHandle<E, C, T, B>
|
||||||
{
|
{
|
||||||
@@ -130,7 +127,6 @@ impl EncryptionState {
|
|||||||
EncryptionState {
|
EncryptionState {
|
||||||
nonce: 0,
|
nonce: 0,
|
||||||
keypair: keypair.clone(),
|
keypair: keypair.clone(),
|
||||||
death: keypair.birth + REJECT_AFTER_TIME,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,7 +137,6 @@ impl<E: Endpoint, C: Callbacks, T: tun::Writer, B: udp::Writer<E>> DecryptionSta
|
|||||||
confirmed: AtomicBool::new(keypair.initiator),
|
confirmed: AtomicBool::new(keypair.initiator),
|
||||||
keypair: keypair.clone(),
|
keypair: keypair.clone(),
|
||||||
protector: spin::Mutex::new(AntiReplay::new()),
|
protector: spin::Mutex::new(AntiReplay::new()),
|
||||||
death: keypair.birth + REJECT_AFTER_TIME,
|
|
||||||
peer,
|
peer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user