Compare commits

..

No commits in common. "1f32f0a6a704cf59997de5e9e5402e7bf869e8fb" and "5718c6391fb9c79cbe2a34fd709a424104afe8f6" have entirely different histories.

19 changed files with 406 additions and 1004 deletions

View File

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

1182
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

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

View File

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

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

View File

@ -17,7 +17,7 @@ use super::ethernet::{Frame, SwitchTable};
use super::types::{Address, Table, Protocol};
use super::ip::Packet;
use super::util::now as util_now;
use super::poll::{Poll, Flags};
use super::poll::{self, Poll};
#[bench]
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 mut poll_handle = Poll::new(1).unwrap();
let fd = socket.as_raw_fd();
poll_handle.register(fd, Flags::WRITE).unwrap();
poll_handle.register(fd, poll::WRITE).unwrap();
b.iter(|| {
assert_eq!(poll_handle.wait(1000).unwrap().len(), 1)
});

View File

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

View File

@ -172,7 +172,7 @@ impl Config {
let mut s = SipHasher24::new();
name[6..].hash(&mut s);
let mut data = [0; 4];
Encoder::write_u32((s.finish() & 0xffff_ffff) as u32, &mut data);
Encoder::write_u32((s.finish() & 0xffffffff) as u32, &mut data);
data
} else {
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)]
const crypto_pwhash_scryptsalsa208sha256_STRBYTES: usize = 102;
#[allow(non_upper_case_globals)]
const crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE: usize = 524_288;
const crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE: usize = 524288;
#[allow(non_upper_case_globals)]
const crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE: usize = 16_777_216;
const crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE: usize = 16777216;
pub struct Aes256State(*mut [u8; crypto_aead_aes256gcm_STATEBYTES]);
@ -193,7 +193,8 @@ impl Crypto {
}
#[inline]
#[allow(unknown_lints,clippy::match_same_arms)]
#[allow(unknown_lints)]
#[allow(match_same_arms)]
pub fn additional_bytes(&self) -> usize {
match *self {
Crypto::None => 0,
@ -224,7 +225,7 @@ impl Crypto {
crypto_key.clone_from_slice(&key[..crypto_aead_chacha20poly1305_ietf_KEYBYTES]);
let mut nonce = [0u8; crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
unsafe { randombytes_buf(nonce.as_mut_ptr(), nonce.len()) };
Crypto::ChaCha20Poly1305{key: crypto_key, nonce}
Crypto::ChaCha20Poly1305{key: crypto_key, nonce: nonce}
},
CryptoMethod::AES256 => {
if ! Crypto::aes256_available() {
@ -238,12 +239,12 @@ impl Crypto {
key[..crypto_aead_aes256gcm_KEYBYTES].as_ptr() as *const [u8; crypto_aead_aes256gcm_KEYBYTES]
) };
assert_eq!(res, 0);
Crypto::AES256GCM{state, nonce}
Crypto::AES256GCM{state: state, nonce: nonce}
}
}
}
pub fn decrypt(&self, buf: &mut [u8], nonce: &[u8], header: &[u8]) -> Result<usize, Error> {
pub fn decrypt(&self, mut buf: &mut [u8], nonce: &[u8], header: &[u8]) -> Result<usize, Error> {
match *self {
Crypto::None => Ok(buf.len()),
Crypto::ChaCha20Poly1305{ref key, ..} => {
@ -285,7 +286,7 @@ impl Crypto {
}
}
pub fn encrypt(&mut self, buf: &mut [u8], mlen: usize, nonce_bytes: &mut [u8], header: &[u8]) -> usize {
pub fn encrypt(&mut self, mut buf: &mut [u8], mlen: usize, nonce_bytes: &mut [u8], header: &[u8]) -> usize {
match *self {
Crypto::None => mlen,
Crypto::ChaCha20Poly1305{ref key, ref mut nonce} => {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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