X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fonion_message%2Fpacket.rs;fp=lightning%2Fsrc%2Fonion_message%2Fpacket.rs;h=37f178f5521ccfcc6f5f26738f949bc69945872b;hb=33ff2746ef3d1a36aab4f07cd1a7b512b6e411da;hp=0000000000000000000000000000000000000000;hpb=4e5381a50fa524cb183a3d92dee05cb4f2950255;p=rust-lightning diff --git a/lightning/src/onion_message/packet.rs b/lightning/src/onion_message/packet.rs new file mode 100644 index 00000000..37f178f5 --- /dev/null +++ b/lightning/src/onion_message/packet.rs @@ -0,0 +1,82 @@ +// This file is Copyright its original authors, visible in version control +// history. +// +// This file is licensed under the Apache License, Version 2.0 or the MIT license +// , at your option. +// You may not use this file except in accordance with one or both of these +// licenses. + +//! Structs and enums useful for constructing and reading an onion message packet. + +use bitcoin::secp256k1::PublicKey; + +use ln::msgs::DecodeError; +use ln::onion_utils; +use util::ser::{LengthRead, LengthReadable, Readable, Writeable, Writer}; + +use core::cmp; +use io; +use prelude::*; + +#[derive(Clone, Debug, PartialEq)] +pub(crate) struct Packet { + version: u8, + public_key: PublicKey, + // Unlike the onion packets used for payments, onion message packets can have payloads greater + // than 1300 bytes. + // TODO: if 1300 ends up being the most common size, optimize this to be: + // enum { ThirteenHundred([u8; 1300]), VarLen(Vec) } + hop_data: Vec, + hmac: [u8; 32], +} + +impl onion_utils::Packet for Packet { + type Data = Vec; + fn new(public_key: PublicKey, hop_data: Vec, hmac: [u8; 32]) -> Packet { + Self { + version: 0, + public_key, + hop_data, + hmac, + } + } +} + +impl Writeable for Packet { + fn write(&self, w: &mut W) -> Result<(), io::Error> { + self.version.write(w)?; + self.public_key.write(w)?; + w.write_all(&self.hop_data)?; + self.hmac.write(w)?; + Ok(()) + } +} + +impl LengthReadable for Packet { + fn read(r: &mut R) -> Result { + const READ_BUFFER_SIZE: usize = 4096; + + let version = Readable::read(r)?; + let public_key = Readable::read(r)?; + + let mut hop_data = Vec::new(); + let hop_data_len = r.total_bytes() as usize - 66; // 1 (version) + 33 (pubkey) + 32 (HMAC) = 66 + let mut read_idx = 0; + while read_idx < hop_data_len { + let mut read_buffer = [0; READ_BUFFER_SIZE]; + let read_amt = cmp::min(hop_data_len - read_idx, READ_BUFFER_SIZE); + r.read_exact(&mut read_buffer[..read_amt]); + hop_data.extend_from_slice(&read_buffer[..read_amt]); + read_idx += read_amt; + } + + let hmac = Readable::read(r)?; + Ok(Packet { + version, + public_key, + hop_data, + hmac, + }) + } +}