solofilter
Frank Denis 5 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_RD: u16 = 1u16 << 8;
const DNS_FLAGS_CD: u16 = 1u16 << 4; const DNS_FLAGS_CD: u16 = 1u16 << 4;
const DNS_OFFSET_QUESTION: usize = DNS_HEADER_SIZE; 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; pub const DNS_TYPE_A: u16 = 1;
const DNS_RCODE_NXDOMAIN: u8 = 3; pub const DNS_TYPE_AAAA: u16 = 28;
const DNS_RCODE_REFUSED: u8 = 5; 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] #[inline]
pub fn rcode(packet: &[u8]) -> u8 { 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) 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> { pub fn serve_nxdomain_response(client_packet: Vec<u8>) -> Result<Vec<u8>, Error> {
ensure!(client_packet.len() >= DNS_HEADER_SIZE, "Short packet"); ensure!(client_packet.len() >= DNS_HEADER_SIZE, "Short packet");
ensure!(qdcount(&client_packet) == 1, "No question"); 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()); return dns::serve_blocked_response(packet.to_vec());
} }
} }
if let Some(undelegated_list) = &globals.undelegated_list { let tld = dns::qname_tld(&packet_qname);
if undelegated_list.find(dns::qname_tld(&packet_qname)) { let synthesize_nxdomain = {
#[cfg(feature = "metrics")] if tld.len() == packet_qname.len() {
globals.varz.client_queries_rcode_nxdomain.inc(); let (qtype, qclass) = dns::qtype_qclass(&packet)?;
return dns::serve_nxdomain_response(packet.to_vec()); 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); let original_tid = dns::tid(&packet);
dns::set_tid(&mut packet, 0); dns::set_tid(&mut packet, 0);

Loading…
Cancel
Save