From c5f7968856f3d0cf37c5882ac19fa70333bae4cc Mon Sep 17 00:00:00 2001 From: Artem Boldariev Date: Tue, 25 Feb 2025 09:52:19 +0200 Subject: [PATCH] DoH: Flush HTTP write buffer on an outgoing DNS message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/lib/isc/netmgr/http.c b/lib/isc/netmgr/http.c index 1e440837b3..bf2abe5e4b 100644 --- a/lib/isc/netmgr/http.c +++ b/lib/isc/netmgr/http.c @@ -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)