]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[v9_11] fix tcp client memory leak
authorEvan Hunt <each@isc.org>
Mon, 29 Aug 2016 18:56:56 +0000 (11:56 -0700)
committerEvan Hunt <each@isc.org>
Mon, 29 Aug 2016 18:56:56 +0000 (11:56 -0700)
4459. [bug] TCP client objects created to handle pipeline queries
were not cleaned up correctly, causing uncontrolled
memory growth. [RT #43106]

(cherry picked from commit a26a62cef2adba0520c5955d740fc75fa7f2c7f5)

CHANGES
bin/dig/dighost.c
bin/named/client.c
bin/named/geoip.c
bin/tests/system/cacheclean/tests.sh

diff --git a/CHANGES b/CHANGES
index ff86c43287fdc2fd7bbbaa1ef91966f7d30d84a9..47756108df7a733c8e18285fa265c5cac7dddaeb 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,9 @@
        --- 9.11.0rc1 released ---
 
+4459.  [bug]           TCP client objects created to handle pipeline queries
+                       were not cleaned up correctly, causing uncontrolled
+                       memory growth. [RT #43106]
+
 4458.  [cleanup]       Update assertions to be more correct, and also remove
                        use of a reserved word. [RT #43090]
 
index b5b92992f216277a312b07edb52471f881b7c03f..675bf70fdd8f9f694cff5cc7d0c5b7920062a56d 100644 (file)
@@ -4690,27 +4690,33 @@ chase_scanname(dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers)
             msg = ISC_LIST_NEXT(msg, link)) {
                if (dns_message_firstname(msg->msg, DNS_SECTION_ANSWER)
                    == ISC_R_SUCCESS)
+               {
                        rdataset = chase_scanname_section(msg->msg, name,
                                                          type, covers,
                                                          DNS_SECTION_ANSWER);
                        if (rdataset != NULL)
                                return (rdataset);
+               }
                if (dns_message_firstname(msg->msg, DNS_SECTION_AUTHORITY)
                    == ISC_R_SUCCESS)
+               {
                        rdataset =
                                chase_scanname_section(msg->msg, name,
                                                       type, covers,
                                                       DNS_SECTION_AUTHORITY);
                        if (rdataset != NULL)
                                return (rdataset);
+               }
                if (dns_message_firstname(msg->msg, DNS_SECTION_ADDITIONAL)
                    == ISC_R_SUCCESS)
+               {
                        rdataset =
                                chase_scanname_section(msg->msg, name, type,
                                                       covers,
                                                       DNS_SECTION_ADDITIONAL);
                        if (rdataset != NULL)
                                return (rdataset);
+               }
        }
 
        return (NULL);
index 20963eb46fe5bb6530b54e9c7bce60144d6d2939..df6e5d1c686df7263344767bd249d349b3a28fa2 100644 (file)
@@ -3543,6 +3543,7 @@ get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *sock)
 
        client->attributes |= NS_CLIENTATTR_TCP;
        client->pipelined = ISC_TRUE;
+       client->mortal = ISC_TRUE;
 
        isc_socket_attach(ifp->tcpsocket, &client->tcplistener);
        isc_socket_attach(sock, &client->tcpsocket);
@@ -3672,7 +3673,6 @@ ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
               isc_logmodule_t *module, int level, const char *fmt, va_list ap)
 {
        char msgbuf[4096];
-       char peerbuf[ISC_SOCKADDR_FORMATSIZE];
        char signerbuf[DNS_NAME_FORMATSIZE], qnamebuf[DNS_NAME_FORMATSIZE];
        const char *viewname = "";
        const char *sep1 = "", *sep2 = "", *sep3 = "", *sep4 = "";
@@ -3681,8 +3681,6 @@ ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
 
        vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
 
-       ns_client_name(client, peerbuf, sizeof(peerbuf));
-
        if (client->signer != NULL) {
                dns_name_format(client->signer, signerbuf, sizeof(signerbuf));
                sep1 = "/key ";
@@ -3704,10 +3702,21 @@ ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
                viewname = client->view->name;
        }
 
-       isc_log_write(ns_g_lctx, category, module, level,
-                     "client %s%s%s%s%s%s%s%s: %s",
-                     peerbuf, sep1, signer, sep2, qname, sep3,
-                     sep4, viewname, msgbuf);
+       if (client->peeraddr_valid) {
+               char peerbuf[ISC_SOCKADDR_FORMATSIZE];
+
+               isc_sockaddr_format(&client->peeraddr,
+                                   peerbuf, sizeof(peerbuf));
+               isc_log_write(ns_g_lctx, category, module, level,
+                             "client @%p %s%s%s%s%s%s%s%s: %s",
+                             client, peerbuf, sep1, signer, sep2, qname, sep3,
+                             sep4, viewname, msgbuf);
+       } else {
+               isc_log_write(ns_g_lctx, category, module, level,
+                             "client @%p%s%s%s%s%s%s%s: %s",
+                             client, sep1, signer, sep2, qname, sep3,
+                             sep4, viewname, msgbuf);
+       }
 }
 
 void
index f2e784b0e6246a0c7dcd50a73ee20be3b70de668..9c0b25a774ca1124e4bc1f089a8504738197d94d 100644 (file)
@@ -60,10 +60,12 @@ init_geoip_db(GeoIP **dbp, GeoIPDBTypes edition, GeoIPDBTypes fallback,
        }
 
        info = GeoIP_database_info(db);
-       if (info != NULL)
+       if (info != NULL) {
                isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
                              NS_LOGMODULE_SERVER, ISC_LOG_INFO,
                              "%s", info);
+               free(info);
+       }
 
        *dbp = db;
        return;
index fd455db14aad373fea81ba741f19a415436ca840..2c6f2ccac21f746e15b2cd3af3b26843932ef464 100644 (file)
@@ -82,7 +82,7 @@ grep ";" dig.out.ns2
 $PERL ../digcomp.pl --lc dig.out.ns2 knowngood.dig.out || status=1
 
 echo "I:only one tcp socket was used"
-tcpclients=`grep "client 10.53.0.7#[0-9]*:" ns2/named.run | awk '{print $4}' | sort | uniq -c | wc -l`
+tcpclients=`awk '$3 == "client" && $5 ~ /10.53.0.7#[0-9]*:/ {print $5}' ns2/named.run | sort | uniq -c | wc -l`
 
 test $tcpclients -eq 1 || { status=1; echo "I:failed"; }