datex_core/global/protocol_structures/
routing_header.rs

1use super::serializable::Serializable;
2use crate::values::core_values::endpoint::Endpoint;
3use binrw::{BinRead, BinWrite};
4use modular_bitfield::prelude::*;
5
6// 2 bit
7#[derive(Debug, PartialEq, Clone, Default, Specifier)]
8#[bits = 2]
9pub enum SignatureType {
10    #[default]
11    None = 0b00,
12    Unencrypted = 0b10,
13    Encrypted = 0b11,
14}
15
16// 1 bit
17#[derive(Debug, PartialEq, Clone, Default, Specifier)]
18pub enum EncryptionType {
19    #[default]
20    Unencrypted = 0b0,
21    Encrypted = 0b1,
22}
23
24// 1 bit
25#[derive(Debug, PartialEq, Clone, Default, Specifier)]
26pub enum BlockSize {
27    #[default]
28    Default = 0b0,
29    Large = 0b1,
30}
31
32// 2 bit + 1 bit + 1 bit + 4 bit = 1 byte
33#[bitfield]
34#[derive(BinWrite, BinRead, Clone, Default, Copy, Debug, PartialEq)]
35#[bw(map = |&x| Self::into_bytes(x))]
36#[br(map = Self::from_bytes)]
37pub struct Flags {
38    pub signature_type: SignatureType,
39    pub encryption_type: EncryptionType,
40    pub block_size: BlockSize,
41    pub is_bounce_back: bool,
42
43    #[allow(unused)]
44    unused_0: bool,
45    #[allow(unused)]
46    unused_1: bool,
47    #[allow(unused)]
48    unused_2: bool,
49}
50
51// 1 byte
52#[bitfield]
53#[derive(BinWrite, BinRead, Clone, Default, Copy, Debug, PartialEq)]
54#[bw(map = |&x| Self::into_bytes(x))]
55#[br(map = Self::from_bytes)]
56pub struct ReceiverFlags {
57    pub has_pointer_id: bool,
58    pub has_endpoints: bool,
59    pub has_endpoint_keys: bool,
60
61    #[allow(unused)]
62    unused_0: bool,
63    #[allow(unused)]
64    unused_1: bool,
65    #[allow(unused)]
66    unused_2: bool,
67    #[allow(unused)]
68    unused_3: bool,
69    #[allow(unused)]
70    unused_4: bool,
71}
72
73// 1 byte + 18 byte + 2 byte + 4 byte + 1 byte = 26 bytes
74#[derive(Debug, Clone, Default, BinWrite, BinRead, PartialEq)]
75pub struct PointerId {
76    pub pointer_type: u8,
77    pub identifier: [u8; 18],
78    pub instance: u16,
79    pub timestamp: u32,
80    pub counter: u8,
81}
82
83// <count>: 2 byte + (21 byte * count)
84// min: 2 bytes
85#[derive(Debug, Clone, Default, BinWrite, BinRead, PartialEq)]
86pub struct ReceiverEndpoints {
87    pub count: u16,
88    #[br(count = count)]
89    pub endpoints: Vec<Endpoint>,
90}
91
92impl ReceiverEndpoints {
93    pub fn new(endpoints: Vec<Endpoint>) -> Self {
94        let count = endpoints.len() as u16;
95        ReceiverEndpoints { count, endpoints }
96    }
97}
98
99// <count>: 2 byte + (21 byte * count) + (512 byte * count)
100// min: 2 bytes
101#[derive(Debug, Clone, Default, BinWrite, BinRead, PartialEq)]
102pub struct ReceiverEndpointsWithKeys {
103    pub count: u16,
104    #[br(count = count)]
105    pub endpoints_with_keys: Vec<(Endpoint, [u8; 512])>,
106}
107
108// min: 1 byte
109#[derive(Debug, Clone, Default, BinWrite, BinRead, PartialEq)]
110pub struct Receivers {
111    pub flags: ReceiverFlags,
112
113    #[brw(if(flags.has_pointer_id()))]
114    pub pointer_id: Option<PointerId>,
115
116    #[brw(if(flags.has_endpoints() && !flags.has_endpoint_keys()))]
117    pub endpoints: Option<ReceiverEndpoints>,
118    #[brw(if(flags.has_endpoints() && flags.has_endpoint_keys()))]
119    pub endpoints_with_keys: Option<ReceiverEndpointsWithKeys>,
120}
121
122// min: 11 byte + 2 byte + 21 byte + 1 byte = 35 bytes
123#[derive(Debug, Clone, BinWrite, BinRead, PartialEq)]
124#[brw(little, magic = b"\x01\x64")]
125pub struct RoutingHeader {
126    pub version: u8,
127    pub distance: i8,
128    pub ttl: u8,
129    pub flags: Flags,
130
131    #[brw(
132        if(flags.block_size() == BlockSize::Default)
133    )]
134    pub block_size_u16: Option<u16>,
135
136    #[brw(
137        if(flags.block_size() == BlockSize::Large),
138        assert(
139            match flags.block_size() {
140                BlockSize::Large => block_size_u32.is_some(),
141                BlockSize::Default => block_size_u16.is_some(),
142            },
143            "No valid block size found"
144        ),
145    )]
146    pub block_size_u32: Option<u32>,
147
148    pub sender: Endpoint,
149    // TODO #115: add custom match receiver queries
150    pub receivers: Receivers,
151}
152
153impl Serializable for RoutingHeader {}
154
155impl Default for RoutingHeader {
156    fn default() -> Self {
157        RoutingHeader {
158            version: 1,
159            distance: 0,
160            ttl: 42,
161            flags: Flags::new(),
162            block_size_u16: Some(26),
163            block_size_u32: None,
164            sender: Endpoint::default(),
165            receivers: Receivers::default(),
166        }
167    }
168}