summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2019-10-27 18:00:05 +0000
committerJeremy Harris <jgh146exb@wizmail.org>2019-10-27 18:08:43 +0000
commitb574c5baeb94e3a176c63982f507a5b48bf3917b (patch)
tree00c60e4fa2110797ca04bdeb4f91a02579deecd9 /src
parentb4a15239139c285af7009b4fcc23e1933b19173b (diff)
Refactor the res_search() fail hack
Diffstat (limited to 'src')
-rw-r--r--src/src/dns.c65
1 files changed, 32 insertions, 33 deletions
diff --git a/src/src/dns.c b/src/src/dns.c
index 8d9ec4708..28bc5958d 100644
--- a/src/src/dns.c
+++ b/src/src/dns.c
@@ -681,17 +681,6 @@ return rc;
-/* Return the TTL suitable for an NXDOMAIN result, which is given
-in the SOA. We hope that one was returned in the lookup, and do not
-bother doing a separate lookup; if not found return a forever TTL.
-*/
-
-time_t
-dns_expire_from_soa(dns_answer * dnsa)
-{
-const HEADER * h = (const HEADER *)dnsa->answer;
-dns_scan dnss;
-
/* This is really gross. The successful return value from res_search() is
the packet length, which is stored in dnsa->answerlen. If we get a
negative DNS reply then res_search() returns -1, which causes the bounds
@@ -703,12 +692,38 @@ re-implement res_search() and res_query() so that they don't muddle their
success and packet length return values.) For added safety we only reset
the packet length if the packet header looks plausible. */
-if ( h->qr == 1 && h->opcode == QUERY && h->tc == 0
+static void
+fake_dnsa_len_for_fail(dns_answer * dnsa)
+{
+const HEADER * h = (const HEADER *)dnsa->answer;
+
+if ( h->qr == 1 /* a response */
+ && h->opcode == QUERY
+ && h->tc == 0 /* nmessage not truncated */
&& (h->rcode == NOERROR || h->rcode == NXDOMAIN)
- && (ntohs(h->qdcount) == 1 || f.running_in_test_harness)
- && ntohs(h->ancount) == 0
- && ntohs(h->nscount) >= 1)
- dnsa->answerlen = sizeof(dnsa->answer);
+ && ( ntohs(h->qdcount) == 1 /* one question record */
+ || f.running_in_test_harness)
+ && ntohs(h->ancount) == 0 /* no answer records */
+ && ntohs(h->nscount) >= 1) /* authority records */
+ {
+ DEBUG(D_dns) debug_printf("faking res_search() response length as %d\n",
+ (int)sizeof(dnsa->answer));
+ dnsa->answerlen = sizeof(dnsa->answer);
+ }
+}
+
+
+/* Return the TTL suitable for an NXDOMAIN result, which is given
+in the SOA. We hope that one was returned in the lookup, and do not
+bother doing a separate lookup; if not found return a forever TTL.
+*/
+
+time_t
+dns_expire_from_soa(dns_answer * dnsa)
+{
+dns_scan dnss;
+
+fake_dnsa_len_for_fail(dnsa);
for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)
@@ -1185,23 +1200,7 @@ switch (type)
if (rc == DNS_NOMATCH)
{
- /* This is really gross. The successful return value from res_search() is
- the packet length, which is stored in dnsa->answerlen. If we get a
- negative DNS reply then res_search() returns -1, which causes the bounds
- checks for name decompression to fail when it is treated as a packet
- length, which in turn causes the authority search to fail. The correct
- packet length has been lost inside libresolv, so we have to guess a
- replacement value. (The only way to fix this properly would be to
- re-implement res_search() and res_query() so that they don't muddle their
- success and packet length return values.) For added safety we only reset
- the packet length if the packet header looks plausible. */
-
- const HEADER * h = (const HEADER *)dnsa->answer;
- if (h->qr == 1 && h->opcode == QUERY && h->tc == 0
- && (h->rcode == NOERROR || h->rcode == NXDOMAIN)
- && ntohs(h->qdcount) == 1 && ntohs(h->ancount) == 0
- && ntohs(h->nscount) >= 1)
- dnsa->answerlen = sizeof(dnsa->answer);
+ fake_dnsa_len_for_fail(dnsa);
for (rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)