tor_cell/relaycell/
conflux.rs1use super::msg::{empty_body, Body};
4
5use amplify::Getters;
6use caret::caret_int;
7use derive_deftly::Deftly;
8
9use tor_bytes::{EncodeResult, Error, Reader, Result, Writer};
10use tor_memquota::derive_deftly_template_HasMemoryCost;
11
12const CONFLUX_LINK_VERSION: u8 = 1;
14
15const V1_LINK_NONCE_LEN: usize = 32;
17
18macro_rules! impl_link_wrapper {
20 ($wrapper:ty) => {
21 impl $wrapper {
22 pub fn version(&self) -> u8 {
24 self.0.version
25 }
26
27 pub fn payload(&self) -> &V1LinkPayload {
29 &self.0.payload
30 }
31 }
32 };
33}
34
35#[derive(Debug, Clone, Deftly)]
37#[derive_deftly(HasMemoryCost)]
38pub struct ConfluxLink(Link);
39
40impl_link_wrapper!(ConfluxLink);
41
42impl Body for ConfluxLink {
43 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
44 Link::decode_from_reader(r).map(Self)
45 }
46
47 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
48 self.0.encode_onto(w)
49 }
50}
51
52#[derive(Debug, Clone, Deftly)]
54#[derive_deftly(HasMemoryCost)]
55pub struct ConfluxLinked(Link);
56
57impl_link_wrapper!(ConfluxLinked);
58
59impl Body for ConfluxLinked {
60 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
61 Link::decode_from_reader(r).map(Self)
62 }
63
64 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
65 self.0.encode_onto(w)
66 }
67}
68
69#[derive(Debug, Clone, Deftly)]
71#[derive_deftly(HasMemoryCost)]
72struct Link {
73 version: u8,
77 payload: V1LinkPayload,
82}
83
84#[derive(Debug, Clone, Deftly, Getters)]
86#[derive_deftly(HasMemoryCost)]
87pub struct V1LinkPayload {
88 nonce: [u8; V1_LINK_NONCE_LEN],
90 last_seqno_sent: u64,
92 last_seqno_recv: u64,
94 desired_ux: V1DesiredUx,
96}
97
98caret_int! {
99 #[derive(Deftly)]
101 #[derive_deftly(HasMemoryCost)]
102 pub struct V1DesiredUx(u8) {
103 NO_OPINION = 0x0,
105 MIN_LATENCY = 0x1,
107 LOW_MEM_LATENCY = 0x2,
109 HIGH_THROUGHPUT = 0x3,
111 LOW_MEM_THROUGHPUT = 0x4,
113 }
114}
115
116impl Body for Link {
117 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
118 let version = r.take_u8()?;
119 if version != CONFLUX_LINK_VERSION {
120 return Err(Error::InvalidMessage(
121 "Unrecognized CONFLUX_LINK/CONFLUX_LINKED version.".into(),
122 ));
123 }
124
125 let payload = V1LinkPayload::decode_from_reader(r)?;
126
127 Ok(Self { version, payload })
128 }
129
130 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
131 w.write(&self.version)?;
132 self.payload.encode_onto(w)?;
133 Ok(())
134 }
135}
136
137impl Body for V1LinkPayload {
138 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
139 let mut nonce = [0; V1_LINK_NONCE_LEN];
140 r.take_into(&mut nonce)?;
141
142 let last_seqno_sent = r.take_u64()?;
143 let last_seqno_recv = r.take_u64()?;
144 let desired_ux = r.take_u8()?.into();
145
146 Ok(V1LinkPayload {
147 nonce,
148 last_seqno_sent,
149 last_seqno_recv,
150 desired_ux,
151 })
152 }
153
154 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
155 let V1LinkPayload {
156 nonce,
157 last_seqno_sent,
158 last_seqno_recv,
159 desired_ux,
160 } = self;
161
162 w.write(&nonce)?;
163 w.write_u64(last_seqno_sent);
164 w.write_u64(last_seqno_recv);
165 w.write_u8(desired_ux.into());
166
167 Ok(())
168 }
169}
170
171#[derive(Clone, Debug, Deftly, Getters)]
174#[derive_deftly(HasMemoryCost)]
175pub struct ConfluxSwitch {
176 seqno: u32,
178}
179
180impl Body for ConfluxSwitch {
181 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
182 let seqno = r.take_u32()?;
183 Ok(Self { seqno })
184 }
185
186 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
187 w.write(&self.seqno)?;
188 Ok(())
189 }
190}
191
192empty_body! {
193 pub struct ConfluxLinkedAck {}
195}