mirror of https://github.com/dswd/vpncloud.git
Reducing published peer timeout to 5 min on NAT
This commit is contained in:
parent
ee8542307f
commit
9cd7e53880
|
@ -4,6 +4,8 @@ This project follows [semantic versioning](http://semver.org).
|
|||
|
||||
### Unreleased
|
||||
|
||||
- [added] Exchange peer timeout and adapt keepalive accordingly
|
||||
- [added] Reducing published peer timeout to 5 min when NAT is detected
|
||||
- [changed] Rust version 1.41.0
|
||||
- [changed] Updated dependencies
|
||||
|
||||
|
|
16
src/cloud.rs
16
src/cloud.rs
|
@ -227,6 +227,7 @@ pub struct GenericCloud<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSou
|
|||
device: D,
|
||||
crypto: Crypto,
|
||||
next_peerlist: Time,
|
||||
peer_timeout_publish: u16,
|
||||
update_freq: u16,
|
||||
buffer_out: [u8; 64 * 1024],
|
||||
next_housekeep: Time,
|
||||
|
@ -255,15 +256,22 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
|||
Err(err) => fail!("Failed to open ipv6 address ::{}: {}", config.port, err)
|
||||
};
|
||||
let now = TS::now();
|
||||
let peer_timeout_publish = if S::detect_nat() {
|
||||
info!("Private IP detected, setting published peer timeout to 300s");
|
||||
300
|
||||
} else {
|
||||
config.peer_timeout as u16
|
||||
};
|
||||
let mut res = GenericCloud {
|
||||
magic: config.get_magic(),
|
||||
node_id: random(),
|
||||
peers: PeerList::new(config.peer_timeout as Duration),
|
||||
peers: PeerList::new(config.peer_timeout),
|
||||
addresses,
|
||||
learning,
|
||||
broadcast,
|
||||
reconnect_peers: Vec::new(),
|
||||
own_addresses: Vec::new(),
|
||||
peer_timeout_publish,
|
||||
table,
|
||||
socket4,
|
||||
socket6,
|
||||
|
@ -414,7 +422,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
|||
// Send a message to each resolved address
|
||||
for a in resolve(&addr)? {
|
||||
// Ignore error this time
|
||||
let mut msg = Message::Init(0, node_id, subnets.clone(), self.config.peer_timeout as u16);
|
||||
let mut msg = Message::Init(0, node_id, subnets.clone(), self.peer_timeout_publish);
|
||||
self.send_msg(a, &mut msg).ok();
|
||||
}
|
||||
Ok(())
|
||||
|
@ -435,7 +443,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
|||
debug!("Connecting to {:?}", addr);
|
||||
let subnets = self.addresses.clone();
|
||||
let node_id = self.node_id;
|
||||
let mut msg = Message::Init(0, node_id, subnets.clone(), self.config.peer_timeout as u16);
|
||||
let mut msg = Message::Init(0, node_id, subnets.clone(), self.peer_timeout_publish);
|
||||
self.send_msg(addr, &mut msg)
|
||||
}
|
||||
|
||||
|
@ -725,7 +733,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
|
|||
let own_node_id = self.node_id;
|
||||
self.send_msg(
|
||||
peer,
|
||||
&mut Message::Init(stage + 1, own_node_id, own_addrs, self.config.peer_timeout as u16)
|
||||
&mut Message::Init(stage + 1, own_node_id, own_addrs, self.peer_timeout_publish)
|
||||
)?;
|
||||
}
|
||||
// Send peers in any case
|
||||
|
|
|
@ -5,6 +5,8 @@ use std::{
|
|||
os::unix::io::{AsRawFd, RawFd}
|
||||
};
|
||||
|
||||
use super::util::get_internal_ip;
|
||||
|
||||
use net2::UdpBuilder;
|
||||
|
||||
|
||||
|
@ -14,6 +16,7 @@ pub trait Socket: AsRawFd + Sized {
|
|||
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 address(&self) -> Result<SocketAddr, io::Error>;
|
||||
fn detect_nat() -> bool;
|
||||
}
|
||||
|
||||
impl Socket for UdpSocket {
|
||||
|
@ -42,6 +45,9 @@ impl Socket for UdpSocket {
|
|||
fn address(&self) -> Result<SocketAddr, io::Error> {
|
||||
self.local_addr()
|
||||
}
|
||||
fn detect_nat() -> bool {
|
||||
get_internal_ip().is_private()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -95,4 +101,7 @@ impl Socket for MockSocket {
|
|||
fn address(&self) -> Result<SocketAddr, io::Error> {
|
||||
Ok(self.address)
|
||||
}
|
||||
fn detect_nat() -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,16 +2,13 @@
|
|||
// Copyright (C) 2015-2019 Dennis Schwerdel
|
||||
// This software is licensed under GPL-3 or newer (see LICENSE.md)
|
||||
|
||||
use std::{
|
||||
io,
|
||||
net::{SocketAddr, SocketAddrV4, UdpSocket}
|
||||
};
|
||||
use std::{io, net::SocketAddrV4};
|
||||
|
||||
use igd::*;
|
||||
|
||||
use super::util::{SystemTimeSource, Time, TimeSource};
|
||||
use super::util::{get_internal_ip, SystemTimeSource, Time, TimeSource};
|
||||
|
||||
const LEASE_TIME: u32 = 300;
|
||||
const LEASE_TIME: u32 = 1800;
|
||||
const DESCRIPTION: &str = "VpnCloud";
|
||||
|
||||
|
||||
|
@ -40,16 +37,7 @@ impl PortForwarding {
|
|||
}
|
||||
};
|
||||
info!("Port-forwarding: found router at {}", gateway.addr);
|
||||
// Get the internal address (this trick gets the address by opening a UDP connection which
|
||||
// does not really open anything but returns the correct address)
|
||||
let dummy_sock = UdpSocket::bind("0.0.0.0:0").expect("Failed to bind");
|
||||
dummy_sock.connect(gateway.addr).expect("Failed to connect");
|
||||
let internal_addr;
|
||||
if let SocketAddr::V4(addr) = dummy_sock.local_addr().expect("Failed to get local address") {
|
||||
internal_addr = SocketAddrV4::new(*addr.ip(), port);
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
let internal_addr = SocketAddrV4::new(get_internal_ip(), port);
|
||||
// Query the external address
|
||||
let external_ip = match gateway.get_external_ip() {
|
||||
Ok(ip) => ip,
|
||||
|
|
14
src/util.rs
14
src/util.rs
|
@ -4,7 +4,7 @@
|
|||
|
||||
use std::{
|
||||
fmt,
|
||||
net::{SocketAddr, ToSocketAddrs},
|
||||
net::{Ipv4Addr, SocketAddr, ToSocketAddrs, UdpSocket},
|
||||
sync::atomic::{AtomicIsize, Ordering}
|
||||
};
|
||||
|
||||
|
@ -115,6 +115,18 @@ macro_rules! try_fail {
|
|||
} );
|
||||
}
|
||||
|
||||
pub fn get_internal_ip() -> Ipv4Addr {
|
||||
// Get the internal address (this trick gets the address by opening a UDP connection which
|
||||
// does not really open anything but returns the correct address)
|
||||
let dummy_sock = UdpSocket::bind("0.0.0.0:0").expect("Failed to bind");
|
||||
dummy_sock.connect("8.8.8.8:53").expect("Failed to connect");
|
||||
if let SocketAddr::V4(addr) = dummy_sock.local_addr().expect("Failed to get local address") {
|
||||
*addr.ip()
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[allow(unknown_lints, clippy::needless_pass_by_value)]
|
||||
pub fn resolve<Addr: ToSocketAddrs + fmt::Debug>(addr: Addr) -> Result<Vec<SocketAddr>, Error> {
|
||||
|
|
Loading…
Reference in New Issue