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