diff options
Diffstat (limited to '')
-rw-r--r-- | src/configuration/config.rs | 30 | ||||
-rw-r--r-- | src/main.rs | 2 | ||||
-rw-r--r-- | src/platform/dummy/bind.rs | 26 | ||||
-rw-r--r-- | src/platform/dummy/endpoint.rs | 23 | ||||
-rw-r--r-- | src/tests.rs | 1 | ||||
-rw-r--r-- | src/wireguard/tests.rs | 71 | ||||
-rw-r--r-- | src/wireguard/wireguard.rs | 86 |
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()); |