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::convert::TryFrom;
14use std::io::{Read, Write};
15
16const WIRE_PROTOCOL_VERSION_MAJ: u8 = 1;
17const WIRE_PROTOCOL_VERSION_MIN: u8 = 0;
18
19const REQUEST_HDR_SIZE: u16 = 30;
20
21#[cfg_attr(feature = "fuzz", derive(Arbitrary))]
26#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
27pub struct WireHeader {
28 pub flags: u16,
30 pub provider: u8,
32 pub session: u64,
34 pub content_type: u8,
36 pub accept_type: u8,
38 pub auth_type: u8,
40 pub body_len: u32,
42 pub auth_len: u16,
44 pub opcode: u32,
46 pub status: u16,
48 pub reserved1: u8,
50 pub reserved2: u8,
52}
53
54impl WireHeader {
55 #[cfg(feature = "testing")]
59 #[allow(clippy::new_without_default)]
60 pub fn new() -> WireHeader {
61 WireHeader {
62 flags: 0,
63 provider: 0,
64 session: 0,
65 content_type: 0,
66 accept_type: 0,
67 auth_type: 0,
68 body_len: 0,
69 auth_len: 0,
70 opcode: 0,
71 status: 0,
72 reserved1: 0,
73 reserved2: 0,
74 }
75 }
76
77 pub fn write_to_stream<W: Write>(&self, stream: &mut W) -> Result<()> {
84 let serializer = bincode::DefaultOptions::new()
85 .with_little_endian()
86 .with_fixint_encoding();
87
88 stream.write_all(&serializer.serialize(&MAGIC_NUMBER)?)?;
89
90 stream.write_all(&serializer.serialize(&REQUEST_HDR_SIZE)?)?;
91
92 stream.write_all(&serializer.serialize(&WIRE_PROTOCOL_VERSION_MAJ)?)?;
93 stream.write_all(&serializer.serialize(&WIRE_PROTOCOL_VERSION_MIN)?)?;
94
95 stream.write_all(&serializer.serialize(&self)?)?;
96
97 Ok(())
98 }
99
100 pub fn read_from_stream<R: Read>(mut stream: &mut R) -> Result<WireHeader> {
113 let magic_number = get_from_stream!(stream, u32);
114 if magic_number != MAGIC_NUMBER {
115 error!(
116 "Expected magic number {}, got {}",
117 MAGIC_NUMBER, magic_number
118 );
119 return Err(ResponseStatus::InvalidHeader);
120 }
121
122 let hdr_size = get_from_stream!(stream, u16);
123 let mut bytes = vec![0_u8; usize::try_from(hdr_size)?];
124 stream.read_exact(&mut bytes)?;
125 if hdr_size != REQUEST_HDR_SIZE {
126 error!(
127 "Expected request header size {}, got {}",
128 REQUEST_HDR_SIZE, hdr_size
129 );
130 return Err(ResponseStatus::InvalidHeader);
131 }
132
133 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 {
136 error!(
137 "Expected wire protocol version {}.{}, got {}.{} instead",
138 WIRE_PROTOCOL_VERSION_MAJ, WIRE_PROTOCOL_VERSION_MIN, version_maj, version_min
139 );
140 return Err(ResponseStatus::WireProtocolVersionNotSupported);
141 }
142
143 let deserializer = bincode::DefaultOptions::new()
144 .with_little_endian()
145 .with_fixint_encoding();
146 let wire_header: WireHeader = deserializer.deserialize(&bytes)?;
147
148 if wire_header.reserved1 != 0x00 || wire_header.reserved2 != 0x00 {
149 Err(ResponseStatus::InvalidHeader)
150 } else {
151 Ok(wire_header)
152 }
153 }
154}