wgtk/net/packet.rs
1//! Packet structure definition with synchronization methods.
2
3use std::io::{Cursor, Read, Write, Seek};
4use std::collections::VecDeque;
5use std::fmt;
6
7use byteorder::{ReadBytesExt, WriteBytesExt, LE};
8
9use crate::util::BytesFmt;
10
11
12/// According to disassembly of WoT, outside of a channel, the max size if always
13/// `1500 - 28 = 1472`, this includes the 4-bytes prefix.
14pub const PACKET_MAX_LEN: usize = 1300;
15// pub const PACKET_MAX_LEN: usize = 1472;
16/// The length of the unknown 4-byte prefix.
17pub const PACKET_PREFIX_LEN: usize = 4;
18/// Flags are u16.
19pub const PACKET_FLAGS_LEN: usize = 2;
20/// Minimum length of a raw packet, containing prefix and flags.
21pub const PACKET_MIN_LEN: usize = PACKET_PREFIX_LEN + PACKET_FLAGS_LEN;
22
23/// Maximum size that can possibly taken by the footer.
24/// - 8 for sequence range
25/// - 4 for first request offset
26/// - 4 for sequence number
27/// - 1 for single acks count
28/// - 4 * 1 for at least one single acks
29/// - 4 for cumulative ack
30/// - 8 for indexed channel (not yet supported in sync data/state)
31/// - 4 for checksum
32pub const PACKET_MAX_FOOTER_LEN: usize = 8 + 4 + 4 + 1 + 4 + 4 + 8 + 4;
33
34/// The theoretical maximum length for the body, if maximum length is used by header + footer.
35pub const PACKET_MAX_BODY_LEN: usize = PACKET_MAX_LEN - PACKET_MIN_LEN - PACKET_MAX_FOOTER_LEN;
36
37
38/// Raw packet layout with only data and length. This structure provides functions for
39/// growing and shrinking data, retrieving and modifying its length. Other states such
40/// are footer offset or first request offset are not saved in this structure, because
41/// this structure is intended to be used as backend of the [`Packet`] structure which
42/// contains such state.
43///
44/// The internal data is split in multiple slices that are accessible through the API:
45///
46/// - *Raw data*, it contains the full internal data with max data length, this should
47/// be used for receiving datagram from the network;
48///
49/// - *Data*, it contains all the data up to the packet's length;
50///
51/// - *Body*, it contains all the data starting with the packet's flags up to the
52/// packet's length.
53///
54#[derive(Clone)]
55pub struct RawPacket {
56 /// Full raw data of the packet.
57 data: [u8; PACKET_MAX_LEN],
58 /// Length of the packet, must not be lower than minimum length which
59 /// contains the prefix and the flags.
60 len: usize,
61}
62
63impl RawPacket {
64
65 #[inline]
66 pub fn new() -> Self {
67 Self {
68 data: [0; PACKET_MAX_LEN],
69 len: PACKET_MIN_LEN,
70 }
71 }
72
73 /// Get a slice to the full raw data, this means that this isn't
74 /// constrained by the length of the packet.
75 #[inline]
76 pub fn raw_data(&self) -> &[u8] {
77 &self.data[..]
78 }
79
80 /// Get a mutable slice to the full raw data, this means that this isn't
81 /// constrained by the length of the packet.
82 ///
83 /// This mutable slice can be used to receive data from an UDP datagram.
84 #[inline]
85 pub fn raw_data_mut(&mut self) -> &mut [u8] {
86 &mut self.data[..]
87 }
88
89 /// Return the maximum size of a packet.
90 #[inline]
91 pub fn data_max_len(&self) -> usize {
92 self.data.len()
93 }
94
95 /// Return the length of this packet.
96 #[inline]
97 pub fn data_len(&self) -> usize {
98 self.len
99 }
100
101 /// Return the available length in this packet.
102 #[inline]
103 pub fn data_available_len(&self) -> usize {
104 self.data_max_len() - self.data_len()
105 }
106
107 /// Set the length of this packet. The function panics if the length
108 /// is not at least `PACKET_MIN_LEN` or at most `PACKET_MAX_LEN`.
109 #[inline]
110 pub fn set_data_len(&mut self, len: usize) {
111 assert!(len >= PACKET_MIN_LEN, "given length too small");
112 assert!(len <= PACKET_MAX_LEN, "given length too high");
113 self.len = len;
114 }
115
116 /// Get a slice to the data, with the packet's length.
117 ///
118 /// This slice can be used to send data as an UDP datagram for exemple.
119 #[inline]
120 pub fn data(&self) -> &[u8] {
121 &self.data[..self.len]
122 }
123
124 /// Get a mutable slice to the data, with the packet's length.
125 #[inline]
126 pub fn data_mut(&mut self) -> &mut [u8] {
127 &mut self.data[..self.len]
128 }
129
130 /// Return the maximum size of the body of a packet.
131 #[inline]
132 pub fn max_body_len(&self) -> usize {
133 self.data_max_len() - PACKET_PREFIX_LEN
134 }
135
136 /// Return the length of this packet.
137 #[inline]
138 pub fn body_len(&self) -> usize {
139 self.data_len() - PACKET_PREFIX_LEN
140 }
141
142 /// Get a slice to the data from after the prefix to the end.
143 #[inline]
144 pub fn body(&self) -> &[u8] {
145 &self.data[PACKET_PREFIX_LEN..self.len]
146 }
147
148 /// Get a mutable slice to the data from after the prefix to the end.
149 #[inline]
150 pub fn body_mut(&mut self) -> &mut [u8] {
151 &mut self.data[PACKET_PREFIX_LEN..self.len]
152 }
153
154 /// Reset this packet's length, flags and prefix.
155 #[inline]
156 pub fn reset(&mut self) {
157 self.len = PACKET_MIN_LEN;
158 self.data[..PACKET_MIN_LEN].fill(0);
159 }
160
161 /// Grow the packet's data by a given amount of bytes, and return a
162 /// mutable slice to the newly allocated data.
163 ///
164 /// This function panics if the available length is smaller than
165 /// requested length.
166 #[inline]
167 pub fn grow(&mut self, len: usize) -> &mut [u8] {
168 assert!(self.data_available_len() >= len, "not enough available data");
169 let ptr = &mut self.data[self.len..][..len];
170 self.len += len;
171 ptr
172 }
173
174 /// Grow the packet's data by a given amount of bytes, and return
175 /// a writer to the given data. This writer can be used to write
176 /// new data to the newly allocated data.
177 ///
178 /// This function panics if the available length is smaller than
179 /// requested length.
180 #[inline]
181 pub fn grow_write(&mut self, len: usize) -> impl Write + Seek + '_ {
182 Cursor::new(self.grow(len))
183 }
184
185 /// Shrink the packet's data by a given amount of bytes, and return
186 /// a slice to the deallocated data. The slice is not mutable because
187 /// returned data is no longer contained in packet's data.
188 ///
189 /// The discarded data is left untouched, which mean that you can
190 /// rollback to the previous length to recover the data.
191 ///
192 /// This function panics if the length after shrink is lower than
193 /// prefix (4 bytes) + flags (2) bytes.
194 #[inline]
195 pub fn shrink(&mut self, len: usize) -> &[u8] {
196 assert!(self.len - len >= PACKET_MIN_LEN, "not enough data to shrink");
197 self.len -= len;
198 &self.data[self.len..][..len]
199 }
200
201 /// Shrink the packet's data by a given amount of bytes, and return
202 /// a reader to the freed data.
203 ///
204 /// This function panics if the length after shrink is lower than
205 /// prefix (4 bytes) + flags (2) bytes.
206 #[inline]
207 pub fn shrink_read(&mut self, len: usize) -> impl Read + '_ {
208 Cursor::new(self.shrink(len))
209 }
210
211 /// Read the prefix of this packet.
212 #[inline]
213 pub fn read_prefix(&self) -> u32 {
214 u32::from_le_bytes(self.data[..PACKET_PREFIX_LEN].try_into().unwrap())
215 }
216
217 /// Write the prefix of this packet.
218 #[inline]
219 pub fn write_prefix(&mut self, prefix: u32) {
220 self.data[..PACKET_PREFIX_LEN].copy_from_slice(&prefix.to_le_bytes())
221 }
222
223 /// Read the flags of this packet.
224 #[inline]
225 pub fn read_flags(&self) -> u16 {
226 u16::from_le_bytes(self.data[PACKET_PREFIX_LEN..][..PACKET_FLAGS_LEN].try_into().unwrap())
227 }
228
229 /// Write the flags of this packet.
230 #[inline]
231 pub fn write_flags(&mut self, flags: u16) {
232 self.data[PACKET_PREFIX_LEN..][..PACKET_FLAGS_LEN].copy_from_slice(&flags.to_le_bytes())
233 }
234
235}
236
237impl fmt::Debug for RawPacket {
238 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
239 f.debug_struct("RawPacket")
240 .field("raw_data", &format_args!("{:X}", BytesFmt(self.raw_data())))
241 .field("data", &format_args!("{:X}", BytesFmt(self.data())))
242 .field("len", &self.len)
243 .finish()
244 }
245}
246
247
248/// Represent a [`RawPacket`] with additional state. The additional state keeps
249/// track of different offsets in the packet's raw data. Like footer and first
250/// request element offsets. This structure also provides functions for
251/// synchronizing data from the state and vice-versa.
252///
253/// This structure only expose a single slice of data which contain the content
254/// data, starting after the flags and ending before the footer. To access more
255/// low-level slices you can should use the raw packet.
256#[derive(Clone)]
257pub struct Packet {
258 /// The internal raw packet used for data manipulation.
259 raw: RawPacket,
260 /// Offset of the footer when the packet is finalized or loaded. The footer
261 /// size if the difference between the raw packet's length and this footer
262 /// offset.
263 footer_offset: usize,
264 /// The offset of the first element (see bundle) that is also a request in
265 /// the packet. If there are more requests in the packet, their offset is
266 /// written in a link manner in the N-1 element.
267 first_request_offset: usize,
268}
269
270impl Packet {
271
272 /// Create a new packet instance.
273 #[inline]
274 pub fn new() -> Self {
275 Self {
276 raw: RawPacket::new(),
277 footer_offset: PACKET_MIN_LEN,
278 first_request_offset: 0,
279 }
280 }
281
282 /// Create a new packet instance on the heap and returns the box containing it.
283 pub fn new_boxed() -> Box<Self> {
284 Box::new(Self::new())
285 }
286
287 /// Return a shared reference to the internal raw packet.
288 #[inline]
289 pub fn raw(&self) -> &RawPacket {
290 &self.raw
291 }
292
293 /// Return a mutable reference to the internal raw packet.
294 ///
295 /// **You should** be really careful when manipulating the internal data and
296 /// always prefer using methods of this structure over manipulating the raw
297 /// data from external modules.
298 #[inline]
299 pub fn raw_mut(&mut self) -> &mut RawPacket {
300 &mut self.raw
301 }
302
303 /// Return the maximum content length.
304 #[inline]
305 pub fn content_max_len(&self) -> usize {
306 // Subtract length of prefix + flags + max footer.
307 self.raw.data_max_len() - PACKET_MIN_LEN - PACKET_MAX_FOOTER_LEN
308 }
309
310 /// Return the length of the content.
311 #[inline]
312 pub fn content_len(&self) -> usize {
313 self.footer_offset - PACKET_MIN_LEN
314 }
315
316 /// Return the available body length for writing elements. The rest of the
317 /// length might be used for the footer.
318 #[inline]
319 pub fn content_available_len(&self) -> usize {
320 self.content_max_len() - self.content_len()
321 }
322
323 /// Return a slice to the content of this packet. The content starts after
324 /// the flags and finish before the footer.
325 #[inline]
326 pub fn content(&self) -> &[u8] {
327 &self.raw.raw_data()[PACKET_MIN_LEN..self.footer_offset]
328 }
329
330 /// Return a mutable slice to the content of this packet. The content starts
331 /// after the flags and finish before the footer.
332 #[inline]
333 pub fn content_mut(&mut self) -> &mut [u8] {
334 &mut self.raw.raw_data_mut()[PACKET_MIN_LEN..self.footer_offset]
335 }
336
337 /// Grow this packet's content by the given size. You must ensure that there
338 /// is enough space for such size, you can obtain remaining length using the
339 /// `content_available_len` function.
340 ///
341 /// Note that because growing the body might overwrite the footer, this
342 /// function reset the footer to zero length. Calling `footer_len()` after
343 /// this function returns 0.
344 #[inline]
345 pub fn grow(&mut self, len: usize) -> &mut [u8] {
346 assert!(self.content_available_len() >= len, "not enough available data");
347 // Reset length to footer offset, so we overwrite the footer.
348 self.raw.set_data_len(self.footer_offset);
349 // Advance the footer by the same amount raw.grow will do.
350 self.footer_offset += len;
351 // Grow should not panic because we checked available length.
352 self.raw.grow(len)
353 }
354
355 /// Grow this packet's content by the given size and return a writer to the
356 /// location to write. See `grow` function for more information.
357 #[inline]
358 pub fn grow_write(&mut self, len: usize) -> impl Write + '_ {
359 Cursor::new(self.grow(len))
360 }
361
362 /// Return the length of the footer. It should not exceed `PACKET_MAX_FOOTER_LEN`.
363 #[inline]
364 pub fn footer_len(&self) -> usize {
365 self.raw.data_len() - self.footer_offset
366 }
367
368 /// Return the available length remaining in the footer.
369 #[inline]
370 pub fn footer_available_len(&self) -> usize {
371 PACKET_MAX_FOOTER_LEN - self.footer_len()
372 }
373
374 /// Return the offset of the next request element in this packet. Because
375 /// this offset cannot be equal to 0 or 1 (which points to packet's flags),
376 /// such values are sentinels that fill returns `None`.
377 #[inline]
378 pub fn first_request_offset(&self) -> Option<usize> {
379 (self.first_request_offset >= PACKET_FLAGS_LEN).then_some(self.first_request_offset)
380 }
381
382 /// Set the first offset of the next request element in this packet. Refer
383 /// to `first_request_offset` function for limitations.
384 #[inline]
385 pub fn set_first_request_offset(&mut self, offset: usize) {
386 assert!(offset >= PACKET_FLAGS_LEN, "invalid request offset");
387 self.first_request_offset = offset;
388 }
389
390 /// Clear the first request offset.
391 #[inline]
392 pub fn clear_first_request_offset(&mut self) {
393 self.first_request_offset = 0;
394 }
395
396 /// Write the given configuration to this packet's flags and footer. This function
397 /// takes a configuration that will be applied to the packet, the configuration must
398 /// be mutable because the function will try to put the maximum number of
399 /// acks in the footer, the remaining acks will be left over in the config.
400 pub fn write_config(&mut self, config: &mut PacketConfig) {
401
402 // If the footer is already filled
403 if self.footer_offset < self.raw.data_len() {
404 self.raw.set_data_len(self.footer_offset);
405 }
406
407 // Note that in this function we are intentionally using the function
408 // 'self.raw.grow[_write]'. This will cause the raw length to grow
409 // without the footer offset, which will increase the footer length.
410
411 let mut flags = 0u16;
412
413 if config.reliable() { flags |= flags::IS_RELIABLE; }
414 if config.on_channel() { flags |= flags::ON_CHANNEL; }
415
416 if let Some((first_num, last_num)) = config.sequence_range() {
417 flags |= flags::IS_FRAGMENT;
418 let mut cursor = self.raw.grow_write(8);
419 cursor.write_u32::<LE>(first_num).unwrap();
420 cursor.write_u32::<LE>(last_num).unwrap();
421 }
422
423 if let Some(request_offset) = self.first_request_offset() {
424 flags |= flags::HAS_REQUESTS;
425 self.raw.grow_write(2).write_u16::<LE>(request_offset as u16).unwrap();
426 }
427
428 if let Some(val) = config.unk_1000() {
429 flags |= flags::UNK_1000;
430 self.raw.grow_write(4).write_u32::<LE>(val).unwrap();
431 }
432
433 if config.reliable() || config.sequence_range().is_some() {
434 flags |= flags::HAS_SEQUENCE_NUMBER;
435 self.raw.grow_write(4).write_u32::<LE>(config.sequence_num()).unwrap();
436 }
437
438 if !config.single_acks().is_empty() {
439
440 flags |= flags::HAS_ACKS;
441
442 // Compute the remaining footer length for acks.
443 let available_len = self.footer_available_len()
444 - if config.cumulative_ack().is_some() { 4 } else { 0 }
445 - if config.indexed_channel().is_some() { 8 } else { 0 }
446 - if config.has_checksum() { 4 } else { 0 }
447 - 1; // Acks count
448
449 let mut count = 0;
450 while let Some(ack) = config.single_acks_mut().pop_front() {
451 if available_len < 4 {
452 break
453 } else {
454 self.raw.grow_write(4).write_u32::<LE>(ack).unwrap();
455 count += 1;
456 }
457 }
458
459 debug_assert!(count != 0);
460 self.raw.grow(1)[0] = count as _;
461
462 }
463
464 if let Some(num) = config.cumulative_ack() {
465 flags |= flags::HAS_CUMULATIVE_ACK;
466 self.raw.grow_write(4).write_u32::<LE>(num).unwrap();
467 }
468
469 if let Some((id, version)) = config.indexed_channel() {
470 flags |= flags::INDEXED_CHANNEL;
471 let mut cursor = self.raw.grow_write(8);
472 cursor.write_u32::<LE>(version).unwrap();
473 cursor.write_u32::<LE>(id).unwrap();
474 }
475
476 if config.has_checksum() {
477 flags |= flags::HAS_CHECKSUM;
478 }
479
480 // Finally, write flags just before computing checksum (if needed).
481 self.raw.write_flags(flags);
482
483 // If checksum enabled, compute the checksum of the whole body of the packet,
484 // which range from flags to the end of the footer. The checksum will be
485 // appended to the footer after computing the checksum.
486 if config.has_checksum() {
487 let checksum = calc_checksum(Cursor::new(self.raw.body()));
488 self.raw.grow_write(4).write_u32::<LE>(checksum).unwrap();
489 }
490
491 }
492
493 /// Read the configuration from this packet's flags and footer.
494 ///
495 /// *Note that* the given length must account for the prefix.
496 ///
497 /// *If this function returns an error, the integrity of the configuration is not
498 /// guaranteed.*
499 pub fn read_config(&mut self, len: usize, config: &mut PacketConfig) -> Result<(), PacketConfigError> {
500
501 // We set the length of the raw packet, it allow us to use
502 // 'shrink_read' on it to read each footer element.
503 self.raw.set_data_len(len);
504
505 // Start by reading flags.
506 let flags = self.raw.read_flags();
507
508 // This list of flags contains all flags supported by this function.
509 const KNOWN_FLAGS: u16 =
510 flags::HAS_CHECKSUM |
511 flags::INDEXED_CHANNEL |
512 flags::HAS_CUMULATIVE_ACK |
513 flags::HAS_ACKS |
514 flags::HAS_SEQUENCE_NUMBER |
515 flags::UNK_1000 |
516 flags::HAS_REQUESTS |
517 flags::IS_FRAGMENT |
518 flags::ON_CHANNEL |
519 flags::IS_RELIABLE;
520
521 if flags & !KNOWN_FLAGS != 0 {
522 return Err(PacketConfigError::UnknownFlags(flags & !KNOWN_FLAGS));
523 }
524
525 if flags & flags::HAS_CHECKSUM != 0 {
526
527 // We shrink the packet to read the checksum and then compute the checksum
528 // from the body data, which no longer contains the checksum itself!
529 let expected_checksum = self.raw.shrink_read(4).read_u32::<LE>().unwrap();
530 let computed_checksum = calc_checksum(Cursor::new(self.raw.body()));
531
532 if expected_checksum != computed_checksum {
533 return Err(PacketConfigError::InvalidChecksum)
534 }
535
536 }
537
538 if flags & flags::INDEXED_CHANNEL != 0 {
539 let mut cursor = self.raw.shrink_read(8);
540 let version = cursor.read_u32::<LE>().unwrap();
541 let id = cursor.read_u32::<LE>().unwrap();
542 config.set_indexed_channel(id, version);
543 } else {
544 config.clear_indexed_channel();
545 }
546
547 if flags & flags::HAS_CUMULATIVE_ACK != 0 {
548 config.set_cumulative_ack(self.raw.shrink_read(4).read_u32::<LE>().unwrap());
549 } else {
550 config.clear_cumulative_ack();
551 }
552
553 if flags & flags::HAS_ACKS != 0 {
554
555 let count = self.raw.shrink(1)[0];
556 if count == 0 {
557 return Err(PacketConfigError::Corrupted)
558 }
559
560 for _ in 0..count {
561 config.single_acks_mut().push_back(self.raw.shrink_read(4).read_u32::<LE>().unwrap());
562 }
563
564 }
565
566 // let mut has_sequence_num = false;
567 if flags & flags::HAS_SEQUENCE_NUMBER != 0 {
568 config.set_sequence_num(self.raw.shrink_read(4).read_u32::<LE>().unwrap());
569 } else {
570 config.set_sequence_num(0);
571 }
572
573 if flags & flags::UNK_1000 != 0 {
574 config.set_unk_1000(self.raw.shrink_read(4).read_u32::<LE>().unwrap());
575 } else {
576 config.clear_unk_1000();
577 }
578
579 if flags & flags::HAS_REQUESTS != 0 {
580 let offset = self.raw.shrink_read(2).read_u16::<LE>().unwrap() as usize;
581 if offset < PACKET_FLAGS_LEN {
582 return Err(PacketConfigError::Corrupted)
583 } else {
584 self.set_first_request_offset(offset);
585 }
586 } else {
587 self.clear_first_request_offset();
588 }
589
590 if flags & flags::IS_FRAGMENT != 0 {
591 let mut cursor = self.raw.shrink_read(8);
592 let first_num = cursor.read_u32::<LE>().unwrap();
593 let last_num = cursor.read_u32::<LE>().unwrap();
594 if first_num >= last_num {
595 return Err(PacketConfigError::Corrupted)
596 } else {
597 config.set_sequence_range(first_num, last_num);
598 }
599 } else {
600 config.clear_sequence_range();
601 }
602
603 config.set_reliable(flags & flags::IS_RELIABLE != 0);
604 config.set_on_channel(flags & flags::ON_CHANNEL != 0);
605
606 // Now that we shrunk all the footer, set the footer offset.
607 self.footer_offset = self.raw.data_len();
608 // Rollback the length.
609 self.raw.set_data_len(len);
610
611 // Check that the footer length is coherent.
612 debug_assert!(self.footer_len() <= PACKET_MAX_FOOTER_LEN);
613
614 Ok(())
615
616 }
617
618}
619
620impl fmt::Debug for Packet {
621 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
622 f.debug_struct("Packet")
623 .field("content", &format_args!("{:X}", BytesFmt(self.content())))
624 .field("content_len", &self.content_len())
625 .field("footer_len", &self.footer_len())
626 .field("first_request_offset", &self.first_request_offset())
627 .finish()
628 }
629}
630
631
632/// Describe a packet configuration that can be used when synchronizing data or
633/// state of a packet.
634#[derive(Debug, Clone)]
635pub struct PacketConfig {
636 /// The sequence number of this packet, it is used if reliable mode is enabled
637 /// **and/or** if the packet is a fragment of a chain of packet.
638 sequence_num: u32,
639 /// If this packet is a fragment (defined just after), this contains the
640 /// sequence number of the first packet in the chain.
641 ///
642 /// A packet is considered to be a fragment of a chain only if `seq_first <
643 /// seq_last`.
644 sequence_first_num: u32,
645 /// If this packet is a fragment (defined in `seq_first` doc), this contains
646 /// the sequence number of the last packet in the chain.
647 sequence_last_num: u32,
648 /// Set to true if the sender of this packet requires an acknowledgment from
649 /// the receiver upon successful receipt of this packet.
650 reliable: bool,
651 /// The cumulative ack number. This number is sent for acknowledging that
652 /// all sequence numbers up to (but excluding) this ack have been received.
653 ///
654 /// The cumulative ack 0 is apparently used when opening a channel.
655 cumulative_ack: Option<u32>,
656 /// Individual acks to send.
657 single_acks: VecDeque<u32>,
658 /// Set to true when this packet is being transferred on a channel.
659 on_channel: bool,
660 /// Indexed channel is a combination of the channel id and version.
661 indexed_channel: Option<(u32, u32)>,
662 /// Enable or disable checksum.
663 has_checksum: bool,
664 /// The usage of this value and flag 0x1000 is unknown. It will be
665 /// renamed in the future if its purpose is discovered.
666 unk_1000: Option<u32>,
667}
668
669impl PacketConfig {
670
671 /// Create a new packet configuration with default values.
672 #[inline]
673 pub fn new() -> Self {
674 Self {
675 sequence_num: 0,
676 sequence_first_num: 0,
677 sequence_last_num: 0,
678 reliable: false,
679 cumulative_ack: None,
680 single_acks: VecDeque::new(),
681 on_channel: false,
682 indexed_channel: None,
683 has_checksum: false,
684 unk_1000: None,
685 }
686 }
687
688 /// Returns the sequence number of this packet. It is actually used only if
689 /// this packet is marked as reliable **and/or** if the packet is a fragment.
690 ///
691 /// It is set to 0 by default.
692 #[inline]
693 pub fn sequence_num(&self) -> u32 {
694 self.sequence_num
695 }
696
697 /// Set the sequence number of this packet. Read `sequence_num` doc for
698 /// explanation of the usage of the sequence number.
699 #[inline]
700 pub fn set_sequence_num(&mut self, num: u32) {
701 self.sequence_num = num;
702 }
703
704 /// Returns the range of sequence number in case this packet is a fragment
705 /// of a packet chain. Both bounds are included.
706 #[inline]
707 pub fn sequence_range(&self) -> Option<(u32, u32)> {
708 if self.sequence_first_num < self.sequence_last_num {
709 Some((self.sequence_first_num, self.sequence_last_num))
710 } else {
711 None
712 }
713 }
714
715 /// Set the range of sequence number if this packet is a fragment of a
716 /// packet chain. Both bounds are included and `last` should be greater
717 /// than `first`, this function panics if this condition is not met.
718 ///
719 /// See also `clear_sequence_range` if you want to clear the range.
720 ///
721 /// *Note that* the sequence number is not checked to be in bounds.
722 #[inline]
723 pub fn set_sequence_range(&mut self, first: u32, last: u32) {
724 assert!(first < last, "invalid range");
725 self.sequence_first_num = first;
726 self.sequence_last_num = last;
727 }
728
729 /// Clear the range of sequence number. After calling this, the packet
730 /// is no longer a fragment in a packet chain.
731 #[inline]
732 pub fn clear_sequence_range(&mut self) {
733 self.sequence_first_num = 0;
734 self.sequence_last_num = 0;
735 }
736
737 /// Returns true if the sender of this packet requires an acknowledgment from
738 /// the receiver upon successful receipt of this packet.
739 #[inline]
740 pub fn reliable(&self) -> bool {
741 self.reliable
742 }
743
744 /// Read `reliable` doc for explanation of this value.
745 #[inline]
746 pub fn set_reliable(&mut self, reliable: bool) {
747 self.reliable = reliable
748 }
749
750 /// This number is sent for acknowledging that all sequence numbers up to (but
751 /// excluding) this ack have been received.
752 #[inline]
753 pub fn cumulative_ack(&self) -> Option<u32> {
754 self.cumulative_ack
755 }
756
757 /// Set the cumulative ack if this packet. Because this value is an excluded
758 /// bound, you should not set this to 0. If you want to reset the cumulative
759 /// ack, use `clear_cumulative_ack` instead.
760 #[inline]
761 pub fn set_cumulative_ack(&mut self, num: u32) {
762 assert_ne!(num, 0, "cumulative ack is exclusive so it cannot be zero");
763 self.cumulative_ack = Some(num);
764 }
765
766 /// Clear the cumulative ack from this packet.
767 #[inline]
768 pub fn clear_cumulative_ack(&mut self) {
769 self.cumulative_ack = None;
770 }
771
772 #[inline]
773 pub fn single_acks(&self) -> &VecDeque<u32> {
774 &self.single_acks
775 }
776
777 #[inline]
778 pub fn single_acks_mut(&mut self) -> &mut VecDeque<u32> {
779 &mut self.single_acks
780 }
781
782 #[inline]
783 pub fn on_channel(&self) -> bool {
784 self.on_channel
785 }
786
787 /// Return the indexed channel, if existing, using tuple `(id, version)`.
788 #[inline]
789 pub fn indexed_channel(&self) -> Option<(u32, u32)> {
790 self.indexed_channel
791 }
792
793 #[inline]
794 pub fn set_indexed_channel(&mut self, id: u32, version: u32) {
795 self.indexed_channel = Some((id, version))
796 }
797
798 #[inline]
799 pub fn clear_indexed_channel(&mut self) {
800 self.indexed_channel = None;
801 }
802
803 #[inline]
804 pub fn set_on_channel(&mut self, on_channel: bool) {
805 self.on_channel = on_channel;
806 }
807
808 #[inline]
809 pub fn has_checksum(&self) -> bool {
810 self.has_checksum
811 }
812
813 #[inline]
814 pub fn set_checksum(&mut self, enabled: bool) {
815 self.has_checksum = enabled;
816 }
817
818 /// The usage of this value and flag 0x1000 is unknown. It will be
819 /// renamed in the future if its purpose is discovered.
820 #[inline]
821 pub fn unk_1000(&self) -> Option<u32> {
822 self.unk_1000
823 }
824
825 /// The usage of this value and flag 0x1000 is unknown. It will be
826 /// renamed in the future if its purpose is discovered.
827 #[inline]
828 pub fn set_unk_1000(&mut self, val: u32) {
829 self.unk_1000 = Some(val);
830 }
831
832 /// The usage of this value and flag 0x1000 is unknown. It will be
833 /// renamed in the future if its purpose is discovered.
834 #[inline]
835 pub fn clear_unk_1000(&mut self) {
836 self.unk_1000 = None;
837 }
838
839}
840
841
842/// Generic function to calculate the checksum from a reader and
843/// a given number of bytes available.
844fn calc_checksum(mut reader: impl Read) -> u32 {
845 let mut checksum = 0;
846 while let Ok(num) = reader.read_u32::<LE>() {
847 checksum ^= num;
848 }
849 checksum
850}
851
852
853/// Internal module defining flags for packets.
854#[allow(unused)]
855mod flags {
856 pub const HAS_REQUESTS: u16 = 0x0001;
857 pub const HAS_PIGGYBACKS: u16 = 0x0002;
858 pub const HAS_ACKS: u16 = 0x0004;
859 pub const ON_CHANNEL: u16 = 0x0008;
860 pub const IS_RELIABLE: u16 = 0x0010;
861 pub const IS_FRAGMENT: u16 = 0x0020;
862 pub const HAS_SEQUENCE_NUMBER: u16 = 0x0040;
863 pub const INDEXED_CHANNEL: u16 = 0x0080;
864 pub const HAS_CHECKSUM: u16 = 0x0100;
865 pub const CREATE_CHANNEL: u16 = 0x0200;
866 pub const HAS_CUMULATIVE_ACK: u16 = 0x0400;
867 pub const UNK_0800: u16 = 0x0800;
868 pub const UNK_1000: u16 = 0x1000;
869}
870
871
872/// Packet error when reading invalid config from a packet.
873#[derive(Debug, Clone, thiserror::Error)]
874pub enum PacketConfigError {
875 /// Unknown flags are used, the packet can't be decoded because this usually
876 /// increase length of the footer.
877 #[error("unknown flags: {0:04X}")]
878 UnknownFlags(u16),
879 /// The packet is corrupted, the footer might be too short or an invalid bit
880 /// pattern has been read.
881 #[error("corrupted")]
882 Corrupted,
883 /// The packet checksum and calculated checksum aren't equal.
884 #[error("invalid checksum")]
885 InvalidChecksum
886}