aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJake McGinty <me@jake.su>2018-05-03 19:36:23 -0700
committerJake McGinty <me@jake.su>2018-05-03 19:36:23 -0700
commit5d48bc89c67a51bb9a699078477c9424fa947d97 (patch)
tree52636a54640fdb5ec7c7db3cdf8bf75ac0a1cc99
parenttests: disable test I know is failing for now before I implement that feature (diff)
downloadwireguard-rs-5d48bc89c67a51bb9a699078477c9424fa947d97.tar.xz
wireguard-rs-5d48bc89c67a51bb9a699078477c9424fa947d97.zip
timers: rewrite persistent keepalive code
-rw-r--r--src/interface/peer_server.rs28
-rw-r--r--src/peer.rs2
-rw-r--r--src/types.rs10
3 files changed, 26 insertions, 14 deletions
diff --git a/src/interface/peer_server.rs b/src/interface/peer_server.rs
index 2acbb6a..7ad6d15 100644
--- a/src/interface/peer_server.rs
+++ b/src/interface/peer_server.rs
@@ -361,6 +361,9 @@ impl PeerServer {
if peer.sessions.current.is_none() {
self.timer.send_after(*KEEPALIVE_TIMEOUT, PassiveKeepAlive(peer_ref.clone(), our_index));
bail!("no active session. waiting until there is one.");
+ } else if peer.info.keepalive.is_some() {
+ self.timer.send_after(*KEEPALIVE_TIMEOUT, PassiveKeepAlive(peer_ref.clone(), our_index));
+ bail!("persistent keepalive set, no passive keepalive needed.");
}
let since_last_recv = peer.timers.data_received.elapsed();
@@ -388,21 +391,20 @@ impl PeerServer {
},
PersistentKeepAlive(peer_ref, our_index) => {
let mut peer = peer_ref.borrow_mut();
- {
- if peer.info.keepalive.is_none() {
- bail!("no persistent keepalive set for peer (likely unset between the time the timer was started and now).");
- }
-
- let (_, session_type) = peer.find_session(our_index).ok_or_else(|| err_msg("missing session for timer"))?;
- ensure!(session_type == SessionType::Current, "expired session for persistent keepalive timer");
- }
- self.send_to_peer(peer.handle_outgoing_transport(&[])?)?;
- debug!("sent persistent keepalive packet ({})", our_index);
+ if let Some(persistent_keepalive) = peer.info.persistent_keepalive() {
+ let since_last_auth_any = peer.timers.authenticated_traversed.elapsed();
+ if since_last_auth_any < persistent_keepalive {
+ let wait = persistent_keepalive - since_last_auth_any;
+ self.timer.send_after(wait, PersistentKeepAlive(peer_ref.clone(), our_index));
+ bail!("persistent keepalive tick (waiting ~{}s due to last authenticated packet time)", wait.as_secs());
+ }
- if let Some(keepalive) = peer.info.keepalive {
- self.timer.send_after(Duration::from_secs(u64::from(keepalive)),
- PersistentKeepAlive(peer_ref.clone(), our_index));
+ self.send_to_peer(peer.handle_outgoing_transport(&[])?)?;
+ self.timer.send_after(persistent_keepalive, PersistentKeepAlive(peer_ref.clone(), our_index));
+ debug!("sent persistent keepalive packet ({})", our_index);
+ } else {
+ bail!("no persistent keepalive set for peer (likely unset between the time the timer was started and now).");
}
},
Wipe(peer_ref) => {
diff --git a/src/peer.rs b/src/peer.rs
index 558c25a..7b5107b 100644
--- a/src/peer.rs
+++ b/src/peer.rs
@@ -360,7 +360,7 @@ impl Peer {
}
self.timers.authenticated_received = Timestamp::now();
self.timers.authenticated_traversed = Timestamp::now();
- self.timers.keepalive_sent = false; // reset passive keepalive token since received a valid ingress transport
+ self.timers.keepalive_sent = false; // reset passive keepalive token since received a valid ingress transport
let transition = if session_type == SessionType::Next {
debug!("moving 'next' session to current after receiving first transport packet");
diff --git a/src/types.rs b/src/types.rs
index 3ed6f64..77a104d 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -1,6 +1,7 @@
use base64;
use std::fmt::{self, Display, Formatter};
use std::net::IpAddr;
+use std::time::Duration;
use udp::Endpoint;
#[derive(Clone, Debug, Default)]
@@ -12,6 +13,15 @@ pub struct PeerInfo {
pub keepalive: Option<u16>,
}
+impl PeerInfo {
+ pub fn persistent_keepalive(&self) -> Option<Duration> {
+ match self.keepalive {
+ Some(keepalive) if keepalive > 0 => Some(Duration::from_secs(u64::from(keepalive))),
+ _ => None
+ }
+ }
+}
+
impl Display for PeerInfo {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let encoded = base64::encode(&self.pub_key);