]> 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 12:04:01 +0000 (14:04 +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.

(cherry picked from commit d8a5feb5567aaebcc11c5b20b9b667c040c4d22a)

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

index 368a9fd77f20a40edcc5068c2ee59a453aaff369..5196a74892603c153643c702b79b39a228601fd7 100644 (file)
@@ -348,6 +348,7 @@ client_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer,
                INSIST(client->tcpbuf == NULL);
                client->tcpbuf = isc_mem_get(client->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 {
@@ -380,7 +381,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)) {
@@ -450,9 +461,7 @@ ns_client_sendraw(ns_client_t *client, dns_message_t *message) {
        return;
 done:
        if (client->tcpbuf != NULL) {
-               isc_mem_put(client->mctx, client->tcpbuf,
-                           NS_CLIENT_TCP_BUFFER_SIZE);
-               client->tcpbuf = NULL;
+               isc_mem_put(client->mctx, client->tcpbuf, client->tcpbuf_size);
        }
 
        ns_client_drop(client, result);
@@ -736,9 +745,7 @@ renderend:
 
 cleanup:
        if (client->tcpbuf != NULL) {
-               isc_mem_put(client->mctx, client->tcpbuf,
-                           NS_CLIENT_TCP_BUFFER_SIZE);
-               client->tcpbuf = NULL;
+               isc_mem_put(client->mctx, client->tcpbuf, client->tcpbuf_size);
        }
 
        if (cleanup_cctx) {
@@ -1620,8 +1627,7 @@ ns__client_reset_cb(void *client0) {
 
        ns_client_endrequest(client);
        if (client->tcpbuf != NULL) {
-               isc_mem_put(client->mctx, client->tcpbuf,
-                           NS_CLIENT_TCP_BUFFER_SIZE);
+               isc_mem_put(client->mctx, client->tcpbuf, client->tcpbuf_size);
        }
 
        if (client->keytag != NULL) {
index f9d694fdd1a6299c4a9ebdba6ce1d8fdcbbd4a16..6bd41d4e4181e8a98df1b464cd12f621ff83ec1c 100644 (file)
@@ -184,6 +184,7 @@ struct ns_client {
        isc_nmhandle_t *prefetchhandle; /* Waiting for prefetch / rpzfetch */
        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;