Work on pure WireGuard test

This commit is contained in:
Mathias Hall-Andersen
2019-10-23 14:00:21 +02:00
parent ee3599d550
commit 8107973342
7 changed files with 156 additions and 83 deletions

View File

@@ -103,7 +103,7 @@ pub trait Configuration {
/// # Returns /// # Returns
/// ///
/// If the peer does not exists this operation is a noop /// 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 /// Adds a new peer to the device
/// ///
@@ -116,7 +116,7 @@ pub trait Configuration {
/// A bool indicating if the peer was added. /// A bool indicating if the peer was added.
/// ///
/// If the peer already exists this operation is a noop /// 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 /// Update the psk of a peer
/// ///
@@ -128,7 +128,7 @@ pub trait Configuration {
/// # Returns /// # Returns
/// ///
/// An error if no such peer exists /// 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 /// Update the endpoint of the
/// ///
@@ -136,7 +136,7 @@ pub trait Configuration {
/// ///
/// - `peer': The public key of the peer /// - `peer': The public key of the peer
/// - `psk` /// - `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 /// Update the endpoint of the
/// ///
@@ -146,7 +146,7 @@ pub trait Configuration {
/// - `psk` /// - `psk`
fn set_persistent_keepalive_interval( fn set_persistent_keepalive_interval(
&self, &self,
peer: PublicKey, peer: &PublicKey,
interval: usize, interval: usize,
) -> Option<ConfigError>; ) -> Option<ConfigError>;
@@ -159,7 +159,7 @@ pub trait Configuration {
/// # Returns /// # Returns
/// ///
/// An error if no such peer exists /// 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 /// 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 API must itself sanitize the (ip, masklen) set:
/// The ip should be masked to remove any set bits right of the first "masklen" bits. /// 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 /// 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(); self.wireguard.clear_peers();
} }
fn remove_peer(&self, peer: PublicKey) { fn remove_peer(&self, peer: &PublicKey) {
self.wireguard.remove_peer(peer); self.wireguard.remove_peer(peer);
} }
fn add_peer(&self, peer: PublicKey) -> bool { fn add_peer(&self, peer: &PublicKey) -> bool {
self.wireguard.new_peer(peer); self.wireguard.new_peer(*peer);
false 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 None
} }
fn set_endpoint(&self, peer: PublicKey, addr: SocketAddr) -> Option<ConfigError> { fn set_endpoint(&self, peer: &PublicKey, addr: SocketAddr) -> Option<ConfigError> {
None None
} }
fn set_persistent_keepalive_interval( fn set_persistent_keepalive_interval(
&self, &self,
peer: PublicKey, peer: &PublicKey,
interval: usize, interval: usize,
) -> Option<ConfigError> { ) -> Option<ConfigError> {
None None
} }
fn replace_allowed_ips(&self, peer: PublicKey) -> Option<ConfigError> { fn replace_allowed_ips(&self, peer: &PublicKey) -> Option<ConfigError> {
None 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 None
} }

View File

@@ -10,8 +10,6 @@ mod configuration;
mod platform; mod platform;
mod wireguard; mod wireguard;
mod tests;
use platform::tun; use platform::tun;
use configuration::WireguardConfig; use configuration::WireguardConfig;

View File

@@ -1,13 +1,14 @@
use std::error::Error; use std::error::Error;
use std::fmt; use std::fmt;
use std::marker; use std::marker;
use std::net::SocketAddr;
use std::sync::mpsc::{sync_channel, Receiver, SyncSender}; use std::sync::mpsc::{sync_channel, Receiver, SyncSender};
use std::sync::Arc; use std::sync::Arc;
use std::sync::Mutex; use std::sync::Mutex;
use super::super::bind::*; use super::super::bind::*;
use super::super::Endpoint; use super::super::Endpoint;
use super::UnitEndpoint;
pub struct VoidOwner {} 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)] #[derive(Clone, Copy)]
pub struct VoidBind {} pub struct VoidBind {}

View File

@@ -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 {}
}
}

View File

@@ -1 +0,0 @@

View File

@@ -1,13 +1,53 @@
use super::wireguard::Wireguard; use super::wireguard::Wireguard;
use super::{bind, dummy, tun}; use super::{bind, dummy, tun};
use std::net::IpAddr;
use std::thread; use std::thread;
use std::time::Duration; 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() { fn init() {
let _ = env_logger::builder().is_test(true).try_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 /* Create and configure two matching pure instances of WireGuard
* *
*/ */
@@ -37,9 +77,36 @@ fn test_pure_wireguard() {
// generate (public, pivate) key pairs // 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 // 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
);
} }

View File

@@ -36,15 +36,6 @@ pub struct Peer<T: Tun, B: Bind> {
pub state: Arc<PeerInner<B>>, 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 struct PeerInner<B: Bind> {
pub keepalive: AtomicUsize, // keepalive interval pub keepalive: AtomicUsize, // keepalive interval
pub rx_bytes: AtomicU64, pub rx_bytes: AtomicU64,
@@ -58,6 +49,44 @@ pub struct PeerInner<B: Bind> {
pub timers: RwLock<Timers>, // 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> { impl<B: Bind> PeerInner<B> {
#[inline(always)] #[inline(always)]
pub fn timers(&self) -> RwLockReadGuard<Timers> { pub fn timers(&self) -> RwLockReadGuard<Timers> {
@@ -94,35 +123,6 @@ struct Handshake {
active: bool, 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> { impl<T: Tun, B: Bind> Deref for WireguardHandle<T, B> {
type Target = Arc<WireguardInner<T, B>>; type Target = Arc<WireguardInner<T, B>>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
@@ -162,10 +162,18 @@ impl<T: Tun, B: Bind> Wireguard<T, B> {
self.state.peers.write().clear(); 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()); 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>> { pub fn list_peers(&self) -> Vec<Peer<T, B>> {
let peers = self.state.peers.read(); let peers = self.state.peers.read();
let mut list = Vec::with_capacity(peers.len()); let mut list = Vec::with_capacity(peers.len());