]> 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>
Thu, 24 Oct 2013 23:09:33 +0000 (10:09 +1100)
CHANGES
bin/dig/dighost.c
bin/dig/host.c
bin/dig/include/dig/dig.h
lib/isc/include/isc/socket.h
lib/isc/socket_api.c
lib/isc/unix/socket.c
lib/isc/win32/libisc.def
lib/isc/win32/socket.c

diff --git a/CHANGES b/CHANGES
index 3433eab5f35d857018f14c5e87bf535847d0f0f9..3e188efd5a30719fd8bb99856a06e78b7b8553cc 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,5 @@
+3662.  [bug]           'host' could die if a UPD query timed out. [RT #34870]
+
        --- 9.10.0a1 released ---
 
 3661.  [bug]           Address lock order reversal deadlock with inline zones.
index c41565e3c97a39e41596f66c2a9437bebea71703..e50e9ffac7ba2a4a0f5b4a6e64fb245fee4ce7c3 100644 (file)
@@ -180,6 +180,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;
@@ -539,6 +540,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);
@@ -2365,8 +2372,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;
@@ -2558,6 +2567,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
@@ -2567,6 +2587,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);
 
@@ -2613,14 +2634,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++;
 }
@@ -2782,6 +2805,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);
 
@@ -2805,9 +2829,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 49fe991e1ca08365c424c677e760ad4cebc55a7e..3cb3ddf5b6e6be4bb0269e4eb323eba85b632fcc 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 f04440cfb5270de7d331a5fc7c2ba21d515631c8..41463d11aeead7a16941dc184fe77e7b30690760 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 4f4bb91e4168c05ffeed327c46f6bcc19dd48330..1fef83f35e8da4ae7e12a2ea1877e3cdbc898f3e 100644 (file)
@@ -87,6 +87,7 @@
 #define isc_socket_sendto isc__socket_sendto
 #define isc_socket_sendv isc__socket_sendv
 #define isc_socket_sendtov isc__socket_sendtov
+#define isc_socket_sendtov2 isc__socket_sendtov2
 #define isc_socket_sendto2 isc__socket_sendto2
 #define isc_socket_cleanunix isc__socket_cleanunix
 #define isc_socket_permunix isc__socket_permunix
@@ -925,6 +926,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 acd73cf231d527b5cc8606f7adf6f3149bda4d27..4cec50f9217b35e3c5e5671ea937c73ceb592137 100644 (file)
@@ -350,6 +350,16 @@ isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
                                    address, 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)
+{
+       return (isc__socket_sendtov2(sock, buflist, task, action, arg,
+                                    address, pktinfo, flags));
+}
+
 isc_result_t
 isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
                    isc_task_t *task,
index be713d67c1cabaa4858465ebc4667ee1e0a76407..f92178ff34178bfa77ba38bd9c1826dac67596f2 100644 (file)
@@ -507,6 +507,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,
@@ -4992,14 +4997,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 *sock0, isc_bufferlist_t *buflist,
+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 *sock0, 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__socket_t *sock = (isc__socket_t *)sock0;
        isc_socketevent_t *dev;
@@ -5034,7 +5049,7 @@ isc__socket_sendtov(isc_socket_t *sock0, 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 5cfd7448441a1ab06f0ef4a4da024086add3f8ba..8258e35585176148a4964557742098f99684968b 100644 (file)
@@ -76,6 +76,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 91219d482fb160eca220efe9967df2ae8737de26..b2e8798edf0ebfdce55ed4b90f4a153914123234 100644 (file)
@@ -3090,14 +3090,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;
@@ -3145,7 +3155,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);
 }