diff --git a/SOURCES/bind-9.11-CVE-2018-5743-atomic.patch b/SOURCES/bind-9.11-CVE-2018-5743-atomic.patch
new file mode 100644
index 0000000..6997084
--- /dev/null
+++ b/SOURCES/bind-9.11-CVE-2018-5743-atomic.patch
@@ -0,0 +1,131 @@
+From 8f02da17a14f5f502bb456b206fd65ecd7d6ca1a Mon Sep 17 00:00:00 2001
+From: Petr Mensik <pemensik@redhat.com>
+Date: Wed, 24 Apr 2019 21:10:26 +0200
+Subject: [PATCH 4/4] Missing atomic fix to original CVE patch
+
+---
+ bin/named/client.c                     | 18 +++++++-----------
+ bin/named/include/named/interfacemgr.h |  5 +++--
+ bin/named/interfacemgr.c               |  7 +++++--
+ 3 files changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/bin/named/client.c b/bin/named/client.c
+index a2e1fde9b8..c247f027d9 100644
+--- a/bin/named/client.c
++++ b/bin/named/client.c
+@@ -389,12 +389,10 @@ tcpconn_detach(ns_client_t *client) {
+ static void
+ mark_tcp_active(ns_client_t *client, isc_boolean_t active) {
+ 	if (active && !client->tcpactive) {
+-		isc_atomic_xadd(&client->interface->ntcpactive, 1);
++		isc_refcount_increment0(&client->interface->ntcpactive, NULL);
+ 		client->tcpactive = active;
+ 	} else if (!active && client->tcpactive) {
+-		uint32_t old =
+-			isc_atomic_xadd(&client->interface->ntcpactive, -1);
+-		INSIST(old > 0);
++		isc_refcount_decrement(&client->interface->ntcpactive, NULL);
+ 		client->tcpactive = active;
+ 	}
+ }
+@@ -540,7 +538,7 @@ exit_check(ns_client_t *client) {
+ 		if (client->mortal && TCP_CLIENT(client) &&
+ 		    client->newstate != NS_CLIENTSTATE_FREED &&
+ 		    !ns_g_clienttest &&
+-		    isc_atomic_xadd(&client->interface->ntcpaccepting, 0) == 0)
++		    isc_refcount_current(&client->interface->ntcpaccepting) == 0)
+ 		{
+ 			/* Nobody else is accepting */
+ 			client->mortal = ISC_FALSE;
+@@ -2433,7 +2431,6 @@ client_newconn(isc_task_t *task, isc_event_t *event) {
+ 	isc_result_t result;
+ 	ns_client_t *client = event->ev_arg;
+ 	isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event;
+-	uint32_t old;
+ 
+ 	REQUIRE(event->ev_type == ISC_SOCKEVENT_NEWCONN);
+ 	REQUIRE(NS_CLIENT_VALID(client));
+@@ -2453,8 +2450,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) {
+ 	INSIST(client->naccepts == 1);
+ 	client->naccepts--;
+ 
+-	old = isc_atomic_xadd(&client->interface->ntcpaccepting, -1);
+-	INSIST(old > 0);
++	isc_refcount_decrement(&client->interface->ntcpaccepting, NULL);
+ 
+ 	/*
+ 	 * We must take ownership of the new socket before the exit
+@@ -2585,8 +2581,8 @@ client_accept(ns_client_t *client) {
+ 		 * quota is tcp-clients plus the number of listening
+ 		 * interfaces plus 1.)
+ 		 */
+-		exit = (isc_atomic_xadd(&client->interface->ntcpactive, 0) >
+-			(client->tcpactive ? 1 : 0));
++		exit = (isc_refcount_current(&client->interface->ntcpactive) >
++			(client->tcpactive ? 1U : 0U));
+ 		if (exit) {
+ 			client->newstate = NS_CLIENTSTATE_INACTIVE;
+ 			(void)exit_check(client);
+@@ -2644,7 +2640,7 @@ client_accept(ns_client_t *client) {
+ 	 * listening for connections itself to prevent the interface
+ 	 * going dead.
+ 	 */
+-	isc_atomic_xadd(&client->interface->ntcpaccepting, 1);
++	isc_refcount_increment0(&client->interface->ntcpaccepting, NULL);
+ }
+ 
+ static void
+diff --git a/bin/named/include/named/interfacemgr.h b/bin/named/include/named/interfacemgr.h
+index a34286698b..28d1b79027 100644
+--- a/bin/named/include/named/interfacemgr.h
++++ b/bin/named/include/named/interfacemgr.h
+@@ -49,6 +49,7 @@
+ #include <isc/magic.h>
+ #include <isc/mem.h>
+ #include <isc/socket.h>
++#include <isc/refcount.h>
+ 
+ #include <dns/result.h>
+ 
+@@ -78,11 +79,11 @@ struct ns_interface {
+ 	dns_dispatch_t *	udpdispatch[MAX_UDP_DISPATCH];
+ 						/*%< UDP dispatchers. */
+ 	isc_socket_t *		tcpsocket;	/*%< TCP socket. */
+-	int32_t			ntcpaccepting;	/*%< Number of clients
++	isc_refcount_t		ntcpaccepting;	/*%< Number of clients
+ 						     ready to accept new
+ 						     TCP connections on this
+ 						     interface */
+-	int32_t			ntcpactive;	/*%< Number of clients
++	isc_refcount_t		ntcpactive;	/*%< Number of clients
+ 						     servicing TCP queries
+ 						     (whether accepting or
+ 						     connected) */
+diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c
+index ebec0c4059..a59e9afd58 100644
+--- a/bin/named/interfacemgr.c
++++ b/bin/named/interfacemgr.c
+@@ -380,8 +380,8 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
+ 	 * connections will be handled in parallel even though there is
+ 	 * only one client initially.
+ 	 */
+-	ifp->ntcpaccepting = 0;
+-	ifp->ntcpactive = 0;
++	isc_refcount_init(&ifp->ntcpaccepting, 0);
++	isc_refcount_init(&ifp->ntcpactive, 0);
+ 
+ 	ifp->nudpdispatch = 0;
+ 
+@@ -595,6 +595,9 @@ ns_interface_destroy(ns_interface_t *ifp) {
+ 
+ 	ns_interfacemgr_detach(&ifp->mgr);
+ 
++	isc_refcount_destroy(&ifp->ntcpactive);
++	isc_refcount_destroy(&ifp->ntcpaccepting);
++
+ 	ifp->magic = 0;
+ 	isc_mem_put(mctx, ifp, sizeof(*ifp));
+ }
+-- 
+2.20.1
+
diff --git a/SOURCES/bind-9.11-CVE-2018-5743.patch b/SOURCES/bind-9.11-CVE-2018-5743.patch
new file mode 100644
index 0000000..6b8c48f
--- /dev/null
+++ b/SOURCES/bind-9.11-CVE-2018-5743.patch
@@ -0,0 +1,864 @@
+From 05bf4fa9056d85782dad528bba3d0fa90946d4d8 Mon Sep 17 00:00:00 2001
+From: Petr Mensik <pemensik@redhat.com>
+Date: Wed, 24 Apr 2019 20:09:07 +0200
+Subject: [PATCH] 5200. [security] tcp-clients settings could be exceeded in
+ some cases, which could lead to exhaustion of file descriptors.
+ (CVE-2018-5743) [GL #615]
+---
+ bin/named/client.c                     | 428 +++++++++++++++++++------
+ bin/named/include/named/client.h       |  13 +-
+ bin/named/include/named/interfacemgr.h |  13 +-
+ bin/named/interfacemgr.c               |   9 +-
+ lib/isc/include/isc/quota.h            |   7 +
+ lib/isc/quota.c                        |  33 +-
+ 6 files changed, 389 insertions(+), 114 deletions(-)
+
+diff --git a/bin/named/client.c b/bin/named/client.c
+index f014b61..0ba383b 100644
+--- a/bin/named/client.c
++++ b/bin/named/client.c
+@@ -234,7 +234,9 @@ static void ns_client_dumpmessage(ns_client_t *client, const char *reason);
+ static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,
+ 			       dns_dispatch_t *disp, isc_boolean_t tcp);
+ static isc_result_t get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp,
+-			       isc_socket_t *socket);
++			       isc_socket_t *sock, ns_client_t *oldclient);
++static inline isc_boolean_t
++allowed(isc_netaddr_t *addr, dns_name_t *signer, dns_acl_t *acl);
+ 
+ void
+ ns_client_recursing(ns_client_t *client) {
+@@ -280,6 +282,119 @@ ns_client_settimeout(ns_client_t *client, unsigned int seconds) {
+ 	}
+ }
+ 
++/*%
++ * Allocate a reference-counted object that will maintain a single pointer to
++ * the (also reference-counted) TCP client quota, shared between all the
++ * clients processing queries on a single TCP connection, so that all
++ * clients sharing the one socket will together consume only one slot in
++ * the 'tcp-clients' quota.
++ */
++static isc_result_t
++tcpconn_init(ns_client_t *client, isc_boolean_t force) {
++	isc_result_t result;
++	isc_quota_t *quota = NULL;
++	ns_tcpconn_t *tconn = NULL;
++
++	REQUIRE(client->tcpconn == NULL);
++
++	/*
++	 * Try to attach to the quota first, so we won't pointlessly
++	 * allocate memory for a tcpconn object if we can't get one.
++	 */
++	if (force) {
++		result = isc_quota_force(&ns_g_server->tcpquota, &quota);
++	} else {
++		result = isc_quota_attach(&ns_g_server->tcpquota, &quota);
++	}
++	if (result != ISC_R_SUCCESS) {
++		return (result);
++	}
++
++	/*
++	 * A global memory context is used for the allocation as different
++	 * client structures may have different memory contexts assigned and a
++	 * reference counter allocated here might need to be freed by a
++	 * different client.  The performance impact caused by memory context
++	 * contention here is expected to be negligible, given that this code
++	 * is only executed for TCP connections.
++	 */
++	tconn = isc_mem_allocate(ns_g_mctx, sizeof(*tconn));
++
++	isc_refcount_init(&tconn->refs, 1);
++	tconn->tcpquota = quota;
++	quota = NULL;
++	tconn->pipelined = ISC_FALSE;
++
++	client->tcpconn = tconn;
++
++	return (ISC_R_SUCCESS);
++}
++
++/*%
++ * Increase the count of client structures sharing the TCP connection
++ * that 'source' is associated with; add a pointer to the same tcpconn
++ * to 'target', thus associating it with the same TCP connection.
++ */
++static void
++tcpconn_attach(ns_client_t *source, ns_client_t *target) {
++	int refs;
++
++	REQUIRE(source->tcpconn != NULL);
++	REQUIRE(target->tcpconn == NULL);
++	REQUIRE(source->tcpconn->pipelined);
++
++	isc_refcount_increment(&source->tcpconn->refs, &refs);
++	INSIST(refs > 1);
++	target->tcpconn = source->tcpconn;
++}
++
++/*%
++ * Decrease the count of client structures sharing the TCP connection that
++ * 'client' is associated with.  If this is the last client using this TCP
++ * connection, we detach from the TCP quota and free the tcpconn
++ * object. Either way, client->tcpconn is set to NULL.
++ */
++static void
++tcpconn_detach(ns_client_t *client) {
++	ns_tcpconn_t *tconn = NULL;
++	int refs;
++
++	REQUIRE(client->tcpconn != NULL);
++
++	tconn = client->tcpconn;
++	client->tcpconn = NULL;
++
++	isc_refcount_decrement(&tconn->refs, &refs);
++	if (refs == 0) {
++		isc_quota_detach(&tconn->tcpquota);
++		isc_mem_free(ns_g_mctx, tconn);
++	}
++}
++
++/*%
++ * Mark a client as active and increment the interface's 'ntcpactive'
++ * counter, as a signal that there is at least one client servicing
++ * TCP queries for the interface. If we reach the TCP client quota at
++ * some point, this will be used to determine whether a quota overrun
++ * should be permitted.
++ *
++ * Marking the client active with the 'tcpactive' flag ensures proper
++ * accounting, by preventing us from incrementing or decrementing
++ * 'ntcpactive' more than once per client.
++ */
++static void
++mark_tcp_active(ns_client_t *client, isc_boolean_t active) {
++	if (active && !client->tcpactive) {
++		isc_atomic_xadd(&client->interface->ntcpactive, 1);
++		client->tcpactive = active;
++	} else if (!active && client->tcpactive) {
++		uint32_t old =
++			isc_atomic_xadd(&client->interface->ntcpactive, -1);
++		INSIST(old > 0);
++		client->tcpactive = active;
++	}
++}
++
+ /*%
+  * Check for a deactivation or shutdown request and take appropriate
+  * action.  Returns ISC_TRUE if either is in progress; in this case
+@@ -369,7 +484,8 @@ exit_check(ns_client_t *client) {
+ 		INSIST(client->recursionquota == NULL);
+ 
+ 		if (NS_CLIENTSTATE_READING == client->newstate) {
+-			if (!client->pipelined) {
++			INSIST(client->tcpconn != NULL);
++			if (!client->tcpconn->pipelined) {
+ 				client_read(client);
+ 				client->newstate = NS_CLIENTSTATE_MAX;
+ 				return (ISC_TRUE); /* We're done. */
+@@ -386,10 +502,13 @@ exit_check(ns_client_t *client) {
+ 		 */
+ 		INSIST(client->recursionquota == NULL);
+ 		INSIST(client->newstate <= NS_CLIENTSTATE_READY);
+-		if (client->nreads > 0)
++
++		if (client->nreads > 0) {
+ 			dns_tcpmsg_cancelread(&client->tcpmsg);
+-		if (! client->nreads == 0) {
+-			/* Still waiting for read cancel completion. */
++		}
++
++		/* Still waiting for read cancel completion. */
++		if (client->nreads > 0) {
+ 			return (ISC_TRUE);
+ 		}
+ 
+@@ -397,14 +516,49 @@ exit_check(ns_client_t *client) {
+ 			dns_tcpmsg_invalidate(&client->tcpmsg);
+ 			client->tcpmsg_valid = ISC_FALSE;
+ 		}
++
++		/*
++		 * Soon the client will be ready to accept a new TCP
++		 * connection or UDP request, but we may have enough
++		 * clients doing that already.  Check whether this client
++		 * needs to remain active and allow it go inactive if
++		 * not.
++		 *
++		 * UDP clients always go inactive at this point, but a TCP
++		 * client may need to stay active and return to READY
++		 * state if no other clients are available to listen
++		 * for TCP requests on this interface.
++		 *
++		 * Regardless, if we're going to FREED state, that means
++		 * the system is shutting down and we don't need to
++		 * retain clients.
++		 */
++		if (client->mortal && TCP_CLIENT(client) &&
++		    client->newstate != NS_CLIENTSTATE_FREED &&
++		    !ns_g_clienttest &&
++		    isc_atomic_xadd(&client->interface->ntcpaccepting, 0) == 0)
++		{
++			/* Nobody else is accepting */
++			client->mortal = ISC_FALSE;
++			client->newstate = NS_CLIENTSTATE_READY;
++		}
++
++		/*
++		 * Detach from TCP connection and TCP client quota,
++		 * if appropriate. If this is the last reference to
++		 * the TCP connection in our pipeline group, the
++		 * TCP quota slot will be released.
++		 */
++		if (client->tcpconn) {
++			tcpconn_detach(client);
++		}
++
+ 		if (client->tcpsocket != NULL) {
+ 			CTRACE("closetcp");
+ 			isc_socket_detach(&client->tcpsocket);
++			mark_tcp_active(client, ISC_FALSE);
+ 		}
+ 
+-		if (client->tcpquota != NULL)
+-			isc_quota_detach(&client->tcpquota);
+-
+ 		if (client->timerset) {
+ 			(void)isc_timer_reset(client->timer,
+ 					      isc_timertype_inactive,
+@@ -412,45 +566,26 @@ exit_check(ns_client_t *client) {
+ 			client->timerset = ISC_FALSE;
+ 		}
+ 
+-		client->pipelined = ISC_FALSE;
+-
+ 		client->peeraddr_valid = ISC_FALSE;
+ 
+ 		client->state = NS_CLIENTSTATE_READY;
+-		INSIST(client->recursionquota == NULL);
+-
+-		/*
+-		 * Now the client is ready to accept a new TCP connection
+-		 * or UDP request, but we may have enough clients doing
+-		 * that already.  Check whether this client needs to remain
+-		 * active and force it to go inactive if not.
+-		 *
+-		 * UDP clients go inactive at this point, but TCP clients
+-		 * may remain active if we have fewer active TCP client
+-		 * objects than desired due to an earlier quota exhaustion.
+-		 */
+-		if (client->mortal && TCP_CLIENT(client) && !ns_g_clienttest) {
+-			LOCK(&client->interface->lock);
+-			if (client->interface->ntcpcurrent <
+-				    client->interface->ntcptarget)
+-				client->mortal = ISC_FALSE;
+-			UNLOCK(&client->interface->lock);
+-		}
+ 
+ 		/*
+ 		 * We don't need the client; send it to the inactive
+ 		 * queue for recycling.
+ 		 */
+ 		if (client->mortal) {
+-			if (client->newstate > NS_CLIENTSTATE_INACTIVE)
++			if (client->newstate > NS_CLIENTSTATE_INACTIVE) {
+ 				client->newstate = NS_CLIENTSTATE_INACTIVE;
++			}
+ 		}
+ 
+ 		if (NS_CLIENTSTATE_READY == client->newstate) {
+ 			if (TCP_CLIENT(client)) {
+ 				client_accept(client);
+-			} else
++			} else {
+ 				client_udprecv(client);
++			}
+ 			client->newstate = NS_CLIENTSTATE_MAX;
+ 			return (ISC_TRUE);
+ 		}
+@@ -462,41 +597,51 @@ exit_check(ns_client_t *client) {
+ 		/*
+ 		 * We are trying to enter the inactive state.
+ 		 */
+-		if (client->naccepts > 0)
++		if (client->naccepts > 0) {
+ 			isc_socket_cancel(client->tcplistener, client->task,
+ 					  ISC_SOCKCANCEL_ACCEPT);
++		}
+ 
+ 		/* Still waiting for accept cancel completion. */
+-		if (! (client->naccepts == 0))
++		if (client->naccepts > 0) {
+ 			return (ISC_TRUE);
++		}
+ 
+ 		/* Accept cancel is complete. */
+-		if (client->nrecvs > 0)
++		if (client->nrecvs > 0) {
+ 			isc_socket_cancel(client->udpsocket, client->task,
+ 					  ISC_SOCKCANCEL_RECV);
++		}
+ 
+ 		/* Still waiting for recv cancel completion. */
+-		if (! (client->nrecvs == 0))
++		if (client->nrecvs > 0) {
+ 			return (ISC_TRUE);
++		}
+ 
+ 		/* Still waiting for control event to be delivered */
+-		if (client->nctls > 0)
++		if (client->nctls > 0) {
+ 			return (ISC_TRUE);
+-
+-		/* Deactivate the client. */
+-		if (client->interface)
+-			ns_interface_detach(&client->interface);
++		}
+ 
+ 		INSIST(client->naccepts == 0);
+ 		INSIST(client->recursionquota == NULL);
+-		if (client->tcplistener != NULL)
++		if (client->tcplistener != NULL) {
+ 			isc_socket_detach(&client->tcplistener);
++			mark_tcp_active(client, ISC_FALSE);
++		}
+ 
+-		if (client->udpsocket != NULL)
++		if (client->udpsocket != NULL) {
+ 			isc_socket_detach(&client->udpsocket);
++		}
+ 
+-		if (client->dispatch != NULL)
++		/* Deactivate the client. */
++		if (client->interface != NULL) {
++			ns_interface_detach(&client->interface);
++		}
++
++		if (client->dispatch != NULL) {
+ 			dns_dispatch_detach(&client->dispatch);
++		}
+ 
+ 		client->attributes = 0;
+ 		client->mortal = ISC_FALSE;
+@@ -515,10 +660,13 @@ exit_check(ns_client_t *client) {
+ 			client->newstate = NS_CLIENTSTATE_MAX;
+ 			if (!ns_g_clienttest && manager != NULL &&
+ 			    !manager->exiting)
++			{
+ 				ISC_QUEUE_PUSH(manager->inactive, client,
+ 					       ilink);
+-			if (client->needshutdown)
++			}
++			if (client->needshutdown) {
+ 				isc_task_shutdown(client->task);
++			}
+ 			return (ISC_TRUE);
+ 		}
+ 	}
+@@ -613,7 +761,7 @@ client_start(isc_task_t *task, isc_event_t *event) {
+ 		return;
+ 
+ 	if (TCP_CLIENT(client)) {
+-		if (client->pipelined) {
++		if (client->tcpconn != NULL) {
+ 			client_read(client);
+ 		} else {
+ 			client_accept(client);
+@@ -623,7 +771,6 @@ client_start(isc_task_t *task, isc_event_t *event) {
+ 	}
+ }
+ 
+-
+ /*%
+  * The client's task has received a shutdown event.
+  */
+@@ -1511,6 +1658,7 @@ client_request(isc_task_t *task, isc_event_t *event) {
+ 		client->nrecvs--;
+ 	} else {
+ 		INSIST(TCP_CLIENT(client));
++		INSIST(client->tcpconn != NULL);
+ 		REQUIRE(event->ev_type == DNS_EVENT_TCPMSG);
+ 		REQUIRE(event->ev_sender == &client->tcpmsg);
+ 		buffer = &client->tcpmsg.buffer;
+@@ -1653,18 +1801,27 @@ client_request(isc_task_t *task, isc_event_t *event) {
+ 	/*
+ 	 * Pipeline TCP query processing.
+ 	 */
+-	if (client->message->opcode != dns_opcode_query)
+-		client->pipelined = ISC_FALSE;
+-	if (TCP_CLIENT(client) && client->pipelined) {
+-		result = isc_quota_reserve(&ns_g_server->tcpquota);
+-		if (result == ISC_R_SUCCESS)
+-			result = ns_client_replace(client);
++	if (TCP_CLIENT(client) &&
++	    client->message->opcode != dns_opcode_query)
++	{
++		client->tcpconn->pipelined = ISC_FALSE;
++	}
++	if (TCP_CLIENT(client) && client->tcpconn->pipelined) {
++		/*
++		 * We're pipelining. Replace the client; the
++		 * replacement can read the TCP socket looking
++		 * for new messages and this one can process the
++		 * current message asynchronously.
++		 *
++		 * There will now be at least three clients using this
++		 * TCP socket - one accepting new connections,
++		 * one reading an existing connection to get new
++		 * messages, and one answering the message already
++		 * received.
++		 */
++		result = ns_client_replace(client);
+ 		if (result != ISC_R_SUCCESS) {
+-			ns_client_log(client, NS_LOGCATEGORY_CLIENT,
+-				      NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,
+-				      "no more TCP clients(read): %s",
+-				      isc_result_totext(result));
+-			client->pipelined = ISC_FALSE;
++			client->tcpconn->pipelined = ISC_FALSE;
+ 		}
+ 	}
+ 
+@@ -2168,8 +2325,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
+ 	client->signer = NULL;
+ 	dns_name_init(&client->signername, NULL);
+ 	client->mortal = ISC_FALSE;
+-	client->pipelined = ISC_FALSE;
+-	client->tcpquota = NULL;
++	client->tcpconn = NULL;
+ 	client->recursionquota = NULL;
+ 	client->interface = NULL;
+ 	client->peeraddr_valid = ISC_FALSE;
+@@ -2177,6 +2333,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
+ 	client->filter_aaaa = dns_v4_aaaa_ok;
+ #endif
+ 	client->needshutdown = ns_g_clienttest;
++	client->tcpactive = ISC_FALSE;
+ 
+ 	ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL,
+ 		       NS_EVENT_CLIENTCONTROL, client_start, client, client,
+@@ -2269,9 +2426,10 @@ client_read(ns_client_t *client) {
+ 
+ static void
+ client_newconn(isc_task_t *task, isc_event_t *event) {
++	isc_result_t result;
+ 	ns_client_t *client = event->ev_arg;
+ 	isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event;
+-	isc_result_t result;
++	uint32_t old;
+ 
+ 	REQUIRE(event->ev_type == ISC_SOCKEVENT_NEWCONN);
+ 	REQUIRE(NS_CLIENT_VALID(client));
+@@ -2281,13 +2439,18 @@ client_newconn(isc_task_t *task, isc_event_t *event) {
+ 
+ 	INSIST(client->state == NS_CLIENTSTATE_READY);
+ 
++	/*
++	 * The accept() was successful and we're now establishing a new
++	 * connection. We need to make note of it in the client and
++	 * interface objects so client objects can do the right thing
++	 * when going inactive in exit_check() (see comments in
++	 * client_accept() for details).
++	 */
+ 	INSIST(client->naccepts == 1);
+ 	client->naccepts--;
+ 
+-	LOCK(&client->interface->lock);
+-	INSIST(client->interface->ntcpcurrent > 0);
+-	client->interface->ntcpcurrent--;
+-	UNLOCK(&client->interface->lock);
++	old = isc_atomic_xadd(&client->interface->ntcpaccepting, -1);
++	INSIST(old > 0);
+ 
+ 	/*
+ 	 * We must take ownership of the new socket before the exit
+@@ -2320,6 +2483,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) {
+ 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
+ 			      "accept failed: %s",
+ 			      isc_result_totext(nevent->result));
++		tcpconn_detach(client);
+ 	}
+ 
+ 	if (exit_check(client))
+@@ -2357,20 +2521,13 @@ client_newconn(isc_task_t *task, isc_event_t *event) {
+ 		 * telnetting to port 53 (once per CPU) will
+ 		 * deny service to legitimate TCP clients.
+ 		 */
+-		client->pipelined = ISC_FALSE;
+-		result = isc_quota_attach(&ns_g_server->tcpquota,
+-					  &client->tcpquota);
+-		if (result == ISC_R_SUCCESS)
+-			result = ns_client_replace(client);
+-		if (result != ISC_R_SUCCESS) {
+-			ns_client_log(client, NS_LOGCATEGORY_CLIENT,
+-				      NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,
+-				      "no more TCP clients(accept): %s",
+-				      isc_result_totext(result));
+-		} else if (ns_g_server->keepresporder == NULL ||
+-			   !allowed(&netaddr, NULL, NULL, 0, NULL,
+-				    ns_g_server->keepresporder)) {
+-			client->pipelined = ISC_TRUE;
++		result = ns_client_replace(client);
++		if (result == ISC_R_SUCCESS &&
++		    (ns_g_server->keepresporder == NULL ||
++		     !allowed(&netaddr, NULL,
++			      ns_g_server->keepresporder)))
++		{
++			client->tcpconn->pipelined = ISC_TRUE;
+ 		}
+ 
+ 		client_read(client);
+@@ -2386,12 +2543,66 @@ client_accept(ns_client_t *client) {
+ 
+ 	CTRACE("accept");
+ 
++	/*
++	 * Set up a new TCP connection. This means try to attach to the
++	 * TCP client quota (tcp-clients), but fail if we're over quota.
++	 */
++	result = tcpconn_init(client, ISC_FALSE);
++	if (result != ISC_R_SUCCESS) {
++		isc_boolean_t exit;
++
++		ns_client_log(client, NS_LOGCATEGORY_CLIENT,
++			      NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,
++			      "TCP client quota reached: %s",
++			      isc_result_totext(result));
++
++		/*
++		 * We have exceeded the system-wide TCP client quota.  But,
++		 * we can't just block this accept in all cases, because if
++		 * we did, a heavy TCP load on other interfaces might cause
++		 * this interface to be starved, with no clients able to
++		 * accept new connections.
++		 *
++		 * So, we check here to see if any other clients are
++		 * already servicing TCP queries on this interface (whether
++		 * accepting, reading, or processing). If we find that at
++		 * least one client other than this one is active, then
++		 * it's okay *not* to call accept - we can let this
++		 * client go inactive and another will take over when it's
++		 * done.
++		 *
++		 * If there aren't enough active clients on the interface,
++		 * then we can be a little bit flexible about the quota.
++		 * We'll allow *one* extra client through to ensure we're
++		 * listening on every interface; we do this by setting the
++		 * 'force' option to tcpconn_init().
++		 *
++		 * (Note: In practice this means that the real TCP client
++		 * quota is tcp-clients plus the number of listening
++		 * interfaces plus 1.)
++		 */
++		exit = (isc_atomic_xadd(&client->interface->ntcpactive, 0) >
++			(client->tcpactive ? 1 : 0));
++		if (exit) {
++			client->newstate = NS_CLIENTSTATE_INACTIVE;
++			(void)exit_check(client);
++			return;
++		}
++
++		result = tcpconn_init(client, ISC_TRUE);
++		RUNTIME_CHECK(result == ISC_R_SUCCESS);
++	}
++
++	/*
++	 * If this client was set up using get_client() or get_worker(),
++	 * then TCP is already marked active. However, if it was restarted
++	 * from exit_check(), it might not be, so we take care of it now.
++	 */
++	mark_tcp_active(client, ISC_TRUE);
++
+ 	result = isc_socket_accept(client->tcplistener, client->task,
+ 				   client_newconn, client);
+ 	if (result != ISC_R_SUCCESS) {
+-		UNEXPECTED_ERROR(__FILE__, __LINE__,
+-				 "isc_socket_accept() failed: %s",
+-				 isc_result_totext(result));
+ 		/*
+ 		 * XXXRTH  What should we do?  We're trying to accept but
+ 		 *	   it didn't work.  If we just give up, then TCP
+@@ -2399,13 +2610,37 @@ client_accept(ns_client_t *client) {
+ 		 *
+ 		 *	   For now, we just go idle.
+ 		 */
++		UNEXPECTED_ERROR(__FILE__, __LINE__,
++				 "isc_socket_accept() failed: %s",
++				 isc_result_totext(result));
++
++		tcpconn_detach(client);
++		mark_tcp_active(client, ISC_FALSE);
+ 		return;
+ 	}
++
++	/*
++	 * The client's 'naccepts' counter indicates that this client has
++	 * called accept() and is waiting for a new connection. It should
++	 * never exceed 1.
++	 */
+ 	INSIST(client->naccepts == 0);
+ 	client->naccepts++;
+-	LOCK(&client->interface->lock);
+-	client->interface->ntcpcurrent++;
+-	UNLOCK(&client->interface->lock);
++
++	/*
++	 * The interface's 'ntcpaccepting' counter is incremented when
++	 * any client calls accept(), and decremented in client_newconn()
++	 * once the connection is established.
++	 *
++	 * When the client object is shutting down after handling a TCP
++	 * request (see exit_check()), if this value is at least one, that
++	 * means another client has called accept() and is waiting to
++	 * establish the next connection. That means the client may be
++	 * be free to become inactive; otherwise it may need to start
++	 * listening for connections itself to prevent the interface
++	 * going dead.
++	 */
++	isc_atomic_xadd(&client->interface->ntcpaccepting, 1);
+ }
+ 
+ static void
+@@ -2476,15 +2711,17 @@ ns_client_replace(ns_client_t *client) {
+ 	REQUIRE(client->manager != NULL);
+ 
+ 	tcp = TCP_CLIENT(client);
+-	if (tcp && client->pipelined) {
++	if (tcp && client->tcpconn != NULL && client->tcpconn->pipelined) {
+ 		result = get_worker(client->manager, client->interface,
+-				    client->tcpsocket);
++				    client->tcpsocket, client);
+ 	} else {
+ 		result = get_client(client->manager, client->interface,
+ 				    client->dispatch, tcp);
++
+ 	}
+-	if (result != ISC_R_SUCCESS)
++	if (result != ISC_R_SUCCESS) {
+ 		return (result);
++	}
+ 
+ 	/*
+ 	 * The responsibility for listening for new requests is hereby
+@@ -2668,9 +2905,12 @@ get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,
+ 	INSIST(client->recursionquota == NULL);
+ 
+ 	if (tcp) {
++		mark_tcp_active(client, ISC_TRUE);
++
+ 		client->attributes |= NS_CLIENTATTR_TCP;
+ 		isc_socket_attach(ifp->tcpsocket,
+ 				  &client->tcplistener);
++
+ 	} else {
+ 		isc_socket_t *sock;
+ 
+@@ -2688,7 +2928,8 @@ get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,
+ }
+ 
+ static isc_result_t
+-get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *socket)
++get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock,
++	   ns_client_t *oldclient)
+ {
+ 	isc_result_t result = ISC_R_SUCCESS;
+ 	isc_event_t *ev;
+@@ -2696,6 +2937,7 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *socket)
+ 	MTRACE("get worker");
+ 
+ 	REQUIRE(manager != NULL);
++	REQUIRE(oldclient != NULL);
+ 
+ 	if (manager->exiting)
+ 		return (ISC_R_SHUTTINGDOWN);
+@@ -2728,15 +2970,15 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *socket)
+ 	ns_interface_attach(ifp, &client->interface);
+ 	client->newstate = client->state = NS_CLIENTSTATE_WORKING;
+ 	INSIST(client->recursionquota == NULL);
+-	client->tcpquota = &ns_g_server->tcpquota;
+-
+-	client->dscp = ifp->dscp;
+ 
+ 	client->attributes |= NS_CLIENTATTR_TCP;
+-	client->pipelined = ISC_TRUE;
++	client->mortal = ISC_TRUE;
++
++	tcpconn_attach(oldclient, client);
++	mark_tcp_active(client, ISC_TRUE);
+ 
+ 	isc_socket_attach(ifp->tcpsocket, &client->tcplistener);
+-	isc_socket_attach(socket, &client->tcpsocket);
++	isc_socket_attach(sock, &client->tcpsocket);
+ 	isc_socket_setname(client->tcpsocket, "worker-tcp", NULL);
+ 	(void)isc_socket_getpeername(client->tcpsocket, &client->peeraddr);
+ 	client->peeraddr_valid = ISC_TRUE;
+diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h
+index bf4d201..ef55a7a 100644
+--- a/bin/named/include/named/client.h
++++ b/bin/named/include/named/client.h
+@@ -15,8 +15,6 @@
+  * PERFORMANCE OF THIS SOFTWARE.
+  */
+ 
+-/* $Id$ */
+-
+ #ifndef NAMED_CLIENT_H
+ #define NAMED_CLIENT_H 1
+ 
+@@ -83,6 +81,13 @@
+  *** Types
+  ***/
+ 
++/*% reference-counted TCP connection object */
++typedef struct ns_tcpconn {
++	isc_refcount_t		refs;
++	isc_quota_t		*tcpquota;
++	isc_boolean_t		pipelined;
++} ns_tcpconn_t;
++
+ /*% nameserver client structure */
+ struct ns_client {
+ 	unsigned int		magic;
+@@ -133,8 +138,8 @@ struct ns_client {
+ 	dns_name_t		signername;   /*%< [T]SIG key name */
+ 	dns_name_t *		signer;	      /*%< NULL if not valid sig */
+ 	isc_boolean_t		mortal;	      /*%< Die after handling request */
+-	isc_boolean_t		pipelined;   /*%< TCP queries not in sequence */
+-	isc_quota_t		*tcpquota;
++	isc_boolean_t		tcpactive;
++	ns_tcpconn_t		*tcpconn;
+ 	isc_quota_t		*recursionquota;
+ 	ns_interface_t		*interface;
+ 	isc_sockaddr_t		peeraddr;
+diff --git a/bin/named/include/named/interfacemgr.h b/bin/named/include/named/interfacemgr.h
+index 380dbed..a342866 100644
+--- a/bin/named/include/named/interfacemgr.h
++++ b/bin/named/include/named/interfacemgr.h
+@@ -15,8 +15,6 @@
+  * PERFORMANCE OF THIS SOFTWARE.
+  */
+ 
+-/* $Id: interfacemgr.h,v 1.35 2011/07/28 23:47:58 tbox Exp $ */
+-
+ #ifndef NAMED_INTERFACEMGR_H
+ #define NAMED_INTERFACEMGR_H 1
+ 
+@@ -80,9 +78,14 @@ struct ns_interface {
+ 	dns_dispatch_t *	udpdispatch[MAX_UDP_DISPATCH];
+ 						/*%< UDP dispatchers. */
+ 	isc_socket_t *		tcpsocket;	/*%< TCP socket. */
+-	int			ntcptarget;	/*%< Desired number of concurrent
+-						     TCP accepts */
+-	int			ntcpcurrent;	/*%< Current ditto, locked */
++	int32_t			ntcpaccepting;	/*%< Number of clients
++						     ready to accept new
++						     TCP connections on this
++						     interface */
++	int32_t			ntcpactive;	/*%< Number of clients
++						     servicing TCP queries
++						     (whether accepting or
++						     connected) */
+ 	int			nudpdispatch;	/*%< Number of UDP dispatches */
+ 	ns_clientmgr_t *	clientmgr;	/*%< Client manager. */
+ 	ISC_LINK(ns_interface_t) link;
+diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c
+index 4aee47a..ebec0c4 100644
+--- a/bin/named/interfacemgr.c
++++ b/bin/named/interfacemgr.c
+@@ -380,8 +380,9 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
+ 	 * connections will be handled in parallel even though there is
+ 	 * only one client initially.
+ 	 */
+-	ifp->ntcptarget = 1;
+-	ifp->ntcpcurrent = 0;
++	ifp->ntcpaccepting = 0;
++	ifp->ntcpactive = 0;
++
+ 	ifp->nudpdispatch = 0;
+ 
+ 	ISC_LINK_INIT(ifp, link);
+@@ -510,9 +511,7 @@ ns_interface_accepttcp(ns_interface_t *ifp) {
+ 	 */
+ 	(void)isc_socket_filter(ifp->tcpsocket, "dataready");
+ 
+-	result = ns_clientmgr_createclients(ifp->clientmgr,
+-					    ifp->ntcptarget, ifp,
+-					    ISC_TRUE);
++	result = ns_clientmgr_createclients(ifp->clientmgr, 1, ifp, ISC_TRUE);
+ 	if (result != ISC_R_SUCCESS) {
+ 		UNEXPECTED_ERROR(__FILE__, __LINE__,
+ 				 "TCP ns_clientmgr_createclients(): %s",
+diff --git a/lib/isc/include/isc/quota.h b/lib/isc/include/isc/quota.h
+index 7b0d0d9..bb1a927 100644
+--- a/lib/isc/include/isc/quota.h
++++ b/lib/isc/include/isc/quota.h
+@@ -107,6 +107,13 @@ isc_quota_attach(isc_quota_t *quota, isc_quota_t **p);
+  * quota if successful (ISC_R_SUCCESS or ISC_R_SOFTQUOTA).
+  */
+ 
++isc_result_t
++isc_quota_force(isc_quota_t *quota, isc_quota_t **p);
++/*%<
++ * Like isc_quota_attach, but will attach '*p' to the quota
++ * even if the hard quota has been exceeded.
++ */
++
+ void
+ isc_quota_detach(isc_quota_t **p);
+ /*%<
+diff --git a/lib/isc/quota.c b/lib/isc/quota.c
+index 5e5c50c..ca4c478 100644
+--- a/lib/isc/quota.c
++++ b/lib/isc/quota.c
+@@ -81,20 +81,39 @@ isc_quota_release(isc_quota_t *quota) {
+ 	UNLOCK(&quota->lock);
+ }
+ 
+-isc_result_t
+-isc_quota_attach(isc_quota_t *quota, isc_quota_t **p)
+-{
++static isc_result_t
++doattach(isc_quota_t *quota, isc_quota_t **p, isc_boolean_t force) {
+ 	isc_result_t result;
+-	INSIST(p != NULL && *p == NULL);
++	REQUIRE(p != NULL && *p == NULL);
++
+ 	result = isc_quota_reserve(quota);
+-	if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA)
++	if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA) {
++		*p = quota;
++	} else if (result == ISC_R_QUOTA && force) {
++		/* attach anyway */
++		LOCK(&quota->lock);
++		quota->used++;
++		UNLOCK(&quota->lock);
++
+ 		*p = quota;
++		result = ISC_R_SUCCESS;
++	}
++
+ 	return (result);
+ }
+ 
++isc_result_t
++isc_quota_attach(isc_quota_t *quota, isc_quota_t **p) {
++	return (doattach(quota, p, ISC_FALSE));
++}
++
++isc_result_t
++isc_quota_force(isc_quota_t *quota, isc_quota_t **p) {
++	return (doattach(quota, p, ISC_TRUE));
++}
++
+ void
+-isc_quota_detach(isc_quota_t **p)
+-{
++isc_quota_detach(isc_quota_t **p) {
+ 	INSIST(p != NULL && *p != NULL);
+ 	isc_quota_release(*p);
+ 	*p = NULL;
+-- 
+2.20.1
+
diff --git a/SOURCES/bind-9.11-rt37039.patch b/SOURCES/bind-9.11-rt37039.patch
new file mode 100644
index 0000000..aa11ed6
--- /dev/null
+++ b/SOURCES/bind-9.11-rt37039.patch
@@ -0,0 +1,380 @@
+From f34cc4f62cd6730fc315ace47b9ae90a82a07ec0 Mon Sep 17 00:00:00 2001
+From: Mark Andrews <marka@isc.org>
+Date: Thu, 4 Sep 2014 10:37:45 +1000
+Subject: [PATCH] 3939. [func] Improve UPDATE forwarding performance by
+ allowing TCP connections to be shared. [RT #37039]
+
+(cherry picked from commit 74717eef53ba5d6aefc80eb262bbb090ff4bb3b5)
+---
+ lib/dns/dispatch.c             | 112 ++++++++++++++++++++++++++++++++-
+ lib/dns/include/dns/dispatch.h |  15 +++++
+ lib/dns/request.c              |  46 ++++++++++----
+ lib/dns/win32/libdns.def       |   2 +
+ 4 files changed, 159 insertions(+), 16 deletions(-)
+
+diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c
+index c93651d..ee82241 100644
+--- a/lib/dns/dispatch.c
++++ b/lib/dns/dispatch.c
+@@ -228,6 +228,7 @@ struct dns_dispatch {
+ 	isc_socket_t	       *socket;		/*%< isc socket attached to */
+ 	isc_sockaddr_t		local;		/*%< local address */
+ 	in_port_t		localport;	/*%< local UDP port */
++	isc_sockaddr_t		peer;		/*%< peer address (TCP) */
+ 	unsigned int		maxrequests;	/*%< max requests */
+ 	isc_event_t	       *ctlevent;
+ 
+@@ -2327,7 +2328,6 @@ dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp) {
+ 
+ 	LOCK(&mgr->lock);
+ 	mgr->state |= MGR_SHUTTINGDOWN;
+-
+ 	killit = destroy_mgr_ok(mgr);
+ 	UNLOCK(&mgr->lock);
+ 
+@@ -2601,6 +2601,7 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests,
+ 	disp->refcount = 1;
+ 	disp->recv_pending = 0;
+ 	memset(&disp->local, 0, sizeof(disp->local));
++	memset(&disp->peer, 0, sizeof(disp->peer));
+ 	disp->localport = 0;
+ 	disp->shutting_down = 0;
+ 	disp->shutdown_out = 0;
+@@ -2702,6 +2703,23 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
+ 		       unsigned int buckets, unsigned int increment,
+ 		       unsigned int attributes, dns_dispatch_t **dispp)
+ {
++
++	attributes |= DNS_DISPATCHATTR_PRIVATE;  /* XXXMLG */
++
++	return (dns_dispatch_createtcp2(mgr, sock, taskmgr, NULL, NULL,
++					buffersize, maxbuffers, maxrequests,
++					buckets, increment, attributes,
++					dispp));
++}
++
++isc_result_t
++dns_dispatch_createtcp2(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
++		        isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
++			isc_sockaddr_t *destaddr, unsigned int buffersize,
++		        unsigned int maxbuffers, unsigned int maxrequests,
++		        unsigned int buckets, unsigned int increment,
++		        unsigned int attributes, dns_dispatch_t **dispp)
++{
+ 	isc_result_t result;
+ 	dns_dispatch_t *disp;
+ 
+@@ -2713,7 +2731,8 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
+ 	REQUIRE((attributes & DNS_DISPATCHATTR_TCP) != 0);
+ 	REQUIRE((attributes & DNS_DISPATCHATTR_UDP) == 0);
+ 
+-	attributes |= DNS_DISPATCHATTR_PRIVATE;  /* XXXMLG */
++	if (destaddr == NULL)
++		attributes |= DNS_DISPATCHATTR_PRIVATE;  /* XXXMLG */
+ 
+ 	LOCK(&mgr->lock);
+ 
+@@ -2760,6 +2779,23 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
+ 
+ 	disp->attributes = attributes;
+ 
++	if (localaddr == NULL) {
++		if (destaddr != NULL) {
++			switch (isc_sockaddr_pf(destaddr)) {
++			case AF_INET:
++				isc_sockaddr_any(&disp->local);
++				break;
++			case AF_INET6:
++				isc_sockaddr_any6(&disp->local);
++				break;
++			}
++		}
++	} else
++		disp->local = *localaddr;
++
++	if (destaddr != NULL)
++		disp->peer = *destaddr;
++
+ 	/*
+ 	 * Append it to the dispatcher list.
+ 	 */
+@@ -2768,7 +2804,6 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
+ 
+ 	mgr_log(mgr, LVL(90), "created TCP dispatcher %p", disp);
+ 	dispatch_log(disp, LVL(90), "created task %p", disp->task[0]);
+-
+ 	*dispp = disp;
+ 
+ 	return (ISC_R_SUCCESS);
+@@ -2788,6 +2823,77 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
+ 	return (result);
+ }
+ 
++isc_result_t
++dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr,
++		    isc_sockaddr_t *localaddr, dns_dispatch_t **dispp)
++{
++#ifdef BIND9
++	dns_dispatch_t *disp;
++	isc_result_t result;
++	isc_sockaddr_t peeraddr;
++	isc_sockaddr_t sockname;
++	isc_sockaddr_t any;
++	unsigned int attributes, mask;
++	isc_boolean_t match = ISC_FALSE;
++
++	REQUIRE(VALID_DISPATCHMGR(mgr));
++	REQUIRE(destaddr != NULL);
++	REQUIRE(dispp != NULL && *dispp == NULL);
++
++	attributes = DNS_DISPATCHATTR_TCP;
++	mask = DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_PRIVATE |
++	       DNS_DISPATCHATTR_EXCLUSIVE;
++
++	if (localaddr == NULL) {
++		switch (isc_sockaddr_pf(destaddr)) {
++		case AF_INET:
++			isc_sockaddr_any(&any);
++			break;
++		case AF_INET6:
++			isc_sockaddr_any6(&any);
++			break;
++		default:
++			return (ISC_R_NOTFOUND);
++		}
++		localaddr = &any;
++	}
++
++	LOCK(&mgr->lock);
++	disp = ISC_LIST_HEAD(mgr->list);
++	while (disp != NULL && !match) {
++		LOCK(&disp->lock);
++		if ((disp->shutting_down == 0) &&
++		    ATTRMATCH(disp->attributes, attributes, mask) &&
++		    (localaddr == NULL ||
++		     isc_sockaddr_eqaddr(localaddr, &disp->local))) {
++			result = isc_socket_getsockname(disp->socket,
++							&sockname);
++			if (result == ISC_R_SUCCESS)
++				result = isc_socket_getpeername(disp->socket,
++								&peeraddr);
++			if (result == ISC_R_SUCCESS &&
++			    isc_sockaddr_equal(destaddr, &peeraddr) &&
++			    isc_sockaddr_eqaddr(localaddr, &sockname)) {
++				/* attach */
++				disp->refcount++;
++				*dispp = disp;
++				match = ISC_TRUE;
++			}
++		}
++		UNLOCK(&disp->lock);
++		disp = ISC_LIST_NEXT(disp, link);
++	}
++	UNLOCK(&mgr->lock);
++	return (match ? ISC_R_SUCCESS : ISC_R_NOTFOUND);
++#else
++	UNUSED(mgr);
++	UNUSED(destaddr);
++	UNUSED(localaddr);
++	UNUSED(dispp);
++	return ISC_R_NOTIMPLEMENTED;
++#endif
++}
++
+ isc_result_t
+ dns_dispatch_getudp_dup(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
+ 		    isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
+diff --git a/lib/dns/include/dns/dispatch.h b/lib/dns/include/dns/dispatch.h
+index 1235f7c..be9cd66 100644
+--- a/lib/dns/include/dns/dispatch.h
++++ b/lib/dns/include/dns/dispatch.h
+@@ -298,6 +298,13 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
+ 		       unsigned int maxbuffers, unsigned int maxrequests,
+ 		       unsigned int buckets, unsigned int increment,
+ 		       unsigned int attributes, dns_dispatch_t **dispp);
++isc_result_t
++dns_dispatch_createtcp2(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
++                        isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
++                        isc_sockaddr_t *destaddr, unsigned int buffersize,
++                        unsigned int maxbuffers, unsigned int maxrequests,
++                        unsigned int buckets, unsigned int increment,
++                        unsigned int attributes, dns_dispatch_t **dispp);
+ /*%<
+  * Create a new dns_dispatch and attach it to the provided isc_socket_t.
+  *
+@@ -369,6 +376,14 @@ dns_dispatch_starttcp(dns_dispatch_t *disp);
+  *\li	'disp' is valid.
+  */
+ 
++isc_result_t
++dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr,
++                    isc_sockaddr_t *localaddr, dns_dispatch_t **dispp);
++/*
++ * Attempt to connect to a existing TCP connection.
++ */
++
++
+ isc_result_t
+ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
+ 			  isc_task_t *task, isc_taskaction_t action, void *arg,
+diff --git a/lib/dns/request.c b/lib/dns/request.c
+index 5c76f9a..9fb6f44 100644
+--- a/lib/dns/request.c
++++ b/lib/dns/request.c
+@@ -510,7 +510,8 @@ isblackholed(dns_dispatchmgr_t *dispatchmgr, isc_sockaddr_t *destaddr) {
+ 
+ static isc_result_t
+ create_tcp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr,
+-		    isc_sockaddr_t *destaddr, dns_dispatch_t **dispatchp)
++		    isc_sockaddr_t *destaddr, isc_boolean_t *connected,
++		    dns_dispatch_t **dispatchp)
+ {
+ 	isc_result_t result;
+ 	isc_socket_t *socket = NULL;
+@@ -518,6 +519,20 @@ create_tcp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr,
+ 	unsigned int attrs;
+ 	isc_sockaddr_t bind_any;
+ 
++	*connected = ISC_FALSE;
++#ifdef BIND9
++	result = dns_dispatch_gettcp(requestmgr->dispatchmgr, destaddr,
++				     srcaddr, dispatchp);
++	if (result == ISC_R_SUCCESS) {
++		*connected = ISC_TRUE;
++		char peer[ISC_SOCKADDR_FORMATSIZE];
++		isc_sockaddr_format(destaddr, peer, sizeof(peer));
++		req_log(ISC_LOG_DEBUG(1), "attached to existing TCP "
++			"connection to %s", peer);
++		return (result);
++	}
++#endif
++
+ 	result = isc_socket_create(requestmgr->socketmgr,
+ 				   isc_sockaddr_pf(destaddr),
+ 				   isc_sockettype_tcp, &socket);
+@@ -538,16 +553,16 @@ create_tcp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr,
+ #endif
+ 	attrs = 0;
+ 	attrs |= DNS_DISPATCHATTR_TCP;
+-	attrs |= DNS_DISPATCHATTR_PRIVATE;
+ 	if (isc_sockaddr_pf(destaddr) == AF_INET)
+ 		attrs |= DNS_DISPATCHATTR_IPV4;
+ 	else
+ 		attrs |= DNS_DISPATCHATTR_IPV6;
+ 	attrs |= DNS_DISPATCHATTR_MAKEQUERY;
+-	result = dns_dispatch_createtcp(requestmgr->dispatchmgr,
+-					socket, requestmgr->taskmgr,
+-					4096, 2, 1, 1, 3, attrs,
+-					dispatchp);
++	result = dns_dispatch_createtcp2(requestmgr->dispatchmgr,
++					 socket, requestmgr->taskmgr,
++					 srcaddr, destaddr,
++					 4096, 32768, 32768, 16411, 16433,
++					 attrs, dispatchp);
+ cleanup:
+ 	isc_socket_detach(&socket);
+ 	return (result);
+@@ -609,12 +624,15 @@ find_udp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr,
+ static isc_result_t
+ get_dispatch(isc_boolean_t tcp, dns_requestmgr_t *requestmgr,
+ 	     isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
++	     isc_boolean_t *connected,
+ 	     dns_dispatch_t **dispatchp)
+ {
+ 	isc_result_t result;
++
+ 	if (tcp)
+ 		result = create_tcp_dispatch(requestmgr, srcaddr,
+-					     destaddr, dispatchp);
++					     destaddr, connected,
++					     dispatchp);
+ 	else
+ 		result = find_udp_dispatch(requestmgr, srcaddr,
+ 					   destaddr, dispatchp);
+@@ -686,6 +704,7 @@ dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
+ 	dns_messageid_t	id;
+ 	isc_boolean_t tcp = ISC_FALSE;
+ 	isc_region_t r;
++	isc_boolean_t connected = ISC_FALSE;
+ 
+ 	REQUIRE(VALID_REQUESTMGR(requestmgr));
+ 	REQUIRE(msgbuf != NULL);
+@@ -747,7 +766,7 @@ dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
+ 		tcp = ISC_TRUE;
+ 
+ 	result = get_dispatch(tcp, requestmgr, srcaddr, destaddr,
+-			      &request->dispatch);
++			      &connected, &request->dispatch);
+ 	if (result != ISC_R_SUCCESS)
+ 		goto cleanup;
+ 
+@@ -794,14 +813,14 @@ dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
+ 		goto unlink;
+ 
+ 	request->destaddr = *destaddr;
+-	if (tcp) {
++	if (tcp && !connected) {
+ 		result = isc_socket_connect(socket, destaddr, task,
+ 					    req_connected, request);
+ 		if (result != ISC_R_SUCCESS)
+ 			goto unlink;
+ 		request->flags |= DNS_REQUEST_F_CONNECTING|DNS_REQUEST_F_TCP;
+ 	} else {
+-		result = req_send(request, task, destaddr);
++		result = req_send(request, task, connected ? NULL : destaddr);
+ 		if (result != ISC_R_SUCCESS)
+ 			goto unlink;
+ 	}
+@@ -886,6 +905,7 @@ dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
+ 	dns_messageid_t	id;
+ 	isc_boolean_t tcp;
+ 	isc_boolean_t setkey = ISC_TRUE;
++	isc_boolean_t connected = ISC_FALSE;
+ 
+ 	REQUIRE(VALID_REQUESTMGR(requestmgr));
+ 	REQUIRE(message != NULL);
+@@ -944,7 +964,7 @@ dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
+  use_tcp:
+ 	tcp = ISC_TF((options & DNS_REQUESTOPT_TCP) != 0);
+ 	result = get_dispatch(tcp, requestmgr, srcaddr, destaddr,
+-			      &request->dispatch);
++			      &connected, &request->dispatch);
+ 	if (result != ISC_R_SUCCESS)
+ 		goto cleanup;
+ 
+@@ -1000,14 +1020,14 @@ dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
+ 		goto unlink;
+ 
+ 	request->destaddr = *destaddr;
+-	if (tcp) {
++	if (tcp && !connected) {
+ 		result = isc_socket_connect(socket, destaddr, task,
+ 					    req_connected, request);
+ 		if (result != ISC_R_SUCCESS)
+ 			goto unlink;
+ 		request->flags |= DNS_REQUEST_F_CONNECTING|DNS_REQUEST_F_TCP;
+ 	} else {
+-		result = req_send(request, task, destaddr);
++		result = req_send(request, task, connected ? NULL : destaddr);
+ 		if (result != ISC_R_SUCCESS)
+ 			goto unlink;
+ 	}
+diff --git a/lib/dns/win32/libdns.def b/lib/dns/win32/libdns.def
+index 5e20491..9aebe16 100644
+--- a/lib/dns/win32/libdns.def
++++ b/lib/dns/win32/libdns.def
+@@ -176,9 +176,11 @@ dns_dispatch_attach
+ dns_dispatch_cancel
+ dns_dispatch_changeattributes
+ dns_dispatch_createtcp
++dns_dispatch_createtcp2
+ dns_dispatch_detach
+ dns_dispatch_getlocaladdress
+ dns_dispatch_getsocket
++dns_dispatch_gettcp
+ dns_dispatch_getudp
+ dns_dispatch_getudp_dup
+ dns_dispatch_importrecv
+-- 
+2.20.1
+
diff --git a/SOURCES/bind-9.11-rt37821.patch b/SOURCES/bind-9.11-rt37821.patch
new file mode 100644
index 0000000..9ae27c1
--- /dev/null
+++ b/SOURCES/bind-9.11-rt37821.patch
@@ -0,0 +1,1532 @@
+From 4d55e959839e1bc8e43124648742056ac2c802e7 Mon Sep 17 00:00:00 2001
+From: Evan Hunt <each@isc.org>
+Date: Tue, 20 Jan 2015 16:10:30 -0800
+Subject: [PATCH] add TCP pipelining support
+
+4040.	[func]		Added server-side support for pipelined TCP
+			queries. TCP connections are no longer closed after
+			the first query received from a client. (The new
+			"keep-response-order" option allows clients to be
+			specified for which the old behavior will still be
+			used.) [RT #37821]
+
+(cherry picked from commit 761d135ed686601f36fe3d0d4aaa6bf41287bb0f)
+
+Modified default value of keep-response-order ACL to any, for best backward
+compatibility. Upstream default is none;
+---
+ bin/named/client.c                            | 123 ++++++-
+ bin/named/config.c                            |   3 +-
+ bin/named/include/named/client.h              |   1 +
+ bin/named/include/named/server.h              |   1 +
+ bin/named/named.conf.docbook                  |   1 +
+ bin/named/server.c                            |   8 +
+ bin/tests/named.conf                          |   3 +-
+ bin/tests/system/Makefile.in                  |   4 +-
+ .../checkconf/bad-keep-response-order.conf    |  21 ++
+ bin/tests/system/checkconf/bad-many.conf      |   3 +-
+ bin/tests/system/checkconf/good.conf          |   3 +
+ bin/tests/system/conf.sh.in                   |   2 +-
+ bin/tests/system/pipelined/Makefile.in        |  51 +++
+ bin/tests/system/pipelined/clean.sh           |  19 +
+ bin/tests/system/pipelined/input              |   8 +
+ bin/tests/system/pipelined/inputb             |   8 +
+ bin/tests/system/pipelined/ns1/named.conf     |  43 +++
+ bin/tests/system/pipelined/ns1/root.db        |  30 ++
+ bin/tests/system/pipelined/ns2/examplea.db    |  35 ++
+ bin/tests/system/pipelined/ns2/named.conf     |  49 +++
+ bin/tests/system/pipelined/ns3/exampleb.db    |  35 ++
+ bin/tests/system/pipelined/ns3/named.args     |   1 +
+ bin/tests/system/pipelined/ns3/named.conf     |  49 +++
+ bin/tests/system/pipelined/ns4/named.conf     |  45 +++
+ bin/tests/system/pipelined/pipequeries.c      | 346 ++++++++++++++++++
+ bin/tests/system/pipelined/ref                |   8 +
+ bin/tests/system/pipelined/refb               |   8 +
+ bin/tests/system/pipelined/setup.sh           |  22 ++
+ bin/tests/system/pipelined/tests.sh           |  41 +++
+ configure                                     |   1 +
+ configure.in                                  |   1 +
+ doc/arm/Bv9ARM-book.xml                       |  19 +-
+ doc/misc/options                              |   1 +
+ lib/bind9/check.c                             |   4 +-
+ lib/dns/dispatch.c                            |  22 +-
+ lib/isccfg/namedconf.c                        |   1 +
+ 36 files changed, 985 insertions(+), 35 deletions(-)
+ create mode 100644 bin/tests/system/checkconf/bad-keep-response-order.conf
+ create mode 100644 bin/tests/system/pipelined/Makefile.in
+ create mode 100644 bin/tests/system/pipelined/clean.sh
+ create mode 100644 bin/tests/system/pipelined/input
+ create mode 100644 bin/tests/system/pipelined/inputb
+ create mode 100644 bin/tests/system/pipelined/ns1/named.conf
+ create mode 100644 bin/tests/system/pipelined/ns1/root.db
+ create mode 100644 bin/tests/system/pipelined/ns2/examplea.db
+ create mode 100644 bin/tests/system/pipelined/ns2/named.conf
+ create mode 100644 bin/tests/system/pipelined/ns3/exampleb.db
+ create mode 100644 bin/tests/system/pipelined/ns3/named.args
+ create mode 100644 bin/tests/system/pipelined/ns3/named.conf
+ create mode 100644 bin/tests/system/pipelined/ns4/named.conf
+ create mode 100644 bin/tests/system/pipelined/pipequeries.c
+ create mode 100644 bin/tests/system/pipelined/ref
+ create mode 100644 bin/tests/system/pipelined/refb
+ create mode 100644 bin/tests/system/pipelined/setup.sh
+ create mode 100644 bin/tests/system/pipelined/tests.sh
+
+diff --git a/bin/named/client.c b/bin/named/client.c
+index 9adf36b..f014b61 100644
+--- a/bin/named/client.c
++++ b/bin/named/client.c
+@@ -233,6 +233,8 @@ static void client_request(isc_task_t *task, isc_event_t *event);
+ static void ns_client_dumpmessage(ns_client_t *client, const char *reason);
+ static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,
+ 			       dns_dispatch_t *disp, isc_boolean_t tcp);
++static isc_result_t get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp,
++			       isc_socket_t *socket);
+ 
+ void
+ ns_client_recursing(ns_client_t *client) {
+@@ -367,9 +369,13 @@ exit_check(ns_client_t *client) {
+ 		INSIST(client->recursionquota == NULL);
+ 
+ 		if (NS_CLIENTSTATE_READING == client->newstate) {
+-			client_read(client);
+-			client->newstate = NS_CLIENTSTATE_MAX;
+-			return (ISC_TRUE); /* We're done. */
++			if (!client->pipelined) {
++				client_read(client);
++				client->newstate = NS_CLIENTSTATE_MAX;
++				return (ISC_TRUE); /* We're done. */
++			} else if (client->mortal) {
++				client->newstate = NS_CLIENTSTATE_INACTIVE;
++			}
+ 		}
+ 	}
+ 
+@@ -406,6 +412,8 @@ exit_check(ns_client_t *client) {
+ 			client->timerset = ISC_FALSE;
+ 		}
+ 
++		client->pipelined = ISC_FALSE;
++
+ 		client->peeraddr_valid = ISC_FALSE;
+ 
+ 		client->state = NS_CLIENTSTATE_READY;
+@@ -605,7 +613,11 @@ client_start(isc_task_t *task, isc_event_t *event) {
+ 		return;
+ 
+ 	if (TCP_CLIENT(client)) {
+-		client_accept(client);
++		if (client->pipelined) {
++			client_read(client);
++		} else {
++			client_accept(client);
++		}
+ 	} else {
+ 		client_udprecv(client);
+ 	}
+@@ -1638,6 +1650,24 @@ client_request(isc_task_t *task, isc_event_t *event) {
+ 		goto cleanup;
+ 	}
+ 
++	/*
++	 * Pipeline TCP query processing.
++	 */
++	if (client->message->opcode != dns_opcode_query)
++		client->pipelined = ISC_FALSE;
++	if (TCP_CLIENT(client) && client->pipelined) {
++		result = isc_quota_reserve(&ns_g_server->tcpquota);
++		if (result == ISC_R_SUCCESS)
++			result = ns_client_replace(client);
++		if (result != ISC_R_SUCCESS) {
++			ns_client_log(client, NS_LOGCATEGORY_CLIENT,
++				      NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,
++				      "no more TCP clients(read): %s",
++				      isc_result_totext(result));
++			client->pipelined = ISC_FALSE;
++		}
++	}
++
+ 	dns_opcodestats_increment(ns_g_server->opcodestats,
+ 				  client->message->opcode);
+ 	switch (client->message->opcode) {
+@@ -2138,6 +2168,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
+ 	client->signer = NULL;
+ 	dns_name_init(&client->signername, NULL);
+ 	client->mortal = ISC_FALSE;
++	client->pipelined = ISC_FALSE;
+ 	client->tcpquota = NULL;
+ 	client->recursionquota = NULL;
+ 	client->interface = NULL;
+@@ -2326,6 +2357,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) {
+ 		 * telnetting to port 53 (once per CPU) will
+ 		 * deny service to legitimate TCP clients.
+ 		 */
++		client->pipelined = ISC_FALSE;
+ 		result = isc_quota_attach(&ns_g_server->tcpquota,
+ 					  &client->tcpquota);
+ 		if (result == ISC_R_SUCCESS)
+@@ -2333,8 +2365,12 @@ client_newconn(isc_task_t *task, isc_event_t *event) {
+ 		if (result != ISC_R_SUCCESS) {
+ 			ns_client_log(client, NS_LOGCATEGORY_CLIENT,
+ 				      NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,
+-				      "no more TCP clients: %s",
++				      "no more TCP clients(accept): %s",
+ 				      isc_result_totext(result));
++		} else if (ns_g_server->keepresporder == NULL ||
++			   !allowed(&netaddr, NULL, NULL, 0, NULL,
++				    ns_g_server->keepresporder)) {
++			client->pipelined = ISC_TRUE;
+ 		}
+ 
+ 		client_read(client);
+@@ -2432,14 +2468,21 @@ ns_client_shuttingdown(ns_client_t *client) {
+ isc_result_t
+ ns_client_replace(ns_client_t *client) {
+ 	isc_result_t result;
++	isc_boolean_t tcp;
+ 
+ 	CTRACE("replace");
+ 
+ 	REQUIRE(client != NULL);
+ 	REQUIRE(client->manager != NULL);
+ 
+-	result = get_client(client->manager, client->interface,
+-			    client->dispatch, TCP_CLIENT(client));
++	tcp = TCP_CLIENT(client);
++	if (tcp && client->pipelined) {
++		result = get_worker(client->manager, client->interface,
++				    client->tcpsocket);
++	} else {
++		result = get_client(client->manager, client->interface,
++				    client->dispatch, tcp);
++	}
+ 	if (result != ISC_R_SUCCESS)
+ 		return (result);
+ 
+@@ -2644,6 +2687,72 @@ get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,
+ 	return (ISC_R_SUCCESS);
+ }
+ 
++static isc_result_t
++get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *socket)
++{
++	isc_result_t result = ISC_R_SUCCESS;
++	isc_event_t *ev;
++	ns_client_t *client;
++	MTRACE("get worker");
++
++	REQUIRE(manager != NULL);
++
++	if (manager->exiting)
++		return (ISC_R_SHUTTINGDOWN);
++
++	/*
++	 * Allocate a client.  First try to get a recycled one;
++	 * if that fails, make a new one.
++	 */
++	client = NULL;
++	if (!ns_g_clienttest)
++		ISC_QUEUE_POP(manager->inactive, ilink, client);
++
++	if (client != NULL)
++		MTRACE("recycle");
++	else {
++		MTRACE("create new");
++
++		LOCK(&manager->lock);
++		result = client_create(manager, &client);
++		UNLOCK(&manager->lock);
++		if (result != ISC_R_SUCCESS)
++			return (result);
++
++		LOCK(&manager->listlock);
++		ISC_LIST_APPEND(manager->clients, client, link);
++		UNLOCK(&manager->listlock);
++	}
++
++	client->manager = manager;
++	ns_interface_attach(ifp, &client->interface);
++	client->newstate = client->state = NS_CLIENTSTATE_WORKING;
++	INSIST(client->recursionquota == NULL);
++	client->tcpquota = &ns_g_server->tcpquota;
++
++	client->dscp = ifp->dscp;
++
++	client->attributes |= NS_CLIENTATTR_TCP;
++	client->pipelined = ISC_TRUE;
++
++	isc_socket_attach(ifp->tcpsocket, &client->tcplistener);
++	isc_socket_attach(socket, &client->tcpsocket);
++	isc_socket_setname(client->tcpsocket, "worker-tcp", NULL);
++	(void)isc_socket_getpeername(client->tcpsocket, &client->peeraddr);
++	client->peeraddr_valid = ISC_TRUE;
++
++	INSIST(client->tcpmsg_valid == ISC_FALSE);
++	dns_tcpmsg_init(client->mctx, client->tcpsocket, &client->tcpmsg);
++	client->tcpmsg_valid = ISC_TRUE;
++
++	INSIST(client->nctls == 0);
++	client->nctls++;
++	ev = &client->ctlevent;
++	isc_task_send(client->task, &ev);
++
++	return (ISC_R_SUCCESS);
++}
++
+ isc_result_t
+ ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
+ 			   ns_interface_t *ifp, isc_boolean_t tcp)
+diff --git a/bin/named/config.c b/bin/named/config.c
+index 22d8a85..f0db926 100644
+--- a/bin/named/config.c
++++ b/bin/named/config.c
+@@ -72,6 +72,7 @@ options {\n\
+ 	heartbeat-interval 60;\n\
+ 	host-statistics no;\n\
+ 	interface-interval 60;\n\
++#	keep-response-order {any;};\n\
+ 	listen-on {any;};\n\
+ 	listen-on-v6 {none;};\n\
+ 	match-mapped-addresses no;\n\
+@@ -101,7 +102,7 @@ options {\n\
+ 	server-id none;\n\
+ 	statistics-file \"named.stats\";\n\
+ 	statistics-interval 60;\n\
+-	tcp-clients 100;\n\
++	tcp-clients 150;\n\
+ 	tcp-listen-queue 10;\n\
+ #	tkey-dhkey <none>\n\
+ #	tkey-gssapi-credential <none>\n\
+diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h
+index 98e79df..bf4d201 100644
+--- a/bin/named/include/named/client.h
++++ b/bin/named/include/named/client.h
+@@ -133,6 +133,7 @@ struct ns_client {
+ 	dns_name_t		signername;   /*%< [T]SIG key name */
+ 	dns_name_t *		signer;	      /*%< NULL if not valid sig */
+ 	isc_boolean_t		mortal;	      /*%< Die after handling request */
++	isc_boolean_t		pipelined;   /*%< TCP queries not in sequence */
+ 	isc_quota_t		*tcpquota;
+ 	isc_quota_t		*recursionquota;
+ 	ns_interface_t		*interface;
+diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h
+index 0107b51..5f36177 100644
+--- a/bin/named/include/named/server.h
++++ b/bin/named/include/named/server.h
+@@ -53,6 +53,7 @@ struct ns_server {
+ 	isc_quota_t		tcpquota;
+ 	isc_quota_t		recursionquota;
+ 	dns_acl_t		*blackholeacl;
++	dns_acl_t		*keepresporder;
+ 	char *			statsfile;	/*%< Statistics file name */
+ 	char *			dumpfile;	/*%< Dump file name */
+ 	char *			secrootsfile;	/*%< Secroots file name */
+diff --git a/bin/named/named.conf.docbook b/bin/named/named.conf.docbook
+index a8cd31e..4d502ac 100644
+--- a/bin/named/named.conf.docbook
++++ b/bin/named/named.conf.docbook
+@@ -209,6 +209,7 @@ options {
+ 	host-statistics-max <replaceable>number</replaceable>; // not implemented
+ 	hostname ( <replaceable>quoted_string</replaceable> | none );
+ 	interface-interval <replaceable>integer</replaceable>;
++	keep-response-order { <replaceable>address_match_element</replaceable>; ... };
+ 	listen-on <optional> port <replaceable>integer</replaceable> </optional> { <replaceable>address_match_element</replaceable>; ... };
+ 	listen-on-v6 <optional> port <replaceable>integer</replaceable> </optional> { <replaceable>address_match_element</replaceable>; ... };
+ 	match-mapped-addresses <replaceable>boolean</replaceable>;
+diff --git a/bin/named/server.c b/bin/named/server.c
+index e8f19d3..e30bf16 100644
+--- a/bin/named/server.c
++++ b/bin/named/server.c
+@@ -5207,6 +5207,10 @@ load_configuration(const char *filename, ns_server_t *server,
+ 		dns_dispatchmgr_setblackhole(ns_g_dispatchmgr,
+ 					     server->blackholeacl);
+ 
++	CHECK(configure_view_acl(NULL, config, "keep-response-order", NULL,
++				 ns_g_aclconfctx, ns_g_mctx,
++				 &server->keepresporder));
++
+ 	obj = NULL;
+ 	result = ns_config_get(maps, "match-mapped-addresses", &obj);
+ 	INSIST(result == ISC_R_SUCCESS);
+@@ -6208,6 +6212,9 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
+ 		dns_name_free(&ns_g_sessionkeyname, server->mctx);
+ 	}
+ 
++	if (server->keepresporder != NULL)
++		dns_acl_detach(&server->keepresporder);
++
+ 	if (server->blackholeacl != NULL)
+ 		dns_acl_detach(&server->blackholeacl);
+ 
+@@ -6259,6 +6266,7 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
+ 	ISC_LIST_INIT(server->viewlist);
+ 	server->in_roothints = NULL;
+ 	server->blackholeacl = NULL;
++	server->keepresporder = NULL;
+ 
+ 	/* Must be first. */
+ 	CHECKFATAL(dst_lib_init2(ns_g_mctx, ns_g_entropy,
+diff --git a/bin/tests/named.conf b/bin/tests/named.conf
+index 722d262..5b40045 100644
+--- a/bin/tests/named.conf
++++ b/bin/tests/named.conf
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2004, 2007, 2011  Internet Systems Consortium, Inc. ("ISC")
++ * Copyright (C) 2004, 2007, 2011, 2014  Internet Systems Consortium, Inc. ("ISC")
+  * Copyright (C) 1999-2001  Internet Software Consortium.
+  *
+  * Permission to use, copy, modify, and/or distribute this software for any
+@@ -116,6 +116,7 @@ options {
+ 	allow-transfer { any; };
+ 	allow-recursion { !any; };
+ 	blackhole { 45/24; };
++	keep-response-order { 46/24; };
+ 
+ 	listen-on {
+ 		10/24;
+diff --git a/bin/tests/system/Makefile.in b/bin/tests/system/Makefile.in
+index afee71b..e7eaef7 100644
+--- a/bin/tests/system/Makefile.in
++++ b/bin/tests/system/Makefile.in
+@@ -21,8 +21,8 @@ top_srcdir =	@top_srcdir@
+ 
+ @BIND9_MAKE_INCLUDES@
+ 
+-SUBDIRS =	dlzexternal dyndb filter-aaaa geoip lwresd rpz rrl \
+-		rsabigexponent tkey tsiggss
++SUBDIRS =	dlzexternal dyndb filter-aaaa geoip lwresd pipelined \
++		rpz rrl rsabigexponent tkey tsiggss
+ CINCLUDES =	${ISC_INCLUDES} ${DNS_INCLUDES}
+ 
+ CDEFINES =	@USE_GSSAPI@
+diff --git a/bin/tests/system/checkconf/bad-keep-response-order.conf b/bin/tests/system/checkconf/bad-keep-response-order.conf
+new file mode 100644
+index 0000000..24c1f6c
+--- /dev/null
++++ b/bin/tests/system/checkconf/bad-keep-response-order.conf
+@@ -0,0 +1,21 @@
++/*
++ * Copyright (C) 2015  Internet Systems Consortium, Inc. ("ISC")
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
++ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
++ * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
++ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
++ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ */
++
++options {
++	keep-response-order {
++		does_not_exist;
++	};
++};
+diff --git a/bin/tests/system/checkconf/bad-many.conf b/bin/tests/system/checkconf/bad-many.conf
+index cfc4d02..09add87 100644
+--- a/bin/tests/system/checkconf/bad-many.conf
++++ b/bin/tests/system/checkconf/bad-many.conf
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2005, 2012  Internet Systems Consortium, Inc. ("ISC")
++ * Copyright (C) 2005, 2012, 2014  Internet Systems Consortium, Inc. ("ISC")
+  *
+  * Permission to use, copy, modify, and/or distribute this software for any
+  * purpose with or without fee is hereby granted, provided that the above
+@@ -33,6 +33,7 @@ options {
+ 	host-statistics-max 100;
+ 	hostname none;
+ 	interface-interval 30;
++	keep-response-order { 10.0.0.10/24; };
+ 	listen-on port 90 { any; };
+ 	listen-on port 100 { 127.0.0.1; };
+ 	listen-on-v6 port 53 { none; };
+diff --git a/bin/tests/system/checkconf/good.conf b/bin/tests/system/checkconf/good.conf
+index cf7c745..43b0638 100644
+--- a/bin/tests/system/checkconf/good.conf
++++ b/bin/tests/system/checkconf/good.conf
+@@ -44,6 +44,9 @@ options {
+ 	host-statistics-max 100;
+ 	hostname none;
+ 	interface-interval 30;
++	keep-response-order {
++		10.0.0.10/24;
++	};
+ 	listen-on port 90 {
+ 		"any";
+ 	};
+diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in
+index 420320c..0d966b3 100644
+--- a/bin/tests/system/conf.sh.in
++++ b/bin/tests/system/conf.sh.in
+@@ -68,7 +68,7 @@ SUBDIRS="acl additional allow_query addzone autosign builtin
+ 	 cacheclean checkconf @CHECKDS@ checknames checkzone @COVERAGE@ @KEYMGR@
+          database digdelv dlv dlvauto dlz dlzexternal dname dns64 dnssec dyndb
+          ecdsa formerr forward glue gost ixfr inline limits logfileconfig
+-         lwresd masterfile masterformat metadata notify nsupdate pending
++         lwresd masterfile masterformat metadata notify nsupdate pending pipelined
+ 	 @PKCS11_TEST@ redirect resolver rndc rpz rrl rrsetorder rsabigexponent
+ 	 smartsign sortlist spf staticstub stub tkey tsig tsiggss unknown
+ 	 upforwd verify views wildcard xfer xferquota zero zonechecks geoip filter-aaaa"
+diff --git a/bin/tests/system/pipelined/Makefile.in b/bin/tests/system/pipelined/Makefile.in
+new file mode 100644
+index 0000000..4d16d78
+--- /dev/null
++++ b/bin/tests/system/pipelined/Makefile.in
+@@ -0,0 +1,51 @@
++# Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
++#
++# Permission to use, copy, modify, and/or distribute this software for any
++# purpose with or without fee is hereby granted, provided that the above
++# copyright notice and this permission notice appear in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
++# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
++# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
++# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
++# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++# PERFORMANCE OF THIS SOFTWARE.
++
++srcdir =	@srcdir@
++VPATH =		@srcdir@
++top_srcdir =	@top_srcdir@
++
++@BIND9_VERSION@
++
++@BIND9_MAKE_INCLUDES@
++
++CINCLUDES =	${DNS_INCLUDES} ${ISC_INCLUDES}
++
++CDEFINES =
++CWARNINGS =
++
++DNSLIBS =	../../../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
++ISCLIBS =	../../../../lib/isc/libisc.@A@
++
++DNSDEPLIBS =	../../../../lib/dns/libdns.@A@
++ISCDEPLIBS =	../../../../lib/isc/libisc.@A@
++
++DEPLIBS =	${DNSDEPLIBS} ${ISCDEPLIBS}
++
++LIBS =		${DNSLIBS} ${ISCLIBS} @LIBS@
++
++TARGETS =	pipequeries@EXEEXT@
++
++SRCS =		pipequeries.c
++
++@BIND9_MAKE_RULES@
++
++all: pipequeries@EXEEXT@
++
++pipequeries@EXEEXT@: pipequeries.@O@ ${DEPLIBS}
++	${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ pipequeries.@O@ ${LIBS}
++
++clean distclean::
++	rm -f ${TARGETS}
++
+diff --git a/bin/tests/system/pipelined/clean.sh b/bin/tests/system/pipelined/clean.sh
+new file mode 100644
+index 0000000..1cca633
+--- /dev/null
++++ b/bin/tests/system/pipelined/clean.sh
+@@ -0,0 +1,19 @@
++#!/bin/sh
++#
++# Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
++#
++# Permission to use, copy, modify, and/or distribute this software for any
++# purpose with or without fee is hereby granted, provided that the above
++# copyright notice and this permission notice appear in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
++# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
++# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
++# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
++# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++# PERFORMANCE OF THIS SOFTWARE.
++
++rm -f */named.memstats
++rm -f */named.run
++rm -f raw* output*
+diff --git a/bin/tests/system/pipelined/input b/bin/tests/system/pipelined/input
+new file mode 100644
+index 0000000..485cf81
+--- /dev/null
++++ b/bin/tests/system/pipelined/input
+@@ -0,0 +1,8 @@
++a.examplea
++a.exampleb
++b.examplea
++b.exampleb
++c.examplea
++c.exampleb
++d.examplea
++d.exampleb
+diff --git a/bin/tests/system/pipelined/inputb b/bin/tests/system/pipelined/inputb
+new file mode 100644
+index 0000000..6ea367e
+--- /dev/null
++++ b/bin/tests/system/pipelined/inputb
+@@ -0,0 +1,8 @@
++e.examplea
++e.exampleb
++f.examplea
++f.exampleb
++g.examplea
++g.exampleb
++h.examplea
++h.exampleb
+diff --git a/bin/tests/system/pipelined/ns1/named.conf b/bin/tests/system/pipelined/ns1/named.conf
+new file mode 100644
+index 0000000..1bbf401
+--- /dev/null
++++ b/bin/tests/system/pipelined/ns1/named.conf
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
++ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
++ * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
++ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
++ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ */
++
++controls { /* empty */ };
++
++options {
++	query-source address 10.53.0.1;
++	notify-source 10.53.0.1;
++	transfer-source 10.53.0.1;
++	port 5300;
++	pid-file "named.pid";
++	listen-on { 10.53.0.1; };
++	listen-on-v6 { none; };
++	recursion no;
++	notify yes;
++};
++
++key rndc_key {
++	secret "1234abcd8765";
++	algorithm hmac-sha256;
++};
++
++controls {
++	inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; };
++};
++
++zone "." {
++	type master;
++	file "root.db";
++};
+diff --git a/bin/tests/system/pipelined/ns1/root.db b/bin/tests/system/pipelined/ns1/root.db
+new file mode 100644
+index 0000000..b5186e5
+--- /dev/null
++++ b/bin/tests/system/pipelined/ns1/root.db
+@@ -0,0 +1,30 @@
++; Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
++;
++; Permission to use, copy, modify, and/or distribute this software for any
++; purpose with or without fee is hereby granted, provided that the above
++; copyright notice and this permission notice appear in all copies.
++;
++; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
++; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
++; AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
++; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
++; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++; PERFORMANCE OF THIS SOFTWARE.
++
++$TTL 300
++. 			IN SOA	gson.nominum.com. a.root.servers.nil. (
++				2000042100   	; serial
++				600         	; refresh
++				600         	; retry
++				1200    	; expire
++				600       	; minimum
++				)
++.			NS	a.root-servers.nil.
++a.root-servers.nil.	A	10.53.0.1
++
++examplea.		NS	ns2.examplea.
++ns2.examplea.		A	10.53.0.2
++
++exampleb.		NS	ns3.exampleb.
++ns3.exampleb.		A	10.53.0.3
+diff --git a/bin/tests/system/pipelined/ns2/examplea.db b/bin/tests/system/pipelined/ns2/examplea.db
+new file mode 100644
+index 0000000..678034a
+--- /dev/null
++++ b/bin/tests/system/pipelined/ns2/examplea.db
+@@ -0,0 +1,35 @@
++; Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
++;
++; Permission to use, copy, modify, and/or distribute this software for any
++; purpose with or without fee is hereby granted, provided that the above
++; copyright notice and this permission notice appear in all copies.
++;
++; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
++; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
++; AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
++; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
++; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++; PERFORMANCE OF THIS SOFTWARE.
++
++$ORIGIN .
++$TTL 300	; 5 minutes
++examplea		IN SOA	mname1. . (
++				1          ; serial
++				20         ; refresh (20 seconds)
++				20         ; retry (20 seconds)
++				1814400    ; expire (3 weeks)
++				3600       ; minimum (1 hour)
++				)
++examplea.		NS	ns2.examplea.
++ns2.examplea.		A	10.53.0.2
++
++$ORIGIN examplea.
++a			A	10.0.1.1
++b			A	10.0.1.2
++c			A	10.0.1.3
++d			A	10.0.1.4
++e			A	10.0.1.5
++f			A	10.0.1.6
++g			A	10.0.1.7
++h			A	10.0.1.8
+diff --git a/bin/tests/system/pipelined/ns2/named.conf b/bin/tests/system/pipelined/ns2/named.conf
+new file mode 100644
+index 0000000..83a9ec7
+--- /dev/null
++++ b/bin/tests/system/pipelined/ns2/named.conf
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
++ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
++ * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
++ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
++ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ */
++
++controls { /* empty */ };
++
++options {
++	query-source address 10.53.0.2;
++	notify-source 10.53.0.2;
++	transfer-source 10.53.0.2;
++	port 5300;
++	pid-file "named.pid";
++	listen-on { 10.53.0.2; };
++	listen-on-v6 { none; };
++	recursion yes;
++	notify yes;
++};
++
++key rndc_key {
++	secret "1234abcd8765";
++	algorithm hmac-sha256;
++};
++
++controls {
++	inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; };
++};
++
++zone "." {
++	type hint;
++	file "../../common/root.hint";
++};
++
++zone "examplea" {
++	type master;
++	file "examplea.db";
++	allow-update { any; };
++};
+diff --git a/bin/tests/system/pipelined/ns3/exampleb.db b/bin/tests/system/pipelined/ns3/exampleb.db
+new file mode 100644
+index 0000000..7d10493
+--- /dev/null
++++ b/bin/tests/system/pipelined/ns3/exampleb.db
+@@ -0,0 +1,35 @@
++; Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
++;
++; Permission to use, copy, modify, and/or distribute this software for any
++; purpose with or without fee is hereby granted, provided that the above
++; copyright notice and this permission notice appear in all copies.
++;
++; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
++; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
++; AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
++; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
++; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++; PERFORMANCE OF THIS SOFTWARE.
++
++$ORIGIN .
++$TTL 300	; 5 minutes
++exampleb		IN SOA	mname1. . (
++				1          ; serial
++				20         ; refresh (20 seconds)
++				20         ; retry (20 seconds)
++				1814400    ; expire (3 weeks)
++				3600       ; minimum (1 hour)
++				)
++exampleb.		NS	ns3.exampleb.
++ns3.exampleb.		A	10.53.0.3
++
++$ORIGIN exampleb.
++a			A	10.0.2.1
++b			A	10.0.2.2
++c			A	10.0.2.3
++d			A	10.0.2.4
++e			A	10.0.2.5
++f			A	10.0.2.6
++g			A	10.0.2.7
++h			A	10.0.2.8
+diff --git a/bin/tests/system/pipelined/ns3/named.args b/bin/tests/system/pipelined/ns3/named.args
+new file mode 100644
+index 0000000..a6b0f54
+--- /dev/null
++++ b/bin/tests/system/pipelined/ns3/named.args
+@@ -0,0 +1 @@
++-m record,size,mctx -c named.conf -d 99 -g -T delay=200
+diff --git a/bin/tests/system/pipelined/ns3/named.conf b/bin/tests/system/pipelined/ns3/named.conf
+new file mode 100644
+index 0000000..8b15622
+--- /dev/null
++++ b/bin/tests/system/pipelined/ns3/named.conf
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
++ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
++ * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
++ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
++ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ */
++
++controls { /* empty */ };
++
++options {
++	query-source address 10.53.0.3;
++	notify-source 10.53.0.3;
++	transfer-source 10.53.0.3;
++	port 5300;
++	pid-file "named.pid";
++	listen-on { 10.53.0.3; };
++	listen-on-v6 { none; };
++	recursion yes;
++	notify yes;
++};
++
++key rndc_key {
++	secret "1234abcd8765";
++	algorithm hmac-sha256;
++};
++
++controls {
++	inet 10.53.0.3 port 9953 allow { any; } keys { rndc_key; };
++};
++
++zone "." {
++	type hint;
++	file "../../common/root.hint";
++};
++
++zone "exampleb" {
++	type master;
++	file "exampleb.db";
++	allow-update { any; };
++};
+diff --git a/bin/tests/system/pipelined/ns4/named.conf b/bin/tests/system/pipelined/ns4/named.conf
+new file mode 100644
+index 0000000..7e7923a
+--- /dev/null
++++ b/bin/tests/system/pipelined/ns4/named.conf
+@@ -0,0 +1,45 @@
++/*
++ * Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
++ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
++ * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
++ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
++ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ */
++
++controls { /* empty */ };
++
++options {
++	query-source address 10.53.0.4;
++	notify-source 10.53.0.4;
++	transfer-source 10.53.0.4;
++	port 5300;
++	directory ".";
++	pid-file "named.pid";
++	listen-on { 10.53.0.4; };
++	listen-on-v6 { none; };
++	keep-response-order { 10.53.0.7/32; };
++	recursion yes;
++	notify yes;
++};
++
++key rndc_key {
++	secret "1234abcd8765";
++	algorithm hmac-sha256;
++};
++
++controls {
++	inet 10.53.0.4 port 9953 allow { any; } keys { rndc_key; };
++};
++
++zone "." {
++	type hint;
++	file "../../common/root.hint";
++};
+diff --git a/bin/tests/system/pipelined/pipequeries.c b/bin/tests/system/pipelined/pipequeries.c
+new file mode 100644
+index 0000000..d34dedd
+--- /dev/null
++++ b/bin/tests/system/pipelined/pipequeries.c
+@@ -0,0 +1,346 @@
++/*
++ * Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
++ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
++ * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
++ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
++ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <config.h>
++
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++#include <isc/app.h>
++#include <isc/base64.h>
++#include <isc/entropy.h>
++#include <isc/hash.h>
++#include <isc/log.h>
++#include <isc/mem.h>
++#include <isc/sockaddr.h>
++#include <isc/socket.h>
++#include <isc/task.h>
++#include <isc/timer.h>
++#include <isc/util.h>
++
++#include <dns/dispatch.h>
++#include <dns/fixedname.h>
++#include <dns/message.h>
++#include <dns/name.h>
++#include <dns/request.h>
++#include <dns/result.h>
++#include <dns/view.h>
++
++#include <dns/events.h>
++#include <dns/rdataset.h>
++#include <dns/resolver.h>
++#include <dns/types.h>
++
++#include <dst/result.h>
++
++#define CHECK(str, x) { \
++	if ((x) != ISC_R_SUCCESS) { \
++		fprintf(stderr, "I:%s: %s\n", (str), isc_result_totext(x)); \
++		exit(-1); \
++	} \
++}
++
++#define RUNCHECK(x) RUNTIME_CHECK((x) == ISC_R_SUCCESS)
++
++#define PORT 5300
++#define TIMEOUT 30
++
++static isc_mem_t *mctx;
++static dns_requestmgr_t *requestmgr;
++isc_sockaddr_t address;
++static int onfly;
++
++static void
++recvresponse(isc_task_t *task, isc_event_t *event) {
++	dns_requestevent_t *reqev = (dns_requestevent_t *)event;
++	isc_result_t result;
++	dns_message_t *query, *response;
++	isc_buffer_t outbuf;
++	char output[1024];
++
++	UNUSED(task);
++
++	REQUIRE(reqev != NULL);
++
++	if (reqev->result != ISC_R_SUCCESS) {
++		fprintf(stderr, "I:request event result: %s\n",
++			isc_result_totext(reqev->result));
++		exit(-1);
++	}
++
++	query = reqev->ev_arg;
++
++	response = NULL;
++	result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
++	CHECK("dns_message_create", result);
++
++	result = dns_request_getresponse(reqev->request, response,
++					 DNS_MESSAGEPARSE_PRESERVEORDER);
++	CHECK("dns_request_getresponse", result);
++
++	if (response->rcode != dns_rcode_noerror) {
++		result = ISC_RESULTCLASS_DNSRCODE + response->rcode;
++		fprintf(stderr, "I:response rcode: %s\n",
++			isc_result_totext(result));
++			exit(-1);
++	}
++	if (response->counts[DNS_SECTION_ANSWER] != 1U) {
++		fprintf(stderr, "I:response answer count (%u!=1)\n",
++			response->counts[DNS_SECTION_ANSWER]);
++	}
++
++	isc_buffer_init(&outbuf, output, sizeof(output));
++	result = dns_message_sectiontotext(response, DNS_SECTION_ANSWER,
++					   &dns_master_style_simple,
++					   DNS_MESSAGETEXTFLAG_NOCOMMENTS,
++					   &outbuf);
++	CHECK("dns_message_sectiontotext", result);
++	printf("%.*s", (int)isc_buffer_usedlength(&outbuf),
++	       (char *)isc_buffer_base(&outbuf));
++	fflush(stdout);
++
++	dns_message_destroy(&query);
++	dns_message_destroy(&response);
++	dns_request_destroy(&reqev->request);
++	isc_event_free(&event);
++
++	if (--onfly == 0)
++		isc_app_shutdown();
++	return;
++}
++
++static isc_result_t
++sendquery(isc_task_t *task)
++{
++	dns_request_t *request;
++	dns_message_t *message;
++	dns_name_t *qname;
++	dns_rdataset_t *qrdataset;
++	isc_result_t result;
++	dns_fixedname_t queryname;
++	isc_buffer_t buf;
++	static char host[256];
++	int c;
++
++	c = scanf("%255s", host);
++	if (c == EOF)
++		return ISC_R_NOMORE;
++
++	onfly++;
++
++	dns_fixedname_init(&queryname);
++	isc_buffer_init(&buf, host, strlen(host));
++	isc_buffer_add(&buf, strlen(host));
++	result = dns_name_fromtext(dns_fixedname_name(&queryname), &buf,
++				   dns_rootname, 0, NULL);
++	CHECK("dns_name_fromtext", result);
++
++	message = NULL;
++	result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message);
++	CHECK("dns_message_create", result);
++
++	message->opcode = dns_opcode_query;
++	message->flags |= DNS_MESSAGEFLAG_RD;
++	message->rdclass = dns_rdataclass_in;
++	message->id = (unsigned short)(random() & 0xFFFF);
++
++	qname = NULL;
++	result = dns_message_gettempname(message, &qname);
++	CHECK("dns_message_gettempname", result);
++
++	qrdataset = NULL;
++	result = dns_message_gettemprdataset(message, &qrdataset);
++	CHECK("dns_message_gettemprdataset", result);
++
++	dns_name_init(qname, NULL);
++	dns_name_clone(dns_fixedname_name(&queryname), qname);
++	dns_rdataset_init(qrdataset);
++	dns_rdataset_makequestion(qrdataset, dns_rdataclass_in,
++				  dns_rdatatype_a);
++	ISC_LIST_APPEND(qname->list, qrdataset, link);
++	dns_message_addname(message, qname, DNS_SECTION_QUESTION);
++
++	request = NULL;
++	result = dns_request_create(requestmgr, message, &address,
++				    DNS_REQUESTOPT_TCP, NULL,
++				    TIMEOUT, task, recvresponse,
++				    message, &request);
++	CHECK("dns_request_create", result);
++
++	return ISC_R_SUCCESS;
++}
++
++static void
++sendqueries(isc_task_t *task, isc_event_t *event)
++{
++	isc_result_t result;
++
++	isc_event_free(&event);
++
++	do {
++		result = sendquery(task);
++	} while (result == ISC_R_SUCCESS);
++
++	if (onfly == 0)
++		isc_app_shutdown();
++	return;
++}
++
++static void
++connecting(isc_task_t *task, isc_event_t *event)
++{
++	isc_socket_t *sock = (isc_socket_t *)(event->ev_arg);
++
++	RUNCHECK(isc_socket_connect(sock, &address, task, sendqueries, NULL));
++
++	isc_event_free(&event);
++}
++
++int
++main(int argc, char *argv[])
++{
++	isc_taskmgr_t *taskmgr;
++	isc_timermgr_t *timermgr;
++	isc_socketmgr_t *socketmgr;
++	isc_socket_t *sock;
++	unsigned int attrs, attrmask;
++	isc_sockaddr_t bind_addr;
++	dns_dispatchmgr_t *dispatchmgr;
++	dns_dispatch_t *dispatchv4;
++	dns_dispatch_t *tcpdispatch;
++	dns_view_t *view;
++	isc_entropy_t *ectx;
++	isc_task_t *task;
++	isc_log_t *lctx;
++	isc_logconfig_t *lcfg;
++	struct in_addr inaddr;
++	isc_result_t result;
++
++	UNUSED(argv);
++
++	RUNCHECK(isc_app_start());
++
++	dns_result_register();
++
++	mctx = NULL;
++	RUNCHECK(isc_mem_create(0, 0, &mctx));
++
++	lctx = NULL;
++	lcfg = NULL;
++	RUNCHECK(isc_log_create(mctx, &lctx, &lcfg));
++
++	ectx = NULL;
++	RUNCHECK(isc_entropy_create(mctx, &ectx));
++	RUNCHECK(isc_entropy_createfilesource(ectx, "../random.data"));
++	RUNCHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE));
++
++	RUNCHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_GOODONLY));
++
++	taskmgr = NULL;
++	RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr));
++	task = NULL;
++	RUNCHECK(isc_task_create(taskmgr, 0, &task));
++	timermgr = NULL;
++
++	RUNCHECK(isc_timermgr_create(mctx, &timermgr));
++	socketmgr = NULL;
++	RUNCHECK(isc_socketmgr_create(mctx, &socketmgr));
++	dispatchmgr = NULL;
++	RUNCHECK(dns_dispatchmgr_create(mctx, ectx, &dispatchmgr));
++	if (argc == 1) {
++		isc_sockaddr_any(&bind_addr);
++	} else {
++		result = ISC_R_FAILURE;
++		if (inet_pton(AF_INET, "10.53.0.7", &inaddr) != 1)
++			CHECK("inet_pton", result);
++		isc_sockaddr_fromin(&bind_addr, &inaddr, 0);
++	}
++	attrs = DNS_DISPATCHATTR_UDP |
++		DNS_DISPATCHATTR_MAKEQUERY |
++		DNS_DISPATCHATTR_IPV4;
++	attrmask = DNS_DISPATCHATTR_UDP |
++		   DNS_DISPATCHATTR_TCP |
++		   DNS_DISPATCHATTR_IPV4 |
++		   DNS_DISPATCHATTR_IPV6;
++	dispatchv4 = NULL;
++	RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr,
++					  &bind_addr, 4096, 4, 2, 3, 5,
++					  attrs, attrmask, &dispatchv4));
++	requestmgr = NULL;
++	RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr,
++					    dispatchmgr, dispatchv4, NULL,
++					    &requestmgr));
++
++	view = NULL;
++	RUNCHECK(dns_view_create(mctx, 0, "_test", &view));
++
++	sock = NULL;
++	RUNCHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_tcp,
++				   &sock));
++	RUNCHECK(isc_socket_bind(sock, &bind_addr, 0));
++
++	result = ISC_R_FAILURE;
++	if (inet_pton(AF_INET, "10.53.0.4", &inaddr) != 1)
++		CHECK("inet_pton", result);
++	isc_sockaddr_fromin(&address, &inaddr, PORT);
++
++	attrs = 0;
++	attrs |= DNS_DISPATCHATTR_TCP;
++	attrs |= DNS_DISPATCHATTR_IPV4;
++	attrs |= DNS_DISPATCHATTR_MAKEQUERY;
++	attrs |= DNS_DISPATCHATTR_CONNECTED;
++	tcpdispatch = NULL;
++	RUNCHECK(dns_dispatch_createtcp2(dispatchmgr, sock, taskmgr,
++					 &bind_addr, &address,
++					 4096, 20, 10, 3, 5,
++					 attrs, &tcpdispatch));
++
++	RUNCHECK(isc_app_onrun(mctx, task, connecting, sock));
++
++	isc_socket_detach(&sock);
++
++	(void)isc_app_run();
++
++	dns_view_detach(&view);
++
++	dns_requestmgr_shutdown(requestmgr);
++	dns_requestmgr_detach(&requestmgr);
++
++	dns_dispatch_detach(&dispatchv4);
++	dns_dispatch_detach(&tcpdispatch);
++	dns_dispatchmgr_destroy(&dispatchmgr);
++
++	isc_socketmgr_destroy(&socketmgr);
++	isc_timermgr_destroy(&timermgr);
++
++	isc_task_shutdown(task);
++	isc_task_detach(&task);
++	isc_taskmgr_destroy(&taskmgr);
++
++	dst_lib_destroy();
++	isc_hash_destroy();
++	isc_entropy_detach(&ectx);
++
++	isc_log_destroy(&lctx);
++
++	isc_mem_destroy(&mctx);
++
++	isc_app_finish();
++
++	return (0);
++}
++
+diff --git a/bin/tests/system/pipelined/ref b/bin/tests/system/pipelined/ref
+new file mode 100644
+index 0000000..fe123f6
+--- /dev/null
++++ b/bin/tests/system/pipelined/ref
+@@ -0,0 +1,8 @@
++a.examplea. 10.0.1.1
++a.exampleb. 10.0.2.1
++b.examplea. 10.0.1.2
++b.exampleb. 10.0.2.2
++c.examplea. 10.0.1.3
++c.exampleb. 10.0.2.3
++d.examplea. 10.0.1.4
++d.exampleb. 10.0.2.4
+diff --git a/bin/tests/system/pipelined/refb b/bin/tests/system/pipelined/refb
+new file mode 100644
+index 0000000..a24c6bc
+--- /dev/null
++++ b/bin/tests/system/pipelined/refb
+@@ -0,0 +1,8 @@
++e.examplea. 10.0.1.5
++e.exampleb. 10.0.2.5
++f.examplea. 10.0.1.6
++f.exampleb. 10.0.2.6
++g.examplea. 10.0.1.7
++g.exampleb. 10.0.2.7
++h.examplea. 10.0.1.8
++h.exampleb. 10.0.2.8
+diff --git a/bin/tests/system/pipelined/setup.sh b/bin/tests/system/pipelined/setup.sh
+new file mode 100644
+index 0000000..6fc981d
+--- /dev/null
++++ b/bin/tests/system/pipelined/setup.sh
+@@ -0,0 +1,22 @@
++#!/bin/sh
++#
++# Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
++#
++# Permission to use, copy, modify, and/or distribute this software for any
++# purpose with or without fee is hereby granted, provided that the above
++# copyright notice and this permission notice appear in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
++# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
++# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
++# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
++# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++# PERFORMANCE OF THIS SOFTWARE.
++
++SYSTEMTESTTOP=..
++. $SYSTEMTESTTOP/conf.sh
++
++$SHELL clean.sh
++
++test -r $RANDFILE || $GENRANDOM 400 $RANDFILE
+diff --git a/bin/tests/system/pipelined/tests.sh b/bin/tests/system/pipelined/tests.sh
+new file mode 100644
+index 0000000..a34e573
+--- /dev/null
++++ b/bin/tests/system/pipelined/tests.sh
+@@ -0,0 +1,41 @@
++#!/bin/sh
++#
++# Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
++#
++# Permission to use, copy, modify, and/or distribute this software for any
++# purpose with or without fee is hereby granted, provided that the above
++# copyright notice and this permission notice appear in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
++# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
++# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
++# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
++# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++# PERFORMANCE OF THIS SOFTWARE.
++
++SYSTEMTESTTOP=..
++. $SYSTEMTESTTOP/conf.sh
++
++status=0
++
++echo "I:check pipelined TCP queries"
++ret=0
++./pipequeries < input > raw || ret=1
++awk '{ print $1 " " $5 }' < raw > output
++sort < output > output-sorted
++diff ref output-sorted || { ret=1 ; echo "I: diff sorted failed"; }
++diff ref output > /dev/null && { ret=1 ; echo "I: diff out of order failed"; }
++if [ $ret != 0 ]; then echo "I:failed"; fi
++status=`expr $status + $ret`
++
++echo "I:check keep response order"
++ret=0
++./pipequeries ++ < inputb > rawb || ret=1
++awk '{ print $1 " " $5 }' < rawb > outputb
++diff refb outputb || ret=1
++if [ $ret != 0 ]; then echo "I:failed"; fi
++status=`expr $status + $ret`
++
++echo "I:exit status: $status"
++exit $status
+diff --git a/configure b/configure
+index a299aac..7f5c7da 100755
+--- a/configure
++++ b/configure
+@@ -22330,6 +22330,7 @@ do
+     "bin/tests/system/geoip/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/geoip/Makefile" ;;
+     "bin/tests/system/gost/prereq.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/system/gost/prereq.sh" ;;
+     "bin/tests/system/lwresd/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/lwresd/Makefile" ;;
++    "bin/tests/system/pipelined/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/pipelined/Makefile" ;;
+     "bin/tests/system/rpz/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/rpz/Makefile" ;;
+     "bin/tests/system/rrl/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/rrl/Makefile" ;;
+     "bin/tests/system/rsabigexponent/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/rsabigexponent/Makefile" ;;
+diff --git a/configure.in b/configure.in
+index ee38901..9c5a9db 100644
+--- a/configure.in
++++ b/configure.in
+@@ -4099,6 +4099,7 @@ AC_CONFIG_FILES([
+ 	bin/tests/system/geoip/Makefile
+ 	bin/tests/system/gost/prereq.sh
+ 	bin/tests/system/lwresd/Makefile
++	bin/tests/system/pipelined/Makefile
+ 	bin/tests/system/rpz/Makefile
+ 	bin/tests/system/rrl/Makefile
+ 	bin/tests/system/rsabigexponent/Makefile
+diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml
+index af194d9..74394a0 100644
+--- a/doc/arm/Bv9ARM-book.xml
++++ b/doc/arm/Bv9ARM-book.xml
+@@ -3025,8 +3025,9 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
+ 	    <command>allow-query-cache-on</command>,
+ 	    <command>allow-transfer</command>,
+ 	    <command>allow-update</command>,
+-	    <command>allow-update-forwarding</command>, and
+-	    <command>blackhole</command> all use address match
++	    <command>allow-update-forwarding</command>,
++	    <command>blackhole</command>, and
++	    <command>keep-response-order</command> all use address match
+ 	    lists.  Similarly, the <command>listen-on</command> option will cause the
+ 	    server to refuse queries on any of the machine's
+ 	    addresses which do not match the list.
+@@ -4829,6 +4830,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
+     <optional> try-tcp-refresh <replaceable>yes_or_no</replaceable>; </optional>
+     <optional> allow-v6-synthesis { <replaceable>address_match_list</replaceable> }; </optional>
+     <optional> blackhole { <replaceable>address_match_list</replaceable> }; </optional>
++    <optional> keep-response-order { <replaceable>address_match_list</replaceable> }; </optional>
+     <optional> use-v4-udp-ports { <replaceable>port_list</replaceable> }; </optional>
+     <optional> avoid-v4-udp-ports { <replaceable>port_list</replaceable> }; </optional>
+     <optional> use-v6-udp-ports { <replaceable>port_list</replaceable> }; </optional>
+@@ -7248,6 +7250,19 @@ options {
+                   Specifies a list of addresses to which
+ 		  <command>filter-aaaa-on-v4</command>
+                   is applies.  The default is <userinput>any</userinput>.
++		</para>
++	      </listitem>
++	    </varlistentry>
++
++	    <varlistentry>
++	      <term><command>keep-response-order</command></term>
++	      <listitem>
++		<para>
++		  Specifies a list of addresses to which the server
++		  will send responses to TCP queries in the same order
++		  in which they were received.  This disables the
++		  processing of TCP queries in parallel. The default
++		  is <userinput>any</userinput>.
+                 </para>
+               </listitem>
+             </varlistentry>
+diff --git a/doc/misc/options b/doc/misc/options
+index 1827bd7..3c0f01f 100644
+--- a/doc/misc/options
++++ b/doc/misc/options
+@@ -147,6 +147,7 @@ options {
+         inline-signing <boolean>;
+         interface-interval <integer>;
+         ixfr-from-differences <ixfrdiff>;
++	keep-response-order { <address_match_element>; ... };
+         key-directory <quoted_string>;
+         lame-ttl <integer>;
+         listen-on [ port <integer> ] { <address_match_element>; ... };
+diff --git a/lib/bind9/check.c b/lib/bind9/check.c
+index 00c4b3e..d4803e2 100644
+--- a/lib/bind9/check.c
++++ b/lib/bind9/check.c
+@@ -403,8 +403,8 @@ check_viewacls(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions,
+ 
+ 	static const char *acls[] = { "allow-query", "allow-query-on",
+ 		"allow-query-cache", "allow-query-cache-on",
+-		"blackhole", "match-clients", "match-destinations",
+-		"sortlist", "filter-aaaa", NULL };
++		"blackhole", "keep-response-order", "match-clients",
++		"match-destinations", "sortlist", "filter-aaaa", NULL };
+ 
+ 	while (acls[i] != NULL) {
+ 		tresult = checkacl(acls[i++], actx, NULL, voptions, config,
+diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c
+index b9f34eb..088c500 100644
+--- a/lib/dns/dispatch.c
++++ b/lib/dns/dispatch.c
+@@ -2831,7 +2831,6 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr,
+ 	isc_result_t result;
+ 	isc_sockaddr_t peeraddr;
+ 	isc_sockaddr_t sockname;
+-	isc_sockaddr_t any;
+ 	unsigned int attributes, mask;
+ 	isc_boolean_t match = ISC_FALSE;
+ 
+@@ -2839,23 +2838,9 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr,
+ 	REQUIRE(destaddr != NULL);
+ 	REQUIRE(dispp != NULL && *dispp == NULL);
+ 
+-	attributes = DNS_DISPATCHATTR_TCP;
++	attributes = DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_CONNECTED;
+ 	mask = DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_PRIVATE |
+-	       DNS_DISPATCHATTR_EXCLUSIVE;
+-
+-	if (localaddr == NULL) {
+-		switch (isc_sockaddr_pf(destaddr)) {
+-		case AF_INET:
+-			isc_sockaddr_any(&any);
+-			break;
+-		case AF_INET6:
+-			isc_sockaddr_any6(&any);
+-			break;
+-		default:
+-			return (ISC_R_NOTFOUND);
+-		}
+-		localaddr = &any;
+-	}
++	       DNS_DISPATCHATTR_EXCLUSIVE | DNS_DISPATCHATTR_CONNECTED;
+ 
+ 	LOCK(&mgr->lock);
+ 	disp = ISC_LIST_HEAD(mgr->list);
+@@ -2872,7 +2857,8 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr,
+ 								&peeraddr);
+ 			if (result == ISC_R_SUCCESS &&
+ 			    isc_sockaddr_equal(destaddr, &peeraddr) &&
+-			    isc_sockaddr_eqaddr(localaddr, &sockname)) {
++			    (localaddr == NULL ||
++			     isc_sockaddr_eqaddr(localaddr, &sockname))) {
+ 				/* attach */
+ 				disp->refcount++;
+ 				*dispp = disp;
+diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c
+index d9b1df1..f357c63 100644
+--- a/lib/isccfg/namedconf.c
++++ b/lib/isccfg/namedconf.c
+@@ -959,6 +959,7 @@ options_clauses[] = {
+ 	{ "host-statistics-max", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTIMP },
+ 	{ "hostname", &cfg_type_qstringornone, 0 },
+ 	{ "interface-interval", &cfg_type_uint32, 0 },
++	{ "keep-response-order", &cfg_type_bracketed_aml, 0 },
+ 	{ "listen-on", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI },
+ 	{ "listen-on-v6", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI },
+ 	{ "managed-keys-directory", &cfg_type_qstring, 0 },
+-- 
+2.20.1
+
diff --git a/SPECS/bind.spec b/SPECS/bind.spec
index 48f91b1..940c830 100644
--- a/SPECS/bind.spec
+++ b/SPECS/bind.spec
@@ -26,7 +26,7 @@ Summary:  The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) serv
 Name:     bind
 License:  ISC
 Version:  9.9.4
-Release:  73%{?PATCHVER}%{?PREVER}%{?dist}
+Release:  74%{?PATCHVER}%{?PREVER}%{?dist}.1
 Epoch:    32
 Url:      http://www.isc.org/products/BIND/
 Buildroot:%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -174,6 +174,10 @@ Patch196: bind99-rh1549130.patch
 Patch197: bind99-rh1549130-2.patch
 Patch198: bind99-CVE-2018-5740.patch
 Patch199: bind99-rh1647539.patch
+Patch200: bind-9.11-rt37039.patch
+Patch201: bind-9.11-rt37821.patch
+Patch202: bind-9.11-CVE-2018-5743.patch
+Patch203: bind-9.11-CVE-2018-5743-atomic.patch
 
 # Native PKCS#11 functionality from 9.10
 Patch150:bind-9.9-allow_external_dnskey.patch
@@ -500,6 +504,10 @@ tar -xf %{SOURCE48} -C bin/tests/system/geoip/data
 %patch197 -p1 -b .rh1549130-2
 %patch198 -p1 -b .CVE-2018-5740
 %patch199 -p1 -b .rh1647539
+%patch200 -p1 -b .tcp-share
+%patch201 -p1 -b .tcp-pipeline
+%patch202 -p1 -b .CVE-2018-5743
+%patch203 -p1 -b .CVE-2018-5743-atomic
 
 # Override upstream builtin keys
 cp -fp %{SOURCE29} bind.keys
@@ -1207,6 +1215,12 @@ rm -rf ${RPM_BUILD_ROOT}
 %endif
 
 %changelog
+* Thu May 23 2019 Petr Menšík <pemensik@redhat.com> - 32:9.9.4-74.1
+- Remove again broken test (CVE-2018-5743)
+
+* Tue May 07 2019 Petr Menšík <pemensik@redhat.com> - 32:9.9.4-74
+- Fix CVE-2018-5743
+
 * Fri Nov 23 2018 Petr Menšík <pemensik@redhat.com> - 32:9.9.4-73
 - Fixes debug level comments (#1647539)