aboutsummaryrefslogtreecommitdiffstats
path: root/src/wireguard/timers.rs
diff options
context:
space:
mode:
authorMathias Hall-Andersen <mathias@hall-andersen.dk>2019-11-06 13:50:38 +0100
committerMathias Hall-Andersen <mathias@hall-andersen.dk>2019-11-06 13:50:38 +0100
commit293914e47b046f862608a1af91864b6b38336aa5 (patch)
treec6851f4c0e8cd38efdcbc2aa6999395f67f1e555 /src/wireguard/timers.rs
parentWork on Up/Down operation on WireGuard device (diff)
downloadwireguard-rs-293914e47b046f862608a1af91864b6b38336aa5.tar.xz
wireguard-rs-293914e47b046f862608a1af91864b6b38336aa5.zip
Implement disable/enable timers
Diffstat (limited to '')
-rw-r--r--src/wireguard/timers.rs148
1 files changed, 90 insertions, 58 deletions
diff --git a/src/wireguard/timers.rs b/src/wireguard/timers.rs
index e844f4d..038f6c6 100644
--- a/src/wireguard/timers.rs
+++ b/src/wireguard/timers.rs
@@ -13,7 +13,9 @@ use super::{bind, tun};
use super::types::KeyPair;
pub struct Timers {
+ // only updated during configuration
enabled: bool,
+ keepalive_interval: u64,
handshake_attempts: AtomicUsize,
sent_lastminute_handshake: AtomicBool,
@@ -68,27 +70,26 @@ impl<B: bind::Bind> PeerInner<B> {
timers.enabled = true;
// start send_persistent_keepalive
- let interval = self.keepalive_interval.load(Ordering::Acquire);
- if interval > 0 {
+ if timers.keepalive_interval > 0 {
timers.send_persistent_keepalive.start(
- Duration::from_secs(interval)
+ Duration::from_secs(timers.keepalive_interval)
);
}
}
/* should be called after an authenticated data packet is sent */
pub fn timers_data_sent(&self) {
- self.timers()
- .new_handshake
- .start(KEEPALIVE_TIMEOUT + REKEY_TIMEOUT);
+ let timers = self.timers();
+ if timers.enabled {
+ timers.new_handshake.start(KEEPALIVE_TIMEOUT + REKEY_TIMEOUT);
+ }
}
/* should be called after an authenticated data packet is received */
pub fn timers_data_received(&self) {
- if !self.timers().send_keepalive.start(KEEPALIVE_TIMEOUT) {
- self.timers()
- .need_another_keepalive
- .store(true, Ordering::SeqCst)
+ let timers = self.timers();
+ if timers.enabled && !timers.send_keepalive.start(KEEPALIVE_TIMEOUT) {
+ timers.need_another_keepalive.store(true, Ordering::SeqCst)
}
}
@@ -98,7 +99,10 @@ impl<B: bind::Bind> PeerInner<B> {
* - handshake
*/
pub fn timers_any_authenticated_packet_sent(&self) {
- self.timers().send_keepalive.stop()
+ let timers = self.timers();
+ if timers.enabled {
+ timers.send_keepalive.stop()
+ }
}
/* Should be called after any type of authenticated packet is received, whether:
@@ -107,48 +111,69 @@ impl<B: bind::Bind> PeerInner<B> {
* - handshake
*/
pub fn timers_any_authenticated_packet_received(&self) {
- self.timers().new_handshake.stop();
+ let timers = self.timers();
+ if timers.enabled {
+ timers.new_handshake.stop();
+ }
}
/* Should be called after a handshake initiation message is sent. */
pub fn timers_handshake_initiated(&self) {
- self.timers().send_keepalive.stop();
- self.timers().retransmit_handshake.reset(REKEY_TIMEOUT);
+ let timers = self.timers();
+ if timers.enabled {
+ timers.send_keepalive.stop();
+ timers.retransmit_handshake.reset(REKEY_TIMEOUT);
+ }
}
/* Should be called after a handshake response message is received and processed
* or when getting key confirmation via the first data message.
*/
pub fn timers_handshake_complete(&self) {
- self.timers().handshake_attempts.store(0, Ordering::SeqCst);
- self.timers()
- .sent_lastminute_handshake
- .store(false, Ordering::SeqCst);
- *self.walltime_last_handshake.lock() = SystemTime::now();
+ let timers = self.timers();
+ if timers.enabled {
+ timers.handshake_attempts.store(0, Ordering::SeqCst);
+ timers.sent_lastminute_handshake.store(false, Ordering::SeqCst);
+ *self.walltime_last_handshake.lock() = SystemTime::now();
+ }
}
/* Should be called after an ephemeral key is created, which is before sending a
* handshake response or after receiving a handshake response.
*/
pub fn timers_session_derived(&self) {
- self.timers().zero_key_material.reset(REJECT_AFTER_TIME * 3);
+ let timers = self.timers();
+ if timers.enabled {
+ timers.zero_key_material.reset(REJECT_AFTER_TIME * 3);
+ }
}
/* Should be called before a packet with authentication, whether
* keepalive, data, or handshake is sent, or after one is received.
*/
pub fn timers_any_authenticated_packet_traversal(&self) {
- let keepalive = self.keepalive_interval.load(Ordering::Acquire);
- if keepalive > 0 {
+ let timers = self.timers();
+ if timers.enabled && timers.keepalive_interval > 0 {
// push persistent_keepalive into the future
- self.timers()
- .send_persistent_keepalive
- .reset(Duration::from_secs(keepalive as u64));
+ timers.send_persistent_keepalive.reset(Duration::from_secs(
+ timers.keepalive_interval
+ ));
}
}
pub fn timers_session_derieved(&self) {
- self.timers().zero_key_material.reset(REJECT_AFTER_TIME * 3);
+ let timers = self.timers();
+ if timers.enabled {
+ timers.zero_key_material.reset(REJECT_AFTER_TIME * 3);
+ }
+ }
+
+ fn timers_set_retransmit_handshake(&self) {
+ let timers = self.timers();
+ if timers.enabled {
+ timers.retransmit_handshake.reset(REKEY_TIMEOUT);
+ }
+
}
/* Called after a handshake worker sends a handshake initiation to the peer
@@ -156,7 +181,7 @@ impl<B: bind::Bind> PeerInner<B> {
pub fn sent_handshake_initiation(&self) {
*self.last_handshake_sent.lock() = Instant::now();
self.handshake_queued.store(false, Ordering::SeqCst);
- self.timers().retransmit_handshake.reset(REKEY_TIMEOUT);
+ self.timers_set_retransmit_handshake();
self.timers_any_authenticated_packet_traversal();
self.timers_any_authenticated_packet_sent();
}
@@ -168,13 +193,18 @@ impl<B: bind::Bind> PeerInner<B> {
}
- pub fn set_persistent_keepalive_interval(&self, interval: u64) {
- self.timers().send_persistent_keepalive.stop();
- self.keepalive_interval.store(interval, Ordering::SeqCst);
- if interval > 0 {
- self.timers()
- .send_persistent_keepalive
- .start(Duration::from_secs(interval as u64));
+ pub fn set_persistent_keepalive_interval(&self, secs: u64) {
+ let mut timers = self.timers_mut();
+
+ // update the stored keepalive_interval
+ timers.keepalive_interval = secs;
+
+ // stop the keepalive timer with the old interval
+ timers.send_persistent_keepalive.stop();
+
+ // restart the persistent_keepalive timer with the new interval
+ if secs > 0 && timers.enabled {
+ timers.send_persistent_keepalive.start(Duration::from_secs(secs));
}
}
@@ -184,8 +214,6 @@ impl<B: bind::Bind> PeerInner<B> {
}
self.packet_send_handshake_initiation();
}
-
-
}
@@ -198,12 +226,20 @@ impl Timers {
// create a timer instance for the provided peer
Timers {
enabled: true,
+ keepalive_interval: 0, // disabled
need_another_keepalive: AtomicBool::new(false),
sent_lastminute_handshake: AtomicBool::new(false),
handshake_attempts: AtomicUsize::new(0),
retransmit_handshake: {
let peer = peer.clone();
runner.timer(move || {
+ // 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);
if attempts > MAX_TIMER_HANDSHAKES {
debug!(
@@ -211,9 +247,9 @@ impl Timers {
peer,
attempts + 1
);
+ timers.send_keepalive.stop();
+ timers.zero_key_material.start(REJECT_AFTER_TIME * 3);
peer.router.purge_staged_packets();
- peer.timers().send_keepalive.stop();
- peer.timers().zero_key_material.start(REJECT_AFTER_TIME * 3);
} else {
debug!(
"Handshake for {} did not complete after {} seconds, retrying (try {})",
@@ -221,8 +257,8 @@ impl Timers {
REKEY_TIMEOUT.as_secs(),
attempts
);
+ timers.retransmit_handshake.reset(REKEY_TIMEOUT);
peer.router.clear_src();
- peer.timers().retransmit_handshake.reset(REKEY_TIMEOUT);
peer.packet_send_queued_handshake_initiation(true);
}
})
@@ -230,9 +266,15 @@ impl Timers {
send_keepalive: {
let peer = peer.clone();
runner.timer(move || {
+ // ignore if timers are disabled
+ let timers = peer.timers();
+ if !timers.enabled {
+ return;
+ }
+
peer.router.send_keepalive();
- if peer.timers().need_another_keepalive() {
- peer.timers().send_keepalive.start(KEEPALIVE_TIMEOUT);
+ if timers.need_another_keepalive() {
+ timers.send_keepalive.start(KEEPALIVE_TIMEOUT);
}
})
},
@@ -257,29 +299,23 @@ impl Timers {
send_persistent_keepalive: {
let peer = peer.clone();
runner.timer(move || {
- let keepalive = peer.state.keepalive_interval.load(Ordering::Acquire);
- if keepalive > 0 {
+ let timers = peer.timers();
+ if timers.enabled && timers.keepalive_interval > 0 {
peer.router.send_keepalive();
- peer.timers().send_keepalive.stop();
- peer.timers()
- .send_persistent_keepalive
- .start(Duration::from_secs(keepalive as u64));
+ timers.send_keepalive.stop();
+ timers.send_persistent_keepalive.start(Duration::from_secs(
+ timers.keepalive_interval
+ ));
}
})
},
}
}
- pub fn updated_persistent_keepalive(&self, keepalive: usize) {
- if keepalive > 0 {
- self.send_persistent_keepalive
- .reset(Duration::from_secs(keepalive as u64));
- }
- }
-
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),
@@ -290,10 +326,6 @@ impl Timers {
zero_key_material: runner.timer(|| {}),
}
}
-
- pub fn handshake_sent(&self) {
- self.send_keepalive.stop();
- }
}
/* Instance of the router callbacks */