Skip to main content

rns_core/
constants.rs

1// =============================================================================
2// Reticulum protocol constants
3// Ported from Python RNS source
4// =============================================================================
5
6// --- From Reticulum.py ---
7
8/// Maximum transmission unit in bytes
9pub const MTU: usize = 500;
10
11/// Truncated hash length in bits
12pub const TRUNCATED_HASHLENGTH: usize = 128;
13
14/// Minimum header size: 2 (flags + hops) + 1 (context) + 16 (dest hash)
15pub const HEADER_MINSIZE: usize = 2 + 1 + (TRUNCATED_HASHLENGTH / 8);
16
17/// Maximum header size: 2 (flags + hops) + 1 (context) + 32 (transport_id + dest hash)
18pub const HEADER_MAXSIZE: usize = 2 + 1 + (TRUNCATED_HASHLENGTH / 8) * 2;
19
20/// Minimum IFAC size
21pub const IFAC_MIN_SIZE: usize = 1;
22
23/// Maximum data unit: MTU - HEADER_MAXSIZE - IFAC_MIN_SIZE
24pub const MDU: usize = MTU - HEADER_MAXSIZE - IFAC_MIN_SIZE;
25
26// --- From Identity.py ---
27
28/// Full key size in bits (256 X25519 + 256 Ed25519)
29pub const KEYSIZE: usize = 512;
30
31/// Ratchet key size in bits
32pub const RATCHETSIZE: usize = 256;
33
34/// Received ratchet expiry in seconds (30 days)
35pub const RATCHET_EXPIRY: u64 = 60 * 60 * 24 * 30;
36
37/// Token overhead in bytes (16 IV + 32 HMAC)
38pub const TOKEN_OVERHEAD: usize = 48;
39
40/// AES-128 block size in bytes
41pub const AES128_BLOCKSIZE: usize = 16;
42
43/// Full hash length in bits (SHA-256)
44pub const HASHLENGTH: usize = 256;
45
46/// Signature length in bits (Ed25519)
47pub const SIGLENGTH: usize = KEYSIZE;
48
49/// Name hash length in bits
50pub const NAME_HASH_LENGTH: usize = 80;
51
52/// Derived key length in bytes
53pub const DERIVED_KEY_LENGTH: usize = 64;
54
55// --- From Packet.py ---
56
57/// Packet types
58pub const PACKET_TYPE_DATA: u8 = 0x00;
59pub const PACKET_TYPE_ANNOUNCE: u8 = 0x01;
60pub const PACKET_TYPE_LINKREQUEST: u8 = 0x02;
61pub const PACKET_TYPE_PROOF: u8 = 0x03;
62
63/// Header types
64pub const HEADER_1: u8 = 0x00;
65pub const HEADER_2: u8 = 0x01;
66
67/// Packet context types
68pub const CONTEXT_NONE: u8 = 0x00;
69pub const CONTEXT_RESOURCE: u8 = 0x01;
70pub const CONTEXT_RESOURCE_ADV: u8 = 0x02;
71pub const CONTEXT_RESOURCE_REQ: u8 = 0x03;
72pub const CONTEXT_RESOURCE_HMU: u8 = 0x04;
73pub const CONTEXT_RESOURCE_PRF: u8 = 0x05;
74pub const CONTEXT_RESOURCE_ICL: u8 = 0x06;
75pub const CONTEXT_RESOURCE_RCL: u8 = 0x07;
76pub const CONTEXT_CACHE_REQUEST: u8 = 0x08;
77pub const CONTEXT_REQUEST: u8 = 0x09;
78pub const CONTEXT_RESPONSE: u8 = 0x0A;
79pub const CONTEXT_PATH_RESPONSE: u8 = 0x0B;
80pub const CONTEXT_COMMAND: u8 = 0x0C;
81pub const CONTEXT_COMMAND_STATUS: u8 = 0x0D;
82pub const CONTEXT_CHANNEL: u8 = 0x0E;
83pub const CONTEXT_KEEPALIVE: u8 = 0xFA;
84pub const CONTEXT_LINKIDENTIFY: u8 = 0xFB;
85pub const CONTEXT_LINKCLOSE: u8 = 0xFC;
86pub const CONTEXT_LINKPROOF: u8 = 0xFD;
87pub const CONTEXT_LRRTT: u8 = 0xFE;
88pub const CONTEXT_LRPROOF: u8 = 0xFF;
89
90/// Context flag values
91pub const FLAG_SET: u8 = 0x01;
92pub const FLAG_UNSET: u8 = 0x00;
93
94/// Encrypted MDU: floor((MDU - TOKEN_OVERHEAD - KEYSIZE/16) / AES128_BLOCKSIZE) * AES128_BLOCKSIZE - 1
95pub const ENCRYPTED_MDU: usize = {
96    let numerator = MDU - TOKEN_OVERHEAD - KEYSIZE / 16;
97    (numerator / AES128_BLOCKSIZE) * AES128_BLOCKSIZE - 1
98};
99
100/// Plain MDU (same as MDU)
101pub const PLAIN_MDU: usize = MDU;
102
103/// Explicit proof length: HASHLENGTH/8 + SIGLENGTH/8 = 32 + 64 = 96
104pub const EXPL_LENGTH: usize = HASHLENGTH / 8 + SIGLENGTH / 8;
105
106/// Implicit proof length: SIGLENGTH/8 = 64
107pub const IMPL_LENGTH: usize = SIGLENGTH / 8;
108
109/// Receipt status constants
110pub const RECEIPT_FAILED: u8 = 0x00;
111pub const RECEIPT_SENT: u8 = 0x01;
112pub const RECEIPT_DELIVERED: u8 = 0x02;
113pub const RECEIPT_CULLED: u8 = 0xFF;
114
115// --- From Destination.py ---
116
117/// Destination types
118pub const DESTINATION_SINGLE: u8 = 0x00;
119pub const DESTINATION_GROUP: u8 = 0x01;
120pub const DESTINATION_PLAIN: u8 = 0x02;
121pub const DESTINATION_LINK: u8 = 0x03;
122
123/// Destination directions
124pub const DESTINATION_IN: u8 = 0x11;
125pub const DESTINATION_OUT: u8 = 0x12;
126
127// --- From Transport.py ---
128
129/// Transport types
130pub const TRANSPORT_BROADCAST: u8 = 0x00;
131pub const TRANSPORT_TRANSPORT: u8 = 0x01;
132pub const TRANSPORT_RELAY: u8 = 0x02;
133pub const TRANSPORT_TUNNEL: u8 = 0x03;
134
135/// Maximum hops
136pub const PATHFINDER_M: u8 = 128;
137
138// --- PATHFINDER algorithm ---
139
140/// Retransmit retries (total sends = PATHFINDER_R + 1)
141pub const PATHFINDER_R: u8 = 1;
142
143/// Grace period between retries (seconds)
144pub const PATHFINDER_G: f64 = 5.0;
145
146/// Random window for announce rebroadcast (seconds)
147pub const PATHFINDER_RW: f64 = 0.5;
148
149/// Path expiry = 7 days (seconds)
150pub const PATHFINDER_E: f64 = 604800.0;
151
152// --- Path expiry by interface mode ---
153
154/// Access Point path expiry = 1 day
155pub const AP_PATH_TIME: f64 = 86400.0;
156
157/// Roaming path expiry = 6 hours
158pub const ROAMING_PATH_TIME: f64 = 21600.0;
159
160// --- Announce bandwidth cap ---
161
162/// Default announce bandwidth cap (2% of interface bandwidth)
163pub const ANNOUNCE_CAP: f64 = 0.02;
164
165/// Maximum queued announces per interface
166pub const MAX_QUEUED_ANNOUNCES: usize = 4096;
167
168/// Queued announce lifetime (3 hours)
169pub const QUEUED_ANNOUNCE_LIFE: f64 = 3.0 * 60.0 * 60.0;
170
171/// Retention TTL for announce retransmission state (seconds)
172pub const ANNOUNCE_TABLE_TTL: f64 = 30.0;
173
174/// Maximum retained bytes for announce retransmission state
175pub const ANNOUNCE_TABLE_MAX_BYTES: usize = 4 * 1024 * 1024;
176
177// --- Table limits ---
178
179/// How many local rebroadcasts of an announce is allowed
180pub const LOCAL_REBROADCASTS_MAX: u8 = 2;
181
182/// Maximum number of random blobs per destination to keep in memory
183pub const MAX_RANDOM_BLOBS: usize = 64;
184
185/// Maximum number of announce timestamps to keep per destination
186pub const MAX_RATE_TIMESTAMPS: usize = 16;
187
188/// Maximum packet hashlist size before rotation
189pub const HASHLIST_MAXSIZE: usize = 250_000;
190
191/// Maximum announce signature cache entries (dedup verified signatures)
192pub const ANNOUNCE_SIG_CACHE_MAXSIZE: usize = 2_000;
193
194/// TTL for announce signature cache entries (seconds)
195pub const ANNOUNCE_SIG_CACHE_TTL: f64 = 600.0;
196
197// --- Timeouts ---
198
199/// Reverse table entry timeout (8 minutes)
200pub const REVERSE_TIMEOUT: f64 = 480.0;
201
202/// Destination table entry timeout (7 days)
203pub const DESTINATION_TIMEOUT: f64 = 604800.0;
204
205/// Tunnel table entry timeout (8 hours)
206pub const TUNNEL_TIMEOUT: f64 = 28800.0;
207
208/// Tunnel path retention timeout (8 hours)
209pub const TUNNEL_PATH_TIMEOUT: f64 = 28800.0;
210
211/// Link stale time = 2 * KEEPALIVE(360) = 720 seconds
212pub const LINK_STALE_TIME: f64 = 720.0;
213
214/// Link timeout = STALE_TIME * 1.25 = 900 seconds
215pub const LINK_TIMEOUT: f64 = 900.0;
216
217/// Link establishment timeout per hop (seconds)
218pub const LINK_ESTABLISHMENT_TIMEOUT_PER_HOP: f64 = 6.0;
219
220// --- Path request ---
221
222/// Default timeout for path requests (seconds)
223pub const PATH_REQUEST_TIMEOUT: f64 = 15.0;
224
225/// Timeout for suppressing or batching repeated path requests (seconds).
226pub const PATH_REQUEST_GATE_TIMEOUT: f64 = 45.0;
227
228/// Minimum usable interface bitrate for timeout calculations (bits/second).
229pub const MINIMUM_BITRATE: u64 = 5;
230
231/// Grace time before a path announcement is made (seconds)
232pub const PATH_REQUEST_GRACE: f64 = 0.4;
233
234/// Extra grace time for roaming-mode interfaces (seconds)
235pub const PATH_REQUEST_RG: f64 = 1.5;
236
237/// Minimum interval for automated path requests (seconds)
238pub const PATH_REQUEST_MI: f64 = 20.0;
239
240/// Maximum amount of unique path request tags to remember
241pub const MAX_PR_TAGS: usize = 16_000;
242
243// --- Job intervals ---
244
245/// Announce check interval (seconds)
246pub const ANNOUNCES_CHECK_INTERVAL: f64 = 1.0;
247
248/// Table culling interval (seconds)
249pub const TABLES_CULL_INTERVAL: f64 = 5.0;
250
251/// Link check interval (seconds)
252pub const LINKS_CHECK_INTERVAL: f64 = 1.0;
253
254// --- Ingress Control (from Interface.py) ---
255
256/// Interface "new" period in seconds (2 hours).
257pub const IC_NEW_TIME: f64 = 7200.0;
258/// Announce frequency threshold for new interfaces (announces/sec).
259pub const IC_BURST_FREQ_NEW: f64 = 3.0;
260/// Announce frequency threshold for mature interfaces (announces/sec).
261pub const IC_BURST_FREQ: f64 = 10.0;
262/// Path request frequency threshold for new interfaces (requests/sec).
263pub const IC_PR_BURST_FREQ_NEW: f64 = 3.0;
264/// Path request frequency threshold for mature interfaces (requests/sec).
265pub const IC_PR_BURST_FREQ: f64 = 8.0;
266/// Minimum burst active duration in seconds.
267pub const IC_BURST_HOLD: f64 = 15.0;
268/// Penalty delay before releasing held announces (seconds).
269pub const IC_BURST_PENALTY: f64 = 15.0;
270/// Interval between individual held announce releases (seconds).
271pub const IC_HELD_RELEASE_INTERVAL: f64 = 5.0;
272/// Minimum path request samples before egress limiting.
273pub const EC_BURST_MIN_SAMPLES: usize = 2;
274/// Default egress path request limit (requests/sec).
275pub const EC_PR_FREQ: f64 = 5.0;
276/// Maximum held announces per interface.
277pub const IC_MAX_HELD_ANNOUNCES: usize = 256;
278
279// --- Interface modes (from Interface.py) ---
280
281pub const MODE_FULL: u8 = 0x01;
282pub const MODE_POINT_TO_POINT: u8 = 0x02;
283pub const MODE_ACCESS_POINT: u8 = 0x03;
284pub const MODE_ROAMING: u8 = 0x04;
285pub const MODE_BOUNDARY: u8 = 0x05;
286pub const MODE_GATEWAY: u8 = 0x06;
287pub const MODE_INTERNAL: u8 = 0x07;
288
289/// Interface modes that forward path requests for unknown destinations.
290/// Python: Interface.DISCOVER_PATHS_FOR = [MODE_ACCESS_POINT, MODE_GATEWAY, MODE_ROAMING, MODE_INTERNAL]
291pub const DISCOVER_PATHS_FOR: [u8; 4] =
292    [MODE_ACCESS_POINT, MODE_GATEWAY, MODE_ROAMING, MODE_INTERNAL];
293
294/// Interface modes searched for an unknown path request received on a boundary interface.
295pub const BOUNDARY_SEARCH_MODES: [u8; 2] = [MODE_BOUNDARY, MODE_GATEWAY];
296
297/// Discovery path request expiry (seconds) — requests older than this are culled.
298pub const DISCOVERY_PATH_REQUEST_TIMEOUT: f64 = 15.0;
299
300// --- Path states ---
301
302pub const STATE_UNKNOWN: u8 = 0x00;
303pub const STATE_UNRESPONSIVE: u8 = 0x01;
304pub const STATE_RESPONSIVE: u8 = 0x02;
305
306// --- From Link.py ---
307
308/// Link ephemeral public key size: 32 (X25519) + 32 (Ed25519)
309pub const LINK_ECPUBSIZE: usize = 64;
310
311/// Link key size in bytes
312pub const LINK_KEYSIZE: usize = 32;
313
314/// Link MTU signalling bytes size
315pub const LINK_MTU_SIZE: usize = 3;
316
317/// Maximum keepalive interval in seconds
318pub const LINK_KEEPALIVE_MAX: f64 = 360.0;
319
320/// Minimum keepalive interval in seconds
321pub const LINK_KEEPALIVE_MIN: f64 = 5.0;
322
323/// Maximum RTT used for keepalive scaling
324pub const LINK_KEEPALIVE_MAX_RTT: f64 = 1.75;
325
326/// RTT timeout factor for stale→close transition
327pub const LINK_KEEPALIVE_TIMEOUT_FACTOR: f64 = 4.0;
328
329/// Grace period for stale→close transition
330pub const LINK_STALE_GRACE: f64 = 5.0;
331
332/// Factor to compute stale_time from keepalive
333pub const LINK_STALE_FACTOR: f64 = 2.0;
334
335/// Traffic timeout factor
336pub const LINK_TRAFFIC_TIMEOUT_FACTOR: f64 = 6.0;
337
338/// Link MDU: floor((MTU - IFAC_MIN_SIZE - HEADER_MINSIZE - TOKEN_OVERHEAD) / AES128_BLOCKSIZE) * AES128_BLOCKSIZE - 1
339pub const LINK_MDU: usize = {
340    let numerator = MTU - IFAC_MIN_SIZE - HEADER_MINSIZE - TOKEN_OVERHEAD;
341    (numerator / AES128_BLOCKSIZE) * AES128_BLOCKSIZE - 1
342};
343
344/// Link MTU bytemask (21-bit MTU field)
345pub const LINK_MTU_BYTEMASK: u32 = 0x1FFFFF;
346
347/// Link mode bytemask (3-bit mode field in upper byte)
348pub const LINK_MODE_BYTEMASK: u8 = 0xE0;
349
350// --- From Channel.py ---
351
352/// Initial window size at channel setup
353pub const CHANNEL_WINDOW: u16 = 2;
354
355/// Absolute minimum window size
356pub const CHANNEL_WINDOW_MIN: u16 = 2;
357
358/// Minimum window limit for slow links
359pub const CHANNEL_WINDOW_MIN_LIMIT_SLOW: u16 = 2;
360
361/// Minimum window limit for medium-speed links
362pub const CHANNEL_WINDOW_MIN_LIMIT_MEDIUM: u16 = 5;
363
364/// Minimum window limit for fast links
365pub const CHANNEL_WINDOW_MIN_LIMIT_FAST: u16 = 16;
366
367/// Maximum window size for slow links
368pub const CHANNEL_WINDOW_MAX_SLOW: u16 = 5;
369
370/// Maximum window size for medium-speed links
371pub const CHANNEL_WINDOW_MAX_MEDIUM: u16 = 12;
372
373/// Maximum window size for fast links
374pub const CHANNEL_WINDOW_MAX_FAST: u16 = 48;
375
376/// Minimum flexibility between window_max and window_min
377pub const CHANNEL_WINDOW_FLEXIBILITY: u16 = 4;
378
379/// Maximum sequence number
380pub const CHANNEL_SEQ_MAX: u16 = 0xFFFF;
381
382/// Sequence number modulus
383pub const CHANNEL_SEQ_MODULUS: u32 = 0x10000;
384
385/// Maximum number of send tries per envelope
386pub const CHANNEL_MAX_TRIES: u8 = 5;
387
388/// RTT threshold for fast links
389pub const CHANNEL_RTT_FAST: f64 = 0.18;
390
391/// RTT threshold for medium links
392pub const CHANNEL_RTT_MEDIUM: f64 = 0.75;
393
394/// RTT threshold for slow links
395pub const CHANNEL_RTT_SLOW: f64 = 1.45;
396
397/// Number of consecutive fast rounds to upgrade window
398pub const CHANNEL_FAST_RATE_THRESHOLD: u16 = 10;
399
400/// Channel envelope overhead: msgtype(2) + seq(2) + len(2)
401pub const CHANNEL_ENVELOPE_OVERHEAD: usize = 6;
402
403// --- From Buffer.py ---
404
405/// System message type for stream data
406pub const STREAM_DATA_MSGTYPE: u16 = 0xFF00;
407
408/// Maximum stream ID (14 bits)
409pub const STREAM_ID_MAX: u16 = 0x3FFF;
410
411/// Stream data overhead: 2 (stream header) + 6 (channel envelope)
412pub const STREAM_DATA_OVERHEAD: usize = 2 + CHANNEL_ENVELOPE_OVERHEAD;
413
414// --- From Resource.py ---
415
416/// Initial window size at beginning of transfer
417pub const RESOURCE_WINDOW: usize = 4;
418
419/// Absolute minimum window size during transfer
420pub const RESOURCE_WINDOW_MIN: usize = 2;
421
422/// Maximum window size for slow links
423pub const RESOURCE_WINDOW_MAX_SLOW: usize = 10;
424
425/// Maximum window size for very slow links
426pub const RESOURCE_WINDOW_MAX_VERY_SLOW: usize = 4;
427
428/// Maximum window size for fast links
429pub const RESOURCE_WINDOW_MAX_FAST: usize = 75;
430
431/// Global maximum window (for calculations)
432pub const RESOURCE_WINDOW_MAX: usize = RESOURCE_WINDOW_MAX_FAST;
433
434/// Minimum flexibility between window_max and window_min
435pub const RESOURCE_WINDOW_FLEXIBILITY: usize = 4;
436
437/// Sustained fast-rate rounds before enabling fast window
438/// = WINDOW_MAX_SLOW - WINDOW - 2 = 10 - 4 - 2 = 4
439pub const RESOURCE_FAST_RATE_THRESHOLD: usize = RESOURCE_WINDOW_MAX_SLOW - RESOURCE_WINDOW - 2;
440
441/// Sustained very-slow-rate rounds before capping to very slow
442pub const RESOURCE_VERY_SLOW_RATE_THRESHOLD: usize = 2;
443
444/// Fast rate threshold: 50 Kbps in bytes/sec = 50000 / 8 = 6250.0
445pub const RESOURCE_RATE_FAST: f64 = (50 * 1000) as f64 / 8.0;
446
447/// Very slow rate threshold: 2 Kbps in bytes/sec = 2000 / 8 = 250.0
448pub const RESOURCE_RATE_VERY_SLOW: f64 = (2 * 1000) as f64 / 8.0;
449
450/// Number of bytes in a map hash
451pub const RESOURCE_MAPHASH_LEN: usize = 4;
452
453/// Resource SDU = Packet.MDU (NOT ENCRYPTED_MDU)
454pub const RESOURCE_SDU: usize = MDU;
455
456/// Random hash size prepended to resource data
457pub const RESOURCE_RANDOM_HASH_SIZE: usize = 4;
458
459/// Maximum efficient resource size (1 MB - 1)
460pub const RESOURCE_MAX_EFFICIENT_SIZE: usize = 1024 * 1024 - 1;
461
462/// Maximum metadata size (16 MB - 1)
463pub const RESOURCE_METADATA_MAX_SIZE: usize = 16 * 1024 * 1024 - 1;
464
465/// Maximum auto-compress size (64 MB)
466pub const RESOURCE_AUTO_COMPRESS_MAX_SIZE: usize = 64 * 1024 * 1024;
467
468/// Part timeout factor (before RTT measured)
469pub const RESOURCE_PART_TIMEOUT_FACTOR: f64 = 4.0;
470
471/// Part timeout factor (after first RTT measured)
472pub const RESOURCE_PART_TIMEOUT_FACTOR_AFTER_RTT: f64 = 2.0;
473
474/// Proof timeout factor (reduced when awaiting proof)
475pub const RESOURCE_PROOF_TIMEOUT_FACTOR: f64 = 3.0;
476
477/// Additional wait allowance, in SDU-sized transfer units, while waiting for HMU data.
478pub const RESOURCE_HMU_WAIT_FACTOR: f64 = 3.5;
479
480/// Maximum retries for part transfers
481pub const RESOURCE_MAX_RETRIES: usize = 16;
482
483/// Maximum retries for advertisement
484pub const RESOURCE_MAX_ADV_RETRIES: usize = 4;
485
486/// Sender grace time (seconds)
487pub const RESOURCE_SENDER_GRACE_TIME: f64 = 10.0;
488
489/// Processing grace for advertisement response (seconds)
490pub const RESOURCE_PROCESSING_GRACE: f64 = 1.0;
491
492/// Retry grace time (seconds)
493pub const RESOURCE_RETRY_GRACE_TIME: f64 = 0.25;
494
495/// Per-retry delay (seconds)
496pub const RESOURCE_PER_RETRY_DELAY: f64 = 0.5;
497
498/// Maximum watchdog sleep interval (seconds)
499pub const RESOURCE_WATCHDOG_MAX_SLEEP: f64 = 1.0;
500
501/// Response max grace time (seconds)
502pub const RESOURCE_RESPONSE_MAX_GRACE_TIME: f64 = 10.0;
503
504/// Advertisement overhead in bytes (fixed msgpack overhead)
505pub const RESOURCE_ADVERTISEMENT_OVERHEAD: usize = 134;
506
507/// Maximum hashmap entries per advertisement segment
508/// = floor((LINK_MDU - ADVERTISEMENT_OVERHEAD) / MAPHASH_LEN)
509pub const RESOURCE_HASHMAP_MAX_LEN: usize =
510    (LINK_MDU - RESOURCE_ADVERTISEMENT_OVERHEAD) / RESOURCE_MAPHASH_LEN;
511
512/// Collision guard size = 2 * WINDOW_MAX + HASHMAP_MAX_LEN
513pub const RESOURCE_COLLISION_GUARD_SIZE: usize = 2 * RESOURCE_WINDOW_MAX + RESOURCE_HASHMAP_MAX_LEN;
514
515/// Hashmap not exhausted flag
516pub const RESOURCE_HASHMAP_IS_NOT_EXHAUSTED: u8 = 0x00;
517
518/// Hashmap exhausted flag
519pub const RESOURCE_HASHMAP_IS_EXHAUSTED: u8 = 0xFF;
520
521#[cfg(test)]
522mod tests {
523    use super::*;
524
525    #[test]
526    fn test_derived_constants() {
527        // MTU = 500
528        assert_eq!(MTU, 500);
529
530        // HEADER_MINSIZE = 2 + 1 + 16 = 19
531        assert_eq!(HEADER_MINSIZE, 19);
532
533        // HEADER_MAXSIZE = 2 + 1 + 32 = 35
534        assert_eq!(HEADER_MAXSIZE, 35);
535
536        // MDU = 500 - 35 - 1 = 464
537        assert_eq!(MDU, 464);
538
539        // ENCRYPTED_MDU = floor((464 - 48 - 32) / 16) * 16 - 1 = floor(384/16)*16 - 1 = 24*16 - 1 = 383
540        assert_eq!(ENCRYPTED_MDU, 383);
541
542        // PLAIN_MDU = MDU = 464
543        assert_eq!(PLAIN_MDU, 464);
544
545        // EXPL_LENGTH = 32 + 64 = 96
546        assert_eq!(EXPL_LENGTH, 96);
547
548        // IMPL_LENGTH = 64
549        assert_eq!(IMPL_LENGTH, 64);
550
551        // NAME_HASH_LENGTH = 80 bits = 10 bytes
552        assert_eq!(NAME_HASH_LENGTH / 8, 10);
553
554        // KEYSIZE = 512 bits = 64 bytes
555        assert_eq!(KEYSIZE / 8, 64);
556
557        // SIGLENGTH = 512 bits = 64 bytes
558        assert_eq!(SIGLENGTH / 8, 64);
559
560        // TRUNCATED_HASHLENGTH = 128 bits = 16 bytes
561        assert_eq!(TRUNCATED_HASHLENGTH / 8, 16);
562    }
563
564    #[test]
565    fn test_link_constants() {
566        assert_eq!(LINK_ECPUBSIZE, 64);
567        assert_eq!(LINK_MTU_SIZE, 3);
568        // LINK_MDU = floor((500 - 1 - 19 - 48) / 16) * 16 - 1 = floor(432/16)*16 - 1 = 27*16 - 1 = 431
569        assert_eq!(LINK_MDU, 431);
570        assert_eq!(CHANNEL_ENVELOPE_OVERHEAD, 6);
571        assert_eq!(STREAM_DATA_OVERHEAD, 8);
572        assert_eq!(STREAM_ID_MAX, 0x3FFF);
573    }
574
575    #[test]
576    fn test_transport_constants() {
577        // PATHFINDER_E = 7 days in seconds
578        assert_eq!(PATHFINDER_E, 60.0 * 60.0 * 24.0 * 7.0);
579
580        // AP_PATH_TIME = 1 day
581        assert_eq!(AP_PATH_TIME, 60.0 * 60.0 * 24.0);
582
583        // ROAMING_PATH_TIME = 6 hours
584        assert_eq!(ROAMING_PATH_TIME, 60.0 * 60.0 * 6.0);
585
586        assert_eq!(MODE_INTERNAL, 0x07);
587        assert!(DISCOVER_PATHS_FOR.contains(&MODE_INTERNAL));
588
589        // LINK_STALE_TIME = 2 * 360
590        assert_eq!(LINK_STALE_TIME, 720.0);
591
592        // LINK_TIMEOUT = STALE_TIME * 1.25
593        assert_eq!(LINK_TIMEOUT, LINK_STALE_TIME * 1.25);
594
595        // REVERSE_TIMEOUT = 8 minutes
596        assert_eq!(REVERSE_TIMEOUT, 8.0 * 60.0);
597
598        assert_eq!(PATH_REQUEST_GATE_TIMEOUT, 45.0);
599        assert_eq!(MAX_PR_TAGS, 16_000);
600
601        // DESTINATION_TIMEOUT = 7 days
602        assert_eq!(DESTINATION_TIMEOUT, 60.0 * 60.0 * 24.0 * 7.0);
603    }
604
605    #[test]
606    fn test_resource_constants() {
607        // SDU = MDU = 464 (NOT ENCRYPTED_MDU)
608        assert_eq!(RESOURCE_SDU, 464);
609        assert_eq!(RESOURCE_SDU, MDU);
610
611        // FAST_RATE_THRESHOLD = WINDOW_MAX_SLOW - WINDOW - 2 = 10 - 4 - 2 = 4
612        assert_eq!(RESOURCE_FAST_RATE_THRESHOLD, 4);
613
614        // RATE_FAST = 50000 / 8 = 6250.0
615        assert_eq!(RESOURCE_RATE_FAST, 6250.0);
616
617        // RATE_VERY_SLOW = 2000 / 8 = 250.0
618        assert_eq!(RESOURCE_RATE_VERY_SLOW, 250.0);
619
620        // HASHMAP_MAX_LEN = floor((431 - 134) / 4) = floor(297/4) = 74
621        assert_eq!(RESOURCE_HASHMAP_MAX_LEN, 74);
622
623        // COLLISION_GUARD_SIZE = 2 * 75 + 74 = 224
624        assert_eq!(RESOURCE_COLLISION_GUARD_SIZE, 224);
625
626        // Window constants
627        assert_eq!(RESOURCE_WINDOW, 4);
628        assert_eq!(RESOURCE_WINDOW_MIN, 2);
629        assert_eq!(RESOURCE_WINDOW_MAX_SLOW, 10);
630        assert_eq!(RESOURCE_WINDOW_MAX_VERY_SLOW, 4);
631        assert_eq!(RESOURCE_WINDOW_MAX_FAST, 75);
632        assert_eq!(RESOURCE_WINDOW_MAX, 75);
633        assert_eq!(RESOURCE_WINDOW_FLEXIBILITY, 4);
634    }
635}