crowdstrike_cloudproto/framing/
packet.rs1use crate::framing::{CloudProtoError, CloudProtoVersion};
2use crate::services::CloudProtoMagic;
3use byteorder::{ReadBytesExt, BE};
4use std::io::Cursor;
5
6pub(crate) const COMMON_HDR_LEN: usize = 8;
7
8#[derive(Eq, PartialEq, Debug, Clone)]
10pub struct CloudProtoPacket {
11 pub magic: CloudProtoMagic,
13 pub kind: u8,
16 pub version: CloudProtoVersion,
17 pub payload: Vec<u8>,
18}
19
20impl CloudProtoPacket {
21 pub(crate) fn from_buf(buf: &[u8]) -> Result<Self, CloudProtoError> {
22 let mut reader = Cursor::new(buf);
23 let magic = reader.read_u8()?.into();
24 let kind = reader.read_u8()?;
25 let version = reader.read_u16::<BE>()?.into();
26 let pkt_size = reader.read_u32::<BE>()? as usize - COMMON_HDR_LEN;
27 let remaining_size = buf.len() - reader.position() as usize;
28 if remaining_size != pkt_size {
29 return Err(CloudProtoError::BadFrameSize(remaining_size, pkt_size));
30 }
31 let payload = buf[reader.position() as usize..].to_vec();
32 Ok(Self {
33 magic,
34 kind,
35 version,
36 payload,
37 })
38 }
39
40 pub(crate) fn to_buf(&self) -> Vec<u8> {
41 use byteorder::WriteBytesExt;
42 use std::io::Write;
43
44 let mut buf = Vec::new();
45 let mut writer = Cursor::new(&mut buf);
46 writer.write_u8(self.magic.into()).unwrap();
47 writer.write_u8(self.kind).unwrap();
48 writer.write_u16::<BE>(self.version.into()).unwrap();
49 writer
50 .write_u32::<BE>((self.payload.len() + COMMON_HDR_LEN) as u32)
51 .unwrap();
52 writer.write_all(&self.payload).unwrap();
53 writer.flush().unwrap();
54 buf
55 }
56}
57
58#[cfg(test)]
59mod test {
60 use crate::framing::packet::CloudProtoPacket;
61 use crate::framing::CloudProtoVersion;
62 use crate::services::CloudProtoMagic;
63 use anyhow::Result;
64
65 #[test_log::test]
66 fn to_from_buf_serialization() -> Result<()> {
67 let pkt = CloudProtoPacket {
68 magic: CloudProtoMagic::Other(0xFF),
69 kind: 0x73,
70 version: CloudProtoVersion::Other(0x10E9),
71 payload: b"Hello world".to_vec(),
72 };
73 let pkt2 = CloudProtoPacket::from_buf(&pkt.to_buf())?;
74 assert_eq!(pkt, pkt2);
75
76 Ok(())
77 }
78}