vpncloud/src/udpmessage.rs

297 lines
10 KiB
Rust
Raw Normal View History

// VpnCloud - Peer-to-Peer VPN
// Copyright (C) 2015-2016 Dennis Schwerdel
// This software is licensed under GPL-3 or newer (see LICENSE.md)
2015-11-27 14:09:59 +00:00
use std::fmt;
2015-11-25 12:51:57 +00:00
use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr, SocketAddrV6, Ipv6Addr};
2015-11-19 15:34:20 +00:00
use super::types::{NodeId, Error, NetworkId, Range, NODE_ID_BYTES};
2015-12-13 21:03:06 +00:00
use super::util::{bytes_to_hex, Encoder};
2015-11-24 19:55:14 +00:00
use super::crypto::Crypto;
2015-11-20 17:09:51 +00:00
2016-07-06 16:48:58 +00:00
const MAGIC: [u8; 3] = *b"vpn";
2015-11-24 10:19:27 +00:00
pub const VERSION: u8 = 1;
2015-11-20 17:09:51 +00:00
2015-11-24 20:15:00 +00:00
const NETWORK_ID_BYTES: usize = 8;
2016-01-19 20:52:44 +00:00
#[derive(Clone, Copy)]
2015-11-20 17:09:51 +00:00
#[repr(packed)]
struct TopHeader {
magic: [u8; 3],
version: u8,
2015-11-24 19:55:14 +00:00
crypto_method : u8,
_reserved: u8,
2015-11-20 17:30:50 +00:00
flags: u8,
2015-11-20 17:09:51 +00:00
msgtype: u8
}
2015-11-26 09:45:25 +00:00
impl TopHeader {
2016-06-11 14:08:57 +00:00
#[inline]
2015-11-27 14:09:59 +00:00
pub fn size() -> usize {
8
}
2015-11-26 09:45:25 +00:00
pub fn read_from(data: &[u8]) -> Result<(TopHeader, usize), Error> {
2015-11-27 14:09:59 +00:00
if data.len() < TopHeader::size() {
2016-07-06 19:14:09 +00:00
return Err(Error::Parse("Empty message"));
2015-11-26 09:45:25 +00:00
}
let mut header = TopHeader::default();
2016-07-06 16:48:58 +00:00
header.magic.copy_from_slice(&data[0..3]);
2015-11-26 09:45:25 +00:00
header.version = data[3];
header.crypto_method = data[4];
header.flags = data[6];
header.msgtype = data[7];
2015-11-27 14:09:59 +00:00
Ok((header, TopHeader::size()))
2015-11-26 09:45:25 +00:00
}
pub fn write_to(&self, data: &mut [u8]) -> usize {
2016-07-06 16:48:58 +00:00
data[0..3].copy_from_slice(&self.magic);
2015-11-26 09:45:25 +00:00
data[3] = self.version;
data[4] = self.crypto_method;
data[6] = self.flags;
data[7] = self.msgtype;
2015-11-27 14:09:59 +00:00
TopHeader::size()
2015-11-26 09:45:25 +00:00
}
}
2015-11-20 17:09:51 +00:00
impl Default for TopHeader {
fn default() -> Self {
2015-11-24 19:55:14 +00:00
TopHeader{magic: MAGIC, version: VERSION, crypto_method: 0, _reserved: 0, flags: 0, msgtype: 0}
2015-11-20 17:09:51 +00:00
}
}
#[derive(Default, Debug, PartialEq, Eq)]
pub struct Options {
2015-11-23 14:40:04 +00:00
pub network_id: Option<NetworkId>,
2015-11-20 17:09:51 +00:00
}
2015-11-19 15:34:20 +00:00
2015-11-22 23:49:58 +00:00
pub enum Message<'a> {
2015-12-13 21:03:06 +00:00
Data(&'a mut[u8], usize, usize), // data, start, end
Peers(Vec<SocketAddr>), // peers
Init(u8, NodeId, Vec<Range>), // step, node_id, ranges
2015-11-19 15:34:20 +00:00
Close,
}
2015-11-22 23:49:58 +00:00
impl<'a> fmt::Debug for Message<'a> {
2015-11-19 15:34:20 +00:00
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
2016-06-11 14:08:57 +00:00
match *self {
Message::Data(_, start, end) => write!(formatter, "Data({} bytes)", end-start),
Message::Peers(ref peers) => {
2015-11-19 15:34:20 +00:00
try!(write!(formatter, "Peers ["));
let mut first = true;
for p in peers {
if !first {
try!(write!(formatter, ", "));
}
first = false;
2015-11-26 23:40:11 +00:00
try!(write!(formatter, "{}", p));
2015-11-19 15:34:20 +00:00
}
write!(formatter, "]")
},
2016-06-11 14:08:57 +00:00
Message::Init(stage, ref node_id, ref peers) => write!(formatter, "Init(stage={}, node_id={}, {:?})", stage, bytes_to_hex(node_id), peers),
Message::Close => write!(formatter, "Close"),
2015-11-19 15:34:20 +00:00
}
}
}
#[allow(unknown_lints)]
#[allow(needless_range_loop)]
2015-11-23 14:40:04 +00:00
pub fn decode<'a>(data: &'a mut [u8], crypto: &mut Crypto) -> Result<(Options, Message<'a>), Error> {
2015-11-24 22:47:38 +00:00
let mut end = data.len();
2015-11-26 09:45:25 +00:00
let (header, mut pos) = try!(TopHeader::read_from(&data[..end]));
2015-11-20 17:09:51 +00:00
if header.magic != MAGIC {
2016-07-06 19:14:09 +00:00
return Err(Error::Parse("Wrong protocol"));
2015-11-20 17:09:51 +00:00
}
if header.version != VERSION {
2016-07-06 19:14:09 +00:00
return Err(Error::Parse("Wrong version"));
2015-11-20 17:09:51 +00:00
}
2015-11-24 19:55:14 +00:00
if header.crypto_method != crypto.method() {
2016-07-06 19:14:09 +00:00
return Err(Error::Crypto("Wrong crypto method"));
2015-11-24 19:55:14 +00:00
}
if crypto.method() > 0 {
2015-11-24 22:47:38 +00:00
let len = crypto.nonce_bytes();
if end < pos + len {
2016-07-06 19:14:09 +00:00
return Err(Error::Parse("Truncated crypto header"));
2015-11-24 19:55:14 +00:00
}
2015-11-24 22:47:38 +00:00
{
let (before, after) = data.split_at_mut(pos);
let (nonce, crypto_data) = after.split_at_mut(len);
pos += len;
2015-11-27 14:09:59 +00:00
end = try!(crypto.decrypt(crypto_data, nonce, &before[..TopHeader::size()])) + pos;
2015-11-24 22:47:38 +00:00
}
assert_eq!(end, data.len()-crypto.additional_bytes());
2015-11-24 19:55:14 +00:00
}
2015-11-20 17:09:51 +00:00
let mut options = Options::default();
2015-11-20 17:30:50 +00:00
if header.flags & 0x01 > 0 {
2015-11-24 22:47:38 +00:00
if end < pos + NETWORK_ID_BYTES {
2016-07-06 19:14:09 +00:00
return Err(Error::Parse("Truncated options"));
2015-11-20 17:09:51 +00:00
}
2015-11-26 09:45:25 +00:00
options.network_id = Some(Encoder::read_u64(&data[pos..pos+NETWORK_ID_BYTES]));
2015-11-24 20:15:00 +00:00
pos += NETWORK_ID_BYTES;
2015-11-20 17:09:51 +00:00
}
let msg = match header.msgtype {
2015-12-13 21:03:06 +00:00
0 => Message::Data(data, pos, end),
2015-11-19 15:34:20 +00:00
1 => {
2015-11-24 22:47:38 +00:00
if end < pos + 1 {
2016-07-06 19:14:09 +00:00
return Err(Error::Parse("Missing IPv4 count"));
2015-11-19 15:34:20 +00:00
}
2015-11-25 12:51:57 +00:00
let mut peers = Vec::new();
2015-11-19 15:34:20 +00:00
let count = data[pos];
pos += 1;
let len = count as usize * 6;
2015-11-24 22:47:38 +00:00
if end < pos + len {
2016-07-06 19:14:09 +00:00
return Err(Error::Parse("IPv4 peer data too short"));
2015-11-19 15:34:20 +00:00
}
for _ in 0..count {
2015-11-26 09:45:25 +00:00
let ip = &data[pos..];
pos += 4;
let port = Encoder::read_u16(&data[pos..]);
pos += 2;
2015-11-19 15:34:20 +00:00
let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(ip[0], ip[1], ip[2], ip[3]), port));
peers.push(addr);
}
2016-07-06 19:14:09 +00:00
if end < pos + 1 {
return Err(Error::Parse("Missing IPv6 count"));
}
2015-11-25 12:51:57 +00:00
let count = data[pos];
pos += 1;
let len = count as usize * 18;
if end < pos + len {
2016-07-06 19:14:09 +00:00
return Err(Error::Parse("IPv6 peer data too short"));
2015-11-25 12:51:57 +00:00
}
for _ in 0..count {
2015-11-26 09:45:25 +00:00
let mut ip = [0u16; 8];
for i in 0..8 {
ip[i] = Encoder::read_u16(&data[pos..]);
2015-11-25 12:51:57 +00:00
pos += 2;
2015-11-26 09:45:25 +00:00
}
let port = Encoder::read_u16(&data[pos..]);
pos += 2;
let addr = SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::new(ip[0], ip[1], ip[2],
ip[3], ip[4], ip[5], ip[6], ip[7]), port, 0, 0));
2015-11-25 12:51:57 +00:00
peers.push(addr);
}
2015-11-20 17:09:51 +00:00
Message::Peers(peers)
2015-11-19 15:34:20 +00:00
},
2015-11-22 21:00:34 +00:00
2 => {
if end < pos + 2 + NODE_ID_BYTES {
2016-07-06 19:14:09 +00:00
return Err(Error::Parse("Init data too short"));
2015-11-22 21:00:34 +00:00
}
2015-11-26 09:52:58 +00:00
let stage = data[pos];
pos += 1;
let mut node_id = [0; NODE_ID_BYTES];
2016-07-06 16:48:58 +00:00
node_id.copy_from_slice(&data[pos..pos+NODE_ID_BYTES]);
pos += NODE_ID_BYTES;
2015-11-22 21:00:34 +00:00
let count = data[pos] as usize;
pos += 1;
let mut addrs = Vec::with_capacity(count);
for _ in 0..count {
2015-11-26 09:45:25 +00:00
let (range, read) = try!(Range::read_from(&data[pos..end]));
pos += read;
addrs.push(range);
2015-11-22 21:00:34 +00:00
}
Message::Init(stage, node_id, addrs)
2015-11-22 21:00:34 +00:00
},
2015-11-20 17:09:51 +00:00
3 => Message::Close,
2016-07-06 19:14:09 +00:00
_ => return Err(Error::Parse("Unknown message type"))
2015-11-20 17:09:51 +00:00
};
Ok((options, msg))
2015-11-19 15:34:20 +00:00
}
#[allow(unknown_lints)]
#[allow(needless_range_loop)]
2015-12-13 21:03:06 +00:00
pub fn encode<'a>(options: &Options, msg: &'a mut Message, mut buf: &'a mut [u8], crypto: &mut Crypto) -> &'a mut [u8] {
let mut start = 64;
let mut end = 64;
2016-06-11 14:08:57 +00:00
match *msg {
Message::Data(ref mut data, data_start, data_end) => {
2015-12-13 21:03:06 +00:00
buf = data;
start = data_start;
end = data_end;
2015-11-19 15:34:20 +00:00
},
2016-06-11 14:08:57 +00:00
Message::Peers(ref peers) => {
2015-11-25 12:51:57 +00:00
let mut v4addrs = Vec::new();
let mut v6addrs = Vec::new();
2015-11-19 15:34:20 +00:00
for p in peers {
2016-06-11 14:08:57 +00:00
match *p {
SocketAddr::V4(addr) => v4addrs.push(addr),
SocketAddr::V6(addr) => v6addrs.push(addr)
2015-11-25 12:51:57 +00:00
}
};
assert!(v4addrs.len() <= 255);
assert!(v6addrs.len() <= 255);
2015-12-13 21:03:06 +00:00
let mut pos = start;
2015-11-25 12:51:57 +00:00
assert!(buf.len() >= pos + 2 + v4addrs.len() * 6 + v6addrs.len() * 18);
buf[pos] = v4addrs.len() as u8;
pos += 1;
for addr in v4addrs {
let ip = addr.ip().octets();
2016-07-06 16:48:58 +00:00
buf[pos..pos+4].copy_from_slice(&ip);
2015-11-26 09:45:25 +00:00
pos += 4;
Encoder::write_u16(addr.port(), &mut buf[pos..]);
pos += 2;
2015-11-19 15:34:20 +00:00
};
2015-11-25 12:51:57 +00:00
buf[pos] = v6addrs.len() as u8;
2015-11-19 21:45:20 +00:00
pos += 1;
2015-11-25 12:51:57 +00:00
for addr in v6addrs {
2015-11-26 09:45:25 +00:00
let ip = addr.ip().segments();
for i in 0..8 {
Encoder::write_u16(ip[i], &mut buf[pos..]);
pos += 2;
2015-11-25 12:51:57 +00:00
}
2015-11-26 09:45:25 +00:00
Encoder::write_u16(addr.port(), &mut buf[pos..]);
pos += 2;
2015-11-25 12:51:57 +00:00
};
2015-12-13 21:03:06 +00:00
end = pos;
2015-11-19 15:34:20 +00:00
},
2016-06-11 14:08:57 +00:00
Message::Init(stage, ref node_id, ref ranges) => {
2015-12-13 21:03:06 +00:00
let mut pos = start;
assert!(buf.len() >= pos + 2 + NODE_ID_BYTES);
2015-11-26 09:52:58 +00:00
buf[pos] = stage;
pos += 1;
2016-07-06 16:48:58 +00:00
buf[pos..pos+NODE_ID_BYTES].copy_from_slice(node_id);
pos += NODE_ID_BYTES;
2015-11-22 23:49:58 +00:00
assert!(ranges.len() <= 255);
buf[pos] = ranges.len() as u8;
2015-11-22 21:00:34 +00:00
pos += 1;
2015-11-22 23:49:58 +00:00
for range in ranges {
2015-11-26 09:45:25 +00:00
pos += range.write_to(&mut buf[pos..]);
2015-11-22 21:00:34 +00:00
}
2015-12-13 21:03:06 +00:00
end = pos;
2015-11-19 15:34:20 +00:00
},
2016-06-11 14:08:57 +00:00
Message::Close => {
2015-11-19 15:34:20 +00:00
}
}
2015-12-13 21:03:06 +00:00
assert!(start >= 64);
assert!(buf.len() >= end + 64);
if let Some(id) = options.network_id {
assert!(start >= NETWORK_ID_BYTES);
Encoder::write_u64(id, &mut buf[start-NETWORK_ID_BYTES..]);
start -= NETWORK_ID_BYTES;
}
let crypto_start = start;
start -= crypto.nonce_bytes();
let mut header = TopHeader::default();
2016-06-11 14:08:57 +00:00
header.msgtype = match *msg {
Message::Data(_, _, _) => 0,
Message::Peers(_) => 1,
Message::Init(_, _, _) => 2,
Message::Close => 3
2015-12-13 21:03:06 +00:00
};
header.crypto_method = crypto.method();
if options.network_id.is_some() {
header.flags |= 0x01;
}
start -= TopHeader::size();
header.write_to(&mut buf[start..]);
2015-11-24 19:55:14 +00:00
if crypto.method() > 0 {
2015-12-13 21:03:06 +00:00
let (junk_before, rest) = buf.split_at_mut(start);
let (header, rest) = rest.split_at_mut(TopHeader::size());
2015-11-24 22:47:38 +00:00
let (nonce, rest) = rest.split_at_mut(crypto.nonce_bytes());
2015-12-13 21:03:06 +00:00
debug_assert_eq!(junk_before.len() + header.len() + crypto.nonce_bytes(), crypto_start);
assert!(rest.len() >= end - crypto_start + crypto.additional_bytes());
end = crypto.encrypt(rest, end-crypto_start, nonce, header) + crypto_start;
2015-11-23 14:40:04 +00:00
}
2015-12-13 21:03:06 +00:00
&mut buf[start..end]
2015-11-19 15:34:20 +00:00
}