parsec_interface/requests/common/
wire_header_1_0.rs1use crate::requests::common::MAGIC_NUMBER;
7use crate::requests::{ResponseStatus, Result};
8#[cfg(feature = "fuzz")]
9use arbitrary::Arbitrary;
10use bincode::Options;
11use log::error;
12use serde::{Deserialize, Serialize};
13use std::io::{Read, Write};
14
15const WIRE_PROTOCOL_VERSION_MAJ: u8 = 1;
16const WIRE_PROTOCOL_VERSION_MIN: u8 = 0;
17
18const REQUEST_HDR_SIZE: u16 = 30;
19
20#[cfg_attr(feature = "fuzz", derive(Arbitrary))]
25#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
26pub struct WireHeader {
27 pub flags: u16,
29 pub provider: u8,
31 pub session: u64,
33 pub content_type: u8,
35 pub accept_type: u8,
37 pub auth_type: u8,
39 pub body_len: u32,
41 pub auth_len: u16,
43 pub opcode: u32,
45 pub status: u16,
47 pub reserved1: u8,
49 pub reserved2: u8,
51}
52
53impl WireHeader {
54 #[cfg(feature = "testing")]
58 #[allow(clippy::new_without_default)]
59 pub fn new() -> WireHeader {
60 WireHeader {
61 flags: 0,
62 provider: 0,
63 session: 0,
64 content_type: 0,
65 accept_type: 0,
66 auth_type: 0,
67 body_len: 0,
68 auth_len: 0,
69 opcode: 0,
70 status: 0,
71 reserved1: 0,
72 reserved2: 0,
73 }
74 }
75
76 pub fn write_to_stream<W: Write>(&self, stream: &mut W) -> Result<()> {
83 let serializer = bincode::DefaultOptions::new()
84 .with_little_endian()
85 .with_fixint_encoding();
86
87 stream.write_all(&serializer.serialize(&MAGIC_NUMBER)?)?;
88
89 stream.write_all(&serializer.serialize(&REQUEST_HDR_SIZE)?)?;
90
91 stream.write_all(&serializer.serialize(&WIRE_PROTOCOL_VERSION_MAJ)?)?;
92 stream.write_all(&serializer.serialize(&WIRE_PROTOCOL_VERSION_MIN)?)?;
93
94 stream.write_all(&serializer.serialize(&self)?)?;
95
96 Ok(())
97 }
98
99 pub fn read_from_stream<R: Read>(mut stream: &mut R) -> Result<WireHeader> {
112 let magic_number = get_from_stream!(stream, u32);
113 if magic_number != MAGIC_NUMBER {
114 error!(
115 "Expected magic number {}, got {}",
116 MAGIC_NUMBER, magic_number
117 );
118 return Err(ResponseStatus::InvalidHeader);
119 }
120
121 let hdr_size = get_from_stream!(stream, u16);
122 let mut bytes = vec![0_u8; usize::from(hdr_size)];
123 stream.read_exact(&mut bytes)?;
124 if hdr_size != REQUEST_HDR_SIZE {
125 error!(
126 "Expected request header size {}, got {}",
127 REQUEST_HDR_SIZE, hdr_size
128 );
129 return Err(ResponseStatus::InvalidHeader);
130 }
131
132 let version_maj = bytes.remove(0); let version_min = bytes.remove(0); if version_maj != WIRE_PROTOCOL_VERSION_MAJ || version_min != WIRE_PROTOCOL_VERSION_MIN {
135 error!(
136 "Expected wire protocol version {}.{}, got {}.{} instead",
137 WIRE_PROTOCOL_VERSION_MAJ, WIRE_PROTOCOL_VERSION_MIN, version_maj, version_min
138 );
139 return Err(ResponseStatus::WireProtocolVersionNotSupported);
140 }
141
142 let deserializer = bincode::DefaultOptions::new()
143 .with_little_endian()
144 .with_fixint_encoding();
145 let wire_header: WireHeader = deserializer.deserialize(&bytes)?;
146
147 if wire_header.reserved1 != 0x00 || wire_header.reserved2 != 0x00 {
148 Err(ResponseStatus::InvalidHeader)
149 } else {
150 Ok(wire_header)
151 }
152 }
153}