1pub use crate::proto::rr::domain::usage::*;
4use crate::proto::rr::domain::{Label, Name};
5use crate::proto::serialize::binary::BinEncodable;
6
7use once_cell::sync::Lazy;
8use radix_trie::{Trie, TrieKey};
9
10pub static IN_ADDR_ARPA_10: Lazy<ZoneUsage> = Lazy::new(|| {
31 ZoneUsage::reverse(
32 Name::from_ascii("10")
33 .unwrap()
34 .append_domain(&IN_ADDR_ARPA)
35 .unwrap(),
36 )
37});
38
39static IN_ADDR_ARPA_172: Lazy<Name> = Lazy::new(|| {
40 Name::from_ascii("172")
41 .unwrap()
42 .append_domain(&IN_ADDR_ARPA)
43 .unwrap()
44});
45
46pub static IN_ADDR_ARPA_172_16: Lazy<ZoneUsage> = Lazy::new(|| {
48 ZoneUsage::reverse(
49 Name::from_ascii("16")
50 .unwrap()
51 .append_domain(&IN_ADDR_ARPA_172)
52 .unwrap(),
53 )
54});
55pub static IN_ADDR_ARPA_172_17: Lazy<ZoneUsage> = Lazy::new(|| {
57 ZoneUsage::reverse(
58 Name::from_ascii("17")
59 .unwrap()
60 .append_domain(&IN_ADDR_ARPA_172)
61 .unwrap(),
62 )
63});
64pub static IN_ADDR_ARPA_172_18: Lazy<ZoneUsage> = Lazy::new(|| {
66 ZoneUsage::reverse(
67 Name::from_ascii("18")
68 .unwrap()
69 .append_domain(&IN_ADDR_ARPA_172)
70 .unwrap(),
71 )
72});
73pub static IN_ADDR_ARPA_172_19: Lazy<ZoneUsage> = Lazy::new(|| {
75 ZoneUsage::reverse(
76 Name::from_ascii("19")
77 .unwrap()
78 .append_domain(&IN_ADDR_ARPA_172)
79 .unwrap(),
80 )
81});
82pub static IN_ADDR_ARPA_172_20: Lazy<ZoneUsage> = Lazy::new(|| {
84 ZoneUsage::reverse(
85 Name::from_ascii("20")
86 .unwrap()
87 .append_domain(&IN_ADDR_ARPA_172)
88 .unwrap(),
89 )
90});
91pub static IN_ADDR_ARPA_172_21: Lazy<ZoneUsage> = Lazy::new(|| {
93 ZoneUsage::reverse(
94 Name::from_ascii("21")
95 .unwrap()
96 .append_domain(&IN_ADDR_ARPA_172)
97 .unwrap(),
98 )
99});
100pub static IN_ADDR_ARPA_172_22: Lazy<ZoneUsage> = Lazy::new(|| {
102 ZoneUsage::reverse(
103 Name::from_ascii("22")
104 .unwrap()
105 .append_domain(&IN_ADDR_ARPA_172)
106 .unwrap(),
107 )
108});
109pub static IN_ADDR_ARPA_172_23: Lazy<ZoneUsage> = Lazy::new(|| {
111 ZoneUsage::reverse(
112 Name::from_ascii("23")
113 .unwrap()
114 .append_domain(&IN_ADDR_ARPA_172)
115 .unwrap(),
116 )
117});
118pub static IN_ADDR_ARPA_172_24: Lazy<ZoneUsage> = Lazy::new(|| {
120 ZoneUsage::reverse(
121 Name::from_ascii("24")
122 .unwrap()
123 .append_domain(&IN_ADDR_ARPA_172)
124 .unwrap(),
125 )
126});
127pub static IN_ADDR_ARPA_172_25: Lazy<ZoneUsage> = Lazy::new(|| {
129 ZoneUsage::reverse(
130 Name::from_ascii("25")
131 .unwrap()
132 .append_domain(&IN_ADDR_ARPA_172)
133 .unwrap(),
134 )
135});
136pub static IN_ADDR_ARPA_172_26: Lazy<ZoneUsage> = Lazy::new(|| {
138 ZoneUsage::reverse(
139 Name::from_ascii("26")
140 .unwrap()
141 .append_domain(&IN_ADDR_ARPA_172)
142 .unwrap(),
143 )
144});
145pub static IN_ADDR_ARPA_172_27: Lazy<ZoneUsage> = Lazy::new(|| {
147 ZoneUsage::reverse(
148 Name::from_ascii("27")
149 .unwrap()
150 .append_domain(&IN_ADDR_ARPA_172)
151 .unwrap(),
152 )
153});
154pub static IN_ADDR_ARPA_172_28: Lazy<ZoneUsage> = Lazy::new(|| {
156 ZoneUsage::reverse(
157 Name::from_ascii("28")
158 .unwrap()
159 .append_domain(&IN_ADDR_ARPA_172)
160 .unwrap(),
161 )
162});
163pub static IN_ADDR_ARPA_172_29: Lazy<ZoneUsage> = Lazy::new(|| {
165 ZoneUsage::reverse(
166 Name::from_ascii("29")
167 .unwrap()
168 .append_domain(&IN_ADDR_ARPA_172)
169 .unwrap(),
170 )
171});
172pub static IN_ADDR_ARPA_172_30: Lazy<ZoneUsage> = Lazy::new(|| {
174 ZoneUsage::reverse(
175 Name::from_ascii("30")
176 .unwrap()
177 .append_domain(&IN_ADDR_ARPA_172)
178 .unwrap(),
179 )
180});
181pub static IN_ADDR_ARPA_172_31: Lazy<ZoneUsage> = Lazy::new(|| {
183 ZoneUsage::reverse(
184 Name::from_ascii("31")
185 .unwrap()
186 .append_domain(&IN_ADDR_ARPA_172)
187 .unwrap(),
188 )
189});
190
191pub static IN_ADDR_ARPA_192_168: Lazy<ZoneUsage> = Lazy::new(|| {
193 ZoneUsage::reverse(
194 Name::from_ascii("168.192")
195 .unwrap()
196 .append_domain(&IN_ADDR_ARPA)
197 .unwrap(),
198 )
199});
200
201static COM: Lazy<Label> = Lazy::new(|| Label::from_ascii("com").unwrap());
214static NET: Lazy<Label> = Lazy::new(|| Label::from_ascii("net").unwrap());
215static ORG: Lazy<Label> = Lazy::new(|| Label::from_ascii("org").unwrap());
216static EXAMPLE_L: Lazy<Label> = Lazy::new(|| Label::from_ascii("example").unwrap());
217
218pub static EXAMPLE: Lazy<ZoneUsage> =
220 Lazy::new(|| ZoneUsage::example(Name::from_labels(vec![EXAMPLE_L.clone()]).unwrap()));
221pub static EXAMPLE_COM: Lazy<ZoneUsage> = Lazy::new(|| {
223 ZoneUsage::example(Name::from_labels(vec![EXAMPLE_L.clone(), COM.clone()]).unwrap())
224});
225pub static EXAMPLE_NET: Lazy<ZoneUsage> = Lazy::new(|| {
227 ZoneUsage::example(Name::from_labels(vec![EXAMPLE_L.clone(), NET.clone()]).unwrap())
228});
229pub static EXAMPLE_ORG: Lazy<ZoneUsage> = Lazy::new(|| {
231 ZoneUsage::example(Name::from_labels(vec![EXAMPLE_L.clone(), ORG.clone()]).unwrap())
232});
233
234pub static TEST: Lazy<ZoneUsage> =
247 Lazy::new(|| ZoneUsage::test(Name::from_ascii("test.").unwrap()));
248
249#[derive(Clone, Eq, PartialEq)]
250struct TrieName(Name);
251
252impl From<Name> for TrieName {
253 fn from(n: Name) -> Self {
254 Self(n)
255 }
256}
257
258impl TrieKey for TrieName {
259 fn encode_bytes(&self) -> Vec<u8> {
265 let mut bytes = self.0.to_bytes().expect("bad name for trie");
266 bytes.reverse();
267 bytes
268 }
269}
270
271#[derive(Clone, Eq, PartialEq)]
272struct TrieNameRef<'n>(&'n Name);
273
274impl<'n> From<&'n Name> for TrieNameRef<'n> {
275 fn from(n: &'n Name) -> Self {
276 TrieNameRef(n)
277 }
278}
279
280impl<'n> TrieKey for TrieNameRef<'n> {
281 fn encode_bytes(&self) -> Vec<u8> {
287 let mut bytes = self.0.to_bytes().expect("bad name for trie");
288 bytes.reverse();
289 bytes
290 }
291}
292
293pub struct UsageTrie(Trie<TrieName, &'static ZoneUsage>);
295
296impl UsageTrie {
297 #[allow(clippy::cognitive_complexity)]
298 fn default() -> Self {
299 let mut trie: Trie<TrieName, &'static ZoneUsage> = Trie::new();
300
301 assert!(trie.insert(DEFAULT.clone().into(), &DEFAULT).is_none());
302
303 assert!(trie
304 .insert(IN_ADDR_ARPA_10.clone().into(), &IN_ADDR_ARPA_10)
305 .is_none());
306 assert!(trie
307 .insert(IN_ADDR_ARPA_172_16.clone().into(), &IN_ADDR_ARPA_172_16)
308 .is_none());
309 assert!(trie
310 .insert(IN_ADDR_ARPA_172_17.clone().into(), &IN_ADDR_ARPA_172_17)
311 .is_none());
312 assert!(trie
313 .insert(IN_ADDR_ARPA_172_18.clone().into(), &IN_ADDR_ARPA_172_18)
314 .is_none());
315 assert!(trie
316 .insert(IN_ADDR_ARPA_172_19.clone().into(), &IN_ADDR_ARPA_172_19)
317 .is_none());
318 assert!(trie
319 .insert(IN_ADDR_ARPA_172_20.clone().into(), &IN_ADDR_ARPA_172_20)
320 .is_none());
321 assert!(trie
322 .insert(IN_ADDR_ARPA_172_21.clone().into(), &IN_ADDR_ARPA_172_21)
323 .is_none());
324 assert!(trie
325 .insert(IN_ADDR_ARPA_172_22.clone().into(), &IN_ADDR_ARPA_172_22)
326 .is_none());
327 assert!(trie
328 .insert(IN_ADDR_ARPA_172_23.clone().into(), &IN_ADDR_ARPA_172_23)
329 .is_none());
330 assert!(trie
331 .insert(IN_ADDR_ARPA_172_24.clone().into(), &IN_ADDR_ARPA_172_24)
332 .is_none());
333 assert!(trie
334 .insert(IN_ADDR_ARPA_172_25.clone().into(), &IN_ADDR_ARPA_172_25)
335 .is_none());
336 assert!(trie
337 .insert(IN_ADDR_ARPA_172_26.clone().into(), &IN_ADDR_ARPA_172_26)
338 .is_none());
339 assert!(trie
340 .insert(IN_ADDR_ARPA_172_27.clone().into(), &IN_ADDR_ARPA_172_27)
341 .is_none());
342 assert!(trie
343 .insert(IN_ADDR_ARPA_172_28.clone().into(), &IN_ADDR_ARPA_172_28)
344 .is_none());
345 assert!(trie
346 .insert(IN_ADDR_ARPA_172_29.clone().into(), &IN_ADDR_ARPA_172_29)
347 .is_none());
348 assert!(trie
349 .insert(IN_ADDR_ARPA_172_30.clone().into(), &IN_ADDR_ARPA_172_30)
350 .is_none());
351 assert!(trie
352 .insert(IN_ADDR_ARPA_172_31.clone().into(), &IN_ADDR_ARPA_172_31)
353 .is_none());
354 assert!(trie
355 .insert(IN_ADDR_ARPA_192_168.clone().into(), &IN_ADDR_ARPA_192_168)
356 .is_none());
357
358 assert!(trie.insert(TEST.clone().into(), &TEST).is_none());
359
360 assert!(trie.insert(LOCALHOST.clone().into(), &LOCALHOST).is_none());
361 assert!(trie
362 .insert(IN_ADDR_ARPA_127.clone().into(), &IN_ADDR_ARPA_127)
363 .is_none());
364 assert!(trie
365 .insert(IP6_ARPA_1.clone().into(), &IP6_ARPA_1)
366 .is_none());
367
368 assert!(trie.insert(INVALID.clone().into(), &INVALID).is_none());
369 assert!(trie.insert(ONION.clone().into(), &ONION).is_none());
370
371 assert!(trie.insert(EXAMPLE.clone().into(), &EXAMPLE).is_none());
372 assert!(trie
373 .insert(EXAMPLE_COM.clone().into(), &EXAMPLE_COM)
374 .is_none());
375 assert!(trie
376 .insert(EXAMPLE_NET.clone().into(), &EXAMPLE_NET)
377 .is_none());
378 assert!(trie
379 .insert(EXAMPLE_ORG.clone().into(), &EXAMPLE_ORG)
380 .is_none());
381
382 Self(trie)
383 }
384
385 pub fn get(&self, name: &Name) -> &'static ZoneUsage {
391 self.0
392 .get_ancestor_value(&TrieName::from(name.clone()))
393 .expect("DEFAULT root ZoneUsage should have been returned")
394 }
395}
396
397pub static USAGE: Lazy<UsageTrie> = Lazy::new(UsageTrie::default);
399
400#[cfg(test)]
401mod tests {
402 use std::net::{Ipv4Addr, Ipv6Addr};
403
404 use super::*;
405
406 #[test]
407 fn test_root() {
408 let name = Name::from_ascii("com.").unwrap();
409
410 let usage = USAGE.get(&name);
411 assert!(usage.is_root());
412 }
413
414 #[test]
415 fn test_local_networks() {
416 assert_eq!(
417 USAGE.get(&Name::from(Ipv4Addr::new(9, 0, 0, 1))).name(),
418 DEFAULT.name()
419 );
420 assert_eq!(
421 USAGE.get(&Name::from(Ipv4Addr::new(10, 0, 0, 1))).name(),
422 IN_ADDR_ARPA_10.name()
423 );
424 assert_eq!(
425 USAGE.get(&Name::from(Ipv4Addr::new(11, 0, 0, 1))).name(),
426 DEFAULT.name()
427 );
428
429 assert_eq!(
430 USAGE.get(&Name::from(Ipv4Addr::new(172, 16, 0, 0))).name(),
431 IN_ADDR_ARPA_172_16.name()
432 );
433 assert_eq!(
434 USAGE.get(&Name::from(Ipv4Addr::new(172, 17, 0, 0))).name(),
435 IN_ADDR_ARPA_172_17.name()
436 );
437 assert_eq!(
438 USAGE.get(&Name::from(Ipv4Addr::new(172, 18, 0, 0))).name(),
439 IN_ADDR_ARPA_172_18.name()
440 );
441 assert_eq!(
442 USAGE.get(&Name::from(Ipv4Addr::new(172, 19, 0, 0))).name(),
443 IN_ADDR_ARPA_172_19.name()
444 );
445 assert_eq!(
446 USAGE.get(&Name::from(Ipv4Addr::new(172, 20, 0, 0))).name(),
447 IN_ADDR_ARPA_172_20.name()
448 );
449 assert_eq!(
450 USAGE.get(&Name::from(Ipv4Addr::new(172, 21, 0, 0))).name(),
451 IN_ADDR_ARPA_172_21.name()
452 );
453 assert_eq!(
454 USAGE.get(&Name::from(Ipv4Addr::new(172, 22, 0, 0))).name(),
455 IN_ADDR_ARPA_172_22.name()
456 );
457 assert_eq!(
458 USAGE.get(&Name::from(Ipv4Addr::new(172, 23, 0, 0))).name(),
459 IN_ADDR_ARPA_172_23.name()
460 );
461 assert_eq!(
462 USAGE.get(&Name::from(Ipv4Addr::new(172, 24, 0, 0))).name(),
463 IN_ADDR_ARPA_172_24.name()
464 );
465 assert_eq!(
466 USAGE.get(&Name::from(Ipv4Addr::new(172, 25, 0, 0))).name(),
467 IN_ADDR_ARPA_172_25.name()
468 );
469 assert_eq!(
470 USAGE.get(&Name::from(Ipv4Addr::new(172, 26, 0, 0))).name(),
471 IN_ADDR_ARPA_172_26.name()
472 );
473 assert_eq!(
474 USAGE.get(&Name::from(Ipv4Addr::new(172, 27, 0, 0))).name(),
475 IN_ADDR_ARPA_172_27.name()
476 );
477 assert_eq!(
478 USAGE.get(&Name::from(Ipv4Addr::new(172, 28, 0, 0))).name(),
479 IN_ADDR_ARPA_172_28.name()
480 );
481 assert_eq!(
482 USAGE.get(&Name::from(Ipv4Addr::new(172, 29, 0, 0))).name(),
483 IN_ADDR_ARPA_172_29.name()
484 );
485 assert_eq!(
486 USAGE.get(&Name::from(Ipv4Addr::new(172, 30, 0, 0))).name(),
487 IN_ADDR_ARPA_172_30.name()
488 );
489 assert_eq!(
490 USAGE.get(&Name::from(Ipv4Addr::new(172, 31, 0, 0))).name(),
491 IN_ADDR_ARPA_172_31.name()
492 );
493
494 assert_eq!(
495 USAGE.get(&Name::from(Ipv4Addr::new(172, 15, 0, 0))).name(),
496 DEFAULT.name()
497 );
498 assert_eq!(
499 USAGE.get(&Name::from(Ipv4Addr::new(172, 32, 0, 0))).name(),
500 DEFAULT.name()
501 );
502
503 assert_eq!(
504 USAGE
505 .get(&Name::from(Ipv4Addr::new(192, 167, 255, 255)))
506 .name(),
507 DEFAULT.name()
508 );
509 assert_eq!(
510 USAGE.get(&Name::from(Ipv4Addr::new(192, 168, 2, 3))).name(),
511 IN_ADDR_ARPA_192_168.name()
512 );
513 assert_eq!(
514 USAGE.get(&Name::from(Ipv4Addr::new(192, 169, 0, 0))).name(),
515 DEFAULT.name()
516 );
517 }
518
519 #[test]
520 fn test_example() {
521 let name = Name::from_ascii("example.").unwrap();
522
523 let usage = USAGE.get(&name);
524 assert_eq!(usage.name(), EXAMPLE.name());
525
526 let name = Name::from_ascii("example.com.").unwrap();
527
528 let usage = USAGE.get(&name);
529 assert_eq!(usage.name(), EXAMPLE_COM.name());
530
531 let name = Name::from_ascii("example.net.").unwrap();
532
533 let usage = USAGE.get(&name);
534 assert_eq!(usage.name(), EXAMPLE_NET.name());
535
536 let name = Name::from_ascii("example.org.").unwrap();
537
538 let usage = USAGE.get(&name);
539 assert_eq!(usage.name(), EXAMPLE_ORG.name());
540
541 let name = Name::from_ascii("www.example.org.").unwrap();
542
543 let usage = USAGE.get(&name);
544 assert_eq!(usage.name(), EXAMPLE_ORG.name());
545 }
546
547 #[test]
548 fn test_localhost() {
549 let name = Name::from_ascii("localhost.").unwrap();
550
551 let usage = USAGE.get(&name);
552 assert_eq!(usage.name(), LOCALHOST.name());
553
554 let name = Name::from_ascii("this.localhost.").unwrap();
555
556 let usage = USAGE.get(&name);
557 assert_eq!(usage.name(), LOCALHOST.name());
558
559 assert_eq!(
560 USAGE.get(&Name::from(Ipv4Addr::new(127, 0, 0, 1))).name(),
561 IN_ADDR_ARPA_127.name()
562 );
563 assert_eq!(
564 USAGE.get(&Name::from(Ipv4Addr::new(127, 0, 0, 2))).name(),
565 IN_ADDR_ARPA_127.name()
566 );
567 assert_eq!(
568 USAGE.get(&Name::from(Ipv4Addr::new(127, 255, 0, 0))).name(),
569 IN_ADDR_ARPA_127.name()
570 );
571 assert_eq!(
572 USAGE
573 .get(&Name::from(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)))
574 .name(),
575 IP6_ARPA_1.name()
576 );
577 }
578
579 #[test]
580 fn test_invalid() {
581 let name = Name::from_ascii("invalid.").unwrap();
582
583 let usage = USAGE.get(&name);
584 assert_eq!(usage.name(), INVALID.name());
585
586 let name = Name::from_ascii("something.invalid.").unwrap();
587
588 let usage = USAGE.get(&name);
589 assert_eq!(usage.name(), INVALID.name());
590 }
591
592 #[test]
593 fn test_onion() {
594 let name = Name::from_ascii("onion.").unwrap();
595
596 let usage = USAGE.get(&name);
597 assert_eq!(usage.name(), ONION.name());
598
599 let name =
600 Name::from_ascii("2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion.")
601 .unwrap(); let usage = USAGE.get(&name);
604 assert_eq!(usage.name(), ONION.name());
605 }
606
607 #[test]
608 fn test_test() {
609 let name = Name::from_ascii("test.").unwrap();
610
611 let usage = USAGE.get(&name);
612 assert_eq!(usage.name(), TEST.name());
613
614 let name = Name::from_ascii("foo.bar.test.").unwrap();
615
616 let usage = USAGE.get(&name);
617 assert_eq!(usage.name(), TEST.name());
618 }
619}