ergot_base/
lib.rs

1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(any(test, feature = "std")), no_std)]
3
4pub mod address;
5pub mod interface_manager;
6pub mod nash;
7pub mod net_stack;
8pub mod socket;
9
10pub use address::Address;
11use interface_manager::InterfaceSendError;
12use log::warn;
13use nash::NameHash;
14pub use net_stack::{NetStack, NetStackSendError};
15use serde::{Deserialize, Serialize};
16
17#[derive(Debug, Clone, Copy, PartialEq)]
18pub struct FrameKind(pub u8);
19
20#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
21pub struct Key(pub [u8; 8]);
22
23#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
24pub struct ProtocolError(pub u16);
25
26#[derive(Debug, Clone)]
27pub struct AnyAllAppendix {
28    pub key: Key,
29    pub nash: Option<NameHash>,
30}
31
32#[derive(Debug, Clone)]
33pub struct Header {
34    pub src: Address,
35    pub dst: Address,
36    pub any_all: Option<AnyAllAppendix>,
37    pub seq_no: Option<u16>,
38    pub kind: FrameKind,
39    pub ttl: u8,
40}
41
42#[derive(Debug, Clone)]
43pub struct HeaderSeq {
44    pub src: Address,
45    pub dst: Address,
46    pub any_all: Option<AnyAllAppendix>,
47    pub seq_no: u16,
48    pub kind: FrameKind,
49    pub ttl: u8,
50}
51
52impl FrameKind {
53    pub const RESERVED: Self = Self(0);
54    pub const ENDPOINT_REQ: Self = Self(1);
55    pub const ENDPOINT_RESP: Self = Self(2);
56    pub const TOPIC_MSG: Self = Self(3);
57    pub const PROTOCOL_ERROR: Self = Self(u8::MAX);
58}
59
60impl ProtocolError {
61    pub const RESERVED: Self = Self(0);
62    // 1..11: SocketSendError
63    pub const SSE_NO_SPACE: Self = Self(1);
64    pub const SSE_DESER_FAILED: Self = Self(2);
65    pub const SSE_TYPE_MISMATCH: Self = Self(3);
66    pub const SSE_WHAT_THE_HELL: Self = Self(4);
67    // 11..21: InterfaceSendError
68    pub const ISE_DESTINATION_LOCAL: Self = Self(11);
69    pub const ISE_NO_ROUTE_TO_DEST: Self = Self(12);
70    pub const ISE_INTERFACE_FULL: Self = Self(13);
71    pub const ISE_PLACEHOLDER_OH_NO: Self = Self(14);
72    pub const ISE_ANY_PORT_MISSING_KEY: Self = Self(15);
73    pub const ISE_TTL_EXPIRED: Self = Self(16);
74    // 21..31: NetStackSendError
75    pub const NSSE_NO_ROUTE: Self = Self(21);
76    pub const NSSE_ANY_PORT_MISSING_KEY: Self = Self(22);
77    pub const NSSE_WRONG_PORT_KIND: Self = Self(23);
78    pub const NSSE_ANY_PORT_NOT_UNIQUE: Self = Self(24);
79    pub const NSSE_ALL_PORT_MISSING_KEY: Self = Self(25);
80}
81
82impl Header {
83    #[inline]
84    pub fn with_seq(self, seq_no: u16) -> HeaderSeq {
85        let Self {
86            src,
87            dst,
88            any_all,
89            seq_no: _,
90            kind,
91            ttl,
92        } = self;
93        HeaderSeq {
94            src,
95            dst,
96            any_all,
97            seq_no,
98            kind,
99            ttl,
100        }
101    }
102
103    #[inline]
104    pub fn to_headerseq_or_with_seq<F: FnOnce() -> u16>(&self, f: F) -> HeaderSeq {
105        HeaderSeq {
106            src: self.src,
107            dst: self.dst,
108            any_all: self.any_all.clone(),
109            seq_no: self.seq_no.unwrap_or_else(f),
110            kind: self.kind,
111            ttl: self.ttl,
112        }
113    }
114
115    #[inline]
116    pub fn decrement_ttl(&mut self) -> Result<(), InterfaceSendError> {
117        self.ttl = self.ttl.checked_sub(1).ok_or_else(|| {
118            warn!("Header TTL expired: {self:?}");
119            InterfaceSendError::TtlExpired
120        })?;
121        Ok(())
122    }
123}
124
125impl From<HeaderSeq> for Header {
126    fn from(val: HeaderSeq) -> Self {
127        Self {
128            src: val.src,
129            dst: val.dst,
130            any_all: val.any_all.clone(),
131            seq_no: Some(val.seq_no),
132            kind: val.kind,
133            ttl: val.ttl,
134        }
135    }
136}
137
138pub const DEFAULT_TTL: u8 = 16;