]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
DoH: Flush HTTP write buffer on an outgoing DNS message
authorArtem Boldariev <artem@boldariev.com>
Tue, 25 Feb 2025 07:52:19 +0000 (09:52 +0200)
committerArtem Boldariev <artem@boldariev.com>
Mon, 3 Mar 2025 09:32:11 +0000 (11:32 +0200)
Previously, the code would try to avoid sending any data regardless of
what it is unless:

a) The flush limit is reached;
b) There are no sends in flight.

This strategy is used to avoid too numerous send requests with little
amount of data. However, it has been proven to be too aggressive and,
in fact, harms performance in some cases (e.g., on longer (≥1h) runs
of "stress:long:rpz:doh+udp:linux:*").

Now, additionally to the listed cases, we also:

c) Flush the buffer and perform a send operation when there is an
outgoing DNS message passed to the code (which is indicated by the
presence of a send callback).

That helps improve performance for "stress:long:rpz:doh+udp:linux:*"
tests.

lib/isc/netmgr/http.c

index 1e440837b3dc02386c9f90a539850fba420dc8e0..bf2abe5e4bc844814ebf90f4937ddaca751e72b2 100644 (file)
@@ -1467,26 +1467,27 @@ http_send_outgoing(isc_nm_http_session_t *session, isc_nmhandle_t *httphandle,
         * to avoid hitting unnecessary limitations on a TLS record size
         * within some tools (e.g. flamethrower).
         */
-       if (max_total_write_size >= FLUSH_HTTP_WRITE_BUFFER_AFTER) {
+       if (cb != NULL) {
                /*
-                * Case 1: We have at least FLUSH_HTTP_WRITE_BUFFER_AFTER
-                * bytes to send. Let's flush it.
+                * Case 0: The callback is specified, that means that a DNS
+                * message is ready. Let's flush the the buffer.
+                */
+               total = max_total_write_size;
+       } else if (max_total_write_size >= FLUSH_HTTP_WRITE_BUFFER_AFTER) {
+               /*
+                * Case 1: We have equal or more than
+                * FLUSH_HTTP_WRITE_BUFFER_AFTER bytes to send. Let's flush it.
                 */
                total = max_total_write_size;
        } else if (session->sending > 0 && total > 0) {
                /*
                 * Case 2: There is one or more write requests in flight and
-                * we have some new data form nghttp2 to send. Let's put the
-                * write callback (if any) into the pending write callbacks
-                * list. Then let's return from the function: as soon as the
+                * we have some new data form nghttp2 to send.
+                * Then let's return from the function: as soon as the
                 * "in-flight" write callback get's called or we have reached
                 * FLUSH_HTTP_WRITE_BUFFER_AFTER bytes in the write buffer, we
-                * will flush the buffer.
-                */
-               if (cb != NULL) {
-                       http_append_pending_send_request(session, httphandle,
-                                                        cb, cbarg);
-               }
+                * will flush the buffer. */
+               INSIST(cb == NULL);
                goto nothing_to_send;
        } else if (session->sending == 0 && total == 0 &&
                   session->pending_write_data != NULL)