Constants

This commit is contained in:
Dennis Schwerdel 2015-11-24 21:15:00 +01:00
parent 553526299c
commit be3a85c3b9
1 changed files with 18 additions and 17 deletions

View File

@ -1,4 +1,4 @@
use std::{mem, ptr, fmt, slice}; use std::{mem, ptr, fmt};
use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr}; use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr};
use std::u16; use std::u16;
@ -9,6 +9,9 @@ use super::crypto::Crypto;
const MAGIC: [u8; 3] = [0x76, 0x70, 0x6e]; const MAGIC: [u8; 3] = [0x76, 0x70, 0x6e];
pub const VERSION: u8 = 1; pub const VERSION: u8 = 1;
const NETWORK_ID_BYTES: usize = 8;
#[derive(Clone)]
#[repr(packed)] #[repr(packed)]
struct TopHeader { struct TopHeader {
magic: [u8; 3], magic: [u8; 3],
@ -66,7 +69,7 @@ pub fn decode<'a>(data: &'a mut [u8], crypto: &mut Crypto) -> Result<(Options, M
return Err(Error::ParseError("Empty message")); return Err(Error::ParseError("Empty message"));
} }
let mut pos = 0; let mut pos = 0;
let header = unsafe { as_obj::<TopHeader>(&data[pos..]) }; let header = unsafe { as_obj::<TopHeader>(&data[pos..]) }.clone();
pos += mem::size_of::<TopHeader>(); pos += mem::size_of::<TopHeader>();
if header.magic != MAGIC { if header.magic != MAGIC {
return Err(Error::ParseError("Wrong protocol")); return Err(Error::ParseError("Wrong protocol"));
@ -78,25 +81,23 @@ pub fn decode<'a>(data: &'a mut [u8], crypto: &mut Crypto) -> Result<(Options, M
return Err(Error::CryptoError("Wrong crypto method")); return Err(Error::CryptoError("Wrong crypto method"));
} }
if crypto.method() > 0 { if crypto.method() > 0 {
if data.len() < pos + crypto.nonce_bytes() + crypto.auth_bytes() { let len = crypto.nonce_bytes() + crypto.auth_bytes();
if data.len() < pos + len {
return Err(Error::ParseError("Truncated crypto header")); return Err(Error::ParseError("Truncated crypto header"));
} }
let nonce = &data[pos..pos+crypto.nonce_bytes()]; let (crypto_header, crypto_data) = data[pos..].split_at_mut(len);
pos += crypto.nonce_bytes(); pos += len;
let hash = &data[pos..pos+crypto.auth_bytes()]; let (nonce, hash) = crypto_header.split_at(crypto.nonce_bytes());
pos += crypto.auth_bytes(); try!(crypto.decrypt(crypto_data, nonce, hash));
// Cheat data mutable to make the borrow checker happy
let data = unsafe { slice::from_raw_parts_mut(mem::transmute(data[pos..].as_ptr()), data.len()-pos) };
try!(crypto.decrypt(data, nonce, hash));
} }
let mut options = Options::default(); let mut options = Options::default();
if header.flags & 0x01 > 0 { if header.flags & 0x01 > 0 {
if data.len() < pos + 8 { if data.len() < pos + NETWORK_ID_BYTES {
return Err(Error::ParseError("Truncated options")); return Err(Error::ParseError("Truncated options"));
} }
let id = u64::from_be(*unsafe { as_obj::<u64>(&data[pos..]) }); let id = u64::from_be(*unsafe { as_obj::<u64>(&data[pos..pos+NETWORK_ID_BYTES]) });
options.network_id = Some(id); options.network_id = Some(id);
pos += 8; pos += NETWORK_ID_BYTES;
} }
let msg = match header.msgtype { let msg = match header.msgtype {
0 => Message::Data(&data[pos..]), 0 => Message::Data(&data[pos..]),
@ -181,12 +182,12 @@ pub fn encode(options: &Options, msg: &Message, buf: &mut [u8], crypto: &mut Cry
pos += crypto.auth_bytes(); pos += crypto.auth_bytes();
let crypto_pos = pos; let crypto_pos = pos;
if let Some(id) = options.network_id { if let Some(id) = options.network_id {
assert!(buf.len() >= pos + 8); assert!(buf.len() >= pos + NETWORK_ID_BYTES);
unsafe { unsafe {
let id_dat = mem::transmute::<u64, [u8; 8]>(id.to_be()); let id_dat = mem::transmute::<u64, [u8; NETWORK_ID_BYTES]>(id.to_be());
ptr::copy_nonoverlapping(id_dat.as_ptr(), buf[pos..].as_mut_ptr(), id_dat.len()); ptr::copy_nonoverlapping(id_dat.as_ptr(), buf[pos..pos+NETWORK_ID_BYTES].as_mut_ptr(), id_dat.len());
} }
pos += 8; pos += NETWORK_ID_BYTES;
} }
match msg { match msg {
&Message::Data(ref data) => { &Message::Data(ref data) => {