nym_sphinx_forwarding/
packet.rs1use nym_sphinx_addressing::nodes::{NymNodeRoutingAddress, NymNodeRoutingAddressError};
5use nym_sphinx_params::{PacketSize, PacketType, SphinxKeyRotation};
6use nym_sphinx_types::{NymPacket, NymPacketError};
7
8use nym_sphinx_anonymous_replies::reply_surb::AppliedReplySurb;
9use nym_sphinx_params::key_rotation::InvalidSphinxKeyRotation;
10use nym_sphinx_params::packet_sizes::InvalidPacketSize;
11use nym_sphinx_params::packet_types::InvalidPacketType;
12use std::net::SocketAddr;
13use thiserror::Error;
14
15#[derive(Debug, Error)]
16pub enum MixPacketFormattingError {
17 #[error("too few bytes provided to recover from bytes")]
18 TooFewBytesProvided,
19
20 #[error("provided packet mode is invalid: {0}")]
21 InvalidPacketType(#[from] InvalidPacketType),
22
23 #[error("received request had an invalid packet size: {0}")]
24 InvalidPacketSize(#[from] InvalidPacketSize),
25
26 #[error("provided key rotation is invalid: {0}")]
27 InvalidKeyRotation(#[from] InvalidSphinxKeyRotation),
28
29 #[error("address field was incorrectly encoded")]
30 InvalidAddress,
31
32 #[error("received sphinx packet was malformed")]
33 MalformedSphinxPacket,
34
35 #[error("Packet: {0}")]
36 Packet(#[from] NymPacketError),
37}
38
39impl From<NymNodeRoutingAddressError> for MixPacketFormattingError {
40 fn from(_: NymNodeRoutingAddressError) -> Self {
41 MixPacketFormattingError::InvalidAddress
42 }
43}
44
45#[derive(Debug)]
46pub struct MixPacket {
47 next_hop: NymNodeRoutingAddress,
48 packet: NymPacket,
49 packet_type: PacketType,
50 key_rotation: SphinxKeyRotation,
51}
52
53impl MixPacket {
54 pub fn new(
55 next_hop: NymNodeRoutingAddress,
56 packet: NymPacket,
57 packet_type: PacketType,
58 key_rotation: SphinxKeyRotation,
59 ) -> Self {
60 MixPacket {
61 next_hop,
62 packet,
63 packet_type,
64 key_rotation,
65 }
66 }
67
68 pub fn from_applied_surb(
69 applied_reply_surb: AppliedReplySurb,
70 packet_type: PacketType,
71 ) -> Self {
72 MixPacket {
73 next_hop: applied_reply_surb.first_hop_address(),
74 key_rotation: applied_reply_surb.key_rotation(),
75 packet: applied_reply_surb.into_packet(),
76 packet_type,
77 }
78 }
79
80 pub fn next_hop(&self) -> NymNodeRoutingAddress {
81 self.next_hop
82 }
83
84 pub fn next_hop_address(&self) -> SocketAddr {
85 self.next_hop.into()
86 }
87
88 pub fn packet(&self) -> &NymPacket {
89 &self.packet
90 }
91
92 pub fn into_packet(self) -> NymPacket {
93 self.packet
94 }
95
96 pub fn key_rotation(&self) -> SphinxKeyRotation {
97 self.key_rotation
98 }
99
100 pub fn packet_type(&self) -> PacketType {
101 self.packet_type
102 }
103
104 pub fn try_from_v1_bytes(b: &[u8]) -> Result<Self, MixPacketFormattingError> {
107 if b.len() < 2 {
109 return Err(MixPacketFormattingError::TooFewBytesProvided);
110 }
111
112 let packet_type = PacketType::try_from(b[0])?;
113
114 let next_hop = NymNodeRoutingAddress::try_from_bytes(&b[1..])?;
115 let addr_offset = next_hop.bytes_min_len();
116
117 let packet_data = &b[addr_offset + 1..];
118 let packet_size = packet_data.len();
119
120 let _ = PacketSize::get_type(packet_size)?;
122
123 let packet = match packet_type {
124 PacketType::Mix => NymPacket::sphinx_from_bytes(packet_data)?,
125 PacketType::Outfox => NymPacket::outfox_from_bytes(packet_data)?,
126 };
127
128 Ok(MixPacket {
129 next_hop,
130 packet,
131 packet_type,
132 key_rotation: SphinxKeyRotation::Unknown,
133 })
134 }
135
136 pub fn into_v1_bytes(self) -> Result<Vec<u8>, MixPacketFormattingError> {
137 Ok(std::iter::once(self.packet_type as u8)
138 .chain(self.next_hop.as_bytes())
139 .chain(self.packet.to_bytes()?)
140 .collect())
141 }
142
143 pub fn try_from_v2_bytes(b: &[u8]) -> Result<Self, MixPacketFormattingError> {
146 if b.len() < 3 {
149 return Err(MixPacketFormattingError::TooFewBytesProvided);
150 }
151
152 let packet_type = PacketType::try_from(b[0])?;
153 let key_rotation = SphinxKeyRotation::try_from(b[1])?;
154
155 let next_hop = NymNodeRoutingAddress::try_from_bytes(&b[2..])?;
156 let addr_offset = next_hop.bytes_min_len();
157
158 let packet_data = &b[addr_offset + 2..];
159 let packet_size = packet_data.len();
160
161 let _ = PacketSize::get_type(packet_size)?;
163
164 let packet = match packet_type {
165 PacketType::Mix => NymPacket::sphinx_from_bytes(packet_data)?,
166 PacketType::Outfox => NymPacket::outfox_from_bytes(packet_data)?,
167 };
168
169 Ok(MixPacket {
170 next_hop,
171 packet,
172 packet_type,
173 key_rotation,
174 })
175 }
176
177 pub fn into_v2_bytes(self) -> Result<Vec<u8>, MixPacketFormattingError> {
178 Ok(std::iter::once(self.packet_type as u8)
179 .chain(std::iter::once(self.key_rotation as u8))
180 .chain(self.next_hop.as_bytes())
181 .chain(self.packet.to_bytes()?)
182 .collect())
183 }
184}
185
186