]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] Prevent dig INSIST failures and hangs in some failure modes
authorMichał Kępień <michal@isc.org>
Thu, 5 Oct 2017 07:42:31 +0000 (09:42 +0200)
committerMichał Kępień <michal@isc.org>
Thu, 5 Oct 2017 07:42:31 +0000 (09:42 +0200)
4756. [bug] Interrupting dig could lead to an INSIST failure after
certain errors were encountered while querying a host
whose name resolved to more than one address.  Change
4537 increased the odds of triggering this issue by
causing dig to hang indefinitely when certain error
paths were evaluated.  dig now also retries TCP queries
(once) if the server gracefully closes the connection
before sending a response. [RT #42832, #45159]

CHANGES
bin/dig/dighost.c
bin/dig/include/dig/dig.h

diff --git a/CHANGES b/CHANGES
index 91dfc2c6727dc3a190fe08a216782f04aaa39c01..8752fd9a00a18d7e235fd426ac268ff2091e3d3b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,12 @@
+4756.  [bug]           Interrupting dig could lead to an INSIST failure after
+                       certain errors were encountered while querying a host
+                       whose name resolved to more than one address.  Change
+                       4537 increased the odds of triggering this issue by
+                       causing dig to hang indefinitely when certain error
+                       paths were evaluated.  dig now also retries TCP queries
+                       (once) if the server gracefully closes the connection
+                       before sending a response. [RT #42832, #45159]
+
 4755.  [cleanup]       Silence unnecessary log message when NZF file doesn't
                        exist. [RT #46186]
 
index 3dd23d8710388c0b7a535e05bcbc5ec05e3e78f0..e0058e5a8da5a1475a8e076eac9c6fb53ee695d4 100644 (file)
@@ -646,6 +646,7 @@ make_empty_lookup(void) {
        looknew->mapped = ISC_TRUE;
        looknew->dscp = -1;
        looknew->rrcomments = 0;
+       looknew->eoferr = 0;
        dns_fixedname_init(&looknew->fdomain);
        ISC_LINK_INIT(looknew, link);
        ISC_LIST_INIT(looknew->q);
@@ -737,6 +738,7 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
        looknew->done_as_is = lookold->done_as_is;
        looknew->dscp = lookold->dscp;
        looknew->rrcomments = lookold->rrcomments;
+       looknew->eoferr = lookold->eoferr;
 
        if (lookold->ecs_addr != NULL) {
                size_t len = sizeof(isc_sockaddr_t);
@@ -2775,9 +2777,12 @@ send_udp(dig_query_t *query) {
                        next = ISC_LIST_NEXT(query, link);
                        l = query->lookup;
                        clear_query(query);
-                       if (next == NULL)
+                       if (next == NULL) {
                                printf(";; No acceptable nameservers\n");
-                       check_next_lookup(l);
+                               check_next_lookup(l);
+                       } else {
+                               send_udp(next);
+                       }
                        return;
                }
 
@@ -2909,7 +2914,7 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) {
        isc_buffer_t *b = NULL;
        isc_result_t result;
        dig_query_t *query = NULL;
-       dig_lookup_t *l;
+       dig_lookup_t *l, *n;
        isc_uint16_t length;
 
        REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE);
@@ -2944,13 +2949,20 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) {
                                    sizeof(sockstr));
                printf(";; communications error to %s: %s\n",
                       sockstr, isc_result_totext(sevent->result));
+               if (keep != NULL)
+                       isc_socket_detach(&keep);
                l = query->lookup;
                isc_socket_detach(&query->sock);
                sockcount--;
                debug("sockcount=%d", sockcount);
                INSIST(sockcount >= 0);
+               if (sevent->result == ISC_R_EOF && l->eoferr == 0U) {
+                       n = requeue_lookup(l, ISC_TRUE);
+                       n->eoferr++;
+               }
                isc_event_free(&event);
                clear_query(query);
+               cancel_lookup(l);
                check_next_lookup(l);
                UNLOCK_LOOKUP;
                return;
@@ -3443,13 +3455,20 @@ recv_done(isc_task_t *task, isc_event_t *event) {
                } else {
                        printf(";; communications error: %s\n",
                               isc_result_totext(sevent->result));
+                       if (keep != NULL)
+                               isc_socket_detach(&keep);
                        isc_socket_detach(&query->sock);
                        sockcount--;
                        debug("sockcount=%d", sockcount);
                        INSIST(sockcount >= 0);
                }
+               if (sevent->result == ISC_R_EOF && l->eoferr == 0U) {
+                       n = requeue_lookup(l, ISC_TRUE);
+                       n->eoferr++;
+               }
                isc_event_free(&event);
                clear_query(query);
+               cancel_lookup(l);
                check_next_lookup(l);
                UNLOCK_LOOKUP;
                return;
@@ -3511,6 +3530,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
                        if (fail) {
                                isc_event_free(&event);
                                clear_query(query);
+                               cancel_lookup(l);
                                check_next_lookup(l);
                                UNLOCK_LOOKUP;
                                return;
@@ -3614,6 +3634,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
                        if (l->tcp_mode) {
                                isc_event_free(&event);
                                clear_query(query);
+                               cancel_lookup(l);
                                check_next_lookup(l);
                                UNLOCK_LOOKUP;
                                return;
index 664b309e47d604df257df8fd08e1a40b8591141b..e34ee02f4884b5d23355e133dbffad967542462f 100644 (file)
@@ -168,6 +168,7 @@ struct dig_lookup {
        unsigned int ednsflags;
        dns_opcode_t opcode;
        int rrcomments;
+       unsigned int eoferr;
 };
 
 /*% The dig_query structure */