vpncloud/src/udpmessage.rs

250 lines
8.0 KiB
Rust
Raw Normal View History

2015-11-19 15:34:20 +00:00
use std::{mem, ptr, fmt};
use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr};
use std::u16;
2015-11-22 17:05:15 +00:00
use super::cloud::{Error, NetworkId};
2015-11-20 17:09:51 +00:00
use super::util::{as_obj, as_bytes};
const MAGIC: [u8; 3] = [0x76, 0x70, 0x6e];
const VERSION: u8 = 0;
#[repr(packed)]
struct TopHeader {
magic: [u8; 3],
version: u8,
_reserved: [u8; 2],
2015-11-20 17:30:50 +00:00
flags: u8,
2015-11-20 17:09:51 +00:00
msgtype: u8
}
impl Default for TopHeader {
fn default() -> Self {
2015-11-20 17:30:50 +00:00
TopHeader{magic: MAGIC, version: VERSION, _reserved: [0; 2], flags: 0, msgtype: 0}
2015-11-20 17:09:51 +00:00
}
}
#[derive(Default, Debug, PartialEq, Eq)]
pub struct Options {
pub network_id: Option<NetworkId>
}
2015-11-19 15:34:20 +00:00
#[derive(PartialEq)]
2015-11-22 17:05:15 +00:00
pub enum Message<'a> {
Frame(&'a[u8]),
2015-11-19 15:34:20 +00:00
Peers(Vec<SocketAddr>),
GetPeers,
Close,
}
2015-11-22 17:05:15 +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> {
match self {
2015-11-22 17:05:15 +00:00
&Message::Frame(ref data) => write!(formatter, "Frame(data: {} bytes)", data.len()),
2015-11-19 15:34:20 +00:00
&Message::Peers(ref peers) => {
try!(write!(formatter, "Peers ["));
let mut first = true;
for p in peers {
if !first {
try!(write!(formatter, ", "));
}
first = false;
try!(p.fmt(formatter));
}
write!(formatter, "]")
},
&Message::GetPeers => write!(formatter, "GetPeers"),
&Message::Close => write!(formatter, "Close"),
}
}
}
2015-11-22 17:05:15 +00:00
pub fn decode(data: &[u8]) -> Result<(Options, Message), Error> {
2015-11-20 17:09:51 +00:00
if data.len() < mem::size_of::<TopHeader>() {
2015-11-19 15:34:20 +00:00
return Err(Error::ParseError("Empty message"));
}
let mut pos = 0;
2015-11-20 17:09:51 +00:00
let header = unsafe { as_obj::<TopHeader>(&data[pos..]) };
pos += mem::size_of::<TopHeader>();
if header.magic != MAGIC {
return Err(Error::ParseError("Wrong protocol"));
}
if header.version != VERSION {
return Err(Error::ParseError("Wrong version"));
}
let mut options = Options::default();
2015-11-20 17:30:50 +00:00
if header.flags & 0x01 > 0 {
if data.len() < pos + 8 {
2015-11-20 17:09:51 +00:00
return Err(Error::ParseError("Truncated options"));
}
2015-11-20 17:30:50 +00:00
let id = u64::from_be(*unsafe { as_obj::<u64>(&data[pos..]) });
options.network_id = Some(id);
pos += 8;
2015-11-20 17:09:51 +00:00
}
let msg = match header.msgtype {
2015-11-22 17:05:15 +00:00
0 => Message::Frame(&data[pos..]),
2015-11-19 15:34:20 +00:00
1 => {
if data.len() < pos + 1 {
return Err(Error::ParseError("Empty peers"));
}
let count = data[pos];
pos += 1;
let len = count as usize * 6;
if data.len() < pos + len {
return Err(Error::ParseError("Peer data too short"));
}
let mut peers = Vec::with_capacity(count as usize);
for _ in 0..count {
let (ip, port) = unsafe {
let ip = as_obj::<[u8; 4]>(&data[pos..]);
pos += 4;
let port = *as_obj::<u16>(&data[pos..]);
let port = u16::from_be(port);
pos += 2;
(ip, port)
};
let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(ip[0], ip[1], ip[2], ip[3]), port));
peers.push(addr);
}
2015-11-20 17:09:51 +00:00
Message::Peers(peers)
2015-11-19 15:34:20 +00:00
},
2015-11-20 17:09:51 +00:00
2 => Message::GetPeers,
3 => Message::Close,
_ => return Err(Error::ParseError("Unknown message type"))
};
Ok((options, msg))
2015-11-19 15:34:20 +00:00
}
2015-11-22 17:05:15 +00:00
pub fn encode(options: &Options, msg: &Message, buf: &mut [u8]) -> usize {
2015-11-20 17:09:51 +00:00
assert!(buf.len() >= mem::size_of::<TopHeader>());
2015-11-19 15:34:20 +00:00
let mut pos = 0;
2015-11-20 17:09:51 +00:00
let mut header = TopHeader::default();
header.msgtype = match msg {
2015-11-22 17:05:15 +00:00
&Message::Frame(_) => 0,
2015-11-20 08:49:41 +00:00
&Message::Peers(_) => 1,
&Message::GetPeers => 2,
&Message::Close => 3
};
2015-11-20 17:09:51 +00:00
if options.network_id.is_some() {
2015-11-20 17:30:50 +00:00
header.flags |= 0x01;
2015-11-20 17:09:51 +00:00
}
let header_dat = unsafe { as_bytes(&header) };
unsafe { ptr::copy_nonoverlapping(header_dat.as_ptr(), buf[pos..].as_mut_ptr(), header_dat.len()) };
pos += header_dat.len();
if let Some(id) = options.network_id {
2015-11-20 17:30:50 +00:00
assert!(buf.len() >= pos + 8);
2015-11-20 17:09:51 +00:00
unsafe {
let id_dat = mem::transmute::<u64, [u8; 8]>(id.to_be());
ptr::copy_nonoverlapping(id_dat.as_ptr(), buf[pos..].as_mut_ptr(), id_dat.len());
}
pos += 8;
}
2015-11-19 15:34:20 +00:00
match msg {
2015-11-22 17:05:15 +00:00
&Message::Frame(ref data) => {
assert!(buf.len() >= pos + data.len());
unsafe { ptr::copy_nonoverlapping(data.as_ptr(), buf[pos..].as_mut_ptr(), data.len()) };
pos += data.len();
2015-11-19 15:34:20 +00:00
},
&Message::Peers(ref peers) => {
let count_pos = pos;
pos += 1;
assert!(buf.len() >= 2 + peers.len() * mem::size_of::<SocketAddrV4>());
let mut count = 0;
for p in peers {
match p {
&SocketAddr::V4(addr) => {
let ip = addr.ip().octets();
let port = addr.port();
unsafe {
ptr::copy_nonoverlapping(ip.as_ptr(), buf[pos..].as_mut_ptr(), ip.len());
pos += ip.len();
let port = mem::transmute::<u16, [u8; 2]>(port.to_be());
ptr::copy_nonoverlapping(port.as_ptr(), buf[pos..].as_mut_ptr(), port.len());
pos += port.len();
}
count += 1;
},
&SocketAddr::V6(_addr) => unimplemented!()
}
};
buf[count_pos] = count;
2015-11-19 21:45:20 +00:00
buf[pos] = 0;
pos += 1;
2015-11-19 15:34:20 +00:00
},
&Message::GetPeers => {
},
&Message::Close => {
}
}
pos
}
#[test]
fn encode_message_packet() {
2015-11-20 17:09:51 +00:00
let options = Options::default();
2015-11-19 15:34:20 +00:00
let payload = [1,2,3,4,5];
2015-11-22 17:05:15 +00:00
let msg = Message::Frame(&payload);
2015-11-19 15:34:20 +00:00
let mut buf = [0; 1024];
2015-11-20 17:09:51 +00:00
let size = encode(&options, &msg, &mut buf[..]);
2015-11-22 17:05:15 +00:00
assert_eq!(size, 13);
2015-11-20 17:09:51 +00:00
assert_eq!(&buf[..8], &[118,112,110,0,0,0,0,0]);
let (options2, msg2) = decode(&buf[..size]).unwrap();
assert_eq!(options, options2);
2015-11-19 15:34:20 +00:00
assert_eq!(msg, msg2);
}
#[test]
fn encode_message_peers() {
use std::str::FromStr;
2015-11-20 17:09:51 +00:00
let options = Options::default();
2015-11-22 17:05:15 +00:00
let msg: Message = Message::Peers(vec![SocketAddr::from_str("1.2.3.4:123").unwrap(), SocketAddr::from_str("5.6.7.8:12345").unwrap()]);
2015-11-19 15:34:20 +00:00
let mut buf = [0; 1024];
2015-11-20 17:09:51 +00:00
let size = encode(&options, &msg, &mut buf[..]);
2015-11-20 10:33:32 +00:00
assert_eq!(size, 22);
2015-11-20 17:09:51 +00:00
assert_eq!(&buf[..size], &[118,112,110,0,0,0,0,1,2,1,2,3,4,0,123,5,6,7,8,48,57,0]);
let (options2, msg2) = decode(&buf[..size]).unwrap();
assert_eq!(options, options2);
assert_eq!(msg, msg2);
}
#[test]
fn encode_option_network_id() {
let mut options = Options::default();
options.network_id = Some(134);
2015-11-22 17:05:15 +00:00
let msg: Message = Message::GetPeers;
2015-11-20 17:09:51 +00:00
let mut buf = [0; 1024];
let size = encode(&options, &msg, &mut buf[..]);
2015-11-20 17:31:57 +00:00
assert_eq!(size, 16);
assert_eq!(&buf[..size], &[118,112,110,0,0,0,1,2,0,0,0,0,0,0,0,134]);
2015-11-20 17:09:51 +00:00
let (options2, msg2) = decode(&buf[..size]).unwrap();
assert_eq!(options, options2);
2015-11-19 15:34:20 +00:00
assert_eq!(msg, msg2);
}
#[test]
fn encode_message_getpeers() {
2015-11-20 17:09:51 +00:00
let options = Options::default();
2015-11-22 17:05:15 +00:00
let msg: Message = Message::GetPeers;
2015-11-19 15:34:20 +00:00
let mut buf = [0; 1024];
2015-11-20 17:09:51 +00:00
let size = encode(&options, &msg, &mut buf[..]);
2015-11-20 10:33:32 +00:00
assert_eq!(size, 8);
2015-11-20 17:09:51 +00:00
assert_eq!(&buf[..size], &[118,112,110,0,0,0,0,2]);
let (options2, msg2) = decode(&buf[..size]).unwrap();
assert_eq!(options, options2);
2015-11-19 15:34:20 +00:00
assert_eq!(msg, msg2);
}
#[test]
fn encode_message_close() {
2015-11-20 17:09:51 +00:00
let options = Options::default();
2015-11-22 17:05:15 +00:00
let msg: Message = Message::Close;
2015-11-19 15:34:20 +00:00
let mut buf = [0; 1024];
2015-11-20 17:09:51 +00:00
let size = encode(&options, &msg, &mut buf[..]);
2015-11-20 10:33:32 +00:00
assert_eq!(size, 8);
2015-11-20 17:09:51 +00:00
assert_eq!(&buf[..size], &[118,112,110,0,0,0,0,3]);
let (options2, msg2) = decode(&buf[..size]).unwrap();
assert_eq!(options, options2);
2015-11-19 15:34:20 +00:00
assert_eq!(msg, msg2);
}