ozzy_replication/wire/
admission.rs1use ozzy_proto::{EnvelopeLimits, Opcode, Packet};
4
5use super::{FetchOps, ReadFields, Reader, WireError};
6use crate::flow::{Channel, FlowError, ReceiveEpoch};
7
8#[derive(Clone, Copy, Debug, Eq, PartialEq)]
11pub enum ReceiveFence {
12 Normal(Channel),
14 History(FetchOps),
16}
17
18impl ReceiveFence {
19 pub const fn scope(self) -> crate::Scope {
21 match self {
22 Self::Normal(channel) => channel.scope,
23 Self::History(request) => request.scope,
24 }
25 }
26
27 pub fn validate_routing(
31 self,
32 packet: Packet<'_>,
33 limits: EnvelopeLimits,
34 ) -> Result<(), WireError> {
35 packet
36 .envelope
37 .validate_frames(packet.metadata.len(), packet.payload.len(), limits)?;
38 let mut reader = Reader::new(packet.metadata);
39 if reader.routing_scope(packet.envelope.sender)? != self.scope() {
40 return Err(WireError::Scope);
41 }
42 match self {
43 Self::Normal(channel) => {
44 if packet.envelope.opcode != Opcode::PrepareFlow {
45 return Err(WireError::UnsupportedCommand);
46 }
47 if packet.envelope.response || packet.envelope.request_id.is_some() {
48 return Err(WireError::Correlation);
49 }
50 let epoch = ReceiveEpoch::new(u128::from_be_bytes(reader.array()?))?;
51 if epoch != channel.epoch {
52 return Err(FlowError::Channel.into());
53 }
54 Ok(())
55 }
56 Self::History(request) => {
57 if packet.envelope.opcode != Opcode::Ops {
58 return Err(WireError::UnsupportedCommand);
59 }
60 super::transfer::validate_routing(
61 request,
62 packet.envelope,
63 reader,
64 packet.payload.len(),
65 )
66 }
67 }
68 }
69}