use super::*;
use toxcore::binary_io::*;
use toxcore::crypto_core::*;
use nom::rest;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct InnerOnionDataRequest {
pub destination_pk: PublicKey,
pub nonce: Nonce,
pub temporary_pk: PublicKey,
pub payload: Vec<u8>
}
impl FromBytes for InnerOnionDataRequest {
named!(from_bytes<InnerOnionDataRequest>, do_parse!(
tag!(&[0x85][..]) >>
destination_pk: call!(PublicKey::from_bytes) >>
nonce: call!(Nonce::from_bytes) >>
temporary_pk: call!(PublicKey::from_bytes) >>
payload: rest >>
(InnerOnionDataRequest {
destination_pk,
nonce,
temporary_pk,
payload: payload.to_vec()
})
));
}
impl ToBytes for InnerOnionDataRequest {
fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> {
do_gen!(buf,
gen_be_u8!(0x85) >>
gen_slice!(self.destination_pk.as_ref()) >>
gen_slice!(self.nonce.as_ref()) >>
gen_slice!(self.temporary_pk.as_ref()) >>
gen_slice!(self.payload)
)
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct OnionDataRequest {
pub inner: InnerOnionDataRequest,
pub onion_return: OnionReturn
}
impl FromBytes for OnionDataRequest {
named!(from_bytes<OnionDataRequest>, do_parse!(
rest_len: verify!(rest_len, |len| len <= ONION_MAX_PACKET_SIZE) >>
inner: cond_reduce!(
rest_len >= ONION_RETURN_3_SIZE,
flat_map!(take!(rest_len - ONION_RETURN_3_SIZE), InnerOnionDataRequest::from_bytes)
) >>
onion_return: call!(OnionReturn::from_bytes) >>
(OnionDataRequest { inner, onion_return })
));
}
impl ToBytes for OnionDataRequest {
fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> {
do_gen!(buf,
gen_call!(|buf, inner| InnerOnionDataRequest::to_bytes(inner, buf), &self.inner) >>
gen_call!(|buf, onion_return| OnionReturn::to_bytes(onion_return, buf), &self.onion_return) >>
gen_len_limit(ONION_MAX_PACKET_SIZE)
)
}
}
#[cfg(test)]
mod tests {
use super::*;
const ONION_RETURN_3_PAYLOAD_SIZE: usize = ONION_RETURN_3_SIZE - secretbox::NONCEBYTES;
encode_decode_test!(
inner_onion_data_request_encode_decode,
InnerOnionDataRequest {
destination_pk: gen_keypair().0,
nonce: gen_nonce(),
temporary_pk: gen_keypair().0,
payload: vec![42; 123]
}
);
encode_decode_test!(
onion_data_request_encode_decode,
OnionDataRequest {
inner: InnerOnionDataRequest {
destination_pk: gen_keypair().0,
nonce: gen_nonce(),
temporary_pk: gen_keypair().0,
payload: vec![42; 123]
},
onion_return: OnionReturn {
nonce: secretbox::gen_nonce(),
payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE]
}
}
);
}