aboutsummaryrefslogtreecommitdiffstats
path: root/src/packet.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/packet.rs')
-rw-r--r--src/packet.rs197
1 files changed, 122 insertions, 75 deletions
diff --git a/src/packet.rs b/src/packet.rs
index 50374a7..4cd7365 100644
--- a/src/packet.rs
+++ b/src/packet.rs
@@ -4,9 +4,12 @@ use crate::std_identity::Keystore;
#[cfg(not(feature = "std"))]
use crate::no_std_identity::Keystore;
+use crate::{
+ anon_req::ClearAnonRequest, packet_content::PacketContent, request::ClearRequest,
+ response::ClearResponse, text::ClearText,
+};
use bytes::{Buf, Bytes};
use tinyvec::ArrayVec;
-use crate::{anon_req::ClearAnonRequest, packet_content::PacketContent, request::ClearRequest, response::ClearResponse, text::ClearText};
#[derive(PartialEq, Clone, core::fmt::Debug)]
pub struct Packet {
@@ -16,7 +19,7 @@ pub struct Packet {
pub transport: [u16; 2],
pub raw_content: Bytes,
pub content: PacketContent,
- pub incomplete: bool
+ pub incomplete: bool,
}
impl core::str::FromStr for Packet {
@@ -36,7 +39,7 @@ impl From<Bytes> for Packet {
let mut packet = Packet::default();
if bytes.len() < 2 {
- return packet
+ return packet;
}
let header = bytes.get_u8();
@@ -49,25 +52,29 @@ impl From<Bytes> for Packet {
packet.transport = match packet.route_type {
RouteType::TransportFlood | RouteType::TransportDirect => {
// The packet isn't long enough to contain the transport
- if bytes.len() < 4 { return packet; }
+ if bytes.len() < 4 {
+ return packet;
+ }
let t1 = bytes.get_u16_le();
let t2 = bytes.get_u16_le();
[t1, t2]
- },
- _ => {
- [0, 0]
}
+ _ => [0, 0],
};
// Get the route
- if bytes.is_empty() { return packet; }
+ if bytes.is_empty() {
+ return packet;
+ }
let path_length = bytes.get_u8() as usize;
packet.path = match packet.version {
PayloadVersion::VersionOne => {
// The packet isn't long enough for the indicated route
- if bytes.len() < path_length { return packet; }
+ if bytes.len() < path_length {
+ return packet;
+ }
let mut route = ArrayVec::new();
for _ in 0..path_length {
@@ -76,11 +83,13 @@ impl From<Bytes> for Packet {
}
route
- },
+ }
PayloadVersion::VersionTwo => {
// The packet isn't long enough for the indicated route
- if bytes.len() < path_length * 2 { return packet; }
+ if bytes.len() < path_length * 2 {
+ return packet;
+ }
let mut route = ArrayVec::new();
for i in 0..path_length {
@@ -89,7 +98,7 @@ impl From<Bytes> for Packet {
}
route
- },
+ }
_ => {
return packet;
}
@@ -121,7 +130,7 @@ impl From<Bytes> for Packet {
// when it prints the SNR results in its Display function.
packet.content = PacketContent::Trace(trace);
}
-
+
// Mark the packet as complete and valid
packet.incomplete = false;
@@ -138,7 +147,7 @@ impl Default for Packet {
transport: [0, 0],
raw_content: Bytes::new(),
content: PacketContent::Invalid,
- incomplete: true
+ incomplete: true,
}
}
}
@@ -149,8 +158,13 @@ impl core::fmt::Display for Packet {
f.write_str(" | ")?;
core::fmt::Display::fmt(&self.version, f)?;
- if self.route_type == RouteType::TransportDirect || self.route_type == RouteType::TransportFlood {
- f.write_fmt(format_args!(" | {:4x?}, {:4x?} | ", self.transport[0], self.transport[1]))?
+ if self.route_type == RouteType::TransportDirect
+ || self.route_type == RouteType::TransportFlood
+ {
+ f.write_fmt(format_args!(
+ " | {:4x?}, {:4x?} | ",
+ self.transport[0], self.transport[1]
+ ))?
} else {
f.write_fmt(format_args!(" | |"))?
}
@@ -159,9 +173,21 @@ impl core::fmt::Display for Packet {
match self.path.len() {
0 => f.write_fmt(format_args!(" [] | ")),
1 => f.write_fmt(format_args!(" [{:02x?}] | ", self.path[0])),
- 2 => f.write_fmt(format_args!(" [{:02x?}, {:02x?}] | ", self.path[0], self.path[1])),
- 3 => f.write_fmt(format_args!(" [{:02x?}, {:02x?}, {:02x?}] | ", self.path[0], self.path[1], self.path[2])),
- _ => f.write_fmt(format_args!(" [{:02x?}, {:02x?}, ... {:02x?}, {:02x?}] | ", self.path[0], self.path[1], self.path[len - 2], self.path[len -1])),
+ 2 => f.write_fmt(format_args!(
+ " [{:02x?}, {:02x?}] | ",
+ self.path[0], self.path[1]
+ )),
+ 3 => f.write_fmt(format_args!(
+ " [{:02x?}, {:02x?}, {:02x?}] | ",
+ self.path[0], self.path[1], self.path[2]
+ )),
+ _ => f.write_fmt(format_args!(
+ " [{:02x?}, {:02x?}, ... {:02x?}, {:02x?}] | ",
+ self.path[0],
+ self.path[1],
+ self.path[len - 2],
+ self.path[len - 1]
+ )),
}?;
if self.incomplete {
@@ -179,21 +205,19 @@ impl Packet {
pub fn try_decrypt(&mut self, keystore: &Keystore) -> bool {
match self.content {
// Encrypted packet types
- PacketContent::Path(ref mut path) => {
- path.cipher.try_decrypt(keystore)
- },
+ PacketContent::Path(ref mut path) => path.cipher.try_decrypt(keystore),
PacketContent::Request(ref mut request) => {
let result = request.cipher.try_decrypt(keystore);
if let Some(cleartext) = &request.cipher.cleartext {
let cleartext = ClearRequest::from(cleartext.clone());
request.cleartext = Some(cleartext);
-
+
result
} else {
false
}
- },
+ }
PacketContent::Response(ref mut response) => {
response.cipher.try_decrypt(keystore);
@@ -203,7 +227,7 @@ impl Packet {
} else {
false
}
- },
+ }
PacketContent::Text(ref mut text) => {
text.cipher.try_decrypt(keystore);
@@ -214,14 +238,14 @@ impl Packet {
} else {
false
}
- },
+ }
PacketContent::AnonReq(ref mut anon_req) => {
let decrypt_result = keystore.decrypt_anon(
anon_req.dest,
&anon_req.public_key,
anon_req.mac,
- &anon_req.ciphertext
+ &anon_req.ciphertext,
);
if let Some(cleartext) = decrypt_result {
@@ -232,14 +256,12 @@ impl Packet {
}
}
- PacketContent::GroupText(ref mut group_text) => {
- group_text.try_decrypt(keystore)
- }
+ PacketContent::GroupText(ref mut group_text) => group_text.try_decrypt(keystore),
// None of the other packets implement any encryption
- _ => false
+ _ => false,
}
- }
+ }
}
#[derive(PartialEq, Debug, Clone)]
@@ -254,11 +276,11 @@ pub enum RouteType {
impl core::fmt::Display for RouteType {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
- RouteType::TransportFlood => f.write_str("T-Flood "),
- RouteType::Flood => f.write_str(" Flood "),
- RouteType::Direct => f.write_str(" Direct"),
+ RouteType::TransportFlood => f.write_str("T-Flood "),
+ RouteType::Flood => f.write_str(" Flood "),
+ RouteType::Direct => f.write_str(" Direct"),
RouteType::TransportDirect => f.write_str("T-Direct"),
- RouteType::Invalid => f.write_str("INVALID "),
+ RouteType::Invalid => f.write_str("INVALID "),
}
}
}
@@ -270,7 +292,7 @@ impl From<u8> for RouteType {
0x01 => RouteType::Flood,
0x02 => RouteType::Direct,
0x03 => RouteType::TransportDirect,
- _ => RouteType::Invalid
+ _ => RouteType::Invalid,
}
}
}
@@ -294,7 +316,7 @@ impl From<u8> for PayloadVersion {
0x01 => PayloadVersion::VersionTwo,
0x02 => PayloadVersion::VersionThree,
0x03 => PayloadVersion::VersionFour,
- _ => PayloadVersion::Invalid
+ _ => PayloadVersion::Invalid,
}
}
}
@@ -302,11 +324,11 @@ impl From<u8> for PayloadVersion {
impl core::fmt::Display for PayloadVersion {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
- PayloadVersion::VersionOne => f.write_str("v1"),
- PayloadVersion::VersionTwo => f.write_str("v2"),
+ PayloadVersion::VersionOne => f.write_str("v1"),
+ PayloadVersion::VersionTwo => f.write_str("v2"),
PayloadVersion::VersionThree => f.write_str("v3"),
- PayloadVersion::VersionFour => f.write_str("v4"),
- PayloadVersion::Invalid => f.write_str("xx"),
+ PayloadVersion::VersionFour => f.write_str("v4"),
+ PayloadVersion::Invalid => f.write_str("xx"),
}
}
}
@@ -316,50 +338,53 @@ mod tests {
use core::str::FromStr;
use tinyvec::array_vec;
- use crate::packet_content::{PacketContent, Raw};
use super::*;
+ use crate::packet_content::{PacketContent, Raw};
#[test]
fn header_route_type() {
// The route type is the lowest-order two bits
- assert_eq!(RouteType::TransportFlood, RouteType::from(0x00));
- assert_eq!(RouteType::TransportFlood, RouteType::from(0xFC));
- assert_eq!(RouteType::Flood, RouteType::from(0x01));
- assert_eq!(RouteType::Flood, RouteType::from(0xFD));
- assert_eq!(RouteType::Direct, RouteType::from(0x02));
- assert_eq!(RouteType::Direct, RouteType::from(0xFE));
+ assert_eq!(RouteType::TransportFlood, RouteType::from(0x00));
+ assert_eq!(RouteType::TransportFlood, RouteType::from(0xFC));
+ assert_eq!(RouteType::Flood, RouteType::from(0x01));
+ assert_eq!(RouteType::Flood, RouteType::from(0xFD));
+ assert_eq!(RouteType::Direct, RouteType::from(0x02));
+ assert_eq!(RouteType::Direct, RouteType::from(0xFE));
assert_eq!(RouteType::TransportDirect, RouteType::from(0x03));
assert_eq!(RouteType::TransportDirect, RouteType::from(0xFF));
- assert_eq!(format!("{}", RouteType::TransportFlood), "T-Flood ");
- assert_eq!(format!("{}", RouteType::Flood), " Flood ");
- assert_eq!(format!("{}", RouteType::Direct), " Direct");
+ assert_eq!(format!("{}", RouteType::TransportFlood), "T-Flood ");
+ assert_eq!(format!("{}", RouteType::Flood), " Flood ");
+ assert_eq!(format!("{}", RouteType::Direct), " Direct");
assert_eq!(format!("{}", RouteType::TransportDirect), "T-Direct");
- assert_eq!(format!("{}", RouteType::Invalid), "INVALID ");
+ assert_eq!(format!("{}", RouteType::Invalid), "INVALID ");
}
#[test]
fn header_version() {
- assert_eq!(PayloadVersion::VersionOne, PayloadVersion::from(0x00));
- assert_eq!(PayloadVersion::VersionOne, PayloadVersion::from(0x3F));
- assert_eq!(PayloadVersion::VersionTwo, PayloadVersion::from(0x40));
- assert_eq!(PayloadVersion::VersionTwo, PayloadVersion::from(0x7F));
+ assert_eq!(PayloadVersion::VersionOne, PayloadVersion::from(0x00));
+ assert_eq!(PayloadVersion::VersionOne, PayloadVersion::from(0x3F));
+ assert_eq!(PayloadVersion::VersionTwo, PayloadVersion::from(0x40));
+ assert_eq!(PayloadVersion::VersionTwo, PayloadVersion::from(0x7F));
assert_eq!(PayloadVersion::VersionThree, PayloadVersion::from(0x80));
assert_eq!(PayloadVersion::VersionThree, PayloadVersion::from(0xBF));
- assert_eq!(PayloadVersion::VersionFour, PayloadVersion::from(0xC0));
- assert_eq!(PayloadVersion::VersionFour, PayloadVersion::from(0xFF));
+ assert_eq!(PayloadVersion::VersionFour, PayloadVersion::from(0xC0));
+ assert_eq!(PayloadVersion::VersionFour, PayloadVersion::from(0xFF));
- assert_eq!(format!("{}", PayloadVersion::VersionOne), "v1");
- assert_eq!(format!("{}", PayloadVersion::VersionTwo), "v2");
+ assert_eq!(format!("{}", PayloadVersion::VersionOne), "v1");
+ assert_eq!(format!("{}", PayloadVersion::VersionTwo), "v2");
assert_eq!(format!("{}", PayloadVersion::VersionThree), "v3");
- assert_eq!(format!("{}", PayloadVersion::VersionFour), "v4");
- assert_eq!(format!("{}", PayloadVersion::Invalid), "xx");
+ assert_eq!(format!("{}", PayloadVersion::VersionFour), "v4");
+ assert_eq!(format!("{}", PayloadVersion::Invalid), "xx");
}
#[test]
fn packet() {
// Check the hex decode errors
- assert_eq!(Err(hex::FromHexError::InvalidHexCharacter { c: 's', index: 0 }), Packet::from_str("s0"));
+ assert_eq!(
+ Err(hex::FromHexError::InvalidHexCharacter { c: 's', index: 0 }),
+ Packet::from_str("s0")
+ );
assert_eq!(Err(hex::FromHexError::OddLength), Packet::from_str("0"));
// Check errors related to packet length issues
@@ -387,7 +412,7 @@ mod tests {
lhs_packet.version = PayloadVersion::VersionTwo;
let rhs_packet = Packet::from_str("420102").unwrap();
assert_eq!(lhs_packet, rhs_packet);
-
+
// Ensure packet remainder is captured. This
// will test version 1 plus transport
let lhs_packet = Packet {
@@ -395,12 +420,19 @@ mod tests {
version: PayloadVersion::VersionOne,
path: array_vec!([u16; 64] => 0x06, 0x07, 0x08, 0x09, 0x0A),
transport: [0x0102, 0x0304],
- raw_content: Bytes::copy_from_slice(&[0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19]),
- content: PacketContent::Raw(Raw { bytes: Bytes::copy_from_slice(&[0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19])}),
+ raw_content: Bytes::copy_from_slice(&[
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
+ ]),
+ content: PacketContent::Raw(Raw {
+ bytes: Bytes::copy_from_slice(&[
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
+ ]),
+ }),
incomplete: false,
};
- let rhs_packet: Packet = Packet::from_str("3F0201040305060708090A10111213141516171819").unwrap();
+ let rhs_packet: Packet =
+ Packet::from_str("3F0201040305060708090A10111213141516171819").unwrap();
let compare_string = "T-Direct | v1 | 102, 304 | [06, 07, ... 09, 0a] | | RAW | Raw { bytes: b\"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\" }";
assert_eq!(format!("{}", rhs_packet), compare_string);
@@ -417,21 +449,36 @@ mod tests {
transport: [0, 1],
raw_content: Bytes::new(),
content: PacketContent::Invalid,
- incomplete: false
+ incomplete: false,
};
- assert_eq!(format!("{}", packet), " Direct | v1 | | [] | | INVALID | INVALID");
+ assert_eq!(
+ format!("{}", packet),
+ " Direct | v1 | | [] | | INVALID | INVALID"
+ );
packet.path.push(0x01);
- assert_eq!(format!("{}", packet), " Direct | v1 | | [01] | | INVALID | INVALID");
+ assert_eq!(
+ format!("{}", packet),
+ " Direct | v1 | | [01] | | INVALID | INVALID"
+ );
packet.path.push(0x02);
- assert_eq!(format!("{}", packet), " Direct | v1 | | [01, 02] | | INVALID | INVALID");
+ assert_eq!(
+ format!("{}", packet),
+ " Direct | v1 | | [01, 02] | | INVALID | INVALID"
+ );
packet.path.push(0xff);
- assert_eq!(format!("{}", packet), " Direct | v1 | | [01, 02, ff] | | INVALID | INVALID");
+ assert_eq!(
+ format!("{}", packet),
+ " Direct | v1 | | [01, 02, ff] | | INVALID | INVALID"
+ );
packet.incomplete = true;
- assert_eq!(format!("{}", packet), " Direct | v1 | | [01, 02, ff] | x | INVALID | INVALID");
+ assert_eq!(
+ format!("{}", packet),
+ " Direct | v1 | | [01, 02, ff] | x | INVALID | INVALID"
+ );
}
-} \ No newline at end of file
+}