summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/configuration/config.rs30
-rw-r--r--src/main.rs2
-rw-r--r--src/platform/dummy/bind.rs26
-rw-r--r--src/platform/dummy/endpoint.rs23
-rw-r--r--src/tests.rs1
-rw-r--r--src/wireguard/tests.rs71
-rw-r--r--src/wireguard/wireguard.rs86
7 files changed, 156 insertions, 83 deletions
diff --git a/src/configuration/config.rs b/src/configuration/config.rs
index f42b53b..6aa6a77 100644
--- a/src/configuration/config.rs
+++ b/src/configuration/config.rs
@@ -103,7 +103,7 @@ pub trait Configuration {
/// # Returns
///
/// If the peer does not exists this operation is a noop
- fn remove_peer(&self, peer: PublicKey);
+ fn remove_peer(&self, peer: &PublicKey);
/// Adds a new peer to the device
///
@@ -116,7 +116,7 @@ pub trait Configuration {
/// A bool indicating if the peer was added.
///
/// If the peer already exists this operation is a noop
- fn add_peer(&self, peer: PublicKey) -> bool;
+ fn add_peer(&self, peer: &PublicKey) -> bool;
/// Update the psk of a peer
///
@@ -128,7 +128,7 @@ pub trait Configuration {
/// # Returns
///
/// An error if no such peer exists
- fn set_preshared_key(&self, peer: PublicKey, psk: Option<[u8; 32]>) -> Option<ConfigError>;
+ fn set_preshared_key(&self, peer: &PublicKey, psk: Option<[u8; 32]>) -> Option<ConfigError>;
/// Update the endpoint of the
///
@@ -136,7 +136,7 @@ pub trait Configuration {
///
/// - `peer': The public key of the peer
/// - `psk`
- fn set_endpoint(&self, peer: PublicKey, addr: SocketAddr) -> Option<ConfigError>;
+ fn set_endpoint(&self, peer: &PublicKey, addr: SocketAddr) -> Option<ConfigError>;
/// Update the endpoint of the
///
@@ -146,7 +146,7 @@ pub trait Configuration {
/// - `psk`
fn set_persistent_keepalive_interval(
&self,
- peer: PublicKey,
+ peer: &PublicKey,
interval: usize,
) -> Option<ConfigError>;
@@ -159,7 +159,7 @@ pub trait Configuration {
/// # Returns
///
/// An error if no such peer exists
- fn replace_allowed_ips(&self, peer: PublicKey) -> Option<ConfigError>;
+ fn replace_allowed_ips(&self, peer: &PublicKey) -> Option<ConfigError>;
/// Add a new allowed subnet to the peer
///
@@ -177,7 +177,7 @@ pub trait Configuration {
///
/// The API must itself sanitize the (ip, masklen) set:
/// The ip should be masked to remove any set bits right of the first "masklen" bits.
- fn add_allowed_ip(&self, peer: PublicKey, ip: IpAddr, masklen: u32) -> Option<ConfigError>;
+ fn add_allowed_ip(&self, peer: &PublicKey, ip: IpAddr, masklen: u32) -> Option<ConfigError>;
/// Returns the state of all peers
///
@@ -228,36 +228,36 @@ impl<T: tun::Tun, B: bind::Platform> Configuration for WireguardConfig<T, B> {
self.wireguard.clear_peers();
}
- fn remove_peer(&self, peer: PublicKey) {
+ fn remove_peer(&self, peer: &PublicKey) {
self.wireguard.remove_peer(peer);
}
- fn add_peer(&self, peer: PublicKey) -> bool {
- self.wireguard.new_peer(peer);
+ fn add_peer(&self, peer: &PublicKey) -> bool {
+ self.wireguard.new_peer(*peer);
false
}
- fn set_preshared_key(&self, peer: PublicKey, psk: Option<[u8; 32]>) -> Option<ConfigError> {
+ fn set_preshared_key(&self, peer: &PublicKey, psk: Option<[u8; 32]>) -> Option<ConfigError> {
None
}
- fn set_endpoint(&self, peer: PublicKey, addr: SocketAddr) -> Option<ConfigError> {
+ fn set_endpoint(&self, peer: &PublicKey, addr: SocketAddr) -> Option<ConfigError> {
None
}
fn set_persistent_keepalive_interval(
&self,
- peer: PublicKey,
+ peer: &PublicKey,
interval: usize,
) -> Option<ConfigError> {
None
}
- fn replace_allowed_ips(&self, peer: PublicKey) -> Option<ConfigError> {
+ fn replace_allowed_ips(&self, peer: &PublicKey) -> Option<ConfigError> {
None
}
- fn add_allowed_ip(&self, peer: PublicKey, ip: IpAddr, masklen: u32) -> Option<ConfigError> {
+ fn add_allowed_ip(&self, peer: &PublicKey, ip: IpAddr, masklen: u32) -> Option<ConfigError> {
None
}
diff --git a/src/main.rs b/src/main.rs
index 5aaeb25..4d34b39 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -10,8 +10,6 @@ mod configuration;
mod platform;
mod wireguard;
-mod tests;
-
use platform::tun;
use configuration::WireguardConfig;
diff --git a/src/platform/dummy/bind.rs b/src/platform/dummy/bind.rs
index 14143ae..5010597 100644
--- a/src/platform/dummy/bind.rs
+++ b/src/platform/dummy/bind.rs
@@ -1,13 +1,14 @@
use std::error::Error;
use std::fmt;
use std::marker;
-use std::net::SocketAddr;
+
use std::sync::mpsc::{sync_channel, Receiver, SyncSender};
use std::sync::Arc;
use std::sync::Mutex;
use super::super::bind::*;
use super::super::Endpoint;
+use super::UnitEndpoint;
pub struct VoidOwner {}
@@ -57,29 +58,6 @@ impl fmt::Display for TunError {
}
}
-/* Endpoint implementation */
-
-#[derive(Clone, Copy)]
-pub struct UnitEndpoint {}
-
-impl Endpoint for UnitEndpoint {
- fn from_address(_: SocketAddr) -> UnitEndpoint {
- UnitEndpoint {}
- }
-
- fn into_address(&self) -> SocketAddr {
- "127.0.0.1:8080".parse().unwrap()
- }
-
- fn clear_src(&mut self) {}
-}
-
-impl UnitEndpoint {
- pub fn new() -> UnitEndpoint {
- UnitEndpoint {}
- }
-}
-
#[derive(Clone, Copy)]
pub struct VoidBind {}
diff --git a/src/platform/dummy/endpoint.rs b/src/platform/dummy/endpoint.rs
index 8b13789..f5fc32c 100644
--- a/src/platform/dummy/endpoint.rs
+++ b/src/platform/dummy/endpoint.rs
@@ -1 +1,24 @@
+use std::net::SocketAddr;
+use super::super::Endpoint;
+
+#[derive(Clone, Copy)]
+pub struct UnitEndpoint {}
+
+impl Endpoint for UnitEndpoint {
+ fn from_address(_: SocketAddr) -> UnitEndpoint {
+ UnitEndpoint {}
+ }
+
+ fn into_address(&self) -> SocketAddr {
+ "127.0.0.1:8080".parse().unwrap()
+ }
+
+ fn clear_src(&mut self) {}
+}
+
+impl UnitEndpoint {
+ pub fn new() -> UnitEndpoint {
+ UnitEndpoint {}
+ }
+}
diff --git a/src/tests.rs b/src/tests.rs
deleted file mode 100644
index 8b13789..0000000
--- a/src/tests.rs
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/wireguard/tests.rs b/src/wireguard/tests.rs
index 4ecd43b..0dc9296 100644
--- a/src/wireguard/tests.rs
+++ b/src/wireguard/tests.rs
@@ -1,13 +1,53 @@
use super::wireguard::Wireguard;
use super::{bind, dummy, tun};
+use std::net::IpAddr;
use std::thread;
use std::time::Duration;
+use rand::rngs::OsRng;
+use x25519_dalek::{PublicKey, StaticSecret};
+
+use pnet::packet::ipv4::MutableIpv4Packet;
+use pnet::packet::ipv6::MutableIpv6Packet;
+
+fn make_packet(size: usize, src: IpAddr, dst: IpAddr) -> Vec<u8> {
+ // create "IP packet"
+ let mut msg = Vec::with_capacity(size);
+ msg.resize(size, 0);
+ match dst {
+ IpAddr::V4(dst) => {
+ let mut packet = MutableIpv4Packet::new(&mut msg[..]).unwrap();
+ packet.set_destination(dst);
+ packet.set_source(if let IpAddr::V4(src) = src {
+ src
+ } else {
+ panic!("src.version != dst.version")
+ });
+ packet.set_version(4);
+ }
+ IpAddr::V6(dst) => {
+ let mut packet = MutableIpv6Packet::new(&mut msg[..]).unwrap();
+ packet.set_destination(dst);
+ packet.set_source(if let IpAddr::V6(src) = src {
+ src
+ } else {
+ panic!("src.version != dst.version")
+ });
+ packet.set_version(6);
+ }
+ }
+ msg
+}
+
fn init() {
let _ = env_logger::builder().is_test(true).try_init();
}
+fn wait() {
+ thread::sleep(Duration::from_millis(500));
+}
+
/* Create and configure two matching pure instances of WireGuard
*
*/
@@ -37,9 +77,36 @@ fn test_pure_wireguard() {
// generate (public, pivate) key pairs
+ let mut rng = OsRng::new().unwrap();
+ let sk1 = StaticSecret::new(&mut rng);
+ let sk2 = StaticSecret::new(&mut rng);
+ let pk1 = PublicKey::from(&sk1);
+ let pk2 = PublicKey::from(&sk2);
+
+ wg1.new_peer(pk2);
+ wg2.new_peer(pk1);
+
+ wg1.set_key(Some(sk1));
+ wg2.set_key(Some(sk2));
+
// configure cryptkey router
- // create IP packets
+ let peer2 = wg1.lookup_peer(&pk2).unwrap();
+ let peer1 = wg2.lookup_peer(&pk1).unwrap();
- thread::sleep(Duration::from_millis(500));
+ peer1.router.add_subnet("192.168.2.0".parse().unwrap(), 24);
+ peer2.router.add_subnet("192.168.1.0".parse().unwrap(), 24);
+
+ // set endpoints
+
+ peer1.router.set_endpoint(dummy::UnitEndpoint::new());
+ peer2.router.set_endpoint(dummy::UnitEndpoint::new());
+
+ // create IP packets (causing a new handshake)
+
+ let packet_p1_to_p2 = make_packet(
+ 1000,
+ "192.168.2.20".parse().unwrap(), // src
+ "192.168.1.10".parse().unwrap(), // dst
+ );
}
diff --git a/src/wireguard/wireguard.rs b/src/wireguard/wireguard.rs
index 96a134c..25544d9 100644
--- a/src/wireguard/wireguard.rs
+++ b/src/wireguard/wireguard.rs
@@ -36,15 +36,6 @@ pub struct Peer<T: Tun, B: Bind> {
pub state: Arc<PeerInner<B>>,
}
-impl<T: Tun, B: Bind> Clone for Peer<T, B> {
- fn clone(&self) -> Peer<T, B> {
- Peer {
- router: self.router.clone(),
- state: self.state.clone(),
- }
- }
-}
-
pub struct PeerInner<B: Bind> {
pub keepalive: AtomicUsize, // keepalive interval
pub rx_bytes: AtomicU64,
@@ -58,6 +49,44 @@ pub struct PeerInner<B: Bind> {
pub timers: RwLock<Timers>, //
}
+pub struct WireguardInner<T: Tun, B: Bind> {
+ // provides access to the MTU value of the tun device
+ // (otherwise owned solely by the router and a dedicated read IO thread)
+ mtu: T::MTU,
+ send: RwLock<Option<B::Writer>>,
+
+ // identify and configuration map
+ peers: RwLock<HashMap<[u8; 32], Peer<T, B>>>,
+
+ // cryptkey router
+ router: router::Device<B::Endpoint, Events<T, B>, T::Writer, B::Writer>,
+
+ // handshake related state
+ handshake: RwLock<Handshake>,
+ under_load: AtomicBool,
+ pending: AtomicUsize, // num of pending handshake packets in queue
+ queue: Mutex<Sender<HandshakeJob<B::Endpoint>>>,
+}
+
+pub enum HandshakeJob<E> {
+ Message(Vec<u8>, E),
+ New(PublicKey),
+}
+
+#[derive(Clone)]
+pub struct WireguardHandle<T: Tun, B: Bind> {
+ inner: Arc<WireguardInner<T, B>>,
+}
+
+impl<T: Tun, B: Bind> Clone for Peer<T, B> {
+ fn clone(&self) -> Peer<T, B> {
+ Peer {
+ router: self.router.clone(),
+ state: self.state.clone(),
+ }
+ }
+}
+
impl<B: Bind> PeerInner<B> {
#[inline(always)]
pub fn timers(&self) -> RwLockReadGuard<Timers> {
@@ -94,35 +123,6 @@ struct Handshake {
active: bool,
}
-pub enum HandshakeJob<E> {
- Message(Vec<u8>, E),
- New(PublicKey),
-}
-
-pub struct WireguardInner<T: Tun, B: Bind> {
- // provides access to the MTU value of the tun device
- // (otherwise owned solely by the router and a dedicated read IO thread)
- mtu: T::MTU,
- send: RwLock<Option<B::Writer>>,
-
- // identify and configuration map
- peers: RwLock<HashMap<[u8; 32], Peer<T, B>>>,
-
- // cryptkey router
- router: router::Device<B::Endpoint, Events<T, B>, T::Writer, B::Writer>,
-
- // handshake related state
- handshake: RwLock<Handshake>,
- under_load: AtomicBool,
- pending: AtomicUsize, // num of pending handshake packets in queue
- queue: Mutex<Sender<HandshakeJob<B::Endpoint>>>,
-}
-
-#[derive(Clone)]
-pub struct WireguardHandle<T: Tun, B: Bind> {
- inner: Arc<WireguardInner<T, B>>,
-}
-
impl<T: Tun, B: Bind> Deref for WireguardHandle<T, B> {
type Target = Arc<WireguardInner<T, B>>;
fn deref(&self) -> &Self::Target {
@@ -162,10 +162,18 @@ impl<T: Tun, B: Bind> Wireguard<T, B> {
self.state.peers.write().clear();
}
- pub fn remove_peer(&self, pk: PublicKey) {
+ pub fn remove_peer(&self, pk: &PublicKey) {
self.state.peers.write().remove(pk.as_bytes());
}
+ pub fn lookup_peer(&self, pk: &PublicKey) -> Option<Peer<T, B>> {
+ self.state
+ .peers
+ .read()
+ .get(pk.as_bytes())
+ .map(|p| p.clone())
+ }
+
pub fn list_peers(&self) -> Vec<Peer<T, B>> {
let peers = self.state.peers.read();
let mut list = Vec::with_capacity(peers.len());