Tomas Hozza 48fc9b
diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c
Tomas Hozza 48fc9b
index 2b7b970..491192d 100644
Tomas Hozza 48fc9b
--- a/bin/dig/dighost.c
Tomas Hozza 48fc9b
+++ b/bin/dig/dighost.c
Tomas Hozza 48fc9b
@@ -180,6 +180,7 @@ isc_boolean_t validated = ISC_TRUE;
Tomas Hozza 48fc9b
 isc_entropy_t *entp = NULL;
Tomas Hozza 48fc9b
 isc_mempool_t *commctx = NULL;
Tomas Hozza 48fc9b
 isc_boolean_t debugging = ISC_FALSE;
Tomas Hozza 48fc9b
+isc_boolean_t debugtiming = ISC_FALSE;
Tomas Hozza 48fc9b
 isc_boolean_t memdebugging = ISC_FALSE;
Tomas Hozza 48fc9b
 char *progname = NULL;
Tomas Hozza 48fc9b
 isc_mutex_t lookup_lock;
Tomas Hozza 48fc9b
@@ -539,6 +540,12 @@ debug(const char *format, ...) {
Tomas Hozza 48fc9b
 
Tomas Hozza 48fc9b
 	if (debugging) {
Tomas Hozza 48fc9b
 		fflush(stdout);
Tomas Hozza 48fc9b
+		if (debugtiming) {
Tomas Hozza 48fc9b
+			struct timeval tv;
Tomas Hozza 48fc9b
+			(void)gettimeofday(&tv, NULL);
Tomas Hozza 48fc9b
+			fprintf(stderr, "%ld.%06ld: ", (long)tv.tv_sec,
Tomas Hozza 48fc9b
+				(long)tv.tv_usec);
Tomas Hozza 48fc9b
+		}
Tomas Hozza 48fc9b
 		va_start(args, format);
Tomas Hozza 48fc9b
 		vfprintf(stderr, format, args);
Tomas Hozza 48fc9b
 		va_end(args);
Tomas Hozza 48fc9b
@@ -2365,8 +2372,10 @@ send_done(isc_task_t *_task, isc_event_t *event) {
Tomas Hozza 48fc9b
 
Tomas Hozza 48fc9b
 	for  (b = ISC_LIST_HEAD(sevent->bufferlist);
Tomas Hozza 48fc9b
 	      b != NULL;
Tomas Hozza 48fc9b
-	      b = ISC_LIST_HEAD(sevent->bufferlist))
Tomas Hozza 48fc9b
+	      b = ISC_LIST_HEAD(sevent->bufferlist)) {
Tomas Hozza 48fc9b
 		ISC_LIST_DEQUEUE(sevent->bufferlist, b, link);
Tomas Hozza 48fc9b
+		isc_mem_free(mctx, b);
Tomas Hozza 48fc9b
+	}
Tomas Hozza 48fc9b
 
Tomas Hozza 48fc9b
 	query = event->ev_arg;
Tomas Hozza 48fc9b
 	query->waiting_senddone = ISC_FALSE;
Tomas Hozza 48fc9b
@@ -2558,6 +2567,17 @@ send_tcp_connect(dig_query_t *query) {
Tomas Hozza 48fc9b
 	}
Tomas Hozza 48fc9b
 }
Tomas Hozza 48fc9b
 
Tomas Hozza 48fc9b
+static isc_buffer_t *
Tomas Hozza 48fc9b
+clone_buffer(isc_buffer_t *source) {
Tomas Hozza 48fc9b
+	isc_buffer_t *buffer;
Tomas Hozza 48fc9b
+	buffer = isc_mem_allocate(mctx, sizeof(*buffer));
Tomas Hozza 48fc9b
+	if (buffer == NULL)
Tomas Hozza 48fc9b
+		fatal("memory allocation failure in %s:%d",
Tomas Hozza 48fc9b
+		      __FILE__, __LINE__);
Tomas Hozza 48fc9b
+	*buffer = *source;
Tomas Hozza 48fc9b
+	return (buffer);
Tomas Hozza 48fc9b
+}
Tomas Hozza 48fc9b
+
Tomas Hozza 48fc9b
 /*%
Tomas Hozza 48fc9b
  * Send a UDP packet to the remote nameserver, possible starting the
Tomas Hozza 48fc9b
  * recv action as well.  Also make sure that the timer is running and
Tomas Hozza 48fc9b
@@ -2567,6 +2587,7 @@ static void
Tomas Hozza 48fc9b
 send_udp(dig_query_t *query) {
Tomas Hozza 48fc9b
 	dig_lookup_t *l = NULL;
Tomas Hozza 48fc9b
 	isc_result_t result;
Tomas Hozza 48fc9b
+	isc_buffer_t *sendbuf;
Tomas Hozza 48fc9b
 
Tomas Hozza 48fc9b
 	debug("send_udp(%p)", query);
Tomas Hozza 48fc9b
 
Tomas Hozza 48fc9b
@@ -2613,14 +2634,16 @@ send_udp(dig_query_t *query) {
Tomas Hozza 48fc9b
 		debug("recvcount=%d", recvcount);
Tomas Hozza 48fc9b
 	}
Tomas Hozza 48fc9b
 	ISC_LIST_INIT(query->sendlist);
Tomas Hozza 48fc9b
-	ISC_LIST_ENQUEUE(query->sendlist, &query->sendbuf, link);
Tomas Hozza 48fc9b
+	sendbuf = clone_buffer(&query->sendbuf);
Tomas Hozza 48fc9b
+	ISC_LIST_ENQUEUE(query->sendlist, sendbuf, link);
Tomas Hozza 48fc9b
 	debug("sending a request");
Tomas Hozza 48fc9b
 	TIME_NOW(&query->time_sent);
Tomas Hozza 48fc9b
 	INSIST(query->sock != NULL);
Tomas Hozza 48fc9b
 	query->waiting_senddone = ISC_TRUE;
Tomas Hozza 48fc9b
-	result = isc_socket_sendtov(query->sock, &query->sendlist,
Tomas Hozza 48fc9b
-				    global_task, send_done, query,
Tomas Hozza 48fc9b
-				    &query->sockaddr, NULL);
Tomas Hozza 48fc9b
+	result = isc_socket_sendtov2(query->sock, &query->sendlist,
Tomas Hozza 48fc9b
+				     global_task, send_done, query,
Tomas Hozza 48fc9b
+				     &query->sockaddr, NULL,
Tomas Hozza 48fc9b
+				     ISC_SOCKFLAG_NORETRY);
Tomas Hozza 48fc9b
 	check_result(result, "isc_socket_sendtov");
Tomas Hozza 48fc9b
 	sendcount++;
Tomas Hozza 48fc9b
 }
Tomas Hozza 48fc9b
@@ -2782,6 +2805,7 @@ static void
Tomas Hozza 48fc9b
 launch_next_query(dig_query_t *query, isc_boolean_t include_question) {
Tomas Hozza 48fc9b
 	isc_result_t result;
Tomas Hozza 48fc9b
 	dig_lookup_t *l;
Tomas Hozza 48fc9b
+	isc_buffer_t *buffer;
Tomas Hozza 48fc9b
 
Tomas Hozza 48fc9b
 	INSIST(!free_now);
Tomas Hozza 48fc9b
 
Tomas Hozza 48fc9b
@@ -2805,9 +2829,13 @@ launch_next_query(dig_query_t *query, isc_boolean_t include_question) {
Tomas Hozza 48fc9b
 	isc_buffer_putuint16(&query->slbuf, (isc_uint16_t) query->sendbuf.used);
Tomas Hozza 48fc9b
 	ISC_LIST_INIT(query->sendlist);
Tomas Hozza 48fc9b
 	ISC_LINK_INIT(&query->slbuf, link);
Tomas Hozza 48fc9b
-	ISC_LIST_ENQUEUE(query->sendlist, &query->slbuf, link);
Tomas Hozza 48fc9b
-	if (include_question)
Tomas Hozza 48fc9b
-		ISC_LIST_ENQUEUE(query->sendlist, &query->sendbuf, link);
Tomas Hozza 48fc9b
+	buffer = clone_buffer(&query->slbuf);
Tomas Hozza 48fc9b
+	ISC_LIST_ENQUEUE(query->sendlist, buffer, link);
Tomas Hozza 48fc9b
+	if (include_question) {
Tomas Hozza 48fc9b
+		buffer = clone_buffer(&query->sendbuf);
Tomas Hozza 48fc9b
+		ISC_LIST_ENQUEUE(query->sendlist, buffer, link);
Tomas Hozza 48fc9b
+	}
Tomas Hozza 48fc9b
+
Tomas Hozza 48fc9b
 	ISC_LINK_INIT(&query->lengthbuf, link);
Tomas Hozza 48fc9b
 	ISC_LIST_ENQUEUE(query->lengthlist, &query->lengthbuf, link);
Tomas Hozza 48fc9b
 
Tomas Hozza 48fc9b
diff --git a/bin/dig/host.c b/bin/dig/host.c
Tomas Hozza 48fc9b
index 49fe991..3cb3ddf 100644
Tomas Hozza 48fc9b
--- a/bin/dig/host.c
Tomas Hozza 48fc9b
+++ b/bin/dig/host.c
Tomas Hozza 48fc9b
@@ -638,6 +638,8 @@ pre_parse_args(int argc, char **argv) {
Tomas Hozza 48fc9b
 		case 'w': break;
Tomas Hozza 48fc9b
 		case 'C': break;
Tomas Hozza 48fc9b
 		case 'D':
Tomas Hozza 48fc9b
+			if (debugging)
Tomas Hozza 48fc9b
+				debugtiming = ISC_TRUE;
Tomas Hozza 48fc9b
 			debugging = ISC_TRUE;
Tomas Hozza 48fc9b
 			break;
Tomas Hozza 48fc9b
 		case 'N': break;
Tomas Hozza 48fc9b
diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h
Tomas Hozza 48fc9b
index f04440c..41463d1 100644
Tomas Hozza 48fc9b
--- a/bin/dig/include/dig/dig.h
Tomas Hozza 48fc9b
+++ b/bin/dig/include/dig/dig.h
Tomas Hozza 48fc9b
@@ -275,7 +275,7 @@ extern isc_boolean_t validated;
Tomas Hozza 48fc9b
 extern isc_taskmgr_t *taskmgr;
Tomas Hozza 48fc9b
 extern isc_task_t *global_task;
Tomas Hozza 48fc9b
 extern isc_boolean_t free_now;
Tomas Hozza 48fc9b
-extern isc_boolean_t debugging, memdebugging;
Tomas Hozza 48fc9b
+extern isc_boolean_t debugging, debugtiming, memdebugging;
Tomas Hozza 48fc9b
 
Tomas Hozza 48fc9b
 extern char *progname;
Tomas Hozza 48fc9b
 extern int tries;
Tomas Hozza 48fc9b
diff --git a/lib/isc/include/isc/namespace.h b/lib/isc/include/isc/namespace.h
Tomas Hozza 48fc9b
index f8744d8..e9bda5e 100644
Tomas Hozza 48fc9b
--- a/lib/isc/include/isc/namespace.h
Tomas Hozza 48fc9b
+++ b/lib/isc/include/isc/namespace.h
Tomas Hozza 48fc9b
@@ -106,6 +106,7 @@
Tomas Hozza 48fc9b
 #define isc_socket_sendv isc__socket_sendv
Tomas Hozza 48fc9b
 #define isc_socket_sendtov isc__socket_sendtov
Tomas Hozza 48fc9b
 #define isc_socket_sendto2 isc__socket_sendto2
Tomas Hozza 48fc9b
+#define isc_socket_sendtov2 isc__socket_sendtov2
Tomas Hozza 48fc9b
 #define isc_socket_cleanunix isc__socket_cleanunix
Tomas Hozza 48fc9b
 #define isc_socket_permunix isc__socket_permunix
Tomas Hozza 48fc9b
 #define isc_socket_bind isc__socket_bind
Tomas Hozza 48fc9b
diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h
Tomas Hozza 48fc9b
index 9d086b4..c5a753a 100644
Tomas Hozza 48fc9b
--- a/lib/isc/include/isc/socket.h
Tomas Hozza 48fc9b
+++ b/lib/isc/include/isc/socket.h
Tomas Hozza 48fc9b
@@ -866,6 +866,11 @@ isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
Tomas Hozza 48fc9b
 		   isc_task_t *task, isc_taskaction_t action, const void *arg,
Tomas Hozza 48fc9b
 		   isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
Tomas Hozza 48fc9b
 isc_result_t
Tomas Hozza 48fc9b
+isc_socket_sendtov2(isc_socket_t *sock, isc_bufferlist_t *buflist,
Tomas Hozza 48fc9b
+		    isc_task_t *task, isc_taskaction_t action, const void *arg,
Tomas Hozza 48fc9b
+		    isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
Tomas Hozza 48fc9b
+		    unsigned int flags);
Tomas Hozza 48fc9b
+isc_result_t
Tomas Hozza 48fc9b
 isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
Tomas Hozza 48fc9b
 		   isc_task_t *task,
Tomas Hozza 48fc9b
 		   isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
Tomas Hozza 48fc9b
diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c
Tomas Hozza 48fc9b
index dc0b141..9b99acb 100644
Tomas Hozza 48fc9b
--- a/lib/isc/unix/socket.c
Tomas Hozza 48fc9b
+++ b/lib/isc/unix/socket.c
Tomas Hozza 48fc9b
@@ -505,6 +505,11 @@ isc__socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
Tomas Hozza 48fc9b
 		    isc_task_t *task, isc_taskaction_t action, const void *arg,
Tomas Hozza 48fc9b
 		    isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
Tomas Hozza 48fc9b
 ISC_SOCKETFUNC_SCOPE isc_result_t
Tomas Hozza 48fc9b
+isc__socket_sendtov2(isc_socket_t *sock, isc_bufferlist_t *buflist,
Tomas Hozza 48fc9b
+		     isc_task_t *task, isc_taskaction_t action, const void *arg,
Tomas Hozza 48fc9b
+		     isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
Tomas Hozza 48fc9b
+		     unsigned int flags);
Tomas Hozza 48fc9b
+ISC_SOCKETFUNC_SCOPE isc_result_t
Tomas Hozza 48fc9b
 isc__socket_sendto2(isc_socket_t *sock, isc_region_t *region,
Tomas Hozza 48fc9b
 		    isc_task_t *task,
Tomas Hozza 48fc9b
 		    isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
Tomas Hozza 48fc9b
@@ -4791,15 +4796,25 @@ ISC_SOCKETFUNC_SCOPE isc_result_t
Tomas Hozza 48fc9b
 isc__socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
Tomas Hozza 48fc9b
 		  isc_task_t *task, isc_taskaction_t action, const void *arg)
Tomas Hozza 48fc9b
 {
Tomas Hozza 48fc9b
-	return (isc__socket_sendtov(sock, buflist, task, action, arg, NULL,
Tomas Hozza 48fc9b
-				    NULL));
Tomas Hozza 48fc9b
+	return (isc__socket_sendtov2(sock, buflist, task, action, arg, NULL,
Tomas Hozza 48fc9b
+				     NULL, 0));
Tomas Hozza 48fc9b
 }
Tomas Hozza 48fc9b
 
Tomas Hozza 48fc9b
 ISC_SOCKETFUNC_SCOPE isc_result_t
Tomas Hozza 48fc9b
-isc__socket_sendtov(isc_socket_t *sock0, isc_bufferlist_t *buflist,
Tomas Hozza 48fc9b
+isc__socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
Tomas Hozza 48fc9b
 		    isc_task_t *task, isc_taskaction_t action, const void *arg,
Tomas Hozza 48fc9b
 		    isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
Tomas Hozza 48fc9b
 {
Tomas Hozza 48fc9b
+	return (isc__socket_sendtov2(sock, buflist, task, action, arg, address,
Tomas Hozza 48fc9b
+				     pktinfo, 0));
Tomas Hozza 48fc9b
+}
Tomas Hozza 48fc9b
+
Tomas Hozza 48fc9b
+ISC_SOCKETFUNC_SCOPE isc_result_t
Tomas Hozza 48fc9b
+isc__socket_sendtov2(isc_socket_t *sock0, isc_bufferlist_t *buflist,
Tomas Hozza 48fc9b
+		     isc_task_t *task, isc_taskaction_t action, const void *arg,
Tomas Hozza 48fc9b
+		     isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
Tomas Hozza 48fc9b
+		     unsigned int flags)
Tomas Hozza 48fc9b
+{
Tomas Hozza 48fc9b
 	isc__socket_t *sock = (isc__socket_t *)sock0;
Tomas Hozza 48fc9b
 	isc_socketevent_t *dev;
Tomas Hozza 48fc9b
 	isc__socketmgr_t *manager;
Tomas Hozza 48fc9b
@@ -4832,7 +4847,7 @@ isc__socket_sendtov(isc_socket_t *sock0, isc_bufferlist_t *buflist,
Tomas Hozza 48fc9b
 		buffer = ISC_LIST_HEAD(*buflist);
Tomas Hozza 48fc9b
 	}
Tomas Hozza 48fc9b
 
Tomas Hozza 48fc9b
-	return (socket_send(sock, dev, task, address, pktinfo, 0));
Tomas Hozza 48fc9b
+	return (socket_send(sock, dev, task, address, pktinfo, flags));
Tomas Hozza 48fc9b
 }
Tomas Hozza 48fc9b
 
Tomas Hozza 48fc9b
 ISC_SOCKETFUNC_SCOPE isc_result_t