solofilter
Frank Denis 4 years ago
parent 3864de1951
commit f3fe2fa123

@ -16,14 +16,17 @@ const DNS_FLAGS_RA: u16 = 1u16 << 7;
const DNS_FLAGS_RD: u16 = 1u16 << 8;
const DNS_FLAGS_CD: u16 = 1u16 << 4;
const DNS_OFFSET_QUESTION: usize = DNS_HEADER_SIZE;
const DNS_TYPE_OPT: u16 = 41;
const DNS_TYPE_TXT: u16 = 16;
const DNS_TYPE_HINFO: u16 = 13;
const DNS_CLASS_INET: u16 = 1;
const DNS_RCODE_SERVFAIL: u8 = 2;
const DNS_RCODE_NXDOMAIN: u8 = 3;
const DNS_RCODE_REFUSED: u8 = 5;
pub const DNS_TYPE_A: u16 = 1;
pub const DNS_TYPE_AAAA: u16 = 28;
pub const DNS_TYPE_OPT: u16 = 41;
pub const DNS_TYPE_TXT: u16 = 16;
pub const DNS_TYPE_HINFO: u16 = 13;
pub const DNS_CLASS_INET: u16 = 1;
pub const DNS_RCODE_SERVFAIL: u8 = 2;
pub const DNS_RCODE_NXDOMAIN: u8 = 3;
pub const DNS_RCODE_REFUSED: u8 = 5;
#[inline]
pub fn rcode(packet: &[u8]) -> u8 {
@ -478,6 +481,16 @@ pub fn serve_truncated_response(client_packet: Vec<u8>) -> Result<Vec<u8>, Error
Ok(packet)
}
pub fn qtype_qclass(packet: &[u8]) -> Result<(u16, u16), Error> {
ensure!(packet.len() >= DNS_HEADER_SIZE, "Short packet");
ensure!(qdcount(&packet) == 1, "No question");
let offset = skip_name(packet, DNS_HEADER_SIZE)?;
ensure!(packet.len() - offset >= 4, "Short packet");
let qtype = BigEndian::read_u16(&packet[offset..]);
let qclass = BigEndian::read_u16(&packet[offset + 2..]);
Ok((qtype, qclass))
}
pub fn serve_nxdomain_response(client_packet: Vec<u8>) -> Result<Vec<u8>, Error> {
ensure!(client_packet.len() >= DNS_HEADER_SIZE, "Short packet");
ensure!(qdcount(&client_packet) == 1, "No question");

@ -170,12 +170,28 @@ pub async fn get_cached_response_or_resolve(
return dns::serve_blocked_response(packet.to_vec());
}
}
if let Some(undelegated_list) = &globals.undelegated_list {
if undelegated_list.find(dns::qname_tld(&packet_qname)) {
#[cfg(feature = "metrics")]
globals.varz.client_queries_rcode_nxdomain.inc();
return dns::serve_nxdomain_response(packet.to_vec());
let tld = dns::qname_tld(&packet_qname);
let synthesize_nxdomain = {
if tld.len() == packet_qname.len() {
let (qtype, qclass) = dns::qtype_qclass(&packet)?;
if qtype == dns::DNS_CLASS_INET
&& (qclass == dns::DNS_TYPE_A || qclass == dns::DNS_TYPE_AAAA)
{
dbg!(String::from_utf8_lossy(&packet_qname));
true
} else {
false
}
} else if let Some(undelegated_list) = &globals.undelegated_list {
undelegated_list.find(tld)
} else {
false
}
};
if synthesize_nxdomain {
#[cfg(feature = "metrics")]
globals.varz.client_queries_rcode_nxdomain.inc();
return dns::serve_nxdomain_response(packet.to_vec());
}
let original_tid = dns::tid(&packet);
dns::set_tid(&mut packet, 0);

Loading…
Cancel
Save