From 1a999353cd496b6cc0d6a6ede3948a0b4cce3e4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Wed, 4 Jan 2023 19:21:14 +0100 Subject: [PATCH] Pin the dns_dispatch to threads when reusing Previously, dns_dispatch_gettcp() could pick a TCP connection created by different thread - this breaks our contractual promise to DNS dispatch by using the TCP connection on a different thread than it was created. Add .tid member to the dns_dispatch_t struct and skip the dispatches from other threads when looking up a TCP dispatch that we can reuse in dns_request. NOTE: This is going to be properly refactored, but this change could be also backported to 9.18 for better stability and thread-affinity. --- lib/dns/dispatch.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index c1dbff4c78..9d2b7732af 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -109,7 +110,8 @@ struct dns_dispentry { struct dns_dispatch { /* Unlocked. */ - unsigned int magic; /*%< magic */ + unsigned int magic; /*%< magic */ + uint32_t tid; dns_dispatchmgr_t *mgr; /*%< dispatch manager */ isc_nmhandle_t *handle; /*%< netmgr handle for TCP connection */ isc_sockaddr_t local; /*%< local address */ @@ -1160,6 +1162,7 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, isc_socktype_t type, .link = ISC_LINK_INITIALIZER, .active = ISC_LIST_INITIALIZER, .pending = ISC_LIST_INITIALIZER, + .tid = isc_tid(), .magic = DISPATCH_MAGIC, }; @@ -1245,6 +1248,11 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr, LOCK(&disp->lock); + if (disp->tid != isc_tid()) { + UNLOCK(&disp->lock); + continue; + } + if (disp->handle != NULL) { sockname = isc_nmhandle_localaddr(disp->handle); peeraddr = isc_nmhandle_peeraddr(disp->handle);