diff --git a/CHANGES b/CHANGES index 3433eab5f3..3e188efd5a 100644 --- 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. diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index c41565e3c9..e50e9ffac7 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -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); diff --git a/bin/dig/host.c b/bin/dig/host.c index 49fe991e1c..3cb3ddf5b6 100644 --- a/bin/dig/host.c +++ b/bin/dig/host.c @@ -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; diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h index f04440cfb5..41463d11ae 100644 --- a/bin/dig/include/dig/dig.h +++ b/bin/dig/include/dig/dig.h @@ -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; diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h index 4f4bb91e41..1fef83f35e 100644 --- a/lib/isc/include/isc/socket.h +++ b/lib/isc/include/isc/socket.h @@ -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, diff --git a/lib/isc/socket_api.c b/lib/isc/socket_api.c index acd73cf231..4cec50f921 100644 --- a/lib/isc/socket_api.c +++ b/lib/isc/socket_api.c @@ -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, diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index be713d67c1..f92178ff34 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -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 diff --git a/lib/isc/win32/libisc.def b/lib/isc/win32/libisc.def index 5cfd744844..8258e35585 100644 --- a/lib/isc/win32/libisc.def +++ b/lib/isc/win32/libisc.def @@ -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 diff --git a/lib/isc/win32/socket.c b/lib/isc/win32/socket.c index 91219d482f..b2e8798edf 100644 --- a/lib/isc/win32/socket.c +++ b/lib/isc/win32/socket.c @@ -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); }