Work on pure WireGuard test
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 {}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
@@ -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
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
Reference in New Issue
Block a user