Compare commits

..

3 Commits

Author SHA1 Message Date
Dennis Schwerdel 1f32f0a6a7 Updated dependencies 2019-01-02 00:57:54 +01:00
Dennis Schwerdel 6866c29a71 Fixed wrong address 2019-01-01 22:55:15 +01:00
Dennis Schwerdel 4c9ec65254 Fixed wrong address 2019-01-01 22:50:04 +01:00
19 changed files with 1025 additions and 427 deletions

View File

@ -5,7 +5,10 @@ This project follows [semantic versioning](http://semver.org).
### UNRELEASED ### UNRELEASED
- [changed] Using serde instead of rustc_serialize - [changed] Using serde instead of rustc_serialize
- [changed] Updated libsodium to 1.0.16
- [changed] Updated dependencies - [changed] Updated dependencies
- [changed] Making clippy happy
- [fixed] Fixed wrong address
### v0.8.1 (2017-05-09) ### v0.8.1 (2017-05-09)

1224
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -12,25 +12,25 @@ readme = "README.md"
[dependencies] [dependencies]
time = "0.1" time = "0.1"
docopt = "0.8" docopt = "^1"
serde = "1.0" serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"
serde_yaml = "0.7" serde_yaml = "0.8"
log = "0.3" log = { version = "0.4", features = ["std"] }
signal = "0.3" signal = "0.6"
libc = "0.2" libc = "0.2"
aligned_alloc = "0.1" aligned_alloc = "0.1"
rand = "0.3" rand = "0.6"
fnv = "1" fnv = "1"
net2 = "0.2" net2 = "0.2"
bitflags = "0.8" bitflags = "^1"
yaml-rust = "0.3" yaml-rust = "0.4"
igd = "0.6" igd = "0.7"
siphasher = "0.2" siphasher = "0.3"
daemonize = "0.2" daemonize = "0.3"
[build-dependencies] [build-dependencies]
gcc = "0.3" cc = "^1"
pkg-config = "0.3" pkg-config = "0.3"
[features] [features]

View File

@ -2,7 +2,7 @@
// Copyright (C) 2015-2017 Dennis Schwerdel // Copyright (C) 2015-2017 Dennis Schwerdel
// This software is licensed under GPL-3 or newer (see LICENSE.md) // This software is licensed under GPL-3 or newer (see LICENSE.md)
extern crate gcc; extern crate cc;
extern crate pkg_config; extern crate pkg_config;
use std::process::Command; use std::process::Command;
@ -11,7 +11,7 @@ use std::env;
use std::fs; use std::fs;
fn main() { fn main() {
gcc::Config::new().file("src/c/tuntap.c").include("src").compile("libtuntap.a"); cc::Build::new().file("src/c/tuntap.c").include("src").compile("libtuntap.a");
if cfg!(feature = "system-libsodium") { if cfg!(feature = "system-libsodium") {
pkg_config::Config::new().atleast_version("1.0.8").probe("libsodium").expect("Libsodium >= 1.0.8 missing"); pkg_config::Config::new().atleast_version("1.0.8").probe("libsodium").expect("Libsodium >= 1.0.8 missing");
return return

@ -1 +1 @@
Subproject commit 70170c28c844a4786e75efc626e1aeebc93caebc Subproject commit 675149b9b8b66ff44152553fb3ebf9858128363d

View File

@ -17,7 +17,7 @@ use super::ethernet::{Frame, SwitchTable};
use super::types::{Address, Table, Protocol}; use super::types::{Address, Table, Protocol};
use super::ip::Packet; use super::ip::Packet;
use super::util::now as util_now; use super::util::now as util_now;
use super::poll::{self, Poll}; use super::poll::{Poll, Flags};
#[bench] #[bench]
fn crypto_salsa20(b: &mut Bencher) { fn crypto_salsa20(b: &mut Bencher) {
@ -141,7 +141,7 @@ fn epoll_wait(b: &mut Bencher) {
let socket = UdpSocket::bind("0.0.0.0:0").unwrap(); let socket = UdpSocket::bind("0.0.0.0:0").unwrap();
let mut poll_handle = Poll::new(1).unwrap(); let mut poll_handle = Poll::new(1).unwrap();
let fd = socket.as_raw_fd(); let fd = socket.as_raw_fd();
poll_handle.register(fd, poll::WRITE).unwrap(); poll_handle.register(fd, Flags::WRITE).unwrap();
b.iter(|| { b.iter(|| {
assert_eq!(poll_handle.wait(1000).unwrap().len(), 1) assert_eq!(poll_handle.wait(1000).unwrap().len(), 1)
}); });

View File

@ -14,9 +14,8 @@ use std::time::Instant;
use std::cmp::min; use std::cmp::min;
use fnv::FnvHasher; use fnv::FnvHasher;
use libc::{SIGTERM, SIGQUIT, SIGINT}; use signal::{trap::Trap, Signal};
use signal::trap::Trap; use rand::{prelude::*, random, thread_rng};
use rand::{random, sample, thread_rng};
use net2::UdpBuilder; use net2::UdpBuilder;
use super::types::{Table, Protocol, Range, Error, HeaderMagic, NodeId}; use super::types::{Table, Protocol, Range, Error, HeaderMagic, NodeId};
@ -25,7 +24,7 @@ use super::udpmessage::{encode, decode, Message};
use super::crypto::Crypto; use super::crypto::Crypto;
use super::port_forwarding::PortForwarding; use super::port_forwarding::PortForwarding;
use super::util::{now, Time, Duration, resolve}; use super::util::{now, Time, Duration, resolve};
use super::poll::{self, Poll}; use super::poll::{Poll, Flags};
type Hash = BuildHasherDefault<FnvHasher>; type Hash = BuildHasherDefault<FnvHasher>;
@ -44,7 +43,7 @@ impl PeerList {
fn new(timeout: Duration) -> PeerList { fn new(timeout: Duration) -> PeerList {
PeerList{ PeerList{
peers: HashMap::default(), peers: HashMap::default(),
timeout: timeout, timeout,
nodes: HashMap::default(), nodes: HashMap::default(),
addresses: HashSet::default() addresses: HashSet::default()
} }
@ -96,7 +95,7 @@ impl PeerList {
fn add(&mut self, node_id: NodeId, addr: SocketAddr) { fn add(&mut self, node_id: NodeId, addr: SocketAddr) {
if self.nodes.insert(node_id, addr).is_none() { if self.nodes.insert(node_id, addr).is_none() {
info!("New peer: {}", addr); info!("New peer: {}", addr);
self.peers.insert(addr, (now()+self.timeout as Time, node_id, vec![])); self.peers.insert(addr, (now()+Time::from(self.timeout), node_id, vec![]));
self.addresses.insert(addr); self.addresses.insert(addr);
} }
} }
@ -104,7 +103,7 @@ impl PeerList {
#[inline] #[inline]
fn refresh(&mut self, addr: &SocketAddr) { fn refresh(&mut self, addr: &SocketAddr) {
if let Some(&mut (ref mut timeout, _node_id, ref _alt_addrs)) = self.peers.get_mut(addr) { if let Some(&mut (ref mut timeout, _node_id, ref _alt_addrs)) = self.peers.get_mut(addr) {
*timeout = now()+self.timeout as Time; *timeout = now()+Time::from(self.timeout);
} }
} }
@ -140,7 +139,7 @@ impl PeerList {
#[inline] #[inline]
fn subset(&self, size: usize) -> Vec<SocketAddr> { fn subset(&self, size: usize) -> Vec<SocketAddr> {
sample(&mut thread_rng(), self.as_vec(), size) self.addresses.iter().choose_multiple(&mut thread_rng(), size).into_iter().cloned().collect()
} }
#[inline] #[inline]
@ -190,8 +189,7 @@ 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)] #[allow(unknown_lints,clippy::too_many_arguments)]
#[allow(too_many_arguments)]
pub fn new(magic: HeaderMagic, device: Device, listen: u16, table: T, pub fn new(magic: HeaderMagic, device: Device, listen: u16, table: T,
peer_timeout: Duration, learning: bool, broadcast: bool, addresses: Vec<Range>, peer_timeout: Duration, learning: bool, broadcast: bool, addresses: Vec<Range>,
crypto: Crypto, port_forwarding: Option<PortForwarding>) -> Self { crypto: Crypto, port_forwarding: Option<PortForwarding>) -> Self {
@ -207,24 +205,24 @@ impl<P: Protocol, T: Table> GenericCloud<P, T> {
Err(err) => fail!("Failed to open ipv6 address ::{}: {}", listen, err) Err(err) => fail!("Failed to open ipv6 address ::{}: {}", listen, err)
}; };
GenericCloud{ GenericCloud{
magic: magic, magic,
node_id: random(), node_id: random(),
peers: PeerList::new(peer_timeout), peers: PeerList::new(peer_timeout),
addresses: addresses, addresses,
learning: learning, learning,
broadcast: broadcast, broadcast,
reconnect_peers: Vec::new(), reconnect_peers: Vec::new(),
blacklist_peers: Vec::new(), blacklist_peers: Vec::new(),
table: table, table,
socket4: socket4, socket4,
socket6: socket6, socket6,
device: device, device,
crypto: crypto, crypto,
next_peerlist: now(), next_peerlist: now(),
update_freq: peer_timeout/2-60, update_freq: peer_timeout/2-60,
buffer_out: [0; 64*1024], buffer_out: [0; 64*1024],
next_housekeep: now(), next_housekeep: now(),
port_forwarding: port_forwarding, port_forwarding,
_dummy_p: PhantomData, _dummy_p: PhantomData,
} }
} }
@ -384,7 +382,7 @@ impl<P: Protocol, T: Table> GenericCloud<P, T> {
let mut msg = Message::Peers(peers); let mut msg = Message::Peers(peers);
try!(self.broadcast_msg(&mut msg)); try!(self.broadcast_msg(&mut msg));
// Reschedule for next update // Reschedule for next update
self.next_peerlist = now + self.update_freq as Time; self.next_peerlist = now + Time::from(self.update_freq);
} }
// Connect to those reconnect_peers that are due // Connect to those reconnect_peers that are due
for entry in self.reconnect_peers.clone() { for entry in self.reconnect_peers.clone() {
@ -423,7 +421,7 @@ impl<P: Protocol, T: Table> GenericCloud<P, T> {
entry.timeout = MAX_RECONNECT_INTERVAL; entry.timeout = MAX_RECONNECT_INTERVAL;
} }
// Schedule next connection attempt // Schedule next connection attempt
entry.next = now + entry.timeout as Time; entry.next = now + Time::from(entry.timeout);
} }
Ok(()) Ok(())
} }
@ -574,18 +572,17 @@ impl<P: Protocol, T: Table> GenericCloud<P, T> {
/// `handle_net_message` method. It will also read from the device and call /// `handle_net_message` method. It will also read from the device and call
/// `handle_interface_data` for each packet read. /// `handle_interface_data` for each packet read.
/// Also, this method will call `housekeep` every second. /// Also, this method will call `housekeep` every second.
#[allow(unknown_lints)] #[allow(unknown_lints,clippy::cyclomatic_complexity)]
#[allow(cyclomatic_complexity)]
pub fn run(&mut self) { pub fn run(&mut self) {
let dummy_time = Instant::now(); let dummy_time = Instant::now();
let trap = Trap::trap(&[SIGINT, SIGTERM, SIGQUIT]); let trap = Trap::trap(&[Signal::SIGINT, Signal::SIGTERM, Signal::SIGQUIT]);
let mut poll_handle = try_fail!(Poll::new(3), "Failed to create poll handle: {}"); let mut poll_handle = try_fail!(Poll::new(3), "Failed to create poll handle: {}");
let socket4_fd = self.socket4.as_raw_fd(); let socket4_fd = self.socket4.as_raw_fd();
let socket6_fd = self.socket6.as_raw_fd(); let socket6_fd = self.socket6.as_raw_fd();
let device_fd = self.device.as_raw_fd(); let device_fd = self.device.as_raw_fd();
try_fail!(poll_handle.register(socket4_fd, poll::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, poll::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, poll::READ), "Failed to add device to poll handle: {}"); try_fail!(poll_handle.register(device_fd, Flags::READ), "Failed to add device to poll handle: {}");
let mut buffer = [0; 64*1024]; let mut buffer = [0; 64*1024];
let mut poll_error = false; let mut poll_error = false;
loop { loop {

View File

@ -172,7 +172,7 @@ impl Config {
let mut s = SipHasher24::new(); let mut s = SipHasher24::new();
name[6..].hash(&mut s); name[6..].hash(&mut s);
let mut data = [0; 4]; let mut data = [0; 4];
Encoder::write_u32((s.finish() & 0xffffffff) as u32, &mut data); Encoder::write_u32((s.finish() & 0xffff_ffff) as u32, &mut data);
data data
} else { } else {
let num = try_fail!(u32::from_str_radix(name, 16), "Failed to parse header magic: {}"); let num = try_fail!(u32::from_str_radix(name, 16), "Failed to parse header magic: {}");

View File

@ -38,9 +38,9 @@ const crypto_pwhash_scryptsalsa208sha256_SALTBYTES: usize = 32;
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
const crypto_pwhash_scryptsalsa208sha256_STRBYTES: usize = 102; const crypto_pwhash_scryptsalsa208sha256_STRBYTES: usize = 102;
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
const crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE: usize = 524288; const crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE: usize = 524_288;
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
const crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE: usize = 16777216; const crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE: usize = 16_777_216;
pub struct Aes256State(*mut [u8; crypto_aead_aes256gcm_STATEBYTES]); pub struct Aes256State(*mut [u8; crypto_aead_aes256gcm_STATEBYTES]);
@ -193,8 +193,7 @@ impl Crypto {
} }
#[inline] #[inline]
#[allow(unknown_lints)] #[allow(unknown_lints,clippy::match_same_arms)]
#[allow(match_same_arms)]
pub fn additional_bytes(&self) -> usize { pub fn additional_bytes(&self) -> usize {
match *self { match *self {
Crypto::None => 0, Crypto::None => 0,
@ -225,7 +224,7 @@ impl Crypto {
crypto_key.clone_from_slice(&key[..crypto_aead_chacha20poly1305_ietf_KEYBYTES]); crypto_key.clone_from_slice(&key[..crypto_aead_chacha20poly1305_ietf_KEYBYTES]);
let mut nonce = [0u8; crypto_aead_chacha20poly1305_ietf_NPUBBYTES]; let mut nonce = [0u8; crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
unsafe { randombytes_buf(nonce.as_mut_ptr(), nonce.len()) }; unsafe { randombytes_buf(nonce.as_mut_ptr(), nonce.len()) };
Crypto::ChaCha20Poly1305{key: crypto_key, nonce: nonce} Crypto::ChaCha20Poly1305{key: crypto_key, nonce}
}, },
CryptoMethod::AES256 => { CryptoMethod::AES256 => {
if ! Crypto::aes256_available() { if ! Crypto::aes256_available() {
@ -239,12 +238,12 @@ impl Crypto {
key[..crypto_aead_aes256gcm_KEYBYTES].as_ptr() as *const [u8; crypto_aead_aes256gcm_KEYBYTES] key[..crypto_aead_aes256gcm_KEYBYTES].as_ptr() as *const [u8; crypto_aead_aes256gcm_KEYBYTES]
) }; ) };
assert_eq!(res, 0); assert_eq!(res, 0);
Crypto::AES256GCM{state: state, nonce: nonce} Crypto::AES256GCM{state, nonce}
} }
} }
} }
pub fn decrypt(&self, mut buf: &mut [u8], nonce: &[u8], header: &[u8]) -> Result<usize, Error> { pub fn decrypt(&self, buf: &mut [u8], nonce: &[u8], header: &[u8]) -> Result<usize, Error> {
match *self { match *self {
Crypto::None => Ok(buf.len()), Crypto::None => Ok(buf.len()),
Crypto::ChaCha20Poly1305{ref key, ..} => { Crypto::ChaCha20Poly1305{ref key, ..} => {
@ -286,7 +285,7 @@ impl Crypto {
} }
} }
pub fn encrypt(&mut self, mut buf: &mut [u8], mlen: usize, nonce_bytes: &mut [u8], header: &[u8]) -> usize { pub fn encrypt(&mut self, buf: &mut [u8], mlen: usize, nonce_bytes: &mut [u8], header: &[u8]) -> usize {
match *self { match *self {
Crypto::None => mlen, Crypto::None => mlen,
Crypto::ChaCha20Poly1305{ref key, ref mut nonce} => { Crypto::ChaCha20Poly1305{ref key, ref mut nonce} => {

View File

@ -81,7 +81,7 @@ impl Device {
while ifname_c.last() == Some(&0) { while ifname_c.last() == Some(&0) {
ifname_c.pop(); ifname_c.pop();
} }
Ok(Device{fd: fd, ifname: String::from_utf8(ifname_c).unwrap(), type_: type_}) Ok(Device{fd, ifname: String::from_utf8(ifname_c).unwrap(), type_})
}, },
_ => Err(IoError::last_os_error()) _ => Err(IoError::last_os_error())
} }
@ -118,7 +118,7 @@ impl Device {
Ok(Device{ Ok(Device{
fd: try!(fs::OpenOptions::new().create(true).read(true).write(true).open(path)), fd: try!(fs::OpenOptions::new().create(true).read(true).write(true).open(path)),
ifname: ifname.to_string(), ifname: ifname.to_string(),
type_: type_ type_
}) })
} }

View File

@ -79,7 +79,7 @@ pub struct SwitchTable {
impl SwitchTable { impl SwitchTable {
/// Creates a new switch table /// Creates a new switch table
pub fn new(timeout: Duration, protection_period: Duration) -> Self { pub fn new(timeout: Duration, protection_period: Duration) -> Self {
SwitchTable{table: HashMap::default(), timeout: timeout, protection_period: protection_period} SwitchTable{table: HashMap::default(), timeout, protection_period}
} }
} }
@ -102,7 +102,7 @@ impl Table for SwitchTable {
/// Learns the given address, inserting it in the hash map /// Learns the given address, inserting it in the hash map
#[inline] #[inline]
fn learn(&mut self, key: Address, _prefix_len: Option<u8>, addr: SocketAddr) { fn learn(&mut self, key: Address, _prefix_len: Option<u8>, addr: SocketAddr) {
let deadline = now() + self.timeout as Time; let deadline = now() + Time::from(self.timeout);
match self.table.entry(key) { match self.table.entry(key) {
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
entry.insert(SwitchTableValue{address: addr, timeout: deadline}); entry.insert(SwitchTableValue{address: addr, timeout: deadline});
@ -110,7 +110,7 @@ impl Table for SwitchTable {
}, },
Entry::Occupied(mut entry) => { Entry::Occupied(mut entry) => {
let mut entry = entry.get_mut(); let mut entry = entry.get_mut();
if entry.timeout + self.protection_period as Time > deadline { if entry.timeout + Time::from(self.protection_period) > deadline {
// Do not override recently learnt entries // Do not override recently learnt entries
return return
} }

View File

@ -24,7 +24,7 @@ impl Protocol for Packet {
/// # Errors /// # Errors
/// This method will fail when the given data is not a valid ipv4 and ipv6 packet. /// This method will fail when the given data is not a valid ipv4 and ipv6 packet.
fn parse(data: &[u8]) -> Result<(Address, Address), Error> { fn parse(data: &[u8]) -> Result<(Address, Address), Error> {
if data.len() < 1 { if data.is_empty() {
return Err(Error::Parse("Empty header")); return Err(Error::Parse("Empty header"));
} }
let version = data[0] >> 4; let version = data[0] >> 4;
@ -90,16 +90,16 @@ impl Table for RoutingTable {
let mut group_bytes = [0; 16]; let mut group_bytes = [0; 16];
group_bytes[..group_len].copy_from_slice(&addr.data[..group_len]); group_bytes[..group_len].copy_from_slice(&addr.data[..group_len]);
// Create an entry // Create an entry
let routing_entry = RoutingEntry{address: address, bytes: addr.data, prefix_len: prefix_len}; let routing_entry = RoutingEntry{address, bytes: addr.data, prefix_len};
// Add the entry to the routing table, creating a new list of the prefix group is empty. // Add the entry to the routing table, creating a new list of the prefix group is empty.
match self.0.entry(group_bytes) { match self.0.entry(group_bytes) {
hash_map::Entry::Occupied(mut entry) => entry.get_mut().push(routing_entry), hash_map::Entry::Occupied(mut entry) => entry.get_mut().push(routing_entry),
hash_map::Entry::Vacant(entry) => { entry.insert(vec![routing_entry]); () } hash_map::Entry::Vacant(entry) => { entry.insert(vec![routing_entry]); }
} }
} }
/// Retrieves a peer for an address if it is inside the routing table /// Retrieves a peer for an address if it is inside the routing table
#[allow(unknown_lints, needless_range_loop)] #[allow(unknown_lints, clippy::needless_range_loop)]
fn lookup(&mut self, addr: &Address) -> Option<SocketAddr> { fn lookup(&mut self, addr: &Address) -> Option<SocketAddr> {
let len = addr.len as usize; let len = addr.len as usize;
let mut found = None; let mut found = None;
@ -110,7 +110,7 @@ impl Table for RoutingTable {
for i in len..16 { for i in len..16 {
group_bytes[i] = 0; group_bytes[i] = 0;
} }
for i in (0..len+1).rev() { for i in (0..=len).rev() {
if i < len { if i < len {
group_bytes[i] = 0; group_bytes[i] = 0;
} }

View File

@ -62,6 +62,7 @@ const MAGIC: HeaderMagic = *b"vpn\x01";
static USAGE: &'static str = include_str!("usage.txt"); static USAGE: &'static str = include_str!("usage.txt");
#[derive(Deserialize, Debug, Default)] #[derive(Deserialize, Debug, Default)]
pub struct Args { pub struct Args {
flag_config: Option<String>, flag_config: Option<String>,
@ -90,7 +91,6 @@ pub struct Args {
flag_log_file: Option<String> flag_log_file: Option<String>
} }
struct DualLogger { struct DualLogger {
file: Mutex<Option<File>> file: Mutex<Option<File>>
} }
@ -108,12 +108,12 @@ impl DualLogger {
impl log::Log for DualLogger { impl log::Log for DualLogger {
#[inline] #[inline]
fn enabled(&self, _metadata: &log::LogMetadata) -> bool { fn enabled(&self, _metadata: &log::Metadata) -> bool {
true true
} }
#[inline] #[inline]
fn log(&self, record: &log::LogRecord) { fn log(&self, record: &log::Record) {
if self.enabled(record.metadata()) { if self.enabled(record.metadata()) {
println!("{} - {}", record.level(), record.args()); println!("{} - {}", record.level(), record.args());
let mut file = self.file.lock().expect("Lock poisoned"); let mut file = self.file.lock().expect("Lock poisoned");
@ -123,6 +123,14 @@ impl log::Log for DualLogger {
} }
} }
} }
#[inline]
fn flush(&self) {
let mut file = self.file.lock().expect("Lock poisoned");
if let Some(ref mut file) = *file {
try_fail!(file.flush(), "Logging error: {}");
}
}
} }
fn run_script(script: &str, ifname: &str) { fn run_script(script: &str, ifname: &str) {
@ -130,9 +138,7 @@ fn run_script(script: &str, ifname: &str) {
cmd.arg("-c").arg(&script).env("IFNAME", ifname); cmd.arg("-c").arg(&script).env("IFNAME", ifname);
debug!("Running script: {:?}", cmd); debug!("Running script: {:?}", cmd);
match cmd.status() { match cmd.status() {
Ok(status) => if status.success() { Ok(status) => if !status.success() {
()
} else {
error!("Script returned with error: {:?}", status.code()) error!("Script returned with error: {:?}", status.code())
}, },
Err(e) => error!("Failed to execute script {:?}: {}", script, e) Err(e) => error!("Failed to execute script {:?}: {}", script, e)
@ -150,7 +156,7 @@ enum AnyCloud<P: Protocol> {
} }
impl<P: Protocol> AnyCloud<P> { impl<P: Protocol> AnyCloud<P> {
#[allow(unknown_lints,too_many_arguments)] #[allow(unknown_lints,clippy::too_many_arguments)]
fn new(magic: HeaderMagic, device: Device, listen: u16, table: AnyTable, fn new(magic: HeaderMagic, device: Device, listen: u16, table: AnyTable,
peer_timeout: Duration, learning: bool, broadcast: bool, addresses: Vec<Range>, peer_timeout: Duration, learning: bool, broadcast: bool, addresses: Vec<Range>,
crypto: Crypto, port_forwarding: Option<PortForwarding>) -> Self { crypto: Crypto, port_forwarding: Option<PortForwarding>) -> Self {
@ -264,17 +270,18 @@ fn main() {
); );
return; return;
} }
log::set_logger(|max_log_level| { let logger = try_fail!(DualLogger::new(args.flag_log_file.as_ref()), "Failed to open logfile: {}");
log::set_boxed_logger(Box::new(logger)).unwrap();
assert!(!args.flag_verbose || !args.flag_quiet); assert!(!args.flag_verbose || !args.flag_quiet);
log::set_max_level(
if args.flag_verbose { if args.flag_verbose {
max_log_level.set(log::LogLevelFilter::Debug); log::LevelFilter::Debug
} else if args.flag_quiet { } else if args.flag_quiet {
max_log_level.set(log::LogLevelFilter::Error); log::LevelFilter::Error
} else { } else {
max_log_level.set(log::LogLevelFilter::Info); log::LevelFilter::Info
} }
Box::new(try_fail!(DualLogger::new(args.flag_log_file.as_ref()), "Failed to open logfile: {}")) );
}).unwrap();
let mut config = Config::default(); let mut config = Config::default();
if let Some(ref file) = args.flag_config { if let Some(ref file) = args.flag_config {
info!("Reading config file '{}'", file); info!("Reading config file '{}'", file);

View File

@ -9,10 +9,10 @@ use std::io;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
bitflags!{ bitflags!{
pub flags Flags: u32 { pub struct Flags: u32 {
const READ = libc::EPOLLIN as u32, const READ = libc::EPOLLIN as u32;
const WRITE = libc::EPOLLOUT as u32, const WRITE = libc::EPOLLOUT as u32;
const ERROR = libc::EPOLLERR as u32, const ERROR = libc::EPOLLERR as u32;
} }
} }
@ -67,7 +67,7 @@ impl Poll {
if fd == -1 { if fd == -1 {
return Err(io::Error::last_os_error()); return Err(io::Error::last_os_error());
} }
Ok(Poll{fd: fd, events: events}) Ok(Poll{fd, events})
} }
#[inline] #[inline]

View File

@ -10,7 +10,7 @@ use igd::*;
use super::util::{Time, now}; use super::util::{Time, now};
const LEASE_TIME: u32 = 300; const LEASE_TIME: u32 = 300;
const DESCRIPTION: &'static str = "VpnCloud"; const DESCRIPTION: &str = "VpnCloud";
pub struct PortForwarding { pub struct PortForwarding {
@ -90,15 +90,15 @@ impl PortForwarding {
}; };
info!("Port-forwarding: sucessfully activated port forward on {}, timeout: {}", external_addr, timeout); info!("Port-forwarding: sucessfully activated port forward on {}, timeout: {}", external_addr, timeout);
let next_extension = if timeout > 0 { let next_extension = if timeout > 0 {
Some(now() + timeout as Time - 60) Some(now() + Time::from(timeout) - 60)
} else { } else {
None None
}; };
Some(PortForwarding { Some(PortForwarding {
internal_addr: internal_addr, internal_addr,
external_addr: external_addr, external_addr,
gateway: gateway, gateway,
next_extension: next_extension next_extension
}) })
} }
@ -114,7 +114,7 @@ impl PortForwarding {
Ok(()) => debug!("Port-forwarding: extended port forwarding"), Ok(()) => debug!("Port-forwarding: extended port forwarding"),
Err(err) => error!("Port-forwarding: failed to extend port forwarding: {}", err) Err(err) => error!("Port-forwarding: failed to extend port forwarding: {}", err)
}; };
self.next_extension = Some(now() + LEASE_TIME as Time - 60); self.next_extension = Some(now() + Time::from(LEASE_TIME) - 60);
} }
fn deactivate(&self) { fn deactivate(&self) {

View File

@ -318,10 +318,10 @@ fn routing_table_ipv6() {
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:2").unwrap()), Some(peer2)); assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:2").unwrap()), Some(peer2));
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:3").unwrap()), Some(peer3)); assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:3").unwrap()), Some(peer3));
assert_eq!(table.lookup(&Address::from_str("::1").unwrap()), Some(peer2)); assert_eq!(table.lookup(&Address::from_str("::1").unwrap()), Some(peer2));
table.learn(Address::from_str("dead:beef:dead:beef:dead:beef:dead::be00").unwrap(), Some(123), peer2.clone()); table.learn(Address::from_str("dead:beef:dead:beef:dead:beef:dead:be00").unwrap(), Some(123), peer2.clone());
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:be1f").unwrap()), Some(peer2)); assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:be1f").unwrap()), Some(peer2));
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:be20").unwrap()), Some(peer3)); assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:be20").unwrap()), Some(peer3));
table.learn(Address::from_str("dead:beef:dead:beef:dead:beef:dead::be00").unwrap(), Some(124), peer3.clone()); table.learn(Address::from_str("dead:beef:dead:beef:dead:beef:dead:be00").unwrap(), Some(124), peer3.clone());
assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:be01").unwrap()), Some(peer3)); assert_eq!(table.lookup(&Address::from_str("dead:beef:dead:beef:dead:beef:dead:be01").unwrap()), Some(peer3));
} }

View File

@ -25,7 +25,7 @@ pub struct Address {
impl Address { impl Address {
#[inline] #[inline]
pub fn read_from(data: &[u8]) -> Result<(Address, usize), Error> { pub fn read_from(data: &[u8]) -> Result<(Address, usize), Error> {
if data.len() < 1 { if data.is_empty() {
return Err(Error::Parse("Address too short")); return Err(Error::Parse("Address too short"));
} }
let len = data[0] as usize; let len = data[0] as usize;
@ -48,10 +48,10 @@ impl Address {
#[inline] #[inline]
pub fn write_to(&self, data: &mut[u8]) -> usize { pub fn write_to(&self, data: &mut[u8]) -> usize {
assert!(data.len() >= self.len as usize + 1); assert!(data.len() > self.len as usize);
data[0] = self.len; data[0] = self.len;
let len = self.len as usize; let len = self.len as usize;
data[1..len+1].copy_from_slice(&self.data[0..len]); data[1..=len].copy_from_slice(&self.data[0..len]);
self.len as usize + 1 self.len as usize + 1
} }
} }
@ -101,8 +101,7 @@ impl fmt::Debug for Address {
impl FromStr for Address { impl FromStr for Address {
type Err=Error; type Err=Error;
#[allow(unknown_lints)] #[allow(unknown_lints,clippy::needless_range_loop)]
#[allow(needless_range_loop)]
fn from_str(text: &str) -> Result<Self, Self::Err> { fn from_str(text: &str) -> Result<Self, Self::Err> {
if let Ok(addr) = Ipv4Addr::from_str(text) { if let Ok(addr) = Ipv4Addr::from_str(text) {
let ip = addr.octets(); let ip = addr.octets();
@ -145,13 +144,13 @@ impl Range {
return Err(Error::Parse("Range too short")); return Err(Error::Parse("Range too short"));
} }
let prefix_len = data[read]; let prefix_len = data[read];
Ok((Range{base: address, prefix_len: prefix_len}, read + 1)) Ok((Range{base: address, prefix_len}, read + 1))
} }
#[inline] #[inline]
pub fn write_to(&self, data: &mut[u8]) -> usize { pub fn write_to(&self, data: &mut[u8]) -> usize {
let pos = self.base.write_to(data); let pos = self.base.write_to(data);
assert!(data.len() >= pos + 1); assert!(data.len() > pos);
data[pos] = self.prefix_len; data[pos] = self.prefix_len;
pos + 1 pos + 1
} }
@ -168,7 +167,7 @@ impl FromStr for Range {
let prefix_len = try!(u8::from_str(&text[pos+1..]) let prefix_len = try!(u8::from_str(&text[pos+1..])
.map_err(|_| Error::Parse("Failed to parse prefix length"))); .map_err(|_| Error::Parse("Failed to parse prefix length")));
let base = try!(Address::from_str(&text[..pos])); let base = try!(Address::from_str(&text[..pos]));
Ok(Range{base: base, prefix_len: prefix_len}) Ok(Range{base, prefix_len})
} }
} }

View File

@ -36,6 +36,7 @@ impl TopHeader {
Ok((header, TopHeader::size())) Ok((header, TopHeader::size()))
} }
#[allow(unknown_lints,clippy::trivially_copy_pass_by_ref)]
pub fn write_to(&self, data: &mut [u8]) -> usize { pub fn write_to(&self, data: &mut [u8]) -> usize {
assert!(data.len() >= 8); assert!(data.len() >= 8);
data[0..4].copy_from_slice(&self.magic); data[0..4].copy_from_slice(&self.magic);
@ -76,8 +77,7 @@ impl<'a> fmt::Debug for Message<'a> {
} }
} }
#[allow(unknown_lints)] #[allow(unknown_lints,clippy::needless_range_loop)]
#[allow(needless_range_loop)]
pub fn decode<'a>(data: &'a mut [u8], magic: HeaderMagic, crypto: &mut Crypto) -> Result<Message<'a>, Error> { pub fn decode<'a>(data: &'a mut [u8], magic: HeaderMagic, crypto: &mut Crypto) -> Result<Message<'a>, Error> {
let mut end = data.len(); let mut end = data.len();
let (header, mut pos) = try!(TopHeader::read_from(&data[..end])); let (header, mut pos) = try!(TopHeader::read_from(&data[..end]));
@ -170,8 +170,7 @@ pub fn decode<'a>(data: &'a mut [u8], magic: HeaderMagic, crypto: &mut Crypto) -
Ok(msg) Ok(msg)
} }
#[allow(unknown_lints)] #[allow(unknown_lints,clippy::needless_range_loop)]
#[allow(needless_range_loop)]
pub fn encode<'a>(msg: &'a mut Message, mut buf: &'a mut [u8], magic: HeaderMagic, crypto: &mut Crypto) -> &'a mut [u8] { pub fn encode<'a>(msg: &'a mut Message, mut buf: &'a mut [u8], magic: HeaderMagic, crypto: &mut Crypto) -> &'a mut [u8] {
let mut start = 64; let mut start = 64;
let mut end = 64; let mut end = 64;

View File

@ -30,7 +30,7 @@ pub fn now() -> Time {
time::get_time().sec time::get_time().sec
} }
const HEX_CHARS: &'static [u8] = b"0123456789abcdef"; const HEX_CHARS: &[u8] = b"0123456789abcdef";
pub fn bytes_to_hex(bytes: &[u8]) -> String { pub fn bytes_to_hex(bytes: &[u8]) -> String {
let mut v = Vec::with_capacity(bytes.len() * 2); let mut v = Vec::with_capacity(bytes.len() * 2);
@ -49,7 +49,7 @@ pub struct Encoder;
impl Encoder { impl Encoder {
#[inline] #[inline]
pub fn read_u16(data: &[u8]) -> u16 { pub fn read_u16(data: &[u8]) -> u16 {
((data[0] as u16) << 8) | data[1] as u16 (u16::from(data[0]) << 8) | u16::from(data[1])
} }
#[inline] #[inline]
@ -60,8 +60,8 @@ impl Encoder {
#[inline] #[inline]
pub fn read_u32(data: &[u8]) -> u32 { pub fn read_u32(data: &[u8]) -> u32 {
((data[0] as u32) << 24) | ((data[1] as u32) << 16) | (u32::from(data[0]) << 24) | (u32::from(data[1]) << 16) |
((data[2] as u32) << 8) | data[3] as u32 (u32::from(data[2]) << 8) | u32::from(data[3])
} }
#[inline] #[inline]
@ -74,10 +74,10 @@ impl Encoder {
#[inline] #[inline]
pub fn read_u64(data: &[u8]) -> u64 { pub fn read_u64(data: &[u8]) -> u64 {
((data[0] as u64) << 56) | ((data[1] as u64) << 48) | (u64::from(data[0]) << 56) | (u64::from(data[1]) << 48) |
((data[2] as u64) << 40) | ((data[3] as u64) << 32) | (u64::from(data[2]) << 40) | (u64::from(data[3]) << 32) |
((data[4] as u64) << 24) | ((data[5] as u64) << 16) | (u64::from(data[4]) << 24) | (u64::from(data[5]) << 16) |
((data[6] as u64) << 8) | data[7] as u64 (u64::from(data[6]) << 8) | u64::from(data[7])
} }
#[inline] #[inline]
@ -123,7 +123,7 @@ macro_rules! try_fail {
} }
#[allow(unknown_lints,needless_pass_by_value)] #[allow(unknown_lints,clippy::needless_pass_by_value)]
pub fn resolve<Addr: ToSocketAddrs+fmt::Debug>(addr: Addr) -> Result<Vec<SocketAddr>, Error> { pub fn resolve<Addr: ToSocketAddrs+fmt::Debug>(addr: Addr) -> Result<Vec<SocketAddr>, Error> {
let addrs = try!(addr.to_socket_addrs().map_err(|_| Error::Name(format!("{:?}", addr)))); let addrs = try!(addr.to_socket_addrs().map_err(|_| Error::Name(format!("{:?}", addr))));
// Remove duplicates in addrs (why are there duplicates???) // Remove duplicates in addrs (why are there duplicates???)