p2p/network/pnet/
p2p_network_pnet_state.rs1use 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}