From 6e828b7ae8726657ad05c06cfa0908484849e313 Mon Sep 17 00:00:00 2001 From: Dennis Schwerdel Date: Tue, 30 Aug 2016 08:52:22 +0200 Subject: [PATCH] Not overriding recently learned addresses in switch mode --- CHANGELOG.md | 2 ++ src/cloud.rs | 10 +++++++--- src/ethernet.rs | 19 ++++++++++++++++--- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b9c409..d1f546d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ This project follows [semantic versioning](http://semver.org). - [added] Support for automatic port forwarding via UPnP - [added] Added `-s` shorthand for `--subnet` - [added] Support for YAML config file via `--config` +- [changed] Not overriding recently learnt addresses in switch mode +- [changed] Caching resolved addresses to increase performance - [changed] Configurable magic header is now used instead of Network-ID (**incompatible**) - [changed] Clarified documentation on TUN netmasks - [changed] Added timestamps to output diff --git a/src/cloud.rs b/src/cloud.rs index 585d60b..e8af439 100644 --- a/src/cloud.rs +++ b/src/cloud.rs @@ -29,6 +29,10 @@ use super::poll::{self, Poll}; type Hash = BuildHasherDefault; +const MAX_RECONNECT_INTERVAL: u16 = 3600; +const RESOLVE_INTERVAL: Time = 300; + + struct PeerList { timeout: Duration, peers: HashMap), Hash>, @@ -404,7 +408,7 @@ impl GenericCloud

{ if let Ok(addrs) = resolve(&entry.address as &str) { entry.resolved = addrs; } - entry.next_resolve = now + 60; + entry.next_resolve = now + RESOLVE_INTERVAL; } // Ignore if next attempt is already in the future if entry.next > now { @@ -417,8 +421,8 @@ impl GenericCloud

{ entry.timeout *= 2; } // Maximum interval is one hour - if entry.timeout > 3600 { - entry.timeout = 3600; + if entry.timeout > MAX_RECONNECT_INTERVAL { + entry.timeout = MAX_RECONNECT_INTERVAL; } // Schedule next connection attempt entry.next = now + entry.timeout as Time; diff --git a/src/ethernet.rs b/src/ethernet.rs index 0271dee..de8b8e8 100644 --- a/src/ethernet.rs +++ b/src/ethernet.rs @@ -4,6 +4,7 @@ use std::net::SocketAddr; use std::collections::HashMap; +use std::collections::hash_map::Entry; use std::hash::BuildHasherDefault; use fnv::FnvHasher; @@ -99,9 +100,21 @@ impl Table for SwitchTable { /// Learns the given address, inserting it in the hash map #[inline] fn learn(&mut self, key: Address, _prefix_len: Option, addr: SocketAddr) { - let value = SwitchTableValue{address: addr, timeout: now()+self.timeout as Time}; - if self.table.insert(key, value).is_none() { - info!("Learned address {} => {}", key, addr); + let deadline = now() + self.timeout as Time; + match self.table.entry(key) { + Entry::Vacant(entry) => { + entry.insert(SwitchTableValue{address: addr, timeout: deadline}); + info!("Learned address {} => {}", key, addr); + }, + Entry::Occupied(mut entry) => { + let mut entry = entry.get_mut(); + if entry.timeout + 10 >= deadline { + // Do not override recently learnt entries + return + } + entry.timeout = deadline; + entry.address = addr; + } } }