Reduced timeout to 5min to work better with NAT

This commit is contained in:
Dennis Schwerdel 2019-12-22 23:03:45 +01:00
parent 10ebd08dad
commit 54a2240f34
8 changed files with 23 additions and 32 deletions

View File

@ -5,7 +5,7 @@ This project follows [semantic versioning](http://semver.org).
### Unreleased ### Unreleased
- [changed] Improved port forwarding on quirky routers - [changed] Improved port forwarding on quirky routers
- [changed] Reduced peer timeout to 5min to work better with NAT
### v1.2.1 (2019-12-22) ### v1.2.1 (2019-12-22)

View File

@ -21,7 +21,7 @@
# Peer timeout in seconds. The peers will exchange information periodically # Peer timeout in seconds. The peers will exchange information periodically
# and drop peers that are silent for this period of time. # and drop peers that are silent for this period of time.
#peer_timeout: 1800 #peer_timeout: 600
# Switch table entry timeout in seconds. This parameter is only used in switch # Switch table entry timeout in seconds. This parameter is only used in switch
# mode. Addresses that have not been seen for the given period of time will # mode. Addresses that have not been seen for the given period of time will

View File

@ -19,7 +19,7 @@ use rand::{prelude::*, random, thread_rng};
use super::{ use super::{
beacon::BeaconSerializer, beacon::BeaconSerializer,
config::Config, config::{Config, DEFAULT_PEER_TIMEOUT},
crypto::Crypto, crypto::Crypto,
device::Device, device::Device,
net::Socket, net::Socket,
@ -86,7 +86,7 @@ impl<TS: TimeSource> PeerList<TS> {
} }
pub fn min_peer_timeout(&self) -> u16 { pub fn min_peer_timeout(&self) -> u16 {
self.peers.iter().map(|p| p.1.peer_timeout).min().unwrap_or(1800) self.peers.iter().map(|p| p.1.peer_timeout).min().unwrap_or(DEFAULT_PEER_TIMEOUT)
} }
#[inline] #[inline]
@ -257,12 +257,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
Err(err) => fail!("Failed to open ipv6 address ::{}: {}", config.port, err) Err(err) => fail!("Failed to open ipv6 address ::{}: {}", config.port, err)
}; };
let now = TS::now(); let now = TS::now();
let update_freq = if socket4.detect_nat() && config.get_keepalive() > 120 { let update_freq = config.get_keepalive() as u16;
info!("Private IP detected, setting keepalive interval to 120s");
120
} else {
config.get_keepalive() as u16
};
let mut res = GenericCloud { let mut res = GenericCloud {
magic: config.get_magic(), magic: config.get_magic(),
node_id: random(), node_id: random(),

View File

@ -16,6 +16,7 @@ use std::hash::{Hash, Hasher};
const HASH_PREFIX: &str = "hash:"; const HASH_PREFIX: &str = "hash:";
pub const DEFAULT_PEER_TIMEOUT: u16 = 600;
#[derive(Deserialize, Debug, PartialEq, Clone)] #[derive(Deserialize, Debug, PartialEq, Clone)]
@ -59,7 +60,7 @@ impl Default for Config {
magic: None, magic: None,
port: 3210, port: 3210,
peers: vec![], peers: vec![],
peer_timeout: 1800, peer_timeout: DEFAULT_PEER_TIMEOUT as Duration,
keepalive: None, keepalive: None,
beacon_store: None, beacon_store: None,
beacon_load: None, beacon_load: None,
@ -296,7 +297,7 @@ port: 3210
peers: peers:
- remote.machine.foo:3210 - remote.machine.foo:3210
- remote.machine.bar:3210 - remote.machine.bar:3210
peer_timeout: 1800 peer_timeout: 600
keepalive: 840 keepalive: 840
dst_timeout: 300 dst_timeout: 300
beacon_store: /run/vpncloud.beacon.out beacon_store: /run/vpncloud.beacon.out
@ -322,7 +323,7 @@ stats_file: /var/log/vpncloud.stats
magic: Some("0123ABCD".to_string()), magic: Some("0123ABCD".to_string()),
port: Some(3210), port: Some(3210),
peers: Some(vec!["remote.machine.foo:3210".to_string(), "remote.machine.bar:3210".to_string()]), peers: Some(vec!["remote.machine.foo:3210".to_string(), "remote.machine.bar:3210".to_string()]),
peer_timeout: Some(1800), peer_timeout: Some(600),
keepalive: Some(840), keepalive: Some(840),
beacon_store: Some("/run/vpncloud.beacon.out".to_string()), beacon_store: Some("/run/vpncloud.beacon.out".to_string()),
beacon_load: Some("/run/vpncloud.beacon.in".to_string()), beacon_load: Some("/run/vpncloud.beacon.in".to_string()),
@ -352,7 +353,7 @@ fn config_merge() {
magic: Some("0123ABCD".to_string()), magic: Some("0123ABCD".to_string()),
port: Some(3210), port: Some(3210),
peers: Some(vec!["remote.machine.foo:3210".to_string(), "remote.machine.bar:3210".to_string()]), peers: Some(vec!["remote.machine.foo:3210".to_string(), "remote.machine.bar:3210".to_string()]),
peer_timeout: Some(1800), peer_timeout: Some(600),
keepalive: Some(840), keepalive: Some(840),
beacon_store: Some("/run/vpncloud.beacon.out".to_string()), beacon_store: Some("/run/vpncloud.beacon.out".to_string()),
beacon_load: Some("/run/vpncloud.beacon.in".to_string()), beacon_load: Some("/run/vpncloud.beacon.in".to_string()),
@ -377,7 +378,7 @@ fn config_merge() {
shared_key: Some("mysecret".to_string()), shared_key: Some("mysecret".to_string()),
port: 3210, port: 3210,
peers: vec!["remote.machine.foo:3210".to_string(), "remote.machine.bar:3210".to_string()], peers: vec!["remote.machine.foo:3210".to_string(), "remote.machine.bar:3210".to_string()],
peer_timeout: 1800, peer_timeout: 600,
keepalive: Some(840), keepalive: Some(840),
dst_timeout: 300, dst_timeout: 300,
beacon_store: Some("/run/vpncloud.beacon.out".to_string()), beacon_store: Some("/run/vpncloud.beacon.out".to_string()),

View File

@ -6,7 +6,7 @@ use std::{
sync::atomic::{AtomicBool, Ordering} sync::atomic::{AtomicBool, Ordering}
}; };
use super::util::{get_internal_ip, MockTimeSource, Time, TimeSource}; use super::util::{MockTimeSource, Time, TimeSource};
use net2::UdpBuilder; use net2::UdpBuilder;
@ -17,7 +17,6 @@ pub trait Socket: AsRawFd + Sized {
fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), io::Error>; fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), io::Error>;
fn send(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize, io::Error>; fn send(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize, io::Error>;
fn address(&self) -> Result<SocketAddr, io::Error>; fn address(&self) -> Result<SocketAddr, io::Error>;
fn detect_nat(&self) -> bool;
} }
impl Socket for UdpSocket { impl Socket for UdpSocket {
@ -40,9 +39,6 @@ impl Socket for UdpSocket {
fn address(&self) -> Result<SocketAddr, io::Error> { fn address(&self) -> Result<SocketAddr, io::Error> {
self.local_addr() self.local_addr()
} }
fn detect_nat(&self) -> bool {
get_internal_ip().is_private()
}
} }
thread_local! { thread_local! {
@ -129,7 +125,4 @@ impl Socket for MockSocket {
fn address(&self) -> Result<SocketAddr, io::Error> { fn address(&self) -> Result<SocketAddr, io::Error> {
Ok(self.address) Ok(self.address)
} }
fn detect_nat(&self) -> bool {
self.nat
}
} }

View File

@ -18,24 +18,24 @@ fn connect_v4() {
node1.connect("2.3.4.5:6789").unwrap(); node1.connect("2.3.4.5:6789").unwrap();
// Node 1 -> Node 2: Init 0 // Node 1 -> Node 2: Init 0
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![], 1800)); assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![], 600));
assert_clean!(node1); assert_clean!(node1);
assert!(node2.peers().contains_node(&node1.node_id())); assert!(node2.peers().contains_node(&node1.node_id()));
// Node 2 -> Node 1: Init 1 | Node 2 -> Node 1: Peers // Node 2 -> Node 1: Init 1 | Node 2 -> Node 1: Peers
assert_message4!(node2, node2_addr, node1, node1_addr, Message::Init(1, node2.node_id(), vec![], 1800)); assert_message4!(node2, node2_addr, node1, node1_addr, Message::Init(1, node2.node_id(), vec![], 600));
assert!(node1.peers().contains_node(&node2.node_id())); assert!(node1.peers().contains_node(&node2.node_id()));
assert_message4!(node2, node2_addr, node1, node1_addr, Message::Peers(vec![node1_addr])); assert_message4!(node2, node2_addr, node1, node1_addr, Message::Peers(vec![node1_addr]));
assert_clean!(node2); assert_clean!(node2);
// Node 1 -> Node 2: Peers | Node 1 -> Node 1: Init 0 // Node 1 -> Node 2: Peers | Node 1 -> Node 1: Init 0
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Peers(vec![node2_addr])); assert_message4!(node1, node1_addr, node2, node2_addr, Message::Peers(vec![node2_addr]));
assert_message4!(node1, node1_addr, node1, node1_addr, Message::Init(0, node1.node_id(), vec![], 1800)); assert_message4!(node1, node1_addr, node1, node1_addr, Message::Init(0, node1.node_id(), vec![], 600));
assert!(node1.own_addresses().contains(&node1_addr)); assert!(node1.own_addresses().contains(&node1_addr));
assert_clean!(node1); assert_clean!(node1);
// Node 2 -> Node 2: Init 0 // Node 2 -> Node 2: Init 0
assert_message4!(node2, node2_addr, node2, node2_addr, Message::Init(0, node2.node_id(), vec![], 1800)); assert_message4!(node2, node2_addr, node2, node2_addr, Message::Init(0, node2.node_id(), vec![], 600));
assert_clean!(node2); assert_clean!(node2);
assert!(node2.own_addresses().contains(&node2_addr)); assert!(node2.own_addresses().contains(&node2_addr));
@ -158,7 +158,7 @@ fn lost_init1() {
node1.connect("2.3.4.5:6789").unwrap(); node1.connect("2.3.4.5:6789").unwrap();
// Node 1 -> Node 2: Init 0 // Node 1 -> Node 2: Init 0
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![], 1800)); assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![], 600));
assert_clean!(node1); assert_clean!(node1);
// Node 2 -> Node 1: Init 1 | Node 2 -> Node 1: Peers // Node 2 -> Node 1: Init 1 | Node 2 -> Node 1: Peers
@ -179,7 +179,7 @@ fn wrong_magic() {
let node2_addr = addr!("2.3.4.5:6789"); let node2_addr = addr!("2.3.4.5:6789");
node1.connect("2.3.4.5:6789").unwrap(); node1.connect("2.3.4.5:6789").unwrap();
assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![], 1800)); assert_message4!(node1, node1_addr, node2, node2_addr, Message::Init(0, node1.node_id(), vec![], 600));
assert_clean!(node1, node2); assert_clean!(node1, node2);

View File

@ -8,6 +8,7 @@ use std::{
}; };
use super::{ use super::{
config::DEFAULT_PEER_TIMEOUT,
crypto::Crypto, crypto::Crypto,
types::{Error, HeaderMagic, NodeId, Range, NODE_ID_BYTES}, types::{Error, HeaderMagic, NodeId, Range, NODE_ID_BYTES},
util::{bytes_to_hex, Encoder} util::{bytes_to_hex, Encoder}
@ -190,7 +191,8 @@ pub fn decode<'a>(data: &'a mut [u8], magic: HeaderMagic, crypto: &Crypto) -> Re
pos += read; pos += read;
addrs.push(range); addrs.push(range);
} }
let peer_timeout = if data.len() >= pos + 2 { Encoder::read_u16(&data[pos..]) } else { 1800 }; let peer_timeout =
if data.len() >= pos + 2 { Encoder::read_u16(&data[pos..]) } else { DEFAULT_PEER_TIMEOUT };
Message::Init(stage, node_id, addrs, peer_timeout) Message::Init(stage, node_id, addrs, peer_timeout)
} }
3 => Message::Close, 3 => Message::Close,

View File

@ -78,7 +78,7 @@ vpncloud(1) -- Peer-to-peer VPN
* `--peer-timeout <secs>`: * `--peer-timeout <secs>`:
Peer timeout in seconds. The peers will exchange information periodically Peer timeout in seconds. The peers will exchange information periodically
and drop peers that are silent for this period of time. [default: `1800`] and drop peers that are silent for this period of time. [default: `600`]
* `--keepalive <secs>`: * `--keepalive <secs>`:
@ -338,7 +338,7 @@ port: 3210
peers: peers:
- remote.machine.foo:3210 - remote.machine.foo:3210
- remote.machine.bar:3210 - remote.machine.bar:3210
peer_timeout: 1800 peer_timeout: 600
mode: normal mode: normal
subnets: subnets:
- 10.0.1.0/24 - 10.0.1.0/24