1mod raw;
2mod header;
3mod incoming;
4mod outgoing;
5mod payload;
6
7pub use raw::*;
8pub use header::*;
9pub use incoming::*;
10pub use outgoing::*;
11pub use payload::*;
12
13#[derive(Debug, Eq, PartialEq, Copy, Clone)]
14pub enum PacketType {
15 Connection,
16 Payload,
17 Heartbeat,
18 Disconnect,
19 Disconnected,
20}
21
22impl PacketType {
23 pub fn from_u8(value: u8) -> Option<Self> {
24 match value {
25 0 => Some(Self::Connection),
26 1 => Some(Self::Payload),
27 2 => Some(Self::Heartbeat),
28 3 => Some(Self::Disconnect),
29 4 => Some(Self::Disconnected),
30 _ => None,
31 }
32 }
33
34 pub fn to_u8(&self) -> u8 {
35 match self {
36 Self::Connection => 0,
37 Self::Payload => 1,
38 Self::Heartbeat => 2,
39 Self::Disconnect => 3,
40 Self::Disconnected => 4,
41 }
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn sign_and_verify_packet() {
51 use std::io::{Read, Write};
52 use crate::security::Secret;
53
54 let secret = Secret::from_bytes([
55 0x2, 0x1, 0x2, 0x4, 0x8, 0x24, 0x2, 0x1,
56 0x2, 0x4, 0x8, 0x24, 0x2, 0x1, 0x2, 0x4,
57 0x8, 0x24, 0x2, 0x1, 0x2, 0x4, 0x8, 0x24,
58 0x2, 0x1, 0x2, 0x4, 0x8, 0x24, 0x0, 0x64]);
59 let mut outgoing = OutgoingPacket::new();
60
61 outgoing.write(&[0x1, 0x2, 0x3, 0x4, 0x5, 0x6]).expect("It writes into the buffer");
62
63 let buffer = outgoing.write_header_and_sign(15, 12, [0x3, 0x2, 0x1, 0x0], PacketType::Payload.to_u8(), &secret);
64
65 let mut incoming = buffer.verify(&secret).expect("The verification succeeds");
66
67 let mut read_into: [u8; 6] = [0; 6];
68 incoming.read(&mut read_into).expect("It reads into the buffer");
69
70 assert_eq!(read_into, [0x1, 0x2, 0x3, 0x4, 0x5, 0x6], "The body matches the written data");
71 assert_eq!(incoming.get_sequence_number(), 15);
72 assert_eq!(incoming.get_ack_sequence_number(), 12);
73 assert_eq!(incoming.get_ack_bits(), [0x3, 0x2, 0x1, 0x0]);
74 assert_eq!(incoming.get_packet_type(), Some(PacketType::Payload));
75 assert_eq!(incoming.get_body_length(), 6);
76 }
77
78 #[test]
79 fn it_rejects_a_tampered_packet() {
80 use std::io::Write;
81 use crate::security::Secret;
82
83 let secret = Secret::from_bytes([
84 0x2, 0x1, 0x2, 0x4, 0x8, 0x24, 0x2, 0x1,
85 0x2, 0x4, 0x8, 0x24, 0x2, 0x1, 0x2, 0x4,
86 0x8, 0x24, 0x2, 0x1, 0x2, 0x4, 0x8, 0x24,
87 0x2, 0x1, 0x2, 0x4, 0x8, 0x24, 0x0, 0x64]);
88 let mut outgoing = OutgoingPacket::new();
89
90 outgoing.write(&[0x1, 0x2, 0x3, 0x4, 0x5, 0x6]).expect("It writes into the buffer");
91
92 let mut buffer = outgoing.write_header_and_sign(0, 1, [0x0, 0x0, 0x0, 0x0], 1, &secret);
93
94 buffer.get_buffer_mut()[56] = 0x2;
95
96 assert!(buffer.verify(&secret).is_none(), "The packet is invalid");
97 }
98
99 #[test]
100 fn it_rejects_a_packet_signed_with_a_different_secret() {
101 use std::io::Write;
102 use crate::security::Secret;
103
104 let secret = Secret::from_bytes([
105 0x2, 0x1, 0x2, 0x4, 0x8, 0x24, 0x2, 0x1,
106 0x2, 0x4, 0x8, 0x24, 0x2, 0x1, 0x2, 0x4,
107 0x8, 0x24, 0x2, 0x1, 0x2, 0x4, 0x8, 0x24,
108 0x2, 0x1, 0x2, 0x4, 0x8, 0x24, 0x0, 0x64]);
109 let mut outgoing = OutgoingPacket::new();
110
111 outgoing.write(&[0x1, 0x2, 0x3, 0x4, 0x5, 0x6]).expect("It writes into the buffer");
112
113 let buffer = outgoing.write_header_and_sign(0, 1, [0x0, 0x0, 0x0, 0x0], 1, &secret);
114
115 let secret = Secret::from_bytes([
116 0x5, 0x1, 0x2, 0x4, 0x8, 0x24, 0x2, 0x1,
117 0x2, 0x4, 0x8, 0x24, 0x2, 0x1, 0x2, 0x4,
118 0x8, 0x24, 0x2, 0x1, 0x2, 0x4, 0x8, 0x24,
119 0x2, 0x1, 0x2, 0x4, 0x8, 0x24, 0x0, 0x64]);
120
121 assert!(buffer.verify(&secret).is_none(), "The packet is invalid");
122 }
123}