netsvc_proto/
debuglog.rs
1use crate::ValidStr;
10use packet::{
11 BufferView, BufferViewMut, FragmentedBytesMut, InnerPacketBuilder, PacketBuilder,
12 PacketConstraints, ParsablePacket, ParseMetadata, SerializeTarget,
13};
14use std::num::NonZeroU16;
15use zerocopy::byteorder::little_endian::U32;
16use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Ref, SplitByteSlice, Unaligned};
17
18pub const MULTICAST_PORT: NonZeroU16 = NonZeroU16::new(33337).unwrap();
19pub const ACK_PORT: NonZeroU16 = NonZeroU16::new(33338).unwrap();
20
21const MAGIC: u32 = 0xAEAE1123;
22const MAX_LOG_DATA: usize = 1216;
23const MAX_NODENAME_LENGTH: usize = 64;
24
25pub const ACK_SIZE: usize = std::mem::size_of::<PacketHead>();
26
27#[repr(C)]
28#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned)]
29pub struct PacketHead {
30 magic: U32,
31 seqno: U32,
32}
33
34pub struct DebugLogPacket<B> {
35 head: Ref<B, PacketHead>,
36 nodename: ValidStr<B>,
37 data: ValidStr<B>,
38}
39
40impl<B: SplitByteSlice> DebugLogPacket<B> {
41 pub fn seqno(&self) -> u32 {
42 self.head.seqno.get()
43 }
44
45 pub fn nodename(&self) -> &str {
46 self.nodename.as_str()
47 }
48
49 pub fn data(&self) -> &str {
50 self.data.as_str()
51 }
52}
53
54#[derive(Debug)]
55pub enum ParseError {
56 BadMagic,
57 Malformed,
58 Encoding(std::str::Utf8Error),
59}
60
61impl<B> ParsablePacket<B, ()> for DebugLogPacket<B>
62where
63 B: SplitByteSlice,
64{
65 type Error = ParseError;
66
67 fn parse<BV: BufferView<B>>(mut buffer: BV, _args: ()) -> Result<Self, Self::Error> {
68 let head = buffer.take_obj_front::<PacketHead>().ok_or(ParseError::Malformed)?;
69 if head.magic.get() != MAGIC {
70 return Err(ParseError::BadMagic);
71 }
72 let nodename = buffer.take_front(MAX_NODENAME_LENGTH).ok_or(ParseError::Malformed)?;
73 let nodename = ValidStr::new(nodename).map_err(ParseError::Encoding)?;
74 let (nodename, _rest) = nodename.truncate_null();
75 let data = ValidStr::new(buffer.into_rest()).map_err(ParseError::Encoding)?;
76
77 Ok(Self { head, nodename, data })
78 }
79
80 fn parse_metadata(&self) -> ParseMetadata {
81 unimplemented!()
83 }
84}
85
86#[derive(Debug)]
87pub struct AckPacketBuilder {
88 seqno: u32,
89}
90
91impl AckPacketBuilder {
92 pub fn new(seqno: u32) -> Self {
93 Self { seqno }
94 }
95}
96
97impl InnerPacketBuilder for AckPacketBuilder {
98 fn bytes_len(&self) -> usize {
99 std::mem::size_of::<PacketHead>()
100 }
101
102 fn serialize(&self, mut buffer: &mut [u8]) {
103 let mut bv = crate::as_buffer_view_mut(&mut buffer);
104 let mut head = bv.take_obj_front::<PacketHead>().unwrap();
105 head.magic.set(MAGIC);
106 head.seqno.set(self.seqno);
107 }
108}
109
110#[derive(Debug)]
111pub struct LogPacketBuilder<'a> {
112 seqno: u32,
113 nodename: &'a str,
114}
115
116impl<'a> LogPacketBuilder<'a> {
117 pub fn new(seqno: u32, nodename: &'a str) -> Option<Self> {
118 if nodename.len() <= MAX_NODENAME_LENGTH {
119 Some(Self { seqno, nodename })
120 } else {
121 None
122 }
123 }
124}
125
126impl<'a> PacketBuilder for LogPacketBuilder<'a> {
127 fn constraints(&self) -> PacketConstraints {
128 PacketConstraints::new(
129 std::mem::size_of::<PacketHead>() + MAX_NODENAME_LENGTH,
130 0,
131 0,
132 MAX_LOG_DATA,
133 )
134 }
135
136 fn serialize(&self, target: &mut SerializeTarget<'_>, _body: FragmentedBytesMut<'_, '_>) {
137 let mut bv = crate::as_buffer_view_mut(&mut target.header);
138 let mut head = bv.take_obj_front::<PacketHead>().unwrap();
139 head.magic.set(MAGIC);
140 head.seqno.set(self.seqno);
141 let nodename_bytes = self.nodename.as_bytes();
142 let nodename = bv.take_front_zero(MAX_NODENAME_LENGTH).unwrap();
143 let (nodename, _rest) = nodename.split_at_mut(nodename_bytes.len());
144 nodename.copy_from_slice(nodename_bytes);
145 }
146}
147
148#[cfg(test)]
149mod tests {
150 use super::*;
151 use packet::{ParseBuffer as _, Serializer as _};
152
153 fn as_buffer_view<'a, B: packet::BufferView<&'a [u8]>>(
155 v: B,
156 ) -> impl packet::BufferView<&'a [u8]> {
157 v
158 }
159
160 #[test]
161 fn test_log_packet() {
162 const LOG_DATA: &'static str = "some log data";
163 const NODENAME: &'static str = "my node";
164 let mut log = LOG_DATA
165 .as_bytes()
166 .into_serializer()
167 .encapsulate(LogPacketBuilder::new(3, NODENAME).unwrap())
168 .serialize_vec_outer()
169 .unwrap_or_else(|_| panic!("Failed to serialize"));
170 let packet = log.parse::<DebugLogPacket<_>>().expect("Failed to parse");
171 assert_eq!(packet.seqno(), 3);
172 assert_eq!(packet.nodename(), NODENAME);
173 assert_eq!(packet.data(), LOG_DATA);
174 }
175
176 #[test]
177 fn test_ack_packet() {
178 const SEQNO: u32 = 4;
179 let ack = AckPacketBuilder::new(SEQNO)
180 .into_serializer()
181 .serialize_vec_outer()
182 .unwrap_or_else(|_| panic!("Failed to serialize"));
183 let mut bv = ack.as_ref();
184 let head = as_buffer_view(&mut bv)
185 .take_obj_front::<PacketHead>()
186 .expect("failed to get serialized head");
187 assert_eq!(head.magic.get(), MAGIC);
188 assert_eq!(head.seqno.get(), SEQNO);
189 }
190}