Recursor: ignore CNAME responses to NS queries; satisfy them with SOA instead

the recursor can now resolve api.mangadex.org
This commit is contained in:
2024-07-17 09:37:26 +00:00
parent bcea3de9b0
commit 2f6f1eab4a

View File

@@ -337,7 +337,7 @@ impl<P: ConnectionProvider + Default> Recursor<P> {
/// Perform a single DNS query, checking/updating the cache.
/// In case that the nameserver answers to a non-CNAME query with a CNAME, this function will
/// return the CNAME. It's up to the caller to expand the answer further.
/// return the CNAME, or possibly a SOA response to a NS query. It's up to the caller to expand the answer further.
async fn lookup(
&self,
query: Query,
@@ -357,6 +357,7 @@ impl<P: ConnectionProvider + Default> Recursor<P> {
Ok(r) => {
let mut r = r.into_message();
info!("response: {}", r.header());
let mut soa = None;
let records = r
.take_answers()
.into_iter()
@@ -372,21 +373,35 @@ impl<P: ConnectionProvider + Default> Recursor<P> {
} else {
true
}
}).map(|x| {
if x.record_type().is_soa() {
soa = Some(x.name().clone());
}
x
});
let lookup = self.record_cache.insert_records(query.clone(), records, now);
let lookup = lookup.or_else(|| {
if query.query_type().is_cname() || query.query_type().is_any() {
if query.query_type().is_ns() || query.query_type().is_cname() || query.query_type().is_any() {
None
} else {
debug!("no records for {}: checking for cached CNAME", query.name());
let mut cname_query = query;
debug!("no records for {:?}: checking for cached CNAME", &query);
let mut cname_query = query.clone();
cname_query.set_query_type(RecordType::CNAME);
self.record_cache.get(&cname_query, now).and_then(Result::ok)
}
});
lookup.ok_or_else(|| Error::from("no records found"))
lookup.ok_or_else(|| {
if query.query_type().is_ns() {
debug!("no records for {:?}: returning SOA {:?}", &query, &soa);
if let Some(soa_name) = soa {
return Error::from(ErrorKind::Forward(soa_name));
}
}
Error::from("no records found")
})
}
Err(e) => {
warn!("lookup error: {e}");