vpncloud/src/udpmessage.rs

517 lines
18 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,
net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}
};
2015-11-19 15:34:20 +00:00
2019-12-04 08:32:35 +00:00
use super::{
config::DEFAULT_PEER_TIMEOUT,
2019-12-04 08:32:35 +00:00
crypto::Crypto,
types::{Error, HeaderMagic, NodeId, Range, NODE_ID_BYTES},
util::{bytes_to_hex, Encoder}
};
2015-11-20 17:09:51 +00:00
#[derive(Clone, Copy, Default)]
2015-11-20 17:09:51 +00:00
#[repr(packed)]
struct TopHeader {
magic: HeaderMagic,
2019-12-04 08:32:35 +00:00
crypto_method: u8,
_reserved1: u8,
_reserved2: 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() {
2019-12-04 08:32:35 +00:00
return Err(Error::Parse("Empty message"))
2015-11-26 09:45:25 +00:00
}
let mut header = TopHeader::default();
header.magic.copy_from_slice(&data[0..4]);
2015-11-26 09:45:25 +00:00
header.crypto_method = data[4];
header.msgtype = data[7];
2015-11-27 14:09:59 +00:00
Ok((header, TopHeader::size()))
2015-11-26 09:45:25 +00:00
}
2019-12-04 08:32:35 +00:00
#[allow(unknown_lints, clippy::trivially_copy_pass_by_ref)]
2015-11-26 09:45:25 +00:00
pub fn write_to(&self, data: &mut [u8]) -> usize {
assert!(data.len() >= 8);
data[0..4].copy_from_slice(&self.magic);
2015-11-26 09:45:25 +00:00
data[4] = self.crypto_method;
2016-11-23 10:27:58 +00:00
data[5] = 0;
data[6] = 0;
2015-11-26 09:45:25 +00:00
data[7] = self.msgtype;
2015-11-27 14:09:59 +00:00
TopHeader::size()
2015-11-26 09:45:25 +00:00
}
}
2015-11-22 23:49:58 +00:00
pub enum Message<'a> {
Data(&'a mut [u8], usize, usize), // data, start, end
Peers(Vec<SocketAddr>), // peers
Init(u8, NodeId, Vec<Range>, u16), // step, node_id, ranges
2019-12-04 08:32:35 +00:00
Close
2015-11-19 15:34:20 +00:00
}
2019-02-26 17:36:54 +00:00
impl<'a> Message<'a> {
pub fn without_data(self) -> Message<'static> {
match self {
Message::Data(_, start, end) => Message::Data(&mut [], start, end),
Message::Peers(peers) => Message::Peers(peers),
Message::Init(step, node_id, ranges, timeout) => Message::Init(step, node_id, ranges, timeout),
2019-02-26 17:36:54 +00:00
Message::Close => Message::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 {
2019-12-04 08:32:35 +00:00
Message::Data(_, start, end) => write!(formatter, "Data({} bytes)", end - start),
2016-06-11 14:08:57 +00:00
Message::Peers(ref peers) => {
2019-03-01 22:12:19 +00:00
write!(formatter, "Peers [")?;
2015-11-19 15:34:20 +00:00
let mut first = true;
for p in peers {
if !first {
2019-03-01 22:12:19 +00:00
write!(formatter, ", ")?;
2015-11-19 15:34:20 +00:00
}
first = false;
2019-03-01 22:12:19 +00:00
write!(formatter, "{}", p)?;
2015-11-19 15:34:20 +00:00
}
write!(formatter, "]")
2019-12-04 08:32:35 +00:00
}
Message::Init(stage, ref node_id, ref peers, ref peer_timeout) => {
write!(
formatter,
"Init(stage={}, node_id={}, peer_timeout={}, {:?})",
stage,
bytes_to_hex(node_id),
peer_timeout,
peers
)
2019-12-04 08:32:35 +00:00
}
Message::Close => write!(formatter, "Close")
2015-11-19 15:34:20 +00:00
}
}
}
2019-12-04 08:32:35 +00:00
#[allow(unknown_lints, clippy::needless_range_loop)]
2019-02-26 00:21:15 +00:00
pub fn decode<'a>(data: &'a mut [u8], magic: HeaderMagic, crypto: &Crypto) -> Result<Message<'a>, Error> {
2015-11-24 22:47:38 +00:00
let mut end = data.len();
2019-03-01 22:12:19 +00:00
let (header, mut pos) = TopHeader::read_from(&data[..end])?;
if header.magic != magic {
2019-12-04 08:32:35 +00:00
return Err(Error::WrongHeaderMagic(header.magic))
2015-11-20 17:09:51 +00:00
}
2015-11-24 19:55:14 +00:00
if header.crypto_method != crypto.method() {
2019-12-04 08:32:35 +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 {
2019-12-04 08:32:35 +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;
2019-03-01 22:12:19 +00:00
end = crypto.decrypt(crypto_data, nonce, &before[..TopHeader::size()])? + pos;
2015-11-24 22:47:38 +00:00
}
2019-12-04 08:32:35 +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 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 {
2019-12-04 08:32:35 +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 {
2019-12-04 08:32:35 +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..];
assert!(ip.len() >= 4);
2015-11-26 09:45:25 +00:00
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 {
2019-12-04 08:32:35 +00:00
return Err(Error::Parse("Missing IPv6 count"))
2016-07-06 19:14:09 +00:00
}
2015-11-25 12:51:57 +00:00
let count = data[pos];
pos += 1;
let len = count as usize * 18;
if end < pos + len {
2019-12-04 08:32:35 +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;
2019-12-04 08:32:35 +00:00
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)
2019-12-04 08:32:35 +00:00
}
2015-11-22 21:00:34 +00:00
2 => {
if end < pos + 2 + NODE_ID_BYTES {
2019-12-04 08:32:35 +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];
2019-12-04 08:32:35 +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 {
2019-03-01 22:12:19 +00:00
let (range, read) = Range::read_from(&data[pos..end])?;
2015-11-26 09:45:25 +00:00
pos += read;
addrs.push(range);
2015-11-22 21:00:34 +00:00
}
let peer_timeout =
if data.len() >= pos + 2 { Encoder::read_u16(&data[pos..]) } else { DEFAULT_PEER_TIMEOUT };
Message::Init(stage, node_id, addrs, peer_timeout)
2019-12-04 08:32:35 +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(msg)
2015-11-19 15:34:20 +00:00
}
2019-12-04 08:32:35 +00:00
#[allow(unknown_lints, clippy::needless_range_loop)]
pub fn encode<'a>(
msg: &'a mut Message, mut buf: &'a mut [u8], magic: HeaderMagic, crypto: &mut Crypto
) -> &'a mut [u8] {
2019-03-01 23:50:55 +00:00
let header_type = match msg {
Message::Data(_, _, _) => 0,
Message::Peers(_) => 1,
Message::Init(_, _, _, _) => 2,
2019-03-01 23:50:55 +00:00
Message::Close => 3
};
2015-12-13 21:03:06 +00:00
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;
2019-12-04 08:32:35 +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
}
2019-02-18 08:40:54 +00:00
}
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();
2019-12-04 08:32:35 +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;
2019-12-04 08:32:35 +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;
2019-12-04 08:32:35 +00:00
}
2015-12-13 21:03:06 +00:00
end = pos;
2019-12-04 08:32:35 +00:00
}
Message::Init(stage, ref node_id, ref ranges, peer_timeout) => {
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;
2019-12-04 08:32:35 +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
}
Encoder::write_u16(peer_timeout, &mut buf[pos..]);
pos += 2;
2015-12-13 21:03:06 +00:00
end = pos;
2015-11-19 15:34:20 +00:00
}
2019-12-04 08:32:35 +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);
let crypto_start = start;
start -= crypto.nonce_bytes();
let mut header = TopHeader::default();
header.magic = magic;
2019-03-01 23:50:55 +00:00
header.msgtype = header_type;
2015-12-13 21:03:06 +00:00
header.crypto_method = crypto.method();
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());
2019-12-04 08:32:35 +00:00
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
}
2019-02-19 17:42:50 +00:00
impl<'a> PartialEq for Message<'a> {
fn eq(&self, other: &Message) -> bool {
2019-03-01 22:25:42 +00:00
match *self {
2019-12-04 08:32:35 +00:00
Message::Data(ref data1, start1, end1) => {
if let Message::Data(ref data2, start2, end2) = *other {
data1[start1..end1] == data2[start2..end2]
} else {
false
}
}
Message::Peers(ref peers1) => {
if let Message::Peers(ref peers2) = *other {
peers1 == peers2
} else {
false
}
}
Message::Init(step1, node_id1, ref ranges1, peer_timeout1) => {
if let Message::Init(step2, node_id2, ref ranges2, peer_timeout2) = *other {
step1 == step2 && node_id1 == node_id2 && ranges1 == ranges2 && peer_timeout1 == peer_timeout2
2019-12-04 08:32:35 +00:00
} else {
false
}
}
Message::Close => {
if let Message::Close = *other {
true
} else {
false
}
}
2019-02-19 17:42:50 +00:00
}
}
}
#[cfg(test)] use super::crypto::CryptoMethod;
2019-12-04 08:32:35 +00:00
#[cfg(test)] use super::types::Address;
#[cfg(test)] use super::MAGIC;
#[cfg(test)] use std::str::FromStr;
2019-02-19 17:42:50 +00:00
#[test]
#[allow(unused_assignments)]
fn udpmessage_packet() {
let mut crypto = Crypto::None;
2019-12-04 08:32:35 +00:00
let mut payload = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
];
2019-02-19 17:42:50 +00:00
let mut msg = Message::Data(&mut payload, 64, 69);
let mut buf = [0; 1024];
let mut len = 0;
{
let res = encode(&mut msg, &mut [], MAGIC, &mut crypto);
assert_eq!(res.len(), 13);
2019-12-04 08:32:35 +00:00
assert_eq!(&res[..8], &[118, 112, 110, 1, 0, 0, 0, 0]);
2019-12-20 12:54:58 +00:00
buf[..res.len()].clone_from_slice(&res);
2019-02-19 17:42:50 +00:00
len = res.len();
}
2019-12-20 12:54:58 +00:00
let msg2 = decode(&mut buf[..len], MAGIC, &crypto).unwrap();
2019-02-19 17:42:50 +00:00
assert_eq!(msg, msg2);
}
#[test]
#[allow(unused_assignments)]
fn udpmessage_encrypted() {
let mut crypto = Crypto::from_shared_key(CryptoMethod::ChaCha20, "test");
2019-12-04 08:32:35 +00:00
let mut payload = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
];
2019-02-19 17:42:50 +00:00
let mut orig_payload = [0; 133];
2019-12-20 12:54:58 +00:00
orig_payload[..payload.len()].clone_from_slice(&payload);
2019-02-19 17:42:50 +00:00
let orig_msg = Message::Data(&mut orig_payload, 64, 69);
let mut msg = Message::Data(&mut payload, 64, 69);
let mut buf = [0; 1024];
let mut len = 0;
{
let res = encode(&mut msg, &mut [], MAGIC, &mut crypto);
assert_eq!(res.len(), 41);
2019-12-04 08:32:35 +00:00
assert_eq!(&res[..8], &[118, 112, 110, 1, 1, 0, 0, 0]);
2019-12-20 12:54:58 +00:00
buf[..res.len()].clone_from_slice(&res);
2019-02-19 17:42:50 +00:00
len = res.len();
}
2019-12-20 12:54:58 +00:00
let msg2 = decode(&mut buf[..len], MAGIC, &crypto).unwrap();
2019-02-19 17:42:50 +00:00
assert_eq!(orig_msg, msg2);
}
#[test]
fn udpmessage_peers() {
use std::str::FromStr;
let mut crypto = Crypto::None;
2019-12-04 08:32:35 +00:00
let mut msg = Message::Peers(vec![
SocketAddr::from_str("1.2.3.4:123").unwrap(),
SocketAddr::from_str("5.6.7.8:12345").unwrap(),
SocketAddr::from_str("[0001:0203:0405:0607:0809:0a0b:0c0d:0e0f]:6789").unwrap(),
]);
let mut should = [
118, 112, 110, 1, 0, 0, 0, 1, 2, 1, 2, 3, 4, 0, 123, 5, 6, 7, 8, 48, 57, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 26, 133
];
2019-02-19 17:42:50 +00:00
{
let mut buf = [0; 1024];
let res = encode(&mut msg, &mut buf[..], MAGIC, &mut crypto);
assert_eq!(res.len(), 40);
for i in 0..res.len() {
assert_eq!(res[i], should[i]);
}
}
2019-12-20 12:54:58 +00:00
let msg2 = decode(&mut should, MAGIC, &crypto).unwrap();
2019-02-19 17:42:50 +00:00
assert_eq!(msg, msg2);
// Missing IPv4 count
2019-12-20 12:54:58 +00:00
assert!(decode(&mut [118, 112, 110, 1, 0, 0, 0, 1], MAGIC, &crypto).is_err());
2019-02-19 17:42:50 +00:00
// Truncated IPv4
2019-12-20 12:54:58 +00:00
assert!(decode(&mut [118, 112, 110, 1, 0, 0, 0, 1, 1], MAGIC, &crypto).is_err());
2019-02-19 17:42:50 +00:00
// Missing IPv6 count
2019-12-20 12:54:58 +00:00
assert!(decode(&mut [118, 112, 110, 1, 0, 0, 0, 1, 1, 1, 2, 3, 4, 0, 0], MAGIC, &crypto).is_err());
2019-02-19 17:42:50 +00:00
// Truncated IPv6
2019-12-20 12:54:58 +00:00
assert!(decode(&mut [118, 112, 110, 1, 0, 0, 0, 1, 1, 1, 2, 3, 4, 0, 0, 1], MAGIC, &crypto).is_err());
2019-02-19 17:42:50 +00:00
}
#[test]
fn udpmessage_init() {
use super::types::Address;
let mut crypto = Crypto::None;
2019-12-04 08:32:35 +00:00
let addrs = vec![
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 },
Range { base: Address { data: [0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 6 }, prefix_len: 16 },
];
let node_id = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
let mut msg = Message::Init(0, node_id, addrs, 1800);
2019-12-04 08:32:35 +00:00
let mut should = [
118, 112, 110, 1, 0, 0, 0, 2, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 2, 4, 0, 1, 2, 3, 24, 6,
0, 1, 2, 3, 4, 5, 16, 7, 8
2019-12-04 08:32:35 +00:00
];
2019-02-19 17:42:50 +00:00
{
let mut buf = [0; 1024];
let res = encode(&mut msg, &mut buf[..], MAGIC, &mut crypto);
assert_eq!(res.len(), 42);
2019-02-19 17:42:50 +00:00
for i in 0..res.len() {
assert_eq!(res[i], should[i]);
}
}
2019-12-20 12:54:58 +00:00
let msg2 = decode(&mut should, MAGIC, &crypto).unwrap();
2019-02-19 17:42:50 +00:00
assert_eq!(msg, msg2);
}
#[test]
fn udpmessage_close() {
let mut crypto = Crypto::None;
let mut msg = Message::Close;
2019-12-04 08:32:35 +00:00
let mut should = [118, 112, 110, 1, 0, 0, 0, 3];
2019-02-19 17:42:50 +00:00
{
let mut buf = [0; 1024];
let res = encode(&mut msg, &mut buf[..], MAGIC, &mut crypto);
assert_eq!(res.len(), 8);
assert_eq!(&res, &should);
}
2019-12-20 12:54:58 +00:00
let msg2 = decode(&mut should, MAGIC, &crypto).unwrap();
2019-02-19 17:42:50 +00:00
assert_eq!(msg, msg2);
}
#[test]
fn udpmessage_invalid() {
2019-12-20 12:54:58 +00:00
let crypto = Crypto::None;
assert!(decode(&mut [0x76, 0x70, 0x6e, 1, 0, 0, 0, 0], MAGIC, &crypto).is_ok());
2019-02-19 17:42:50 +00:00
// too short
2019-12-20 12:54:58 +00:00
assert!(decode(&mut [], MAGIC, &crypto).is_err());
2019-02-19 17:42:50 +00:00
// invalid protocol
2019-12-20 12:54:58 +00:00
assert!(decode(&mut [0, 1, 2, 0, 0, 0, 0, 0], MAGIC, &crypto).is_err());
2019-02-19 17:42:50 +00:00
// invalid version
2019-12-20 12:54:58 +00:00
assert!(decode(&mut [0x76, 0x70, 0x6e, 0xaa, 0, 0, 0, 0], MAGIC, &crypto).is_err());
2019-02-19 17:42:50 +00:00
// invalid crypto
2019-12-20 12:54:58 +00:00
assert!(decode(&mut [0x76, 0x70, 0x6e, 1, 0xaa, 0, 0, 0], MAGIC, &crypto).is_err());
2019-02-19 17:42:50 +00:00
// invalid msg type
2019-12-20 12:54:58 +00:00
assert!(decode(&mut [0x76, 0x70, 0x6e, 1, 0, 0, 0, 0xaa], MAGIC, &crypto).is_err());
2019-02-19 17:42:50 +00:00
}
#[test]
fn udpmessage_invalid_crypto() {
2019-12-20 12:54:58 +00:00
let crypto = Crypto::from_shared_key(CryptoMethod::ChaCha20, "test");
2019-02-19 17:42:50 +00:00
// truncated crypto
2019-12-20 12:54:58 +00:00
assert!(decode(&mut [0x76, 0x70, 0x6e, 1, 1, 0, 0, 0], MAGIC, &crypto).is_err());
2019-02-19 17:42:50 +00:00
}
#[test]
fn message_fmt() {
2019-12-04 08:32:35 +00:00
assert_eq!(format!("{:?}", Message::Data(&mut [1, 2, 3, 4, 5], 0, 5)), "Data(5 bytes)");
assert_eq!(
format!(
"{:?}",
Message::Peers(vec![
SocketAddr::from_str("1.2.3.4:123").unwrap(),
SocketAddr::from_str("5.6.7.8:12345").unwrap(),
SocketAddr::from_str("[0001:0203:0405:0607:0809:0a0b:0c0d:0e0f]:6789").unwrap()
])
),
"Peers [1.2.3.4:123, 5.6.7.8:12345, [1:203:405:607:809:a0b:c0d:e0f]:6789]"
);
assert_eq!(
format!(
"{:?}",
Message::Init(0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], vec![
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
},
Range {
base: Address { data: [0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], len: 6 },
prefix_len: 16
}
], 1800)
2019-12-04 08:32:35 +00:00
),
"Init(stage=0, node_id=000102030405060708090a0b0c0d0e0f, peer_timeout=1800, [0.1.2.3/24, 00:01:02:03:04:05/16])"
2019-12-04 08:32:35 +00:00
);
2019-02-19 17:42:50 +00:00
assert_eq!(format!("{:?}", Message::Close), "Close");
}