<div dir="ltr"><div dir="ltr">On Wed, 27 Nov 2019 at 21:25, akuster808 &lt;<a href="mailto:akuster808@gmail.com">akuster808@gmail.com</a>&gt; wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
<br>
On 11/27/19 8:40 AM, Alexander Kanavin wrote:<br>
&gt; Drop backports.<br>
&gt;<br>
&gt; Drop 0001-gen.c-extend-DIRNAMESIZE-from-256-to-512.patch and<br>
&gt; 0001-lib-dns-gen.c-fix-too-long-error.patch as problem is fixed<br>
<br>
Bug fix only?<br></blockquote><div><br></div><div>I don&#39;t think so, there are some new features as well:</div><div><a href="https://downloads.isc.org/isc/bind9/9.11.13/RELEASE-NOTES-bind-9.11.13.html">https://downloads.isc.org/isc/bind9/9.11.13/RELEASE-NOTES-bind-9.11.13.html</a></div><div><br></div><div>Alex<br></div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
-armin<br>
&gt; upstream.<br>
&gt;<br>
&gt; Signed-off-by: Alexander Kanavin &lt;<a href="mailto:alex.kanavin@gmail.com" target="_blank">alex.kanavin@gmail.com</a>&gt;<br>
&gt; ---<br>
&gt;  .../bind/0001-bind-fix-CVE-2019-6471.patch    |  64 --<br>
&gt;  ....in-remove-useless-L-use_openssl-lib.patch |  18 +-<br>
&gt;  ...01-fix-enforcement-of-tcp-clients-v1.patch |  60 --<br>
&gt;  ...c-extend-DIRNAMESIZE-from-256-to-512.patch |  22 -<br>
&gt;  ...001-lib-dns-gen.c-fix-too-long-error.patch |  31 -<br>
&gt;  ...p-clients-could-still-be-exceeded-v2.patch | 670 -------------<br>
&gt;  ...rence-counter-for-pipeline-groups-v3.patch | 278 ------<br>
&gt;  ...accounting-and-client-mortality-chec.patch | 512 ----------<br>
&gt;  ...a-and-pipeline-refs-allow-special-ca.patch | 911 ------------------<br>
&gt;  ...allowance-for-tcp-clients-interfaces.patch |  80 --<br>
&gt;  ...perations-in-bin-named-client.c-with.patch | 140 ---<br>
&gt;  ...ching-for-json-headers-searches-sysr.patch |  15 +-<br>
&gt;  .../{<a href="http://bind_9.11.5-P4.bb" rel="noreferrer" target="_blank">bind_9.11.5-P4.bb</a> =&gt; <a href="http://bind_9.11.13.bb" rel="noreferrer" target="_blank">bind_9.11.13.bb</a>}    |  18 +-<br>
&gt;  13 files changed, 20 insertions(+), 2799 deletions(-)<br>
&gt;  delete mode 100644 meta/recipes-connectivity/bind/bind/0001-bind-fix-CVE-2019-6471.patch<br>
&gt;  delete mode 100644 meta/recipes-connectivity/bind/bind/0001-fix-enforcement-of-tcp-clients-v1.patch<br>
&gt;  delete mode 100644 meta/recipes-connectivity/bind/bind/0001-gen.c-extend-DIRNAMESIZE-from-256-to-512.patch<br>
&gt;  delete mode 100644 meta/recipes-connectivity/bind/bind/0001-lib-dns-gen.c-fix-too-long-error.patch<br>
&gt;  delete mode 100644 meta/recipes-connectivity/bind/bind/0002-tcp-clients-could-still-be-exceeded-v2.patch<br>
&gt;  delete mode 100644 meta/recipes-connectivity/bind/bind/0003-use-reference-counter-for-pipeline-groups-v3.patch<br>
&gt;  delete mode 100644 meta/recipes-connectivity/bind/bind/0004-better-tcpquota-accounting-and-client-mortality-chec.patch<br>
&gt;  delete mode 100644 meta/recipes-connectivity/bind/bind/0005-refactor-tcpquota-and-pipeline-refs-allow-special-ca.patch<br>
&gt;  delete mode 100644 meta/recipes-connectivity/bind/bind/0006-restore-allowance-for-tcp-clients-interfaces.patch<br>
&gt;  delete mode 100644 meta/recipes-connectivity/bind/bind/0007-Replace-atomic-operations-in-bin-named-client.c-with.patch<br>
&gt;  rename meta/recipes-connectivity/bind/{<a href="http://bind_9.11.5-P4.bb" rel="noreferrer" target="_blank">bind_9.11.5-P4.bb</a> =&gt; <a href="http://bind_9.11.13.bb" rel="noreferrer" target="_blank">bind_9.11.13.bb</a>} (86%)<br>
&gt;<br>
&gt; diff --git a/meta/recipes-connectivity/bind/bind/0001-bind-fix-CVE-2019-6471.patch b/meta/recipes-connectivity/bind/bind/0001-bind-fix-CVE-2019-6471.patch<br>
&gt; deleted file mode 100644<br>
&gt; index 2fed99e1bba..00000000000<br>
&gt; --- a/meta/recipes-connectivity/bind/bind/0001-bind-fix-CVE-2019-6471.patch<br>
&gt; +++ /dev/null<br>
&gt; @@ -1,64 +0,0 @@<br>
&gt; -Backport patch to fix CVE-2019-6471.<br>
&gt; -<br>
&gt; -Ref:<br>
&gt; -<a href="https://security-tracker.debian.org/tracker/CVE-2019-6471" rel="noreferrer" target="_blank">https://security-tracker.debian.org/tracker/CVE-2019-6471</a><br>
&gt; -<br>
&gt; -CVE: CVE-2019-6471<br>
&gt; -Upstream-Status: Backport [<a href="https://gitlab.isc.org/isc-projects/bind9/commit/3a9c7bb" rel="noreferrer" target="_blank">https://gitlab.isc.org/isc-projects/bind9/commit/3a9c7bb</a>]<br>
&gt; -<br>
&gt; -Signed-off-by: Kai Kang &lt;<a href="mailto:kai.kang@windriver.com" target="_blank">kai.kang@windriver.com</a>&gt;<br>
&gt; -<br>
&gt; -From 3a9c7bb80d4a609b86427406d9dd783199920b5b Mon Sep 17 00:00:00 2001<br>
&gt; -From: Mark Andrews &lt;<a href="mailto:marka@isc.org" target="_blank">marka@isc.org</a>&gt;<br>
&gt; -Date: Tue, 19 Mar 2019 14:14:21 +1100<br>
&gt; -Subject: [PATCH] move item_out test inside lock in dns_dispatch_getnext()<br>
&gt; -<br>
&gt; -(cherry picked from commit 60c42f849d520564ed42e5ed0ba46b4b69c07712)<br>
&gt; ----<br>
&gt; - lib/dns/dispatch.c | 12 ++++++++----<br>
&gt; - 1 file changed, 8 insertions(+), 4 deletions(-)<br>
&gt; -<br>
&gt; -diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c<br>
&gt; -index 408beda367..3278db4a07 100644<br>
&gt; ---- a/lib/dns/dispatch.c<br>
&gt; -+++ b/lib/dns/dispatch.c<br>
&gt; -@@ -134,7 +134,7 @@ struct dns_dispentry {<br>
&gt; -     isc_task_t                     *task;<br>
&gt; -     isc_taskaction_t                action;<br>
&gt; -     void                           *arg;<br>
&gt; --    bool                    item_out;<br>
&gt; -+    bool                            item_out;<br>
&gt; -     dispsocket_t                    *dispsocket;<br>
&gt; -     ISC_LIST(dns_dispatchevent_t)   items;<br>
&gt; -     ISC_LINK(dns_dispentry_t)       link;<br>
&gt; -@@ -3422,13 +3422,14 @@ dns_dispatch_getnext(dns_dispentry_t *resp, dns_dispatchevent_t **sockevent) {<br>
&gt; -     disp = resp-&gt;disp;<br>
&gt; -     REQUIRE(VALID_DISPATCH(disp));<br>
&gt; - <br>
&gt; --    REQUIRE(resp-&gt;item_out == true);<br>
&gt; --    resp-&gt;item_out = false;<br>
&gt; --<br>
&gt; -     ev = *sockevent;<br>
&gt; -     *sockevent = NULL;<br>
&gt; - <br>
&gt; -     LOCK(&amp;disp-&gt;lock);<br>
&gt; -+<br>
&gt; -+    REQUIRE(resp-&gt;item_out == true);<br>
&gt; -+    resp-&gt;item_out = false;<br>
&gt; -+<br>
&gt; -     if (ev-&gt;buffer.base != NULL)<br>
&gt; -             free_buffer(disp, ev-&gt;buffer.base, ev-&gt;buffer.length);<br>
&gt; -     free_devent(disp, ev);<br>
&gt; -@@ -3573,6 +3574,9 @@ dns_dispatch_removeresponse(dns_dispentry_t **resp,<br>
&gt; -             isc_task_send(disp-&gt;task[0], &amp;disp-&gt;ctlevent);<br>
&gt; - }<br>
&gt; - <br>
&gt; -+/*<br>
&gt; -+ * disp must be locked.<br>
&gt; -+ */<br>
&gt; - static void<br>
&gt; - do_cancel(dns_dispatch_t *disp) {<br>
&gt; -     dns_dispatchevent_t *ev;<br>
&gt; --- <br>
&gt; -2.20.1<br>
&gt; -<br>
&gt; diff --git a/meta/recipes-connectivity/bind/bind/0001-configure.in-remove-useless-L-use_openssl-lib.patch b/meta/recipes-connectivity/bind/bind/0001-configure.in-remove-useless-L-use_openssl-lib.patch<br>
&gt; index 871bb2a5f6c..9d31b980807 100644<br>
&gt; --- a/meta/recipes-connectivity/bind/bind/0001-configure.in-remove-useless-L-use_openssl-lib.patch<br>
&gt; +++ b/meta/recipes-connectivity/bind/bind/0001-configure.in-remove-useless-L-use_openssl-lib.patch<br>
&gt; @@ -1,4 +1,4 @@<br>
&gt; -From 950867d9fd3f690e271c8c807b6eed144b2935b2 Mon Sep 17 00:00:00 2001<br>
&gt; +From 2325a92f1896a2a7f586611686801b41fbc91b50 Mon Sep 17 00:00:00 2001<br>
&gt;  From: Hongxu Jia &lt;<a href="mailto:hongxu.jia@windriver.com" target="_blank">hongxu.jia@windriver.com</a>&gt;<br>
&gt;  Date: Mon, 27 Aug 2018 15:00:51 +0800<br>
&gt;  Subject: [PATCH] <a href="http://configure.in" rel="noreferrer" target="_blank">configure.in</a>: remove useless `-L$use_openssl/lib&#39;<br>
&gt; @@ -10,15 +10,16 @@ and helpful for clean up host build path in isc-config.sh<br>
&gt;  Upstream-Status: Inappropriate [oe-core specific]<br>
&gt;  <br>
&gt;  Signed-off-by: Hongxu Jia &lt;<a href="mailto:hongxu.jia@windriver.com" target="_blank">hongxu.jia@windriver.com</a>&gt;<br>
&gt; +<br>
&gt;  ---<br>
&gt; - <a href="http://configure.in" rel="noreferrer" target="_blank">configure.in</a> | 2 +-<br>
&gt; + <a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a> | 2 +-<br>
&gt;   1 file changed, 1 insertion(+), 1 deletion(-)<br>
&gt;  <br>
&gt; -diff --git a/<a href="http://configure.in" rel="noreferrer" target="_blank">configure.in</a> b/<a href="http://configure.in" rel="noreferrer" target="_blank">configure.in</a><br>
&gt; -index 54efc55..76ac0eb 100644<br>
&gt; ---- a/<a href="http://configure.in" rel="noreferrer" target="_blank">configure.in</a><br>
&gt; -+++ b/<a href="http://configure.in" rel="noreferrer" target="_blank">configure.in</a><br>
&gt; -@@ -1691,7 +1691,7 @@ If you don&#39;t want OpenSSL, use --without-openssl])<br>
&gt; +diff --git a/<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a> b/<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a><br>
&gt; +index e85a5c6..2bbfc58 100644<br>
&gt; +--- a/<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a><br>
&gt; ++++ b/<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a><br>
&gt; +@@ -1631,7 +1631,7 @@ If you don&#39;t want OpenSSL, use --without-openssl])<br>
&gt;                               fi<br>
&gt;                               ;;<br>
&gt;                       *)<br>
&gt; @@ -27,6 +28,3 @@ index 54efc55..76ac0eb 100644<br>
&gt;                               ;;<br>
&gt;                       esac<br>
&gt;               fi<br>
&gt; --- <br>
&gt; -2.7.4<br>
&gt; -<br>
&gt; diff --git a/meta/recipes-connectivity/bind/bind/0001-fix-enforcement-of-tcp-clients-v1.patch b/meta/recipes-connectivity/bind/bind/0001-fix-enforcement-of-tcp-clients-v1.patch<br>
&gt; deleted file mode 100644<br>
&gt; index 48ae125f845..00000000000<br>
&gt; --- a/meta/recipes-connectivity/bind/bind/0001-fix-enforcement-of-tcp-clients-v1.patch<br>
&gt; +++ /dev/null<br>
&gt; @@ -1,60 +0,0 @@<br>
&gt; -Backport patch to fix CVE-2018-5743.<br>
&gt; -<br>
&gt; -Ref:<br>
&gt; -<a href="https://security-tracker.debian.org/tracker/CVE-2018-5743" rel="noreferrer" target="_blank">https://security-tracker.debian.org/tracker/CVE-2018-5743</a><br>
&gt; -<br>
&gt; -CVE: CVE-2018-5743<br>
&gt; -Upstream-Status: Backport [<a href="https://gitlab.isc.org/isc-projects/bind9/commit/ec2d50d" rel="noreferrer" target="_blank">https://gitlab.isc.org/isc-projects/bind9/commit/ec2d50d</a>]<br>
&gt; -<br>
&gt; -Signed-off-by: Kai Kang &lt;<a href="mailto:kai.kang@windriver.com" target="_blank">kai.kang@windriver.com</a>&gt;<br>
&gt; -<br>
&gt; -From ec2d50da8d81814640e28593d912f4b96c7efece Mon Sep 17 00:00:00 2001<br>
&gt; -From: =?UTF-8?q?Witold=20Kr=C4=99cicki?= &lt;<a href="mailto:wpk@isc.org" target="_blank">wpk@isc.org</a>&gt;<br>
&gt; -Date: Thu, 3 Jan 2019 14:17:43 +0100<br>
&gt; -Subject: [PATCH 1/6] fix enforcement of tcp-clients (v1)<br>
&gt; -<br>
&gt; -tcp-clients settings could be exceeded in some cases by<br>
&gt; -creating more and more active TCP clients that are over<br>
&gt; -the set quota limit, which in the end could lead to a<br>
&gt; -DoS attack by e.g. exhaustion of file descriptors.<br>
&gt; -<br>
&gt; -If TCP client we&#39;re closing went over the quota (so it&#39;s<br>
&gt; -not attached to a quota) mark it as mortal - so that it<br>
&gt; -will be destroyed and not set up to listen for new<br>
&gt; -connections - unless it&#39;s the last client for a specific<br>
&gt; -interface.<br>
&gt; -<br>
&gt; -(cherry picked from commit f97131d21b97381cef72b971b157345c1f9b4115)<br>
&gt; -(cherry picked from commit 9689ffc485df8f971f0ad81ab8ab1f5389493776)<br>
&gt; ----<br>
&gt; - bin/named/client.c | 13 ++++++++++++-<br>
&gt; - 1 file changed, 12 insertions(+), 1 deletion(-)<br>
&gt; -<br>
&gt; -diff --git a/bin/named/client.c b/bin/named/client.c<br>
&gt; -index d482da7121..0739dd48af 100644<br>
&gt; ---- a/bin/named/client.c<br>
&gt; -+++ b/bin/named/client.c<br>
&gt; -@@ -421,8 +421,19 @@ exit_check(ns_client_t *client) {<br>
&gt; -                     isc_socket_detach(&amp;client-&gt;tcpsocket);<br>
&gt; -             }<br>
&gt; - <br>
&gt; --            if (client-&gt;tcpquota != NULL)<br>
&gt; -+            if (client-&gt;tcpquota != NULL) {<br>
&gt; -                     isc_quota_detach(&amp;client-&gt;tcpquota);<br>
&gt; -+            } else {<br>
&gt; -+                    /*<br>
&gt; -+                     * We went over quota with this client, we don&#39;t<br>
&gt; -+                     * want to restart listening unless this is the<br>
&gt; -+                     * last client on this interface, which is<br>
&gt; -+                     * checked later.<br>
&gt; -+                     */<br>
&gt; -+                    if (TCP_CLIENT(client)) {<br>
&gt; -+                            client-&gt;mortal = true;<br>
&gt; -+                    }<br>
&gt; -+            }<br>
&gt; - <br>
&gt; -             if (client-&gt;timerset) {<br>
&gt; -                     (void)isc_timer_reset(client-&gt;timer,<br>
&gt; --- <br>
&gt; -2.20.1<br>
&gt; -<br>
&gt; diff --git a/meta/recipes-connectivity/bind/bind/0001-gen.c-extend-DIRNAMESIZE-from-256-to-512.patch b/meta/recipes-connectivity/bind/bind/0001-gen.c-extend-DIRNAMESIZE-from-256-to-512.patch<br>
&gt; deleted file mode 100644<br>
&gt; index a8d601dcaa7..00000000000<br>
&gt; --- a/meta/recipes-connectivity/bind/bind/0001-gen.c-extend-DIRNAMESIZE-from-256-to-512.patch<br>
&gt; +++ /dev/null<br>
&gt; @@ -1,22 +0,0 @@<br>
&gt; -Upstream-Status: Pending<br>
&gt; -<br>
&gt; -Subject: gen.c: extend DIRNAMESIZE from 256 to 512<br>
&gt; -<br>
&gt; -Signed-off-by: Chen Qi &lt;<a href="mailto:Qi.Chen@windriver.com" target="_blank">Qi.Chen@windriver.com</a>&gt;<br>
&gt; ----<br>
&gt; - lib/dns/gen.c | 2 +-<br>
&gt; - 1 file changed, 1 insertion(+), 1 deletion(-)<br>
&gt; -<br>
&gt; -Index: bind-9.11.3/lib/dns/gen.c<br>
&gt; -===================================================================<br>
&gt; ---- bind-9.11.3.orig/lib/dns/gen.c<br>
&gt; -+++ bind-9.11.3/lib/dns/gen.c<br>
&gt; -@@ -130,7 +130,7 @@ static const char copyright[] =<br>
&gt; - #define TYPECLASSBUF (TYPECLASSLEN + 1)<br>
&gt; - #define TYPECLASSFMT &quot;%&quot; STR(TYPECLASSLEN) &quot;[-0-9a-z]_%d&quot;<br>
&gt; - #define ATTRIBUTESIZE 256<br>
&gt; --#define DIRNAMESIZE 256<br>
&gt; -+#define DIRNAMESIZE 512<br>
&gt; - <br>
&gt; - static struct cc {<br>
&gt; -     struct cc *next;<br>
&gt; diff --git a/meta/recipes-connectivity/bind/bind/0001-lib-dns-gen.c-fix-too-long-error.patch b/meta/recipes-connectivity/bind/bind/0001-lib-dns-gen.c-fix-too-long-error.patch<br>
&gt; deleted file mode 100644<br>
&gt; index 01874a44076..00000000000<br>
&gt; --- a/meta/recipes-connectivity/bind/bind/0001-lib-dns-gen.c-fix-too-long-error.patch<br>
&gt; +++ /dev/null<br>
&gt; @@ -1,31 +0,0 @@<br>
&gt; -From 5bc3167a8b714ec0c4a3f1c7f3b9411296ec0a23 Mon Sep 17 00:00:00 2001<br>
&gt; -From: Robert Yang &lt;<a href="mailto:liezhi.yang@windriver.com" target="_blank">liezhi.yang@windriver.com</a>&gt;<br>
&gt; -Date: Wed, 16 Sep 2015 20:23:47 -0700<br>
&gt; -Subject: [PATCH] lib/dns/gen.c: fix too long error<br>
&gt; -<br>
&gt; -The 512 is a little short when build in deep dir, and cause &quot;too long&quot;<br>
&gt; -error, use PATH_MAX if defined.<br>
&gt; -<br>
&gt; -Upstream-Status: Pending<br>
&gt; -<br>
&gt; -Signed-off-by: Robert Yang &lt;<a href="mailto:liezhi.yang@windriver.com" target="_blank">liezhi.yang@windriver.com</a>&gt;<br>
&gt; ----<br>
&gt; - lib/dns/gen.c |    4 ++++<br>
&gt; - 1 file changed, 4 insertions(+)<br>
&gt; -<br>
&gt; -Index: bind-9.11.3/lib/dns/gen.c<br>
&gt; -===================================================================<br>
&gt; ---- bind-9.11.3.orig/lib/dns/gen.c<br>
&gt; -+++ bind-9.11.3/lib/dns/gen.c<br>
&gt; -@@ -130,7 +130,11 @@ static const char copyright[] =<br>
&gt; - #define TYPECLASSBUF (TYPECLASSLEN + 1)<br>
&gt; - #define TYPECLASSFMT &quot;%&quot; STR(TYPECLASSLEN) &quot;[-0-9a-z]_%d&quot;<br>
&gt; - #define ATTRIBUTESIZE 256<br>
&gt; -+#ifdef PATH_MAX<br>
&gt; -+#define DIRNAMESIZE PATH_MAX<br>
&gt; -+#else<br>
&gt; - #define DIRNAMESIZE 512<br>
&gt; -+#endif<br>
&gt; - <br>
&gt; - static struct cc {<br>
&gt; -     struct cc *next;<br>
&gt; diff --git a/meta/recipes-connectivity/bind/bind/0002-tcp-clients-could-still-be-exceeded-v2.patch b/meta/recipes-connectivity/bind/bind/0002-tcp-clients-could-still-be-exceeded-v2.patch<br>
&gt; deleted file mode 100644<br>
&gt; index ca4e8b1a662..00000000000<br>
&gt; --- a/meta/recipes-connectivity/bind/bind/0002-tcp-clients-could-still-be-exceeded-v2.patch<br>
&gt; +++ /dev/null<br>
&gt; @@ -1,670 +0,0 @@<br>
&gt; -Backport patch to fix CVE-2018-5743.<br>
&gt; -<br>
&gt; -Ref:<br>
&gt; -<a href="https://security-tracker.debian.org/tracker/CVE-2018-5743" rel="noreferrer" target="_blank">https://security-tracker.debian.org/tracker/CVE-2018-5743</a><br>
&gt; -<br>
&gt; -CVE: CVE-2018-5743<br>
&gt; -Upstream-Status: Backport [<a href="https://gitlab.isc.org/isc-projects/bind9/commit/719f604" rel="noreferrer" target="_blank">https://gitlab.isc.org/isc-projects/bind9/commit/719f604</a>]<br>
&gt; -<br>
&gt; -Signed-off-by: Kai Kang &lt;<a href="mailto:kai.kang@windriver.com" target="_blank">kai.kang@windriver.com</a>&gt;<br>
&gt; -<br>
&gt; -From 719f604e3fad5b7479bd14e2fa0ef4413f0a8fdc Mon Sep 17 00:00:00 2001<br>
&gt; -From: =?UTF-8?q?Witold=20Kr=C4=99cicki?= &lt;<a href="mailto:wpk@isc.org" target="_blank">wpk@isc.org</a>&gt;<br>
&gt; -Date: Fri, 4 Jan 2019 12:50:51 +0100<br>
&gt; -Subject: [PATCH 2/6] tcp-clients could still be exceeded (v2)<br>
&gt; -<br>
&gt; -the TCP client quota could still be ineffective under some<br>
&gt; -circumstances.  this change:<br>
&gt; -<br>
&gt; -- improves quota accounting to ensure that TCP clients are<br>
&gt; -  properly limited, while still guaranteeing that at least one client<br>
&gt; -  is always available to serve TCP connections on each interface.<br>
&gt; -- uses more descriptive names and removes one (ntcptarget) that<br>
&gt; -  was no longer needed<br>
&gt; -- adds comments<br>
&gt; -<br>
&gt; -(cherry picked from commit 924651f1d5e605cd186d03f4f7340bcc54d77cc2)<br>
&gt; -(cherry picked from commit 55a7a458e30e47874d34bdf1079eb863a0512396)<br>
&gt; ----<br>
&gt; - bin/named/client.c                     | 311 ++++++++++++++++++++-----<br>
&gt; - bin/named/include/named/client.h       |  14 +-<br>
&gt; - bin/named/include/named/interfacemgr.h |  11 +-<br>
&gt; - bin/named/interfacemgr.c               |   8 +-<br>
&gt; - 4 files changed, 267 insertions(+), 77 deletions(-)<br>
&gt; -<br>
&gt; -diff --git a/bin/named/client.c b/bin/named/client.c<br>
&gt; -index 0739dd48af..a7b49a0f71 100644<br>
&gt; ---- a/bin/named/client.c<br>
&gt; -+++ b/bin/named/client.c<br>
&gt; -@@ -246,10 +246,11 @@ static void ns_client_dumpmessage(ns_client_t *client, const char *reason);<br>
&gt; - static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,<br>
&gt; -                            dns_dispatch_t *disp, bool tcp);<br>
&gt; - static isc_result_t get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp,<br>
&gt; --                           isc_socket_t *sock);<br>
&gt; -+                           isc_socket_t *sock, ns_client_t *oldclient);<br>
&gt; - static inline bool<br>
&gt; --allowed(isc_netaddr_t *addr, dns_name_t *signer, isc_netaddr_t *ecs_addr,<br>
&gt; --    uint8_t ecs_addrlen, uint8_t *ecs_scope, dns_acl_t *acl);<br>
&gt; -+allowed(isc_netaddr_t *addr, dns_name_t *signer,<br>
&gt; -+    isc_netaddr_t *ecs_addr, uint8_t ecs_addrlen,<br>
&gt; -+    uint8_t *ecs_scope, dns_acl_t *acl)<br>
&gt; - static void compute_cookie(ns_client_t *client, uint32_t when,<br>
&gt; -                        uint32_t nonce, const unsigned char *secret,<br>
&gt; -                        isc_buffer_t *buf);<br>
&gt; -@@ -405,8 +406,11 @@ exit_check(ns_client_t *client) {<br>
&gt; -              */<br>
&gt; -             INSIST(client-&gt;recursionquota == NULL);<br>
&gt; -             INSIST(client-&gt;newstate &lt;= NS_CLIENTSTATE_READY);<br>
&gt; --            if (client-&gt;nreads &gt; 0)<br>
&gt; -+<br>
&gt; -+            if (client-&gt;nreads &gt; 0) {<br>
&gt; -                     dns_tcpmsg_cancelread(&amp;client-&gt;tcpmsg);<br>
&gt; -+            }<br>
&gt; -+<br>
&gt; -             if (client-&gt;nreads != 0) {<br>
&gt; -                     /* Still waiting for read cancel completion. */<br>
&gt; -                     return (true);<br>
&gt; -@@ -416,25 +420,58 @@ exit_check(ns_client_t *client) {<br>
&gt; -                     dns_tcpmsg_invalidate(&amp;client-&gt;tcpmsg);<br>
&gt; -                     client-&gt;tcpmsg_valid = false;<br>
&gt; -             }<br>
&gt; -+<br>
&gt; -             if (client-&gt;tcpsocket != NULL) {<br>
&gt; -                     CTRACE(&quot;closetcp&quot;);<br>
&gt; -                     isc_socket_detach(&amp;client-&gt;tcpsocket);<br>
&gt; -+<br>
&gt; -+                    if (client-&gt;tcpactive) {<br>
&gt; -+                            LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+                            INSIST(client-&gt;interface-&gt;ntcpactive &gt; 0);<br>
&gt; -+                            client-&gt;interface-&gt;ntcpactive--;<br>
&gt; -+                            UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+                            client-&gt;tcpactive = false;<br>
&gt; -+                    }<br>
&gt; -             }<br>
&gt; - <br>
&gt; -             if (client-&gt;tcpquota != NULL) {<br>
&gt; --                    isc_quota_detach(&amp;client-&gt;tcpquota);<br>
&gt; --            } else {<br>
&gt; -                     /*<br>
&gt; --                     * We went over quota with this client, we don&#39;t<br>
&gt; --                     * want to restart listening unless this is the<br>
&gt; --                     * last client on this interface, which is<br>
&gt; --                     * checked later.<br>
&gt; -+                     * If we are not in a pipeline group, or<br>
&gt; -+                     * we are the last client in the group, detach from<br>
&gt; -+                     * tcpquota; otherwise, transfer the quota to<br>
&gt; -+                     * another client in the same group.<br>
&gt; -                      */<br>
&gt; --                    if (TCP_CLIENT(client)) {<br>
&gt; --                            client-&gt;mortal = true;<br>
&gt; -+                    if (!ISC_LINK_LINKED(client, glink) ||<br>
&gt; -+                        (client-&gt;glink.next == NULL &amp;&amp;<br>
&gt; -+                         client-&gt;glink.prev == NULL))<br>
&gt; -+                    {<br>
&gt; -+                            isc_quota_detach(&amp;client-&gt;tcpquota);<br>
&gt; -+                    } else if (client-&gt;glink.next != NULL) {<br>
&gt; -+                            INSIST(client-&gt;glink.next-&gt;tcpquota == NULL);<br>
&gt; -+                            client-&gt;glink.next-&gt;tcpquota = client-&gt;tcpquota;<br>
&gt; -+                            client-&gt;tcpquota = NULL;<br>
&gt; -+                    } else {<br>
&gt; -+                            INSIST(client-&gt;glink.prev-&gt;tcpquota == NULL);<br>
&gt; -+                            client-&gt;glink.prev-&gt;tcpquota = client-&gt;tcpquota;<br>
&gt; -+                            client-&gt;tcpquota = NULL;<br>
&gt; -                     }<br>
&gt; -             }<br>
&gt; - <br>
&gt; -+            /*<br>
&gt; -+             * Unlink from pipeline group.<br>
&gt; -+             */<br>
&gt; -+            if (ISC_LINK_LINKED(client, glink)) {<br>
&gt; -+                    if (client-&gt;glink.next != NULL) {<br>
&gt; -+                            client-&gt;glink.next-&gt;glink.prev =<br>
&gt; -+                                    client-&gt;glink.prev;<br>
&gt; -+                    }<br>
&gt; -+                    if (client-&gt;glink.prev != NULL) {<br>
&gt; -+                            client-&gt;glink.prev-&gt;glink.next =<br>
&gt; -+                                    client-&gt;glink.next;<br>
&gt; -+                    }<br>
&gt; -+                    ISC_LINK_INIT(client, glink);<br>
&gt; -+            }<br>
&gt; -+<br>
&gt; -             if (client-&gt;timerset) {<br>
&gt; -                     (void)isc_timer_reset(client-&gt;timer,<br>
&gt; -                                           isc_timertype_inactive,<br>
&gt; -@@ -455,15 +492,16 @@ exit_check(ns_client_t *client) {<br>
&gt; -              * that already.  Check whether this client needs to remain<br>
&gt; -              * active and force it to go inactive if not.<br>
&gt; -              *<br>
&gt; --             * UDP clients go inactive at this point, but TCP clients<br>
&gt; --             * may remain active if we have fewer active TCP client<br>
&gt; --             * objects than desired due to an earlier quota exhaustion.<br>
&gt; -+             * UDP clients go inactive at this point, but a TCP client<br>
&gt; -+             * will needs to remain active if no other clients are<br>
&gt; -+             * listening for TCP requests on this interface, to<br>
&gt; -+             * prevent this interface from going nonresponsive.<br>
&gt; -              */<br>
&gt; -             if (client-&gt;mortal &amp;&amp; TCP_CLIENT(client) &amp;&amp; !ns_g_clienttest) {<br>
&gt; -                     LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --                    if (client-&gt;interface-&gt;ntcpcurrent &lt;<br>
&gt; --                                client-&gt;interface-&gt;ntcptarget)<br>
&gt; -+                    if (client-&gt;interface-&gt;ntcpaccepting == 0) {<br>
&gt; -                             client-&gt;mortal = false;<br>
&gt; -+                    }<br>
&gt; -                     UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -             }<br>
&gt; - <br>
&gt; -@@ -472,15 +510,17 @@ exit_check(ns_client_t *client) {<br>
&gt; -              * queue for recycling.<br>
&gt; -              */<br>
&gt; -             if (client-&gt;mortal) {<br>
&gt; --                    if (client-&gt;newstate &gt; NS_CLIENTSTATE_INACTIVE)<br>
&gt; -+                    if (client-&gt;newstate &gt; NS_CLIENTSTATE_INACTIVE) {<br>
&gt; -                             client-&gt;newstate = NS_CLIENTSTATE_INACTIVE;<br>
&gt; -+                    }<br>
&gt; -             }<br>
&gt; - <br>
&gt; -             if (NS_CLIENTSTATE_READY == client-&gt;newstate) {<br>
&gt; -                     if (TCP_CLIENT(client)) {<br>
&gt; -                             client_accept(client);<br>
&gt; --                    } else<br>
&gt; -+                    } else {<br>
&gt; -                             client_udprecv(client);<br>
&gt; -+                    }<br>
&gt; -                     client-&gt;newstate = NS_CLIENTSTATE_MAX;<br>
&gt; -                     return (true);<br>
&gt; -             }<br>
&gt; -@@ -492,41 +532,57 @@ exit_check(ns_client_t *client) {<br>
&gt; -             /*<br>
&gt; -              * We are trying to enter the inactive state.<br>
&gt; -              */<br>
&gt; --            if (client-&gt;naccepts &gt; 0)<br>
&gt; -+            if (client-&gt;naccepts &gt; 0) {<br>
&gt; -                     isc_socket_cancel(client-&gt;tcplistener, client-&gt;task,<br>
&gt; -                                       ISC_SOCKCANCEL_ACCEPT);<br>
&gt; -+            }<br>
&gt; - <br>
&gt; -             /* Still waiting for accept cancel completion. */<br>
&gt; --            if (! (client-&gt;naccepts == 0))<br>
&gt; -+            if (! (client-&gt;naccepts == 0)) {<br>
&gt; -                     return (true);<br>
&gt; -+            }<br>
&gt; - <br>
&gt; -             /* Accept cancel is complete. */<br>
&gt; --            if (client-&gt;nrecvs &gt; 0)<br>
&gt; -+            if (client-&gt;nrecvs &gt; 0) {<br>
&gt; -                     isc_socket_cancel(client-&gt;udpsocket, client-&gt;task,<br>
&gt; -                                       ISC_SOCKCANCEL_RECV);<br>
&gt; -+            }<br>
&gt; - <br>
&gt; -             /* Still waiting for recv cancel completion. */<br>
&gt; --            if (! (client-&gt;nrecvs == 0))<br>
&gt; -+            if (! (client-&gt;nrecvs == 0)) {<br>
&gt; -                     return (true);<br>
&gt; -+            }<br>
&gt; - <br>
&gt; -             /* Still waiting for control event to be delivered */<br>
&gt; --            if (client-&gt;nctls &gt; 0)<br>
&gt; -+            if (client-&gt;nctls &gt; 0) {<br>
&gt; -                     return (true);<br>
&gt; --<br>
&gt; --            /* Deactivate the client. */<br>
&gt; --            if (client-&gt;interface)<br>
&gt; --                    ns_interface_detach(&amp;client-&gt;interface);<br>
&gt; -+            }<br>
&gt; - <br>
&gt; -             INSIST(client-&gt;naccepts == 0);<br>
&gt; -             INSIST(client-&gt;recursionquota == NULL);<br>
&gt; --            if (client-&gt;tcplistener != NULL)<br>
&gt; -+            if (client-&gt;tcplistener != NULL) {<br>
&gt; -                     isc_socket_detach(&amp;client-&gt;tcplistener);<br>
&gt; - <br>
&gt; --            if (client-&gt;udpsocket != NULL)<br>
&gt; -+                    if (client-&gt;tcpactive) {<br>
&gt; -+                            LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+                            INSIST(client-&gt;interface-&gt;ntcpactive &gt; 0);<br>
&gt; -+                            client-&gt;interface-&gt;ntcpactive--;<br>
&gt; -+                            UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+                            client-&gt;tcpactive = false;<br>
&gt; -+                    }<br>
&gt; -+            }<br>
&gt; -+            if (client-&gt;udpsocket != NULL) {<br>
&gt; -                     isc_socket_detach(&amp;client-&gt;udpsocket);<br>
&gt; -+            }<br>
&gt; - <br>
&gt; --            if (client-&gt;dispatch != NULL)<br>
&gt; -+            /* Deactivate the client. */<br>
&gt; -+            if (client-&gt;interface != NULL) {<br>
&gt; -+                    ns_interface_detach(&amp;client-&gt;interface);<br>
&gt; -+            }<br>
&gt; -+<br>
&gt; -+            if (client-&gt;dispatch != NULL) {<br>
&gt; -                     dns_dispatch_detach(&amp;client-&gt;dispatch);<br>
&gt; -+            }<br>
&gt; - <br>
&gt; -             client-&gt;attributes = 0;<br>
&gt; -             client-&gt;mortal = false;<br>
&gt; -@@ -551,10 +607,13 @@ exit_check(ns_client_t *client) {<br>
&gt; -                     client-&gt;newstate = NS_CLIENTSTATE_MAX;<br>
&gt; -                     if (!ns_g_clienttest &amp;&amp; manager != NULL &amp;&amp;<br>
&gt; -                         !manager-&gt;exiting)<br>
&gt; -+                    {<br>
&gt; -                             ISC_QUEUE_PUSH(manager-&gt;inactive, client,<br>
&gt; -                                            ilink);<br>
&gt; --                    if (client-&gt;needshutdown)<br>
&gt; -+                    }<br>
&gt; -+                    if (client-&gt;needshutdown) {<br>
&gt; -                             isc_task_shutdown(client-&gt;task);<br>
&gt; -+                    }<br>
&gt; -                     return (true);<br>
&gt; -             }<br>
&gt; -     }<br>
&gt; -@@ -675,7 +734,6 @@ client_start(isc_task_t *task, isc_event_t *event) {<br>
&gt; -     }<br>
&gt; - }<br>
&gt; - <br>
&gt; --<br>
&gt; - /*%<br>
&gt; -  * The client&#39;s task has received a shutdown event.<br>
&gt; -  */<br>
&gt; -@@ -2507,17 +2565,12 @@ client_request(isc_task_t *task, isc_event_t *event) {<br>
&gt; -     /*<br>
&gt; -      * Pipeline TCP query processing.<br>
&gt; -      */<br>
&gt; --    if (client-&gt;message-&gt;opcode != dns_opcode_query)<br>
&gt; -+    if (client-&gt;message-&gt;opcode != dns_opcode_query) {<br>
&gt; -             client-&gt;pipelined = false;<br>
&gt; -+    }<br>
&gt; -     if (TCP_CLIENT(client) &amp;&amp; client-&gt;pipelined) {<br>
&gt; --            result = isc_quota_reserve(&amp;ns_g_server-&gt;tcpquota);<br>
&gt; --            if (result == ISC_R_SUCCESS)<br>
&gt; --                    result = ns_client_replace(client);<br>
&gt; -+            result = ns_client_replace(client);<br>
&gt; -             if (result != ISC_R_SUCCESS) {<br>
&gt; --                    ns_client_log(client, NS_LOGCATEGORY_CLIENT,<br>
&gt; --                                  NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,<br>
&gt; --                                  &quot;no more TCP clients(read): %s&quot;,<br>
&gt; --                                  isc_result_totext(result));<br>
&gt; -                     client-&gt;pipelined = false;<br>
&gt; -             }<br>
&gt; -     }<br>
&gt; -@@ -3087,6 +3140,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {<br>
&gt; -     client-&gt;filter_aaaa = dns_aaaa_ok;<br>
&gt; - #endif<br>
&gt; -     client-&gt;needshutdown = ns_g_clienttest;<br>
&gt; -+    client-&gt;tcpactive = false;<br>
&gt; - <br>
&gt; -     ISC_EVENT_INIT(&amp;client-&gt;ctlevent, sizeof(client-&gt;ctlevent), 0, NULL,<br>
&gt; -                    NS_EVENT_CLIENTCONTROL, client_start, client, client,<br>
&gt; -@@ -3100,6 +3154,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {<br>
&gt; -     client-&gt;<a href="http://formerrcache.id" rel="noreferrer" target="_blank">formerrcache.id</a> = 0;<br>
&gt; -     ISC_LINK_INIT(client, link);<br>
&gt; -     ISC_LINK_INIT(client, rlink);<br>
&gt; -+    ISC_LINK_INIT(client, glink);<br>
&gt; -     ISC_QLINK_INIT(client, ilink);<br>
&gt; -     client-&gt;keytag = NULL;<br>
&gt; -     client-&gt;keytag_len = 0;<br>
&gt; -@@ -3193,12 +3248,19 @@ client_newconn(isc_task_t *task, isc_event_t *event) {<br>
&gt; - <br>
&gt; -     INSIST(client-&gt;state == NS_CLIENTSTATE_READY);<br>
&gt; - <br>
&gt; -+    /*<br>
&gt; -+     * The accept() was successful and we&#39;re now establishing a new<br>
&gt; -+     * connection. We need to make note of it in the client and<br>
&gt; -+     * interface objects so client objects can do the right thing<br>
&gt; -+     * when going inactive in exit_check() (see comments in<br>
&gt; -+     * client_accept() for details).<br>
&gt; -+     */<br>
&gt; -     INSIST(client-&gt;naccepts == 1);<br>
&gt; -     client-&gt;naccepts--;<br>
&gt; - <br>
&gt; -     LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --    INSIST(client-&gt;interface-&gt;ntcpcurrent &gt; 0);<br>
&gt; --    client-&gt;interface-&gt;ntcpcurrent--;<br>
&gt; -+    INSIST(client-&gt;interface-&gt;ntcpaccepting &gt; 0);<br>
&gt; -+    client-&gt;interface-&gt;ntcpaccepting--;<br>
&gt; -     UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; - <br>
&gt; -     /*<br>
&gt; -@@ -3232,6 +3294,9 @@ client_newconn(isc_task_t *task, isc_event_t *event) {<br>
&gt; -                           NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),<br>
&gt; -                           &quot;accept failed: %s&quot;,<br>
&gt; -                           isc_result_totext(nevent-&gt;result));<br>
&gt; -+            if (client-&gt;tcpquota != NULL) {<br>
&gt; -+                    isc_quota_detach(&amp;client-&gt;tcpquota);<br>
&gt; -+            }<br>
&gt; -     }<br>
&gt; - <br>
&gt; -     if (exit_check(client))<br>
&gt; -@@ -3270,18 +3335,12 @@ client_newconn(isc_task_t *task, isc_event_t *event) {<br>
&gt; -              * deny service to legitimate TCP clients.<br>
&gt; -              */<br>
&gt; -             client-&gt;pipelined = false;<br>
&gt; --            result = isc_quota_attach(&amp;ns_g_server-&gt;tcpquota,<br>
&gt; --                                      &amp;client-&gt;tcpquota);<br>
&gt; --            if (result == ISC_R_SUCCESS)<br>
&gt; --                    result = ns_client_replace(client);<br>
&gt; --            if (result != ISC_R_SUCCESS) {<br>
&gt; --                    ns_client_log(client, NS_LOGCATEGORY_CLIENT,<br>
&gt; --                                  NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,<br>
&gt; --                                  &quot;no more TCP clients(accept): %s&quot;,<br>
&gt; --                                  isc_result_totext(result));<br>
&gt; --            } else if (ns_g_server-&gt;keepresporder == NULL ||<br>
&gt; --                       !allowed(&amp;netaddr, NULL, NULL, 0, NULL,<br>
&gt; --                                ns_g_server-&gt;keepresporder)) {<br>
&gt; -+            result = ns_client_replace(client);<br>
&gt; -+            if (result == ISC_R_SUCCESS &amp;&amp;<br>
&gt; -+                (client-&gt;sctx-&gt;keepresporder == NULL ||<br>
&gt; -+                 !allowed(&amp;netaddr, NULL, NULL, 0, NULL,<br>
&gt; -+                          ns_g_server-&gt;keepresporder)))<br>
&gt; -+            {<br>
&gt; -                     client-&gt;pipelined = true;<br>
&gt; -             }<br>
&gt; - <br>
&gt; -@@ -3298,12 +3357,80 @@ client_accept(ns_client_t *client) {<br>
&gt; - <br>
&gt; -     CTRACE(&quot;accept&quot;);<br>
&gt; - <br>
&gt; -+    /*<br>
&gt; -+     * The tcpquota object can only be simultaneously referenced a<br>
&gt; -+     * pre-defined number of times; this is configured by &#39;tcp-clients&#39;<br>
&gt; -+     * in named.conf. If we can&#39;t attach to it here, that means the TCP<br>
&gt; -+     * client quota has been exceeded.<br>
&gt; -+     */<br>
&gt; -+    result = isc_quota_attach(&amp;client-&gt;sctx-&gt;tcpquota,<br>
&gt; -+                              &amp;client-&gt;tcpquota);<br>
&gt; -+    if (result != ISC_R_SUCCESS) {<br>
&gt; -+                    bool exit;<br>
&gt; -+<br>
&gt; -+                    ns_client_log(client, NS_LOGCATEGORY_CLIENT,<br>
&gt; -+                                  NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),<br>
&gt; -+                                  &quot;no more TCP clients: %s&quot;,<br>
&gt; -+                                  isc_result_totext(result));<br>
&gt; -+<br>
&gt; -+                    /*<br>
&gt; -+                     * We have exceeded the system-wide TCP client<br>
&gt; -+                     * quota.  But, we can&#39;t just block this accept<br>
&gt; -+                     * in all cases, because if we did, a heavy TCP<br>
&gt; -+                     * load on other interfaces might cause this<br>
&gt; -+                     * interface to be starved, with no clients able<br>
&gt; -+                     * to accept new connections.<br>
&gt; -+                     *<br>
&gt; -+                     * So, we check here to see if any other client<br>
&gt; -+                     * is already servicing TCP queries on this<br>
&gt; -+                     * interface (whether accepting, reading, or<br>
&gt; -+                     * processing).<br>
&gt; -+                     *<br>
&gt; -+                     * If so, then it&#39;s okay *not* to call<br>
&gt; -+                     * accept - we can let this client to go inactive<br>
&gt; -+                     * and the other one handle the next connection<br>
&gt; -+                     * when it&#39;s ready.<br>
&gt; -+                     *<br>
&gt; -+                     * But if not, then we need to be a little bit<br>
&gt; -+                     * flexible about the quota. We allow *one* extra<br>
&gt; -+                     * TCP client through, to ensure we&#39;re listening on<br>
&gt; -+                     * every interface.<br>
&gt; -+                     *<br>
&gt; -+                     * (Note: In practice this means that the *real*<br>
&gt; -+                     * TCP client quota is tcp-clients plus the number<br>
&gt; -+                     * of interfaces.)<br>
&gt; -+                     */<br>
&gt; -+                    LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+                    exit = (client-&gt;interface-&gt;ntcpactive &gt; 0);<br>
&gt; -+                    UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+<br>
&gt; -+                    if (exit) {<br>
&gt; -+                            client-&gt;newstate = NS_CLIENTSTATE_INACTIVE;<br>
&gt; -+                            (void)exit_check(client);<br>
&gt; -+                            return;<br>
&gt; -+                    }<br>
&gt; -+    }<br>
&gt; -+<br>
&gt; -+    /*<br>
&gt; -+     * By incrementing the interface&#39;s ntcpactive counter we signal<br>
&gt; -+     * that there is at least one client servicing TCP queries for the<br>
&gt; -+     * interface.<br>
&gt; -+     *<br>
&gt; -+     * We also make note of the fact in the client itself with the<br>
&gt; -+     * tcpactive flag. This ensures proper accounting by preventing<br>
&gt; -+     * us from accidentally incrementing or decrementing ntcpactive<br>
&gt; -+     * more than once per client object.<br>
&gt; -+     */<br>
&gt; -+    if (!client-&gt;tcpactive) {<br>
&gt; -+            LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+            client-&gt;interface-&gt;ntcpactive++;<br>
&gt; -+            UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+            client-&gt;tcpactive = true;<br>
&gt; -+    }<br>
&gt; -+<br>
&gt; -     result = isc_socket_accept(client-&gt;tcplistener, client-&gt;task,<br>
&gt; -                                client_newconn, client);<br>
&gt; -     if (result != ISC_R_SUCCESS) {<br>
&gt; --            UNEXPECTED_ERROR(__FILE__, __LINE__,<br>
&gt; --                             &quot;isc_socket_accept() failed: %s&quot;,<br>
&gt; --                             isc_result_totext(result));<br>
&gt; -             /*<br>
&gt; -              * XXXRTH  What should we do?  We&#39;re trying to accept but<br>
&gt; -              *         it didn&#39;t work.  If we just give up, then TCP<br>
&gt; -@@ -3311,12 +3438,39 @@ client_accept(ns_client_t *client) {<br>
&gt; -              *<br>
&gt; -              *         For now, we just go idle.<br>
&gt; -              */<br>
&gt; -+            UNEXPECTED_ERROR(__FILE__, __LINE__,<br>
&gt; -+                             &quot;isc_socket_accept() failed: %s&quot;,<br>
&gt; -+                             isc_result_totext(result));<br>
&gt; -+            if (client-&gt;tcpquota != NULL) {<br>
&gt; -+                    isc_quota_detach(&amp;client-&gt;tcpquota);<br>
&gt; -+            }<br>
&gt; -             return;<br>
&gt; -     }<br>
&gt; -+<br>
&gt; -+    /*<br>
&gt; -+     * The client&#39;s &#39;naccepts&#39; counter indicates that this client has<br>
&gt; -+     * called accept() and is waiting for a new connection. It should<br>
&gt; -+     * never exceed 1.<br>
&gt; -+     */<br>
&gt; -     INSIST(client-&gt;naccepts == 0);<br>
&gt; -     client-&gt;naccepts++;<br>
&gt; -+<br>
&gt; -+    /*<br>
&gt; -+     * The interface&#39;s &#39;ntcpaccepting&#39; counter is incremented when<br>
&gt; -+     * any client calls accept(), and decremented in client_newconn()<br>
&gt; -+     * once the connection is established.<br>
&gt; -+     *<br>
&gt; -+     * When the client object is shutting down after handling a TCP<br>
&gt; -+     * request (see exit_check()), it looks to see whether this value is<br>
&gt; -+     * non-zero. If so, that means another client has already called<br>
&gt; -+     * accept() and is waiting to establish the next connection, which<br>
&gt; -+     * means the first client is free to go inactive. Otherwise,<br>
&gt; -+     * the first client must come back and call accept() again; this<br>
&gt; -+     * guarantees there will always be at least one client listening<br>
&gt; -+     * for new TCP connections on each interface.<br>
&gt; -+     */<br>
&gt; -     LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --    client-&gt;interface-&gt;ntcpcurrent++;<br>
&gt; -+    client-&gt;interface-&gt;ntcpaccepting++;<br>
&gt; -     UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; - }<br>
&gt; - <br>
&gt; -@@ -3390,13 +3544,14 @@ ns_client_replace(ns_client_t *client) {<br>
&gt; -     tcp = TCP_CLIENT(client);<br>
&gt; -     if (tcp &amp;&amp; client-&gt;pipelined) {<br>
&gt; -             result = get_worker(client-&gt;manager, client-&gt;interface,<br>
&gt; --                                client-&gt;tcpsocket);<br>
&gt; -+                                client-&gt;tcpsocket, client);<br>
&gt; -     } else {<br>
&gt; -             result = get_client(client-&gt;manager, client-&gt;interface,<br>
&gt; -                                 client-&gt;dispatch, tcp);<br>
&gt; -     }<br>
&gt; --    if (result != ISC_R_SUCCESS)<br>
&gt; -+    if (result != ISC_R_SUCCESS) {<br>
&gt; -             return (result);<br>
&gt; -+    }<br>
&gt; - <br>
&gt; -     /*<br>
&gt; -      * The responsibility for listening for new requests is hereby<br>
&gt; -@@ -3585,6 +3740,7 @@ get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,<br>
&gt; -             client-&gt;attributes |= NS_CLIENTATTR_TCP;<br>
&gt; -             isc_socket_attach(ifp-&gt;tcpsocket,<br>
&gt; -                               &amp;client-&gt;tcplistener);<br>
&gt; -+<br>
&gt; -     } else {<br>
&gt; -             isc_socket_t *sock;<br>
&gt; - <br>
&gt; -@@ -3602,7 +3758,8 @@ get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,<br>
&gt; - }<br>
&gt; - <br>
&gt; - static isc_result_t<br>
&gt; --get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock)<br>
&gt; -+get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock,<br>
&gt; -+       ns_client_t *oldclient)<br>
&gt; - {<br>
&gt; -     isc_result_t result = ISC_R_SUCCESS;<br>
&gt; -     isc_event_t *ev;<br>
&gt; -@@ -3610,6 +3767,7 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock)<br>
&gt; -     MTRACE(&quot;get worker&quot;);<br>
&gt; - <br>
&gt; -     REQUIRE(manager != NULL);<br>
&gt; -+    REQUIRE(oldclient != NULL);<br>
&gt; - <br>
&gt; -     if (manager-&gt;exiting)<br>
&gt; -             return (ISC_R_SHUTTINGDOWN);<br>
&gt; -@@ -3642,7 +3800,28 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock)<br>
&gt; -     ns_interface_attach(ifp, &amp;client-&gt;interface);<br>
&gt; -     client-&gt;newstate = client-&gt;state = NS_CLIENTSTATE_WORKING;<br>
&gt; -     INSIST(client-&gt;recursionquota == NULL);<br>
&gt; --    client-&gt;tcpquota = &amp;ns_g_server-&gt;tcpquota;<br>
&gt; -+<br>
&gt; -+    /*<br>
&gt; -+     * Transfer TCP quota to the new client.<br>
&gt; -+     */<br>
&gt; -+    INSIST(client-&gt;tcpquota == NULL);<br>
&gt; -+    INSIST(oldclient-&gt;tcpquota != NULL);<br>
&gt; -+    client-&gt;tcpquota = oldclient-&gt;tcpquota;<br>
&gt; -+    oldclient-&gt;tcpquota = NULL;<br>
&gt; -+<br>
&gt; -+    /*<br>
&gt; -+     * Link to a pipeline group, creating it if needed.<br>
&gt; -+     */<br>
&gt; -+    if (!ISC_LINK_LINKED(oldclient, glink)) {<br>
&gt; -+            oldclient-&gt;glink.next = NULL;<br>
&gt; -+            oldclient-&gt;glink.prev = NULL;<br>
&gt; -+    }<br>
&gt; -+    client-&gt;glink.next = oldclient-&gt;glink.next;<br>
&gt; -+    client-&gt;glink.prev = oldclient;<br>
&gt; -+    if (oldclient-&gt;glink.next != NULL) {<br>
&gt; -+            oldclient-&gt;glink.next-&gt;glink.prev = client;<br>
&gt; -+    }<br>
&gt; -+    oldclient-&gt;glink.next = client;<br>
&gt; - <br>
&gt; -     client-&gt;dscp = ifp-&gt;dscp;<br>
&gt; - <br>
&gt; -@@ -3656,6 +3835,12 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock)<br>
&gt; -     (void)isc_socket_getpeername(client-&gt;tcpsocket, &amp;client-&gt;peeraddr);<br>
&gt; -     client-&gt;peeraddr_valid = true;<br>
&gt; - <br>
&gt; -+    LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+    client-&gt;interface-&gt;ntcpactive++;<br>
&gt; -+    UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+<br>
&gt; -+    client-&gt;tcpactive = true;<br>
&gt; -+<br>
&gt; -     INSIST(client-&gt;tcpmsg_valid == false);<br>
&gt; -     dns_tcpmsg_init(client-&gt;mctx, client-&gt;tcpsocket, &amp;client-&gt;tcpmsg);<br>
&gt; -     client-&gt;tcpmsg_valid = true;<br>
&gt; -diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h<br>
&gt; -index b23a7b191d..1f7973f9c5 100644<br>
&gt; ---- a/bin/named/include/named/client.h<br>
&gt; -+++ b/bin/named/include/named/client.h<br>
&gt; -@@ -94,7 +94,8 @@ struct ns_client {<br>
&gt; -     int                     nupdates;<br>
&gt; -     int                     nctls;<br>
&gt; -     int                     references;<br>
&gt; --    bool            needshutdown;   /*<br>
&gt; -+    bool                    tcpactive;<br>
&gt; -+    bool                    needshutdown;   /*<br>
&gt; -                                              * Used by clienttest to get<br>
&gt; -                                              * the client to go from<br>
&gt; -                                              * inactive to free state<br>
&gt; -@@ -130,9 +131,9 @@ struct ns_client {<br>
&gt; -     isc_stdtime_t           now;<br>
&gt; -     isc_time_t              tnow;<br>
&gt; -     dns_name_t              signername;   /*%&lt; [T]SIG key name */<br>
&gt; --    dns_name_t *            signer;       /*%&lt; NULL if not valid sig */<br>
&gt; --    bool            mortal;       /*%&lt; Die after handling request */<br>
&gt; --    bool            pipelined;   /*%&lt; TCP queries not in sequence */<br>
&gt; -+    dns_name_t              *signer;      /*%&lt; NULL if not valid sig */<br>
&gt; -+    bool                    mortal;       /*%&lt; Die after handling request */<br>
&gt; -+    bool                    pipelined;   /*%&lt; TCP queries not in sequence */<br>
&gt; -     isc_quota_t             *tcpquota;<br>
&gt; -     isc_quota_t             *recursionquota;<br>
&gt; -     ns_interface_t          *interface;<br>
&gt; -@@ -143,8 +144,8 @@ struct ns_client {<br>
&gt; -     isc_sockaddr_t          destsockaddr;<br>
&gt; - <br>
&gt; -     isc_netaddr_t           ecs_addr;       /*%&lt; EDNS client subnet */<br>
&gt; --    uint8_t         ecs_addrlen;<br>
&gt; --    uint8_t         ecs_scope;<br>
&gt; -+    uint8_t                 ecs_addrlen;<br>
&gt; -+    uint8_t                 ecs_scope;<br>
&gt; - <br>
&gt; -     struct in6_pktinfo      pktinfo;<br>
&gt; -     isc_dscp_t              dscp;<br>
&gt; -@@ -166,6 +167,7 @@ struct ns_client {<br>
&gt; - <br>
&gt; -     ISC_LINK(ns_client_t)   link;<br>
&gt; -     ISC_LINK(ns_client_t)   rlink;<br>
&gt; -+    ISC_LINK(ns_client_t)   glink;<br>
&gt; -     ISC_QLINK(ns_client_t)  ilink;<br>
&gt; -     unsigned char           cookie[8];<br>
&gt; -     uint32_t                expire;<br>
&gt; -diff --git a/bin/named/include/named/interfacemgr.h b/bin/named/include/named/interfacemgr.h<br>
&gt; -index 7d1883e1e8..61b08826a6 100644<br>
&gt; ---- a/bin/named/include/named/interfacemgr.h<br>
&gt; -+++ b/bin/named/include/named/interfacemgr.h<br>
&gt; -@@ -77,9 +77,14 @@ struct ns_interface {<br>
&gt; -                                             /*%&lt; UDP dispatchers. */<br>
&gt; -     isc_socket_t *          tcpsocket;      /*%&lt; TCP socket. */<br>
&gt; -     isc_dscp_t              dscp;           /*%&lt; &quot;listen-on&quot; DSCP value */<br>
&gt; --    int                     ntcptarget;     /*%&lt; Desired number of concurrent<br>
&gt; --                                                 TCP accepts */<br>
&gt; --    int                     ntcpcurrent;    /*%&lt; Current ditto, locked */<br>
&gt; -+    int                     ntcpaccepting;  /*%&lt; Number of clients<br>
&gt; -+                                                 ready to accept new<br>
&gt; -+                                                 TCP connections on this<br>
&gt; -+                                                 interface */<br>
&gt; -+    int                     ntcpactive;     /*%&lt; Number of clients<br>
&gt; -+                                                 servicing TCP queries<br>
&gt; -+                                                 (whether accepting or<br>
&gt; -+                                                 connected) */<br>
&gt; -     int                     nudpdispatch;   /*%&lt; Number of UDP dispatches */<br>
&gt; -     ns_clientmgr_t *        clientmgr;      /*%&lt; Client manager. */<br>
&gt; -     ISC_LINK(ns_interface_t) link;<br>
&gt; -diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c<br>
&gt; -index 419927bf54..955096ef47 100644<br>
&gt; ---- a/bin/named/interfacemgr.c<br>
&gt; -+++ b/bin/named/interfacemgr.c<br>
&gt; -@@ -386,8 +386,8 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,<br>
&gt; -      * connections will be handled in parallel even though there is<br>
&gt; -      * only one client initially.<br>
&gt; -      */<br>
&gt; --    ifp-&gt;ntcptarget = 1;<br>
&gt; --    ifp-&gt;ntcpcurrent = 0;<br>
&gt; -+    ifp-&gt;ntcpaccepting = 0;<br>
&gt; -+    ifp-&gt;ntcpactive = 0;<br>
&gt; -     ifp-&gt;nudpdispatch = 0;<br>
&gt; - <br>
&gt; -     ifp-&gt;dscp = -1;<br>
&gt; -@@ -522,9 +522,7 @@ ns_interface_accepttcp(ns_interface_t *ifp) {<br>
&gt; -      */<br>
&gt; -     (void)isc_socket_filter(ifp-&gt;tcpsocket, &quot;dataready&quot;);<br>
&gt; - <br>
&gt; --    result = ns_clientmgr_createclients(ifp-&gt;clientmgr,<br>
&gt; --                                        ifp-&gt;ntcptarget, ifp,<br>
&gt; --                                        true);<br>
&gt; -+    result = ns_clientmgr_createclients(ifp-&gt;clientmgr, 1, ifp, true);<br>
&gt; -     if (result != ISC_R_SUCCESS) {<br>
&gt; -             UNEXPECTED_ERROR(__FILE__, __LINE__,<br>
&gt; -                              &quot;TCP ns_clientmgr_createclients(): %s&quot;,<br>
&gt; --- <br>
&gt; -2.20.1<br>
&gt; -<br>
&gt; diff --git a/meta/recipes-connectivity/bind/bind/0003-use-reference-counter-for-pipeline-groups-v3.patch b/meta/recipes-connectivity/bind/bind/0003-use-reference-counter-for-pipeline-groups-v3.patch<br>
&gt; deleted file mode 100644<br>
&gt; index 032cfb8c442..00000000000<br>
&gt; --- a/meta/recipes-connectivity/bind/bind/0003-use-reference-counter-for-pipeline-groups-v3.patch<br>
&gt; +++ /dev/null<br>
&gt; @@ -1,278 +0,0 @@<br>
&gt; -Backport patch to fix CVE-2018-5743.<br>
&gt; -<br>
&gt; -Ref:<br>
&gt; -<a href="https://security-tracker.debian.org/tracker/CVE-2018-5743" rel="noreferrer" target="_blank">https://security-tracker.debian.org/tracker/CVE-2018-5743</a><br>
&gt; -<br>
&gt; -CVE: CVE-2018-5743<br>
&gt; -Upstream-Status: Backport [<a href="https://gitlab.isc.org/isc-projects/bind9/commit/366b4e1" rel="noreferrer" target="_blank">https://gitlab.isc.org/isc-projects/bind9/commit/366b4e1</a>]<br>
&gt; -<br>
&gt; -Signed-off-by: Kai Kang &lt;<a href="mailto:kai.kang@windriver.com" target="_blank">kai.kang@windriver.com</a>&gt;<br>
&gt; -<br>
&gt; -From 366b4e1ede8aed690e981e07137cb1cb77879c36 Mon Sep 17 00:00:00 2001<br>
&gt; -From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= &lt;<a href="mailto:michal@isc.org" target="_blank">michal@isc.org</a>&gt;<br>
&gt; -Date: Thu, 17 Jan 2019 15:53:38 +0100<br>
&gt; -Subject: [PATCH 3/6] use reference counter for pipeline groups (v3)<br>
&gt; -<br>
&gt; -Track pipeline groups using a shared reference counter<br>
&gt; -instead of a linked list.<br>
&gt; -<br>
&gt; -(cherry picked from commit 513afd33eb17d5dc41a3f0d2d38204ef8c5f6f91)<br>
&gt; -(cherry picked from commit 9446629b730c59c4215f08d37fbaf810282fbccb)<br>
&gt; ----<br>
&gt; - bin/named/client.c               | 171 ++++++++++++++++++++-----------<br>
&gt; - bin/named/include/named/client.h |   2 +-<br>
&gt; - 2 files changed, 110 insertions(+), 63 deletions(-)<br>
&gt; -<br>
&gt; -diff --git a/bin/named/client.c b/bin/named/client.c<br>
&gt; -index a7b49a0f71..277656cef0 100644<br>
&gt; ---- a/bin/named/client.c<br>
&gt; -+++ b/bin/named/client.c<br>
&gt; -@@ -299,6 +299,75 @@ ns_client_settimeout(ns_client_t *client, unsigned int seconds) {<br>
&gt; -     }<br>
&gt; - }<br>
&gt; - <br>
&gt; -+/*%<br>
&gt; -+ * Allocate a reference counter that will track the number of client structures<br>
&gt; -+ * using the TCP connection that &#39;client&#39; called accept() for.  This counter<br>
&gt; -+ * will be shared between all client structures associated with this TCP<br>
&gt; -+ * connection.<br>
&gt; -+ */<br>
&gt; -+static void<br>
&gt; -+pipeline_init(ns_client_t *client) {<br>
&gt; -+    isc_refcount_t *refs;<br>
&gt; -+<br>
&gt; -+    REQUIRE(client-&gt;pipeline_refs == NULL);<br>
&gt; -+<br>
&gt; -+    /*<br>
&gt; -+     * A global memory context is used for the allocation as different<br>
&gt; -+     * client structures may have different memory contexts assigned and a<br>
&gt; -+     * reference counter allocated here might need to be freed by a<br>
&gt; -+     * different client.  The performance impact caused by memory context<br>
&gt; -+     * contention here is expected to be negligible, given that this code<br>
&gt; -+     * is only executed for TCP connections.<br>
&gt; -+     */<br>
&gt; -+    refs = isc_mem_allocate(client-&gt;sctx-&gt;mctx, sizeof(*refs));<br>
&gt; -+    isc_refcount_init(refs, 1);<br>
&gt; -+    client-&gt;pipeline_refs = refs;<br>
&gt; -+}<br>
&gt; -+<br>
&gt; -+/*%<br>
&gt; -+ * Increase the count of client structures using the TCP connection that<br>
&gt; -+ * &#39;source&#39; is associated with and put a pointer to that count in &#39;target&#39;,<br>
&gt; -+ * thus associating it with the same TCP connection.<br>
&gt; -+ */<br>
&gt; -+static void<br>
&gt; -+pipeline_attach(ns_client_t *source, ns_client_t *target) {<br>
&gt; -+    int old_refs;<br>
&gt; -+<br>
&gt; -+    REQUIRE(source-&gt;pipeline_refs != NULL);<br>
&gt; -+    REQUIRE(target-&gt;pipeline_refs == NULL);<br>
&gt; -+<br>
&gt; -+    old_refs = isc_refcount_increment(source-&gt;pipeline_refs);<br>
&gt; -+    INSIST(old_refs &gt; 0);<br>
&gt; -+    target-&gt;pipeline_refs = source-&gt;pipeline_refs;<br>
&gt; -+}<br>
&gt; -+<br>
&gt; -+/*%<br>
&gt; -+ * Decrease the count of client structures using the TCP connection that<br>
&gt; -+ * &#39;client&#39; is associated with.  If this is the last client using this TCP<br>
&gt; -+ * connection, free the reference counter and return true; otherwise, return<br>
&gt; -+ * false.<br>
&gt; -+ */<br>
&gt; -+static bool<br>
&gt; -+pipeline_detach(ns_client_t *client) {<br>
&gt; -+    isc_refcount_t *refs;<br>
&gt; -+    int old_refs;<br>
&gt; -+<br>
&gt; -+    REQUIRE(client-&gt;pipeline_refs != NULL);<br>
&gt; -+<br>
&gt; -+    refs = client-&gt;pipeline_refs;<br>
&gt; -+    client-&gt;pipeline_refs = NULL;<br>
&gt; -+<br>
&gt; -+    old_refs = isc_refcount_decrement(refs);<br>
&gt; -+    INSIST(old_refs &gt; 0);<br>
&gt; -+<br>
&gt; -+    if (old_refs == 1) {<br>
&gt; -+            isc_mem_free(client-&gt;sctx-&gt;mctx, refs);<br>
&gt; -+            return (true);<br>
&gt; -+    }<br>
&gt; -+<br>
&gt; -+    return (false);<br>
&gt; -+}<br>
&gt; -+<br>
&gt; - /*%<br>
&gt; -  * Check for a deactivation or shutdown request and take appropriate<br>
&gt; -  * action.  Returns true if either is in progress; in this case<br>
&gt; -@@ -421,6 +490,40 @@ exit_check(ns_client_t *client) {<br>
&gt; -                     client-&gt;tcpmsg_valid = false;<br>
&gt; -             }<br>
&gt; - <br>
&gt; -+            if (client-&gt;tcpquota != NULL) {<br>
&gt; -+                    if (client-&gt;pipeline_refs == NULL ||<br>
&gt; -+                        pipeline_detach(client))<br>
&gt; -+                    {<br>
&gt; -+                            /*<br>
&gt; -+                             * Only detach from the TCP client quota if<br>
&gt; -+                             * there are no more client structures using<br>
&gt; -+                             * this TCP connection.<br>
&gt; -+                             *<br>
&gt; -+                             * Note that we check &#39;pipeline_refs&#39; and not<br>
&gt; -+                             * &#39;pipelined&#39; because in some cases (e.g.<br>
&gt; -+                             * after receiving a request with an opcode<br>
&gt; -+                             * different than QUERY) &#39;pipelined&#39; is set to<br>
&gt; -+                             * false after the reference counter gets<br>
&gt; -+                             * allocated in pipeline_init() and we must<br>
&gt; -+                             * still drop our reference as failing to do so<br>
&gt; -+                             * would prevent the reference counter itself<br>
&gt; -+                             * from being freed.<br>
&gt; -+                             */<br>
&gt; -+                            isc_quota_detach(&amp;client-&gt;tcpquota);<br>
&gt; -+                    } else {<br>
&gt; -+                            /*<br>
&gt; -+                             * There are other client structures using this<br>
&gt; -+                             * TCP connection, so we cannot detach from the<br>
&gt; -+                             * TCP client quota to prevent excess TCP<br>
&gt; -+                             * connections from being accepted.  However,<br>
&gt; -+                             * this client structure might later be reused<br>
&gt; -+                             * for accepting new connections and thus must<br>
&gt; -+                             * have its &#39;tcpquota&#39; field set to NULL.<br>
&gt; -+                             */<br>
&gt; -+                            client-&gt;tcpquota = NULL;<br>
&gt; -+                    }<br>
&gt; -+            }<br>
&gt; -+<br>
&gt; -             if (client-&gt;tcpsocket != NULL) {<br>
&gt; -                     CTRACE(&quot;closetcp&quot;);<br>
&gt; -                     isc_socket_detach(&amp;client-&gt;tcpsocket);<br>
&gt; -@@ -434,44 +537,6 @@ exit_check(ns_client_t *client) {<br>
&gt; -                     }<br>
&gt; -             }<br>
&gt; - <br>
&gt; --            if (client-&gt;tcpquota != NULL) {<br>
&gt; --                    /*<br>
&gt; --                     * If we are not in a pipeline group, or<br>
&gt; --                     * we are the last client in the group, detach from<br>
&gt; --                     * tcpquota; otherwise, transfer the quota to<br>
&gt; --                     * another client in the same group.<br>
&gt; --                     */<br>
&gt; --                    if (!ISC_LINK_LINKED(client, glink) ||<br>
&gt; --                        (client-&gt;glink.next == NULL &amp;&amp;<br>
&gt; --                         client-&gt;glink.prev == NULL))<br>
&gt; --                    {<br>
&gt; --                            isc_quota_detach(&amp;client-&gt;tcpquota);<br>
&gt; --                    } else if (client-&gt;glink.next != NULL) {<br>
&gt; --                            INSIST(client-&gt;glink.next-&gt;tcpquota == NULL);<br>
&gt; --                            client-&gt;glink.next-&gt;tcpquota = client-&gt;tcpquota;<br>
&gt; --                            client-&gt;tcpquota = NULL;<br>
&gt; --                    } else {<br>
&gt; --                            INSIST(client-&gt;glink.prev-&gt;tcpquota == NULL);<br>
&gt; --                            client-&gt;glink.prev-&gt;tcpquota = client-&gt;tcpquota;<br>
&gt; --                            client-&gt;tcpquota = NULL;<br>
&gt; --                    }<br>
&gt; --            }<br>
&gt; --<br>
&gt; --            /*<br>
&gt; --             * Unlink from pipeline group.<br>
&gt; --             */<br>
&gt; --            if (ISC_LINK_LINKED(client, glink)) {<br>
&gt; --                    if (client-&gt;glink.next != NULL) {<br>
&gt; --                            client-&gt;glink.next-&gt;glink.prev =<br>
&gt; --                                    client-&gt;glink.prev;<br>
&gt; --                    }<br>
&gt; --                    if (client-&gt;glink.prev != NULL) {<br>
&gt; --                            client-&gt;glink.prev-&gt;glink.next =<br>
&gt; --                                    client-&gt;glink.next;<br>
&gt; --                    }<br>
&gt; --                    ISC_LINK_INIT(client, glink);<br>
&gt; --            }<br>
&gt; --<br>
&gt; -             if (client-&gt;timerset) {<br>
&gt; -                     (void)isc_timer_reset(client-&gt;timer,<br>
&gt; -                                           isc_timertype_inactive,<br>
&gt; -@@ -3130,6 +3195,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {<br>
&gt; -     dns_name_init(&amp;client-&gt;signername, NULL);<br>
&gt; -     client-&gt;mortal = false;<br>
&gt; -     client-&gt;pipelined = false;<br>
&gt; -+    client-&gt;pipeline_refs = NULL;<br>
&gt; -     client-&gt;tcpquota = NULL;<br>
&gt; -     client-&gt;recursionquota = NULL;<br>
&gt; -     client-&gt;interface = NULL;<br>
&gt; -@@ -3154,7 +3220,6 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {<br>
&gt; -     client-&gt;<a href="http://formerrcache.id" rel="noreferrer" target="_blank">formerrcache.id</a> = 0;<br>
&gt; -     ISC_LINK_INIT(client, link);<br>
&gt; -     ISC_LINK_INIT(client, rlink);<br>
&gt; --    ISC_LINK_INIT(client, glink);<br>
&gt; -     ISC_QLINK_INIT(client, ilink);<br>
&gt; -     client-&gt;keytag = NULL;<br>
&gt; -     client-&gt;keytag_len = 0;<br>
&gt; -@@ -3341,6 +3406,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) {<br>
&gt; -                  !allowed(&amp;netaddr, NULL, NULL, 0, NULL,<br>
&gt; -                           ns_g_server-&gt;keepresporder)))<br>
&gt; -             {<br>
&gt; -+                    pipeline_init(client);<br>
&gt; -                     client-&gt;pipelined = true;<br>
&gt; -             }<br>
&gt; - <br>
&gt; -@@ -3800,35 +3866,16 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock,<br>
&gt; -     ns_interface_attach(ifp, &amp;client-&gt;interface);<br>
&gt; -     client-&gt;newstate = client-&gt;state = NS_CLIENTSTATE_WORKING;<br>
&gt; -     INSIST(client-&gt;recursionquota == NULL);<br>
&gt; --<br>
&gt; --    /*<br>
&gt; --     * Transfer TCP quota to the new client.<br>
&gt; --     */<br>
&gt; --    INSIST(client-&gt;tcpquota == NULL);<br>
&gt; --    INSIST(oldclient-&gt;tcpquota != NULL);<br>
&gt; --    client-&gt;tcpquota = oldclient-&gt;tcpquota;<br>
&gt; --    oldclient-&gt;tcpquota = NULL;<br>
&gt; --<br>
&gt; --    /*<br>
&gt; --     * Link to a pipeline group, creating it if needed.<br>
&gt; --     */<br>
&gt; --    if (!ISC_LINK_LINKED(oldclient, glink)) {<br>
&gt; --            oldclient-&gt;glink.next = NULL;<br>
&gt; --            oldclient-&gt;glink.prev = NULL;<br>
&gt; --    }<br>
&gt; --    client-&gt;glink.next = oldclient-&gt;glink.next;<br>
&gt; --    client-&gt;glink.prev = oldclient;<br>
&gt; --    if (oldclient-&gt;glink.next != NULL) {<br>
&gt; --            oldclient-&gt;glink.next-&gt;glink.prev = client;<br>
&gt; --    }<br>
&gt; --    oldclient-&gt;glink.next = client;<br>
&gt; -+    client-&gt;tcpquota = &amp;client-&gt;sctx-&gt;tcpquota;<br>
&gt; - <br>
&gt; -     client-&gt;dscp = ifp-&gt;dscp;<br>
&gt; - <br>
&gt; -     client-&gt;attributes |= NS_CLIENTATTR_TCP;<br>
&gt; --    client-&gt;pipelined = true;<br>
&gt; -     client-&gt;mortal = true;<br>
&gt; - <br>
&gt; -+    pipeline_attach(oldclient, client);<br>
&gt; -+    client-&gt;pipelined = true;<br>
&gt; -+<br>
&gt; -     isc_socket_attach(ifp-&gt;tcpsocket, &amp;client-&gt;tcplistener);<br>
&gt; -     isc_socket_attach(sock, &amp;client-&gt;tcpsocket);<br>
&gt; -     isc_socket_setname(client-&gt;tcpsocket, &quot;worker-tcp&quot;, NULL);<br>
&gt; -diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h<br>
&gt; -index 1f7973f9c5..aeed9ccdda 100644<br>
&gt; ---- a/bin/named/include/named/client.h<br>
&gt; -+++ b/bin/named/include/named/client.h<br>
&gt; -@@ -134,6 +134,7 @@ struct ns_client {<br>
&gt; -     dns_name_t              *signer;      /*%&lt; NULL if not valid sig */<br>
&gt; -     bool                    mortal;       /*%&lt; Die after handling request */<br>
&gt; -     bool                    pipelined;   /*%&lt; TCP queries not in sequence */<br>
&gt; -+    isc_refcount_t          *pipeline_refs;<br>
&gt; -     isc_quota_t             *tcpquota;<br>
&gt; -     isc_quota_t             *recursionquota;<br>
&gt; -     ns_interface_t          *interface;<br>
&gt; -@@ -167,7 +168,6 @@ struct ns_client {<br>
&gt; - <br>
&gt; -     ISC_LINK(ns_client_t)   link;<br>
&gt; -     ISC_LINK(ns_client_t)   rlink;<br>
&gt; --    ISC_LINK(ns_client_t)   glink;<br>
&gt; -     ISC_QLINK(ns_client_t)  ilink;<br>
&gt; -     unsigned char           cookie[8];<br>
&gt; -     uint32_t                expire;<br>
&gt; --- <br>
&gt; -2.20.1<br>
&gt; -<br>
&gt; diff --git a/meta/recipes-connectivity/bind/bind/0004-better-tcpquota-accounting-and-client-mortality-chec.patch b/meta/recipes-connectivity/bind/bind/0004-better-tcpquota-accounting-and-client-mortality-chec.patch<br>
&gt; deleted file mode 100644<br>
&gt; index 034ab13303b..00000000000<br>
&gt; --- a/meta/recipes-connectivity/bind/bind/0004-better-tcpquota-accounting-and-client-mortality-chec.patch<br>
&gt; +++ /dev/null<br>
&gt; @@ -1,512 +0,0 @@<br>
&gt; -Backport patch to fix CVE-2018-5743.<br>
&gt; -<br>
&gt; -Ref:<br>
&gt; -<a href="https://security-tracker.debian.org/tracker/CVE-2018-5743" rel="noreferrer" target="_blank">https://security-tracker.debian.org/tracker/CVE-2018-5743</a><br>
&gt; -<br>
&gt; -CVE: CVE-2018-5743<br>
&gt; -Upstream-Status: Backport [<a href="https://gitlab.isc.org/isc-projects/bind9/commit/2ab8a08" rel="noreferrer" target="_blank">https://gitlab.isc.org/isc-projects/bind9/commit/2ab8a08</a>]<br>
&gt; -<br>
&gt; -Signed-off-by: Kai Kang &lt;<a href="mailto:kai.kang@windriver.com" target="_blank">kai.kang@windriver.com</a>&gt;<br>
&gt; -<br>
&gt; -From 2ab8a085b3c666f28f1f9229bd6ecb59915b26c3 Mon Sep 17 00:00:00 2001<br>
&gt; -From: Evan Hunt &lt;<a href="mailto:each@isc.org" target="_blank">each@isc.org</a>&gt;<br>
&gt; -Date: Fri, 5 Apr 2019 16:12:18 -0700<br>
&gt; -Subject: [PATCH 4/6] better tcpquota accounting and client mortality checks<br>
&gt; -<br>
&gt; -- ensure that tcpactive is cleaned up correctly when accept() fails.<br>
&gt; -- set &#39;client-&gt;tcpattached&#39; when the client is attached to the tcpquota.<br>
&gt; -  carry this value on to new clients sharing the same pipeline group.<br>
&gt; -  don&#39;t call isc_quota_detach() on the tcpquota unless tcpattached is<br>
&gt; -  set.  this way clients that were allowed to accept TCP connections<br>
&gt; -  despite being over quota (and therefore, were never attached to the<br>
&gt; -  quota) will not inadvertently detach from it and mess up the<br>
&gt; -  accounting.<br>
&gt; -- simplify the code for tcpquota disconnection by using a new function<br>
&gt; -  tcpquota_disconnect().<br>
&gt; -- before deciding whether to reject a new connection due to quota<br>
&gt; -  exhaustion, check to see whether there are at least two active<br>
&gt; -  clients. previously, this was &quot;at least one&quot;, but that could be<br>
&gt; -  insufficient if there was one other client in READING state (waiting<br>
&gt; -  for messages on an open connection) but none in READY (listening<br>
&gt; -  for new connections).<br>
&gt; -- before deciding whether a TCP client object can to go inactive, we<br>
&gt; -  must ensure there are enough other clients to maintain service<br>
&gt; -  afterward -- both accepting new connections and reading/processing new<br>
&gt; -  queries.  A TCP client can&#39;t shut down unless at least one<br>
&gt; -  client is accepting new connections and (in the case of pipelined<br>
&gt; -  clients) at least one additional client is waiting to read.<br>
&gt; -<br>
&gt; -(cherry picked from commit c7394738b2445c16f728a88394864dd61baad900)<br>
&gt; -(cherry picked from commit e965d5f11d3d0f6d59704e614fceca2093cb1856)<br>
&gt; -(cherry picked from commit 87d431161450777ea093821212abfb52d51b36e3)<br>
&gt; ----<br>
&gt; - bin/named/client.c               | 244 +++++++++++++++++++------------<br>
&gt; - bin/named/include/named/client.h |   3 +-<br>
&gt; - 2 files changed, 152 insertions(+), 95 deletions(-)<br>
&gt; -<br>
&gt; -diff --git a/bin/named/client.c b/bin/named/client.c<br>
&gt; -index 277656cef0..61e96dd28c 100644<br>
&gt; ---- a/bin/named/client.c<br>
&gt; -+++ b/bin/named/client.c<br>
&gt; -@@ -244,13 +244,14 @@ static void client_start(isc_task_t *task, isc_event_t *event);<br>
&gt; - static void client_request(isc_task_t *task, isc_event_t *event);<br>
&gt; - static void ns_client_dumpmessage(ns_client_t *client, const char *reason);<br>
&gt; - static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,<br>
&gt; --                           dns_dispatch_t *disp, bool tcp);<br>
&gt; -+                           dns_dispatch_t *disp, ns_client_t *oldclient,<br>
&gt; -+                           bool tcp);<br>
&gt; - static isc_result_t get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp,<br>
&gt; -                            isc_socket_t *sock, ns_client_t *oldclient);<br>
&gt; - static inline bool<br>
&gt; - allowed(isc_netaddr_t *addr, dns_name_t *signer,<br>
&gt; -     isc_netaddr_t *ecs_addr, uint8_t ecs_addrlen,<br>
&gt; --    uint8_t *ecs_scope, dns_acl_t *acl)<br>
&gt; -+    uint8_t *ecs_scope, dns_acl_t *acl);<br>
&gt; - static void compute_cookie(ns_client_t *client, uint32_t when,<br>
&gt; -                        uint32_t nonce, const unsigned char *secret,<br>
&gt; -                        isc_buffer_t *buf);<br>
&gt; -@@ -319,7 +320,7 @@ pipeline_init(ns_client_t *client) {<br>
&gt; -      * contention here is expected to be negligible, given that this code<br>
&gt; -      * is only executed for TCP connections.<br>
&gt; -      */<br>
&gt; --    refs = isc_mem_allocate(client-&gt;sctx-&gt;mctx, sizeof(*refs));<br>
&gt; -+    refs = isc_mem_allocate(ns_g_mctx, sizeof(*refs));<br>
&gt; -     isc_refcount_init(refs, 1);<br>
&gt; -     client-&gt;pipeline_refs = refs;<br>
&gt; - }<br>
&gt; -@@ -331,13 +332,13 @@ pipeline_init(ns_client_t *client) {<br>
&gt; -  */<br>
&gt; - static void<br>
&gt; - pipeline_attach(ns_client_t *source, ns_client_t *target) {<br>
&gt; --    int old_refs;<br>
&gt; -+    int refs;<br>
&gt; - <br>
&gt; -     REQUIRE(source-&gt;pipeline_refs != NULL);<br>
&gt; -     REQUIRE(target-&gt;pipeline_refs == NULL);<br>
&gt; - <br>
&gt; --    old_refs = isc_refcount_increment(source-&gt;pipeline_refs);<br>
&gt; --    INSIST(old_refs &gt; 0);<br>
&gt; -+    isc_refcount_increment(source-&gt;pipeline_refs, &amp;refs);<br>
&gt; -+    INSIST(refs &gt; 1);<br>
&gt; -     target-&gt;pipeline_refs = source-&gt;pipeline_refs;<br>
&gt; - }<br>
&gt; - <br>
&gt; -@@ -349,25 +350,51 @@ pipeline_attach(ns_client_t *source, ns_client_t *target) {<br>
&gt; -  */<br>
&gt; - static bool<br>
&gt; - pipeline_detach(ns_client_t *client) {<br>
&gt; --    isc_refcount_t *refs;<br>
&gt; --    int old_refs;<br>
&gt; -+    isc_refcount_t *refcount;<br>
&gt; -+    int refs;<br>
&gt; - <br>
&gt; -     REQUIRE(client-&gt;pipeline_refs != NULL);<br>
&gt; - <br>
&gt; --    refs = client-&gt;pipeline_refs;<br>
&gt; -+    refcount = client-&gt;pipeline_refs;<br>
&gt; -     client-&gt;pipeline_refs = NULL;<br>
&gt; - <br>
&gt; --    old_refs = isc_refcount_decrement(refs);<br>
&gt; --    INSIST(old_refs &gt; 0);<br>
&gt; -+    isc_refcount_decrement(refcount, refs);<br>
&gt; - <br>
&gt; --    if (old_refs == 1) {<br>
&gt; --            isc_mem_free(client-&gt;sctx-&gt;mctx, refs);<br>
&gt; -+    if (refs == 0) {<br>
&gt; -+            isc_mem_free(ns_g_mctx, refs);<br>
&gt; -             return (true);<br>
&gt; -     }<br>
&gt; - <br>
&gt; -     return (false);<br>
&gt; - }<br>
&gt; - <br>
&gt; -+/*<br>
&gt; -+ * Detach a client from the TCP client quota if appropriate, and set<br>
&gt; -+ * the quota pointer to NULL.<br>
&gt; -+ *<br>
&gt; -+ * Sometimes when the TCP client quota is exhausted but there are no other<br>
&gt; -+ * clients servicing the interface, a client will be allowed to continue<br>
&gt; -+ * running despite not having been attached to the quota. In this event,<br>
&gt; -+ * the TCP quota was never attached to the client, so when the client (or<br>
&gt; -+ * associated pipeline group) shuts down, the quota must NOT be detached.<br>
&gt; -+ *<br>
&gt; -+ * Otherwise, if the quota pointer is set, it should be detached. If not<br>
&gt; -+ * set at all, we just return without doing anything.<br>
&gt; -+ */<br>
&gt; -+static void<br>
&gt; -+tcpquota_disconnect(ns_client_t *client) {<br>
&gt; -+    if (client-&gt;tcpquota == NULL) {<br>
&gt; -+            return;<br>
&gt; -+    }<br>
&gt; -+<br>
&gt; -+    if (client-&gt;tcpattached) {<br>
&gt; -+            isc_quota_detach(&amp;client-&gt;tcpquota);<br>
&gt; -+            client-&gt;tcpattached = false;<br>
&gt; -+    } else {<br>
&gt; -+            client-&gt;tcpquota = NULL;<br>
&gt; -+    }<br>
&gt; -+}<br>
&gt; -+<br>
&gt; - /*%<br>
&gt; -  * Check for a deactivation or shutdown request and take appropriate<br>
&gt; -  * action.  Returns true if either is in progress; in this case<br>
&gt; -@@ -490,38 +517,31 @@ exit_check(ns_client_t *client) {<br>
&gt; -                     client-&gt;tcpmsg_valid = false;<br>
&gt; -             }<br>
&gt; - <br>
&gt; --            if (client-&gt;tcpquota != NULL) {<br>
&gt; --                    if (client-&gt;pipeline_refs == NULL ||<br>
&gt; --                        pipeline_detach(client))<br>
&gt; --                    {<br>
&gt; --                            /*<br>
&gt; --                             * Only detach from the TCP client quota if<br>
&gt; --                             * there are no more client structures using<br>
&gt; --                             * this TCP connection.<br>
&gt; --                             *<br>
&gt; --                             * Note that we check &#39;pipeline_refs&#39; and not<br>
&gt; --                             * &#39;pipelined&#39; because in some cases (e.g.<br>
&gt; --                             * after receiving a request with an opcode<br>
&gt; --                             * different than QUERY) &#39;pipelined&#39; is set to<br>
&gt; --                             * false after the reference counter gets<br>
&gt; --                             * allocated in pipeline_init() and we must<br>
&gt; --                             * still drop our reference as failing to do so<br>
&gt; --                             * would prevent the reference counter itself<br>
&gt; --                             * from being freed.<br>
&gt; --                             */<br>
&gt; --                            isc_quota_detach(&amp;client-&gt;tcpquota);<br>
&gt; --                    } else {<br>
&gt; --                            /*<br>
&gt; --                             * There are other client structures using this<br>
&gt; --                             * TCP connection, so we cannot detach from the<br>
&gt; --                             * TCP client quota to prevent excess TCP<br>
&gt; --                             * connections from being accepted.  However,<br>
&gt; --                             * this client structure might later be reused<br>
&gt; --                             * for accepting new connections and thus must<br>
&gt; --                             * have its &#39;tcpquota&#39; field set to NULL.<br>
&gt; --                             */<br>
&gt; --                            client-&gt;tcpquota = NULL;<br>
&gt; --                    }<br>
&gt; -+            /*<br>
&gt; -+             * Detach from pipeline group and from TCP client quota,<br>
&gt; -+             * if appropriate.<br>
&gt; -+             *<br>
&gt; -+             * - If no pipeline group is active, attempt to<br>
&gt; -+             *   detach from the TCP client quota.<br>
&gt; -+             *<br>
&gt; -+             * - If a pipeline group is active, detach from it;<br>
&gt; -+             *   if the return code indicates that there no more<br>
&gt; -+             *   clients left if this pipeline group, we also detach<br>
&gt; -+             *   from the TCP client quota.<br>
&gt; -+             *<br>
&gt; -+             * - Otherwise we don&#39;t try to detach, we just set the<br>
&gt; -+             *   TCP quota pointer to NULL if it wasn&#39;t NULL already.<br>
&gt; -+             *<br>
&gt; -+             * tcpquota_disconnect() will set tcpquota to NULL, either<br>
&gt; -+             * by detaching it or by assignment, depending on the<br>
&gt; -+             * needs of the client. See the comments on that function<br>
&gt; -+             * for further information.<br>
&gt; -+             */<br>
&gt; -+            if (client-&gt;pipeline_refs == NULL || pipeline_detach(client)) {<br>
&gt; -+                    tcpquota_disconnect(client);<br>
&gt; -+            } else {<br>
&gt; -+                    client-&gt;tcpquota = NULL;<br>
&gt; -+                    client-&gt;tcpattached = false;<br>
&gt; -             }<br>
&gt; - <br>
&gt; -             if (client-&gt;tcpsocket != NULL) {<br>
&gt; -@@ -544,8 +564,6 @@ exit_check(ns_client_t *client) {<br>
&gt; -                     client-&gt;timerset = false;<br>
&gt; -             }<br>
&gt; - <br>
&gt; --            client-&gt;pipelined = false;<br>
&gt; --<br>
&gt; -             client-&gt;peeraddr_valid = false;<br>
&gt; - <br>
&gt; -             client-&gt;state = NS_CLIENTSTATE_READY;<br>
&gt; -@@ -558,18 +576,27 @@ exit_check(ns_client_t *client) {<br>
&gt; -              * active and force it to go inactive if not.<br>
&gt; -              *<br>
&gt; -              * UDP clients go inactive at this point, but a TCP client<br>
&gt; --             * will needs to remain active if no other clients are<br>
&gt; --             * listening for TCP requests on this interface, to<br>
&gt; --             * prevent this interface from going nonresponsive.<br>
&gt; -+             * may need to remain active and go into ready state if<br>
&gt; -+             * no other clients are available to listen for TCP<br>
&gt; -+             * requests on this interface or (in the case of pipelined<br>
&gt; -+             * clients) to read for additional messages on the current<br>
&gt; -+             * connection.<br>
&gt; -              */<br>
&gt; -             if (client-&gt;mortal &amp;&amp; TCP_CLIENT(client) &amp;&amp; !ns_g_clienttest) {<br>
&gt; -                     LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --                    if (client-&gt;interface-&gt;ntcpaccepting == 0) {<br>
&gt; -+                    if ((client-&gt;interface-&gt;ntcpaccepting == 0 ||<br>
&gt; -+                        (client-&gt;pipelined &amp;&amp;<br>
&gt; -+                         client-&gt;interface-&gt;ntcpactive &lt; 2)) &amp;&amp;<br>
&gt; -+                        client-&gt;newstate != NS_CLIENTSTATE_FREED)<br>
&gt; -+                    {<br>
&gt; -                             client-&gt;mortal = false;<br>
&gt; -+                            client-&gt;newstate = NS_CLIENTSTATE_READY;<br>
&gt; -                     }<br>
&gt; -                     UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -             }<br>
&gt; - <br>
&gt; -+            client-&gt;pipelined = false;<br>
&gt; -+<br>
&gt; -             /*<br>
&gt; -              * We don&#39;t need the client; send it to the inactive<br>
&gt; -              * queue for recycling.<br>
&gt; -@@ -2634,6 +2661,18 @@ client_request(isc_task_t *task, isc_event_t *event) {<br>
&gt; -             client-&gt;pipelined = false;<br>
&gt; -     }<br>
&gt; -     if (TCP_CLIENT(client) &amp;&amp; client-&gt;pipelined) {<br>
&gt; -+            /*<br>
&gt; -+             * We&#39;re pipelining. Replace the client; the<br>
&gt; -+             * the replacement can read the TCP socket looking<br>
&gt; -+             * for new messages and this client can process the<br>
&gt; -+             * current message asynchronously.<br>
&gt; -+             *<br>
&gt; -+             * There are now at least three clients using this<br>
&gt; -+             * TCP socket - one accepting new connections,<br>
&gt; -+             * one reading an existing connection to get new<br>
&gt; -+             * messages, and one answering the message already<br>
&gt; -+             * received.<br>
&gt; -+             */<br>
&gt; -             result = ns_client_replace(client);<br>
&gt; -             if (result != ISC_R_SUCCESS) {<br>
&gt; -                     client-&gt;pipelined = false;<br>
&gt; -@@ -3197,6 +3236,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {<br>
&gt; -     client-&gt;pipelined = false;<br>
&gt; -     client-&gt;pipeline_refs = NULL;<br>
&gt; -     client-&gt;tcpquota = NULL;<br>
&gt; -+    client-&gt;tcpattached = false;<br>
&gt; -     client-&gt;recursionquota = NULL;<br>
&gt; -     client-&gt;interface = NULL;<br>
&gt; -     client-&gt;peeraddr_valid = false;<br>
&gt; -@@ -3359,9 +3399,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) {<br>
&gt; -                           NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),<br>
&gt; -                           &quot;accept failed: %s&quot;,<br>
&gt; -                           isc_result_totext(nevent-&gt;result));<br>
&gt; --            if (client-&gt;tcpquota != NULL) {<br>
&gt; --                    isc_quota_detach(&amp;client-&gt;tcpquota);<br>
&gt; --            }<br>
&gt; -+            tcpquota_disconnect(client);<br>
&gt; -     }<br>
&gt; - <br>
&gt; -     if (exit_check(client))<br>
&gt; -@@ -3402,7 +3440,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) {<br>
&gt; -             client-&gt;pipelined = false;<br>
&gt; -             result = ns_client_replace(client);<br>
&gt; -             if (result == ISC_R_SUCCESS &amp;&amp;<br>
&gt; --                (client-&gt;sctx-&gt;keepresporder == NULL ||<br>
&gt; -+                (ns_g_server-&gt;keepresporder == NULL ||<br>
&gt; -                  !allowed(&amp;netaddr, NULL, NULL, 0, NULL,<br>
&gt; -                           ns_g_server-&gt;keepresporder)))<br>
&gt; -             {<br>
&gt; -@@ -3429,7 +3467,7 @@ client_accept(ns_client_t *client) {<br>
&gt; -      * in named.conf. If we can&#39;t attach to it here, that means the TCP<br>
&gt; -      * client quota has been exceeded.<br>
&gt; -      */<br>
&gt; --    result = isc_quota_attach(&amp;client-&gt;sctx-&gt;tcpquota,<br>
&gt; -+    result = isc_quota_attach(&amp;ns_g_server-&gt;tcpquota,<br>
&gt; -                               &amp;client-&gt;tcpquota);<br>
&gt; -     if (result != ISC_R_SUCCESS) {<br>
&gt; -                     bool exit;<br>
&gt; -@@ -3447,27 +3485,27 @@ client_accept(ns_client_t *client) {<br>
&gt; -                      * interface to be starved, with no clients able<br>
&gt; -                      * to accept new connections.<br>
&gt; -                      *<br>
&gt; --                     * So, we check here to see if any other client<br>
&gt; --                     * is already servicing TCP queries on this<br>
&gt; -+                     * So, we check here to see if any other clients<br>
&gt; -+                     * are already servicing TCP queries on this<br>
&gt; -                      * interface (whether accepting, reading, or<br>
&gt; --                     * processing).<br>
&gt; --                     *<br>
&gt; --                     * If so, then it&#39;s okay *not* to call<br>
&gt; --                     * accept - we can let this client to go inactive<br>
&gt; --                     * and the other one handle the next connection<br>
&gt; --                     * when it&#39;s ready.<br>
&gt; -+                     * processing). If there are at least two<br>
&gt; -+                     * (one reading and one processing a request)<br>
&gt; -+                     * then it&#39;s okay *not* to call accept - we<br>
&gt; -+                     * can let this client go inactive and another<br>
&gt; -+                     * one will resume accepting when it&#39;s done.<br>
&gt; -                      *<br>
&gt; --                     * But if not, then we need to be a little bit<br>
&gt; --                     * flexible about the quota. We allow *one* extra<br>
&gt; --                     * TCP client through, to ensure we&#39;re listening on<br>
&gt; --                     * every interface.<br>
&gt; -+                     * If there aren&#39;t enough active clients on the<br>
&gt; -+                     * interface, then we can be a little bit<br>
&gt; -+                     * flexible about the quota. We&#39;ll allow *one*<br>
&gt; -+                     * extra client through to ensure we&#39;re listening<br>
&gt; -+                     * on every interface.<br>
&gt; -                      *<br>
&gt; --                     * (Note: In practice this means that the *real*<br>
&gt; --                     * TCP client quota is tcp-clients plus the number<br>
&gt; --                     * of interfaces.)<br>
&gt; -+                     * (Note: In practice this means that the real<br>
&gt; -+                     * TCP client quota is tcp-clients plus the<br>
&gt; -+                     * number of listening interfaces plus 2.)<br>
&gt; -                      */<br>
&gt; -                     LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --                    exit = (client-&gt;interface-&gt;ntcpactive &gt; 0);<br>
&gt; -+                    exit = (client-&gt;interface-&gt;ntcpactive &gt; 1);<br>
&gt; -                     UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; - <br>
&gt; -                     if (exit) {<br>
&gt; -@@ -3475,6 +3513,9 @@ client_accept(ns_client_t *client) {<br>
&gt; -                             (void)exit_check(client);<br>
&gt; -                             return;<br>
&gt; -                     }<br>
&gt; -+<br>
&gt; -+    } else {<br>
&gt; -+            client-&gt;tcpattached = true;<br>
&gt; -     }<br>
&gt; - <br>
&gt; -     /*<br>
&gt; -@@ -3507,9 +3548,16 @@ client_accept(ns_client_t *client) {<br>
&gt; -             UNEXPECTED_ERROR(__FILE__, __LINE__,<br>
&gt; -                              &quot;isc_socket_accept() failed: %s&quot;,<br>
&gt; -                              isc_result_totext(result));<br>
&gt; --            if (client-&gt;tcpquota != NULL) {<br>
&gt; --                    isc_quota_detach(&amp;client-&gt;tcpquota);<br>
&gt; -+<br>
&gt; -+            tcpquota_disconnect(client);<br>
&gt; -+<br>
&gt; -+            if (client-&gt;tcpactive) {<br>
&gt; -+                    LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+                    client-&gt;interface-&gt;ntcpactive--;<br>
&gt; -+                    UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+                    client-&gt;tcpactive = false;<br>
&gt; -             }<br>
&gt; -+<br>
&gt; -             return;<br>
&gt; -     }<br>
&gt; - <br>
&gt; -@@ -3527,13 +3575,12 @@ client_accept(ns_client_t *client) {<br>
&gt; -      * once the connection is established.<br>
&gt; -      *<br>
&gt; -      * When the client object is shutting down after handling a TCP<br>
&gt; --     * request (see exit_check()), it looks to see whether this value is<br>
&gt; --     * non-zero. If so, that means another client has already called<br>
&gt; --     * accept() and is waiting to establish the next connection, which<br>
&gt; --     * means the first client is free to go inactive. Otherwise,<br>
&gt; --     * the first client must come back and call accept() again; this<br>
&gt; --     * guarantees there will always be at least one client listening<br>
&gt; --     * for new TCP connections on each interface.<br>
&gt; -+     * request (see exit_check()), if this value is at least one, that<br>
&gt; -+     * means another client has called accept() and is waiting to<br>
&gt; -+     * establish the next connection. That means the client may be<br>
&gt; -+     * be free to become inactive; otherwise it may need to start<br>
&gt; -+     * listening for connections itself to prevent the interface<br>
&gt; -+     * going dead.<br>
&gt; -      */<br>
&gt; -     LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -     client-&gt;interface-&gt;ntcpaccepting++;<br>
&gt; -@@ -3613,19 +3660,19 @@ ns_client_replace(ns_client_t *client) {<br>
&gt; -                                 client-&gt;tcpsocket, client);<br>
&gt; -     } else {<br>
&gt; -             result = get_client(client-&gt;manager, client-&gt;interface,<br>
&gt; --                                client-&gt;dispatch, tcp);<br>
&gt; -+                                client-&gt;dispatch, client, tcp);<br>
&gt; -+<br>
&gt; -+            /*<br>
&gt; -+             * The responsibility for listening for new requests is hereby<br>
&gt; -+             * transferred to the new client.  Therefore, the old client<br>
&gt; -+             * should refrain from listening for any more requests.<br>
&gt; -+             */<br>
&gt; -+            client-&gt;mortal = true;<br>
&gt; -     }<br>
&gt; -     if (result != ISC_R_SUCCESS) {<br>
&gt; -             return (result);<br>
&gt; -     }<br>
&gt; - <br>
&gt; --    /*<br>
&gt; --     * The responsibility for listening for new requests is hereby<br>
&gt; --     * transferred to the new client.  Therefore, the old client<br>
&gt; --     * should refrain from listening for any more requests.<br>
&gt; --     */<br>
&gt; --    client-&gt;mortal = true;<br>
&gt; --<br>
&gt; -     return (ISC_R_SUCCESS);<br>
&gt; - }<br>
&gt; - <br>
&gt; -@@ -3759,7 +3806,7 @@ ns_clientmgr_destroy(ns_clientmgr_t **managerp) {<br>
&gt; - <br>
&gt; - static isc_result_t<br>
&gt; - get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,<br>
&gt; --       dns_dispatch_t *disp, bool tcp)<br>
&gt; -+       dns_dispatch_t *disp, ns_client_t *oldclient, bool tcp)<br>
&gt; - {<br>
&gt; -     isc_result_t result = ISC_R_SUCCESS;<br>
&gt; -     isc_event_t *ev;<br>
&gt; -@@ -3803,6 +3850,16 @@ get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,<br>
&gt; -     client-&gt;dscp = ifp-&gt;dscp;<br>
&gt; - <br>
&gt; -     if (tcp) {<br>
&gt; -+            client-&gt;tcpattached = false;<br>
&gt; -+            if (oldclient != NULL) {<br>
&gt; -+                    client-&gt;tcpattached = oldclient-&gt;tcpattached;<br>
&gt; -+            }<br>
&gt; -+<br>
&gt; -+            LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+            client-&gt;interface-&gt;ntcpactive++;<br>
&gt; -+            UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+            client-&gt;tcpactive = true;<br>
&gt; -+<br>
&gt; -             client-&gt;attributes |= NS_CLIENTATTR_TCP;<br>
&gt; -             isc_socket_attach(ifp-&gt;tcpsocket,<br>
&gt; -                               &amp;client-&gt;tcplistener);<br>
&gt; -@@ -3866,7 +3923,8 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock,<br>
&gt; -     ns_interface_attach(ifp, &amp;client-&gt;interface);<br>
&gt; -     client-&gt;newstate = client-&gt;state = NS_CLIENTSTATE_WORKING;<br>
&gt; -     INSIST(client-&gt;recursionquota == NULL);<br>
&gt; --    client-&gt;tcpquota = &amp;client-&gt;sctx-&gt;tcpquota;<br>
&gt; -+    client-&gt;tcpquota = &amp;ns_g_server-&gt;tcpquota;<br>
&gt; -+    client-&gt;tcpattached = oldclient-&gt;tcpattached;<br>
&gt; - <br>
&gt; -     client-&gt;dscp = ifp-&gt;dscp;<br>
&gt; - <br>
&gt; -@@ -3885,7 +3943,6 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock,<br>
&gt; -     LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -     client-&gt;interface-&gt;ntcpactive++;<br>
&gt; -     UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --<br>
&gt; -     client-&gt;tcpactive = true;<br>
&gt; - <br>
&gt; -     INSIST(client-&gt;tcpmsg_valid == false);<br>
&gt; -@@ -3913,7 +3970,8 @@ ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,<br>
&gt; -     MTRACE(&quot;createclients&quot;);<br>
&gt; - <br>
&gt; -     for (disp = 0; disp &lt; n; disp++) {<br>
&gt; --            result = get_client(manager, ifp, ifp-&gt;udpdispatch[disp], tcp);<br>
&gt; -+            result = get_client(manager, ifp, ifp-&gt;udpdispatch[disp],<br>
&gt; -+                                NULL, tcp);<br>
&gt; -             if (result != ISC_R_SUCCESS)<br>
&gt; -                     break;<br>
&gt; -     }<br>
&gt; -diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h<br>
&gt; -index aeed9ccdda..e2c40acd28 100644<br>
&gt; ---- a/bin/named/include/named/client.h<br>
&gt; -+++ b/bin/named/include/named/client.h<br>
&gt; -@@ -9,8 +9,6 @@<br>
&gt; -  * information regarding copyright ownership.<br>
&gt; -  */<br>
&gt; - <br>
&gt; --/* $Id: client.h,v 1.96 2012/01/31 23:47:31 tbox Exp $ */<br>
&gt; --<br>
&gt; - #ifndef NAMED_CLIENT_H<br>
&gt; - #define NAMED_CLIENT_H 1<br>
&gt; - <br>
&gt; -@@ -136,6 +134,7 @@ struct ns_client {<br>
&gt; -     bool                    pipelined;   /*%&lt; TCP queries not in sequence */<br>
&gt; -     isc_refcount_t          *pipeline_refs;<br>
&gt; -     isc_quota_t             *tcpquota;<br>
&gt; -+    bool                    tcpattached;<br>
&gt; -     isc_quota_t             *recursionquota;<br>
&gt; -     ns_interface_t          *interface;<br>
&gt; - <br>
&gt; --- <br>
&gt; -2.20.1<br>
&gt; -<br>
&gt; diff --git a/meta/recipes-connectivity/bind/bind/0005-refactor-tcpquota-and-pipeline-refs-allow-special-ca.patch b/meta/recipes-connectivity/bind/bind/0005-refactor-tcpquota-and-pipeline-refs-allow-special-ca.patch<br>
&gt; deleted file mode 100644<br>
&gt; index 987e75bc0ee..00000000000<br>
&gt; --- a/meta/recipes-connectivity/bind/bind/0005-refactor-tcpquota-and-pipeline-refs-allow-special-ca.patch<br>
&gt; +++ /dev/null<br>
&gt; @@ -1,911 +0,0 @@<br>
&gt; -Backport patch to fix CVE-2018-5743.<br>
&gt; -<br>
&gt; -Ref:<br>
&gt; -<a href="https://security-tracker.debian.org/tracker/CVE-2018-5743" rel="noreferrer" target="_blank">https://security-tracker.debian.org/tracker/CVE-2018-5743</a><br>
&gt; -<br>
&gt; -CVE: CVE-2018-5743<br>
&gt; -Upstream-Status: Backport [<a href="https://gitlab.isc.org/isc-projects/bind9/commit/c47ccf6" rel="noreferrer" target="_blank">https://gitlab.isc.org/isc-projects/bind9/commit/c47ccf6</a>]<br>
&gt; -<br>
&gt; -Signed-off-by: Kai Kang &lt;<a href="mailto:kai.kang@windriver.com" target="_blank">kai.kang@windriver.com</a>&gt;<br>
&gt; -<br>
&gt; -From c47ccf630f147378568b33e8fdb7b754f228c346 Mon Sep 17 00:00:00 2001<br>
&gt; -From: Evan Hunt &lt;<a href="mailto:each@isc.org" target="_blank">each@isc.org</a>&gt;<br>
&gt; -Date: Fri, 5 Apr 2019 16:26:05 -0700<br>
&gt; -Subject: [PATCH 5/6] refactor tcpquota and pipeline refs; allow special-case<br>
&gt; - overrun in isc_quota<br>
&gt; -<br>
&gt; -- if the TCP quota has been exceeded but there are no clients listening<br>
&gt; -  for new connections on the interface, we can now force attachment to the<br>
&gt; -  quota using isc_quota_force(), instead of carrying on with the quota not<br>
&gt; -  attached.<br>
&gt; -- the TCP client quota is now referenced via a reference-counted<br>
&gt; -  &#39;ns_tcpconn&#39; object, one of which is created whenever a client begins<br>
&gt; -  listening for new connections, and attached to by members of that<br>
&gt; -  client&#39;s pipeline group. when the last reference to the tcpconn<br>
&gt; -  object is detached, it is freed and the TCP quota slot is released.<br>
&gt; -- reduce code duplication by adding mark_tcp_active() function.<br>
&gt; -- convert counters to atomic.<br>
&gt; -<br>
&gt; -(cherry picked from commit 7e8222378ca24f1302a0c1c638565050ab04681b)<br>
&gt; -(cherry picked from commit 4939451275722bfda490ea86ca13e84f6bc71e46)<br>
&gt; -(cherry picked from commit 13f7c918b8720d890408f678bd73c20e634539d9)<br>
&gt; ----<br>
&gt; - bin/named/client.c                     | 444 +++++++++++--------------<br>
&gt; - bin/named/include/named/client.h       |  12 +-<br>
&gt; - bin/named/include/named/interfacemgr.h |   6 +-<br>
&gt; - bin/named/interfacemgr.c               |   1 +<br>
&gt; - lib/isc/include/isc/quota.h            |   7 +<br>
&gt; - lib/isc/quota.c                        |  33 +-<br>
&gt; - lib/isc/win32/<a href="http://libisc.def.in" rel="noreferrer" target="_blank">libisc.def.in</a>            |   1 +<br>
&gt; - 7 files changed, 236 insertions(+), 268 deletions(-)<br>
&gt; -<br>
&gt; -diff --git a/bin/named/client.c b/bin/named/client.c<br>
&gt; -index 61e96dd28c..d826ab32bf 100644<br>
&gt; ---- a/bin/named/client.c<br>
&gt; -+++ b/bin/named/client.c<br>
&gt; -@@ -244,8 +244,7 @@ static void client_start(isc_task_t *task, isc_event_t *event);<br>
&gt; - static void client_request(isc_task_t *task, isc_event_t *event);<br>
&gt; - static void ns_client_dumpmessage(ns_client_t *client, const char *reason);<br>
&gt; - static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,<br>
&gt; --                           dns_dispatch_t *disp, ns_client_t *oldclient,<br>
&gt; --                           bool tcp);<br>
&gt; -+                           dns_dispatch_t *disp, bool tcp);<br>
&gt; - static isc_result_t get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp,<br>
&gt; -                            isc_socket_t *sock, ns_client_t *oldclient);<br>
&gt; - static inline bool<br>
&gt; -@@ -301,16 +300,32 @@ ns_client_settimeout(ns_client_t *client, unsigned int seconds) {<br>
&gt; - }<br>
&gt; - <br>
&gt; - /*%<br>
&gt; -- * Allocate a reference counter that will track the number of client structures<br>
&gt; -- * using the TCP connection that &#39;client&#39; called accept() for.  This counter<br>
&gt; -- * will be shared between all client structures associated with this TCP<br>
&gt; -- * connection.<br>
&gt; -+ * Allocate a reference-counted object that will maintain a single pointer to<br>
&gt; -+ * the (also reference-counted) TCP client quota, shared between all the<br>
&gt; -+ * clients processing queries on a single TCP connection, so that all<br>
&gt; -+ * clients sharing the one socket will together consume only one slot in<br>
&gt; -+ * the &#39;tcp-clients&#39; quota.<br>
&gt; -  */<br>
&gt; --static void<br>
&gt; --pipeline_init(ns_client_t *client) {<br>
&gt; --    isc_refcount_t *refs;<br>
&gt; -+static isc_result_t<br>
&gt; -+tcpconn_init(ns_client_t *client, bool force) {<br>
&gt; -+    isc_result_t result;<br>
&gt; -+    isc_quota_t *quota = NULL;<br>
&gt; -+    ns_tcpconn_t *tconn = NULL;<br>
&gt; - <br>
&gt; --    REQUIRE(client-&gt;pipeline_refs == NULL);<br>
&gt; -+    REQUIRE(client-&gt;tcpconn == NULL);<br>
&gt; -+<br>
&gt; -+    /*<br>
&gt; -+     * Try to attach to the quota first, so we won&#39;t pointlessly<br>
&gt; -+     * allocate memory for a tcpconn object if we can&#39;t get one.<br>
&gt; -+     */<br>
&gt; -+    if (force) {<br>
&gt; -+            result = isc_quota_force(&amp;ns_g_server-&gt;tcpquota, &amp;quota);<br>
&gt; -+    } else {<br>
&gt; -+            result = isc_quota_attach(&amp;ns_g_server-&gt;tcpquota, &amp;quota);<br>
&gt; -+    }<br>
&gt; -+    if (result != ISC_R_SUCCESS) {<br>
&gt; -+            return (result);<br>
&gt; -+    }<br>
&gt; - <br>
&gt; -     /*<br>
&gt; -      * A global memory context is used for the allocation as different<br>
&gt; -@@ -320,78 +335,80 @@ pipeline_init(ns_client_t *client) {<br>
&gt; -      * contention here is expected to be negligible, given that this code<br>
&gt; -      * is only executed for TCP connections.<br>
&gt; -      */<br>
&gt; --    refs = isc_mem_allocate(ns_g_mctx, sizeof(*refs));<br>
&gt; --    isc_refcount_init(refs, 1);<br>
&gt; --    client-&gt;pipeline_refs = refs;<br>
&gt; -+    tconn = isc_mem_allocate(ns_g_mctx, sizeof(*tconn));<br>
&gt; -+<br>
&gt; -+    isc_refcount_init(&amp;tconn-&gt;refs, 1);<br>
&gt; -+    tconn-&gt;tcpquota = quota;<br>
&gt; -+    quota = NULL;<br>
&gt; -+    tconn-&gt;pipelined = false;<br>
&gt; -+<br>
&gt; -+    client-&gt;tcpconn = tconn;<br>
&gt; -+<br>
&gt; -+    return (ISC_R_SUCCESS);<br>
&gt; - }<br>
&gt; - <br>
&gt; - /*%<br>
&gt; -- * Increase the count of client structures using the TCP connection that<br>
&gt; -- * &#39;source&#39; is associated with and put a pointer to that count in &#39;target&#39;,<br>
&gt; -- * thus associating it with the same TCP connection.<br>
&gt; -+ * Increase the count of client structures sharing the TCP connection<br>
&gt; -+ * that &#39;source&#39; is associated with; add a pointer to the same tcpconn<br>
&gt; -+ * to &#39;target&#39;, thus associating it with the same TCP connection.<br>
&gt; -  */<br>
&gt; - static void<br>
&gt; --pipeline_attach(ns_client_t *source, ns_client_t *target) {<br>
&gt; -+tcpconn_attach(ns_client_t *source, ns_client_t *target) {<br>
&gt; -     int refs;<br>
&gt; - <br>
&gt; --    REQUIRE(source-&gt;pipeline_refs != NULL);<br>
&gt; --    REQUIRE(target-&gt;pipeline_refs == NULL);<br>
&gt; -+    REQUIRE(source-&gt;tcpconn != NULL);<br>
&gt; -+    REQUIRE(target-&gt;tcpconn == NULL);<br>
&gt; -+    REQUIRE(source-&gt;tcpconn-&gt;pipelined);<br>
&gt; - <br>
&gt; --    isc_refcount_increment(source-&gt;pipeline_refs, &amp;refs);<br>
&gt; -+    isc_refcount_increment(&amp;source-&gt;tcpconn-&gt;refs, &amp;refs);<br>
&gt; -     INSIST(refs &gt; 1);<br>
&gt; --    target-&gt;pipeline_refs = source-&gt;pipeline_refs;<br>
&gt; -+    target-&gt;tcpconn = source-&gt;tcpconn;<br>
&gt; - }<br>
&gt; - <br>
&gt; - /*%<br>
&gt; -- * Decrease the count of client structures using the TCP connection that<br>
&gt; -+ * Decrease the count of client structures sharing the TCP connection that<br>
&gt; -  * &#39;client&#39; is associated with.  If this is the last client using this TCP<br>
&gt; -- * connection, free the reference counter and return true; otherwise, return<br>
&gt; -- * false.<br>
&gt; -+ * connection, we detach from the TCP quota and free the tcpconn<br>
&gt; -+ * object. Either way, client-&gt;tcpconn is set to NULL.<br>
&gt; -  */<br>
&gt; --static bool<br>
&gt; --pipeline_detach(ns_client_t *client) {<br>
&gt; --    isc_refcount_t *refcount;<br>
&gt; -+static void<br>
&gt; -+tcpconn_detach(ns_client_t *client) {<br>
&gt; -+    ns_tcpconn_t *tconn = NULL;<br>
&gt; -     int refs;<br>
&gt; - <br>
&gt; --    REQUIRE(client-&gt;pipeline_refs != NULL);<br>
&gt; --<br>
&gt; --    refcount = client-&gt;pipeline_refs;<br>
&gt; --    client-&gt;pipeline_refs = NULL;<br>
&gt; -+    REQUIRE(client-&gt;tcpconn != NULL);<br>
&gt; - <br>
&gt; --    isc_refcount_decrement(refcount, refs);<br>
&gt; -+    tconn = client-&gt;tcpconn;<br>
&gt; -+    client-&gt;tcpconn = NULL;<br>
&gt; - <br>
&gt; -+    isc_refcount_decrement(&amp;tconn-&gt;refs, &amp;refs);<br>
&gt; -     if (refs == 0) {<br>
&gt; --            isc_mem_free(ns_g_mctx, refs);<br>
&gt; --            return (true);<br>
&gt; -+            isc_quota_detach(&amp;tconn-&gt;tcpquota);<br>
&gt; -+            isc_mem_free(ns_g_mctx, tconn);<br>
&gt; -     }<br>
&gt; --<br>
&gt; --    return (false);<br>
&gt; - }<br>
&gt; - <br>
&gt; --/*<br>
&gt; -- * Detach a client from the TCP client quota if appropriate, and set<br>
&gt; -- * the quota pointer to NULL.<br>
&gt; -- *<br>
&gt; -- * Sometimes when the TCP client quota is exhausted but there are no other<br>
&gt; -- * clients servicing the interface, a client will be allowed to continue<br>
&gt; -- * running despite not having been attached to the quota. In this event,<br>
&gt; -- * the TCP quota was never attached to the client, so when the client (or<br>
&gt; -- * associated pipeline group) shuts down, the quota must NOT be detached.<br>
&gt; -+/*%<br>
&gt; -+ * Mark a client as active and increment the interface&#39;s &#39;ntcpactive&#39;<br>
&gt; -+ * counter, as a signal that there is at least one client servicing<br>
&gt; -+ * TCP queries for the interface. If we reach the TCP client quota at<br>
&gt; -+ * some point, this will be used to determine whether a quota overrun<br>
&gt; -+ * should be permitted.<br>
&gt; -  *<br>
&gt; -- * Otherwise, if the quota pointer is set, it should be detached. If not<br>
&gt; -- * set at all, we just return without doing anything.<br>
&gt; -+ * Marking the client active with the &#39;tcpactive&#39; flag ensures proper<br>
&gt; -+ * accounting, by preventing us from incrementing or decrementing<br>
&gt; -+ * &#39;ntcpactive&#39; more than once per client.<br>
&gt; -  */<br>
&gt; - static void<br>
&gt; --tcpquota_disconnect(ns_client_t *client) {<br>
&gt; --    if (client-&gt;tcpquota == NULL) {<br>
&gt; --            return;<br>
&gt; --    }<br>
&gt; --<br>
&gt; --    if (client-&gt;tcpattached) {<br>
&gt; --            isc_quota_detach(&amp;client-&gt;tcpquota);<br>
&gt; --            client-&gt;tcpattached = false;<br>
&gt; --    } else {<br>
&gt; --            client-&gt;tcpquota = NULL;<br>
&gt; -+mark_tcp_active(ns_client_t *client, bool active) {<br>
&gt; -+    if (active &amp;&amp; !client-&gt;tcpactive) {<br>
&gt; -+            isc_atomic_xadd(&amp;client-&gt;interface-&gt;ntcpactive, 1);<br>
&gt; -+            client-&gt;tcpactive = active;<br>
&gt; -+    } else if (!active &amp;&amp; client-&gt;tcpactive) {<br>
&gt; -+            uint32_t old =<br>
&gt; -+                    isc_atomic_xadd(&amp;client-&gt;interface-&gt;ntcpactive, -1);<br>
&gt; -+            INSIST(old &gt; 0);<br>
&gt; -+            client-&gt;tcpactive = active;<br>
&gt; -     }<br>
&gt; - }<br>
&gt; - <br>
&gt; -@@ -484,7 +501,8 @@ exit_check(ns_client_t *client) {<br>
&gt; -             INSIST(client-&gt;recursionquota == NULL);<br>
&gt; - <br>
&gt; -             if (NS_CLIENTSTATE_READING == client-&gt;newstate) {<br>
&gt; --                    if (!client-&gt;pipelined) {<br>
&gt; -+                    INSIST(client-&gt;tcpconn != NULL);<br>
&gt; -+                    if (!client-&gt;tcpconn-&gt;pipelined) {<br>
&gt; -                             client_read(client);<br>
&gt; -                             client-&gt;newstate = NS_CLIENTSTATE_MAX;<br>
&gt; -                             return (true); /* We&#39;re done. */<br>
&gt; -@@ -507,8 +525,8 @@ exit_check(ns_client_t *client) {<br>
&gt; -                     dns_tcpmsg_cancelread(&amp;client-&gt;tcpmsg);<br>
&gt; -             }<br>
&gt; - <br>
&gt; --            if (client-&gt;nreads != 0) {<br>
&gt; --                    /* Still waiting for read cancel completion. */<br>
&gt; -+            /* Still waiting for read cancel completion. */<br>
&gt; -+            if (client-&gt;nreads &gt; 0) {<br>
&gt; -                     return (true);<br>
&gt; -             }<br>
&gt; - <br>
&gt; -@@ -518,43 +536,45 @@ exit_check(ns_client_t *client) {<br>
&gt; -             }<br>
&gt; - <br>
&gt; -             /*<br>
&gt; --             * Detach from pipeline group and from TCP client quota,<br>
&gt; --             * if appropriate.<br>
&gt; -+             * Soon the client will be ready to accept a new TCP<br>
&gt; -+             * connection or UDP request, but we may have enough<br>
&gt; -+             * clients doing that already.  Check whether this client<br>
&gt; -+             * needs to remain active and allow it go inactive if<br>
&gt; -+             * not.<br>
&gt; -              *<br>
&gt; --             * - If no pipeline group is active, attempt to<br>
&gt; --             *   detach from the TCP client quota.<br>
&gt; -+             * UDP clients always go inactive at this point, but a TCP<br>
&gt; -+             * client may need to stay active and return to READY<br>
&gt; -+             * state if no other clients are available to listen<br>
&gt; -+             * for TCP requests on this interface.<br>
&gt; -              *<br>
&gt; --             * - If a pipeline group is active, detach from it;<br>
&gt; --             *   if the return code indicates that there no more<br>
&gt; --             *   clients left if this pipeline group, we also detach<br>
&gt; --             *   from the TCP client quota.<br>
&gt; --             *<br>
&gt; --             * - Otherwise we don&#39;t try to detach, we just set the<br>
&gt; --             *   TCP quota pointer to NULL if it wasn&#39;t NULL already.<br>
&gt; --             *<br>
&gt; --             * tcpquota_disconnect() will set tcpquota to NULL, either<br>
&gt; --             * by detaching it or by assignment, depending on the<br>
&gt; --             * needs of the client. See the comments on that function<br>
&gt; --             * for further information.<br>
&gt; -+             * Regardless, if we&#39;re going to FREED state, that means<br>
&gt; -+             * the system is shutting down and we don&#39;t need to<br>
&gt; -+             * retain clients.<br>
&gt; -              */<br>
&gt; --            if (client-&gt;pipeline_refs == NULL || pipeline_detach(client)) {<br>
&gt; --                    tcpquota_disconnect(client);<br>
&gt; --            } else {<br>
&gt; --                    client-&gt;tcpquota = NULL;<br>
&gt; --                    client-&gt;tcpattached = false;<br>
&gt; -+            if (client-&gt;mortal &amp;&amp; TCP_CLIENT(client) &amp;&amp;<br>
&gt; -+                client-&gt;newstate != NS_CLIENTSTATE_FREED &amp;&amp;<br>
&gt; -+                !ns_g_clienttest &amp;&amp;<br>
&gt; -+                isc_atomic_xadd(&amp;client-&gt;interface-&gt;ntcpaccepting, 0) == 0)<br>
&gt; -+            {<br>
&gt; -+                    /* Nobody else is accepting */<br>
&gt; -+                    client-&gt;mortal = false;<br>
&gt; -+                    client-&gt;newstate = NS_CLIENTSTATE_READY;<br>
&gt; -+            }<br>
&gt; -+<br>
&gt; -+            /*<br>
&gt; -+             * Detach from TCP connection and TCP client quota,<br>
&gt; -+             * if appropriate. If this is the last reference to<br>
&gt; -+             * the TCP connection in our pipeline group, the<br>
&gt; -+             * TCP quota slot will be released.<br>
&gt; -+             */<br>
&gt; -+            if (client-&gt;tcpconn) {<br>
&gt; -+                    tcpconn_detach(client);<br>
&gt; -             }<br>
&gt; - <br>
&gt; -             if (client-&gt;tcpsocket != NULL) {<br>
&gt; -                     CTRACE(&quot;closetcp&quot;);<br>
&gt; -                     isc_socket_detach(&amp;client-&gt;tcpsocket);<br>
&gt; --<br>
&gt; --                    if (client-&gt;tcpactive) {<br>
&gt; --                            LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --                            INSIST(client-&gt;interface-&gt;ntcpactive &gt; 0);<br>
&gt; --                            client-&gt;interface-&gt;ntcpactive--;<br>
&gt; --                            UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --                            client-&gt;tcpactive = false;<br>
&gt; --                    }<br>
&gt; -+                    mark_tcp_active(client, false);<br>
&gt; -             }<br>
&gt; - <br>
&gt; -             if (client-&gt;timerset) {<br>
&gt; -@@ -567,35 +587,6 @@ exit_check(ns_client_t *client) {<br>
&gt; -             client-&gt;peeraddr_valid = false;<br>
&gt; - <br>
&gt; -             client-&gt;state = NS_CLIENTSTATE_READY;<br>
&gt; --            INSIST(client-&gt;recursionquota == NULL);<br>
&gt; --<br>
&gt; --            /*<br>
&gt; --             * Now the client is ready to accept a new TCP connection<br>
&gt; --             * or UDP request, but we may have enough clients doing<br>
&gt; --             * that already.  Check whether this client needs to remain<br>
&gt; --             * active and force it to go inactive if not.<br>
&gt; --             *<br>
&gt; --             * UDP clients go inactive at this point, but a TCP client<br>
&gt; --             * may need to remain active and go into ready state if<br>
&gt; --             * no other clients are available to listen for TCP<br>
&gt; --             * requests on this interface or (in the case of pipelined<br>
&gt; --             * clients) to read for additional messages on the current<br>
&gt; --             * connection.<br>
&gt; --             */<br>
&gt; --            if (client-&gt;mortal &amp;&amp; TCP_CLIENT(client) &amp;&amp; !ns_g_clienttest) {<br>
&gt; --                    LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --                    if ((client-&gt;interface-&gt;ntcpaccepting == 0 ||<br>
&gt; --                        (client-&gt;pipelined &amp;&amp;<br>
&gt; --                         client-&gt;interface-&gt;ntcpactive &lt; 2)) &amp;&amp;<br>
&gt; --                        client-&gt;newstate != NS_CLIENTSTATE_FREED)<br>
&gt; --                    {<br>
&gt; --                            client-&gt;mortal = false;<br>
&gt; --                            client-&gt;newstate = NS_CLIENTSTATE_READY;<br>
&gt; --                    }<br>
&gt; --                    UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --            }<br>
&gt; --<br>
&gt; --            client-&gt;pipelined = false;<br>
&gt; - <br>
&gt; -             /*<br>
&gt; -              * We don&#39;t need the client; send it to the inactive<br>
&gt; -@@ -630,7 +621,7 @@ exit_check(ns_client_t *client) {<br>
&gt; -             }<br>
&gt; - <br>
&gt; -             /* Still waiting for accept cancel completion. */<br>
&gt; --            if (! (client-&gt;naccepts == 0)) {<br>
&gt; -+            if (client-&gt;naccepts &gt; 0) {<br>
&gt; -                     return (true);<br>
&gt; -             }<br>
&gt; - <br>
&gt; -@@ -641,7 +632,7 @@ exit_check(ns_client_t *client) {<br>
&gt; -             }<br>
&gt; - <br>
&gt; -             /* Still waiting for recv cancel completion. */<br>
&gt; --            if (! (client-&gt;nrecvs == 0)) {<br>
&gt; -+            if (client-&gt;nrecvs &gt; 0) {<br>
&gt; -                     return (true);<br>
&gt; -             }<br>
&gt; - <br>
&gt; -@@ -654,14 +645,7 @@ exit_check(ns_client_t *client) {<br>
&gt; -             INSIST(client-&gt;recursionquota == NULL);<br>
&gt; -             if (client-&gt;tcplistener != NULL) {<br>
&gt; -                     isc_socket_detach(&amp;client-&gt;tcplistener);<br>
&gt; --<br>
&gt; --                    if (client-&gt;tcpactive) {<br>
&gt; --                            LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --                            INSIST(client-&gt;interface-&gt;ntcpactive &gt; 0);<br>
&gt; --                            client-&gt;interface-&gt;ntcpactive--;<br>
&gt; --                            UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --                            client-&gt;tcpactive = false;<br>
&gt; --                    }<br>
&gt; -+                    mark_tcp_active(client, false);<br>
&gt; -             }<br>
&gt; -             if (client-&gt;udpsocket != NULL) {<br>
&gt; -                     isc_socket_detach(&amp;client-&gt;udpsocket);<br>
&gt; -@@ -816,7 +800,7 @@ client_start(isc_task_t *task, isc_event_t *event) {<br>
&gt; -             return;<br>
&gt; - <br>
&gt; -     if (TCP_CLIENT(client)) {<br>
&gt; --            if (client-&gt;pipelined) {<br>
&gt; -+            if (client-&gt;tcpconn != NULL) {<br>
&gt; -                     client_read(client);<br>
&gt; -             } else {<br>
&gt; -                     client_accept(client);<br>
&gt; -@@ -2470,6 +2454,7 @@ client_request(isc_task_t *task, isc_event_t *event) {<br>
&gt; -             client-&gt;nrecvs--;<br>
&gt; -     } else {<br>
&gt; -             INSIST(TCP_CLIENT(client));<br>
&gt; -+            INSIST(client-&gt;tcpconn != NULL);<br>
&gt; -             REQUIRE(event-&gt;ev_type == DNS_EVENT_TCPMSG);<br>
&gt; -             REQUIRE(event-&gt;ev_sender == &amp;client-&gt;tcpmsg);<br>
&gt; -             buffer = &amp;client-&gt;tcpmsg.buffer;<br>
&gt; -@@ -2657,17 +2642,19 @@ client_request(isc_task_t *task, isc_event_t *event) {<br>
&gt; -     /*<br>
&gt; -      * Pipeline TCP query processing.<br>
&gt; -      */<br>
&gt; --    if (client-&gt;message-&gt;opcode != dns_opcode_query) {<br>
&gt; --            client-&gt;pipelined = false;<br>
&gt; -+    if (TCP_CLIENT(client) &amp;&amp;<br>
&gt; -+        client-&gt;message-&gt;opcode != dns_opcode_query)<br>
&gt; -+    {<br>
&gt; -+            client-&gt;tcpconn-&gt;pipelined = false;<br>
&gt; -     }<br>
&gt; --    if (TCP_CLIENT(client) &amp;&amp; client-&gt;pipelined) {<br>
&gt; -+    if (TCP_CLIENT(client) &amp;&amp; client-&gt;tcpconn-&gt;pipelined) {<br>
&gt; -             /*<br>
&gt; -              * We&#39;re pipelining. Replace the client; the<br>
&gt; --             * the replacement can read the TCP socket looking<br>
&gt; --             * for new messages and this client can process the<br>
&gt; -+             * replacement can read the TCP socket looking<br>
&gt; -+             * for new messages and this one can process the<br>
&gt; -              * current message asynchronously.<br>
&gt; -              *<br>
&gt; --             * There are now at least three clients using this<br>
&gt; -+             * There will now be at least three clients using this<br>
&gt; -              * TCP socket - one accepting new connections,<br>
&gt; -              * one reading an existing connection to get new<br>
&gt; -              * messages, and one answering the message already<br>
&gt; -@@ -2675,7 +2662,7 @@ client_request(isc_task_t *task, isc_event_t *event) {<br>
&gt; -              */<br>
&gt; -             result = ns_client_replace(client);<br>
&gt; -             if (result != ISC_R_SUCCESS) {<br>
&gt; --                    client-&gt;pipelined = false;<br>
&gt; -+                    client-&gt;tcpconn-&gt;pipelined = false;<br>
&gt; -             }<br>
&gt; -     }<br>
&gt; - <br>
&gt; -@@ -3233,10 +3220,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {<br>
&gt; -     client-&gt;signer = NULL;<br>
&gt; -     dns_name_init(&amp;client-&gt;signername, NULL);<br>
&gt; -     client-&gt;mortal = false;<br>
&gt; --    client-&gt;pipelined = false;<br>
&gt; --    client-&gt;pipeline_refs = NULL;<br>
&gt; --    client-&gt;tcpquota = NULL;<br>
&gt; --    client-&gt;tcpattached = false;<br>
&gt; -+    client-&gt;tcpconn = NULL;<br>
&gt; -     client-&gt;recursionquota = NULL;<br>
&gt; -     client-&gt;interface = NULL;<br>
&gt; -     client-&gt;peeraddr_valid = false;<br>
&gt; -@@ -3341,9 +3325,10 @@ client_read(ns_client_t *client) {<br>
&gt; - <br>
&gt; - static void<br>
&gt; - client_newconn(isc_task_t *task, isc_event_t *event) {<br>
&gt; -+    isc_result_t result;<br>
&gt; -     ns_client_t *client = event-&gt;ev_arg;<br>
&gt; -     isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event;<br>
&gt; --    isc_result_t result;<br>
&gt; -+    uint32_t old;<br>
&gt; - <br>
&gt; -     REQUIRE(event-&gt;ev_type == ISC_SOCKEVENT_NEWCONN);<br>
&gt; -     REQUIRE(NS_CLIENT_VALID(client));<br>
&gt; -@@ -3363,10 +3348,8 @@ client_newconn(isc_task_t *task, isc_event_t *event) {<br>
&gt; -     INSIST(client-&gt;naccepts == 1);<br>
&gt; -     client-&gt;naccepts--;<br>
&gt; - <br>
&gt; --    LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --    INSIST(client-&gt;interface-&gt;ntcpaccepting &gt; 0);<br>
&gt; --    client-&gt;interface-&gt;ntcpaccepting--;<br>
&gt; --    UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+    old = isc_atomic_xadd(&amp;client-&gt;interface-&gt;ntcpaccepting, -1);<br>
&gt; -+    INSIST(old &gt; 0);<br>
&gt; - <br>
&gt; -     /*<br>
&gt; -      * We must take ownership of the new socket before the exit<br>
&gt; -@@ -3399,7 +3382,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) {<br>
&gt; -                           NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),<br>
&gt; -                           &quot;accept failed: %s&quot;,<br>
&gt; -                           isc_result_totext(nevent-&gt;result));<br>
&gt; --            tcpquota_disconnect(client);<br>
&gt; -+            tcpconn_detach(client);<br>
&gt; -     }<br>
&gt; - <br>
&gt; -     if (exit_check(client))<br>
&gt; -@@ -3437,15 +3420,13 @@ client_newconn(isc_task_t *task, isc_event_t *event) {<br>
&gt; -              * telnetting to port 53 (once per CPU) will<br>
&gt; -              * deny service to legitimate TCP clients.<br>
&gt; -              */<br>
&gt; --            client-&gt;pipelined = false;<br>
&gt; -             result = ns_client_replace(client);<br>
&gt; -             if (result == ISC_R_SUCCESS &amp;&amp;<br>
&gt; -                 (ns_g_server-&gt;keepresporder == NULL ||<br>
&gt; -                  !allowed(&amp;netaddr, NULL, NULL, 0, NULL,<br>
&gt; -                           ns_g_server-&gt;keepresporder)))<br>
&gt; -             {<br>
&gt; --                    pipeline_init(client);<br>
&gt; --                    client-&gt;pipelined = true;<br>
&gt; -+                    client-&gt;tcpconn-&gt;pipelined = true;<br>
&gt; -             }<br>
&gt; - <br>
&gt; -             client_read(client);<br>
&gt; -@@ -3462,78 +3443,59 @@ client_accept(ns_client_t *client) {<br>
&gt; -     CTRACE(&quot;accept&quot;);<br>
&gt; - <br>
&gt; -     /*<br>
&gt; --     * The tcpquota object can only be simultaneously referenced a<br>
&gt; --     * pre-defined number of times; this is configured by &#39;tcp-clients&#39;<br>
&gt; --     * in named.conf. If we can&#39;t attach to it here, that means the TCP<br>
&gt; --     * client quota has been exceeded.<br>
&gt; -+     * Set up a new TCP connection. This means try to attach to the<br>
&gt; -+     * TCP client quota (tcp-clients), but fail if we&#39;re over quota.<br>
&gt; -      */<br>
&gt; --    result = isc_quota_attach(&amp;ns_g_server-&gt;tcpquota,<br>
&gt; --                              &amp;client-&gt;tcpquota);<br>
&gt; -+    result = tcpconn_init(client, false);<br>
&gt; -     if (result != ISC_R_SUCCESS) {<br>
&gt; --                    bool exit;<br>
&gt; -+            bool exit;<br>
&gt; - <br>
&gt; --                    ns_client_log(client, NS_LOGCATEGORY_CLIENT,<br>
&gt; --                                  NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),<br>
&gt; --                                  &quot;no more TCP clients: %s&quot;,<br>
&gt; --                                  isc_result_totext(result));<br>
&gt; --<br>
&gt; --                    /*<br>
&gt; --                     * We have exceeded the system-wide TCP client<br>
&gt; --                     * quota.  But, we can&#39;t just block this accept<br>
&gt; --                     * in all cases, because if we did, a heavy TCP<br>
&gt; --                     * load on other interfaces might cause this<br>
&gt; --                     * interface to be starved, with no clients able<br>
&gt; --                     * to accept new connections.<br>
&gt; --                     *<br>
&gt; --                     * So, we check here to see if any other clients<br>
&gt; --                     * are already servicing TCP queries on this<br>
&gt; --                     * interface (whether accepting, reading, or<br>
&gt; --                     * processing). If there are at least two<br>
&gt; --                     * (one reading and one processing a request)<br>
&gt; --                     * then it&#39;s okay *not* to call accept - we<br>
&gt; --                     * can let this client go inactive and another<br>
&gt; --                     * one will resume accepting when it&#39;s done.<br>
&gt; --                     *<br>
&gt; --                     * If there aren&#39;t enough active clients on the<br>
&gt; --                     * interface, then we can be a little bit<br>
&gt; --                     * flexible about the quota. We&#39;ll allow *one*<br>
&gt; --                     * extra client through to ensure we&#39;re listening<br>
&gt; --                     * on every interface.<br>
&gt; --                     *<br>
&gt; --                     * (Note: In practice this means that the real<br>
&gt; --                     * TCP client quota is tcp-clients plus the<br>
&gt; --                     * number of listening interfaces plus 2.)<br>
&gt; --                     */<br>
&gt; --                    LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --                    exit = (client-&gt;interface-&gt;ntcpactive &gt; 1);<br>
&gt; --                    UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+            ns_client_log(client, NS_LOGCATEGORY_CLIENT,<br>
&gt; -+                          NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,<br>
&gt; -+                          &quot;TCP client quota reached: %s&quot;,<br>
&gt; -+                          isc_result_totext(result));<br>
&gt; - <br>
&gt; --                    if (exit) {<br>
&gt; --                            client-&gt;newstate = NS_CLIENTSTATE_INACTIVE;<br>
&gt; --                            (void)exit_check(client);<br>
&gt; --                            return;<br>
&gt; --                    }<br>
&gt; -+            /*<br>
&gt; -+             * We have exceeded the system-wide TCP client quota.  But,<br>
&gt; -+             * we can&#39;t just block this accept in all cases, because if<br>
&gt; -+             * we did, a heavy TCP load on other interfaces might cause<br>
&gt; -+             * this interface to be starved, with no clients able to<br>
&gt; -+             * accept new connections.<br>
&gt; -+             *<br>
&gt; -+             * So, we check here to see if any other clients are<br>
&gt; -+             * already servicing TCP queries on this interface (whether<br>
&gt; -+             * accepting, reading, or processing). If we find at least<br>
&gt; -+             * one, then it&#39;s okay *not* to call accept - we can let this<br>
&gt; -+             * client go inactive and another will take over when it&#39;s<br>
&gt; -+             * done.<br>
&gt; -+             *<br>
&gt; -+             * If there aren&#39;t enough active clients on the interface,<br>
&gt; -+             * then we can be a little bit flexible about the quota.<br>
&gt; -+             * We&#39;ll allow *one* extra client through to ensure we&#39;re<br>
&gt; -+             * listening on every interface; we do this by setting the<br>
&gt; -+             * &#39;force&#39; option to tcpconn_init().<br>
&gt; -+             *<br>
&gt; -+             * (Note: In practice this means that the real TCP client<br>
&gt; -+             * quota is tcp-clients plus the number of listening<br>
&gt; -+             * interfaces plus 1.)<br>
&gt; -+             */<br>
&gt; -+            exit = (isc_atomic_xadd(&amp;client-&gt;interface-&gt;ntcpactive, 0) &gt; 0);<br>
&gt; -+            if (exit) {<br>
&gt; -+                    client-&gt;newstate = NS_CLIENTSTATE_INACTIVE;<br>
&gt; -+                    (void)exit_check(client);<br>
&gt; -+                    return;<br>
&gt; -+            }<br>
&gt; - <br>
&gt; --    } else {<br>
&gt; --            client-&gt;tcpattached = true;<br>
&gt; -+            result = tcpconn_init(client, true);<br>
&gt; -+            RUNTIME_CHECK(result == ISC_R_SUCCESS);<br>
&gt; -     }<br>
&gt; - <br>
&gt; -     /*<br>
&gt; --     * By incrementing the interface&#39;s ntcpactive counter we signal<br>
&gt; --     * that there is at least one client servicing TCP queries for the<br>
&gt; --     * interface.<br>
&gt; --     *<br>
&gt; --     * We also make note of the fact in the client itself with the<br>
&gt; --     * tcpactive flag. This ensures proper accounting by preventing<br>
&gt; --     * us from accidentally incrementing or decrementing ntcpactive<br>
&gt; --     * more than once per client object.<br>
&gt; -+     * If this client was set up using get_client() or get_worker(),<br>
&gt; -+     * then TCP is already marked active. However, if it was restarted<br>
&gt; -+     * from exit_check(), it might not be, so we take care of it now.<br>
&gt; -      */<br>
&gt; --    if (!client-&gt;tcpactive) {<br>
&gt; --            LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --            client-&gt;interface-&gt;ntcpactive++;<br>
&gt; --            UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --            client-&gt;tcpactive = true;<br>
&gt; --    }<br>
&gt; -+    mark_tcp_active(client, true);<br>
&gt; - <br>
&gt; -     result = isc_socket_accept(client-&gt;tcplistener, client-&gt;task,<br>
&gt; -                                client_newconn, client);<br>
&gt; -@@ -3549,15 +3511,8 @@ client_accept(ns_client_t *client) {<br>
&gt; -                              &quot;isc_socket_accept() failed: %s&quot;,<br>
&gt; -                              isc_result_totext(result));<br>
&gt; - <br>
&gt; --            tcpquota_disconnect(client);<br>
&gt; --<br>
&gt; --            if (client-&gt;tcpactive) {<br>
&gt; --                    LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --                    client-&gt;interface-&gt;ntcpactive--;<br>
&gt; --                    UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --                    client-&gt;tcpactive = false;<br>
&gt; --            }<br>
&gt; --<br>
&gt; -+            tcpconn_detach(client);<br>
&gt; -+            mark_tcp_active(client, false);<br>
&gt; -             return;<br>
&gt; -     }<br>
&gt; - <br>
&gt; -@@ -3582,9 +3537,7 @@ client_accept(ns_client_t *client) {<br>
&gt; -      * listening for connections itself to prevent the interface<br>
&gt; -      * going dead.<br>
&gt; -      */<br>
&gt; --    LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --    client-&gt;interface-&gt;ntcpaccepting++;<br>
&gt; --    UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; -+    isc_atomic_xadd(&amp;client-&gt;interface-&gt;ntcpaccepting, 1);<br>
&gt; - }<br>
&gt; - <br>
&gt; - static void<br>
&gt; -@@ -3655,24 +3608,25 @@ ns_client_replace(ns_client_t *client) {<br>
&gt; -     REQUIRE(client-&gt;manager != NULL);<br>
&gt; - <br>
&gt; -     tcp = TCP_CLIENT(client);<br>
&gt; --    if (tcp &amp;&amp; client-&gt;pipelined) {<br>
&gt; -+    if (tcp &amp;&amp; client-&gt;tcpconn != NULL &amp;&amp; client-&gt;tcpconn-&gt;pipelined) {<br>
&gt; -             result = get_worker(client-&gt;manager, client-&gt;interface,<br>
&gt; -                                 client-&gt;tcpsocket, client);<br>
&gt; -     } else {<br>
&gt; -             result = get_client(client-&gt;manager, client-&gt;interface,<br>
&gt; --                                client-&gt;dispatch, client, tcp);<br>
&gt; -+                                client-&gt;dispatch, tcp);<br>
&gt; - <br>
&gt; --            /*<br>
&gt; --             * The responsibility for listening for new requests is hereby<br>
&gt; --             * transferred to the new client.  Therefore, the old client<br>
&gt; --             * should refrain from listening for any more requests.<br>
&gt; --             */<br>
&gt; --            client-&gt;mortal = true;<br>
&gt; -     }<br>
&gt; -     if (result != ISC_R_SUCCESS) {<br>
&gt; -             return (result);<br>
&gt; -     }<br>
&gt; - <br>
&gt; -+    /*<br>
&gt; -+     * The responsibility for listening for new requests is hereby<br>
&gt; -+     * transferred to the new client.  Therefore, the old client<br>
&gt; -+     * should refrain from listening for any more requests.<br>
&gt; -+     */<br>
&gt; -+    client-&gt;mortal = true;<br>
&gt; -+<br>
&gt; -     return (ISC_R_SUCCESS);<br>
&gt; - }<br>
&gt; - <br>
&gt; -@@ -3806,7 +3760,7 @@ ns_clientmgr_destroy(ns_clientmgr_t **managerp) {<br>
&gt; - <br>
&gt; - static isc_result_t<br>
&gt; - get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,<br>
&gt; --       dns_dispatch_t *disp, ns_client_t *oldclient, bool tcp)<br>
&gt; -+       dns_dispatch_t *disp, bool tcp)<br>
&gt; - {<br>
&gt; -     isc_result_t result = ISC_R_SUCCESS;<br>
&gt; -     isc_event_t *ev;<br>
&gt; -@@ -3850,15 +3804,7 @@ get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,<br>
&gt; -     client-&gt;dscp = ifp-&gt;dscp;<br>
&gt; - <br>
&gt; -     if (tcp) {<br>
&gt; --            client-&gt;tcpattached = false;<br>
&gt; --            if (oldclient != NULL) {<br>
&gt; --                    client-&gt;tcpattached = oldclient-&gt;tcpattached;<br>
&gt; --            }<br>
&gt; --<br>
&gt; --            LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --            client-&gt;interface-&gt;ntcpactive++;<br>
&gt; --            UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --            client-&gt;tcpactive = true;<br>
&gt; -+            mark_tcp_active(client, true);<br>
&gt; - <br>
&gt; -             client-&gt;attributes |= NS_CLIENTATTR_TCP;<br>
&gt; -             isc_socket_attach(ifp-&gt;tcpsocket,<br>
&gt; -@@ -3923,16 +3869,14 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock,<br>
&gt; -     ns_interface_attach(ifp, &amp;client-&gt;interface);<br>
&gt; -     client-&gt;newstate = client-&gt;state = NS_CLIENTSTATE_WORKING;<br>
&gt; -     INSIST(client-&gt;recursionquota == NULL);<br>
&gt; --    client-&gt;tcpquota = &amp;ns_g_server-&gt;tcpquota;<br>
&gt; --    client-&gt;tcpattached = oldclient-&gt;tcpattached;<br>
&gt; - <br>
&gt; -     client-&gt;dscp = ifp-&gt;dscp;<br>
&gt; - <br>
&gt; -     client-&gt;attributes |= NS_CLIENTATTR_TCP;<br>
&gt; -     client-&gt;mortal = true;<br>
&gt; - <br>
&gt; --    pipeline_attach(oldclient, client);<br>
&gt; --    client-&gt;pipelined = true;<br>
&gt; -+    tcpconn_attach(oldclient, client);<br>
&gt; -+    mark_tcp_active(client, true);<br>
&gt; - <br>
&gt; -     isc_socket_attach(ifp-&gt;tcpsocket, &amp;client-&gt;tcplistener);<br>
&gt; -     isc_socket_attach(sock, &amp;client-&gt;tcpsocket);<br>
&gt; -@@ -3940,11 +3884,6 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock,<br>
&gt; -     (void)isc_socket_getpeername(client-&gt;tcpsocket, &amp;client-&gt;peeraddr);<br>
&gt; -     client-&gt;peeraddr_valid = true;<br>
&gt; - <br>
&gt; --    LOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --    client-&gt;interface-&gt;ntcpactive++;<br>
&gt; --    UNLOCK(&amp;client-&gt;interface-&gt;lock);<br>
&gt; --    client-&gt;tcpactive = true;<br>
&gt; --<br>
&gt; -     INSIST(client-&gt;tcpmsg_valid == false);<br>
&gt; -     dns_tcpmsg_init(client-&gt;mctx, client-&gt;tcpsocket, &amp;client-&gt;tcpmsg);<br>
&gt; -     client-&gt;tcpmsg_valid = true;<br>
&gt; -@@ -3970,8 +3909,7 @@ ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,<br>
&gt; -     MTRACE(&quot;createclients&quot;);<br>
&gt; - <br>
&gt; -     for (disp = 0; disp &lt; n; disp++) {<br>
&gt; --            result = get_client(manager, ifp, ifp-&gt;udpdispatch[disp],<br>
&gt; --                                NULL, tcp);<br>
&gt; -+            result = get_client(manager, ifp, ifp-&gt;udpdispatch[disp], tcp);<br>
&gt; -             if (result != ISC_R_SUCCESS)<br>
&gt; -                     break;<br>
&gt; -     }<br>
&gt; -diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h<br>
&gt; -index e2c40acd28..969ee4c08f 100644<br>
&gt; ---- a/bin/named/include/named/client.h<br>
&gt; -+++ b/bin/named/include/named/client.h<br>
&gt; -@@ -78,6 +78,13 @@<br>
&gt; -  *** Types<br>
&gt; -  ***/<br>
&gt; - <br>
&gt; -+/*% reference-counted TCP connection object */<br>
&gt; -+typedef struct ns_tcpconn {<br>
&gt; -+    isc_refcount_t          refs;<br>
&gt; -+    isc_quota_t             *tcpquota;<br>
&gt; -+    bool                    pipelined;<br>
&gt; -+} ns_tcpconn_t;<br>
&gt; -+<br>
&gt; - /*% nameserver client structure */<br>
&gt; - struct ns_client {<br>
&gt; -     unsigned int            magic;<br>
&gt; -@@ -131,10 +138,7 @@ struct ns_client {<br>
&gt; -     dns_name_t              signername;   /*%&lt; [T]SIG key name */<br>
&gt; -     dns_name_t              *signer;      /*%&lt; NULL if not valid sig */<br>
&gt; -     bool                    mortal;       /*%&lt; Die after handling request */<br>
&gt; --    bool                    pipelined;   /*%&lt; TCP queries not in sequence */<br>
&gt; --    isc_refcount_t          *pipeline_refs;<br>
&gt; --    isc_quota_t             *tcpquota;<br>
&gt; --    bool                    tcpattached;<br>
&gt; -+    ns_tcpconn_t            *tcpconn;<br>
&gt; -     isc_quota_t             *recursionquota;<br>
&gt; -     ns_interface_t          *interface;<br>
&gt; - <br>
&gt; -diff --git a/bin/named/include/named/interfacemgr.h b/bin/named/include/named/interfacemgr.h<br>
&gt; -index 61b08826a6..3535ef22a8 100644<br>
&gt; ---- a/bin/named/include/named/interfacemgr.h<br>
&gt; -+++ b/bin/named/include/named/interfacemgr.h<br>
&gt; -@@ -9,8 +9,6 @@<br>
&gt; -  * information regarding copyright ownership.<br>
&gt; -  */<br>
&gt; - <br>
&gt; --/* $Id: interfacemgr.h,v 1.35 2011/07/28 23:47:58 tbox Exp $ */<br>
&gt; --<br>
&gt; - #ifndef NAMED_INTERFACEMGR_H<br>
&gt; - #define NAMED_INTERFACEMGR_H 1<br>
&gt; - <br>
&gt; -@@ -77,11 +75,11 @@ struct ns_interface {<br>
&gt; -                                             /*%&lt; UDP dispatchers. */<br>
&gt; -     isc_socket_t *          tcpsocket;      /*%&lt; TCP socket. */<br>
&gt; -     isc_dscp_t              dscp;           /*%&lt; &quot;listen-on&quot; DSCP value */<br>
&gt; --    int                     ntcpaccepting;  /*%&lt; Number of clients<br>
&gt; -+    int32_t                 ntcpaccepting;  /*%&lt; Number of clients<br>
&gt; -                                                  ready to accept new<br>
&gt; -                                                  TCP connections on this<br>
&gt; -                                                  interface */<br>
&gt; --    int                     ntcpactive;     /*%&lt; Number of clients<br>
&gt; -+    int32_t                 ntcpactive;     /*%&lt; Number of clients<br>
&gt; -                                                  servicing TCP queries<br>
&gt; -                                                  (whether accepting or<br>
&gt; -                                                  connected) */<br>
&gt; -diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c<br>
&gt; -index 955096ef47..d9f6df5802 100644<br>
&gt; ---- a/bin/named/interfacemgr.c<br>
&gt; -+++ b/bin/named/interfacemgr.c<br>
&gt; -@@ -388,6 +388,7 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,<br>
&gt; -      */<br>
&gt; -     ifp-&gt;ntcpaccepting = 0;<br>
&gt; -     ifp-&gt;ntcpactive = 0;<br>
&gt; -+<br>
&gt; -     ifp-&gt;nudpdispatch = 0;<br>
&gt; - <br>
&gt; -     ifp-&gt;dscp = -1;<br>
&gt; -diff --git a/lib/isc/include/isc/quota.h b/lib/isc/include/isc/quota.h<br>
&gt; -index b9bf59877a..36c5830242 100644<br>
&gt; ---- a/lib/isc/include/isc/quota.h<br>
&gt; -+++ b/lib/isc/include/isc/quota.h<br>
&gt; -@@ -100,6 +100,13 @@ isc_quota_attach(isc_quota_t *quota, isc_quota_t **p);<br>
&gt; -  * quota if successful (ISC_R_SUCCESS or ISC_R_SOFTQUOTA).<br>
&gt; -  */<br>
&gt; - <br>
&gt; -+isc_result_t<br>
&gt; -+isc_quota_force(isc_quota_t *quota, isc_quota_t **p);<br>
&gt; -+/*%&lt;<br>
&gt; -+ * Like isc_quota_attach, but will attach &#39;*p&#39; to the quota<br>
&gt; -+ * even if the hard quota has been exceeded.<br>
&gt; -+ */<br>
&gt; -+<br>
&gt; - void<br>
&gt; - isc_quota_detach(isc_quota_t **p);<br>
&gt; - /*%&lt;<br>
&gt; -diff --git a/lib/isc/quota.c b/lib/isc/quota.c<br>
&gt; -index 3ddff0d875..556a61f21d 100644<br>
&gt; ---- a/lib/isc/quota.c<br>
&gt; -+++ b/lib/isc/quota.c<br>
&gt; -@@ -74,20 +74,39 @@ isc_quota_release(isc_quota_t *quota) {<br>
&gt; -     UNLOCK(&amp;quota-&gt;lock);<br>
&gt; - }<br>
&gt; - <br>
&gt; --isc_result_t<br>
&gt; --isc_quota_attach(isc_quota_t *quota, isc_quota_t **p)<br>
&gt; --{<br>
&gt; -+static isc_result_t<br>
&gt; -+doattach(isc_quota_t *quota, isc_quota_t **p, bool force) {<br>
&gt; -     isc_result_t result;<br>
&gt; --    INSIST(p != NULL &amp;&amp; *p == NULL);<br>
&gt; -+    REQUIRE(p != NULL &amp;&amp; *p == NULL);<br>
&gt; -+<br>
&gt; -     result = isc_quota_reserve(quota);<br>
&gt; --    if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA)<br>
&gt; -+    if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA) {<br>
&gt; -+            *p = quota;<br>
&gt; -+    } else if (result == ISC_R_QUOTA &amp;&amp; force) {<br>
&gt; -+            /* attach anyway */<br>
&gt; -+            LOCK(&amp;quota-&gt;lock);<br>
&gt; -+            quota-&gt;used++;<br>
&gt; -+            UNLOCK(&amp;quota-&gt;lock);<br>
&gt; -+<br>
&gt; -             *p = quota;<br>
&gt; -+            result = ISC_R_SUCCESS;<br>
&gt; -+    }<br>
&gt; -+<br>
&gt; -     return (result);<br>
&gt; - }<br>
&gt; - <br>
&gt; -+isc_result_t<br>
&gt; -+isc_quota_attach(isc_quota_t *quota, isc_quota_t **p) {<br>
&gt; -+    return (doattach(quota, p, false));<br>
&gt; -+}<br>
&gt; -+<br>
&gt; -+isc_result_t<br>
&gt; -+isc_quota_force(isc_quota_t *quota, isc_quota_t **p) {<br>
&gt; -+    return (doattach(quota, p, true));<br>
&gt; -+}<br>
&gt; -+<br>
&gt; - void<br>
&gt; --isc_quota_detach(isc_quota_t **p)<br>
&gt; --{<br>
&gt; -+isc_quota_detach(isc_quota_t **p) {<br>
&gt; -     INSIST(p != NULL &amp;&amp; *p != NULL);<br>
&gt; -     isc_quota_release(*p);<br>
&gt; -     *p = NULL;<br>
&gt; -diff --git a/lib/isc/win32/<a href="http://libisc.def.in" rel="noreferrer" target="_blank">libisc.def.in</a> b/lib/isc/win32/<a href="http://libisc.def.in" rel="noreferrer" target="_blank">libisc.def.in</a><br>
&gt; -index a82facec0f..7b9f23d776 100644<br>
&gt; ---- a/lib/isc/win32/<a href="http://libisc.def.in" rel="noreferrer" target="_blank">libisc.def.in</a><br>
&gt; -+++ b/lib/isc/win32/<a href="http://libisc.def.in" rel="noreferrer" target="_blank">libisc.def.in</a><br>
&gt; -@@ -519,6 +519,7 @@ isc_portset_removerange<br>
&gt; - isc_quota_attach<br>
&gt; - isc_quota_destroy<br>
&gt; - isc_quota_detach<br>
&gt; -+isc_quota_force<br>
&gt; - isc_quota_init<br>
&gt; - isc_quota_max<br>
&gt; - isc_quota_release<br>
&gt; --- <br>
&gt; -2.20.1<br>
&gt; -<br>
&gt; diff --git a/meta/recipes-connectivity/bind/bind/0006-restore-allowance-for-tcp-clients-interfaces.patch b/meta/recipes-connectivity/bind/bind/0006-restore-allowance-for-tcp-clients-interfaces.patch<br>
&gt; deleted file mode 100644<br>
&gt; index 3821d185012..00000000000<br>
&gt; --- a/meta/recipes-connectivity/bind/bind/0006-restore-allowance-for-tcp-clients-interfaces.patch<br>
&gt; +++ /dev/null<br>
&gt; @@ -1,80 +0,0 @@<br>
&gt; -Backport patch to fix CVE-2018-5743.<br>
&gt; -<br>
&gt; -Ref:<br>
&gt; -<a href="https://security-tracker.debian.org/tracker/CVE-2018-5743" rel="noreferrer" target="_blank">https://security-tracker.debian.org/tracker/CVE-2018-5743</a><br>
&gt; -<br>
&gt; -CVE: CVE-2018-5743<br>
&gt; -Upstream-Status: Backport [<a href="https://gitlab.isc.org/isc-projects/bind9/commit/59434b9" rel="noreferrer" target="_blank">https://gitlab.isc.org/isc-projects/bind9/commit/59434b9</a>]<br>
&gt; -<br>
&gt; -Signed-off-by: Kai Kang &lt;<a href="mailto:kai.kang@windriver.com" target="_blank">kai.kang@windriver.com</a>&gt;<br>
&gt; -<br>
&gt; -From 59434b987e8eb436b08c24e559ee094c4e939daa Mon Sep 17 00:00:00 2001<br>
&gt; -From: Evan Hunt &lt;<a href="mailto:each@isc.org" target="_blank">each@isc.org</a>&gt;<br>
&gt; -Date: Fri, 5 Apr 2019 16:26:19 -0700<br>
&gt; -Subject: [PATCH 6/6] restore allowance for tcp-clients &lt; interfaces<br>
&gt; -<br>
&gt; -in the &quot;refactor tcpquota and pipeline refs&quot; commit, the counting<br>
&gt; -of active interfaces was tightened in such a way that named could<br>
&gt; -fail to listen on an interface if there were more interfaces than<br>
&gt; -tcp-clients. when checking the quota to start accepting on an<br>
&gt; -interface, if the number of active clients was above zero, then<br>
&gt; -it was presumed that some other client was able to handle accepting<br>
&gt; -new connections. this, however, ignored the fact that the current client<br>
&gt; -could be included in that count, so if the quota was already exceeded<br>
&gt; -before all the interfaces were listening, some interfaces would never<br>
&gt; -listen.<br>
&gt; -<br>
&gt; -we now check whether the current client has been marked active; if so,<br>
&gt; -then the number of active clients on the interface must be greater<br>
&gt; -than 1, not 0.<br>
&gt; -<br>
&gt; -(cherry picked from commit 0b4e2cd4c3192ba88569dd344f542a8cc43742b5)<br>
&gt; -(cherry picked from commit d01023aaac35543daffbdf48464e320150235d41)<br>
&gt; ----<br>
&gt; - bin/named/client.c      | 8 +++++---<br>
&gt; - doc/arm/Bv9ARM-book.xml | 3 ++-<br>
&gt; - 2 files changed, 7 insertions(+), 4 deletions(-)<br>
&gt; -<br>
&gt; -diff --git a/bin/named/client.c b/bin/named/client.c<br>
&gt; -index d826ab32bf..845326abc0 100644<br>
&gt; ---- a/bin/named/client.c<br>
&gt; -+++ b/bin/named/client.c<br>
&gt; -@@ -3464,8 +3464,9 @@ client_accept(ns_client_t *client) {<br>
&gt; -              *<br>
&gt; -              * So, we check here to see if any other clients are<br>
&gt; -              * already servicing TCP queries on this interface (whether<br>
&gt; --             * accepting, reading, or processing). If we find at least<br>
&gt; --             * one, then it&#39;s okay *not* to call accept - we can let this<br>
&gt; -+             * accepting, reading, or processing). If we find that at<br>
&gt; -+             * least one client other than this one is active, then<br>
&gt; -+             * it&#39;s okay *not* to call accept - we can let this<br>
&gt; -              * client go inactive and another will take over when it&#39;s<br>
&gt; -              * done.<br>
&gt; -              *<br>
&gt; -@@ -3479,7 +3480,8 @@ client_accept(ns_client_t *client) {<br>
&gt; -              * quota is tcp-clients plus the number of listening<br>
&gt; -              * interfaces plus 1.)<br>
&gt; -              */<br>
&gt; --            exit = (isc_atomic_xadd(&amp;client-&gt;interface-&gt;ntcpactive, 0) &gt; 0);<br>
&gt; -+            exit = (isc_atomic_xadd(&amp;client-&gt;interface-&gt;ntcpactive, 0) &gt;<br>
&gt; -+                    (client-&gt;tcpactive ? 1 : 0));<br>
&gt; -             if (exit) {<br>
&gt; -                     client-&gt;newstate = NS_CLIENTSTATE_INACTIVE;<br>
&gt; -                     (void)exit_check(client);<br>
&gt; -diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml<br>
&gt; -index 381768d540..9c76d3cd6f 100644<br>
&gt; ---- a/doc/arm/Bv9ARM-book.xml<br>
&gt; -+++ b/doc/arm/Bv9ARM-book.xml<br>
&gt; -@@ -8493,7 +8493,8 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };<br>
&gt; -             &lt;para&gt;<br>
&gt; -               The number of file descriptors reserved for TCP, stdio,<br>
&gt; -               etc.  This needs to be big enough to cover the number of<br>
&gt; --              interfaces &lt;command&gt;named&lt;/command&gt; listens on, &lt;command&gt;tcp-clients&lt;/command&gt; as well as<br>
&gt; -+              interfaces &lt;command&gt;named&lt;/command&gt; listens on plus<br>
&gt; -+              &lt;command&gt;tcp-clients&lt;/command&gt;, as well as<br>
&gt; -               to provide room for outgoing TCP queries and incoming zone<br>
&gt; -               transfers.  The default is &lt;literal&gt;512&lt;/literal&gt;.<br>
&gt; -               The minimum value is &lt;literal&gt;128&lt;/literal&gt; and the<br>
&gt; --- <br>
&gt; -2.20.1<br>
&gt; -<br>
&gt; diff --git a/meta/recipes-connectivity/bind/bind/0007-Replace-atomic-operations-in-bin-named-client.c-with.patch b/meta/recipes-connectivity/bind/bind/0007-Replace-atomic-operations-in-bin-named-client.c-with.patch<br>
&gt; deleted file mode 100644<br>
&gt; index 1a84eca58a7..00000000000<br>
&gt; --- a/meta/recipes-connectivity/bind/bind/0007-Replace-atomic-operations-in-bin-named-client.c-with.patch<br>
&gt; +++ /dev/null<br>
&gt; @@ -1,140 +0,0 @@<br>
&gt; -Backport commit to fix compile error on arm caused by commits which are<br>
&gt; -to fix CVE-2018-5743.<br>
&gt; -<br>
&gt; -CVE: CVE-2018-5743<br>
&gt; -Upstream-Status: Backport [<a href="https://gitlab.isc.org/isc-projects/bind9/commit/ef49780" rel="noreferrer" target="_blank">https://gitlab.isc.org/isc-projects/bind9/commit/ef49780</a>]<br>
&gt; -<br>
&gt; -Signed-off-by: Kai Kang &lt;<a href="mailto:kai.kang@windriver.com" target="_blank">kai.kang@windriver.com</a>&gt;<br>
&gt; -<br>
&gt; -From ef49780d30d3ddc5735cfc32561b678a634fa72f Mon Sep 17 00:00:00 2001<br>
&gt; -From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= &lt;<a href="mailto:ondrej@sury.org" target="_blank">ondrej@sury.org</a>&gt;<br>
&gt; -Date: Wed, 17 Apr 2019 15:22:27 +0200<br>
&gt; -Subject: [PATCH] Replace atomic operations in bin/named/client.c with<br>
&gt; - isc_refcount reference counting<br>
&gt; -<br>
&gt; ----<br>
&gt; - bin/named/client.c                     | 18 +++++++-----------<br>
&gt; - bin/named/include/named/interfacemgr.h |  5 +++--<br>
&gt; - bin/named/interfacemgr.c               |  7 +++++--<br>
&gt; - 3 files changed, 15 insertions(+), 15 deletions(-)<br>
&gt; -<br>
&gt; -diff --git a/bin/named/client.c b/bin/named/client.c<br>
&gt; -index 845326abc0..29fecadca8 100644<br>
&gt; ---- a/bin/named/client.c<br>
&gt; -+++ b/bin/named/client.c<br>
&gt; -@@ -402,12 +402,10 @@ tcpconn_detach(ns_client_t *client) {<br>
&gt; - static void<br>
&gt; - mark_tcp_active(ns_client_t *client, bool active) {<br>
&gt; -     if (active &amp;&amp; !client-&gt;tcpactive) {<br>
&gt; --            isc_atomic_xadd(&amp;client-&gt;interface-&gt;ntcpactive, 1);<br>
&gt; -+            isc_refcount_increment0(&amp;client-&gt;interface-&gt;ntcpactive, NULL);<br>
&gt; -             client-&gt;tcpactive = active;<br>
&gt; -     } else if (!active &amp;&amp; client-&gt;tcpactive) {<br>
&gt; --            uint32_t old =<br>
&gt; --                    isc_atomic_xadd(&amp;client-&gt;interface-&gt;ntcpactive, -1);<br>
&gt; --            INSIST(old &gt; 0);<br>
&gt; -+            isc_refcount_decrement(&amp;client-&gt;interface-&gt;ntcpactive, NULL);<br>
&gt; -             client-&gt;tcpactive = active;<br>
&gt; -     }<br>
&gt; - }<br>
&gt; -@@ -554,7 +552,7 @@ exit_check(ns_client_t *client) {<br>
&gt; -             if (client-&gt;mortal &amp;&amp; TCP_CLIENT(client) &amp;&amp;<br>
&gt; -                 client-&gt;newstate != NS_CLIENTSTATE_FREED &amp;&amp;<br>
&gt; -                 !ns_g_clienttest &amp;&amp;<br>
&gt; --                isc_atomic_xadd(&amp;client-&gt;interface-&gt;ntcpaccepting, 0) == 0)<br>
&gt; -+                isc_refcount_current(&amp;client-&gt;interface-&gt;ntcpaccepting) == 0)<br>
&gt; -             {<br>
&gt; -                     /* Nobody else is accepting */<br>
&gt; -                     client-&gt;mortal = false;<br>
&gt; -@@ -3328,7 +3326,6 @@ client_newconn(isc_task_t *task, isc_event_t *event) {<br>
&gt; -     isc_result_t result;<br>
&gt; -     ns_client_t *client = event-&gt;ev_arg;<br>
&gt; -     isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event;<br>
&gt; --    uint32_t old;<br>
&gt; - <br>
&gt; -     REQUIRE(event-&gt;ev_type == ISC_SOCKEVENT_NEWCONN);<br>
&gt; -     REQUIRE(NS_CLIENT_VALID(client));<br>
&gt; -@@ -3348,8 +3345,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) {<br>
&gt; -     INSIST(client-&gt;naccepts == 1);<br>
&gt; -     client-&gt;naccepts--;<br>
&gt; - <br>
&gt; --    old = isc_atomic_xadd(&amp;client-&gt;interface-&gt;ntcpaccepting, -1);<br>
&gt; --    INSIST(old &gt; 0);<br>
&gt; -+    isc_refcount_decrement(&amp;client-&gt;interface-&gt;ntcpaccepting, NULL);<br>
&gt; - <br>
&gt; -     /*<br>
&gt; -      * We must take ownership of the new socket before the exit<br>
&gt; -@@ -3480,8 +3476,8 @@ client_accept(ns_client_t *client) {<br>
&gt; -              * quota is tcp-clients plus the number of listening<br>
&gt; -              * interfaces plus 1.)<br>
&gt; -              */<br>
&gt; --            exit = (isc_atomic_xadd(&amp;client-&gt;interface-&gt;ntcpactive, 0) &gt;<br>
&gt; --                    (client-&gt;tcpactive ? 1 : 0));<br>
&gt; -+            exit = (isc_refcount_current(&amp;client-&gt;interface-&gt;ntcpactive) &gt;<br>
&gt; -+                    (client-&gt;tcpactive ? 1U : 0U));<br>
&gt; -             if (exit) {<br>
&gt; -                     client-&gt;newstate = NS_CLIENTSTATE_INACTIVE;<br>
&gt; -                     (void)exit_check(client);<br>
&gt; -@@ -3539,7 +3535,7 @@ client_accept(ns_client_t *client) {<br>
&gt; -      * listening for connections itself to prevent the interface<br>
&gt; -      * going dead.<br>
&gt; -      */<br>
&gt; --    isc_atomic_xadd(&amp;client-&gt;interface-&gt;ntcpaccepting, 1);<br>
&gt; -+    isc_refcount_increment0(&amp;client-&gt;interface-&gt;ntcpaccepting, NULL);<br>
&gt; - }<br>
&gt; - <br>
&gt; - static void<br>
&gt; -diff --git a/bin/named/include/named/interfacemgr.h b/bin/named/include/named/interfacemgr.h<br>
&gt; -index 3535ef22a8..6e10f210fd 100644<br>
&gt; ---- a/bin/named/include/named/interfacemgr.h<br>
&gt; -+++ b/bin/named/include/named/interfacemgr.h<br>
&gt; -@@ -45,6 +45,7 @@<br>
&gt; - #include &lt;isc/magic.h&gt;<br>
&gt; - #include &lt;isc/mem.h&gt;<br>
&gt; - #include &lt;isc/socket.h&gt;<br>
&gt; -+#include &lt;isc/refcount.h&gt;<br>
&gt; - <br>
&gt; - #include &lt;dns/result.h&gt;<br>
&gt; - <br>
&gt; -@@ -75,11 +76,11 @@ struct ns_interface {<br>
&gt; -                                             /*%&lt; UDP dispatchers. */<br>
&gt; -     isc_socket_t *          tcpsocket;      /*%&lt; TCP socket. */<br>
&gt; -     isc_dscp_t              dscp;           /*%&lt; &quot;listen-on&quot; DSCP value */<br>
&gt; --    int32_t                 ntcpaccepting;  /*%&lt; Number of clients<br>
&gt; -+    isc_refcount_t          ntcpaccepting;  /*%&lt; Number of clients<br>
&gt; -                                                  ready to accept new<br>
&gt; -                                                  TCP connections on this<br>
&gt; -                                                  interface */<br>
&gt; --    int32_t                 ntcpactive;     /*%&lt; Number of clients<br>
&gt; -+    isc_refcount_t          ntcpactive;     /*%&lt; Number of clients<br>
&gt; -                                                  servicing TCP queries<br>
&gt; -                                                  (whether accepting or<br>
&gt; -                                                  connected) */<br>
&gt; -diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c<br>
&gt; -index d9f6df5802..135533be6b 100644<br>
&gt; ---- a/bin/named/interfacemgr.c<br>
&gt; -+++ b/bin/named/interfacemgr.c<br>
&gt; -@@ -386,8 +386,8 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,<br>
&gt; -      * connections will be handled in parallel even though there is<br>
&gt; -      * only one client initially.<br>
&gt; -      */<br>
&gt; --    ifp-&gt;ntcpaccepting = 0;<br>
&gt; --    ifp-&gt;ntcpactive = 0;<br>
&gt; -+    isc_refcount_init(&amp;ifp-&gt;ntcpaccepting, 0);<br>
&gt; -+    isc_refcount_init(&amp;ifp-&gt;ntcpactive, 0);<br>
&gt; - <br>
&gt; -     ifp-&gt;nudpdispatch = 0;<br>
&gt; - <br>
&gt; -@@ -618,6 +618,9 @@ ns_interface_destroy(ns_interface_t *ifp) {<br>
&gt; - <br>
&gt; -     ns_interfacemgr_detach(&amp;ifp-&gt;mgr);<br>
&gt; - <br>
&gt; -+    isc_refcount_destroy(&amp;ifp-&gt;ntcpactive);<br>
&gt; -+    isc_refcount_destroy(&amp;ifp-&gt;ntcpaccepting);<br>
&gt; -+<br>
&gt; -     ifp-&gt;magic = 0;<br>
&gt; -     isc_mem_put(mctx, ifp, sizeof(*ifp));<br>
&gt; - }<br>
&gt; --- <br>
&gt; -2.20.1<br>
&gt; -<br>
&gt; diff --git a/meta/recipes-connectivity/bind/bind/bind-ensure-searching-for-json-headers-searches-sysr.patch b/meta/recipes-connectivity/bind/bind/bind-ensure-searching-for-json-headers-searches-sysr.patch<br>
&gt; index 37e210e6da9..84559e5f378 100644<br>
&gt; --- a/meta/recipes-connectivity/bind/bind/bind-ensure-searching-for-json-headers-searches-sysr.patch<br>
&gt; +++ b/meta/recipes-connectivity/bind/bind/bind-ensure-searching-for-json-headers-searches-sysr.patch<br>
&gt; @@ -1,4 +1,4 @@<br>
&gt; -From 9473d29843579802e96b0293a3e953fed93de82c Mon Sep 17 00:00:00 2001<br>
&gt; +From edda20fb5a6e88548f85e39d34d6c074306e15bc Mon Sep 17 00:00:00 2001<br>
&gt;  From: Paul Gortmaker &lt;<a href="mailto:paul.gortmaker@windriver.com" target="_blank">paul.gortmaker@windriver.com</a>&gt;<br>
&gt;  Date: Tue, 9 Jun 2015 11:22:00 -0400<br>
&gt;  Subject: [PATCH] bind: ensure searching for json headers searches sysroot<br>
&gt; @@ -27,15 +27,16 @@ to make use of the combination some day.<br>
&gt;  <br>
&gt;  Upstream-Status: Inappropriate [OE Specific]<br>
&gt;  Signed-off-by: Paul Gortmaker &lt;<a href="mailto:paul.gortmaker@windriver.com" target="_blank">paul.gortmaker@windriver.com</a>&gt;<br>
&gt; +<br>
&gt;  ---<br>
&gt; - <a href="http://configure.in" rel="noreferrer" target="_blank">configure.in</a> | 2 +-<br>
&gt; + <a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a> | 2 +-<br>
&gt;   1 file changed, 1 insertion(+), 1 deletion(-)<br>
&gt;  <br>
&gt; -Index: bind-9.11.3/<a href="http://configure.in" rel="noreferrer" target="_blank">configure.in</a><br>
&gt; -===================================================================<br>
&gt; ---- bind-9.11.3.orig/<a href="http://configure.in" rel="noreferrer" target="_blank">configure.in</a><br>
&gt; -+++ bind-9.11.3/<a href="http://configure.in" rel="noreferrer" target="_blank">configure.in</a><br>
&gt; -@@ -2574,7 +2574,7 @@ case &quot;$use_libjson&quot; in<br>
&gt; +diff --git a/<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a> b/<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a><br>
&gt; +index 17392fd..e85a5c6 100644<br>
&gt; +--- a/<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a><br>
&gt; ++++ b/<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a><br>
&gt; +@@ -2449,7 +2449,7 @@ case &quot;$use_libjson&quot; in<br>
&gt;               libjson_libs=&quot;&quot;<br>
&gt;               ;;<br>
&gt;       auto|yes)<br>
&gt; diff --git a/meta/recipes-connectivity/bind/<a href="http://bind_9.11.5-P4.bb" rel="noreferrer" target="_blank">bind_9.11.5-P4.bb</a> b/meta/recipes-connectivity/bind/<a href="http://bind_9.11.13.bb" rel="noreferrer" target="_blank">bind_9.11.13.bb</a><br>
&gt; similarity index 86%<br>
&gt; rename from meta/recipes-connectivity/bind/<a href="http://bind_9.11.5-P4.bb" rel="noreferrer" target="_blank">bind_9.11.5-P4.bb</a><br>
&gt; rename to meta/recipes-connectivity/bind/<a href="http://bind_9.11.13.bb" rel="noreferrer" target="_blank">bind_9.11.13.bb</a><br>
&gt; index 0897706346b..338d6c717a6 100644<br>
&gt; --- a/meta/recipes-connectivity/bind/<a href="http://bind_9.11.5-P4.bb" rel="noreferrer" target="_blank">bind_9.11.5-P4.bb</a><br>
&gt; +++ b/meta/recipes-connectivity/bind/<a href="http://bind_9.11.13.bb" rel="noreferrer" target="_blank">bind_9.11.13.bb</a><br>
&gt; @@ -15,23 +15,13 @@ SRC_URI = &quot;<a href="https://ftp.isc.org/isc/bind9/$%7BPV%7D/$%7BBPN%7D-$%7BPV%7D.tar.gz" rel="noreferrer" target="_blank">https://ftp.isc.org/isc/bind9/${PV}/${BPN}-${PV}.tar.gz</a> \<br>
&gt;             file://make-etc-initd-bind-stop-work.patch \<br>
&gt;             file://init.d-add-support-for-read-only-rootfs.patch \<br>
&gt;             file://bind-ensure-searching-for-json-headers-searches-sysr.patch \<br>
&gt; -           file://0001-gen.c-extend-DIRNAMESIZE-from-256-to-512.patch \<br>
&gt; -           file://0001-lib-dns-gen.c-fix-too-long-error.patch \<br>
&gt;             file://0001-configure.in-remove-useless-L-use_openssl-lib.patch \<br>
&gt;             file://0001-named-lwresd-V-and-start-log-hide-build-options.patch \<br>
&gt;             file://0001-avoid-start-failure-with-bind-user.patch \<br>
&gt; -           file://0001-bind-fix-CVE-2019-6471.patch \<br>
&gt; -           file://0001-fix-enforcement-of-tcp-clients-v1.patch \<br>
&gt; -           file://0002-tcp-clients-could-still-be-exceeded-v2.patch \<br>
&gt; -           file://0003-use-reference-counter-for-pipeline-groups-v3.patch \<br>
&gt; -           file://0004-better-tcpquota-accounting-and-client-mortality-chec.patch \<br>
&gt; -           file://0005-refactor-tcpquota-and-pipeline-refs-allow-special-ca.patch \<br>
&gt; -           file://0006-restore-allowance-for-tcp-clients-interfaces.patch \<br>
&gt; -           file://0007-Replace-atomic-operations-in-bin-named-client.c-with.patch \<br>
&gt; -&quot;<br>
&gt; -<br>
&gt; -SRC_URI[md5sum] = &quot;8ddab4b61fa4516fe404679c74e37960&quot;<br>
&gt; -SRC_URI[sha256sum] = &quot;7e8c08192bcbaeb6e9f2391a70e67583b027b90e8c4bc1605da6eb126edde434&quot;<br>
&gt; +           &quot;<br>
&gt; +<br>
&gt; +SRC_URI[md5sum] = &quot;17de0d024ab1eac377f1c2854dc25057&quot;<br>
&gt; +SRC_URI[sha256sum] = &quot;fd3f3cc9fcfcdaa752db35eb24598afa1fdcc2509d3227fc90a8631b7b400f7d&quot;<br>
&gt;  <br>
&gt;  UPSTREAM_CHECK_URI = &quot;<a href="https://ftp.isc.org/isc/bind9/" rel="noreferrer" target="_blank">https://ftp.isc.org/isc/bind9/</a>&quot;<br>
&gt;  # stay at 9.11 until 9.16, from 9.16 follow the ESV versions divisible by 4<br>
<br>
</blockquote></div></div>