Fixed inadequate response packet lengths and made proper CNAME resolution.

This commit is contained in:
Revertron
2021-09-12 13:03:10 +02:00
parent 2b57d07da5
commit 7b79f86e17
3 changed files with 37 additions and 22 deletions
+1 -1
View File
@@ -433,7 +433,7 @@ impl DnsClient for HttpsDnsClient {
packet.questions.push(DnsQuestion::new(String::from(qname), qtype)); packet.questions.push(DnsQuestion::new(String::from(qname), qtype));
let mut req_buffer = VectorPacketBuffer::new(); let mut req_buffer = VectorPacketBuffer::new();
packet.write(&mut req_buffer, 512).expect("Preparing DnsPacket failed!"); packet.write(&mut req_buffer, 512 - 32).expect("Preparing DnsPacket failed!");
let response = self.agent let response = self.agent
.post(doh_url) .post(doh_url)
+16 -1
View File
@@ -810,12 +810,14 @@ impl DnsPacket {
None None
} }
pub fn get_unresolved_cnames(&self) -> Vec<DnsRecord> { pub fn get_unresolved_cnames(&self, qtype: QueryType) -> Vec<DnsRecord> {
let mut unresolved = Vec::new(); let mut unresolved = Vec::new();
for answer in &self.answers { for answer in &self.answers {
let mut matched = false; let mut matched = false;
if let DnsRecord::CNAME { ref host, .. } = *answer { if let DnsRecord::CNAME { ref host, .. } = *answer {
for answer2 in &self.answers { for answer2 in &self.answers {
match qtype {
QueryType::A => {
if let DnsRecord::A { ref domain, .. } = *answer2 { if let DnsRecord::A { ref domain, .. } = *answer2 {
if domain == host { if domain == host {
matched = true; matched = true;
@@ -823,6 +825,19 @@ impl DnsPacket {
} }
} }
} }
QueryType::AAAA => {
if let DnsRecord::AAAA { ref domain, .. } = *answer2 {
if domain == host {
matched = true;
break;
}
}
}
_ => {}
}
}
} else {
continue;
} }
if !matched { if !matched {
+13 -13
View File
@@ -62,7 +62,7 @@ pub trait DnsServer {
/// Utility function for resolving domains referenced in for example CNAME or SRV /// Utility function for resolving domains referenced in for example CNAME or SRV
/// records. This usually spares the client from having to perform additional lookups. /// records. This usually spares the client from having to perform additional lookups.
fn resolve_cnames(lookup_list: &[DnsRecord], results: &mut Vec<DnsPacket>, resolver: &mut Box<dyn DnsResolver>, depth: u16) { fn resolve_cnames(lookup_list: &[DnsRecord], results: &mut Vec<DnsPacket>, resolver: &mut Box<dyn DnsResolver>, qtype: QueryType, depth: u16) {
if depth > 10 { if depth > 10 {
return; return;
} }
@@ -70,17 +70,11 @@ fn resolve_cnames(lookup_list: &[DnsRecord], results: &mut Vec<DnsPacket>, resol
for ref rec in lookup_list { for ref rec in lookup_list {
match **rec { match **rec {
DnsRecord::CNAME { ref host, .. } | DnsRecord::SRV { ref host, .. } => { DnsRecord::CNAME { ref host, .. } | DnsRecord::SRV { ref host, .. } => {
if let Ok(result2) = resolver.resolve(host, QueryType::A, true) { if let Ok(result2) = resolver.resolve(host, qtype, true) {
let new_unmatched = result2.get_unresolved_cnames(); let new_unmatched = result2.get_unresolved_cnames(qtype);
results.push(result2); results.push(result2);
resolve_cnames(&new_unmatched, results, resolver, depth + 1); resolve_cnames(&new_unmatched, results, resolver, qtype, depth + 1);
}
if let Ok(result2) = resolver.resolve(host, QueryType::AAAA, true) {
let new_unmatched = result2.get_unresolved_cnames();
results.push(result2);
resolve_cnames(&new_unmatched, results, resolver, depth + 1);
} }
} }
_ => {} _ => {}
@@ -122,10 +116,10 @@ pub fn execute_query(context: Arc<ServerContext>, request: &DnsPacket) -> DnsPac
packet.header.authoritative_answer = true; packet.header.authoritative_answer = true;
} }
let unmatched = result.get_unresolved_cnames(); let unmatched = result.get_unresolved_cnames(question.qtype);
results.push(result); results.push(result);
resolve_cnames(&unmatched, &mut results, &mut resolver, 0); resolve_cnames(&unmatched, &mut results, &mut resolver, question.qtype, 0);
res_code res_code
} }
@@ -139,16 +133,22 @@ pub fn execute_query(context: Arc<ServerContext>, request: &DnsPacket) -> DnsPac
for result in results { for result in results {
for rec in result.answers { for rec in result.answers {
if !packet.answers.contains(&rec) {
packet.answers.push(rec); packet.answers.push(rec);
} }
}
for rec in result.authorities { for rec in result.authorities {
if !packet.authorities.contains(&rec) {
packet.authorities.push(rec); packet.authorities.push(rec);
} }
}
for rec in result.resources { for rec in result.resources {
if !packet.resources.contains(&rec) {
packet.resources.push(rec); packet.resources.push(rec);
} }
} }
} }
}
packet packet
} }
@@ -212,7 +212,7 @@ impl DnsServer for DnsUdpServer {
} }
}; };
let mut size_limit = 512; let mut size_limit = 512 - 32; // Minus 32 bytes for the packet header
// Check for EDNS // Check for EDNS
if request.resources.len() == 1 { if request.resources.len() == 1 {