1#![warn(clippy::pedantic)]
2#![allow(clippy::redundant_else)]
4#![allow(clippy::mutable_key_type)]
6#![allow(clippy::needless_lifetimes)]
8#![allow(clippy::elidable_lifetime_names)]
9#![allow(clippy::match_same_arms)]
11#![allow(clippy::must_use_candidate)]
12#![allow(clippy::module_name_repetitions)]
13#![allow(clippy::return_self_not_must_use)]
14#![allow(clippy::similar_names)]
15#![allow(clippy::struct_excessive_bools)]
16#![allow(clippy::too_many_lines)]
17#![allow(clippy::wildcard_imports)]
18
19pub mod cache;
20pub mod context;
21pub mod forwarding;
22pub mod local;
23pub mod metrics;
24pub mod recursive;
25pub mod util;
26
27use std::net::SocketAddr;
28use tracing::Instrument;
29
30use dns_types::protocol::types::Question;
31use dns_types::zones::types::Zones;
32
33use self::cache::SharedCache;
34use self::context::Context;
35use self::forwarding::{resolve_forwarding, ForwardingContextInner};
36use self::local::resolve_local;
37use self::metrics::Metrics;
38use self::recursive::{resolve_recursive, RecursiveContextInner};
39use self::util::types::{ProtocolMode, ResolutionError, ResolvedRecord};
40
41pub const RECURSION_LIMIT: usize = 32;
48
49pub async fn resolve(
51 is_recursive: bool,
52 protocol_mode: ProtocolMode,
53 upstream_dns_port: u16,
54 forward_address: Option<SocketAddr>,
55 zones: &Zones,
56 cache: &SharedCache,
57 question: &Question,
58) -> (Metrics, Result<ResolvedRecord, ResolutionError>) {
59 match (is_recursive, forward_address) {
60 (true, Some(address)) => {
61 let mut context = Context::new(
62 ForwardingContextInner {
63 forward_address: address,
64 },
65 zones,
66 cache,
67 RECURSION_LIMIT,
68 );
69 let result = resolve_forwarding(&mut context, question)
70 .instrument(tracing::error_span!("resolve_forwarding", %address, %question))
71 .await;
72 (context.done(), result)
73 }
74 (true, None) => {
75 let mut context = Context::new(
76 RecursiveContextInner {
77 protocol_mode,
78 upstream_dns_port,
79 },
80 zones,
81 cache,
82 RECURSION_LIMIT,
83 );
84 let result = resolve_recursive(&mut context, question)
85 .instrument(tracing::error_span!("resolve_recursive", %question))
86 .await;
87 (context.done(), result)
88 }
89 (false, _) => {
90 let mut context = Context::new((), zones, cache, RECURSION_LIMIT);
91 let result = resolve_local(&mut context, question).map(ResolvedRecord::from);
92 (context.done(), result)
93 }
94 }
95}