diff options
author | Mathias Hall-Andersen <mathias@hall-andersen.dk> | 2020-05-10 21:23:34 +0200 |
---|---|---|
committer | Mathias Hall-Andersen <mathias@hall-andersen.dk> | 2020-05-10 21:23:51 +0200 |
commit | 6c386146a77ecb8ff317d76823c0f788bd70d8c3 (patch) | |
tree | fa7a7399a74eebb2b1000f0bab0d41efe6c9ec50 /src/wireguard/timers.rs | |
parent | Added basic readme. (diff) | |
download | wireguard-rs-6c386146a77ecb8ff317d76823c0f788bd70d8c3.tar.xz wireguard-rs-6c386146a77ecb8ff317d76823c0f788bd70d8c3.zip |
Refactoring timer code:
- Remove the Events struct
- Implement Callbacks on the PeerInner, elimiting an Arc.
Diffstat (limited to 'src/wireguard/timers.rs')
-rw-r--r-- | src/wireguard/timers.rs | 129 |
1 files changed, 76 insertions, 53 deletions
diff --git a/src/wireguard/timers.rs b/src/wireguard/timers.rs index 0197a9e..a435e5c 100644 --- a/src/wireguard/timers.rs +++ b/src/wireguard/timers.rs @@ -1,17 +1,19 @@ -use std::marker::PhantomData; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::Arc; use std::time::{Duration, Instant, SystemTime}; -use hjul::{Runner, Timer}; use log::debug; +use hjul::Timer; +use x25519_dalek::PublicKey; + use super::constants::*; -use super::peer::{Peer, PeerInner}; +use super::peer::PeerInner; use super::router::{message_data_len, Callbacks}; use super::tun::Tun; use super::types::KeyPair; use super::udp::UDP; +use super::WireGuard; pub struct Timers { // only updated during configuration @@ -229,7 +231,35 @@ impl<T: Tun, B: UDP> PeerInner<T, B> { } impl Timers { - pub fn new<T: Tun, B: UDP>(runner: &Runner, running: bool, peer: Peer<T, B>) -> Timers { + pub fn new<T: Tun, B: UDP>( + wg: WireGuard<T, B>, // WireGuard device + pk: PublicKey, // public key of peer + running: bool, // timers started + ) -> Timers { + macro_rules! fetch_peer { + ( $wg:expr, $pk:expr ) => { + match $wg.lookup_peer(&$pk) { + None => { + return; + } + Some(peer) => peer, + } + }; + } + + macro_rules! fetch_timer { + ( $peer:expr ) => {{ + let timers = $peer.timers(); + if timers.enabled { + timers + } else { + return; + } + }}; + } + + let runner = wg.runner.lock(); + // create a timer instance for the provided peer Timers { enabled: running, @@ -238,21 +268,16 @@ impl Timers { sent_lastminute_handshake: AtomicBool::new(false), handshake_attempts: AtomicUsize::new(0), retransmit_handshake: { - let peer = peer.clone(); + let wg = wg.clone(); + let pk = pk.clone(); runner.timer(move || { + // fetch peer by public key + let peer = fetch_peer!(wg, pk); + let timers = fetch_timer!(peer); log::trace!("{} : timer fired (retransmit_handshake)", peer); - // ignore if timers are disabled - let timers = peer.timers(); - if !timers.enabled { - return; - } - // check if handshake attempts remaining - let attempts = peer - .timers() - .handshake_attempts - .fetch_add(1, Ordering::SeqCst); + let attempts = timers.handshake_attempts.fetch_add(1, Ordering::SeqCst); if attempts > MAX_TIMER_HANDSHAKES { debug!( "Handshake for peer {} did not complete after {} attempts, giving up", @@ -261,7 +286,7 @@ impl Timers { ); timers.send_keepalive.stop(); timers.zero_key_material.start(REJECT_AFTER_TIME * 3); - peer.router.purge_staged_packets(); + peer.purge_staged_packets(); } else { debug!( "Handshake for {} did not complete after {} seconds, retrying (try {})", @@ -270,56 +295,72 @@ impl Timers { attempts ); timers.retransmit_handshake.reset(REKEY_TIMEOUT); - peer.router.clear_src(); + peer.clear_src(); peer.packet_send_queued_handshake_initiation(true); } }) }, send_keepalive: { - let peer = peer.clone(); + let wg = wg.clone(); + let pk = pk.clone(); runner.timer(move || { + // fetch peer by public key + let peer = fetch_peer!(wg, pk); + let timers = fetch_timer!(peer); log::trace!("{} : timer fired (send_keepalive)", peer); - // ignore if timers are disabled - let timers = peer.timers(); - if !timers.enabled { - return; - } - - peer.router.send_keepalive(); + // send keepalive and schedule next keepalive + peer.send_keepalive(); if timers.need_another_keepalive() { timers.send_keepalive.start(KEEPALIVE_TIMEOUT); } }) }, new_handshake: { - let peer = peer.clone(); + let wg = wg.clone(); + let pk = pk.clone(); runner.timer(move || { + // fetch peer by public key + let peer = fetch_peer!(wg, pk); + let _timers = fetch_timer!(peer); log::trace!("{} : timer fired (new_handshake)", peer); + + // clear source and retry log::debug!( "Retrying handshake with {} because we stopped hearing back after {} seconds", peer, (KEEPALIVE_TIMEOUT + REKEY_TIMEOUT).as_secs() ); - peer.router.clear_src(); + peer.clear_src(); peer.packet_send_queued_handshake_initiation(false); }) }, zero_key_material: { - let peer = peer.clone(); + let wg = wg.clone(); + let pk = pk.clone(); runner.timer(move || { + // fetch peer by public key + let peer = fetch_peer!(wg, pk); + let _timers = fetch_timer!(peer); log::trace!("{} : timer fired (zero_key_material)", peer); - peer.router.zero_keys(); + + // null all key-material + peer.zero_keys(); }) }, send_persistent_keepalive: { - let peer = peer.clone(); + let wg = wg.clone(); + let pk = pk.clone(); runner.timer(move || { + // fetch peer by public key + let peer = fetch_peer!(wg, pk); + let timers = fetch_timer!(peer); log::trace!("{} : timer fired (send_persistent_keepalive)", peer); - let timers = peer.timers(); - if timers.enabled && timers.keepalive_interval > 0 { + + // send and schedule persistent keepalive + if timers.keepalive_interval > 0 { timers.send_keepalive.stop(); - peer.router.send_keepalive(); + peer.send_keepalive(); log::trace!("{} : keepalive queued", peer); timers .send_persistent_keepalive @@ -329,28 +370,10 @@ impl Timers { }, } } - - pub fn dummy(runner: &Runner) -> Timers { - Timers { - enabled: false, - keepalive_interval: 0, - need_another_keepalive: AtomicBool::new(false), - sent_lastminute_handshake: AtomicBool::new(false), - handshake_attempts: AtomicUsize::new(0), - retransmit_handshake: runner.timer(|| {}), - new_handshake: runner.timer(|| {}), - send_keepalive: runner.timer(|| {}), - send_persistent_keepalive: runner.timer(|| {}), - zero_key_material: runner.timer(|| {}), - } - } } -/* instance of the router callbacks */ -pub struct Events<T, B>(PhantomData<(T, B)>); - -impl<T: Tun, B: UDP> Callbacks for Events<T, B> { - type Opaque = Arc<PeerInner<T, B>>; +impl<T: Tun, B: UDP> Callbacks for PeerInner<T, B> { + type Opaque = Self; /* Called after the router encrypts a transport message destined for the peer. * This method is called, even if the encrypted payload is empty (keepalive) |