Fixed inadequate response packet lengths and made proper CNAME resolution.
This commit is contained in:
+1
-1
@@ -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
@@ -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
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user