mirror of https://github.com/dswd/vpncloud.git
Finish advertise address & exchange own addresses
This commit is contained in:
parent
7427be31c8
commit
8c55e6c076
50
src/cloud.rs
50
src/cloud.rs
|
@ -222,26 +222,18 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
||||||
|
|
||||||
pub fn reset_own_addresses(&mut self) -> io::Result<()> {
|
pub fn reset_own_addresses(&mut self) -> io::Result<()> {
|
||||||
self.own_addresses.clear();
|
self.own_addresses.clear();
|
||||||
if self.config.advertise_addresses.len() > 0 &&
|
let socket_addr = self.socket.address().map(mapped_addr)?;
|
||||||
!self.config.listen.starts_with("ws://") {
|
// 1) Specified advertise addresses
|
||||||
// Force advertised addresses based on configuration instead
|
for addr in &self.config.advertise_addresses {
|
||||||
// of discovery. Note: Disables port forwarding
|
self.own_addresses.push(parse_listen(addr, socket_addr.port()));
|
||||||
// Because the listen config may contain a color (aka
|
|
||||||
// both address and port are specified) we parse it and
|
|
||||||
// then extract just the port.
|
|
||||||
let sockaddr = parse_listen(&self.config.listen);
|
|
||||||
let port = sockaddr.port();
|
|
||||||
for address in &self.config.advertise_addresses {
|
|
||||||
let sockaddr = try_fail!(SocketAddr::from_str(&format!("{}:{}", address, port)), "Invalid IP Address or port {}");
|
|
||||||
self.own_addresses.push(sockaddr);
|
|
||||||
}
|
}
|
||||||
} else {
|
// 2) Address of UDP socket
|
||||||
self.own_addresses.push(self.socket.address().map(mapped_addr)?);
|
self.own_addresses.push(socket_addr);
|
||||||
|
// 3) Addresses from port forwarding
|
||||||
if let Some(ref pfw) = self.port_forwarding {
|
if let Some(ref pfw) = self.port_forwarding {
|
||||||
self.own_addresses.push(pfw.get_internal_ip().into());
|
self.own_addresses.push(pfw.get_internal_ip().into());
|
||||||
self.own_addresses.push(pfw.get_external_ip().into());
|
self.own_addresses.push(pfw.get_external_ip().into());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
debug!("Own addresses: {:?}", self.own_addresses);
|
debug!("Own addresses: {:?}", self.own_addresses);
|
||||||
// TODO: detect address changes and call event
|
// TODO: detect address changes and call event
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -450,11 +442,6 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
||||||
pfw.check_extend();
|
pfw.check_extend();
|
||||||
}
|
}
|
||||||
let now = TS::now();
|
let now = TS::now();
|
||||||
// Periodically reset own peers
|
|
||||||
if self.next_own_address_reset <= now {
|
|
||||||
self.reset_own_addresses().map_err(|err| Error::SocketIo("Failed to get own addresses", err))?;
|
|
||||||
self.next_own_address_reset = now + OWN_ADDRESS_RESET_INTERVAL;
|
|
||||||
}
|
|
||||||
// Periodically send peer list to peers
|
// Periodically send peer list to peers
|
||||||
if self.next_peers <= now {
|
if self.next_peers <= now {
|
||||||
debug!("Send peer list to all peers");
|
debug!("Send peer list to all peers");
|
||||||
|
@ -485,6 +472,11 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
||||||
self.load_beacon()?;
|
self.load_beacon()?;
|
||||||
self.next_beacon = now + Time::from(self.config.beacon_interval);
|
self.next_beacon = now + Time::from(self.config.beacon_interval);
|
||||||
}
|
}
|
||||||
|
// Periodically reset own peers
|
||||||
|
if self.next_own_address_reset <= now {
|
||||||
|
self.reset_own_addresses().map_err(|err| Error::SocketIo("Failed to get own addresses", err))?;
|
||||||
|
self.next_own_address_reset = now + OWN_ADDRESS_RESET_INTERVAL;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,6 +698,12 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
||||||
}
|
}
|
||||||
if let Some(node_id) = peer.node_id {
|
if let Some(node_id) = peer.node_id {
|
||||||
if self.node_id == node_id {
|
if self.node_id == node_id {
|
||||||
|
// Check addresses and add addresses that we don't know to own addresses
|
||||||
|
for addr in &peer.addrs {
|
||||||
|
if !self.own_addresses.contains(addr) {
|
||||||
|
self.own_addresses.push(*addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
continue 'outer;
|
continue 'outer;
|
||||||
}
|
}
|
||||||
for p in self.peers.values() {
|
for p in self.peers.values() {
|
||||||
|
@ -722,7 +720,17 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
|
||||||
fn update_peer_info(&mut self, addr: SocketAddr, info: Option<NodeInfo>) -> Result<(), Error> {
|
fn update_peer_info(&mut self, addr: SocketAddr, info: Option<NodeInfo>) -> Result<(), Error> {
|
||||||
if let Some(peer) = self.peers.get_mut(&addr) {
|
if let Some(peer) = self.peers.get_mut(&addr) {
|
||||||
peer.last_seen = TS::now();
|
peer.last_seen = TS::now();
|
||||||
peer.timeout = TS::now() + self.config.peer_timeout as Time
|
peer.timeout = TS::now() + self.config.peer_timeout as Time;
|
||||||
|
if let Some(info) = &info {
|
||||||
|
// Update peer addresses, always add seen address
|
||||||
|
peer.addrs.clear();
|
||||||
|
peer.addrs.push(addr);
|
||||||
|
for addr in &info.addrs {
|
||||||
|
if !peer.addrs.contains(addr) {
|
||||||
|
peer.addrs.push(*addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
error!("Received peer update from non peer {}", addr_nice(addr));
|
error!("Received peer update from non peer {}", addr_nice(addr));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|
14
src/net.rs
14
src/net.rs
|
@ -11,7 +11,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::util::{MockTimeSource, MsgBuffer, Time, TimeSource};
|
use super::util::{MockTimeSource, MsgBuffer, Time, TimeSource};
|
||||||
use crate::port_forwarding::PortForwarding;
|
use crate::{config::DEFAULT_PORT, port_forwarding::PortForwarding};
|
||||||
|
|
||||||
pub fn mapped_addr(addr: SocketAddr) -> SocketAddr {
|
pub fn mapped_addr(addr: SocketAddr) -> SocketAddr {
|
||||||
// HOT PATH
|
// HOT PATH
|
||||||
|
@ -35,21 +35,23 @@ pub trait Socket: AsRawFd + Sized {
|
||||||
fn create_port_forwarding(&self) -> Option<PortForwarding>;
|
fn create_port_forwarding(&self) -> Option<PortForwarding>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_listen(addr: &str) -> SocketAddr {
|
pub fn parse_listen(addr: &str, default_port: u16) -> SocketAddr {
|
||||||
if let Some(addr) = addr.strip_prefix("*:") {
|
if let Some(addr) = addr.strip_prefix("*:") {
|
||||||
let port = try_fail!(addr.parse::<u16>(), "Invalid port: {}");
|
let port = try_fail!(addr.parse::<u16>(), "Invalid port: {}");
|
||||||
SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), port)
|
SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), port)
|
||||||
} else if addr.contains(':') {
|
} else if addr.contains(':') {
|
||||||
try_fail!(addr.parse::<SocketAddr>(), "Invalid address: {}: {}", addr)
|
try_fail!(addr.parse::<SocketAddr>(), "Invalid address: {}: {}", addr)
|
||||||
} else {
|
} else if let Ok(port) = addr.parse::<u16>() {
|
||||||
let port = try_fail!(addr.parse::<u16>(), "Invalid port: {}");
|
|
||||||
SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), port)
|
SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), port)
|
||||||
|
} else {
|
||||||
|
let ip = try_fail!(addr.parse::<IpAddr>(), "Invalid addr: {}");
|
||||||
|
SocketAddr::new(ip, default_port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Socket for UdpSocket {
|
impl Socket for UdpSocket {
|
||||||
fn listen(addr: &str) -> Result<Self, io::Error> {
|
fn listen(addr: &str) -> Result<Self, io::Error> {
|
||||||
let addr = parse_listen(addr);
|
let addr = parse_listen(addr, DEFAULT_PORT);
|
||||||
UdpSocket::bind(addr)
|
UdpSocket::bind(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +136,7 @@ impl AsRawFd for MockSocket {
|
||||||
|
|
||||||
impl Socket for MockSocket {
|
impl Socket for MockSocket {
|
||||||
fn listen(addr: &str) -> Result<Self, io::Error> {
|
fn listen(addr: &str) -> Result<Self, io::Error> {
|
||||||
Ok(Self::new(parse_listen(addr)))
|
Ok(Self::new(parse_listen(addr, DEFAULT_PORT)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receive(&mut self, buffer: &mut MsgBuffer) -> Result<SocketAddr, io::Error> {
|
fn receive(&mut self, buffer: &mut MsgBuffer) -> Result<SocketAddr, io::Error> {
|
||||||
|
|
|
@ -41,6 +41,12 @@ fn configure_connectivity(config: &mut Config, mode: usize, theme: &ColorfulThem
|
||||||
.interact()?;
|
.interact()?;
|
||||||
}
|
}
|
||||||
if mode == MODE_EXPERT {
|
if mode == MODE_EXPERT {
|
||||||
|
config.advertise_addresses = str_list(
|
||||||
|
Input::with_theme(theme)
|
||||||
|
.with_prompt("Advertise addresses (comma separated)")
|
||||||
|
.default(config.advertise_addresses.join(","))
|
||||||
|
.interact_text()?,
|
||||||
|
);
|
||||||
config.peer_timeout = Input::with_theme(theme)
|
config.peer_timeout = Input::with_theme(theme)
|
||||||
.with_prompt("Peer timeout (in seconds)")
|
.with_prompt("Peer timeout (in seconds)")
|
||||||
.default(config.peer_timeout)
|
.default(config.peer_timeout)
|
||||||
|
|
|
@ -92,7 +92,7 @@ fn serve_proxy_connection(stream: TcpStream) -> Result<(), io::Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_proxy(listen: &str) -> Result<(), io::Error> {
|
pub fn run_proxy(listen: &str) -> Result<(), io::Error> {
|
||||||
let addr = parse_listen(listen);
|
let addr = parse_listen(listen, 8080);
|
||||||
let server = TcpListener::bind(addr)?;
|
let server = TcpListener::bind(addr)?;
|
||||||
info!("Listening on ws://{}", server.local_addr()?);
|
info!("Listening on ws://{}", server.local_addr()?);
|
||||||
for stream in server.incoming() {
|
for stream in server.incoming() {
|
||||||
|
|
Loading…
Reference in New Issue