Work on platform specific code (Linux)

This commit is contained in:
Mathias Hall-Andersen
2019-10-23 10:32:18 +02:00
parent 2f3ceab036
commit 3fa928b315
14 changed files with 279 additions and 82 deletions

View File

@@ -1,9 +1,11 @@
use spin::Mutex;
use std::net::{IpAddr, SocketAddr}; use std::net::{IpAddr, SocketAddr};
use x25519_dalek::{PublicKey, StaticSecret}; use x25519_dalek::{PublicKey, StaticSecret};
use super::wireguard::Wireguard; use super::BindOwner;
use super::types::bind::Bind; use super::PlatformBind;
use super::types::tun::Tun; use super::Tun;
use super::Wireguard;
/// The goal of the configuration interface is, among others, /// The goal of the configuration interface is, among others,
/// to hide the IO implementations (over which the WG device is generic), /// to hide the IO implementations (over which the WG device is generic),
@@ -19,15 +21,28 @@ pub struct PeerState {
allowed_ips: Vec<(IpAddr, u32)>, allowed_ips: Vec<(IpAddr, u32)>,
} }
struct UDPState<O: BindOwner> {
fwmark: Option<u32>,
owner: O,
port: u16,
}
pub struct WireguardConfig<T: Tun, B: PlatformBind> {
wireguard: Wireguard<T, B>,
network: Mutex<Option<UDPState<B::Owner>>>,
}
pub enum ConfigError { pub enum ConfigError {
NoSuchPeer NoSuchPeer,
NotListening,
} }
impl ConfigError { impl ConfigError {
fn errno(&self) -> i32 { fn errno(&self) -> i32 {
// TODO: obtain the correct error values
match self { match self {
NoSuchPeer => 1, NoSuchPeer => 1,
NotListening => 2,
} }
} }
} }
@@ -122,7 +137,11 @@ pub trait Configuration {
/// ///
/// - `peer': The public key of the peer /// - `peer': The public key of the peer
/// - `psk` /// - `psk`
fn set_persistent_keepalive_interval(&self, peer: PublicKey) -> Option<ConfigError>; fn set_persistent_keepalive_interval(
&self,
peer: PublicKey,
interval: usize,
) -> Option<ConfigError>;
/// Remove all allowed IPs from the peer /// Remove all allowed IPs from the peer
/// ///
@@ -161,26 +180,81 @@ pub trait Configuration {
fn get_peers(&self) -> Vec<PeerState>; fn get_peers(&self) -> Vec<PeerState>;
} }
impl <T : Tun, B : Bind>Configuration for Wireguard<T, B> { impl<T: Tun, B: PlatformBind> Configuration for WireguardConfig<T, B> {
fn set_private_key(&self, sk: Option<StaticSecret>) {
fn set_private_key(&self, sk : Option<StaticSecret>) { self.wireguard.set_key(sk)
self.set_key(sk)
} }
fn get_private_key(&self) -> Option<StaticSecret> { fn get_private_key(&self) -> Option<StaticSecret> {
self.get_sk() self.wireguard.get_sk()
} }
fn get_protocol_version(&self) -> usize { fn get_protocol_version(&self) -> usize {
1 1
} }
fn set_listen_port(&self, port : u16) -> Option<ConfigError> { fn set_listen_port(&self, port: u16) -> Option<ConfigError> {
None let mut udp = self.network.lock();
}
// close the current listener
fn set_fwmark(&self, mark: Option<u32>) -> Option<ConfigError> { *udp = None;
None None
} }
} fn set_fwmark(&self, mark: Option<u32>) -> Option<ConfigError> {
match self.network.lock().as_mut() {
Some(mut bind) => {
// there is a active bind
// set the fwmark (the IO operation)
bind.owner.set_fwmark(mark).unwrap(); // TODO: handle
// update stored value
bind.fwmark = mark;
None
}
None => Some(ConfigError::NotListening),
}
}
fn replace_peers(&self) {
self.wireguard.clear_peers();
}
fn remove_peer(&self, peer: PublicKey) {
self.wireguard.remove_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> {
None
}
fn set_endpoint(&self, peer: PublicKey, addr: SocketAddr) -> Option<ConfigError> {
None
}
fn set_persistent_keepalive_interval(
&self,
peer: PublicKey,
interval: usize,
) -> Option<ConfigError> {
None
}
fn replace_allowed_ips(&self, peer: PublicKey) -> Option<ConfigError> {
None
}
fn add_allowed_ip(&self, peer: PublicKey, ip: IpAddr, masklen: u32) -> Option<ConfigError> {
None
}
fn get_peers(&self) -> Vec<PeerState> {
vec![]
}
}

5
src/configuration/mod.rs Normal file
View File

@@ -0,0 +1,5 @@
mod config;
use super::platform::{BindOwner, PlatformBind};
use super::wireguard::tun::Tun;
use super::wireguard::Wireguard;

View File

@@ -6,12 +6,12 @@ extern crate jemallocator;
#[global_allocator] #[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
// mod config; mod configuration;
mod platform; mod platform;
mod wireguard; mod wireguard;
use platform::TunBind; use platform::PlatformTun;
fn main() { fn main() {
let (readers, writers, mtu) = platform::PlatformTun::create("test").unwrap(); let (readers, writer, mtu) = platform::TunInstance::create("test").unwrap();
} }

22
src/platform/dummy.rs Normal file
View File

@@ -0,0 +1,22 @@
#[cfg(test)]
use super::super::wireguard::dummy;
use super::BindOwner;
use super::PlatformBind;
pub struct VoidOwner {}
impl BindOwner for VoidOwner {
type Error = dummy::BindError;
fn set_fwmark(&self, value: Option<u32>) -> Option<Self::Error> {
None
}
}
impl PlatformBind for dummy::PairBind {
type Owner = VoidOwner;
fn bind(_port: u16) -> Result<(Vec<Self::Reader>, Self::Writer, Self::Owner), Self::Error> {
Err(dummy::BindError::Disconnected)
}
}

View File

@@ -1,4 +1,5 @@
mod tun; mod tun;
mod udp; mod udp;
pub use tun::PlatformTun; pub use tun::LinuxTun;
pub use udp::LinuxBind;

View File

@@ -1,6 +1,6 @@
use super::super::super::wireguard::tun::*; use super::super::super::wireguard::tun::*;
use super::super::PlatformTun;
use super::super::Tun; use super::super::Tun;
use super::super::TunBind;
use libc::*; use libc::*;
@@ -32,13 +32,13 @@ struct Ifreq {
_pad: [u8; 64], _pad: [u8; 64],
} }
pub struct PlatformTun {} pub struct LinuxTun {}
pub struct PlatformTunReader { pub struct LinuxTunReader {
fd: RawFd, fd: RawFd,
} }
pub struct PlatformTunWriter { pub struct LinuxTunWriter {
fd: RawFd, fd: RawFd,
} }
@@ -46,7 +46,7 @@ pub struct PlatformTunWriter {
* announcing an MTU update for the interface * announcing an MTU update for the interface
*/ */
#[derive(Clone)] #[derive(Clone)]
pub struct PlatformTunMTU { pub struct LinuxTunMTU {
value: Arc<AtomicUsize>, value: Arc<AtomicUsize>,
} }
@@ -83,14 +83,14 @@ impl Error for LinuxTunError {
} }
} }
impl MTU for PlatformTunMTU { impl MTU for LinuxTunMTU {
#[inline(always)] #[inline(always)]
fn mtu(&self) -> usize { fn mtu(&self) -> usize {
self.value.load(Ordering::Relaxed) self.value.load(Ordering::Relaxed)
} }
} }
impl Reader for PlatformTunReader { impl Reader for LinuxTunReader {
type Error = LinuxTunError; type Error = LinuxTunError;
fn read(&self, buf: &mut [u8], offset: usize) -> Result<usize, Self::Error> { fn read(&self, buf: &mut [u8], offset: usize) -> Result<usize, Self::Error> {
@@ -109,7 +109,7 @@ impl Reader for PlatformTunReader {
} }
} }
impl Writer for PlatformTunWriter { impl Writer for LinuxTunWriter {
type Error = LinuxTunError; type Error = LinuxTunError;
fn write(&self, src: &[u8]) -> Result<(), Self::Error> { fn write(&self, src: &[u8]) -> Result<(), Self::Error> {
@@ -120,14 +120,14 @@ impl Writer for PlatformTunWriter {
} }
} }
impl Tun for PlatformTun { impl Tun for LinuxTun {
type Error = LinuxTunError; type Error = LinuxTunError;
type Reader = PlatformTunReader; type Reader = LinuxTunReader;
type Writer = PlatformTunWriter; type Writer = LinuxTunWriter;
type MTU = PlatformTunMTU; type MTU = LinuxTunMTU;
} }
impl TunBind for PlatformTun { impl PlatformTun for LinuxTun {
fn create(name: &str) -> Result<(Vec<Self::Reader>, Self::Writer, Self::MTU), Self::Error> { fn create(name: &str) -> Result<(Vec<Self::Reader>, Self::Writer, Self::MTU), Self::Error> {
// construct request struct // construct request struct
let mut req = Ifreq { let mut req = Ifreq {
@@ -157,10 +157,10 @@ impl TunBind for PlatformTun {
// create PlatformTunMTU instance // create PlatformTunMTU instance
Ok(( Ok((
vec![PlatformTunReader { fd }], // TODO: enable multi-queue for Linux vec![LinuxTunReader { fd }], // TODO: enable multi-queue for Linux
PlatformTunWriter { fd }, LinuxTunWriter { fd },
PlatformTunMTU { LinuxTunMTU {
value: Arc::new(AtomicUsize::new(1500)), value: Arc::new(AtomicUsize::new(1500)), // TODO: fetch and update
}, },
)) ))
} }
@@ -174,7 +174,7 @@ mod tests {
fn is_root() -> bool { fn is_root() -> bool {
match env::var("USER") { match env::var("USER") {
Ok(val) => val == "root", Ok(val) => val == "root",
Err(e) => false, Err(_) => false,
} }
} }
@@ -183,6 +183,7 @@ mod tests {
if !is_root() { if !is_root() {
return; return;
} }
let (readers, writers, mtu) = PlatformTun::create("test").unwrap(); let (readers, writers, mtu) = LinuxTun::create("test").unwrap();
// TODO: test (any good idea how?)
} }
} }

View File

@@ -0,0 +1,27 @@
use super::super::Bind;
use super::super::Endpoint;
use super::super::PlatformBind;
use std::net::SocketAddr;
pub struct LinuxEndpoint {}
pub struct LinuxBind {}
impl Endpoint for LinuxEndpoint {
fn clear_src(&mut self) {}
fn from_address(addr: SocketAddr) -> Self {
LinuxEndpoint {}
}
fn into_address(&self) -> SocketAddr {
"127.0.0.1:6060".parse().unwrap()
}
}
/*
impl Bind for PlatformBind {
type Endpoint = PlatformEndpoint;
}
*/

View File

@@ -2,21 +2,32 @@ use std::error::Error;
use super::wireguard::bind::Bind; use super::wireguard::bind::Bind;
use super::wireguard::tun::Tun; use super::wireguard::tun::Tun;
use super::wireguard::Endpoint;
#[cfg(test)]
mod dummy;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
mod linux; mod linux;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub use linux::PlatformTun; pub use linux::LinuxTun as TunInstance;
pub trait UDPBind: Bind { pub trait BindOwner: Send {
type Closer; type Error: Error;
fn set_fwmark(&self, value: Option<u32>) -> Option<Self::Error>;
}
pub trait PlatformBind: Bind {
type Owner: BindOwner;
/// Bind to a new port, returning the reader/writer and /// Bind to a new port, returning the reader/writer and
/// an associated instance of the Closer type, which closes the UDP socket upon "drop". /// an associated instance of the owner type, which closes the UDP socket upon "drop"
fn bind(port: u16) -> Result<(Self::Reader, Self::Writer, Self::Closer), Self::Error>; /// and enables configuration of the fwmark value.
fn bind(port: u16) -> Result<(Vec<Self::Reader>, Self::Writer, Self::Owner), Self::Error>;
} }
pub trait TunBind: Tun { pub trait PlatformTun: Tun {
fn create(name: &str) -> Result<(Vec<Self::Reader>, Self::Writer, Self::MTU), Self::Error>; fn create(name: &str) -> Result<(Vec<Self::Reader>, Self::Writer, Self::MTU), Self::Error>;
} }

View File

@@ -77,9 +77,9 @@ impl Device {
} }
/// Return the secret key of the device /// Return the secret key of the device
/// ///
/// # Returns /// # Returns
/// ///
/// A secret key (x25519 scalar) /// A secret key (x25519 scalar)
pub fn get_sk(&self) -> StaticSecret { pub fn get_sk(&self) -> StaticSecret {
StaticSecret::from(self.sk.to_bytes()) StaticSecret::from(self.sk.to_bytes())
@@ -95,7 +95,7 @@ impl Device {
pub fn add(&mut self, pk: PublicKey) -> Result<(), ConfigError> { pub fn add(&mut self, pk: PublicKey) -> Result<(), ConfigError> {
// check that the pk is not added twice // check that the pk is not added twice
if let Some(_) = self.pk_map.get(pk.as_bytes()) { if let Some(_) = self.pk_map.get(pk.as_bytes()) {
return Err(ConfigError::new("Duplicate public key")); return Ok(());
}; };
// check that the pk is not that of the device // check that the pk is not that of the device

View File

@@ -1,7 +1,6 @@
mod wireguard;
// mod config;
mod constants; mod constants;
mod timers; mod timers;
mod wireguard;
mod handshake; mod handshake;
mod router; mod router;
@@ -12,12 +11,14 @@ mod tests;
/// The WireGuard sub-module contains a pure, configurable implementation of WireGuard. /// The WireGuard sub-module contains a pure, configurable implementation of WireGuard.
/// The implementation is generic over: /// The implementation is generic over:
/// ///
/// - TUN type, specifying how packets are received on the interface side: a reader/writer and MTU reporting interface. /// - TUN type, specifying how packets are received on the interface side: a reader/writer and MTU reporting interface.
/// - Bind type, specifying how WireGuard messages are sent/received from the internet and what constitutes an "endpoint" /// - Bind type, specifying how WireGuard messages are sent/received from the internet and what constitutes an "endpoint"
pub use wireguard::{Peer, Wireguard};
pub use wireguard::{Wireguard, Peer};
pub use types::bind; pub use types::bind;
pub use types::tun; pub use types::tun;
pub use types::Endpoint; pub use types::Endpoint;
#[cfg(test)]
pub use types::dummy;

View File

@@ -2,11 +2,11 @@ use std::error::Error;
use std::fmt; use std::fmt;
use std::marker; use std::marker;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::sync::atomic::{AtomicUsize, Ordering};
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 std::time::Instant; use std::time::Instant;
use std::sync::atomic::{Ordering, AtomicUsize};
use super::*; use super::*;
@@ -43,7 +43,7 @@ impl fmt::Display for BindError {
#[derive(Debug)] #[derive(Debug)]
pub enum TunError { pub enum TunError {
Disconnected Disconnected,
} }
impl Error for TunError { impl Error for TunError {
@@ -76,7 +76,7 @@ impl Endpoint for UnitEndpoint {
"127.0.0.1:8080".parse().unwrap() "127.0.0.1:8080".parse().unwrap()
} }
fn clear_src(&self) {} fn clear_src(&mut self) {}
} }
impl UnitEndpoint { impl UnitEndpoint {
@@ -92,21 +92,21 @@ pub struct TunTest {}
pub struct TunFakeIO { pub struct TunFakeIO {
store: bool, store: bool,
tx: SyncSender<Vec<u8>>, tx: SyncSender<Vec<u8>>,
rx: Receiver<Vec<u8>> rx: Receiver<Vec<u8>>,
} }
pub struct TunReader { pub struct TunReader {
rx: Receiver<Vec<u8>> rx: Receiver<Vec<u8>>,
} }
pub struct TunWriter { pub struct TunWriter {
store: bool, store: bool,
tx: Mutex<SyncSender<Vec<u8>>> tx: Mutex<SyncSender<Vec<u8>>>,
} }
#[derive(Clone)] #[derive(Clone)]
pub struct TunMTU { pub struct TunMTU {
mtu: Arc<AtomicUsize> mtu: Arc<AtomicUsize>,
} }
impl tun::Reader for TunReader { impl tun::Reader for TunReader {
@@ -118,7 +118,7 @@ impl tun::Reader for TunReader {
buf[offset..].copy_from_slice(&m[..]); buf[offset..].copy_from_slice(&m[..]);
Ok(m.len()) Ok(m.len())
} }
Err(_) => Err(TunError::Disconnected) Err(_) => Err(TunError::Disconnected),
} }
} }
} }
@@ -131,7 +131,7 @@ impl tun::Writer for TunWriter {
let m = src.to_owned(); let m = src.to_owned();
match self.tx.lock().unwrap().send(m) { match self.tx.lock().unwrap().send(m) {
Ok(_) => Ok(()), Ok(_) => Ok(()),
Err(_) => Err(TunError::Disconnected) Err(_) => Err(TunError::Disconnected),
} }
} else { } else {
Ok(()) Ok(())
@@ -153,7 +153,7 @@ impl tun::Tun for TunTest {
} }
impl TunFakeIO { impl TunFakeIO {
pub fn write(&self, msg : Vec<u8>) { pub fn write(&self, msg: Vec<u8>) {
if self.store { if self.store {
self.tx.send(msg).unwrap(); self.tx.send(msg).unwrap();
} }
@@ -165,15 +165,31 @@ impl TunFakeIO {
} }
impl TunTest { impl TunTest {
pub fn create(mtu : usize, store: bool) -> (TunFakeIO, TunReader, TunWriter, TunMTU) { pub fn create(mtu: usize, store: bool) -> (TunFakeIO, TunReader, TunWriter, TunMTU) {
let (tx1, rx1) = if store {
sync_channel(32)
} else {
sync_channel(1)
};
let (tx2, rx2) = if store {
sync_channel(32)
} else {
sync_channel(1)
};
let (tx1, rx1) = if store { sync_channel(32) } else { sync_channel(1) }; let fake = TunFakeIO {
let (tx2, rx2) = if store { sync_channel(32) } else { sync_channel(1) }; tx: tx1,
rx: rx2,
let fake = TunFakeIO{tx: tx1, rx: rx2, store}; store,
let reader = TunReader{rx : rx1}; };
let writer = TunWriter{tx : Mutex::new(tx2), store}; let reader = TunReader { rx: rx1 };
let mtu = TunMTU{mtu : Arc::new(AtomicUsize::new(mtu))}; let writer = TunWriter {
tx: Mutex::new(tx2),
store,
};
let mtu = TunMTU {
mtu: Arc::new(AtomicUsize::new(mtu)),
};
(fake, reader, writer, mtu) (fake, reader, writer, mtu)
} }

View File

@@ -3,5 +3,5 @@ use std::net::SocketAddr;
pub trait Endpoint: Send + 'static { pub trait Endpoint: Send + 'static {
fn from_address(addr: SocketAddr) -> Self; fn from_address(addr: SocketAddr) -> Self;
fn into_address(&self) -> SocketAddr; fn into_address(&self) -> SocketAddr;
fn clear_src(&self); fn clear_src(&mut self);
} }

View File

@@ -1,10 +1,11 @@
mod endpoint; mod endpoint;
mod keys; mod keys;
pub mod tun;
pub mod bind; pub mod bind;
pub mod tun;
#[cfg(test)] #[cfg(test)]
pub mod dummy; pub mod dummy;
pub use endpoint::Endpoint; pub use endpoint::Endpoint;
pub use keys::{Key, KeyPair}; pub use keys::{Key, KeyPair};

View File

@@ -54,7 +54,7 @@ pub struct PeerInner<B: Bind> {
pub handshake_queued: AtomicBool, pub handshake_queued: AtomicBool,
pub queue: Mutex<Sender<HandshakeJob<B::Endpoint>>>, // handshake queue pub queue: Mutex<Sender<HandshakeJob<B::Endpoint>>>, // handshake queue
pub pk: PublicKey, // DISCUSS: Change layout in handshake module (adopt pattern of router), to avoid this. pub pk: PublicKey, // DISCUSS: Change layout in handshake module (adopt pattern of router), to avoid this. TODO: remove
pub timers: RwLock<Timers>, // pub timers: RwLock<Timers>, //
} }
@@ -99,7 +99,7 @@ pub enum HandshakeJob<E> {
New(PublicKey), New(PublicKey),
} }
struct WireguardInner<T: Tun, B: Bind> { pub struct WireguardInner<T: Tun, B: Bind> {
// provides access to the MTU value of the tun device // provides access to the MTU value of the tun device
// (otherwise owned solely by the router and a dedicated read IO thread) // (otherwise owned solely by the router and a dedicated read IO thread)
mtu: T::MTU, mtu: T::MTU,
@@ -118,9 +118,21 @@ struct WireguardInner<T: Tun, B: Bind> {
queue: Mutex<Sender<HandshakeJob<B::Endpoint>>>, 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 {
&self.inner
}
}
pub struct Wireguard<T: Tun, B: Bind> { pub struct Wireguard<T: Tun, B: Bind> {
runner: Runner, runner: Runner,
state: Arc<WireguardInner<T, B>>, state: WireguardHandle<T, B>,
} }
/* Returns the padded length of a message: /* Returns the padded length of a message:
@@ -146,6 +158,24 @@ const fn padding(size: usize, mtu: usize) -> usize {
} }
impl<T: Tun, B: Bind> Wireguard<T, B> { impl<T: Tun, B: Bind> Wireguard<T, B> {
pub fn clear_peers(&self) {
self.state.peers.write().clear();
}
pub fn remove_peer(&self, pk: PublicKey) {
self.state.peers.write().remove(pk.as_bytes());
}
pub fn list_peers(&self) -> Vec<Peer<T, B>> {
let peers = self.state.peers.read();
let mut list = Vec::with_capacity(peers.len());
for (k, v) in peers.iter() {
debug_assert!(k == v.pk.as_bytes());
list.push(v.clone());
}
list
}
pub fn set_key(&self, sk: Option<StaticSecret>) { pub fn set_key(&self, sk: Option<StaticSecret>) {
let mut handshake = self.state.handshake.write(); let mut handshake = self.state.handshake.write();
match sk { match sk {
@@ -170,7 +200,7 @@ impl<T: Tun, B: Bind> Wireguard<T, B> {
} }
} }
pub fn new_peer(&self, pk: PublicKey) -> Peer<T, B> { pub fn new_peer(&self, pk: PublicKey) {
let state = Arc::new(PeerInner { let state = Arc::new(PeerInner {
pk, pk,
last_handshake: Mutex::new(SystemTime::UNIX_EPOCH), last_handshake: Mutex::new(SystemTime::UNIX_EPOCH),
@@ -182,8 +212,13 @@ impl<T: Tun, B: Bind> Wireguard<T, B> {
timers: RwLock::new(Timers::dummy(&self.runner)), timers: RwLock::new(Timers::dummy(&self.runner)),
}); });
// create a router peer
let router = Arc::new(self.state.router.new_peer(state.clone())); let router = Arc::new(self.state.router.new_peer(state.clone()));
// add to the handshake device
self.state.handshake.write().device.add(pk).unwrap(); // TODO: handle adding of public key for interface
// form WireGuard peer
let peer = Peer { router, state }; let peer = Peer { router, state };
/* The need for dummy timers arises from the chicken-egg /* The need for dummy timers arises from the chicken-egg
@@ -193,7 +228,10 @@ impl<T: Tun, B: Bind> Wireguard<T, B> {
* TODO: Consider the ease of using atomic pointers instead. * TODO: Consider the ease of using atomic pointers instead.
*/ */
*peer.timers.write() = Timers::new(&self.runner, peer.clone()); *peer.timers.write() = Timers::new(&self.runner, peer.clone());
peer
// finally, add the peer to the wireguard device
let mut peers = self.state.peers.write();
peers.entry(*pk.as_bytes()).or_insert(peer);
} }
/* Begin consuming messages from the reader. /* Begin consuming messages from the reader.
@@ -417,7 +455,7 @@ impl<T: Tun, B: Bind> Wireguard<T, B> {
} }
Wireguard { Wireguard {
state: wg, state: WireguardHandle { inner: wg },
runner: Runner::new(TIMERS_TICK, TIMERS_SLOTS, TIMERS_CAPACITY), runner: Runner::new(TIMERS_TICK, TIMERS_SLOTS, TIMERS_CAPACITY),
} }
} }