Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
486 changes: 267 additions & 219 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ hashbrown = "0.17"
heck = "0.5"
hex = "0.4"
hex-literal = "0.4"
hickory-client = "0.24"
hickory-server = "0.24"
hickory-proto = "0.26"
hickory-server = "0.26"
hmac = "0.12"
http = "1.3"
hyper = "1.7"
Expand All @@ -215,7 +215,6 @@ oneshot = "0.1"
parity-scale-codec = "3.7"
parking_lot = "0.12"
paste = "1.0"
probabilistic-collections = "0.7"
proc-macro2 = "1.0"
proptest = "1.11"
qrcodegen = "1.8"
Expand Down Expand Up @@ -365,3 +364,8 @@ ledger-proto = { git = "https://github.com/ledger-community/rust-ledger.git", re
# Note that the fix is needed for the Ledger app, but we have to use the same version of parity-scale-codec
# across Trezor, Ledger, mintlayer-core and mintlayer-core-primitives repos.
parity-scale-codec = { git = "https://github.com/paritytech/parity-scale-codec.git", rev = "5021525697edc0661591ebc71392c48d950a10b0" }
# Fork of iced_glyphon 0.6.0 with the lru dependency upgraded to 0.16.3 to pick up the fix
# for RUSTSEC-2026-0002 ("IterMut violates Stacked Borrows by invalidating internal pointer").
# Upstream has replaced the crate with "cryoglyph" in unreleased iced 0.15, so there is no
# upstream release with the fix. Drop this patch once iced ships one.
iced_glyphon = { git = "https://github.com/mintlayer/iced-glyphon", rev = "acb3fc10a3a15ee6e0e7da4e264db2338c09a7c1" }
2 changes: 1 addition & 1 deletion dns-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ itertools.workspace = true
parity-scale-codec.workspace = true
thiserror.workspace = true
tokio = { workspace = true, default-features = false }
hickory-client.workspace = true
hickory-proto.workspace = true
hickory-server.workspace = true

[dev-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion dns-server/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use std::{
};

use clap::Parser;
use hickory_client::rr::Name;
use hickory_proto::rr::Name;

use common::primitives::per_thousand::PerThousand;
use utils::{app_version_with_git_info, clap_utils, root_user::ForceRunAsRootOptions};
Expand Down
78 changes: 38 additions & 40 deletions dns-server/src/dns_server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,16 @@ use std::{
};

use futures::never::Never;
use hickory_client::{
proto::rr::{LowerName, RrKey},
rr::{
Name, RData, RecordSet, RecordType,
rdata::{NS, SOA},
},
use hickory_proto::rr::{
LowerName, Name, RData, RecordSet, RecordType, RrKey, TSigResponseContext,
rdata::{NS, SOA},
};
use hickory_server::{
ServerFuture,
authority::{
AuthLookup, Authority, Catalog, LookupError, LookupOptions, MessageRequest, UpdateResult,
ZoneType,
server::{Request, RequestInfo, Server},
store::in_memory::InMemoryZoneHandler,
zone_handler::{
AuthLookup, AxfrPolicy, Catalog, LookupControlFlow, LookupOptions, ZoneHandler, ZoneType,
},
server::RequestInfo,
store::in_memory::InMemoryAuthority,
};
use itertools::Itertools;
use tokio::{net::UdpSocket, sync::mpsc};
Expand All @@ -61,7 +56,7 @@ pub enum DnsServerCommand {
pub struct DnsServer {
auth: Arc<AuthorityImpl>,

server: ServerFuture<Catalog>,
server: Server<Catalog>,

cmd_rx: mpsc::UnboundedReceiver<DnsServerCommand>,
}
Expand Down Expand Up @@ -91,7 +86,8 @@ impl DnsServer {
chain_config: Arc<ChainConfig>,
cmd_rx: mpsc::UnboundedReceiver<DnsServerCommand>,
) -> crate::Result<Self> {
let inner = InMemoryAuthority::empty(config.host.clone(), ZoneType::Primary, false);
let inner =
InMemoryZoneHandler::empty(config.host.clone(), ZoneType::Primary, AxfrPolicy::Deny);

let auth = Arc::new(AuthorityImpl {
config: AuthorityImplConfig::from_dns_server_config(&config),
Expand All @@ -102,11 +98,13 @@ impl DnsServer {
ipv6_addrs: Default::default(),
});

let handlers: Vec<Arc<dyn ZoneHandler>> = vec![Arc::clone(&auth) as _];

let mut catalog = Catalog::new();

catalog.upsert(config.host.clone().into(), Box::new(Arc::clone(&auth)));
catalog.upsert(config.host.clone().into(), handlers);

let mut server = ServerFuture::new(catalog);
let mut server = Server::new(catalog);

for bind_addr in config.bind_addr.iter() {
let udp_socket = UdpSocket::bind(bind_addr).await?;
Expand Down Expand Up @@ -139,7 +137,7 @@ impl DnsServer {
server.block_until_done().await?;

Err(DnsServerError::Other(
"trust_dns_server terminated unexpectedly",
"hickory DNS server terminated unexpectedly",
))
}
}
Expand Down Expand Up @@ -171,12 +169,12 @@ impl AuthorityImplConfig {
}
}

/// Wrapper for InMemoryAuthority that selects random addresses every second
/// Wrapper for InMemoryZoneHandler that selects random addresses every second
struct AuthorityImpl {
chain_config: Arc<ChainConfig>,
config: AuthorityImplConfig,
serial: RelaxedAtomicU32,
inner: InMemoryAuthority,
inner: InMemoryZoneHandler,
ipv4_addrs: Mutex<BTreeMap<Ipv4Addr, SoftwareInfo>>,
ipv6_addrs: Mutex<BTreeMap<Ipv6Addr, SoftwareInfo>>,
}
Expand Down Expand Up @@ -355,20 +353,19 @@ impl AuthorityImpl {
}
}

/// Note: dynamic DNS updates (RFC 2136) are not supported. The `ZoneHandler::update`
/// default implementation responds with `NotImplemented`, which is a stricter rejection
/// than the previous hickory 0.24-based code (which delegated to `InMemoryAuthority`'s
/// RFC 2136 processing and only rejected updates indirectly, for the lack of any
/// configured signature keys). A public seed node must never accept updates.
#[async_trait::async_trait]
impl Authority for AuthorityImpl {
type Lookup = AuthLookup;

impl ZoneHandler for AuthorityImpl {
fn zone_type(&self) -> ZoneType {
self.inner.zone_type()
}

fn is_axfr_allowed(&self) -> bool {
self.inner.is_axfr_allowed()
}

async fn update(&self, update: &MessageRequest) -> UpdateResult<bool> {
self.inner.update(update).await
fn axfr_policy(&self) -> AxfrPolicy {
self.inner.axfr_policy()
}

fn origin(&self) -> &LowerName {
Expand All @@ -379,41 +376,42 @@ impl Authority for AuthorityImpl {
&self,
name: &LowerName,
query_type: RecordType,
request_info: Option<&RequestInfo<'_>>,
lookup_options: LookupOptions,
) -> Result<Self::Lookup, LookupError> {
) -> LookupControlFlow<AuthLookup> {
log::trace!(
"In lookup for {:?}, query_type = {:?}, lookup_options = {:?}",
name,
query_type,
lookup_options
);
self.refresh().await;
self.inner.lookup(name, query_type, lookup_options).await
self.inner.lookup(name, query_type, request_info, lookup_options).await
}

async fn search(
&self,
request_info: RequestInfo<'_>,
request: &Request,
lookup_options: LookupOptions,
) -> Result<Self::Lookup, LookupError> {
) -> (LookupControlFlow<AuthLookup>, Option<TSigResponseContext>) {
log::trace!(
"In search, src = {:?}, protocol = {:?}, header = {:?}, query = {:?}, lookup_options = {:?}",
request_info.src,
request_info.protocol,
request_info.header,
request_info.query,
request.src(),
request.protocol(),
request.metadata,
request.queries,
lookup_options
);
self.refresh().await;
self.inner.search(request_info, lookup_options).await
self.inner.search(request, lookup_options).await
}

async fn get_nsec_records(
async fn nsec_records(
&self,
name: &LowerName,
lookup_options: LookupOptions,
) -> Result<Self::Lookup, LookupError> {
self.inner.get_nsec_records(name, lookup_options).await
) -> LookupControlFlow<AuthLookup> {
self.inner.nsec_records(name, lookup_options).await
}
}

Expand Down
37 changes: 24 additions & 13 deletions dns-server/src/dns_server/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ use std::{
sync::Arc,
};

use hickory_client::rr::{RData, RecordType};
use hickory_proto::rr::{RData, RecordType};
use hickory_server::{
authority::{Authority, ZoneType},
store::in_memory::InMemoryAuthority,
store::in_memory::InMemoryZoneHandler,
zone_handler::{AxfrPolicy, LookupOptions, ZoneHandler, ZoneType},
};

use common::{
Expand Down Expand Up @@ -61,7 +61,7 @@ async fn dns_server_basic() {
version: SemVer::new(1, 2, 3),
};

let inner = InMemoryAuthority::empty(host.clone(), ZoneType::Primary, false);
let inner = InMemoryZoneHandler::empty(host.clone(), ZoneType::Primary, AxfrPolicy::Deny);

let auth = AuthorityImpl {
config,
Expand All @@ -83,26 +83,36 @@ async fn dns_server_basic() {
assert_eq!(auth.ipv6_addrs.lock().unwrap().len(), 1);

let result_a = auth
.lookup(&host.clone().into(), RecordType::A, Default::default())
.lookup(
&host.clone().into(),
RecordType::A,
None,
LookupOptions::default(),
)
.await
.unwrap()
.expect("lookup must not fail")
.unwrap_records()
.iter()
.cloned()
.collect::<Vec<_>>();
assert_eq!(result_a.len(), 1);
assert_eq!(result_a[0].data(), Some(&RData::A(ip1.into())));
assert_eq!(result_a[0].data, RData::A(ip1.into()));

let result_aaaa = auth
.lookup(&host.clone().into(), RecordType::AAAA, Default::default())
.lookup(
&host.clone().into(),
RecordType::AAAA,
None,
LookupOptions::default(),
)
.await
.unwrap()
.expect("lookup must not fail")
.unwrap_records()
.iter()
.cloned()
.collect::<Vec<_>>();
assert_eq!(result_aaaa.len(), 1);
assert_eq!(result_aaaa[0].data(), Some(&RData::AAAA(ip2.into())));
assert_eq!(result_aaaa[0].data, RData::AAAA(ip2.into()));

handle_command(&auth, DnsServerCommand::DelAddress(ip1.into()));
handle_command(&auth, DnsServerCommand::DelAddress(ip2.into()));
Expand Down Expand Up @@ -145,7 +155,8 @@ mod same_software_version_addr_selection_test {
};
let cur_soft_info = SoftwareInfo::current(&chain_config);

let inner = InMemoryAuthority::empty(config.host.clone(), ZoneType::Primary, false);
let inner =
InMemoryZoneHandler::empty(config.host.clone(), ZoneType::Primary, AxfrPolicy::Deny);
let auth = AuthorityImpl {
config,
chain_config: Arc::clone(&chain_config),
Expand All @@ -170,7 +181,7 @@ mod same_software_version_addr_selection_test {
let selected_v4_addrs = records[0]
.1
.records_without_rrsigs()
.map(|rec| assert_matches_return_val!(rec.data(), Some(&RData::A(a)), a.0))
.map(|rec| assert_matches_return_val!(&rec.data, RData::A(a), a.0))
.collect::<Vec<_>>();
assert_eq!(
selected_v4_addrs.len(),
Expand All @@ -188,7 +199,7 @@ mod same_software_version_addr_selection_test {
let selected_v6_addrs = records[1]
.1
.records_without_rrsigs()
.map(|rec| assert_matches_return_val!(rec.data(), Some(&RData::AAAA(a)), a.0))
.map(|rec| assert_matches_return_val!(&rec.data, RData::AAAA(a), a.0))
.collect::<Vec<_>>();
assert_eq!(
selected_v6_addrs.len(),
Expand Down
6 changes: 5 additions & 1 deletion dns-server/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@

use std::net::AddrParseError;

use hickory_client::proto::error::ProtoError;
use hickory_proto::ProtoError;
use hickory_server::net::NetError;
use p2p::{error::P2pError, peer_manager::peerdb_common};
use thiserror::Error;
use utils::try_as::TryAsRef;
Expand All @@ -24,6 +25,8 @@ use utils::try_as::TryAsRef;
pub enum DnsServerError {
#[error("Proto error: {0}")]
ProtoError(#[from] ProtoError),
#[error("Net error: {0}")]
NetError(#[from] NetError),
#[error("Parse error: {0}")]
AddrParseError(#[from] AddrParseError),
#[error("IO error: {0}")]
Expand All @@ -47,6 +50,7 @@ impl TryAsRef<storage::Error> for DnsServerError {
fn try_as_ref(&self) -> Option<&storage::Error> {
match self {
DnsServerError::ProtoError(_)
| DnsServerError::NetError(_)
| DnsServerError::AddrParseError(_)
| DnsServerError::IoError(_)
| DnsServerError::P2pError(_)
Expand Down
1 change: 1 addition & 0 deletions dns-server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ async fn run(options: DnsServerRunOptions) -> anyhow::Result<Never> {
open_storage(open_storage_backend(storage_data_dir))
}
DnsServerError::ProtoError(_)
| DnsServerError::NetError(_)
| DnsServerError::AddrParseError(_)
| DnsServerError::IoError(_)
| DnsServerError::P2pError(_)
Expand Down
4 changes: 2 additions & 2 deletions supply-chain/audits.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2075,13 +2075,13 @@ end = "2026-10-15"

[[trusted.zerocopy]]
criteria = "safe-to-deploy"
user-id = 7178 # Joshua Liebow-Feeser (joshlf)
user-id = 7178 # Josh Liebow-Feeser (joshlf)
start = "2019-02-28"
end = "2026-10-15"

[[trusted.zerocopy-derive]]
criteria = "safe-to-deploy"
user-id = 7178 # Joshua Liebow-Feeser (joshlf)
user-id = 7178 # Josh Liebow-Feeser (joshlf)
start = "2019-02-28"
end = "2026-10-15"

Expand Down
Loading
Loading