]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
1193. [bug] dig +besteffort parsing didn't handle packet
authorMark Andrews <marka@isc.org>
Tue, 12 Feb 2002 02:10:33 +0000 (02:10 +0000)
committerMark Andrews <marka@isc.org>
Tue, 12 Feb 2002 02:10:33 +0000 (02:10 +0000)
                        truncation.  dns_message_parse() has new flag
                        DNS_MESSAGE_IGNORETRUNCATION.

CHANGES
bin/dig/dighost.c
lib/dns/include/dns/message.h
lib/dns/message.c

diff --git a/CHANGES b/CHANGES
index 6044fd88e7d35138a6ee88b1e4c5de0ba326bf4e..b2b8572a0f6d7779a0adef40055d3a8f4bc59cba 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -19,7 +19,9 @@
 1194.  [bug]           Not all duplicate zone definitions were being detected
                        at the named.conf checking stage. [RT #2431]
 
-1193.  [bug]           Best effort parsing didn't handle packet truncation.
+1193.  [bug]           dig +besteffort parsing didn't handle packet
+                       truncation.  dns_message_parse() has new flag
+                       DNS_MESSAGE_IGNORETRUNCATION.
 
 1192.  [bug]           The seconds fields in LOC records were restricted
                        to three decimal places.  More decimal places should
index 1c32a9ff07e956f52bd722ad31a4e9eb136bac8d..55aca6f6ec829a5b960f17633713b8f828f68e2d 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dighost.c,v 1.238 2001/11/30 01:58:39 gson Exp $ */
+/* $Id: dighost.c,v 1.239 2002/02/12 02:10:30 marka Exp $ */
 
 /*
  * Notice to programmers:  Do not use this code as an example of how to
@@ -2195,8 +2195,10 @@ recv_done(isc_task_t *task, isc_event_t *event) {
 
        debug("before parse starts");
        parseflags = DNS_MESSAGEPARSE_PRESERVEORDER;
-       if (l->besteffort)
+       if (l->besteffort) {
                parseflags |= DNS_MESSAGEPARSE_BESTEFFORT;
+               parseflags |= DNS_MESSAGEPARSE_IGNORETRUNCATION;
+       }
        result = dns_message_parse(msg, b, parseflags);
        if (result == DNS_R_RECOVERABLE) {
                printf(";; Warning: Message parser reports malformed "
index 06cf170827ff511282e4f1da5b43263ffe47648c..4467fa0c757bb8aff26603db9967e82621bfd340 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: message.h,v 1.106 2002/01/22 09:07:26 bwelling Exp $ */
+/* $Id: message.h,v 1.107 2002/02/12 02:10:33 marka Exp $ */
 
 #ifndef DNS_MESSAGE_H
 #define DNS_MESSAGE_H 1
@@ -153,6 +153,8 @@ typedef int dns_messagetextflag_t;
                                                   occurs */
 #define DNS_MESSAGEPARSE_CLONEBUFFER   0x0004  /* save a copy of the
                                                   source buffer */
+#define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /* trucation errors are
+                                                 * not fatal. */
 
 /*
  * Control behavior of rendering
@@ -401,6 +403,9 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
  * not be considered FORMERRs.  If the entire message can be parsed, it
  * will be returned and DNS_R_RECOVERABLE will be returned.
  *
+ * If DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete
+ * RR's as possible, DNS_R_RECOVERABLE will be returned.
+ *
  * OPT and TSIG records are always handled specially, regardless of the
  * 'preserve_order' setting.
  *
index 2011e9f294177a097514fcae8d3291542b787e42..beb7d4af56d62a553272f67928ba1a6d2a973444 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: message.c,v 1.206 2002/02/11 02:03:23 marka Exp $ */
+/* $Id: message.c,v 1.207 2002/02/12 02:10:32 marka Exp $ */
 
 /***
  *** Imports
@@ -942,7 +942,6 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
        isc_boolean_t free_name;
        isc_boolean_t best_effort;
        isc_boolean_t seen_problem;
-       isc_buffer_t save = *source;
 
        section = &msg->sections[DNS_SECTION_QUESTION];
 
@@ -954,7 +953,6 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
        rdatalist = NULL;
 
        for (count = 0; count < msg->counts[DNS_SECTION_QUESTION]; count++) {
-               save = *source;
                name = isc_mempool_get(msg->namepool);
                if (name == NULL)
                        return (ISC_R_NOMEMORY);
@@ -1074,10 +1072,6 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
        return (ISC_R_SUCCESS);
 
  cleanup:
-       if (result == ISC_R_UNEXPECTEDEND && best_effort) {
-               *source = save;
-               result = DNS_R_RECOVERABLE;
-       }
        if (rdataset != NULL) {
                INSIST(!dns_rdataset_isassociated(rdataset));
                isc_mempool_put(msg->rdspool, rdataset);
@@ -1122,7 +1116,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
        isc_boolean_t free_name, free_rdataset;
        isc_boolean_t preserve_order, best_effort, seen_problem;
        isc_boolean_t issigzero;
-       isc_buffer_t save = *source;
 
        preserve_order = ISC_TF(options & DNS_MESSAGEPARSE_PRESERVEORDER);
        best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
@@ -1138,7 +1131,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
                skip_type_search = ISC_FALSE;
                free_name = ISC_FALSE;
                free_rdataset = ISC_FALSE;
-               save = *source;
 
                name = isc_mempool_get(msg->namepool);
                if (name == NULL)
@@ -1482,10 +1474,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
        return (ISC_R_SUCCESS);
 
  cleanup:
-       if (result == ISC_R_UNEXPECTEDEND && best_effort) {
-               *source = save;
-               result = DNS_R_RECOVERABLE;
-       }
        if (free_name)
                isc_mempool_put(msg->namepool, name);
        if (free_rdataset)
@@ -1504,12 +1492,14 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
        isc_uint16_t tmpflags;
        isc_buffer_t origsource;
        isc_boolean_t seen_problem;
+       isc_boolean_t ignore_tc;
 
        REQUIRE(DNS_MESSAGE_VALID(msg));
        REQUIRE(source != NULL);
        REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
 
        seen_problem = ISC_FALSE;
+       ignore_tc = ISC_TF(options & DNS_MESSAGEPARSE_IGNORETRUNCATION);
 
        origsource = *source;
 
@@ -1541,6 +1531,8 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
        dns_decompress_setmethods(&dctx, DNS_COMPRESS_GLOBAL14);
 
        ret = getquestions(source, msg, &dctx, options);
+       if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
+               goto truncated;
        if (ret == DNS_R_RECOVERABLE) {
                seen_problem = ISC_TRUE;
                ret = ISC_R_SUCCESS;
@@ -1550,6 +1542,8 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
        msg->question_ok = 1;
 
        ret = getsection(source, msg, &dctx, DNS_SECTION_ANSWER, options);
+       if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
+               goto truncated;
        if (ret == DNS_R_RECOVERABLE) {
                seen_problem = ISC_TRUE;
                ret = ISC_R_SUCCESS;
@@ -1558,6 +1552,8 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
                return (ret);
 
        ret = getsection(source, msg, &dctx, DNS_SECTION_AUTHORITY, options);
+       if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
+               goto truncated;
        if (ret == DNS_R_RECOVERABLE) {
                seen_problem = ISC_TRUE;
                ret = ISC_R_SUCCESS;
@@ -1566,6 +1562,8 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
                return (ret);
 
        ret = getsection(source, msg, &dctx, DNS_SECTION_ADDITIONAL, options);
+       if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
+               goto truncated;
        if (ret == DNS_R_RECOVERABLE) {
                seen_problem = ISC_TRUE;
                ret = ISC_R_SUCCESS;
@@ -1581,6 +1579,7 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
                              r.length);
        }
 
+ truncated:
        if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0)
                isc_buffer_usedregion(&origsource, &msg->saved);
        else {
@@ -1593,6 +1592,8 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
                msg->free_saved = 1;
        }
 
+       if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
+               return (DNS_R_RECOVERABLE);
        if (seen_problem == ISC_TRUE)
                return (DNS_R_RECOVERABLE);
        return (ISC_R_SUCCESS);