vpncloud/src/types.rs

318 lines
10 KiB
Rust
Raw Normal View History

// VpnCloud - Peer-to-Peer VPN
2020-05-28 07:03:48 +00:00
// Copyright (C) 2015-2020 Dennis Schwerdel
// This software is licensed under GPL-3 or newer (see LICENSE.md)
2019-12-04 08:32:35 +00:00
use std::{
fmt,
hash::{Hash, Hasher},
io::{self, Write},
net::{Ipv4Addr, Ipv6Addr, SocketAddr},
str::FromStr
};
2015-11-23 00:04:30 +00:00
use super::util::{bytes_to_hex, Encoder};
pub const NODE_ID_BYTES: usize = 16;
2015-11-23 00:04:30 +00:00
pub type HeaderMagic = [u8; 4];
pub type NodeId = [u8; NODE_ID_BYTES];
2015-11-23 00:04:30 +00:00
2016-07-06 19:29:28 +00:00
#[derive(Eq, Clone, Copy)]
2015-11-26 09:45:25 +00:00
pub struct Address {
pub data: [u8; 16],
pub len: u8
}
impl Address {
#[inline]
pub fn read_from(data: &[u8]) -> Result<(Address, usize), Error> {
2019-01-01 23:35:14 +00:00
if data.is_empty() {
2019-12-04 08:32:35 +00:00
return Err(Error::Parse("Address too short"))
2015-11-26 09:45:25 +00:00
}
let len = data[0] as usize;
2019-03-01 22:12:19 +00:00
let addr = Address::read_from_fixed(&data[1..], len)?;
2015-11-26 09:45:25 +00:00
Ok((addr, len + 1))
}
#[inline]
pub fn read_from_fixed(data: &[u8], len: usize) -> Result<Address, Error> {
if len > 16 {
2019-12-04 08:32:35 +00:00
return Err(Error::Parse("Invalid address, too long"))
2015-11-26 09:45:25 +00:00
}
if data.len() < len {
2019-12-04 08:32:35 +00:00
return Err(Error::Parse("Address too short"))
2015-11-26 09:45:25 +00:00
}
let mut bytes = [0; 16];
2016-07-06 16:48:58 +00:00
bytes[0..len].copy_from_slice(&data[0..len]);
2019-12-04 08:32:35 +00:00
Ok(Address { data: bytes, len: len as u8 })
2015-11-26 09:45:25 +00:00
}
#[inline]
2019-12-04 08:32:35 +00:00
pub fn write_to(&self, data: &mut [u8]) -> usize {
2019-01-01 23:35:14 +00:00
assert!(data.len() > self.len as usize);
2015-11-26 09:45:25 +00:00
data[0] = self.len;
let len = self.len as usize;
2019-01-01 23:35:14 +00:00
data[1..=len].copy_from_slice(&self.data[0..len]);
2015-11-26 09:45:25 +00:00
self.len as usize + 1
}
}
impl PartialEq for Address {
2015-11-26 09:45:25 +00:00
#[inline]
fn eq(&self, rhs: &Self) -> bool {
2016-07-06 19:14:09 +00:00
self.len == rhs.len && self.data[..self.len as usize] == rhs.data[..self.len as usize]
}
}
2016-06-11 14:08:57 +00:00
impl Hash for Address {
#[inline]
fn hash<H: Hasher>(&self, hasher: &mut H) {
hasher.write(&self.data[0..self.len as usize])
}
}
2015-11-26 21:16:51 +00:00
impl fmt::Display for Address {
2015-11-23 00:04:30 +00:00
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
2015-11-26 09:45:25 +00:00
let d = &self.data;
match self.len {
4 => write!(formatter, "{}.{}.{}.{}", d[0], d[1], d[2], d[3]),
2015-11-23 20:43:00 +00:00
6 => write!(formatter, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
2015-11-26 09:45:25 +00:00
d[0], d[1], d[2], d[3], d[4], d[5]),
2015-11-23 10:55:37 +00:00
8 => {
2015-11-27 14:09:59 +00:00
let vlan = Encoder::read_u16(&d[0..2]);
2015-11-23 20:43:00 +00:00
write!(formatter, "vlan{}/{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
2015-11-26 09:45:25 +00:00
vlan, d[2], d[3], d[4], d[5], d[6], d[7])
2015-11-23 10:55:37 +00:00
},
2015-11-23 20:43:00 +00:00
16 => write!(formatter, "{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}:{:02x}{:02x}",
2015-11-26 09:45:25 +00:00
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]),
2016-02-02 22:58:47 +00:00
_ => write!(formatter, "{}", bytes_to_hex(&d[0..self.len as usize]))
2015-11-23 00:04:30 +00:00
}
}
}
2015-11-26 21:16:51 +00:00
impl fmt::Debug for Address {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(formatter, "{}", self)
}
}
2015-11-23 00:04:30 +00:00
impl FromStr for Address {
2019-12-04 08:32:35 +00:00
type Err = Error;
2015-11-23 00:04:30 +00:00
2019-12-04 08:32:35 +00:00
#[allow(unknown_lints, clippy::needless_range_loop)]
2015-11-23 00:04:30 +00:00
fn from_str(text: &str) -> Result<Self, Self::Err> {
if let Ok(addr) = Ipv4Addr::from_str(text) {
let ip = addr.octets();
let mut res = [0; 16];
2016-07-06 16:48:58 +00:00
res[0..4].copy_from_slice(&ip);
2019-12-04 08:32:35 +00:00
return Ok(Address { data: res, len: 4 })
2015-11-23 00:04:30 +00:00
}
if let Ok(addr) = Ipv6Addr::from_str(text) {
2015-11-27 14:09:59 +00:00
let segments = addr.segments();
let mut res = [0; 16];
2015-11-27 14:09:59 +00:00
for i in 0..8 {
2019-12-04 08:32:35 +00:00
Encoder::write_u16(segments[i], &mut res[2 * i..]);
2015-11-23 00:04:30 +00:00
}
2019-12-04 08:32:35 +00:00
return Ok(Address { data: res, len: 16 })
2015-11-23 00:04:30 +00:00
}
2015-11-23 00:48:50 +00:00
let parts: Vec<&str> = text.split(':').collect();
if parts.len() == 6 {
let mut bytes = [0; 16];
2015-11-23 00:48:50 +00:00
for i in 0..6 {
2019-03-01 22:12:19 +00:00
bytes[i] = u8::from_str_radix(parts[i], 16).map_err(|_| Error::Parse("Failed to parse mac"))?;
2015-11-23 00:48:50 +00:00
}
2019-12-04 08:32:35 +00:00
return Ok(Address { data: bytes, len: 6 })
2015-11-23 00:48:50 +00:00
}
2016-07-06 19:14:09 +00:00
Err(Error::Parse("Failed to parse address"))
2015-11-23 00:04:30 +00:00
}
}
2016-07-06 19:29:28 +00:00
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
2015-11-23 00:04:30 +00:00
pub struct Range {
pub base: Address,
pub prefix_len: u8
}
2015-11-26 09:45:25 +00:00
impl Range {
#[inline]
pub fn read_from(data: &[u8]) -> Result<(Range, usize), Error> {
2019-03-01 22:12:19 +00:00
let (address, read) = Address::read_from(data)?;
2015-11-26 09:45:25 +00:00
if data.len() < read + 1 {
2019-12-04 08:32:35 +00:00
return Err(Error::Parse("Range too short"))
2015-11-26 09:45:25 +00:00
}
let prefix_len = data[read];
2019-12-04 08:32:35 +00:00
Ok((Range { base: address, prefix_len }, read + 1))
2015-11-26 09:45:25 +00:00
}
#[inline]
2019-12-04 08:32:35 +00:00
pub fn write_to(&self, data: &mut [u8]) -> usize {
2015-11-26 09:45:25 +00:00
let pos = self.base.write_to(data);
2019-01-01 23:35:14 +00:00
assert!(data.len() > pos);
2015-11-26 09:45:25 +00:00
data[pos] = self.prefix_len;
pos + 1
}
}
2015-11-23 00:04:30 +00:00
impl FromStr for Range {
2019-12-04 08:32:35 +00:00
type Err = Error;
2015-11-23 00:04:30 +00:00
fn from_str(text: &str) -> Result<Self, Self::Err> {
2016-06-11 14:08:57 +00:00
let pos = match text.find('/') {
2015-11-23 00:04:30 +00:00
Some(pos) => pos,
2016-07-06 19:14:09 +00:00
None => return Err(Error::Parse("Invalid range format"))
2015-11-23 00:04:30 +00:00
};
2019-12-04 08:32:35 +00:00
let prefix_len = u8::from_str(&text[pos + 1..]).map_err(|_| Error::Parse("Failed to parse prefix length"))?;
2019-03-01 22:12:19 +00:00
let base = Address::from_str(&text[..pos])?;
2019-12-04 08:32:35 +00:00
Ok(Range { base, prefix_len })
2015-11-23 00:04:30 +00:00
}
}
2015-11-26 21:16:51 +00:00
impl fmt::Display for Range {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(formatter, "{}/{}", self.base, self.prefix_len)
}
}
impl fmt::Debug for Range {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(formatter, "{}", self)
}
}
2015-11-23 00:04:30 +00:00
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
2015-11-23 10:55:37 +00:00
pub enum Mode {
#[serde(rename = "normal")]
Normal,
#[serde(rename = "hub")]
Hub,
#[serde(rename = "switch")]
Switch,
#[serde(rename = "router")]
Router
2015-11-23 00:04:30 +00:00
}
impl fmt::Display for Mode {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
2016-06-11 14:08:57 +00:00
match *self {
Mode::Normal => write!(formatter, "normal"),
Mode::Hub => write!(formatter, "hub"),
Mode::Switch => write!(formatter, "switch"),
2019-12-04 08:32:35 +00:00
Mode::Router => write!(formatter, "router")
}
}
}
2015-11-23 00:04:30 +00:00
pub trait Table {
2019-03-01 22:12:19 +00:00
fn learn(&mut self, _: Address, _: Option<u8>, _: SocketAddr);
fn lookup(&mut self, _: &Address) -> Option<SocketAddr>;
2015-11-23 00:04:30 +00:00
fn housekeep(&mut self);
2019-01-09 16:45:12 +00:00
fn write_out<W: Write>(&self, out: &mut W) -> Result<(), io::Error>;
2019-03-01 22:12:19 +00:00
fn remove(&mut self, _: &Address) -> bool;
fn remove_all(&mut self, _: &SocketAddr);
2015-11-23 00:04:30 +00:00
}
pub trait Protocol: Sized {
2019-03-01 22:12:19 +00:00
fn parse(_: &[u8]) -> Result<(Address, Address), Error>;
2015-11-23 00:04:30 +00:00
}
2016-07-06 20:35:42 +00:00
#[derive(Debug)]
2015-11-23 00:04:30 +00:00
pub enum Error {
2016-07-06 19:14:09 +00:00
Parse(&'static str),
WrongHeaderMagic(HeaderMagic),
2016-07-06 20:35:42 +00:00
Socket(&'static str, io::Error),
2016-07-06 19:14:09 +00:00
Name(String),
2016-07-06 20:35:42 +00:00
TunTapDev(&'static str, io::Error),
2019-01-09 16:45:12 +00:00
Crypto(&'static str),
2019-02-19 21:04:21 +00:00
File(&'static str, io::Error),
Beacon(&'static str, io::Error)
2015-11-23 00:04:30 +00:00
}
impl fmt::Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
2016-06-11 14:08:57 +00:00
match *self {
2016-08-29 11:12:50 +00:00
Error::Parse(msg) => write!(formatter, "{}", msg),
Error::Socket(msg, ref err) => write!(formatter, "{}: {:?}", msg, err),
Error::TunTapDev(msg, ref err) => write!(formatter, "{}: {:?}", msg, err),
Error::Crypto(msg) => write!(formatter, "{}", msg),
2016-07-06 19:14:09 +00:00
Error::Name(ref name) => write!(formatter, "failed to resolve name '{}'", name),
Error::WrongHeaderMagic(net) => write!(formatter, "wrong header magic: {}", bytes_to_hex(&net)),
2019-02-19 21:04:21 +00:00
Error::File(msg, ref err) => write!(formatter, "{}: {:?}", msg, err),
Error::Beacon(msg, ref err) => write!(formatter, "{}: {:?}", msg, err)
}
}
2019-02-19 17:42:50 +00:00
}
#[test]
fn address_parse_fmt() {
assert_eq!(format!("{}", Address::from_str("120.45.22.5").unwrap()), "120.45.22.5");
assert_eq!(format!("{}", Address::from_str("78:2d:16:05:01:02").unwrap()), "78:2d:16:05:01:02");
2019-12-04 08:32:35 +00:00
assert_eq!(
format!("{}", Address { data: [3, 56, 120, 45, 22, 5, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0], len: 8 }),
"vlan824/78:2d:16:05:01:02"
);
assert_eq!(
format!("{}", Address::from_str("0001:0203:0405:0607:0809:0a0b:0c0d:0e0f").unwrap()),
"0001:0203:0405:0607:0809:0a0b:0c0d:0e0f"
);
assert_eq!(format!("{:?}", Address { data: [1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 2 }), "0102");
2019-02-19 17:42:50 +00:00
assert!(Address::from_str("").is_err()); // Failed to parse address
}
#[test]
fn address_decode_encode() {
let mut buf = [0; 32];
let addr = Address::from_str("120.45.22.5").unwrap();
assert_eq!(addr.write_to(&mut buf), 5);
assert_eq!(&buf[0..5], &[4, 120, 45, 22, 5]);
assert_eq!((addr, 5), Address::read_from(&buf).unwrap());
assert_eq!(addr, Address::read_from_fixed(&buf[1..], 4).unwrap());
let addr = Address::from_str("78:2d:16:05:01:02").unwrap();
assert_eq!(addr.write_to(&mut buf), 7);
assert_eq!(&buf[0..7], &[6, 0x78, 0x2d, 0x16, 0x05, 0x01, 0x02]);
assert_eq!((addr, 7), Address::read_from(&buf).unwrap());
assert_eq!(addr, Address::read_from_fixed(&buf[1..], 6).unwrap());
assert!(Address::read_from(&buf[0..0]).is_err()); // Address too short
buf[0] = 100;
assert!(Address::read_from(&buf).is_err()); // Invalid address, too long
buf[0] = 5;
assert!(Address::read_from(&buf[0..4]).is_err()); // Address too short
}
#[test]
fn address_eq() {
2019-12-04 08:32:35 +00:00
assert_eq!(
Address::read_from_fixed(&[1, 2, 3, 4], 4).unwrap(),
Address::read_from_fixed(&[1, 2, 3, 4], 4).unwrap()
);
assert_ne!(
Address::read_from_fixed(&[1, 2, 3, 4], 4).unwrap(),
Address::read_from_fixed(&[1, 2, 3, 5], 4).unwrap()
);
assert_eq!(
Address::read_from_fixed(&[1, 2, 3, 4], 3).unwrap(),
Address::read_from_fixed(&[1, 2, 3, 5], 3).unwrap()
);
assert_ne!(
Address::read_from_fixed(&[1, 2, 3, 4], 3).unwrap(),
Address::read_from_fixed(&[1, 2, 3, 4], 4).unwrap()
);
2019-02-19 17:42:50 +00:00
}
#[test]
fn address_range_decode_encode() {
let mut buf = [0; 32];
2019-12-04 08:32:35 +00:00
let range =
Range { base: Address { data: [0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 4 }, prefix_len: 24 };
2019-02-19 17:42:50 +00:00
assert_eq!(range.write_to(&mut buf), 6);
assert_eq!(&buf[0..6], &[4, 0, 1, 2, 3, 24]);
assert_eq!((range, 6), Range::read_from(&buf).unwrap());
assert!(Range::read_from(&buf[..5]).is_err()); // Missing prefix length
buf[0] = 17;
assert!(Range::read_from(&buf).is_err());
}