]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Limit the number of DNS message processed from a single TCP read
authorOndřej Surý <ondrej@isc.org>
Wed, 5 Jun 2024 07:15:39 +0000 (09:15 +0200)
committerNicki Křížek <nicki@isc.org>
Mon, 10 Jun 2024 16:43:46 +0000 (18:43 +0200)
The single TCP read can create as much as 64k divided by the minimum
size of the DNS message.  This can clog the processing thread and trash
the memory allocator because we need to do as much as ~20k allocations in
a single UV loop tick.

Limit the number of the DNS messages processed in a single UV loop tick
to just single DNS message and limit the number of the outstanding DNS
messages back to 23.  This effectively limits the number of pipelined
DNS messages to that number (this is the limit we already had before).

This reverts commit 780a89012d8627b9284983702dced8a3f65688aa.

lib/isc/netmgr/netmgr-int.h
lib/isc/netmgr/netmgr.c

index 6d2bd9ad9f2e5daf32ff8c7bff930e3d8fc74dab..4ceb182e7bd0c47688083c89da52b6ef974145a1 100644 (file)
@@ -2262,6 +2262,14 @@ isc__nmsocket_readtimeout_cb(uv_timer_t *timer);
 void
 isc__nmsocket_writetimeout_cb(void *data, isc_result_t eresult);
 
+/*%<
+ *
+ * Maximum number of simultaneous handles in flight supported for a single
+ * connected TCPDNS socket. This value was chosen arbitrarily, and may be
+ * changed in the future.
+ */
+#define STREAM_CLIENTS_PER_CONN 23
+
 #define UV_RUNTIME_CHECK(func, ret)                                      \
        if (ret != 0) {                                                  \
                FATAL_ERROR("%s failed: %s\n", #func, uv_strerror(ret)); \
index 7b09639440a34781199c4d915a1d03b2c6edc9da..336cad4e231038647d461a13b442032103c07bb2 100644 (file)
@@ -2343,8 +2343,10 @@ processbuffer(isc_nmsocket_t *sock) {
  * timers. If we do have a full message, reset the timer.
  *
  * Stop reading if this is a client socket, or if the server socket
- * has been set to sequential mode. In this case we'll be called again
- * later by isc__nm_resume_processing().
+ * has been set to sequential mode, or the number of queries we are
+ * processing simultaneously has reached the clients-per-connection
+ * limit. In this case we'll be called again later by
+ * isc__nm_resume_processing().
  */
 isc_result_t
 isc__nm_process_sock_buffer(isc_nmsocket_t *sock) {
@@ -2384,7 +2386,8 @@ isc__nm_process_sock_buffer(isc_nmsocket_t *sock) {
                        isc__nmsocket_timer_stop(sock);
 
                        if (atomic_load(&sock->client) ||
-                           atomic_load(&sock->sequential))
+                           atomic_load(&sock->sequential) ||
+                           atomic_load(&sock->ah) >= STREAM_CLIENTS_PER_CONN)
                        {
                                isc__nm_stop_reading(sock);
                                goto done;