mirror of https://github.com/dswd/vpncloud.git
Add ability to configure “own” addresses (#185)
* Add ability to configure “own” addresses This configuration option permits the declaration of external or public addresses instead of attempting to learn them from port forwarding or interfaces. This is useful in situations where it isn’t possible to accurately obtain the correct external addresses that peers should use. * Update args and use better parse listen address Add the --advertise_addresses control argument to accompany the new configuration option. Also parse the listen address/port to extract the port to advertise with advertise_addresses instead of assuming it is just a port.
This commit is contained in:
parent
7a55529cb9
commit
0f9a0d8f91
17
src/cloud.rs
17
src/cloud.rs
|
@ -29,7 +29,7 @@ use crate::{
|
||||||
AddrList, NodeInfo, PeerInfo, MESSAGE_TYPE_CLOSE, MESSAGE_TYPE_DATA, MESSAGE_TYPE_KEEPALIVE,
|
AddrList, NodeInfo, PeerInfo, MESSAGE_TYPE_CLOSE, MESSAGE_TYPE_DATA, MESSAGE_TYPE_KEEPALIVE,
|
||||||
MESSAGE_TYPE_NODE_INFO,
|
MESSAGE_TYPE_NODE_INFO,
|
||||||
},
|
},
|
||||||
net::{mapped_addr, Socket},
|
net::{mapped_addr, parse_listen, Socket},
|
||||||
payload::Protocol,
|
payload::Protocol,
|
||||||
poll::{WaitImpl, WaitResult},
|
poll::{WaitImpl, WaitResult},
|
||||||
port_forwarding::PortForwarding,
|
port_forwarding::PortForwarding,
|
||||||
|
@ -222,11 +222,26 @@ 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 &&
|
||||||
|
!self.config.listen.starts_with("ws://") {
|
||||||
|
// Force advertised addresses based on configuration instead
|
||||||
|
// of discovery. Note: Disables port forwarding
|
||||||
|
// 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 {
|
||||||
self.own_addresses.push(self.socket.address().map(mapped_addr)?);
|
self.own_addresses.push(self.socket.address().map(mapped_addr)?);
|
||||||
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(())
|
||||||
|
|
|
@ -19,6 +19,7 @@ pub struct Config {
|
||||||
pub fix_rp_filter: bool,
|
pub fix_rp_filter: bool,
|
||||||
|
|
||||||
pub ip: Option<String>,
|
pub ip: Option<String>,
|
||||||
|
pub advertise_addresses: Vec<String>,
|
||||||
pub ifup: Option<String>,
|
pub ifup: Option<String>,
|
||||||
pub ifdown: Option<String>,
|
pub ifdown: Option<String>,
|
||||||
|
|
||||||
|
@ -56,6 +57,7 @@ impl Default for Config {
|
||||||
device_path: None,
|
device_path: None,
|
||||||
fix_rp_filter: false,
|
fix_rp_filter: false,
|
||||||
ip: None,
|
ip: None,
|
||||||
|
advertise_addresses: vec![],
|
||||||
ifup: None,
|
ifup: None,
|
||||||
ifdown: None,
|
ifdown: None,
|
||||||
crypto: CryptoConfig::default(),
|
crypto: CryptoConfig::default(),
|
||||||
|
@ -105,6 +107,9 @@ impl Config {
|
||||||
if let Some(val) = file.ip {
|
if let Some(val) = file.ip {
|
||||||
self.ip = Some(val);
|
self.ip = Some(val);
|
||||||
}
|
}
|
||||||
|
if let Some(mut val) = file.advertise_addresses {
|
||||||
|
self.advertise_addresses.append(&mut val);
|
||||||
|
}
|
||||||
if let Some(val) = file.ifup {
|
if let Some(val) = file.ifup {
|
||||||
self.ifup = Some(val);
|
self.ifup = Some(val);
|
||||||
}
|
}
|
||||||
|
@ -212,6 +217,7 @@ impl Config {
|
||||||
if let Some(val) = args.ifup {
|
if let Some(val) = args.ifup {
|
||||||
self.ifup = Some(val);
|
self.ifup = Some(val);
|
||||||
}
|
}
|
||||||
|
self.advertise_addresses.append(&mut args.advertise_addresses);
|
||||||
if let Some(val) = args.ifdown {
|
if let Some(val) = args.ifdown {
|
||||||
self.ifdown = Some(val);
|
self.ifdown = Some(val);
|
||||||
}
|
}
|
||||||
|
@ -318,6 +324,7 @@ impl Config {
|
||||||
ifup: self.ifup,
|
ifup: self.ifup,
|
||||||
ifdown: self.ifdown,
|
ifdown: self.ifdown,
|
||||||
ip: self.ip,
|
ip: self.ip,
|
||||||
|
advertise_addresses: Some(self.advertise_addresses),
|
||||||
keepalive: self.keepalive,
|
keepalive: self.keepalive,
|
||||||
listen: Some(self.listen),
|
listen: Some(self.listen),
|
||||||
mode: Some(self.mode),
|
mode: Some(self.mode),
|
||||||
|
@ -467,6 +474,10 @@ pub struct Args {
|
||||||
#[structopt(long)]
|
#[structopt(long)]
|
||||||
pub ip: Option<String>,
|
pub ip: Option<String>,
|
||||||
|
|
||||||
|
/// A list of IP Addresses to advertise as our external address(s)
|
||||||
|
#[structopt(long = "advertise_addresses", use_delimiter = true)]
|
||||||
|
pub advertise_addresses: Vec<String>,
|
||||||
|
|
||||||
/// A command to setup the network interface
|
/// A command to setup the network interface
|
||||||
#[structopt(long)]
|
#[structopt(long)]
|
||||||
pub ifup: Option<String>,
|
pub ifup: Option<String>,
|
||||||
|
@ -606,6 +617,7 @@ pub struct ConfigFile {
|
||||||
pub device: Option<ConfigFileDevice>,
|
pub device: Option<ConfigFileDevice>,
|
||||||
|
|
||||||
pub ip: Option<String>,
|
pub ip: Option<String>,
|
||||||
|
pub advertise_addresses: Option<Vec<String>>,
|
||||||
pub ifup: Option<String>,
|
pub ifup: Option<String>,
|
||||||
pub ifdown: Option<String>,
|
pub ifdown: Option<String>,
|
||||||
|
|
||||||
|
@ -638,6 +650,9 @@ device:
|
||||||
name: vpncloud%d
|
name: vpncloud%d
|
||||||
path: /dev/net/tun
|
path: /dev/net/tun
|
||||||
ip: 10.0.1.1/16
|
ip: 10.0.1.1/16
|
||||||
|
advertise-addresses:
|
||||||
|
- 192.168.0.1
|
||||||
|
- 192.168.1.1
|
||||||
ifup: ifconfig $IFNAME 10.0.1.1/16 mtu 1400 up
|
ifup: ifconfig $IFNAME 10.0.1.1/16 mtu 1400 up
|
||||||
ifdown: 'true'
|
ifdown: 'true'
|
||||||
peers:
|
peers:
|
||||||
|
@ -673,6 +688,7 @@ statsd:
|
||||||
fix_rp_filter: None
|
fix_rp_filter: None
|
||||||
}),
|
}),
|
||||||
ip: Some("10.0.1.1/16".to_string()),
|
ip: Some("10.0.1.1/16".to_string()),
|
||||||
|
advertise_addresses: Some(vec!["192.168.0.1".to_string(), "192.168.1.1".to_string()]),
|
||||||
ifup: Some("ifconfig $IFNAME 10.0.1.1/16 mtu 1400 up".to_string()),
|
ifup: Some("ifconfig $IFNAME 10.0.1.1/16 mtu 1400 up".to_string()),
|
||||||
ifdown: Some("true".to_string()),
|
ifdown: Some("true".to_string()),
|
||||||
crypto: CryptoConfig::default(),
|
crypto: CryptoConfig::default(),
|
||||||
|
@ -721,6 +737,7 @@ fn config_merge() {
|
||||||
fix_rp_filter: None,
|
fix_rp_filter: None,
|
||||||
}),
|
}),
|
||||||
ip: None,
|
ip: None,
|
||||||
|
advertise_addresses: Some(vec![]),
|
||||||
ifup: Some("ifconfig $IFNAME 10.0.1.1/16 mtu 1400 up".to_string()),
|
ifup: Some("ifconfig $IFNAME 10.0.1.1/16 mtu 1400 up".to_string()),
|
||||||
ifdown: Some("true".to_string()),
|
ifdown: Some("true".to_string()),
|
||||||
crypto: CryptoConfig::default(),
|
crypto: CryptoConfig::default(),
|
||||||
|
@ -757,6 +774,7 @@ fn config_merge() {
|
||||||
device_name: "vpncloud%d".to_string(),
|
device_name: "vpncloud%d".to_string(),
|
||||||
device_path: None,
|
device_path: None,
|
||||||
ip: None,
|
ip: None,
|
||||||
|
advertise_addresses: vec![],
|
||||||
ifup: Some("ifconfig $IFNAME 10.0.1.1/16 mtu 1400 up".to_string()),
|
ifup: Some("ifconfig $IFNAME 10.0.1.1/16 mtu 1400 up".to_string()),
|
||||||
ifdown: Some("true".to_string()),
|
ifdown: Some("true".to_string()),
|
||||||
listen: "3210".to_string(),
|
listen: "3210".to_string(),
|
||||||
|
@ -816,6 +834,8 @@ fn config_merge() {
|
||||||
device_path: Some("/dev/null".to_string()),
|
device_path: Some("/dev/null".to_string()),
|
||||||
fix_rp_filter: false,
|
fix_rp_filter: false,
|
||||||
ip: None,
|
ip: None,
|
||||||
|
advertise_addresses: vec![],
|
||||||
|
|
||||||
ifup: Some("ifconfig $IFNAME 10.0.1.2/16 mtu 1400 up".to_string()),
|
ifup: Some("ifconfig $IFNAME 10.0.1.2/16 mtu 1400 up".to_string()),
|
||||||
ifdown: Some("ifconfig $IFNAME down".to_string()),
|
ifdown: Some("ifconfig $IFNAME down".to_string()),
|
||||||
crypto: CryptoConfig { password: Some("anothersecret".to_string()), ..CryptoConfig::default() },
|
crypto: CryptoConfig { password: Some("anothersecret".to_string()), ..CryptoConfig::default() },
|
||||||
|
|
|
@ -109,6 +109,7 @@ impl OldConfigFile {
|
||||||
ifdown: self.ifdown,
|
ifdown: self.ifdown,
|
||||||
ifup: self.ifup,
|
ifup: self.ifup,
|
||||||
ip: None,
|
ip: None,
|
||||||
|
advertise_addresses: None,
|
||||||
keepalive: self.keepalive,
|
keepalive: self.keepalive,
|
||||||
listen: self.listen.or(self.port.map(|p| format!("{}", p))),
|
listen: self.listen.or(self.port.map(|p| format!("{}", p))),
|
||||||
mode: self.mode,
|
mode: self.mode,
|
||||||
|
|
Loading…
Reference in New Issue