1use malloc_size_of_derive::MallocSizeOf;
2use serde::{Deserialize, Serialize};
3
4use crate::Data;
5
6const MAX_TOKEN_LENGTH: usize = 256;
7
8#[derive(Clone, Serialize, Deserialize, Debug, MallocSizeOf)]
10pub enum Token {
11 Handshake,
12 Na,
13 SimultaneousConnect,
14 Protocol(Protocol),
15 UnknownProtocol(Data),
16}
17
18impl Token {
19 pub const fn name(&self) -> &'static [u8] {
20 match self {
21 Self::Handshake => b"\x13/multistream/1.0.0\n",
22 Self::Na => b"\x03na\n",
23 Self::SimultaneousConnect => b"\x1d/libp2p/simultaneous-connect\n",
24 Self::Protocol(v) => v.name(),
25 Self::UnknownProtocol(_) => b"",
26 }
27 }
28
29 pub const ALL: &'static [Self] = &[
31 Token::Handshake,
32 Token::Na,
33 Token::SimultaneousConnect,
34 Token::Protocol(Protocol::Auth(AuthKind::Noise)),
35 Token::Protocol(Protocol::Mux(MuxKind::Yamux1_0_0)),
36 Token::Protocol(Protocol::Mux(MuxKind::YamuxNoNewLine1_0_0)),
37 Token::Protocol(Protocol::Stream(StreamKind::Status(
38 StatusAlgorithm::MinaNodeStatus,
39 ))),
40 Token::Protocol(Protocol::Stream(StreamKind::Bitswap(
41 BitswapAlgorithm::MinaBitswap,
42 ))),
43 Token::Protocol(Protocol::Stream(StreamKind::Bitswap(
44 BitswapAlgorithm::MinaBitswap1_0_0,
45 ))),
46 Token::Protocol(Protocol::Stream(StreamKind::Bitswap(
47 BitswapAlgorithm::MinaBitswap1_1_0,
48 ))),
49 Token::Protocol(Protocol::Stream(StreamKind::Bitswap(
50 BitswapAlgorithm::MinaBitswap1_2_0,
51 ))),
52 Token::Protocol(Protocol::Stream(StreamKind::Ping(PingAlgorithm::Ping1_0_0))),
53 Token::Protocol(Protocol::Stream(StreamKind::Identify(
54 IdentifyAlgorithm::Identify1_0_0,
55 ))),
56 Token::Protocol(Protocol::Stream(StreamKind::Identify(
57 IdentifyAlgorithm::IdentifyPush1_0_0,
58 ))),
59 Token::Protocol(Protocol::Stream(StreamKind::Discovery(
60 DiscoveryAlgorithm::Kademlia1_0_0,
61 ))),
62 Token::Protocol(Protocol::Stream(StreamKind::Broadcast(
63 BroadcastAlgorithm::Floodsub1_0_0,
64 ))),
65 Token::Protocol(Protocol::Stream(StreamKind::Broadcast(
66 BroadcastAlgorithm::Meshsub1_0_0,
67 ))),
68 Token::Protocol(Protocol::Stream(StreamKind::Broadcast(
69 BroadcastAlgorithm::Meshsub1_1_0,
70 ))),
71 Token::Protocol(Protocol::Stream(StreamKind::Rpc(RpcAlgorithm::Rpc0_0_1))),
72 ];
73}
74
75#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq)]
76pub enum Protocol {
77 Auth(AuthKind),
78 Mux(MuxKind),
79 Stream(StreamKind),
80}
81
82impl malloc_size_of::MallocSizeOf for Protocol {
83 fn size_of(&self, _ops: &mut malloc_size_of::MallocSizeOfOps) -> usize {
84 0
85 }
86}
87
88impl Protocol {
89 pub const fn name(&self) -> &'static [u8] {
90 match self {
91 Self::Auth(v) => v.name(),
92 Self::Mux(v) => v.name(),
93 Self::Stream(v) => v.name(),
94 }
95 }
96
97 pub const fn name_str(&self) -> &'static str {
98 match self {
99 Self::Auth(v) => v.name_str(),
100 Self::Mux(v) => v.name_str(),
101 Self::Stream(v) => v.name_str(),
102 }
103 }
104}
105
106#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq)]
107pub enum AuthKind {
108 Noise,
109}
110
111impl AuthKind {
112 pub const fn name(&self) -> &'static [u8] {
113 b"\x07/noise\n"
114 }
115
116 pub const fn name_str(&self) -> &'static str {
117 "/noise"
118 }
119}
120
121#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq)]
122pub enum MuxKind {
123 Yamux1_0_0,
124 YamuxNoNewLine1_0_0,
125}
126
127impl MuxKind {
128 pub const fn name(&self) -> &'static [u8] {
129 match self {
130 Self::Yamux1_0_0 => b"\x12/coda/yamux/1.0.0\n",
131 Self::YamuxNoNewLine1_0_0 => b"\x11/coda/yamux/1.0.0",
132 }
133 }
134
135 pub const fn name_str(&self) -> &'static str {
136 match self {
137 Self::Yamux1_0_0 => "/coda/yamux/1.0.0",
138 Self::YamuxNoNewLine1_0_0 => "/coda/yamux/1.0.0",
139 }
140 }
141}
142
143#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq)]
144pub enum StreamKind {
145 Status(StatusAlgorithm),
146 Bitswap(BitswapAlgorithm),
147 Ping(PingAlgorithm),
148 Identify(IdentifyAlgorithm),
149 Discovery(DiscoveryAlgorithm),
150 Broadcast(BroadcastAlgorithm),
151 Rpc(RpcAlgorithm),
152}
153
154impl malloc_size_of::MallocSizeOf for StreamKind {
155 fn size_of(&self, _ops: &mut malloc_size_of::MallocSizeOfOps) -> usize {
156 0
157 }
158}
159
160impl StreamKind {
161 pub const fn name(&self) -> &'static [u8] {
162 match self {
163 Self::Status(v) => v.name(),
164 Self::Bitswap(v) => v.name(),
165 Self::Ping(v) => v.name(),
166 Self::Identify(v) => v.name(),
167 Self::Discovery(v) => v.name(),
168 Self::Broadcast(v) => v.name(),
169 Self::Rpc(v) => v.name(),
170 }
171 }
172
173 pub const fn name_str(&self) -> &'static str {
174 match self {
175 Self::Status(v) => v.name_str(),
176 Self::Bitswap(v) => v.name_str(),
177 Self::Ping(v) => v.name_str(),
178 Self::Identify(v) => v.name_str(),
179 Self::Discovery(v) => v.name_str(),
180 Self::Broadcast(v) => v.name_str(),
181 Self::Rpc(v) => v.name_str(),
182 }
183 }
184}
185
186#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq)]
187pub enum StatusAlgorithm {
188 MinaNodeStatus,
189}
190
191impl StatusAlgorithm {
192 pub const fn name(&self) -> &'static [u8] {
193 match self {
194 Self::MinaNodeStatus => b"\x12/mina/node-status\n",
195 }
196 }
197
198 pub const fn name_str(&self) -> &'static str {
199 match self {
200 Self::MinaNodeStatus => "/mina/node-status",
201 }
202 }
203}
204
205#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq)]
206pub enum BitswapAlgorithm {
207 MinaBitswap,
208 MinaBitswap1_0_0,
209 MinaBitswap1_1_0,
210 MinaBitswap1_2_0,
211}
212
213impl malloc_size_of::MallocSizeOf for BitswapAlgorithm {
214 fn size_of(&self, _ops: &mut malloc_size_of::MallocSizeOfOps) -> usize {
215 0
216 }
217}
218
219impl BitswapAlgorithm {
220 pub const fn name(&self) -> &'static [u8] {
221 match self {
222 Self::MinaBitswap => b"\x24/mina/bitswap-exchange/ipfs/bitswap\n",
223 Self::MinaBitswap1_0_0 => b"\x2a/mina/bitswap-exchange/ipfs/bitswap/1.0.0\n",
224 Self::MinaBitswap1_1_0 => b"\x2a/mina/bitswap-exchange/ipfs/bitswap/1.1.0\n",
225 Self::MinaBitswap1_2_0 => b"\x2a/mina/bitswap-exchange/ipfs/bitswap/1.2.0\n",
226 }
227 }
228
229 pub const fn name_str(&self) -> &'static str {
230 match self {
231 Self::MinaBitswap => "/mina/bitswap-exchange/ipfs/bitswap",
232 Self::MinaBitswap1_0_0 => "/mina/bitswap-exchange/ipfs/bitswap/1.0.0",
233 Self::MinaBitswap1_1_0 => "/mina/bitswap-exchange/ipfs/bitswap/1.1.0",
234 Self::MinaBitswap1_2_0 => "/mina/bitswap-exchange/ipfs/bitswap/1.2.0",
235 }
236 }
237}
238
239#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq)]
240pub enum PingAlgorithm {
241 Ping1_0_0,
242}
243
244impl PingAlgorithm {
245 pub const fn name(&self) -> &'static [u8] {
246 match self {
247 Self::Ping1_0_0 => b"\x11/ipfs/ping/1.0.0\n",
248 }
249 }
250
251 pub const fn name_str(&self) -> &'static str {
252 match self {
253 Self::Ping1_0_0 => "/ipfs/ping/1.0.0",
254 }
255 }
256}
257
258#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq)]
259pub enum IdentifyAlgorithm {
260 Identify1_0_0,
261 IdentifyPush1_0_0,
262}
263
264impl IdentifyAlgorithm {
265 pub const fn name(&self) -> &'static [u8] {
266 match self {
267 Self::Identify1_0_0 => b"\x0f/ipfs/id/1.0.0\n",
268 Self::IdentifyPush1_0_0 => b"\x14/ipfs/id/push/1.0.0\n",
269 }
270 }
271
272 pub const fn name_str(&self) -> &'static str {
273 match self {
274 Self::Identify1_0_0 => "/ipfs/id/1.0.0",
275 Self::IdentifyPush1_0_0 => "/ipfs/id/push/1.0.0",
276 }
277 }
278}
279
280#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq)]
281pub enum DiscoveryAlgorithm {
282 Kademlia1_0_0,
283}
284
285impl DiscoveryAlgorithm {
286 pub const fn name(&self) -> &'static [u8] {
287 match self {
288 Self::Kademlia1_0_0 => b"\x10/coda/kad/1.0.0\n",
289 }
290 }
291
292 pub const fn name_str(&self) -> &'static str {
293 match self {
294 Self::Kademlia1_0_0 => "/coda/kad/1.0.0",
295 }
296 }
297}
298
299#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq)]
300pub enum BroadcastAlgorithm {
301 Floodsub1_0_0,
302 Meshsub1_0_0,
303 Meshsub1_1_0,
304}
305
306impl malloc_size_of::MallocSizeOf for BroadcastAlgorithm {
307 fn size_of(&self, _ops: &mut malloc_size_of::MallocSizeOfOps) -> usize {
308 0
309 }
310}
311
312impl BroadcastAlgorithm {
313 pub const fn name(&self) -> &'static [u8] {
314 match self {
315 Self::Floodsub1_0_0 => b"\x10/floodsub/1.0.0\n",
316 Self::Meshsub1_0_0 => b"\x0f/meshsub/1.0.0\n",
317 Self::Meshsub1_1_0 => b"\x0f/meshsub/1.1.0\n",
318 }
319 }
320
321 pub const fn name_str(&self) -> &'static str {
322 match self {
323 Self::Floodsub1_0_0 => "/floodsub/1.0.0",
324 Self::Meshsub1_0_0 => "/meshsub/1.0.0",
325 Self::Meshsub1_1_0 => "/meshsub/1.1.0",
326 }
327 }
328}
329
330#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq)]
331pub enum RpcAlgorithm {
332 Rpc0_0_1,
333}
334
335impl RpcAlgorithm {
336 pub const fn name(&self) -> &'static [u8] {
337 match self {
338 Self::Rpc0_0_1 => b"\x10coda/rpcs/0.0.1\n",
339 }
340 }
341
342 pub const fn name_str(&self) -> &'static str {
343 match self {
344 Self::Rpc0_0_1 => "coda/rpcs/0.0.1",
345 }
346 }
347}
348
349#[derive(Default, Serialize, Deserialize, Debug, Clone, MallocSizeOf)]
350pub struct State {
351 pub buffer: Vec<u8>,
352}
353
354#[derive(Debug)]
355pub struct ParseTokenError;
356
357impl State {
358 pub fn put(&mut self, data: &[u8]) {
359 self.buffer.extend_from_slice(data);
360 }
361
362 pub fn parse_token(&mut self) -> Result<Option<Token>, ParseTokenError> {
365 use unsigned_varint::decode::{self, Error::*};
366
367 let (len, rem) = match decode::usize(&self.buffer) {
368 Ok(v) => v,
369 Err(Insufficient) => return Ok(None),
370 Err(_) => return Err(ParseTokenError),
371 };
372 let len_length = self.buffer.len() - rem.len();
373
374 if len > MAX_TOKEN_LENGTH {
375 return Err(ParseTokenError);
376 }
377
378 if len_length > MAX_TOKEN_LENGTH {
379 return Err(ParseTokenError);
380 }
381
382 if self.buffer.len() < len_length + len {
383 return Ok(None);
384 }
385
386 let token = Token::ALL
388 .iter()
389 .find(|t| t.name() == &self.buffer[..(len_length + len)]);
390 let name = self.buffer.drain(..(len_length + len)).collect::<Vec<_>>();
391 Ok(Some(token.cloned().unwrap_or(Token::UnknownProtocol(
392 Data(name.into_boxed_slice()),
393 ))))
394 }
395}