37f178f5521ccfcc6f5f26738f949bc69945872b
[rust-lightning] / lightning / src / onion_message / packet.rs
1 // This file is Copyright its original authors, visible in version control
2 // history.
3 //
4 // This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5 // or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7 // You may not use this file except in accordance with one or both of these
8 // licenses.
9
10 //! Structs and enums useful for constructing and reading an onion message packet.
11
12 use bitcoin::secp256k1::PublicKey;
13
14 use ln::msgs::DecodeError;
15 use ln::onion_utils;
16 use util::ser::{LengthRead, LengthReadable, Readable, Writeable, Writer};
17
18 use core::cmp;
19 use io;
20 use prelude::*;
21
22 #[derive(Clone, Debug, PartialEq)]
23 pub(crate) struct Packet {
24         version: u8,
25         public_key: PublicKey,
26         // Unlike the onion packets used for payments, onion message packets can have payloads greater
27         // than 1300 bytes.
28         // TODO: if 1300 ends up being the most common size, optimize this to be:
29         // enum { ThirteenHundred([u8; 1300]), VarLen(Vec<u8>) }
30         hop_data: Vec<u8>,
31         hmac: [u8; 32],
32 }
33
34 impl onion_utils::Packet for Packet {
35         type Data = Vec<u8>;
36         fn new(public_key: PublicKey, hop_data: Vec<u8>, hmac: [u8; 32]) -> Packet {
37                 Self {
38                         version: 0,
39                         public_key,
40                         hop_data,
41                         hmac,
42                 }
43         }
44 }
45
46 impl Writeable for Packet {
47         fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
48                 self.version.write(w)?;
49                 self.public_key.write(w)?;
50                 w.write_all(&self.hop_data)?;
51                 self.hmac.write(w)?;
52                 Ok(())
53         }
54 }
55
56 impl LengthReadable for Packet {
57         fn read<R: LengthRead>(r: &mut R) -> Result<Self, DecodeError> {
58                 const READ_BUFFER_SIZE: usize = 4096;
59
60                 let version = Readable::read(r)?;
61                 let public_key = Readable::read(r)?;
62
63                 let mut hop_data = Vec::new();
64                 let hop_data_len = r.total_bytes() as usize - 66; // 1 (version) + 33 (pubkey) + 32 (HMAC) = 66
65                 let mut read_idx = 0;
66                 while read_idx < hop_data_len {
67                         let mut read_buffer = [0; READ_BUFFER_SIZE];
68                         let read_amt = cmp::min(hop_data_len - read_idx, READ_BUFFER_SIZE);
69                         r.read_exact(&mut read_buffer[..read_amt]);
70                         hop_data.extend_from_slice(&read_buffer[..read_amt]);
71                         read_idx += read_amt;
72                 }
73
74                 let hmac = Readable::read(r)?;
75                 Ok(Packet {
76                         version,
77                         public_key,
78                         hop_data,
79                         hmac,
80                 })
81         }
82 }