Skip to content

Commit 2641303

Browse files
oxide-renovate[bot]ahliximeow
authored
Update hickory-dns monorepo to 0.25.2 (#8391)
the PR has some notes about expected changes we'll see in a future 0.26.0. also, DNS resolvers used in most tests are no longer pinned to distrusting authoritative no-answer responses - this is not expected to be a meaningful change as we only query one DNS server for most tests. otherwise, little functional difference. some simpler APIs, some typos fixed up, and cleanup along the way. Co-authored-by: oxide-renovate[bot] <146848827+oxide-renovate[bot]@users.noreply.github.com> Co-authored-by: Adam H. Leventhal <ahl@oxide.computer> Co-authored-by: iximeow <iximeow@oxide.computer>
1 parent bbdd4b6 commit 2641303

File tree

17 files changed

+677
-322
lines changed

17 files changed

+677
-322
lines changed

Cargo.lock

Lines changed: 308 additions & 36 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -456,10 +456,10 @@ headers = "0.4.1"
456456
heck = "0.5"
457457
hex = "0.4.3"
458458
hex-literal = "0.4.1"
459-
hickory-client = "0.24.4"
460-
hickory-proto = "0.24.4"
461-
hickory-resolver = "0.24.4"
462-
hickory-server = "0.24.4"
459+
hickory-client = "0.25.2"
460+
hickory-proto = "0.25.2"
461+
hickory-resolver = "0.25.2"
462+
hickory-server = "0.25.2"
463463
highway = "1.3.0"
464464
hkdf = "0.12.4"
465465
hmac = "0.12.1"

clients/oxide-client/src/lib.rs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
use anyhow::Context;
88
use anyhow::anyhow;
99
use futures::FutureExt;
10-
use hickory_resolver::TokioAsyncResolver;
10+
use hickory_resolver::TokioResolver;
1111
use hickory_resolver::config::{
12-
NameServerConfig, Protocol, ResolverConfig, ResolverOpts,
12+
NameServerConfig, ResolverConfig, ResolverOpts,
1313
};
14+
use hickory_resolver::name_server::TokioConnectionProvider;
1415
use std::net::SocketAddr;
1516
use std::sync::Arc;
1617
use thiserror::Error;
@@ -29,32 +30,35 @@ progenitor::generate_api!(
2930
/// for Nexus. This is often useful when trying to connect with Nexus using
3031
/// TLS, since you need to come in via the DNS name to do that.
3132
///
32-
/// This is a thin wrapper around `TokioAsyncResolver`
33+
/// This is a thin wrapper around `TokioResolver`
3334
pub struct CustomDnsResolver {
3435
dns_addr: SocketAddr,
3536
// The lifetime constraints on the `Resolve` trait make it hard to avoid an
3637
// Arc here.
37-
resolver: Arc<TokioAsyncResolver>,
38+
resolver: Arc<TokioResolver>,
3839
}
3940

4041
impl CustomDnsResolver {
4142
/// Make a new custom resolver that uses the DNS server at the specified
4243
/// address
4344
pub fn new(dns_addr: SocketAddr) -> anyhow::Result<CustomDnsResolver> {
4445
let mut resolver_config = ResolverConfig::new();
45-
resolver_config.add_name_server(NameServerConfig {
46-
socket_addr: dns_addr,
47-
protocol: Protocol::Udp,
48-
tls_dns_name: None,
49-
trust_negative_responses: false,
50-
bind_addr: None,
51-
});
46+
resolver_config.add_name_server(NameServerConfig::new(
47+
dns_addr,
48+
hickory_resolver::proto::xfer::Protocol::Udp,
49+
));
5250
let mut resolver_opts = ResolverOpts::default();
5351
// Enable edns for potentially larger records
5452
resolver_opts.edns0 = true;
5553

56-
let resolver =
57-
Arc::new(TokioAsyncResolver::tokio(resolver_config, resolver_opts));
54+
let resolver = Arc::new(
55+
TokioResolver::builder_with_config(
56+
resolver_config,
57+
TokioConnectionProvider::default(),
58+
)
59+
.with_options(resolver_opts)
60+
.build(),
61+
);
5862
Ok(CustomDnsResolver { dns_addr, resolver })
5963
}
6064

@@ -63,8 +67,8 @@ impl CustomDnsResolver {
6367
self.dns_addr
6468
}
6569

66-
/// Returns the underlying `TokioAsyncResolver
67-
pub fn resolver(&self) -> &TokioAsyncResolver {
70+
/// Returns the underlying `TokioResolver`
71+
pub fn resolver(&self) -> &TokioResolver {
6872
&self.resolver
6973
}
7074
}

dev-tools/omdb/tests/successes.out

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ task: "nat_v4_garbage_collector"
484484
currently executing: no
485485
last completed activation: <REDACTED ITERATIONS>, triggered by a periodic timer firing
486486
started at <REDACTED_TIMESTAMP> (<REDACTED DURATION>s ago) and ran for <REDACTED DURATION>ms
487-
last completion reported error: failed to resolve addresses for Dendrite services: no record found for Query { name: Name("_dendrite._tcp.control-plane.oxide.internal."), query_type: SRV, query_class: IN }
487+
last completion reported error: failed to resolve addresses for Dendrite services: proto error: no records found for Query { name: Name("_dendrite._tcp.control-plane.oxide.internal."), query_type: SRV, query_class: IN }
488488

489489
task: "blueprint_loader"
490490
configured period: every <REDACTED_DURATION>m <REDACTED_DURATION>s
@@ -523,7 +523,7 @@ task: "bfd_manager"
523523
currently executing: no
524524
last completed activation: <REDACTED ITERATIONS>, triggered by a periodic timer firing
525525
started at <REDACTED_TIMESTAMP> (<REDACTED DURATION>s ago) and ran for <REDACTED DURATION>ms
526-
last completion reported error: failed to resolve addresses for Dendrite services: no record found for Query { name: Name("_dendrite._tcp.control-plane.oxide.internal."), query_type: SRV, query_class: IN }
526+
last completion reported error: failed to resolve addresses for Dendrite services: proto error: no records found for Query { name: Name("_dendrite._tcp.control-plane.oxide.internal."), query_type: SRV, query_class: IN }
527527

528528
task: "blueprint_planner"
529529
configured period: every <REDACTED_DURATION>m
@@ -1010,7 +1010,7 @@ task: "nat_v4_garbage_collector"
10101010
currently executing: no
10111011
last completed activation: <REDACTED ITERATIONS>, triggered by a periodic timer firing
10121012
started at <REDACTED_TIMESTAMP> (<REDACTED DURATION>s ago) and ran for <REDACTED DURATION>ms
1013-
last completion reported error: failed to resolve addresses for Dendrite services: no record found for Query { name: Name("_dendrite._tcp.control-plane.oxide.internal."), query_type: SRV, query_class: IN }
1013+
last completion reported error: failed to resolve addresses for Dendrite services: proto error: no records found for Query { name: Name("_dendrite._tcp.control-plane.oxide.internal."), query_type: SRV, query_class: IN }
10141014

10151015
task: "blueprint_loader"
10161016
configured period: every <REDACTED_DURATION>m <REDACTED_DURATION>s
@@ -1049,7 +1049,7 @@ task: "bfd_manager"
10491049
currently executing: no
10501050
last completed activation: <REDACTED ITERATIONS>, triggered by a periodic timer firing
10511051
started at <REDACTED_TIMESTAMP> (<REDACTED DURATION>s ago) and ran for <REDACTED DURATION>ms
1052-
last completion reported error: failed to resolve addresses for Dendrite services: no record found for Query { name: Name("_dendrite._tcp.control-plane.oxide.internal."), query_type: SRV, query_class: IN }
1052+
last completion reported error: failed to resolve addresses for Dendrite services: proto error: no records found for Query { name: Name("_dendrite._tcp.control-plane.oxide.internal."), query_type: SRV, query_class: IN }
10531053

10541054
task: "blueprint_planner"
10551055
configured period: every <REDACTED_DURATION>m

dns-server/src/dns_server.rs

Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use hickory_proto::op::ResponseCode;
1717
use hickory_proto::rr::RData;
1818
use hickory_proto::rr::Record;
1919
use hickory_proto::rr::RecordType;
20+
use hickory_proto::rr::rdata::NS;
2021
use hickory_proto::rr::rdata::SRV;
2122
use hickory_proto::serialize::binary::BinDecodable;
2223
use hickory_proto::serialize::binary::BinDecoder;
@@ -224,19 +225,11 @@ fn dns_record_to_record(
224225
) -> Result<Record, RequestError> {
225226
match record {
226227
DnsRecord::A(addr) => {
227-
let mut a = Record::new();
228-
a.set_name(name.clone())
229-
.set_rr_type(RecordType::A)
230-
.set_data(Some(RData::A((*addr).into())));
231-
Ok(a)
228+
Ok(Record::from_rdata(name.clone(), 0, RData::A((*addr).into())))
232229
}
233230

234231
DnsRecord::Aaaa(addr) => {
235-
let mut aaaa = Record::new();
236-
aaaa.set_name(name.clone())
237-
.set_rr_type(RecordType::AAAA)
238-
.set_data(Some(RData::AAAA((*addr).into())));
239-
Ok(aaaa)
232+
Ok(Record::from_rdata(name.clone(), 0, RData::AAAA((*addr).into())))
240233
}
241234

242235
DnsRecord::Srv(Srv { prio, weight, port, target }) => {
@@ -247,11 +240,11 @@ fn dns_record_to_record(
247240
error
248241
))
249242
})?;
250-
let mut srv = Record::new();
251-
srv.set_name(name.clone()).set_rr_type(RecordType::SRV).set_data(
252-
Some(RData::SRV(SRV::new(*prio, *weight, *port, tgt))),
253-
);
254-
Ok(srv)
243+
Ok(Record::from_rdata(
244+
name.clone(),
245+
0,
246+
RData::SRV(SRV::new(*prio, *weight, *port, tgt)),
247+
))
255248
}
256249

257250
DnsRecord::Ns(nsdname) => {
@@ -262,12 +255,7 @@ fn dns_record_to_record(
262255
error
263256
))
264257
})?;
265-
let mut ns = Record::new();
266-
use hickory_proto::rr::rdata::NS;
267-
ns.set_name(name.clone())
268-
.set_rr_type(RecordType::NS)
269-
.set_data(Some(RData::NS(NS(nsdname))));
270-
Ok(ns)
258+
Ok(Record::from_rdata(name.clone(), 0, RData::NS(NS(nsdname))))
271259
}
272260
}
273261
}
@@ -287,9 +275,27 @@ async fn handle_dns_message(
287275
// have to decide if the error is authoritative.
288276
header.set_authoritative(true);
289277

290-
let query = mr.query();
278+
let query = match mr.queries() {
279+
[] => {
280+
// A request with no queries could be legitimate (such as RFC 7873's Server Cookie
281+
// query), but we won't look enough to find out because we don't support that.
282+
return Err(RequestError::ServFail(anyhow!(
283+
"request with no query?"
284+
)));
285+
}
286+
[query] => query,
287+
_ => {
288+
// A request that is a query (opcode 0) with more than one question
289+
// is invalid according to RFC 9619. We don't currently check that
290+
// the opcode is actually QUERY, but even for other opcodes we don't
291+
// support more than one question.
292+
return Err(RequestError::ServFail(anyhow!(
293+
"request with too many queries"
294+
)));
295+
}
296+
};
291297
let name = query.original().name().clone();
292-
let answer = store.query(mr)?;
298+
let answer = store.query(query)?;
293299
let rb = MessageResponseBuilder::from_message_request(mr);
294300
let mut additional_records = vec![];
295301

@@ -315,29 +321,22 @@ async fn handle_dns_message(
315321
if name_records.is_empty() {
316322
return Err(RequestError::NxDomain(answer.queried_fqdn()));
317323
}
318-
319324
let response_records = name_records
320325
.into_iter()
321-
.filter(|record| {
322-
let ty = query.query_type();
323-
if ty == RecordType::ANY {
324-
return true;
325-
}
326-
327-
match (ty, record.data()) {
328-
(RecordType::A, Some(RData::A(_))) => true,
329-
(RecordType::AAAA, Some(RData::AAAA(_))) => true,
330-
(RecordType::SRV, Some(RData::SRV(_))) => true,
331-
(RecordType::NS, Some(RData::NS(_))) => true,
332-
(RecordType::SOA, Some(RData::SOA(_))) => true,
333-
_ => false,
334-
}
326+
.filter(|record| match (query.query_type(), record.data()) {
327+
(RecordType::ANY, _) => true,
328+
(RecordType::A, RData::A(_)) => true,
329+
(RecordType::AAAA, RData::AAAA(_)) => true,
330+
(RecordType::SRV, RData::SRV(_)) => true,
331+
(RecordType::NS, RData::NS(_)) => true,
332+
(RecordType::SOA, RData::SOA(_)) => true,
333+
_ => false,
335334
})
336335
.map(|record| {
337336
// DNS allows for the server to return additional records that
338337
// weren't explicitly asked for by the client but that the server
339338
// expects the client will want. SRV and NS records both use names
340-
// for their referents (rather than IP addresses dierctly). If
339+
// for their referents (rather than IP addresses directly). If
341340
// someone has queried for one of those kinds of records, they'll
342341
// almost certainly be needing the IP addresses that go with them as
343342
// well. We opportunistically attempt to resolve the target here and
@@ -346,8 +345,8 @@ async fn handle_dns_message(
346345
// NOTE: we only do this one-layer deep. If the target of a SRV or
347346
// NS is a CNAME instead of A/AAAA directly, it will be lost here.
348347
let additionals_target = match record.data() {
349-
Some(RData::SRV(srv)) => Some(srv.target()),
350-
Some(RData::NS(ns)) => Some(&ns.0),
348+
RData::SRV(srv) => Some(srv.target()),
349+
RData::NS(ns) => Some(&ns.0),
351350
_ => None,
352351
};
353352

dns-server/src/lib.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ pub mod http_server;
5656
pub mod storage;
5757

5858
use anyhow::{Context, anyhow};
59-
use hickory_resolver::TokioAsyncResolver;
59+
use hickory_resolver::TokioResolver;
6060
use hickory_resolver::config::NameServerConfig;
61-
use hickory_resolver::config::Protocol;
6261
use hickory_resolver::config::ResolverConfig;
6362
use hickory_resolver::config::ResolverOpts;
63+
use hickory_resolver::name_server::TokioConnectionProvider;
6464
use internal_dns_types::config::DnsConfigParams;
6565
use slog::o;
6666
use std::net::SocketAddr;
@@ -179,20 +179,23 @@ impl TransientServer {
179179
Ok(())
180180
}
181181

182-
pub async fn resolver(&self) -> Result<TokioAsyncResolver, anyhow::Error> {
182+
pub async fn resolver(&self) -> Result<TokioResolver, anyhow::Error> {
183183
let mut resolver_config = ResolverConfig::new();
184-
resolver_config.add_name_server(NameServerConfig {
185-
socket_addr: self.dns_server.local_address(),
186-
protocol: Protocol::Udp,
187-
tls_dns_name: None,
188-
trust_negative_responses: false,
189-
bind_addr: None,
190-
});
184+
resolver_config.add_name_server(NameServerConfig::new(
185+
self.dns_server.local_address(),
186+
hickory_proto::xfer::Protocol::Udp,
187+
));
191188
let mut resolver_opts = ResolverOpts::default();
192189
// Enable edns for potentially larger records
193190
resolver_opts.edns0 = true;
194-
let resolver =
195-
TokioAsyncResolver::tokio(resolver_config, resolver_opts);
191+
192+
let resolver = TokioResolver::builder_with_config(
193+
resolver_config,
194+
TokioConnectionProvider::default(),
195+
)
196+
.with_options(resolver_opts)
197+
.build();
198+
196199
Ok(resolver)
197200
}
198201
}

dns-server/src/storage.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494

9595
use anyhow::{Context, anyhow};
9696
use camino::Utf8PathBuf;
97-
use hickory_proto::rr::LowerName;
97+
use hickory_proto::{op::LowerQuery, rr::LowerName};
9898
use hickory_resolver::Name;
9999
use internal_dns_types::{
100100
config::{DnsConfig, DnsConfigParams, DnsConfigZone, DnsRecord},
@@ -439,23 +439,23 @@ impl Store {
439439
})
440440
.map(name_from_str)??;
441441

442-
let mut record = hickory_proto::rr::Record::new();
443442
let soa_name = name_from_str(&answer.queried_fqdn())?;
444443
let rname = name_from_str(format!("admin.{}", answer.zone.as_str()))?;
445-
record
446-
.set_name(soa_name)
447-
.set_rr_type(hickory_proto::rr::RecordType::SOA)
448-
.set_data(Some(hickory_proto::rr::RData::SOA(
449-
hickory_proto::rr::rdata::SOA::new(
450-
preferred_nameserver,
451-
rname,
452-
answer.serial,
453-
3600,
454-
600,
455-
1800,
456-
600,
457-
),
458-
)));
444+
445+
let record = hickory_proto::rr::Record::from_rdata(
446+
soa_name,
447+
0,
448+
hickory_proto::rr::RData::SOA(hickory_proto::rr::rdata::SOA::new(
449+
preferred_nameserver,
450+
rname,
451+
answer.serial,
452+
3600,
453+
600,
454+
1800,
455+
600,
456+
)),
457+
);
458+
459459
Ok(record)
460460
}
461461

@@ -759,10 +759,10 @@ impl Store {
759759
/// If the name does not match any zone, returns `QueryError::NoZone`.
760760
pub(crate) fn query(
761761
&self,
762-
mr: &hickory_server::authority::MessageRequest,
762+
query: &LowerQuery,
763763
) -> Result<Answer, QueryError> {
764-
let name = mr.query().name();
765-
let orig_name = mr.query().original().name();
764+
let name = query.name();
765+
let orig_name = query.original().name();
766766
self.query_raw(name, orig_name)
767767
}
768768

0 commit comments

Comments
 (0)