mirror of
https://github.com/Astatin3/unshell.git
synced 2026-06-09 06:47:59 -06:00
Rebuild protocol runtime from scratch
Implement an aligned two-section frame format, a compiled prefix router, a minimal pending and active hook engine, and a header-first receive path that only decodes payloads on local delivery. Recreate the protocol-focused test suite and document the explicit framing deviation in src/protocol/PROTOCOL_CHANGES.md.
This commit is contained in:
@@ -1,7 +1,4 @@
|
||||
//! Packet builders and basic endpoint configuration.
|
||||
//!
|
||||
//! These helpers map to `PROTOCOL.md` sections covering packet construction,
|
||||
//! call headers, and hook declaration fields.
|
||||
//! Packet builders and endpoint construction.
|
||||
|
||||
use alloc::{collections::BTreeSet, string::String, vec::Vec};
|
||||
|
||||
@@ -49,30 +46,6 @@ impl ProtocolEndpoint {
|
||||
Ok((header, call))
|
||||
}
|
||||
|
||||
fn register_outbound_call_hook(
|
||||
&mut self,
|
||||
header: &PacketHeader,
|
||||
call: &CallMessage,
|
||||
) -> Result<(), EndpointError> {
|
||||
if let Some(hook) = &call.response_hook
|
||||
&& self
|
||||
.hooks
|
||||
.insert_active(ActiveHook {
|
||||
return_path: hook.return_path.clone(),
|
||||
hook_id: hook.hook_id,
|
||||
peer_path: header.dst_path.clone(),
|
||||
procedure_id: call.procedure_id.clone(),
|
||||
dst_leaf: header.dst_leaf.clone(),
|
||||
local_ended: false,
|
||||
peer_ended: false,
|
||||
})
|
||||
.is_err()
|
||||
{
|
||||
return Err(EndpointError::Validation(ValidationError::InvalidHookId));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prepare_data(
|
||||
&self,
|
||||
dst_path: Vec<String>,
|
||||
@@ -101,14 +74,30 @@ impl ProtocolEndpoint {
|
||||
Ok((header, message))
|
||||
}
|
||||
|
||||
/// Creates a runtime endpoint with static tree topology and leaf metadata.
|
||||
///
|
||||
/// ```
|
||||
/// use unshell::protocol::tree::{Endpoint, ProtocolEndpoint};
|
||||
///
|
||||
/// let endpoint = ProtocolEndpoint::new(Vec::new(), None, Vec::new(), Vec::new());
|
||||
/// assert!(endpoint.path().is_empty());
|
||||
/// ```
|
||||
fn register_outbound_call_hook(
|
||||
&mut self,
|
||||
header: &PacketHeader,
|
||||
call: &CallMessage,
|
||||
) -> Result<(), EndpointError> {
|
||||
if let Some(hook) = &call.response_hook
|
||||
&& self
|
||||
.hooks
|
||||
.insert_active(ActiveHook {
|
||||
return_path: hook.return_path.clone(),
|
||||
hook_id: hook.hook_id,
|
||||
peer_path: header.dst_path.clone(),
|
||||
procedure_id: call.procedure_id.clone(),
|
||||
dst_leaf: header.dst_leaf.clone(),
|
||||
local_ended: false,
|
||||
peer_ended: false,
|
||||
})
|
||||
.is_err()
|
||||
{
|
||||
return Err(EndpointError::Validation(ValidationError::InvalidHookId));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn new(
|
||||
path: Vec<String>,
|
||||
@@ -135,7 +124,6 @@ impl ProtocolEndpoint {
|
||||
}
|
||||
}
|
||||
|
||||
/// Registers an endpoint-local procedure identifier.
|
||||
pub fn add_endpoint_procedure(
|
||||
&mut self,
|
||||
procedure_id: impl Into<String>,
|
||||
@@ -146,13 +134,11 @@ impl ProtocolEndpoint {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Allocates a locally unique hook id.
|
||||
#[must_use]
|
||||
pub fn allocate_hook_id(&mut self) -> u64 {
|
||||
self.hooks.allocate_hook_id(&self.path)
|
||||
}
|
||||
|
||||
/// Builds an outbound `Call` packet and pre-registers active hook state when requested.
|
||||
pub fn make_call(
|
||||
&mut self,
|
||||
dst_path: Vec<String>,
|
||||
@@ -167,7 +153,6 @@ impl ProtocolEndpoint {
|
||||
Ok(encode_packet(&header, &call)?)
|
||||
}
|
||||
|
||||
/// Routes one locally originated `Call` without an encode/decode roundtrip.
|
||||
pub fn send_call(
|
||||
&mut self,
|
||||
dst_path: Vec<String>,
|
||||
@@ -186,7 +171,6 @@ impl ProtocolEndpoint {
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds an outbound `Data` packet for an existing hook.
|
||||
pub fn make_data(
|
||||
&self,
|
||||
dst_path: Vec<String>,
|
||||
@@ -199,7 +183,6 @@ impl ProtocolEndpoint {
|
||||
Ok(encode_packet(&header, &message)?)
|
||||
}
|
||||
|
||||
/// Routes one locally originated `Data` packet without an encode/decode roundtrip.
|
||||
pub fn send_data(
|
||||
&mut self,
|
||||
dst_path: Vec<String>,
|
||||
@@ -211,9 +194,12 @@ impl ProtocolEndpoint {
|
||||
let (header, message) = self.prepare_data(dst_path, hook_id, procedure_id, data, end_hook)?;
|
||||
|
||||
if end_hook {
|
||||
let key = HookKey::new(self.path.clone(), hook_id);
|
||||
if self.hooks.mark_local_end(&key) {
|
||||
self.hooks.remove_active(&key);
|
||||
let sender_key = self
|
||||
.hooks
|
||||
.resolve_active_key(&self.path, hook_id, &self.path)
|
||||
.unwrap_or_else(|| HookKey::new(self.path.clone(), hook_id));
|
||||
if self.hooks.mark_local_end(&sender_key) {
|
||||
self.hooks.remove_active(&sender_key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
//! Core endpoint state and externally visible types.
|
||||
//!
|
||||
//! This file maps to the protocol concepts described in `PROTOCOL.md`:
|
||||
//! - Packet processing entry points and local delivery state: "Packet Types"
|
||||
//! - Child registration state used during route selection: "Routing"
|
||||
//! - Hook-hosting endpoint state: "Hooks"
|
||||
|
||||
use alloc::{
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
@@ -18,26 +13,19 @@ use crate::protocol::{
|
||||
|
||||
use super::super::{CompiledRoutes, HookTable, RouteDecision};
|
||||
|
||||
/// Local connection state used for child route eligibility.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ConnectionState {
|
||||
/// The child exists in the static topology but is not currently routable.
|
||||
Unregistered,
|
||||
/// The child may receive routed traffic.
|
||||
Registered,
|
||||
}
|
||||
|
||||
/// Child path plus current registration state.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ChildRoute {
|
||||
/// Absolute child endpoint path.
|
||||
pub path: Vec<String>,
|
||||
/// Whether the child currently participates in routing.
|
||||
pub state: ConnectionState,
|
||||
}
|
||||
|
||||
impl ChildRoute {
|
||||
/// Convenience constructor for the common registered-child case.
|
||||
#[must_use]
|
||||
pub fn registered(path: Vec<String>) -> Self {
|
||||
Self {
|
||||
@@ -47,62 +35,43 @@ impl ChildRoute {
|
||||
}
|
||||
}
|
||||
|
||||
/// Static leaf metadata used for procedure dispatch and introspection.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct LeafSpec {
|
||||
/// Stable local leaf name.
|
||||
pub name: String,
|
||||
/// Procedures supported by the leaf.
|
||||
pub procedures: Vec<String>,
|
||||
}
|
||||
|
||||
/// Where a frame entered the local endpoint.
|
||||
///
|
||||
/// This corresponds to the authority and ingress checks described in the
|
||||
/// `PROTOCOL.md` routing and call sections.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Ingress {
|
||||
/// Received from the parent link.
|
||||
Parent,
|
||||
/// Received from the child at the given absolute path.
|
||||
Child(Vec<String>),
|
||||
/// Injected locally by code running on this endpoint.
|
||||
Local,
|
||||
}
|
||||
|
||||
/// Locally delivered protocol events.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum LocalEvent {
|
||||
/// A call reached this endpoint runtime.
|
||||
Call {
|
||||
header: PacketHeader,
|
||||
message: CallMessage,
|
||||
},
|
||||
/// Hook data reached this endpoint runtime.
|
||||
Data {
|
||||
header: PacketHeader,
|
||||
message: DataMessage,
|
||||
},
|
||||
/// A protocol fault reached this endpoint runtime.
|
||||
Fault {
|
||||
header: PacketHeader,
|
||||
message: FaultMessage,
|
||||
},
|
||||
}
|
||||
|
||||
/// Result of processing one framed packet.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct EndpointOutcome {
|
||||
/// Forwarding action to perform after local processing.
|
||||
pub forward: Option<(RouteDecision, FrameBytes)>,
|
||||
/// Event delivered to the local runtime consumer.
|
||||
pub event: Option<LocalEvent>,
|
||||
/// Whether the packet was intentionally dropped with no other side effects.
|
||||
pub dropped: bool,
|
||||
}
|
||||
|
||||
impl EndpointOutcome {
|
||||
/// Returns an outcome that only forwards one frame.
|
||||
#[must_use]
|
||||
pub fn forward(route: RouteDecision, frame: FrameBytes) -> Self {
|
||||
Self {
|
||||
@@ -112,7 +81,6 @@ impl EndpointOutcome {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an outcome that only delivers one local event.
|
||||
#[must_use]
|
||||
pub fn event(event: LocalEvent) -> Self {
|
||||
Self {
|
||||
@@ -122,7 +90,6 @@ impl EndpointOutcome {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an outcome that silently drops the packet.
|
||||
#[must_use]
|
||||
pub fn dropped() -> Self {
|
||||
Self {
|
||||
@@ -133,12 +100,9 @@ impl EndpointOutcome {
|
||||
}
|
||||
}
|
||||
|
||||
/// Errors returned while decoding or validating a packet.
|
||||
#[derive(Debug)]
|
||||
pub enum EndpointError {
|
||||
/// The frame could not be decoded.
|
||||
Frame(FrameError),
|
||||
/// The decoded packet violated protocol invariants.
|
||||
Validation(ValidationError),
|
||||
}
|
||||
|
||||
@@ -165,12 +129,9 @@ impl From<ValidationError> for EndpointError {
|
||||
}
|
||||
}
|
||||
|
||||
/// Public packet-processing trait exposed by the tree runtime.
|
||||
pub trait Endpoint {
|
||||
/// Returns the absolute endpoint path.
|
||||
fn path(&self) -> &[String];
|
||||
|
||||
/// Processes one incoming frame from the given ingress side.
|
||||
fn receive(
|
||||
&mut self,
|
||||
ingress: &Ingress,
|
||||
@@ -178,7 +139,6 @@ pub trait Endpoint {
|
||||
) -> Result<EndpointOutcome, EndpointError>;
|
||||
}
|
||||
|
||||
/// Stateful endpoint runtime implementing routing, hooks, and local dispatch.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ProtocolEndpoint {
|
||||
pub(crate) path: Vec<String>,
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
//! Hook-state transitions and route helpers.
|
||||
//!
|
||||
//! These methods implement the hook lifecycle described in `PROTOCOL.md`:
|
||||
//! pending contexts, active contexts, peer validation, and fault emission.
|
||||
|
||||
use alloc::string::String;
|
||||
|
||||
@@ -13,7 +10,6 @@ use super::super::{HookKey, RouteDecision};
|
||||
use super::core::{EndpointError, EndpointOutcome, Ingress, LocalEvent, ProtocolEndpoint};
|
||||
|
||||
impl ProtocolEndpoint {
|
||||
/// Emits a protocol fault only when the original call declared a response hook.
|
||||
pub(crate) fn emit_fault_if_possible(
|
||||
&mut self,
|
||||
key: Option<HookKey>,
|
||||
@@ -34,18 +30,13 @@ impl ProtocolEndpoint {
|
||||
hook_id: Some(key.hook_id),
|
||||
};
|
||||
let message = FaultMessage { fault };
|
||||
let route = self.decide_route(&key.return_path);
|
||||
|
||||
match route {
|
||||
match self.decide_route(&key.return_path) {
|
||||
RouteDecision::Local => Ok(EndpointOutcome::event(LocalEvent::Fault { header, message })),
|
||||
_ => {
|
||||
let frame = encode_packet(&header, &message)?;
|
||||
Ok(EndpointOutcome::forward(route, frame))
|
||||
}
|
||||
route => Ok(EndpointOutcome::forward(route, encode_packet(&header, &message)?)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles locally delivered hook `Data` packets.
|
||||
pub(crate) fn handle_local_data(
|
||||
&mut self,
|
||||
header: PacketHeader,
|
||||
@@ -90,44 +81,34 @@ impl ProtocolEndpoint {
|
||||
Ok(EndpointOutcome::event(LocalEvent::Data { header, message }))
|
||||
}
|
||||
|
||||
/// Handles locally delivered hook `Fault` packets.
|
||||
pub(crate) fn handle_local_fault(
|
||||
&mut self,
|
||||
header: PacketHeader,
|
||||
message: FaultMessage,
|
||||
) -> Result<EndpointOutcome, EndpointError> {
|
||||
let Some(key) = self.hooks.resolve_active_key(
|
||||
&self.path,
|
||||
header.hook_id.expect("validated"),
|
||||
&header.src_path,
|
||||
) else {
|
||||
let key = HookKey::new(self.path.clone(), header.hook_id.expect("validated"));
|
||||
let matches_pending = self
|
||||
.hooks
|
||||
.pending(&key)
|
||||
.is_some_and(|pending| pending.caller_src_path == header.src_path);
|
||||
if !matches_pending {
|
||||
return Ok(EndpointOutcome::dropped());
|
||||
}
|
||||
self.hooks.remove_pending(&key);
|
||||
let hook_id = header.hook_id.expect("validated");
|
||||
if let Some(key) = self.hooks.resolve_active_key(&self.path, hook_id, &header.src_path) {
|
||||
self.hooks.remove_active(&key);
|
||||
return Ok(EndpointOutcome::event(LocalEvent::Fault { header, message }));
|
||||
};
|
||||
}
|
||||
|
||||
self.hooks.remove_active(&key);
|
||||
let pending_key = HookKey::new(self.path.clone(), hook_id);
|
||||
if self
|
||||
.hooks
|
||||
.pending(&pending_key)
|
||||
.is_some_and(|pending| pending.caller_src_path == header.src_path)
|
||||
{
|
||||
self.hooks.remove_pending(&pending_key);
|
||||
return Ok(EndpointOutcome::event(LocalEvent::Fault { header, message }));
|
||||
}
|
||||
|
||||
Ok(EndpointOutcome::event(LocalEvent::Fault { header, message }))
|
||||
Ok(EndpointOutcome::dropped())
|
||||
}
|
||||
|
||||
/// Chooses the next hop using the protocol's longest-prefix routing rule.
|
||||
pub(crate) fn decide_route(&self, dst_path: &[String]) -> RouteDecision {
|
||||
self.routing.route(dst_path)
|
||||
}
|
||||
|
||||
/// Validates whether a source path is attributable to the ingress side.
|
||||
///
|
||||
/// Rationale: this looks backwards at first because parent ingress accepts
|
||||
/// non-local source paths. That is required for multi-hop routing, where a
|
||||
/// parent forwards traffic originating from ancestors or siblings.
|
||||
pub(crate) fn valid_source_for_ingress(&self, ingress: &Ingress, src_path: &[String]) -> bool {
|
||||
match ingress {
|
||||
Ingress::Parent => {
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
//! Introspection response generation.
|
||||
//!
|
||||
//! This code implements the reserved empty-procedure behavior from the
|
||||
//! introspection sections of `PROTOCOL.md`.
|
||||
|
||||
use alloc::string::String;
|
||||
use rkyv::{rancor::Error as RkyvError, to_bytes};
|
||||
@@ -15,7 +12,6 @@ use super::super::HookKey;
|
||||
use super::core::{EndpointError, EndpointOutcome, ProtocolEndpoint};
|
||||
|
||||
impl ProtocolEndpoint {
|
||||
/// Handles the reserved introspection procedure.
|
||||
pub(crate) fn handle_introspection(
|
||||
&mut self,
|
||||
header: &PacketHeader,
|
||||
@@ -68,20 +64,19 @@ impl ProtocolEndpoint {
|
||||
data: payload,
|
||||
end_hook: true,
|
||||
};
|
||||
self.hooks.remove_active(&key);
|
||||
let route = self.decide_route(&key.return_path);
|
||||
|
||||
match route {
|
||||
if self.hooks.mark_local_end(&key) {
|
||||
self.hooks.remove_active(&key);
|
||||
}
|
||||
|
||||
match self.decide_route(&key.return_path) {
|
||||
super::super::RouteDecision::Local => Ok(EndpointOutcome::event(
|
||||
super::core::LocalEvent::Data {
|
||||
header: response_header,
|
||||
message: response,
|
||||
},
|
||||
)),
|
||||
_ => {
|
||||
let frame = encode_packet(&response_header, &response)?;
|
||||
Ok(EndpointOutcome::forward(route, frame))
|
||||
}
|
||||
route => Ok(EndpointOutcome::forward(route, encode_packet(&response_header, &response)?)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
//! Endpoint runtime and traits.
|
||||
//!
|
||||
//! This module provides the core logic for a protocol endpoint, including
|
||||
//! packet ingress, routing decisions, and hook lifecycle management.
|
||||
//!
|
||||
//! Protocol section mapping:
|
||||
//! - `builders`: packet construction and outbound hook declaration
|
||||
//! - `receive`: framed ingress, authority checks, and route selection
|
||||
//! - `hooks`: hook lifecycle, peer validation, and fault emission
|
||||
//! - `introspection`: reserved empty-procedure discovery responses
|
||||
//! - `core`: externally visible endpoint state and result types
|
||||
|
||||
mod builders;
|
||||
mod core;
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
//! Packet ingress and local call dispatch.
|
||||
//!
|
||||
//! This file implements the transport-facing packet entry point and maps it to
|
||||
//! the `Call`, `Data`, and `Fault` sections of `PROTOCOL.md`.
|
||||
|
||||
use crate::protocol::types::{ArchivedCallMessage, ArchivedDataMessage, ArchivedFaultMessage};
|
||||
use crate::protocol::{
|
||||
CallMessage, PacketType, ProtocolFault, decode_frame, deserialize_archived_bytes,
|
||||
introspection::INTROSPECTION_PROCEDURE_ID, validate_call, validate_header,
|
||||
};
|
||||
use crate::protocol::types::{ArchivedCallMessage, ArchivedDataMessage, ArchivedFaultMessage};
|
||||
|
||||
use super::super::{HookKey, PendingHook, RouteDecision};
|
||||
use super::core::{
|
||||
@@ -15,7 +12,6 @@ use super::core::{
|
||||
};
|
||||
|
||||
impl ProtocolEndpoint {
|
||||
/// Handles a locally delivered `Call` packet after routing selected `Local`.
|
||||
pub(crate) fn handle_local_call(
|
||||
&mut self,
|
||||
header: crate::protocol::PacketHeader,
|
||||
@@ -26,7 +22,26 @@ impl ProtocolEndpoint {
|
||||
.as_ref()
|
||||
.map(|hook| HookKey::new(hook.return_path.clone(), hook.hook_id));
|
||||
|
||||
if let Some(hook) = &message.response_hook
|
||||
&& hook.return_path != self.path
|
||||
&& self
|
||||
.hooks
|
||||
.insert_pending(PendingHook {
|
||||
return_path: hook.return_path.clone(),
|
||||
hook_id: hook.hook_id,
|
||||
caller_src_path: header.src_path.clone(),
|
||||
procedure_id: message.procedure_id.clone(),
|
||||
dst_leaf: header.dst_leaf.clone(),
|
||||
})
|
||||
.is_err()
|
||||
{
|
||||
return self.emit_fault_if_possible(key, ProtocolFault::INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
if message.procedure_id == INTROSPECTION_PROCEDURE_ID {
|
||||
if let Some(key) = &key {
|
||||
self.hooks.activate_pending(key);
|
||||
}
|
||||
return self.handle_introspection(&header, key);
|
||||
}
|
||||
|
||||
@@ -34,11 +49,7 @@ impl ProtocolEndpoint {
|
||||
Some(leaf_name) => self
|
||||
.leaves
|
||||
.get(leaf_name)
|
||||
.map(|leaf| {
|
||||
leaf.procedures
|
||||
.iter()
|
||||
.any(|procedure| procedure == &message.procedure_id)
|
||||
})
|
||||
.map(|leaf| leaf.procedures.iter().any(|procedure| procedure == &message.procedure_id))
|
||||
.unwrap_or(false),
|
||||
None => self.endpoint_procedures.contains(&message.procedure_id),
|
||||
};
|
||||
@@ -56,28 +67,10 @@ impl ProtocolEndpoint {
|
||||
return self.emit_fault_if_possible(key, fault);
|
||||
}
|
||||
|
||||
if let Some(hook) = &message.response_hook
|
||||
&& hook.return_path != self.path
|
||||
if let Some(key) = &key
|
||||
&& self.hooks.activate_pending(key).is_none()
|
||||
{
|
||||
if self
|
||||
.hooks
|
||||
.insert_pending(PendingHook {
|
||||
return_path: hook.return_path.clone(),
|
||||
hook_id: hook.hook_id,
|
||||
caller_src_path: header.src_path.clone(),
|
||||
procedure_id: message.procedure_id.clone(),
|
||||
dst_leaf: header.dst_leaf.clone(),
|
||||
})
|
||||
.is_err()
|
||||
{
|
||||
return self.emit_fault_if_possible(key, ProtocolFault::INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
if let Some(key) = &key
|
||||
&& self.hooks.activate_pending(key).is_none()
|
||||
{
|
||||
return self.emit_fault_if_possible(Some(key.clone()), ProtocolFault::INTERNAL_ERROR);
|
||||
}
|
||||
return self.emit_fault_if_possible(Some(key.clone()), ProtocolFault::INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
Ok(EndpointOutcome::event(LocalEvent::Call { header, message }))
|
||||
@@ -112,9 +105,7 @@ impl Endpoint for ProtocolEndpoint {
|
||||
RouteDecision::Child(index) => {
|
||||
Ok(EndpointOutcome::forward(RouteDecision::Child(index), frame))
|
||||
}
|
||||
RouteDecision::Parent => {
|
||||
Ok(EndpointOutcome::forward(RouteDecision::Parent, frame))
|
||||
}
|
||||
RouteDecision::Parent => Ok(EndpointOutcome::forward(RouteDecision::Parent, frame)),
|
||||
RouteDecision::Drop => Ok(EndpointOutcome::dropped()),
|
||||
RouteDecision::Local => {
|
||||
let (header, payload) = parsed.into_parts();
|
||||
@@ -125,44 +116,36 @@ impl Endpoint for ProtocolEndpoint {
|
||||
}
|
||||
}
|
||||
}
|
||||
PacketType::Data => {
|
||||
match self.decide_route(&header.dst_path) {
|
||||
RouteDecision::Local => {
|
||||
let (header, payload) = parsed.into_parts();
|
||||
let message = deserialize_archived_bytes::<
|
||||
ArchivedDataMessage,
|
||||
crate::protocol::DataMessage,
|
||||
>(payload)?;
|
||||
self.handle_local_data(header, message)
|
||||
}
|
||||
RouteDecision::Child(index) => {
|
||||
Ok(EndpointOutcome::forward(RouteDecision::Child(index), frame))
|
||||
}
|
||||
RouteDecision::Parent => {
|
||||
Ok(EndpointOutcome::forward(RouteDecision::Parent, frame))
|
||||
}
|
||||
RouteDecision::Drop => Ok(EndpointOutcome::dropped()),
|
||||
PacketType::Data => match self.decide_route(&header.dst_path) {
|
||||
RouteDecision::Local => {
|
||||
let (header, payload) = parsed.into_parts();
|
||||
let message = deserialize_archived_bytes::<
|
||||
ArchivedDataMessage,
|
||||
crate::protocol::DataMessage,
|
||||
>(payload)?;
|
||||
self.handle_local_data(header, message)
|
||||
}
|
||||
}
|
||||
PacketType::Fault => {
|
||||
match self.decide_route(&header.dst_path) {
|
||||
RouteDecision::Local => {
|
||||
let (header, payload) = parsed.into_parts();
|
||||
let message = deserialize_archived_bytes::<
|
||||
ArchivedFaultMessage,
|
||||
crate::protocol::FaultMessage,
|
||||
>(payload)?;
|
||||
self.handle_local_fault(header, message)
|
||||
}
|
||||
RouteDecision::Child(index) => {
|
||||
Ok(EndpointOutcome::forward(RouteDecision::Child(index), frame))
|
||||
}
|
||||
RouteDecision::Parent => {
|
||||
Ok(EndpointOutcome::forward(RouteDecision::Parent, frame))
|
||||
}
|
||||
RouteDecision::Drop => Ok(EndpointOutcome::dropped()),
|
||||
RouteDecision::Child(index) => {
|
||||
Ok(EndpointOutcome::forward(RouteDecision::Child(index), frame))
|
||||
}
|
||||
}
|
||||
RouteDecision::Parent => Ok(EndpointOutcome::forward(RouteDecision::Parent, frame)),
|
||||
RouteDecision::Drop => Ok(EndpointOutcome::dropped()),
|
||||
},
|
||||
PacketType::Fault => match self.decide_route(&header.dst_path) {
|
||||
RouteDecision::Local => {
|
||||
let (header, payload) = parsed.into_parts();
|
||||
let message = deserialize_archived_bytes::<
|
||||
ArchivedFaultMessage,
|
||||
crate::protocol::FaultMessage,
|
||||
>(payload)?;
|
||||
self.handle_local_fault(header, message)
|
||||
}
|
||||
RouteDecision::Child(index) => {
|
||||
Ok(EndpointOutcome::forward(RouteDecision::Child(index), frame))
|
||||
}
|
||||
RouteDecision::Parent => Ok(EndpointOutcome::forward(RouteDecision::Parent, frame)),
|
||||
RouteDecision::Drop => Ok(EndpointOutcome::dropped()),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user