mirror of https://github.com/dswd/vpncloud.git
Many changes for 0.9.0
This commit is contained in:
parent
a519e875ba
commit
17254876fc
|
@ -2,11 +2,16 @@
|
||||||
|
|
||||||
This project follows [semantic versioning](http://semver.org).
|
This project follows [semantic versioning](http://semver.org).
|
||||||
|
|
||||||
### UNRELEASED
|
### v0.9.0 (UNRELEASED)
|
||||||
|
|
||||||
|
- [added] Added keepalive option for nodes behind NAT
|
||||||
|
- [added] Added ability to write out statistics file with peers and traffic info
|
||||||
|
- [added] Added dummy device type that does not allocate an interface
|
||||||
|
- [changed] Using ring instead of libsodium
|
||||||
|
- [changed] Using PBKDF2 for shared keys (**incompatible**)
|
||||||
- [fixed] Hashed magics now also consider first character (**incompatible**)
|
- [fixed] Hashed magics now also consider first character (**incompatible**)
|
||||||
|
|
||||||
### v0.8.2 (2018-01-02)
|
### v0.8.2 (2019-01-02)
|
||||||
|
|
||||||
- [changed] Using serde instead of rustc_serialize
|
- [changed] Using serde instead of rustc_serialize
|
||||||
- [changed] Updated libsodium to 1.0.16
|
- [changed] Updated libsodium to 1.0.16
|
||||||
|
|
|
@ -961,7 +961,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vpncloud"
|
name = "vpncloud"
|
||||||
version = "0.8.2"
|
version = "0.9.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "vpncloud"
|
name = "vpncloud"
|
||||||
version = "0.8.2"
|
version = "0.9.0"
|
||||||
authors = ["Dennis Schwerdel <schwerdel@informatik.uni-kl.de>"]
|
authors = ["Dennis Schwerdel <schwerdel@googlemail.com>"]
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
description = "Peer-to-peer VPN"
|
description = "Peer-to-peer VPN"
|
||||||
|
|
40
src/cloud.rs
40
src/cloud.rs
|
@ -19,8 +19,9 @@ use signal::{trap::Trap, Signal};
|
||||||
use rand::{prelude::*, random, thread_rng};
|
use rand::{prelude::*, random, thread_rng};
|
||||||
use net2::UdpBuilder;
|
use net2::UdpBuilder;
|
||||||
|
|
||||||
|
use super::config::Config;
|
||||||
use super::types::{Table, Protocol, Range, Error, HeaderMagic, NodeId};
|
use super::types::{Table, Protocol, Range, Error, HeaderMagic, NodeId};
|
||||||
use super::device::Device;
|
use super::device::{Device, Type};
|
||||||
use super::udpmessage::{encode, decode, Message};
|
use super::udpmessage::{encode, decode, Message};
|
||||||
use super::crypto::Crypto;
|
use super::crypto::Crypto;
|
||||||
use super::port_forwarding::PortForwarding;
|
use super::port_forwarding::PortForwarding;
|
||||||
|
@ -214,26 +215,25 @@ pub struct GenericCloud<P: Protocol, T: Table> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Protocol, T: Table> GenericCloud<P, T> {
|
impl<P: Protocol, T: Table> GenericCloud<P, T> {
|
||||||
#[allow(unknown_lints,clippy::too_many_arguments)]
|
pub fn new(config: &Config, device: Device, table: T,
|
||||||
pub fn new(magic: HeaderMagic, device: Device, listen: u16, table: T,
|
learning: bool, broadcast: bool, addresses: Vec<Range>,
|
||||||
peer_timeout: Duration, learning: bool, broadcast: bool, addresses: Vec<Range>,
|
crypto: Crypto, port_forwarding: Option<PortForwarding>
|
||||||
crypto: Crypto, port_forwarding: Option<PortForwarding>, stats_file: Option<String>
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let socket4 = match UdpBuilder::new_v4().expect("Failed to obtain ipv4 socket builder")
|
let socket4 = match UdpBuilder::new_v4().expect("Failed to obtain ipv4 socket builder")
|
||||||
.reuse_address(true).expect("Failed to set so_reuseaddr").bind(("0.0.0.0", listen)) {
|
.reuse_address(true).expect("Failed to set so_reuseaddr").bind(("0.0.0.0", config.port)) {
|
||||||
Ok(socket) => socket,
|
Ok(socket) => socket,
|
||||||
Err(err) => fail!("Failed to open ipv4 address 0.0.0.0:{}: {}", listen, err)
|
Err(err) => fail!("Failed to open ipv4 address 0.0.0.0:{}: {}", config.port, err)
|
||||||
};
|
};
|
||||||
let socket6 = match UdpBuilder::new_v6().expect("Failed to obtain ipv6 socket builder")
|
let socket6 = match UdpBuilder::new_v6().expect("Failed to obtain ipv6 socket builder")
|
||||||
.only_v6(true).expect("Failed to set only_v6")
|
.only_v6(true).expect("Failed to set only_v6")
|
||||||
.reuse_address(true).expect("Failed to set so_reuseaddr").bind(("::", listen)) {
|
.reuse_address(true).expect("Failed to set so_reuseaddr").bind(("::", config.port)) {
|
||||||
Ok(socket) => socket,
|
Ok(socket) => socket,
|
||||||
Err(err) => fail!("Failed to open ipv6 address ::{}: {}", listen, err)
|
Err(err) => fail!("Failed to open ipv6 address ::{}: {}", config.port, err)
|
||||||
};
|
};
|
||||||
GenericCloud{
|
GenericCloud{
|
||||||
magic,
|
magic: config.get_magic(),
|
||||||
node_id: random(),
|
node_id: random(),
|
||||||
peers: PeerList::new(peer_timeout),
|
peers: PeerList::new(config.peer_timeout),
|
||||||
addresses,
|
addresses,
|
||||||
learning,
|
learning,
|
||||||
broadcast,
|
broadcast,
|
||||||
|
@ -245,13 +245,13 @@ impl<P: Protocol, T: Table> GenericCloud<P, T> {
|
||||||
device,
|
device,
|
||||||
crypto,
|
crypto,
|
||||||
next_peerlist: now(),
|
next_peerlist: now(),
|
||||||
update_freq: peer_timeout/2-60,
|
update_freq: config.get_keepalive(),
|
||||||
buffer_out: [0; 64*1024],
|
buffer_out: [0; 64*1024],
|
||||||
next_housekeep: now(),
|
next_housekeep: now(),
|
||||||
next_stats_out: now() + STATS_INTERVAL,
|
next_stats_out: now() + STATS_INTERVAL,
|
||||||
port_forwarding,
|
port_forwarding,
|
||||||
traffic: TrafficStats::new(),
|
traffic: TrafficStats::new(),
|
||||||
stats_file,
|
stats_file: config.stats_file.clone(),
|
||||||
_dummy_p: PhantomData,
|
_dummy_p: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -635,7 +635,13 @@ impl<P: Protocol, T: Table> GenericCloud<P, T> {
|
||||||
let device_fd = self.device.as_raw_fd();
|
let device_fd = self.device.as_raw_fd();
|
||||||
try_fail!(poll_handle.register(socket4_fd, Flags::READ), "Failed to add ipv4 socket to poll handle: {}");
|
try_fail!(poll_handle.register(socket4_fd, Flags::READ), "Failed to add ipv4 socket to poll handle: {}");
|
||||||
try_fail!(poll_handle.register(socket6_fd, Flags::READ), "Failed to add ipv6 socket to poll handle: {}");
|
try_fail!(poll_handle.register(socket6_fd, Flags::READ), "Failed to add ipv6 socket to poll handle: {}");
|
||||||
try_fail!(poll_handle.register(device_fd, Flags::READ), "Failed to add device to poll handle: {}");
|
if let Err(err) = poll_handle.register(device_fd, Flags::READ) {
|
||||||
|
if self.device.get_type() != Type::Dummy {
|
||||||
|
fail!("Failed to add device to poll handle: {}", err);
|
||||||
|
} else {
|
||||||
|
warn!("Failed to add device to poll handle: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
let mut buffer = [0; 64*1024];
|
let mut buffer = [0; 64*1024];
|
||||||
let mut poll_error = false;
|
let mut poll_error = false;
|
||||||
loop {
|
loop {
|
||||||
|
@ -658,8 +664,10 @@ impl<P: Protocol, T: Table> GenericCloud<P, T> {
|
||||||
fd if fd == socket6_fd => try_fail!(self.socket6.recv_from(&mut buffer), "Failed to read from ipv6 network socket: {}"),
|
fd if fd == socket6_fd => try_fail!(self.socket6.recv_from(&mut buffer), "Failed to read from ipv6 network socket: {}"),
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
};
|
};
|
||||||
self.traffic.count_in_traffic(src, size);
|
if let Err(e) = decode(&mut buffer[..size], self.magic, &mut self.crypto).and_then(|msg| {
|
||||||
if let Err(e) = decode(&mut buffer[..size], self.magic, &mut self.crypto).and_then(|msg| self.handle_net_message(src, msg)) {
|
self.traffic.count_in_traffic(src, size);
|
||||||
|
self.handle_net_message(src, msg)
|
||||||
|
}) {
|
||||||
error!("Error: {}, from: {}", e, src);
|
error!("Error: {}, from: {}", e, src);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -13,7 +13,7 @@ use std::hash::{Hash, Hasher};
|
||||||
use siphasher::sip::SipHasher24;
|
use siphasher::sip::SipHasher24;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, PartialEq)]
|
#[derive(Deserialize, Debug, PartialEq, Clone)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub device_type: Type,
|
pub device_type: Type,
|
||||||
pub device_name: String,
|
pub device_name: String,
|
||||||
|
@ -25,6 +25,7 @@ pub struct Config {
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
pub peers: Vec<String>,
|
pub peers: Vec<String>,
|
||||||
pub peer_timeout: Duration,
|
pub peer_timeout: Duration,
|
||||||
|
pub keepalive: Option<Duration>,
|
||||||
pub mode: Mode,
|
pub mode: Mode,
|
||||||
pub dst_timeout: Duration,
|
pub dst_timeout: Duration,
|
||||||
pub subnets: Vec<String>,
|
pub subnets: Vec<String>,
|
||||||
|
@ -43,7 +44,7 @@ impl Default for Config {
|
||||||
ifup: None, ifdown: None,
|
ifup: None, ifdown: None,
|
||||||
crypto: CryptoMethod::ChaCha20, shared_key: None,
|
crypto: CryptoMethod::ChaCha20, shared_key: None,
|
||||||
magic: None,
|
magic: None,
|
||||||
port: 3210, peers: vec![], peer_timeout: 1800,
|
port: 3210, peers: vec![], peer_timeout: 1800, keepalive: None,
|
||||||
mode: Mode::Normal, dst_timeout: 300,
|
mode: Mode::Normal, dst_timeout: 300,
|
||||||
subnets: vec![],
|
subnets: vec![],
|
||||||
port_forwarding: true,
|
port_forwarding: true,
|
||||||
|
@ -88,6 +89,9 @@ impl Config {
|
||||||
if let Some(val) = file.peer_timeout {
|
if let Some(val) = file.peer_timeout {
|
||||||
self.peer_timeout = val;
|
self.peer_timeout = val;
|
||||||
}
|
}
|
||||||
|
if let Some(val) = file.keepalive {
|
||||||
|
self.keepalive = Some(val);
|
||||||
|
}
|
||||||
if let Some(val) = file.mode {
|
if let Some(val) = file.mode {
|
||||||
self.mode = val;
|
self.mode = val;
|
||||||
}
|
}
|
||||||
|
@ -147,6 +151,9 @@ impl Config {
|
||||||
if let Some(val) = args.flag_peer_timeout {
|
if let Some(val) = args.flag_peer_timeout {
|
||||||
self.peer_timeout = val;
|
self.peer_timeout = val;
|
||||||
}
|
}
|
||||||
|
if let Some(val) = args.flag_keepalive {
|
||||||
|
self.keepalive = Some(val);
|
||||||
|
}
|
||||||
if let Some(val) = args.flag_mode {
|
if let Some(val) = args.flag_mode {
|
||||||
self.mode = val;
|
self.mode = val;
|
||||||
}
|
}
|
||||||
|
@ -192,6 +199,13 @@ impl Config {
|
||||||
MAGIC
|
MAGIC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_keepalive(&self) -> Duration {
|
||||||
|
match self.keepalive {
|
||||||
|
Some(dur) => dur,
|
||||||
|
None => self.peer_timeout/2-60
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -207,6 +221,7 @@ pub struct ConfigFile {
|
||||||
pub port: Option<u16>,
|
pub port: Option<u16>,
|
||||||
pub peers: Option<Vec<String>>,
|
pub peers: Option<Vec<String>>,
|
||||||
pub peer_timeout: Option<Duration>,
|
pub peer_timeout: Option<Duration>,
|
||||||
|
pub keepalive: Option<Duration>,
|
||||||
pub mode: Option<Mode>,
|
pub mode: Option<Mode>,
|
||||||
pub dst_timeout: Option<Duration>,
|
pub dst_timeout: Option<Duration>,
|
||||||
pub subnets: Option<Vec<String>>,
|
pub subnets: Option<Vec<String>>,
|
||||||
|
|
|
@ -10,7 +10,7 @@ use ring::digest::*;
|
||||||
use super::types::Error;
|
use super::types::Error;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy)]
|
||||||
pub enum CryptoMethod {
|
pub enum CryptoMethod {
|
||||||
#[serde(rename = "chacha20")]
|
#[serde(rename = "chacha20")]
|
||||||
ChaCha20,
|
ChaCha20,
|
||||||
|
|
|
@ -23,7 +23,10 @@ pub enum Type {
|
||||||
Tun,
|
Tun,
|
||||||
/// Tap interface: This insterface transports Ethernet frames.
|
/// Tap interface: This insterface transports Ethernet frames.
|
||||||
#[serde(rename = "tap")]
|
#[serde(rename = "tap")]
|
||||||
Tap
|
Tap,
|
||||||
|
/// Dummy interface: This interface does nothing.
|
||||||
|
#[serde(rename = "dummy")]
|
||||||
|
Dummy
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Type {
|
impl fmt::Display for Type {
|
||||||
|
@ -31,6 +34,7 @@ impl fmt::Display for Type {
|
||||||
match *self {
|
match *self {
|
||||||
Type::Tun => write!(formatter, "tun"),
|
Type::Tun => write!(formatter, "tun"),
|
||||||
Type::Tap => write!(formatter, "tap"),
|
Type::Tap => write!(formatter, "tap"),
|
||||||
|
Type::Dummy => write!(formatter, "dummy")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +68,9 @@ impl Device {
|
||||||
/// # Panics
|
/// # Panics
|
||||||
/// This method panics if the interface name is longer than 31 bytes.
|
/// This method panics if the interface name is longer than 31 bytes.
|
||||||
pub fn new(ifname: &str, type_: Type) -> io::Result<Self> {
|
pub fn new(ifname: &str, type_: Type) -> io::Result<Self> {
|
||||||
|
if type_ == Type::Dummy {
|
||||||
|
return Self::dummy(ifname, "/dev/null", type_);
|
||||||
|
}
|
||||||
let fd = try!(fs::OpenOptions::new().read(true).write(true).open("/dev/net/tun"));
|
let fd = try!(fs::OpenOptions::new().read(true).write(true).open("/dev/net/tun"));
|
||||||
// Add trailing \0 to interface name
|
// Add trailing \0 to interface name
|
||||||
let mut ifname_string = String::with_capacity(32);
|
let mut ifname_string = String::with_capacity(32);
|
||||||
|
@ -73,7 +80,8 @@ impl Device {
|
||||||
let mut ifname_c = ifname_string.into_bytes();
|
let mut ifname_c = ifname_string.into_bytes();
|
||||||
let res = match type_ {
|
let res = match type_ {
|
||||||
Type::Tun => unsafe { setup_tun_device(fd.as_raw_fd(), ifname_c.as_mut_ptr()) },
|
Type::Tun => unsafe { setup_tun_device(fd.as_raw_fd(), ifname_c.as_mut_ptr()) },
|
||||||
Type::Tap => unsafe { setup_tap_device(fd.as_raw_fd(), ifname_c.as_mut_ptr()) }
|
Type::Tap => unsafe { setup_tap_device(fd.as_raw_fd(), ifname_c.as_mut_ptr()) },
|
||||||
|
Type::Dummy => unreachable!()
|
||||||
};
|
};
|
||||||
match res {
|
match res {
|
||||||
0 => {
|
0 => {
|
||||||
|
|
23
src/main.rs
23
src/main.rs
|
@ -78,6 +78,7 @@ pub struct Args {
|
||||||
flag_magic: Option<String>,
|
flag_magic: Option<String>,
|
||||||
flag_connect: Vec<String>,
|
flag_connect: Vec<String>,
|
||||||
flag_peer_timeout: Option<Duration>,
|
flag_peer_timeout: Option<Duration>,
|
||||||
|
flag_keepalive: Option<Duration>,
|
||||||
flag_dst_timeout: Option<Duration>,
|
flag_dst_timeout: Option<Duration>,
|
||||||
flag_verbose: bool,
|
flag_verbose: bool,
|
||||||
flag_quiet: bool,
|
flag_quiet: bool,
|
||||||
|
@ -159,15 +160,15 @@ enum AnyCloud<P: Protocol> {
|
||||||
|
|
||||||
impl<P: Protocol> AnyCloud<P> {
|
impl<P: Protocol> AnyCloud<P> {
|
||||||
#[allow(unknown_lints,clippy::too_many_arguments)]
|
#[allow(unknown_lints,clippy::too_many_arguments)]
|
||||||
fn new(magic: HeaderMagic, device: Device, listen: u16, table: AnyTable,
|
fn new(config: &Config, device: Device, table: AnyTable,
|
||||||
peer_timeout: Duration, learning: bool, broadcast: bool, addresses: Vec<Range>,
|
learning: bool, broadcast: bool, addresses: Vec<Range>,
|
||||||
crypto: Crypto, port_forwarding: Option<PortForwarding>, stats_file: Option<String>) -> Self {
|
crypto: Crypto, port_forwarding: Option<PortForwarding>) -> Self {
|
||||||
match table {
|
match table {
|
||||||
AnyTable::Switch(t) => AnyCloud::Switch(GenericCloud::<P, SwitchTable>::new(
|
AnyTable::Switch(t) => AnyCloud::Switch(GenericCloud::<P, SwitchTable>::new(
|
||||||
magic, device, listen, t, peer_timeout, learning, broadcast, addresses, crypto, port_forwarding, stats_file
|
config, device,t, learning, broadcast, addresses, crypto, port_forwarding
|
||||||
)),
|
)),
|
||||||
AnyTable::Routing(t) => AnyCloud::Routing(GenericCloud::<P, RoutingTable>::new(
|
AnyTable::Routing(t) => AnyCloud::Routing(GenericCloud::<P, RoutingTable>::new(
|
||||||
magic, device, listen, t, peer_timeout, learning, broadcast, addresses, crypto, port_forwarding, stats_file
|
config, device,t, learning, broadcast, addresses, crypto, port_forwarding
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,20 +212,19 @@ fn run<P: Protocol> (config: Config) {
|
||||||
ranges.push(try_fail!(Range::from_str(s), "Invalid subnet format: {} ({})", s));
|
ranges.push(try_fail!(Range::from_str(s), "Invalid subnet format: {} ({})", s));
|
||||||
}
|
}
|
||||||
let dst_timeout = config.dst_timeout;
|
let dst_timeout = config.dst_timeout;
|
||||||
let peer_timeout = config.peer_timeout;
|
|
||||||
let (learning, broadcasting, table) = match config.mode {
|
let (learning, broadcasting, table) = match config.mode {
|
||||||
Mode::Normal => match config.device_type {
|
Mode::Normal => match config.device_type {
|
||||||
Type::Tap => (true, true, AnyTable::Switch(SwitchTable::new(dst_timeout, 10))),
|
Type::Tap => (true, true, AnyTable::Switch(SwitchTable::new(dst_timeout, 10))),
|
||||||
Type::Tun => (false, false, AnyTable::Routing(RoutingTable::new()))
|
Type::Tun => (false, false, AnyTable::Routing(RoutingTable::new())),
|
||||||
|
Type::Dummy => (false, false, AnyTable::Switch(SwitchTable::new(dst_timeout, 10)))
|
||||||
},
|
},
|
||||||
Mode::Router => (false, false, AnyTable::Routing(RoutingTable::new())),
|
Mode::Router => (false, false, AnyTable::Routing(RoutingTable::new())),
|
||||||
Mode::Switch => (true, true, AnyTable::Switch(SwitchTable::new(dst_timeout, 10))),
|
Mode::Switch => (true, true, AnyTable::Switch(SwitchTable::new(dst_timeout, 10))),
|
||||||
Mode::Hub => (false, true, AnyTable::Switch(SwitchTable::new(dst_timeout, 10)))
|
Mode::Hub => (false, true, AnyTable::Switch(SwitchTable::new(dst_timeout, 10)))
|
||||||
};
|
};
|
||||||
let magic = config.get_magic();
|
|
||||||
Crypto::init();
|
Crypto::init();
|
||||||
let crypto = match config.shared_key {
|
let crypto = match config.shared_key {
|
||||||
Some(key) => Crypto::from_shared_key(config.crypto, &key),
|
Some(ref key) => Crypto::from_shared_key(config.crypto, key),
|
||||||
None => Crypto::None
|
None => Crypto::None
|
||||||
};
|
};
|
||||||
let port_forwarding = if config.port_forwarding {
|
let port_forwarding = if config.port_forwarding {
|
||||||
|
@ -232,7 +232,7 @@ fn run<P: Protocol> (config: Config) {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
let mut cloud = AnyCloud::<P>::new(magic, device, config.port, table, peer_timeout, learning, broadcasting, ranges, crypto, port_forwarding, config.stats_file);
|
let mut cloud = AnyCloud::<P>::new(&config, device, table, learning,broadcasting,ranges, crypto, port_forwarding);
|
||||||
if let Some(script) = config.ifup {
|
if let Some(script) = config.ifup {
|
||||||
run_script(&script, cloud.ifname());
|
run_script(&script, cloud.ifname());
|
||||||
}
|
}
|
||||||
|
@ -295,6 +295,7 @@ fn main() {
|
||||||
debug!("Config: {:?}", config);
|
debug!("Config: {:?}", config);
|
||||||
match config.device_type {
|
match config.device_type {
|
||||||
Type::Tap => run::<ethernet::Frame>(config),
|
Type::Tap => run::<ethernet::Frame>(config),
|
||||||
Type::Tun => run::<ip::Packet>(config)
|
Type::Tun => run::<ip::Packet>(config),
|
||||||
|
Type::Dummy => run::<ethernet::Frame>(config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
src/tests.rs
16
src/tests.rs
|
@ -456,6 +456,7 @@ peers:
|
||||||
- remote.machine.foo:3210
|
- remote.machine.foo:3210
|
||||||
- remote.machine.bar:3210
|
- remote.machine.bar:3210
|
||||||
peer_timeout: 1800
|
peer_timeout: 1800
|
||||||
|
keepalive: 840
|
||||||
dst_timeout: 300
|
dst_timeout: 300
|
||||||
mode: normal
|
mode: normal
|
||||||
subnets:
|
subnets:
|
||||||
|
@ -464,6 +465,7 @@ port_forwarding: true
|
||||||
user: nobody
|
user: nobody
|
||||||
group: nogroup
|
group: nogroup
|
||||||
pid_file: /run/vpncloud.run
|
pid_file: /run/vpncloud.run
|
||||||
|
stats_file: /var/log/vpncloud.stats
|
||||||
";
|
";
|
||||||
assert_eq!(serde_yaml::from_str::<ConfigFile>(config_file).unwrap(), ConfigFile{
|
assert_eq!(serde_yaml::from_str::<ConfigFile>(config_file).unwrap(), ConfigFile{
|
||||||
device_type: Some(Type::Tun),
|
device_type: Some(Type::Tun),
|
||||||
|
@ -476,13 +478,15 @@ pid_file: /run/vpncloud.run
|
||||||
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(1800),
|
||||||
|
keepalive: Some(840),
|
||||||
mode: Some(Mode::Normal),
|
mode: Some(Mode::Normal),
|
||||||
dst_timeout: Some(300),
|
dst_timeout: Some(300),
|
||||||
subnets: Some(vec!["10.0.1.0/24".to_string()]),
|
subnets: Some(vec!["10.0.1.0/24".to_string()]),
|
||||||
port_forwarding: Some(true),
|
port_forwarding: Some(true),
|
||||||
user: Some("nobody".to_string()),
|
user: Some("nobody".to_string()),
|
||||||
group: Some("nogroup".to_string()),
|
group: Some("nogroup".to_string()),
|
||||||
pid_file: Some("/run/vpncloud.run".to_string())
|
pid_file: Some("/run/vpncloud.run".to_string()),
|
||||||
|
stats_file: Some("/var/log/vpncloud.stats".to_string())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,13 +504,15 @@ fn config_merge() {
|
||||||
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(1800),
|
||||||
|
keepalive: Some(840),
|
||||||
mode: Some(Mode::Normal),
|
mode: Some(Mode::Normal),
|
||||||
dst_timeout: Some(300),
|
dst_timeout: Some(300),
|
||||||
subnets: Some(vec!["10.0.1.0/24".to_string()]),
|
subnets: Some(vec!["10.0.1.0/24".to_string()]),
|
||||||
port_forwarding: Some(true),
|
port_forwarding: Some(true),
|
||||||
user: Some("nobody".to_string()),
|
user: Some("nobody".to_string()),
|
||||||
group: Some("nogroup".to_string()),
|
group: Some("nogroup".to_string()),
|
||||||
pid_file: Some("/run/vpncloud.run".to_string())
|
pid_file: Some("/run/vpncloud.run".to_string()),
|
||||||
|
stats_file: Some("/var/log/vpncloud.stats".to_string())
|
||||||
});
|
});
|
||||||
assert_eq!(config, Config{
|
assert_eq!(config, Config{
|
||||||
device_type: Type::Tun,
|
device_type: Type::Tun,
|
||||||
|
@ -519,6 +525,7 @@ fn config_merge() {
|
||||||
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: 1800,
|
||||||
|
keepalive: Some(840),
|
||||||
dst_timeout: 300,
|
dst_timeout: 300,
|
||||||
mode: Mode::Normal,
|
mode: Mode::Normal,
|
||||||
port_forwarding: true,
|
port_forwarding: true,
|
||||||
|
@ -526,6 +533,7 @@ fn config_merge() {
|
||||||
user: Some("nobody".to_string()),
|
user: Some("nobody".to_string()),
|
||||||
group: Some("nogroup".to_string()),
|
group: Some("nogroup".to_string()),
|
||||||
pid_file: Some("/run/vpncloud.run".to_string()),
|
pid_file: Some("/run/vpncloud.run".to_string()),
|
||||||
|
stats_file: Some("/var/log/vpncloud.stats".to_string()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
config.merge_args(Args{
|
config.merge_args(Args{
|
||||||
|
@ -538,6 +546,7 @@ fn config_merge() {
|
||||||
flag_magic: Some("hash:mynet".to_string()),
|
flag_magic: Some("hash:mynet".to_string()),
|
||||||
flag_listen: Some(3211),
|
flag_listen: Some(3211),
|
||||||
flag_peer_timeout: Some(1801),
|
flag_peer_timeout: Some(1801),
|
||||||
|
flag_keepalive: Some(850),
|
||||||
flag_dst_timeout: Some(301),
|
flag_dst_timeout: Some(301),
|
||||||
flag_mode: Some(Mode::Switch),
|
flag_mode: Some(Mode::Switch),
|
||||||
flag_subnet: vec![],
|
flag_subnet: vec![],
|
||||||
|
@ -545,6 +554,7 @@ fn config_merge() {
|
||||||
flag_no_port_forwarding: true,
|
flag_no_port_forwarding: true,
|
||||||
flag_daemon: true,
|
flag_daemon: true,
|
||||||
flag_pid_file: Some("/run/vpncloud-mynet.run".to_string()),
|
flag_pid_file: Some("/run/vpncloud-mynet.run".to_string()),
|
||||||
|
flag_stats_file: Some("/var/log/vpncloud-mynet.stats".to_string()),
|
||||||
flag_user: Some("root".to_string()),
|
flag_user: Some("root".to_string()),
|
||||||
flag_group: Some("root".to_string()),
|
flag_group: Some("root".to_string()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -560,6 +570,7 @@ fn config_merge() {
|
||||||
port: 3211,
|
port: 3211,
|
||||||
peers: vec!["remote.machine.foo:3210".to_string(), "remote.machine.bar:3210".to_string(), "another:3210".to_string()],
|
peers: vec!["remote.machine.foo:3210".to_string(), "remote.machine.bar:3210".to_string(), "another:3210".to_string()],
|
||||||
peer_timeout: 1801,
|
peer_timeout: 1801,
|
||||||
|
keepalive: Some(850),
|
||||||
dst_timeout: 301,
|
dst_timeout: 301,
|
||||||
mode: Mode::Switch,
|
mode: Mode::Switch,
|
||||||
port_forwarding: false,
|
port_forwarding: false,
|
||||||
|
@ -567,6 +578,7 @@ fn config_merge() {
|
||||||
user: Some("root".to_string()),
|
user: Some("root".to_string()),
|
||||||
group: Some("root".to_string()),
|
group: Some("root".to_string()),
|
||||||
pid_file: Some("/run/vpncloud-mynet.run".to_string()),
|
pid_file: Some("/run/vpncloud-mynet.run".to_string()),
|
||||||
|
stats_file: Some("/var/log/vpncloud-mynet.stats".to_string()),
|
||||||
daemonize: true,
|
daemonize: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,6 +19,8 @@ Options:
|
||||||
--crypto <method> The encryption method to use ("aes256", or
|
--crypto <method> The encryption method to use ("aes256", or
|
||||||
"chacha20").
|
"chacha20").
|
||||||
--peer-timeout <secs> Peer timeout in seconds.
|
--peer-timeout <secs> Peer timeout in seconds.
|
||||||
|
--keepalive <secs> Periodically send message to keep
|
||||||
|
connections alive.
|
||||||
--dst-timeout <secs> Switch table entry timeout in seconds.
|
--dst-timeout <secs> Switch table entry timeout in seconds.
|
||||||
--ifup <command> A command to setup the network interface.
|
--ifup <command> A command to setup the network interface.
|
||||||
--ifdown <command> A command to bring down the network
|
--ifdown <command> A command to bring down the network
|
||||||
|
|
Loading…
Reference in New Issue