1use crate::peer::PeerId;
2use bytes::Bytes;
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7pub enum PacketType {
8 Data,
10 Control,
12 DhtQuery,
14 DhtResponse,
16 Discovery,
18 Heartbeat,
20 NatTraversal,
22 Dummy,
24}
25
26#[derive(Clone, Serialize, Deserialize)]
28pub struct Packet {
29 pub packet_type: PacketType,
31
32 pub source: Option<PeerId>,
34
35 pub destination: Option<PeerId>,
37
38 pub sequence: u64,
40
41 pub timestamp: u64,
43
44 pub payload: Bytes,
46
47 pub signature: Option<Vec<u8>>,
49
50 pub routing_hints: Option<Vec<PeerId>>,
52}
53
54impl Packet {
55 pub fn new(
57 packet_type: PacketType,
58 source: Option<PeerId>,
59 destination: Option<PeerId>,
60 payload: Bytes,
61 ) -> Self {
62 Self {
63 packet_type,
64 source,
65 destination,
66 sequence: 0,
67 timestamp: current_timestamp_ms(),
68 payload,
69 signature: None,
70 routing_hints: None,
71 }
72 }
73
74 pub fn dummy(size: usize) -> Self {
76 Self::new(
77 PacketType::Dummy,
78 None,
79 None,
80 Bytes::from(vec![0u8; size]),
81 )
82 }
83
84 pub fn to_bytes(&self) -> crate::error::Result<Vec<u8>> {
86 bincode::serialize(self).map_err(Into::into)
87 }
88
89 pub fn from_bytes(data: &[u8]) -> crate::error::Result<Self> {
91 bincode::deserialize(data).map_err(Into::into)
92 }
93
94 pub fn size(&self) -> usize {
96 self.to_bytes().map(|b| b.len()).unwrap_or(0)
97 }
98
99 pub fn is_dummy(&self) -> bool {
101 self.packet_type == PacketType::Dummy
102 }
103
104 pub fn with_sequence(mut self, sequence: u64) -> Self {
106 self.sequence = sequence;
107 self
108 }
109
110 pub fn with_routing_hints(mut self, hints: Vec<PeerId>) -> Self {
112 self.routing_hints = Some(hints);
113 self
114 }
115}
116
117impl std::fmt::Debug for Packet {
118 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119 f.debug_struct("Packet")
120 .field("type", &self.packet_type)
121 .field("source", &self.source)
122 .field("destination", &self.destination)
123 .field("sequence", &self.sequence)
124 .field("payload_size", &self.payload.len())
125 .field("has_signature", &self.signature.is_some())
126 .finish()
127 }
128}
129
130#[derive(Debug, Clone, Default)]
132pub struct PacketStats {
133 pub total_sent: u64,
134 pub total_received: u64,
135 pub total_dummy: u64,
136 pub bytes_sent: u64,
137 pub bytes_received: u64,
138 pub avg_packet_size: f64,
139}
140
141fn current_timestamp_ms() -> u64 {
142 use std::time::{SystemTime, UNIX_EPOCH};
143 SystemTime::now()
144 .duration_since(UNIX_EPOCH)
145 .unwrap()
146 .as_millis() as u64
147}