tor_cell/relaycell/
conflux.rs
1use super::msg::{empty_body, Body};
4
5use amplify::Getters;
6use caret::caret_int;
7use derive_deftly::Deftly;
8use rand::{CryptoRng, Rng, RngCore};
9
10use tor_bytes::{EncodeResult, Error, Readable, Reader, Result, Writeable, Writer};
11use tor_llcrypto::util::ct::CtByteArray;
12use tor_memquota::derive_deftly_template_HasMemoryCost;
13
14const CONFLUX_LINK_VERSION: u8 = 1;
16
17const V1_LINK_NONCE_LEN: usize = 32;
19
20macro_rules! impl_link_wrapper {
22 ($wrapper:ty) => {
23 impl $wrapper {
24 pub fn version(&self) -> u8 {
26 self.0.version
27 }
28
29 pub fn payload(&self) -> &V1LinkPayload {
31 &self.0.payload
32 }
33 }
34 };
35}
36
37#[derive(Debug, Clone, Deftly)]
39#[derive_deftly(HasMemoryCost)]
40pub struct ConfluxLink(Link);
41
42impl ConfluxLink {
43 pub fn new(payload: V1LinkPayload) -> Self {
45 let link = Link {
46 version: CONFLUX_LINK_VERSION,
47 payload,
48 };
49
50 Self(link)
51 }
52}
53
54impl_link_wrapper!(ConfluxLink);
55
56impl Body for ConfluxLink {
57 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
58 Link::decode_from_reader(r).map(Self)
59 }
60
61 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
62 self.0.encode_onto(w)
63 }
64}
65
66#[derive(Debug, Clone, Deftly)]
68#[derive_deftly(HasMemoryCost)]
69pub struct ConfluxLinked(Link);
70
71impl ConfluxLinked {
72 pub fn new(payload: V1LinkPayload) -> Self {
74 let link = Link {
75 version: CONFLUX_LINK_VERSION,
76 payload,
77 };
78
79 Self(link)
80 }
81}
82
83impl_link_wrapper!(ConfluxLinked);
84
85impl Body for ConfluxLinked {
86 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
87 Link::decode_from_reader(r).map(Self)
88 }
89
90 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
91 self.0.encode_onto(w)
92 }
93}
94
95#[derive(Debug, Clone, Deftly)]
97#[derive_deftly(HasMemoryCost)]
98struct Link {
99 version: u8,
103 payload: V1LinkPayload,
108}
109
110#[derive(Debug, Clone, Copy, Deftly, PartialEq, Eq)]
112#[derive_deftly(HasMemoryCost)]
113pub struct V1Nonce(CtByteArray<V1_LINK_NONCE_LEN>);
114
115impl V1Nonce {
116 pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> V1Nonce {
118 let mut nonce = [0_u8; V1_LINK_NONCE_LEN];
119 rng.fill(&mut nonce[..]);
120 Self(nonce.into())
121 }
122}
123
124impl Readable for V1Nonce {
125 fn take_from(r: &mut Reader<'_>) -> Result<Self> {
126 Ok(Self(Readable::take_from(r)?))
127 }
128}
129
130impl Writeable for V1Nonce {
131 fn write_onto<W: Writer + ?Sized>(&self, w: &mut W) -> EncodeResult<()> {
132 self.0.write_onto(w)
133 }
134}
135
136#[derive(Debug, Clone, Deftly, Getters)]
138#[derive_deftly(HasMemoryCost)]
139pub struct V1LinkPayload {
140 nonce: V1Nonce,
142 last_seqno_sent: u64,
144 last_seqno_recv: u64,
146 desired_ux: V1DesiredUx,
148}
149
150impl V1LinkPayload {
151 pub fn new(nonce: V1Nonce, desired_ux: V1DesiredUx) -> Self {
153 Self {
154 nonce,
155 last_seqno_sent: 0,
159 last_seqno_recv: 0,
160 desired_ux,
161 }
162 }
163
164 pub fn set_last_seqno_sent(&mut self, seqno: u64) {
166 self.last_seqno_sent = seqno;
167 }
168
169 pub fn set_last_seqno_recv(&mut self, seqno: u64) {
171 self.last_seqno_recv = seqno;
172 }
173}
174
175caret_int! {
176 #[derive(Deftly)]
178 #[derive_deftly(HasMemoryCost)]
179 pub struct V1DesiredUx(u8) {
180 NO_OPINION = 0x0,
182 MIN_LATENCY = 0x1,
184 LOW_MEM_LATENCY = 0x2,
186 HIGH_THROUGHPUT = 0x3,
188 LOW_MEM_THROUGHPUT = 0x4,
190 }
191}
192
193impl Body for Link {
194 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
195 let version = r.take_u8()?;
196 if version != CONFLUX_LINK_VERSION {
197 return Err(Error::InvalidMessage(
198 "Unrecognized CONFLUX_LINK/CONFLUX_LINKED version.".into(),
199 ));
200 }
201
202 let payload = V1LinkPayload::decode_from_reader(r)?;
203
204 Ok(Self { version, payload })
205 }
206
207 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
208 w.write(&self.version)?;
209 self.payload.encode_onto(w)?;
210 Ok(())
211 }
212}
213
214impl Body for V1LinkPayload {
215 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
216 let nonce = r.extract()?;
217 let last_seqno_sent = r.take_u64()?;
218 let last_seqno_recv = r.take_u64()?;
219 let desired_ux = r.take_u8()?.into();
220
221 Ok(V1LinkPayload {
222 nonce,
223 last_seqno_sent,
224 last_seqno_recv,
225 desired_ux,
226 })
227 }
228
229 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
230 let V1LinkPayload {
231 nonce,
232 last_seqno_sent,
233 last_seqno_recv,
234 desired_ux,
235 } = self;
236
237 w.write(&nonce)?;
238 w.write_u64(last_seqno_sent);
239 w.write_u64(last_seqno_recv);
240 w.write_u8(desired_ux.into());
241
242 Ok(())
243 }
244}
245
246#[derive(Clone, Debug, Deftly, Getters)]
249#[derive_deftly(HasMemoryCost)]
250pub struct ConfluxSwitch {
251 #[getter(as_copy)]
253 seqno: u32,
254}
255
256impl ConfluxSwitch {
257 pub fn new(seqno: u32) -> Self {
259 Self { seqno }
260 }
261}
262
263impl Body for ConfluxSwitch {
264 fn decode_from_reader(r: &mut Reader<'_>) -> Result<Self> {
265 let seqno = r.take_u32()?;
266 Ok(Self { seqno })
267 }
268
269 fn encode_onto<W: Writer + ?Sized>(self, w: &mut W) -> EncodeResult<()> {
270 w.write(&self.seqno)?;
271 Ok(())
272 }
273}
274
275empty_body! {
276 pub struct ConfluxLinkedAck {}
278}