2017-07-22 14:49:53 +00:00
|
|
|
// VpnCloud - Peer-to-Peer VPN
|
2020-05-28 07:03:48 +00:00
|
|
|
// Copyright (C) 2015-2020 Dennis Schwerdel
|
2017-07-22 14:49:53 +00:00
|
|
|
// This software is licensed under GPL-3 or newer (see LICENSE.md)
|
|
|
|
|
2019-12-04 08:32:35 +00:00
|
|
|
use super::{Args, MAGIC};
|
2016-08-08 14:30:22 +00:00
|
|
|
|
2019-12-04 08:32:35 +00:00
|
|
|
use super::{
|
|
|
|
crypto::CryptoMethod,
|
|
|
|
device::Type,
|
|
|
|
types::{HeaderMagic, Mode},
|
|
|
|
util::{Duration, Encoder}
|
|
|
|
};
|
2016-08-08 14:30:22 +00:00
|
|
|
|
2016-11-23 10:37:09 +00:00
|
|
|
use siphasher::sip::SipHasher24;
|
2020-02-20 15:25:35 +00:00
|
|
|
use std::{
|
|
|
|
hash::{Hash, Hasher},
|
|
|
|
net::{IpAddr, Ipv6Addr, SocketAddr}
|
|
|
|
};
|
2016-08-08 14:30:22 +00:00
|
|
|
|
|
|
|
|
2019-02-15 21:42:13 +00:00
|
|
|
const HASH_PREFIX: &str = "hash:";
|
2019-12-22 22:03:45 +00:00
|
|
|
pub const DEFAULT_PEER_TIMEOUT: u16 = 600;
|
2019-02-15 21:42:13 +00:00
|
|
|
|
|
|
|
|
2020-02-20 15:25:35 +00:00
|
|
|
fn parse_listen(addr: &str) -> SocketAddr {
|
|
|
|
if addr.starts_with("*:") {
|
|
|
|
let port = try_fail!(addr[2..].parse::<u16>(), "Invalid port: {}");
|
|
|
|
SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), port)
|
|
|
|
} else if addr.contains(':') {
|
|
|
|
try_fail!(addr.parse::<SocketAddr>(), "Invalid address: {}: {}", addr)
|
|
|
|
} else {
|
|
|
|
let port = try_fail!(addr.parse::<u16>(), "Invalid port: {}");
|
|
|
|
SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), port)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-10 18:36:50 +00:00
|
|
|
#[derive(Deserialize, Debug, PartialEq, Clone)]
|
2016-08-08 14:30:22 +00:00
|
|
|
pub struct Config {
|
|
|
|
pub device_type: Type,
|
|
|
|
pub device_name: String,
|
2019-02-12 18:30:38 +00:00
|
|
|
pub device_path: Option<String>,
|
2016-08-08 14:30:22 +00:00
|
|
|
pub ifup: Option<String>,
|
|
|
|
pub ifdown: Option<String>,
|
|
|
|
pub crypto: CryptoMethod,
|
|
|
|
pub shared_key: Option<String>,
|
|
|
|
pub magic: Option<String>,
|
2020-02-20 15:25:35 +00:00
|
|
|
pub listen: SocketAddr,
|
2016-08-08 14:30:22 +00:00
|
|
|
pub peers: Vec<String>,
|
|
|
|
pub peer_timeout: Duration,
|
2019-01-10 18:36:50 +00:00
|
|
|
pub keepalive: Option<Duration>,
|
2019-02-19 21:04:21 +00:00
|
|
|
pub beacon_store: Option<String>,
|
|
|
|
pub beacon_load: Option<String>,
|
|
|
|
pub beacon_interval: Duration,
|
2016-08-08 14:30:22 +00:00
|
|
|
pub mode: Mode,
|
|
|
|
pub dst_timeout: Duration,
|
|
|
|
pub subnets: Vec<String>,
|
2016-08-10 09:34:13 +00:00
|
|
|
pub port_forwarding: bool,
|
2016-11-23 14:21:22 +00:00
|
|
|
pub daemonize: bool,
|
|
|
|
pub pid_file: Option<String>,
|
2019-01-09 16:45:12 +00:00
|
|
|
pub stats_file: Option<String>,
|
2020-05-29 09:51:04 +00:00
|
|
|
pub statsd_server: Option<String>,
|
2020-05-30 14:12:54 +00:00
|
|
|
pub statsd_prefix: Option<String>,
|
2016-11-23 14:21:22 +00:00
|
|
|
pub user: Option<String>,
|
|
|
|
pub group: Option<String>
|
2016-08-08 14:30:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for Config {
|
|
|
|
fn default() -> Self {
|
|
|
|
Config {
|
2019-12-04 08:32:35 +00:00
|
|
|
device_type: Type::Tap,
|
|
|
|
device_name: "vpncloud%d".to_string(),
|
|
|
|
device_path: None,
|
|
|
|
ifup: None,
|
|
|
|
ifdown: None,
|
|
|
|
crypto: CryptoMethod::ChaCha20,
|
|
|
|
shared_key: None,
|
2016-08-08 14:30:22 +00:00
|
|
|
magic: None,
|
2020-02-20 15:25:35 +00:00
|
|
|
listen: "[::]:3210".parse::<SocketAddr>().unwrap(),
|
2019-12-04 08:32:35 +00:00
|
|
|
peers: vec![],
|
2019-12-22 22:03:45 +00:00
|
|
|
peer_timeout: DEFAULT_PEER_TIMEOUT as Duration,
|
2019-12-04 08:32:35 +00:00
|
|
|
keepalive: None,
|
|
|
|
beacon_store: None,
|
|
|
|
beacon_load: None,
|
|
|
|
beacon_interval: 3600,
|
|
|
|
mode: Mode::Normal,
|
|
|
|
dst_timeout: 300,
|
2016-08-10 09:34:13 +00:00
|
|
|
subnets: vec![],
|
2016-11-23 14:21:22 +00:00
|
|
|
port_forwarding: true,
|
|
|
|
daemonize: false,
|
|
|
|
pid_file: None,
|
2019-01-09 16:45:12 +00:00
|
|
|
stats_file: None,
|
2020-05-29 09:51:04 +00:00
|
|
|
statsd_server: None,
|
2020-05-30 14:12:54 +00:00
|
|
|
statsd_prefix: None,
|
2016-11-23 14:21:22 +00:00
|
|
|
user: None,
|
|
|
|
group: None
|
2016-08-08 14:30:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Config {
|
2020-02-20 15:25:35 +00:00
|
|
|
#[allow(clippy::cognitive_complexity)]
|
2016-08-08 14:30:22 +00:00
|
|
|
pub fn merge_file(&mut self, file: ConfigFile) {
|
|
|
|
if let Some(val) = file.device_type {
|
|
|
|
self.device_type = val;
|
|
|
|
}
|
|
|
|
if let Some(val) = file.device_name {
|
|
|
|
self.device_name = val;
|
|
|
|
}
|
2019-02-12 18:30:38 +00:00
|
|
|
if let Some(val) = file.device_path {
|
|
|
|
self.device_path = Some(val);
|
|
|
|
}
|
2016-08-08 14:30:22 +00:00
|
|
|
if let Some(val) = file.ifup {
|
|
|
|
self.ifup = Some(val);
|
|
|
|
}
|
|
|
|
if let Some(val) = file.ifdown {
|
|
|
|
self.ifdown = Some(val);
|
|
|
|
}
|
|
|
|
if let Some(val) = file.crypto {
|
|
|
|
self.crypto = val;
|
|
|
|
}
|
|
|
|
if let Some(val) = file.shared_key {
|
|
|
|
self.shared_key = Some(val);
|
|
|
|
}
|
|
|
|
if let Some(val) = file.magic {
|
|
|
|
self.magic = Some(val);
|
|
|
|
}
|
|
|
|
if let Some(val) = file.port {
|
2020-02-20 15:25:35 +00:00
|
|
|
self.listen = parse_listen(&format!("{}", &val));
|
|
|
|
warn!("The config option 'port' is deprecated, use 'listen' instead.");
|
|
|
|
}
|
|
|
|
if let Some(val) = file.listen {
|
|
|
|
self.listen = parse_listen(&val);
|
2016-08-08 14:30:22 +00:00
|
|
|
}
|
|
|
|
if let Some(mut val) = file.peers {
|
|
|
|
self.peers.append(&mut val);
|
|
|
|
}
|
|
|
|
if let Some(val) = file.peer_timeout {
|
|
|
|
self.peer_timeout = val;
|
|
|
|
}
|
2019-01-10 18:36:50 +00:00
|
|
|
if let Some(val) = file.keepalive {
|
|
|
|
self.keepalive = Some(val);
|
|
|
|
}
|
2019-02-19 21:04:21 +00:00
|
|
|
if let Some(val) = file.beacon_store {
|
|
|
|
self.beacon_store = Some(val);
|
|
|
|
}
|
|
|
|
if let Some(val) = file.beacon_load {
|
|
|
|
self.beacon_load = Some(val);
|
|
|
|
}
|
|
|
|
if let Some(val) = file.beacon_interval {
|
|
|
|
self.beacon_interval = val;
|
|
|
|
}
|
2016-08-08 14:30:22 +00:00
|
|
|
if let Some(val) = file.mode {
|
|
|
|
self.mode = val;
|
|
|
|
}
|
|
|
|
if let Some(val) = file.dst_timeout {
|
|
|
|
self.dst_timeout = val;
|
|
|
|
}
|
|
|
|
if let Some(mut val) = file.subnets {
|
|
|
|
self.subnets.append(&mut val);
|
|
|
|
}
|
2016-08-10 09:34:13 +00:00
|
|
|
if let Some(val) = file.port_forwarding {
|
|
|
|
self.port_forwarding = val;
|
|
|
|
}
|
2016-11-23 14:21:22 +00:00
|
|
|
if let Some(val) = file.pid_file {
|
|
|
|
self.pid_file = Some(val);
|
|
|
|
}
|
2019-01-09 16:45:12 +00:00
|
|
|
if let Some(val) = file.stats_file {
|
|
|
|
self.stats_file = Some(val);
|
|
|
|
}
|
2020-05-29 09:51:04 +00:00
|
|
|
if let Some(val) = file.statsd_server {
|
|
|
|
self.statsd_server = Some(val);
|
|
|
|
}
|
2020-05-30 14:12:54 +00:00
|
|
|
if let Some(val) = file.statsd_prefix {
|
|
|
|
self.statsd_prefix = Some(val);
|
|
|
|
}
|
2016-11-23 14:21:22 +00:00
|
|
|
if let Some(val) = file.user {
|
|
|
|
self.user = Some(val);
|
|
|
|
}
|
|
|
|
if let Some(val) = file.group {
|
|
|
|
self.group = Some(val);
|
|
|
|
}
|
2016-08-08 14:30:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn merge_args(&mut self, mut args: Args) {
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.type_ {
|
2016-08-08 14:30:22 +00:00
|
|
|
self.device_type = val;
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.device {
|
2016-08-08 14:30:22 +00:00
|
|
|
self.device_name = val;
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.device_path {
|
2019-02-12 18:30:38 +00:00
|
|
|
self.device_path = Some(val);
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.ifup {
|
2016-08-08 14:30:22 +00:00
|
|
|
self.ifup = Some(val);
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.ifdown {
|
2016-08-08 14:30:22 +00:00
|
|
|
self.ifdown = Some(val);
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.crypto {
|
2016-08-08 14:30:22 +00:00
|
|
|
self.crypto = val;
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.key {
|
2016-08-08 14:30:22 +00:00
|
|
|
self.shared_key = Some(val);
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.network_id {
|
2016-08-08 14:30:22 +00:00
|
|
|
warn!("The --network-id argument is deprecated, please use --magic instead.");
|
|
|
|
self.magic = Some(val);
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.magic {
|
2016-08-08 14:30:22 +00:00
|
|
|
self.magic = Some(val);
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.listen {
|
2020-02-20 15:25:35 +00:00
|
|
|
self.listen = parse_listen(&val);
|
2016-08-08 14:30:22 +00:00
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
self.peers.append(&mut args.connect);
|
|
|
|
if let Some(val) = args.peer_timeout {
|
2016-08-08 14:30:22 +00:00
|
|
|
self.peer_timeout = val;
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.keepalive {
|
2019-01-10 18:36:50 +00:00
|
|
|
self.keepalive = Some(val);
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.beacon_store {
|
2019-02-19 21:04:21 +00:00
|
|
|
self.beacon_store = Some(val);
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.beacon_load {
|
2019-02-19 21:04:21 +00:00
|
|
|
self.beacon_load = Some(val);
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.beacon_interval {
|
2019-02-19 21:04:21 +00:00
|
|
|
self.beacon_interval = val;
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.mode {
|
2016-08-08 14:30:22 +00:00
|
|
|
self.mode = val;
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.dst_timeout {
|
2016-08-08 14:30:22 +00:00
|
|
|
self.dst_timeout = val;
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
self.subnets.append(&mut args.subnets);
|
|
|
|
if args.no_port_forwarding {
|
2016-08-10 09:34:13 +00:00
|
|
|
self.port_forwarding = false;
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if args.daemon {
|
2016-11-23 14:21:22 +00:00
|
|
|
self.daemonize = true;
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.pid_file {
|
2016-11-23 14:21:22 +00:00
|
|
|
self.pid_file = Some(val);
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.stats_file {
|
2019-01-09 16:45:12 +00:00
|
|
|
self.stats_file = Some(val);
|
|
|
|
}
|
2020-05-29 09:51:04 +00:00
|
|
|
if let Some(val) = args.statsd_server {
|
|
|
|
self.statsd_server = Some(val);
|
|
|
|
}
|
2020-05-30 14:12:54 +00:00
|
|
|
if let Some(val) = args.statsd_prefix {
|
|
|
|
self.statsd_prefix = Some(val);
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.user {
|
2016-11-23 14:21:22 +00:00
|
|
|
self.user = Some(val);
|
|
|
|
}
|
2020-05-29 06:37:29 +00:00
|
|
|
if let Some(val) = args.group {
|
2016-11-23 14:21:22 +00:00
|
|
|
self.group = Some(val);
|
|
|
|
}
|
2016-08-08 14:30:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_magic(&self) -> HeaderMagic {
|
|
|
|
if let Some(ref name) = self.magic {
|
2019-02-15 21:42:13 +00:00
|
|
|
if name.starts_with(HASH_PREFIX) {
|
2016-11-23 10:37:09 +00:00
|
|
|
let mut s = SipHasher24::new();
|
2019-02-15 21:42:13 +00:00
|
|
|
name[HASH_PREFIX.len()..].hash(&mut s);
|
2016-08-08 14:30:22 +00:00
|
|
|
let mut data = [0; 4];
|
2019-01-01 23:35:14 +00:00
|
|
|
Encoder::write_u32((s.finish() & 0xffff_ffff) as u32, &mut data);
|
2016-08-08 14:30:22 +00:00
|
|
|
data
|
|
|
|
} else {
|
2017-05-04 05:26:21 +00:00
|
|
|
let num = try_fail!(u32::from_str_radix(name, 16), "Failed to parse header magic: {}");
|
2016-08-08 14:30:22 +00:00
|
|
|
let mut data = [0; 4];
|
|
|
|
Encoder::write_u32(num, &mut data);
|
|
|
|
data
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
MAGIC
|
|
|
|
}
|
|
|
|
}
|
2019-01-10 18:36:50 +00:00
|
|
|
|
|
|
|
pub fn get_keepalive(&self) -> Duration {
|
|
|
|
match self.keepalive {
|
|
|
|
Some(dur) => dur,
|
2019-12-04 08:32:35 +00:00
|
|
|
None => self.peer_timeout / 2 - 60
|
2019-01-10 18:36:50 +00:00
|
|
|
}
|
|
|
|
}
|
2016-08-08 14:30:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-22 14:34:20 +00:00
|
|
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Default)]
|
2016-08-08 14:30:22 +00:00
|
|
|
pub struct ConfigFile {
|
|
|
|
pub device_type: Option<Type>,
|
|
|
|
pub device_name: Option<String>,
|
2019-02-12 18:30:38 +00:00
|
|
|
pub device_path: Option<String>,
|
2016-08-08 14:30:22 +00:00
|
|
|
pub ifup: Option<String>,
|
|
|
|
pub ifdown: Option<String>,
|
|
|
|
pub crypto: Option<CryptoMethod>,
|
|
|
|
pub shared_key: Option<String>,
|
|
|
|
pub magic: Option<String>,
|
|
|
|
pub port: Option<u16>,
|
2020-02-20 15:25:35 +00:00
|
|
|
pub listen: Option<String>,
|
2016-08-08 14:30:22 +00:00
|
|
|
pub peers: Option<Vec<String>>,
|
|
|
|
pub peer_timeout: Option<Duration>,
|
2019-01-10 18:36:50 +00:00
|
|
|
pub keepalive: Option<Duration>,
|
2019-02-19 21:04:21 +00:00
|
|
|
pub beacon_store: Option<String>,
|
|
|
|
pub beacon_load: Option<String>,
|
|
|
|
pub beacon_interval: Option<Duration>,
|
2016-08-08 14:30:22 +00:00
|
|
|
pub mode: Option<Mode>,
|
|
|
|
pub dst_timeout: Option<Duration>,
|
|
|
|
pub subnets: Option<Vec<String>>,
|
2016-11-23 14:21:22 +00:00
|
|
|
pub port_forwarding: Option<bool>,
|
|
|
|
pub pid_file: Option<String>,
|
2019-01-09 16:45:12 +00:00
|
|
|
pub stats_file: Option<String>,
|
2020-05-29 09:51:04 +00:00
|
|
|
pub statsd_server: Option<String>,
|
2020-05-30 14:12:54 +00:00
|
|
|
pub statsd_prefix: Option<String>,
|
2016-11-23 14:21:22 +00:00
|
|
|
pub user: Option<String>,
|
2019-12-04 08:32:35 +00:00
|
|
|
pub group: Option<String>
|
2016-08-08 14:30:22 +00:00
|
|
|
}
|
2019-02-19 17:42:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn config_file() {
|
|
|
|
let config_file = "
|
|
|
|
device_type: tun
|
|
|
|
device_name: vpncloud%d
|
|
|
|
device_path: /dev/net/tun
|
|
|
|
magic: 0123ABCD
|
|
|
|
ifup: ifconfig $IFNAME 10.0.1.1/16 mtu 1400 up
|
|
|
|
ifdown: 'true'
|
|
|
|
crypto: aes256
|
|
|
|
shared_key: mysecret
|
|
|
|
port: 3210
|
|
|
|
peers:
|
|
|
|
- remote.machine.foo:3210
|
|
|
|
- remote.machine.bar:3210
|
2019-12-22 22:03:45 +00:00
|
|
|
peer_timeout: 600
|
2019-02-19 17:42:50 +00:00
|
|
|
keepalive: 840
|
|
|
|
dst_timeout: 300
|
2019-02-19 21:04:21 +00:00
|
|
|
beacon_store: /run/vpncloud.beacon.out
|
|
|
|
beacon_load: /run/vpncloud.beacon.in
|
|
|
|
beacon_interval: 3600
|
2019-02-19 17:42:50 +00:00
|
|
|
mode: normal
|
|
|
|
subnets:
|
|
|
|
- 10.0.1.0/24
|
|
|
|
port_forwarding: true
|
|
|
|
user: nobody
|
|
|
|
group: nogroup
|
|
|
|
pid_file: /run/vpncloud.run
|
|
|
|
stats_file: /var/log/vpncloud.stats
|
2020-05-29 09:51:04 +00:00
|
|
|
statsd_server: example.com:1234
|
2020-05-30 14:12:54 +00:00
|
|
|
statsd_prefix: prefix
|
2019-02-19 17:42:50 +00:00
|
|
|
";
|
2019-12-04 08:32:35 +00:00
|
|
|
assert_eq!(serde_yaml::from_str::<ConfigFile>(config_file).unwrap(), ConfigFile {
|
2019-02-19 17:42:50 +00:00
|
|
|
device_type: Some(Type::Tun),
|
|
|
|
device_name: Some("vpncloud%d".to_string()),
|
|
|
|
device_path: Some("/dev/net/tun".to_string()),
|
|
|
|
ifup: Some("ifconfig $IFNAME 10.0.1.1/16 mtu 1400 up".to_string()),
|
|
|
|
ifdown: Some("true".to_string()),
|
|
|
|
crypto: Some(CryptoMethod::AES256),
|
|
|
|
shared_key: Some("mysecret".to_string()),
|
|
|
|
magic: Some("0123ABCD".to_string()),
|
|
|
|
port: Some(3210),
|
2020-02-20 15:25:35 +00:00
|
|
|
listen: None,
|
2019-02-19 17:42:50 +00:00
|
|
|
peers: Some(vec!["remote.machine.foo:3210".to_string(), "remote.machine.bar:3210".to_string()]),
|
2019-12-22 22:03:45 +00:00
|
|
|
peer_timeout: Some(600),
|
2019-02-19 17:42:50 +00:00
|
|
|
keepalive: Some(840),
|
2019-02-19 21:04:21 +00:00
|
|
|
beacon_store: Some("/run/vpncloud.beacon.out".to_string()),
|
|
|
|
beacon_load: Some("/run/vpncloud.beacon.in".to_string()),
|
|
|
|
beacon_interval: Some(3600),
|
2019-02-19 17:42:50 +00:00
|
|
|
mode: Some(Mode::Normal),
|
|
|
|
dst_timeout: Some(300),
|
|
|
|
subnets: Some(vec!["10.0.1.0/24".to_string()]),
|
|
|
|
port_forwarding: Some(true),
|
|
|
|
user: Some("nobody".to_string()),
|
|
|
|
group: Some("nogroup".to_string()),
|
|
|
|
pid_file: Some("/run/vpncloud.run".to_string()),
|
2020-05-29 09:51:04 +00:00
|
|
|
stats_file: Some("/var/log/vpncloud.stats".to_string()),
|
2020-05-30 14:12:54 +00:00
|
|
|
statsd_server: Some("example.com:1234".to_string()),
|
|
|
|
statsd_prefix: Some("prefix".to_string())
|
2019-02-19 17:42:50 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn config_merge() {
|
|
|
|
let mut config = Config::default();
|
2019-12-04 08:32:35 +00:00
|
|
|
config.merge_file(ConfigFile {
|
2019-02-19 17:42:50 +00:00
|
|
|
device_type: Some(Type::Tun),
|
|
|
|
device_name: Some("vpncloud%d".to_string()),
|
|
|
|
device_path: None,
|
|
|
|
ifup: Some("ifconfig $IFNAME 10.0.1.1/16 mtu 1400 up".to_string()),
|
|
|
|
ifdown: Some("true".to_string()),
|
|
|
|
crypto: Some(CryptoMethod::AES256),
|
|
|
|
shared_key: Some("mysecret".to_string()),
|
|
|
|
magic: Some("0123ABCD".to_string()),
|
|
|
|
port: Some(3210),
|
2020-02-20 15:25:35 +00:00
|
|
|
listen: None,
|
2019-02-19 17:42:50 +00:00
|
|
|
peers: Some(vec!["remote.machine.foo:3210".to_string(), "remote.machine.bar:3210".to_string()]),
|
2019-12-22 22:03:45 +00:00
|
|
|
peer_timeout: Some(600),
|
2019-02-19 17:42:50 +00:00
|
|
|
keepalive: Some(840),
|
2019-02-19 21:04:21 +00:00
|
|
|
beacon_store: Some("/run/vpncloud.beacon.out".to_string()),
|
|
|
|
beacon_load: Some("/run/vpncloud.beacon.in".to_string()),
|
|
|
|
beacon_interval: Some(7200),
|
2019-02-19 17:42:50 +00:00
|
|
|
mode: Some(Mode::Normal),
|
|
|
|
dst_timeout: Some(300),
|
|
|
|
subnets: Some(vec!["10.0.1.0/24".to_string()]),
|
|
|
|
port_forwarding: Some(true),
|
|
|
|
user: Some("nobody".to_string()),
|
|
|
|
group: Some("nogroup".to_string()),
|
|
|
|
pid_file: Some("/run/vpncloud.run".to_string()),
|
2020-05-29 09:51:04 +00:00
|
|
|
stats_file: Some("/var/log/vpncloud.stats".to_string()),
|
2020-05-30 14:12:54 +00:00
|
|
|
statsd_server: Some("example.com:1234".to_string()),
|
|
|
|
statsd_prefix: Some("prefix".to_string())
|
2019-02-19 17:42:50 +00:00
|
|
|
});
|
2019-12-04 08:32:35 +00:00
|
|
|
assert_eq!(config, Config {
|
2019-02-19 17:42:50 +00:00
|
|
|
device_type: Type::Tun,
|
|
|
|
device_name: "vpncloud%d".to_string(),
|
|
|
|
device_path: None,
|
|
|
|
ifup: Some("ifconfig $IFNAME 10.0.1.1/16 mtu 1400 up".to_string()),
|
|
|
|
ifdown: Some("true".to_string()),
|
|
|
|
magic: Some("0123ABCD".to_string()),
|
|
|
|
crypto: CryptoMethod::AES256,
|
|
|
|
shared_key: Some("mysecret".to_string()),
|
2020-02-20 15:25:35 +00:00
|
|
|
listen: "[::]:3210".parse::<SocketAddr>().unwrap(),
|
2019-02-19 17:42:50 +00:00
|
|
|
peers: vec!["remote.machine.foo:3210".to_string(), "remote.machine.bar:3210".to_string()],
|
2019-12-22 22:03:45 +00:00
|
|
|
peer_timeout: 600,
|
2019-02-19 17:42:50 +00:00
|
|
|
keepalive: Some(840),
|
|
|
|
dst_timeout: 300,
|
2019-02-19 21:04:21 +00:00
|
|
|
beacon_store: Some("/run/vpncloud.beacon.out".to_string()),
|
|
|
|
beacon_load: Some("/run/vpncloud.beacon.in".to_string()),
|
|
|
|
beacon_interval: 7200,
|
2019-02-19 17:42:50 +00:00
|
|
|
mode: Mode::Normal,
|
|
|
|
port_forwarding: true,
|
|
|
|
subnets: vec!["10.0.1.0/24".to_string()],
|
|
|
|
user: Some("nobody".to_string()),
|
|
|
|
group: Some("nogroup".to_string()),
|
|
|
|
pid_file: Some("/run/vpncloud.run".to_string()),
|
|
|
|
stats_file: Some("/var/log/vpncloud.stats".to_string()),
|
2020-05-29 09:51:04 +00:00
|
|
|
statsd_server: Some("example.com:1234".to_string()),
|
2020-05-30 14:12:54 +00:00
|
|
|
statsd_prefix: Some("prefix".to_string()),
|
2019-02-19 17:42:50 +00:00
|
|
|
..Default::default()
|
|
|
|
});
|
2019-12-04 08:32:35 +00:00
|
|
|
config.merge_args(Args {
|
2020-05-29 06:37:29 +00:00
|
|
|
type_: Some(Type::Tap),
|
|
|
|
device: Some("vpncloud0".to_string()),
|
|
|
|
device_path: Some("/dev/null".to_string()),
|
|
|
|
ifup: Some("ifconfig $IFNAME 10.0.1.2/16 mtu 1400 up".to_string()),
|
|
|
|
ifdown: Some("ifconfig $IFNAME down".to_string()),
|
|
|
|
crypto: Some(CryptoMethod::ChaCha20),
|
|
|
|
key: Some("anothersecret".to_string()),
|
|
|
|
magic: Some("hash:mynet".to_string()),
|
|
|
|
listen: Some("3211".to_string()),
|
|
|
|
peer_timeout: Some(1801),
|
|
|
|
keepalive: Some(850),
|
|
|
|
dst_timeout: Some(301),
|
|
|
|
beacon_store: Some("/run/vpncloud.beacon.out2".to_string()),
|
|
|
|
beacon_load: Some("/run/vpncloud.beacon.in2".to_string()),
|
|
|
|
beacon_interval: Some(3600),
|
|
|
|
mode: Some(Mode::Switch),
|
|
|
|
subnets: vec![],
|
|
|
|
connect: vec!["another:3210".to_string()],
|
|
|
|
no_port_forwarding: true,
|
|
|
|
daemon: true,
|
|
|
|
pid_file: Some("/run/vpncloud-mynet.run".to_string()),
|
|
|
|
stats_file: Some("/var/log/vpncloud-mynet.stats".to_string()),
|
2020-05-29 09:51:04 +00:00
|
|
|
statsd_server: Some("example.com:2345".to_string()),
|
2020-05-30 14:12:54 +00:00
|
|
|
statsd_prefix: Some("prefix2".to_string()),
|
2020-05-29 06:37:29 +00:00
|
|
|
user: Some("root".to_string()),
|
|
|
|
group: Some("root".to_string()),
|
2019-02-19 17:42:50 +00:00
|
|
|
..Default::default()
|
|
|
|
});
|
2019-12-04 08:32:35 +00:00
|
|
|
assert_eq!(config, Config {
|
2019-02-19 17:42:50 +00:00
|
|
|
device_type: Type::Tap,
|
|
|
|
device_name: "vpncloud0".to_string(),
|
|
|
|
device_path: Some("/dev/null".to_string()),
|
|
|
|
ifup: Some("ifconfig $IFNAME 10.0.1.2/16 mtu 1400 up".to_string()),
|
|
|
|
ifdown: Some("ifconfig $IFNAME down".to_string()),
|
|
|
|
magic: Some("hash:mynet".to_string()),
|
|
|
|
crypto: CryptoMethod::ChaCha20,
|
|
|
|
shared_key: Some("anothersecret".to_string()),
|
2020-02-20 15:25:35 +00:00
|
|
|
listen: "[::]:3211".parse::<SocketAddr>().unwrap(),
|
2019-12-04 08:32:35 +00:00
|
|
|
peers: vec![
|
|
|
|
"remote.machine.foo:3210".to_string(),
|
|
|
|
"remote.machine.bar:3210".to_string(),
|
|
|
|
"another:3210".to_string()
|
|
|
|
],
|
2019-02-19 17:42:50 +00:00
|
|
|
peer_timeout: 1801,
|
|
|
|
keepalive: Some(850),
|
|
|
|
dst_timeout: 301,
|
2019-02-19 21:04:21 +00:00
|
|
|
beacon_store: Some("/run/vpncloud.beacon.out2".to_string()),
|
|
|
|
beacon_load: Some("/run/vpncloud.beacon.in2".to_string()),
|
|
|
|
beacon_interval: 3600,
|
2019-02-19 17:42:50 +00:00
|
|
|
mode: Mode::Switch,
|
|
|
|
port_forwarding: false,
|
|
|
|
subnets: vec!["10.0.1.0/24".to_string()],
|
|
|
|
user: Some("root".to_string()),
|
|
|
|
group: Some("root".to_string()),
|
|
|
|
pid_file: Some("/run/vpncloud-mynet.run".to_string()),
|
|
|
|
stats_file: Some("/var/log/vpncloud-mynet.stats".to_string()),
|
2020-05-29 09:51:04 +00:00
|
|
|
statsd_server: Some("example.com:2345".to_string()),
|
2020-05-30 14:12:54 +00:00
|
|
|
statsd_prefix: Some("prefix2".to_string()),
|
2019-12-20 12:54:58 +00:00
|
|
|
daemonize: true
|
2019-02-19 17:42:50 +00:00
|
|
|
});
|
|
|
|
}
|