diff options
Diffstat (limited to '')
-rw-r--r-- | src/wireguard/wireguard.rs | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/src/wireguard/wireguard.rs b/src/wireguard/wireguard.rs index 1363c27..9bcac0a 100644 --- a/src/wireguard/wireguard.rs +++ b/src/wireguard/wireguard.rs @@ -54,7 +54,7 @@ pub struct PeerInner<B: Bind> { pub handshake_queued: AtomicBool, 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>, // } @@ -99,7 +99,7 @@ pub enum HandshakeJob<E> { 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 // (otherwise owned solely by the router and a dedicated read IO thread) mtu: T::MTU, @@ -118,9 +118,21 @@ struct WireguardInner<T: Tun, B: Bind> { 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> { runner: Runner, - state: Arc<WireguardInner<T, B>>, + state: WireguardHandle<T, B>, } /* 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> { + 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>) { let mut handshake = self.state.handshake.write(); 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 { pk, 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)), }); + // create a router peer 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 }; /* 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. */ *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. @@ -417,7 +455,7 @@ impl<T: Tun, B: Bind> Wireguard<T, B> { } Wireguard { - state: wg, + state: WireguardHandle { inner: wg }, runner: Runner::new(TIMERS_TICK, TIMERS_SLOTS, TIMERS_CAPACITY), } } |