feat(proto): add directional open and close codecs
This commit is contained in:
5 files changed
+240
-7
No files matched your search
@@ -1,8 +1,8 @@
|
||||
use crate::{
|
||||
envelope::{self, FlagRule},
|
||||
flags::{FLAG_CLOSE, FLAG_OPEN, FLAG_REPLY},
|
||||
flags::{has, FLAG_CLOSE, FLAG_OPEN, FLAG_REPLY},
|
||||
layout::PacketLayout,
|
||||
Result,
|
||||
ProtoError, Result, TOKEN_SIZE,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
@@ -25,6 +25,35 @@ pub fn encode_close_request(request: &CloseRequest, hmac_key: Option<&[u8]>) ->
|
||||
envelope::finish(out, hmac_key)
|
||||
}
|
||||
|
||||
pub fn decode_close_request(packet: &[u8], hmac_key: Option<&[u8]>) -> Result<CloseRequest> {
|
||||
let envelope = envelope::decode(
|
||||
packet,
|
||||
hmac_key,
|
||||
&[
|
||||
FlagRule::Require(FLAG_CLOSE),
|
||||
FlagRule::Reject(FLAG_OPEN),
|
||||
FlagRule::Reject(FLAG_REPLY),
|
||||
],
|
||||
)?;
|
||||
let expected_len =
|
||||
PacketLayout::close_request(has(envelope.flags, crate::FLAG_HMAC)).header_len();
|
||||
if packet.len() != expected_len {
|
||||
return Err(ProtoError::PacketLengthMismatch {
|
||||
expected: expected_len,
|
||||
actual: packet.len(),
|
||||
});
|
||||
}
|
||||
envelope::verify(packet, hmac_key)?;
|
||||
|
||||
Ok(CloseRequest {
|
||||
token: u64::from_le_bytes(
|
||||
packet[envelope.body_offset..envelope.body_offset + TOKEN_SIZE]
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -31,13 +31,16 @@ pub mod open;
|
||||
pub mod params;
|
||||
pub mod varint;
|
||||
|
||||
pub use close::{encode_close_request, CloseRequest};
|
||||
pub use close::{decode_close_request, encode_close_request, CloseRequest};
|
||||
pub use echo::{decode_echo_reply, encode_echo_request, EchoReply, EchoRequest, TimestampFields};
|
||||
pub use error::{ProtoError, Result};
|
||||
pub use flags::*;
|
||||
pub use hmac::{compute_hmac, compute_hmac_in_place, verify_hmac};
|
||||
pub use layout::{echo_header_len, echo_packet_len, PacketLayout};
|
||||
pub use open::{decode_open_reply, encode_open_request, OpenReply, OpenRequest};
|
||||
pub use open::{
|
||||
decode_open_reply, decode_open_request, encode_open_reply, encode_open_request, OpenReply,
|
||||
OpenRequest,
|
||||
};
|
||||
pub use params::{Clock, Params, ReceivedStats, ServerFill, StampAt, MAX_SERVER_FILL_BYTES};
|
||||
|
||||
pub const MAGIC: [u8; 3] = [0x14, 0xA7, 0x5B];
|
||||
|
||||
@@ -35,6 +35,37 @@ pub fn encode_open_request(request: &OpenRequest, hmac_key: Option<&[u8]>) -> Re
|
||||
envelope::finish(out, hmac_key)
|
||||
}
|
||||
|
||||
pub fn decode_open_request(packet: &[u8], hmac_key: Option<&[u8]>) -> Result<OpenRequest> {
|
||||
let envelope = envelope::decode(
|
||||
packet,
|
||||
hmac_key,
|
||||
&[FlagRule::Require(FLAG_OPEN), FlagRule::Reject(FLAG_REPLY)],
|
||||
)?;
|
||||
envelope::verify(packet, hmac_key)?;
|
||||
|
||||
Ok(OpenRequest {
|
||||
params: Params::decode(&packet[envelope.body_offset..])?,
|
||||
close: has(envelope.flags, FLAG_CLOSE),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn encode_open_reply(reply: &OpenReply, hmac_key: Option<&[u8]>) -> Result<Vec<u8>> {
|
||||
let params = reply.params.encode();
|
||||
let mut out = envelope::begin(
|
||||
reply.flags,
|
||||
hmac_key,
|
||||
&[FlagRule::Require(FLAG_OPEN), FlagRule::Require(FLAG_REPLY)],
|
||||
PacketLayout::open_reply(hmac_key.is_some()).header_len() + params.len(),
|
||||
)?;
|
||||
if reply.token == 0 && !has(reply.flags, FLAG_CLOSE) {
|
||||
return Err(ProtoError::ZeroToken);
|
||||
}
|
||||
|
||||
out.extend_from_slice(&reply.token.to_le_bytes());
|
||||
out.extend_from_slice(¶ms);
|
||||
envelope::finish(out, hmac_key)
|
||||
}
|
||||
|
||||
pub fn decode_open_reply(packet: &[u8], hmac_key: Option<&[u8]>) -> Result<OpenReply> {
|
||||
let envelope = envelope::decode(
|
||||
packet,
|
||||
|
||||
Reference in new issue
Block a user