nardol/packet/
mod.rs

1mod packet_kind;
2
3use serde::{Deserialize, Serialize};
4
5use itertools::Itertools;
6
7use std::io::{Read, Write};
8use std::net::{SocketAddr, TcpStream, ToSocketAddrs, UdpSocket};
9use std::sync::atomic::{AtomicU16, Ordering};
10
11use crate::bytes::Bytes;
12use crate::error::{Error, ErrorKind};
13use crate::ron::{FromRon, ToRon};
14
15pub use packet_kind::PacketKind;
16
17/// For information go to [Packet::description_size].
18const PACKET_DESCRIPTION_SIZE: u16 = 4;
19
20/// For information go to [Packet::max_size].
21static mut MAX_PACKET_SIZE: AtomicU16 = AtomicU16::new(1024);
22
23/// Gives structure to data to be sent or received from `stream`.
24///
25/// [Packet] is the lowest abstraction above buffer in this library.
26///
27/// # Fields
28///
29/// * `size` -- size of the whole [packet](Packet) in number of bytes.
30/// It is [u16] so that packet can not have size over [u16::MAX]
31/// * `kind` -- [kind](PacketKind) of [packet](Packet).
32/// * `content` -- data stored in the [packet](Packet).
33#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
34pub struct Packet {
35    size: u16,
36    kind: PacketKind,
37    content: Bytes,
38}
39
40impl ToRon for Packet {}
41impl FromRon<'_> for Packet {}
42
43impl Default for Packet {
44    fn default() -> Self {
45        Packet {
46            size: Packet::description_size(),
47            kind: PacketKind::Empty,
48            content: Bytes::empty(),
49        }
50    }
51}
52
53impl TryFrom<Bytes> for Packet {
54    type Error = Error;
55
56    fn try_from(value: Bytes) -> Result<Self, Self::Error> {
57        // Checks if value has enough bytes to parse to Packet
58        // (at least 4 for packet with no content).
59        if value
60            .get((Packet::description_size() - 1) as usize)
61            .is_none()
62        {
63            return Err(Error::new(
64                ErrorKind::InvalidBufferSize,
65                Some(
66                    "impl TryFrom<Bytes> for Packet requires buffer of length of at least 4 bytes."
67                        .to_string(),
68                ),
69            ));
70        }
71
72        let size = value.len();
73        // Starts at 2 because size field takes 2 bytes in buffer.
74        let kind = PacketKind::try_from(&value[2..4])?;
75        let content = value[4..size].to_vec();
76
77        Ok(Packet {
78            size: size as u16,
79            kind,
80            content: content.into(),
81        })
82    }
83}
84
85impl TryFrom<&Bytes> for Packet {
86    type Error = Error;
87
88    fn try_from(value: &Bytes) -> Result<Self, Self::Error> {
89        // Checks if value has enough bytes to parse to Packet
90        // (at least 4 for packet with no content).
91        if value
92            .get((Packet::description_size() - 1) as usize)
93            .is_none()
94        {
95            return Err(Error::new(
96                ErrorKind::InvalidBufferSize,
97                Some(
98                    "impl TryFrom<Bytes> for Packet requires buffer of length of at least 4 bytes."
99                        .to_string(),
100                ),
101            ));
102        }
103
104        let size = value.len();
105        // Starts at 2 because size field takes 2 bytes in buffer.
106        let kind = PacketKind::try_from(&value[2..4])?;
107        let content = value[4..size].to_vec();
108
109        Ok(Packet {
110            size: size as u16,
111            kind,
112            content: content.into(),
113        })
114    }
115}
116
117impl TryFrom<&[u8]> for Packet {
118    type Error = Error;
119
120    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
121        // Checks if value has enough bytes to parse to Packet
122        // (at least 4 for packet with no content).
123        if value
124            .get((Packet::description_size() - 1) as usize)
125            .is_none()
126        {
127            return Err(Error::new(
128                ErrorKind::InvalidBufferSize,
129                Some(
130                    "impl TryFrom<Bytes> for Packet requires buffer of length of at least 4 bytes."
131                        .to_string(),
132                ),
133            ));
134        }
135
136        let size = value.len();
137        // Starts at 2 because size field takes 2 bytes in buffer.
138        let kind = PacketKind::try_from(&value[2..4])?;
139        let content = value[4..size].to_vec();
140
141        Ok(Packet {
142            size: size as u16,
143            kind,
144            content: content.into(),
145        })
146    }
147}
148
149impl From<Packet> for Bytes {
150    fn from(mut value: Packet) -> Self {
151        let mut bytes = Bytes::empty();
152
153        bytes.append(&mut value.size.into());
154        bytes.append(&mut value.kind.into());
155        bytes.append(&mut value.content);
156
157        bytes
158    }
159}
160
161impl Packet {
162    /// Creates a new [Packet].
163    ///
164    /// Returns an [Error] if created packet would be bigger than
165    /// [`MAX_PACKET_SIZE`](Packet::max_size).
166    ///
167    /// To avoid this check, use [Packet::new_unchecked].
168    ///
169    /// Size of packet is derived from `content`.
170    ///
171    /// # Examples
172    /// Content packet is created like that.
173    /// ```
174    /// # use nardol::packet::{Packet, PacketKind};
175    /// # use nardol::bytes::Bytes;
176    /// # fn packet_new_doc_test() -> Result<(), nardol::error::Error> {
177    /// #   
178    ///     let packet = Packet::new(PacketKind::End, Bytes::from([1_u8, 2_u8]))?;
179    /// #   Ok(())
180    /// # }
181    /// ```
182    pub fn new(kind: PacketKind, content: Bytes) -> Result<Self, Error> {
183        // Size is composed of three parts:
184        // Size of size field which is always 2.
185        // Size of PacketKind which is always 2.
186        // Size of content.
187        let size = Packet::description_size() + content.len() as u16;
188
189        if size > Packet::max_size() {
190            return Err(Error::new(
191                ErrorKind::TooBigPacket,
192                Some("Created Packet would be bigger than MAX_PACKET_SIZE.".to_string()),
193            ));
194        }
195
196        Ok(Packet {
197            size: size as u16,
198            kind,
199            content,
200        })
201    }
202
203    /// Creates a new [Packet] without checking if resulting packet size is not bigger than
204    /// [`MAX_PACKET_SIZE`](Packet::max_size).
205    ///
206    /// Size of packet is derived from `content`.
207    pub fn new_unchecked(kind: PacketKind, content: Bytes) -> Self {
208        // Size is composed of three parts:
209        // Size of size field which is always 2.
210        // Size of PacketKind which is always 2.
211        // Size of content.
212        let size = Packet::description_size() + content.len() as u16;
213
214        Packet {
215            size: size as u16,
216            kind,
217            content,
218        }
219    }
220
221    /// Sends `self` via `stream`.
222    ///
223    /// This takes ownership of `self`.
224    pub fn send(self, stream: &mut TcpStream) -> Result<(), Error> {
225        let packet_bytes: Bytes = self.into();
226        let packet_buff = packet_bytes.as_slice();
227
228        if let Err(e) = stream.write(packet_buff) {
229            let packet = Packet::try_from(packet_buff)?;
230            return Err(Error::new(
231                ErrorKind::WritingToStreamFailed,
232                Some(format!(
233                    "Failed to write packet to stream.\n{}\n{}",
234                    packet.to_ron_pretty(None)?,
235                    e,
236                )),
237            ));
238        }
239
240        Ok(())
241    }
242
243    /// Sends `self` to given `address` on [UdpSocket].
244    ///
245    /// This takes ownership of `self`.
246    pub fn send_to<A>(self, socket: UdpSocket, address: A) -> Result<(), Error>
247    where
248        A: ToSocketAddrs,
249    {
250        let packet_bytes: Bytes = self.into();
251        let packet_buff = packet_bytes.as_slice();
252
253        if let Err(e) = socket.send_to(packet_buff, address) {
254            let packet = Packet::try_from(packet_buff)?;
255            return Err(Error::new(
256                ErrorKind::SendingToAddressFailed,
257                Some(format!(
258                    "Failed to send packet to address.\n{}\n{}",
259                    packet.to_ron_pretty(None)?,
260                    e,
261                )),
262            ));
263        }
264
265        Ok(())
266    }
267
268    /// Sends `self` to connected [UdpSocket].
269    ///
270    /// This takes ownership of `self`.
271    pub fn send_to_connected(self, socket: UdpSocket) -> Result<(), Error> {
272        let packet_bytes: Bytes = self.into();
273        let packet_buff = packet_bytes.as_slice();
274
275        if let Err(e) = socket.send(packet_buff) {
276            let packet = Packet::try_from(packet_buff)?;
277            return Err(Error::new(
278                ErrorKind::SendingToAddressFailed,
279                Some(format!(
280                    "Failed to send packet to connected socket.\n{}\n{}",
281                    packet.to_ron_pretty(None)?,
282                    e,
283                )),
284            ));
285        }
286
287        Ok(())
288    }
289
290    /// Receives a [Packet] from [`stream`][TcpStream].
291    pub fn receive(stream: &mut TcpStream) -> Result<Packet, Error> {
292        // Reads the size of packet.
293        let mut size_buff = vec![0_u8; 2];
294        if let Err(e) = stream.read_exact(&mut size_buff) {
295            return Err(Error::new(
296                ErrorKind::ReadingFromStreamFailed,
297                Some(format!("Failed to read the size of packet. \n({})", e)),
298            ));
299        }
300        let size = u16::try_from(&Bytes::from(size_buff.clone()))?;
301
302        // Reads rest of packet.
303        // - 2 for size of packet encoded as bytes which already exist.
304        let mut buff = vec![0_u8; (size - 2) as usize];
305        // USE READ EXACT, WITH OTHER METHODS THIS DOES NOT WORK.
306        if let Err(e) = stream.read_exact(&mut buff) {
307            return Err(Error::new(
308                ErrorKind::ReadingFromStreamFailed,
309                Some(format!("Failed to read contents of packet. \n({})", e)),
310            ));
311        }
312
313        // Connect whole buffer and change name, so it makes more sense.
314        size_buff.extend(buff);
315        let buff = size_buff;
316
317        // Create and return a packet from buffer.
318        Packet::try_from(buff.as_slice())
319    }
320
321    /// Receives a [Packet] and a [SocketAddr] on a [UdpSocket].
322    pub fn receive_from(socket: UdpSocket) -> Result<(Packet, SocketAddr), Error> {
323        let mut buff = vec![0_u8; Packet::max_size().into()];
324
325        match socket.recv_from(&mut buff) {
326            Ok((number_of_byte_read, address)) => {
327                // Truncate the buffer to remove invalid data.
328                buff.truncate(number_of_byte_read);
329                Ok((Packet::try_from(buff.as_slice())?, address))
330            }
331            Err(e) => Err(Error::new(
332                ErrorKind::ReceivingFromAddressFailed,
333                Some(format!(
334                    "Failed to receive a packet from an address. \n({e})"
335                )),
336            )),
337        }
338    }
339
340    /// Receives a [Packet] on a connected [UdpSocket].
341    pub fn receive_from_connected(socket: UdpSocket) -> Result<Packet, Error> {
342        let mut buff = vec![0_u8; Packet::max_size().into()];
343
344        match socket.recv(&mut buff) {
345            Ok(number_of_byte_read) => {
346                // Truncate the buffer to remove invalid data.
347                buff.truncate(number_of_byte_read);
348                Ok(Packet::try_from(buff.as_slice())?)
349            }
350            Err(e) => Err(Error::new(
351                ErrorKind::ReceivingFromAddressFailed,
352                Some(format!(
353                    "Failed to receive a packet from the connected socket. \n({e})"
354                )),
355            )),
356        }
357    }
358
359    /// Peeks on data on [TcpStream] if those data are valid, [Packet] is created.
360    ///
361    /// Since `TcpStream::peek` is used to retrieve data, calling this again returns the same data.
362    pub fn peek(stream: &mut TcpStream) -> Result<Packet, Error> {
363        // Peeks on the size of packet.
364        let mut size_buff = vec![0_u8; 2];
365        if let Err(e) = stream.peek(&mut size_buff) {
366            return Err(Error::new(
367                ErrorKind::ReadingFromStreamFailed,
368                Some(format!("Failed to peek on the size of packet. \n({})", e)),
369            ));
370        }
371
372        let size = u16::try_from(&Bytes::from(size_buff))?;
373
374        // Peek on rest of packet.
375        // Size is peeked on again as for getting it was used peek as well.
376        let mut buff = vec![0_u8; (size) as usize];
377        if let Err(e) = stream.peek(&mut buff) {
378            return Err(Error::new(
379                ErrorKind::ReadingFromStreamFailed,
380                Some(format!(
381                    "Failed to peek on the contents of packet. \n({})",
382                    e
383                )),
384            ));
385        }
386
387        // Create and return a packet from buffer.
388        Packet::try_from(buff.as_slice())
389    }
390
391    /// Peeks on data on `socket`, if valid data are received a [Packet] is created and
392    /// returned together with a [SocketAddr].
393    ///
394    /// Since `UdpSocket::peek_from` is used to retrieve data,
395    /// calling this again returns the same data.
396    pub fn peek_from(socket: UdpSocket) -> Result<(Self, SocketAddr), Error> {
397        let mut buff = vec![0_u8; Packet::max_size().into()];
398
399        match socket.peek_from(&mut buff) {
400            Ok((number_of_byte_read, address)) => {
401                buff.truncate(number_of_byte_read);
402                Ok((Packet::try_from(buff.as_slice())?, address))
403            }
404            Err(e) => Err(Error::new(
405                ErrorKind::ReceivingFromAddressFailed,
406                Some(format!(
407                    "Failed to receive a packet from the address. \n({e})"
408                )),
409            )),
410        }
411    }
412
413    /// Peeks on data on a connected `socket`, if valid data are received a [Packet] is created.
414    ///
415    /// Since `UdpSocket::peek` is used to retrieve data, calling this again returns the same data.
416    pub fn peek_from_connected(socket: UdpSocket) -> Result<Self, Error> {
417        let mut buff = vec![0_u8; Packet::max_size().into()];
418
419        match socket.peek(&mut buff) {
420            Ok(number_of_byte_read) => {
421                buff.truncate(number_of_byte_read);
422                Ok(Packet::try_from(buff.as_slice())?)
423            }
424            Err(e) => Err(Error::new(
425                ErrorKind::ReceivingFromAddressFailed,
426                Some(format!(
427                    "Failed to receive a packet from the connected socket. \n({e})"
428                )),
429            )),
430        }
431    }
432
433    // MISSING EXAMPLE
434
435    /// Returns number of packets needed to send data with given byte `length`.
436    pub fn number_of_packets(length: usize) -> u32 {
437        // Get number of packets by dividing by MAX_PACKET_CONTENT_SIZE.
438        let mut number_of_packets = length / (Packet::max_content_size() as usize);
439        // Add one packet if there is any remainder after the division.
440        if length % (Packet::max_content_size() as usize) != 0 {
441            number_of_packets += 1;
442        }
443        number_of_packets as u32
444    }
445
446    // MISSING EXAMPLE
447
448    /// Takes [Bytes] and returns [Vec] of [Bytes] each with maximum length of
449    /// [`MAX_CONTENT_SIZE`](Packet::max_content_size).
450    pub fn split_to_max_packet_size(buffer: Bytes) -> Vec<Bytes> {
451        // This splits given buffer to multiple owned chunks with chunks method
452        // from itertools crate, then it will split every chunk to iterator as well
453        // which are then collected to vectors of bytes, that are collected to single vector.
454        // From: https://stackoverflow.com/a/67009164.
455        let vectored_content: Vec<Bytes> = buffer
456            .into_iter()
457            .chunks(Packet::max_content_size() as usize)
458            .into_iter()
459            .map(|chunk| chunk.collect::<Vec<u8>>().into())
460            .collect::<Vec<Bytes>>();
461
462        vectored_content
463    }
464
465    /// Returns `size`.
466    pub fn size(&self) -> u16 {
467        self.size
468    }
469
470    /// Returns `kind`.
471    pub fn kind(&self) -> PacketKind {
472        self.kind.clone()
473    }
474
475    /// Returns `content`.
476    ///
477    /// Content is cloned.
478    pub fn content(&self) -> Bytes {
479        self.content.clone()
480    }
481
482    /// Returns a reference to `content`.
483    pub fn content_ref(&self) -> &Bytes {
484        &self.content
485    }
486
487    /// Returns a mutable reference to `content`.
488    pub fn content_mut(&mut self) -> &mut Bytes {
489        &mut self.content
490    }
491
492    /// Takes ownership of `self` and returns `content`.
493    pub fn content_move(self) -> Bytes {
494        self.content
495    }
496
497    /// Returns maximum number of bytes that can one [Packet] hold as [u16].
498    /// This is global value for every [Packet] that can be changed with [Packet::set_max_size].
499    ///
500    /// Minimum value is 5 bytes, 2 for packet `size`([u16]), 2 for [`packet kind`](PacketKind),
501    /// and at least 1 for [`content`](Bytes).
502    ///
503    /// This accesses a `mutable` static with [AtomicU16] to provide global access to this data
504    /// and an ability to change its value for specific needs, but since [AtomicU16] is used
505    /// it is capped by [u16::MAX].
506    pub fn max_size() -> u16 {
507        unsafe { MAX_PACKET_SIZE.load(Ordering::SeqCst) }
508    }
509
510    /// Sets [`MAX_PACKET_SIZE`](Packet::max_size) to `size`.
511    ///
512    /// Minimum value is 5 bytes, 2 for packet `size`([u16]), 2 for [`packet kind`](PacketKind),
513    /// and at least 1 for [`content`](Bytes).
514    ///
515    /// For more information look at [Packet::max_size].
516    pub fn set_max_size(size: u16) {
517        unsafe {
518            MAX_PACKET_SIZE.store(size, Ordering::SeqCst);
519        }
520    }
521
522    /// Returns minimal number of bytes that is every packet guaranteed to have,
523    /// 2 bytes are for its size and 2 for its kind as [u16].
524    pub const fn description_size() -> u16 {
525        PACKET_DESCRIPTION_SIZE
526    }
527
528    /// Maximum amount of bytes that a [Packet] can use for its content, its lower than
529    /// [`MAX_PACKET_SIZE`](Packet::max_size) by
530    /// [`PACKET_DESCRIPTION_SIZE`](Packet::description_size).
531    pub fn max_content_size() -> u16 {
532        Packet::max_size() - Packet::description_size()
533    }
534}