]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Use appropriately sized send buffers for DNS messages over TCP
authorArtem Boldariev <artem@boldariev.com>
Fri, 2 Jun 2023 11:28:50 +0000 (14:28 +0300)
committerOndřej Surý <ondrej@isc.org>
Tue, 6 Jun 2023 11:40:42 +0000 (13:40 +0200)
This commit changes send buffers allocation strategy for stream based
transports. Before that change we would allocate a dynamic buffers
sized at 64Kb even when we do not need that much. That could lead to
high memory usage on server. Now we resize the send buffer to match
the size of the actual data, freeing the memory at the end of the
buffer for being reused later.

lib/ns/client.c
lib/ns/include/ns/client.h

index 7dc52b43c44d5aba714ac1304f8e8a957d86219e..395ebde6bf3e93cb8344a81a6a2d56a193e905e9 100644 (file)
@@ -331,6 +331,7 @@ client_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer,
                INSIST(client->tcpbuf == NULL);
                client->tcpbuf = isc_mem_get(client->manager->mctx,
                                             NS_CLIENT_TCP_BUFFER_SIZE);
+               client->tcpbuf_size = NS_CLIENT_TCP_BUFFER_SIZE;
                data = client->tcpbuf;
                isc_buffer_init(buffer, data, NS_CLIENT_TCP_BUFFER_SIZE);
        } else {
@@ -363,7 +364,17 @@ client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) {
 
        REQUIRE(client->sendhandle == NULL);
 
-       isc_buffer_usedregion(buffer, &r);
+       if (isc_buffer_base(buffer) == client->tcpbuf) {
+               size_t used = isc_buffer_usedlength(buffer);
+               client->tcpbuf = isc_mem_reget(client->manager->mctx,
+                                              client->tcpbuf,
+                                              client->tcpbuf_size, used);
+               client->tcpbuf_size = used;
+               r.base = client->tcpbuf;
+               r.length = used;
+       } else {
+               isc_buffer_usedregion(buffer, &r);
+       }
        isc_nmhandle_attach(client->handle, &client->sendhandle);
 
        if (isc_nm_is_http_handle(client->handle)) {
@@ -434,8 +445,7 @@ ns_client_sendraw(ns_client_t *client, dns_message_t *message) {
 done:
        if (client->tcpbuf != NULL) {
                isc_mem_put(client->manager->mctx, client->tcpbuf,
-                           NS_CLIENT_TCP_BUFFER_SIZE);
-               client->tcpbuf = NULL;
+                           client->tcpbuf_size);
        }
 
        ns_client_drop(client, result);
@@ -719,8 +729,7 @@ renderend:
 cleanup:
        if (client->tcpbuf != NULL) {
                isc_mem_put(client->manager->mctx, client->tcpbuf,
-                           NS_CLIENT_TCP_BUFFER_SIZE);
-               client->tcpbuf = NULL;
+                           client->tcpbuf_size);
        }
 
        if (cleanup_cctx) {
@@ -1609,7 +1618,7 @@ ns__client_reset_cb(void *client0) {
        ns_client_endrequest(client);
        if (client->tcpbuf != NULL) {
                isc_mem_put(client->manager->mctx, client->tcpbuf,
-                           NS_CLIENT_TCP_BUFFER_SIZE);
+                           client->tcpbuf_size);
        }
 
        if (client->keytag != NULL) {
index 28f4bfd9292101e8f4e3cba61a26933fcc064f8c..04dbb9c4a8b996c74d4481881f79bf492f68325a 100644 (file)
@@ -171,6 +171,7 @@ struct ns_client {
                                         (query, update, notify) */
        isc_nmhandle_t *updatehandle; /* Waiting for update callback */
        unsigned char  *tcpbuf;
+       size_t          tcpbuf_size;
        dns_message_t  *message;
        unsigned char  *sendbuf;
        dns_rdataset_t *opt;