]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3662. [bug] 'host' could die if a UPD query timed out. [RT #34870]
authorMark Andrews <marka@isc.org>
Thu, 24 Oct 2013 23:09:33 +0000 (10:09 +1100)
committerMark Andrews <marka@isc.org>
Fri, 25 Oct 2013 01:33:01 +0000 (12:33 +1100)
(cherry picked from commit 6100b1769956200b2815803ab7b35556396ce0d1)

CHANGES
bin/dig/dighost.c
bin/dig/host.c
bin/dig/include/dig/dig.h
lib/isc/include/isc/socket.h
lib/isc/unix/socket.c
lib/isc/win32/libisc.def
lib/isc/win32/socket.c

diff --git a/CHANGES b/CHANGES
index 808d1058a275c51ae02568fab44fbecee3a92471..108295f6f0bc948c6c6935bf233ddfc6b877af90 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,5 @@
+3662.  [bug]           'host' could die if a UPD query timed out. [RT #34870]
+
 3660.  [cleanup]       Changed the name of "isc-config.sh" to "bind9-config".
                        [RT #23825]
 
index 79b11d082da0da59103437c25c09eb540bfa860f..5dcb3f5dc924b5c41a75985593293c4885388d9d 100644 (file)
@@ -174,6 +174,7 @@ isc_boolean_t validated = ISC_TRUE;
 isc_entropy_t *entp = NULL;
 isc_mempool_t *commctx = NULL;
 isc_boolean_t debugging = ISC_FALSE;
+isc_boolean_t debugtiming = ISC_FALSE;
 isc_boolean_t memdebugging = ISC_FALSE;
 char *progname = NULL;
 isc_mutex_t lookup_lock;
@@ -515,6 +516,12 @@ debug(const char *format, ...) {
 
        if (debugging) {
                fflush(stdout);
+               if (debugtiming) {
+                       struct timeval tv;
+                       (void)gettimeofday(&tv, NULL);
+                       fprintf(stderr, "%ld.%06u: ", (long)tv.tv_sec,
+                               tv.tv_usec);
+               }
                va_start(args, format);
                vfprintf(stderr, format, args);
                va_end(args);
@@ -2183,8 +2190,10 @@ send_done(isc_task_t *_task, isc_event_t *event) {
 
        for  (b = ISC_LIST_HEAD(sevent->bufferlist);
              b != NULL;
-             b = ISC_LIST_HEAD(sevent->bufferlist))
+             b = ISC_LIST_HEAD(sevent->bufferlist)) {
                ISC_LIST_DEQUEUE(sevent->bufferlist, b, link);
+               isc_mem_free(mctx, b);
+       }
 
        query = event->ev_arg;
        query->waiting_senddone = ISC_FALSE;
@@ -2376,6 +2385,17 @@ send_tcp_connect(dig_query_t *query) {
        }
 }
 
+static isc_buffer_t *
+clone_buffer(isc_buffer_t *source) {
+       isc_buffer_t *buffer;
+       buffer = isc_mem_allocate(mctx, sizeof(*buffer));
+       if (buffer == NULL)
+               fatal("memory allocation failure in %s:%d",
+                     __FILE__, __LINE__);
+       *buffer = *source;
+       return (buffer);
+}
+
 /*%
  * Send a UDP packet to the remote nameserver, possible starting the
  * recv action as well.  Also make sure that the timer is running and
@@ -2385,6 +2405,7 @@ static void
 send_udp(dig_query_t *query) {
        dig_lookup_t *l = NULL;
        isc_result_t result;
+       isc_buffer_t *sendbuf;
 
        debug("send_udp(%p)", query);
 
@@ -2431,14 +2452,16 @@ send_udp(dig_query_t *query) {
                debug("recvcount=%d", recvcount);
        }
        ISC_LIST_INIT(query->sendlist);
-       ISC_LIST_ENQUEUE(query->sendlist, &query->sendbuf, link);
+       sendbuf = clone_buffer(&query->sendbuf);
+       ISC_LIST_ENQUEUE(query->sendlist, sendbuf, link);
        debug("sending a request");
        TIME_NOW(&query->time_sent);
        INSIST(query->sock != NULL);
        query->waiting_senddone = ISC_TRUE;
-       result = isc_socket_sendtov(query->sock, &query->sendlist,
-                                   global_task, send_done, query,
-                                   &query->sockaddr, NULL);
+       result = isc_socket_sendtov2(query->sock, &query->sendlist,
+                                    global_task, send_done, query,
+                                    &query->sockaddr, NULL,
+                                    ISC_SOCKFLAG_NORETRY);
        check_result(result, "isc_socket_sendtov");
        sendcount++;
 }
@@ -2600,6 +2623,7 @@ static void
 launch_next_query(dig_query_t *query, isc_boolean_t include_question) {
        isc_result_t result;
        dig_lookup_t *l;
+       isc_buffer_t *buffer;
 
        INSIST(!free_now);
 
@@ -2623,9 +2647,13 @@ launch_next_query(dig_query_t *query, isc_boolean_t include_question) {
        isc_buffer_putuint16(&query->slbuf, (isc_uint16_t) query->sendbuf.used);
        ISC_LIST_INIT(query->sendlist);
        ISC_LINK_INIT(&query->slbuf, link);
-       ISC_LIST_ENQUEUE(query->sendlist, &query->slbuf, link);
-       if (include_question)
-               ISC_LIST_ENQUEUE(query->sendlist, &query->sendbuf, link);
+       buffer = clone_buffer(&query->slbuf);
+       ISC_LIST_ENQUEUE(query->sendlist, buffer, link);
+       if (include_question) { 
+               buffer = clone_buffer(&query->sendbuf);
+               ISC_LIST_ENQUEUE(query->sendlist, buffer, link); 
+       }
+
        ISC_LINK_INIT(&query->lengthbuf, link);
        ISC_LIST_ENQUEUE(query->lengthlist, &query->lengthbuf, link);
 
index 76be9926b7428c1d223f01c492c14dba233c321c..741d9d9e11eb29327906f1c7c791d1446cd7616c 100644 (file)
@@ -638,6 +638,8 @@ pre_parse_args(int argc, char **argv) {
                case 'w': break;
                case 'C': break;
                case 'D':
+                       if (debugging)
+                               debugtiming = ISC_TRUE;
                        debugging = ISC_TRUE;
                        break;
                case 'N': break;
index 8bdd8af9ba186241e675336844738e6acb37ca71..1e54001daf90dc269e4404f2166dbce959d8441b 100644 (file)
@@ -275,7 +275,7 @@ extern isc_boolean_t validated;
 extern isc_taskmgr_t *taskmgr;
 extern isc_task_t *global_task;
 extern isc_boolean_t free_now;
-extern isc_boolean_t debugging, memdebugging;
+extern isc_boolean_t debugging, debugtiming, memdebugging;
 
 extern char *progname;
 extern int tries;
index 08b746d092c79f8d794ef18739e13d19a19c8b64..98e0e5a203c7edb2455bebfcbb5524170a39ea45 100644 (file)
@@ -741,6 +741,11 @@ isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
                   isc_task_t *task, isc_taskaction_t action, const void *arg,
                   isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
 isc_result_t
+isc_socket_sendtov2(isc_socket_t *sock, isc_bufferlist_t *buflist,
+                   isc_task_t *task, isc_taskaction_t action, const void *arg,
+                   isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
+                   unsigned int flags);
+isc_result_t
 isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
                   isc_task_t *task,
                   isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
index 9b1209f24c2271c4e197035b9314c1986d5ae4d5..77ef50f6c6da8b0443e7c43412e059a2b2b8f728 100644 (file)
@@ -4484,14 +4484,24 @@ isc_result_t
 isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
                 isc_task_t *task, isc_taskaction_t action, const void *arg)
 {
-       return (isc_socket_sendtov(sock, buflist, task, action, arg, NULL,
-                                  NULL));
+       return (isc_socket_sendtov2(sock, buflist, task, action, arg, NULL,
+                                   NULL, 0));
 }
 
 isc_result_t
 isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
-                  isc_task_t *task, isc_taskaction_t action, const void *arg,
-                  isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
+                   isc_task_t *task, isc_taskaction_t action, const void *arg,
+                   isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
+{
+       return (isc_socket_sendtov2(sock, buflist, task, action, arg, address,
+                                   pktinfo, 0));
+}
+
+isc_result_t
+isc_socket_sendtov2(isc_socket_t *sock, isc_bufferlist_t *buflist,
+                    isc_task_t *task, isc_taskaction_t action, const void *arg,
+                    isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
+                    unsigned int flags)
 {
        isc_socketevent_t *dev;
        isc_socketmgr_t *manager;
@@ -4524,7 +4534,7 @@ isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
                buffer = ISC_LIST_HEAD(*buflist);
        }
 
-       return (socket_send(sock, dev, task, address, pktinfo, 0));
+       return (socket_send(sock, dev, task, address, pktinfo, flags));
 }
 
 isc_result_t
index 1a7eafa6448aee0015525ff296b9e72d49a07c85..7aecdfb57082872824b156007b988c3bf2aac55d 100644 (file)
@@ -447,6 +447,7 @@ isc_socket_send
 isc_socket_sendto
 isc_socket_sendto2
 isc_socket_sendtov
+isc_socket_sendtov2
 isc_socket_sendv
 isc_socket_setname
 isc_socketmgr_create
index 904117187939c96898a35e8e9e0a62c0439425dc..4120bf93c617645829608430aa730d774f7f3a9d 100644 (file)
@@ -3029,14 +3029,24 @@ isc_result_t
 isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
                 isc_task_t *task, isc_taskaction_t action, const void *arg)
 {
-       return (isc_socket_sendtov(sock, buflist, task, action, arg, NULL,
-                                  NULL));
+       return (isc_socket_sendtov2(sock, buflist, task, action, arg, NULL,
+                                   NULL, 0));
 }
 
 isc_result_t
 isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
                   isc_task_t *task, isc_taskaction_t action, const void *arg,
                   isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
+{
+       return (isc_socket_sendtov2(sock, buflist, task, action, arg, address,
+                                   pktinfo, 0));
+}
+
+isc_result_t
+isc__socket_sendtov2(isc_socket_t *sock, isc_bufferlist_t *buflist,
+                    isc_task_t *task, isc_taskaction_t action, const void *arg,
+                    isc_sockaddr_t *address, struct in6_pktinfo *pktinfo
+                    unsigned int flags)
 {
        isc_socketevent_t *dev;
        isc_socketmgr_t *manager;
@@ -3083,7 +3093,7 @@ isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
                buffer = ISC_LIST_HEAD(*buflist);
        }
 
-       ret = socket_send(sock, dev, task, address, pktinfo, 0);
+       ret = socket_send(sock, dev, task, address, pktinfo, flags);
        UNLOCK(&sock->lock);
        return (ret);
 }