diff options
Diffstat (limited to 'src/packet.rs')
| -rw-r--r-- | src/packet.rs | 197 |
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 +} |
