p2p/network/pnet/
p2p_network_pnet_state.rs

1use malloc_size_of_derive::MallocSizeOf;
2use redux::Timestamp;
3use serde::{Deserialize, Serialize};
4use zeroize::Zeroize;
5
6use salsa_simple::XSalsa20;
7
8use crate::P2pTimeouts;
9
10#[serde_with::serde_as]
11#[derive(Serialize, Deserialize, Debug, Clone, MallocSizeOf)]
12pub struct P2pNetworkPnetState {
13    #[ignore_malloc_size_of = "doesn't allocate"]
14    pub time: Option<Timestamp>,
15
16    #[serde_as(as = "serde_with::hex::Hex")]
17    pub shared_secret: [u8; 32],
18
19    pub incoming: Half,
20    pub outgoing: Half,
21}
22
23impl Drop for P2pNetworkPnetState {
24    fn drop(&mut self) {
25        self.shared_secret.zeroize();
26    }
27}
28
29impl P2pNetworkPnetState {
30    pub fn new(shared_secret: [u8; 32], time: Timestamp) -> Self {
31        P2pNetworkPnetState {
32            time: Some(time),
33            shared_secret,
34
35            incoming: Half::Buffering {
36                buffer: [0; 24],
37                offset: 0,
38            },
39            outgoing: Half::Buffering {
40                buffer: [0; 24],
41                offset: 0,
42            },
43        }
44    }
45
46    pub fn is_timed_out(&self, now: Timestamp, timeouts: &P2pTimeouts) -> bool {
47        if matches!(self.incoming, Half::Buffering { .. })
48            || matches!(self.outgoing, Half::Buffering { .. })
49        {
50            if let Some(time) = self.time {
51                now.checked_sub(time)
52                    .and_then(|dur| timeouts.pnet.map(|to| dur >= to))
53                    .unwrap_or(false)
54            } else {
55                false
56            }
57        } else {
58            false
59        }
60    }
61}
62
63#[derive(Serialize, Deserialize, Debug, Clone)]
64pub enum Half {
65    Buffering { buffer: [u8; 24], offset: usize },
66    Done { cipher: XSalsa20, to_send: Vec<u8> },
67}
68
69mod measurement {
70    use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
71
72    use super::*;
73
74    impl MallocSizeOf for Half {
75        fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
76            match self {
77                Self::Done { to_send, .. } => to_send.capacity(),
78                _ => 0,
79            }
80        }
81    }
82}