1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
4pub enum KnownRoute {
5 #[serde(rename = "iroh")]
6 Iroh,
7 #[serde(rename = "iroh-quic")]
8 IrohQuic,
9 #[serde(rename = "iroh-relay")]
10 IrohRelay,
11 #[serde(rename = "iroh-lan")]
12 IrohLan,
13 #[serde(rename = "ble")]
14 Ble,
15 #[serde(rename = "webrtc")]
16 WebRtc,
17 #[serde(rename = "moq")]
18 Moq,
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
22#[serde(rename_all = "kebab-case")]
23pub enum RouteFamily {
24 IrohPath,
25 IrohPhysical,
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
29#[serde(rename_all = "kebab-case")]
30pub enum RouteImplementation {
31 Core,
32 HostInstalled,
33 CarrierAdapter,
34 PathLabel,
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
38#[serde(rename_all = "kebab-case")]
39pub enum RouteLocality {
40 Nearby,
41 DirectInternet,
42 Relay,
43 Mixed,
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
47#[serde(rename_all = "kebab-case")]
48pub enum RouteMaturity {
49 Stable,
50 Experimental,
51 Unsupported,
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
55#[serde(rename_all = "camelCase")]
56pub struct RouteDescriptor {
57 #[serde(skip)]
58 pub route: KnownRoute,
59 pub id: &'static str,
60 pub base_protocol: &'static str,
61 pub family: RouteFamily,
62 pub implementation: RouteImplementation,
63 pub locality: RouteLocality,
64 pub maturity: RouteMaturity,
65 pub default_rank: u8,
66 pub browser: bool,
67 pub native: bool,
68}
69
70impl KnownRoute {
71 pub const fn as_str(self) -> &'static str {
72 match self {
73 Self::Iroh => "iroh",
74 Self::IrohQuic => "iroh-quic",
75 Self::IrohRelay => "iroh-relay",
76 Self::IrohLan => "iroh-lan",
77 Self::Ble => "ble",
78 Self::WebRtc => "webrtc",
79 Self::Moq => "moq",
80 }
81 }
82
83 pub const fn default_rank(self) -> u8 {
84 match self {
85 Self::Iroh => 6,
86 Self::IrohQuic => 1,
87 Self::IrohRelay => 5,
88 Self::IrohLan => 0,
89 Self::Ble => 2,
90 Self::WebRtc => 3,
91 Self::Moq => 4,
92 }
93 }
94
95 pub const fn descriptor(self) -> RouteDescriptor {
96 match self {
97 Self::Iroh => RouteDescriptor {
98 route: self,
99 id: "iroh",
100 base_protocol: "iroh",
101 family: RouteFamily::IrohPath,
102 implementation: RouteImplementation::Core,
103 locality: RouteLocality::Mixed,
104 maturity: RouteMaturity::Stable,
105 default_rank: 6,
106 browser: true,
107 native: true,
108 },
109 Self::IrohQuic => RouteDescriptor {
110 route: self,
111 id: "iroh-quic",
112 base_protocol: "iroh",
113 family: RouteFamily::IrohPath,
114 implementation: RouteImplementation::PathLabel,
115 locality: RouteLocality::DirectInternet,
116 maturity: RouteMaturity::Stable,
117 default_rank: 1,
118 browser: false,
119 native: true,
120 },
121 Self::IrohRelay => RouteDescriptor {
122 route: self,
123 id: "iroh-relay",
124 base_protocol: "iroh",
125 family: RouteFamily::IrohPath,
126 implementation: RouteImplementation::PathLabel,
127 locality: RouteLocality::Relay,
128 maturity: RouteMaturity::Stable,
129 default_rank: 5,
130 browser: true,
131 native: true,
132 },
133 Self::IrohLan => RouteDescriptor {
134 route: self,
135 id: "iroh-lan",
136 base_protocol: "iroh",
137 family: RouteFamily::IrohPath,
138 implementation: RouteImplementation::PathLabel,
139 locality: RouteLocality::Nearby,
140 maturity: RouteMaturity::Stable,
141 default_rank: 0,
142 browser: false,
143 native: true,
144 },
145 Self::Ble => RouteDescriptor {
146 route: self,
147 id: "ble",
148 base_protocol: "iroh",
149 family: RouteFamily::IrohPhysical,
150 implementation: RouteImplementation::HostInstalled,
151 locality: RouteLocality::Nearby,
152 maturity: RouteMaturity::Experimental,
153 default_rank: 2,
154 browser: false,
155 native: true,
156 },
157 Self::WebRtc => RouteDescriptor {
158 route: self,
159 id: "webrtc",
160 base_protocol: "iroh",
161 family: RouteFamily::IrohPhysical,
162 implementation: RouteImplementation::CarrierAdapter,
163 locality: RouteLocality::Mixed,
164 maturity: RouteMaturity::Stable,
165 default_rank: 3,
166 browser: true,
167 native: true,
168 },
169 Self::Moq => RouteDescriptor {
170 route: self,
171 id: "moq",
172 base_protocol: "iroh",
173 family: RouteFamily::IrohPhysical,
174 implementation: RouteImplementation::CarrierAdapter,
175 locality: RouteLocality::Relay,
176 maturity: RouteMaturity::Experimental,
177 default_rank: 4,
178 browser: true,
179 native: true,
180 },
181 }
182 }
183
184 pub const ALL_BY_DEFAULT_RANK: [Self; 7] = [
185 Self::IrohLan,
186 Self::IrohQuic,
187 Self::Ble,
188 Self::WebRtc,
189 Self::Moq,
190 Self::IrohRelay,
191 Self::Iroh,
192 ];
193
194 pub const DEFAULT_PRIORITY: [Self; 5] = [
195 Self::IrohLan,
196 Self::IrohQuic,
197 Self::WebRtc,
198 Self::Moq,
199 Self::IrohRelay,
200 ];
201}
202
203pub const KNOWN_ROUTE_DESCRIPTORS: [RouteDescriptor; 7] = [
204 KnownRoute::IrohLan.descriptor(),
205 KnownRoute::IrohQuic.descriptor(),
206 KnownRoute::Ble.descriptor(),
207 KnownRoute::WebRtc.descriptor(),
208 KnownRoute::Moq.descriptor(),
209 KnownRoute::IrohRelay.descriptor(),
210 KnownRoute::Iroh.descriptor(),
211];
212
213#[cfg(test)]
214pub const TRANSPORT_REGISTRY_JSON: &str = r###"{
215 "schemaVersion": 2,
216 "routes": [
217 {
218 "id": "iroh",
219 "rustVariant": "Iroh",
220 "baseProtocol": "iroh",
221 "family": "iroh-path",
222 "implementation": "core",
223 "locality": "mixed",
224 "maturity": "stable",
225 "defaultRank": 6,
226 "browser": true,
227 "native": true
228 },
229 {
230 "id": "iroh-quic",
231 "rustVariant": "IrohQuic",
232 "baseProtocol": "iroh",
233 "family": "iroh-path",
234 "implementation": "path-label",
235 "locality": "direct-internet",
236 "maturity": "stable",
237 "defaultRank": 1,
238 "browser": false,
239 "native": true
240 },
241 {
242 "id": "iroh-relay",
243 "rustVariant": "IrohRelay",
244 "baseProtocol": "iroh",
245 "family": "iroh-path",
246 "implementation": "path-label",
247 "locality": "relay",
248 "maturity": "stable",
249 "defaultRank": 5,
250 "browser": true,
251 "native": true
252 },
253 {
254 "id": "iroh-lan",
255 "rustVariant": "IrohLan",
256 "baseProtocol": "iroh",
257 "family": "iroh-path",
258 "implementation": "path-label",
259 "locality": "nearby",
260 "maturity": "stable",
261 "defaultRank": 0,
262 "browser": false,
263 "native": true
264 },
265 {
266 "id": "ble",
267 "rustVariant": "Ble",
268 "baseProtocol": "iroh",
269 "family": "iroh-physical",
270 "implementation": "host-installed",
271 "locality": "nearby",
272 "maturity": "experimental",
273 "defaultRank": 2,
274 "browser": false,
275 "native": true
276 },
277 {
278 "id": "webrtc",
279 "rustVariant": "WebRtc",
280 "baseProtocol": "iroh",
281 "family": "iroh-physical",
282 "implementation": "carrier-adapter",
283 "locality": "mixed",
284 "maturity": "stable",
285 "defaultRank": 3,
286 "browser": true,
287 "native": true
288 },
289 {
290 "id": "moq",
291 "rustVariant": "Moq",
292 "baseProtocol": "iroh",
293 "family": "iroh-physical",
294 "implementation": "carrier-adapter",
295 "locality": "relay",
296 "maturity": "experimental",
297 "defaultRank": 4,
298 "browser": true,
299 "native": true
300 }
301 ],
302 "defaultPriority": [
303 "iroh-lan",
304 "iroh-quic",
305 "webrtc",
306 "moq",
307 "iroh-relay"
308 ],
309 "legacyPreferredRanks": {
310 "iroh": 80,
311 "iroh-quic": 30,
312 "iroh-relay": 70,
313 "iroh-lan": 10,
314 "ble": 25,
315 "webrtc": 40,
316 "moq": 50
317 },
318 "labels": [
319 {
320 "input": "iroh",
321 "normalized": "iroh",
322 "irohBase": true,
323 "directIroh": false,
324 "webRtc": false
325 },
326 {
327 "input": " IROH-QUIC ",
328 "normalized": "iroh-quic",
329 "irohBase": true,
330 "directIroh": true,
331 "webRtc": false
332 },
333 {
334 "input": "iroh-relay",
335 "normalized": "iroh-relay",
336 "irohBase": true,
337 "directIroh": false,
338 "webRtc": false
339 },
340 {
341 "input": "iroh-lan",
342 "normalized": "iroh-lan",
343 "irohBase": true,
344 "directIroh": true,
345 "webRtc": false
346 },
347 {
348 "input": "ble",
349 "normalized": "ble",
350 "irohBase": true,
351 "directIroh": true,
352 "webRtc": false
353 },
354 {
355 "input": "webrtc",
356 "normalized": "webrtc",
357 "irohBase": true,
358 "directIroh": false,
359 "webRtc": true
360 },
361 {
362 "input": "moq",
363 "normalized": "moq",
364 "irohBase": true,
365 "directIroh": false,
366 "webRtc": false
367 },
368 {
369 "input": "iroh-webrtc",
370 "normalized": null,
371 "irohBase": false,
372 "directIroh": false,
373 "webRtc": false
374 },
375 {
376 "input": "iroh-moq",
377 "normalized": null,
378 "irohBase": false,
379 "directIroh": false,
380 "webRtc": false
381 },
382 {
383 "input": "webrtc-lan",
384 "normalized": null,
385 "irohBase": false,
386 "directIroh": false,
387 "webRtc": false
388 },
389 {
390 "input": "webrtc-turn",
391 "normalized": null,
392 "irohBase": false,
393 "directIroh": false,
394 "webRtc": false
395 },
396 {
397 "input": "webtransport",
398 "normalized": null,
399 "irohBase": false,
400 "directIroh": false,
401 "webRtc": false
402 }
403 ],
404 "rankRoutes": [
405 {
406 "configuredPriority": [
407 "webrtc",
408 "iroh-lan"
409 ],
410 "candidates": [
411 " IROH-LAN ",
412 "unknown",
413 "webrtc",
414 "webrtc",
415 "moq"
416 ],
417 "expected": [
418 "webrtc",
419 "iroh-lan",
420 "moq"
421 ]
422 },
423 {
424 "configuredPriority": [],
425 "candidates": [
426 "iroh",
427 "moq",
428 "iroh-moq",
429 "webrtc",
430 "iroh-webrtc",
431 "ble",
432 "webrtc-lan",
433 "iroh-lan",
434 "iroh-quic",
435 "iroh-relay",
436 "webrtc-turn"
437 ],
438 "expected": [
439 "iroh-lan",
440 "iroh-quic",
441 "webrtc",
442 "moq",
443 "iroh-relay",
444 "ble",
445 "iroh"
446 ]
447 },
448 {
449 "configuredPriority": [
450 "MOQ",
451 "moq",
452 "webtransport",
453 "BLE"
454 ],
455 "candidates": [
456 "webrtc-turn",
457 "ble",
458 "moq",
459 "IROH-RELAY",
460 "ble"
461 ],
462 "expected": [
463 "moq",
464 "ble",
465 "iroh-relay"
466 ]
467 }
468 ]
469}"###;