mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Limit TCP pipelining per shared dispatch
Cap the number of in-flight queries on a single shared TCP dispatch. When the limit is reached, the dispatch is removed from the hash table so subsequent queries get a fresh connection. The existing dispatch continues serving its queries until they complete. This bounds the blast radius of a connection drop: at most N queries fail simultaneously instead of all queries to that server. The default limit is 256. It can be overridden for testing via 'named -T tcppipelining=N'.
This commit is contained in:
parent
05e8b58307
commit
385ceabe8f
2 changed files with 28 additions and 0 deletions
|
|
@ -126,6 +126,7 @@ extern unsigned int dns_zone_mkey_month;
|
|||
|
||||
extern unsigned int dns_adb_entrywindow;
|
||||
extern unsigned int dns_adb_cachemin;
|
||||
extern size_t dns_dispatch_tcppipelining;
|
||||
|
||||
static bool want_stats = false;
|
||||
static char absolute_conffile[PATH_MAX];
|
||||
|
|
@ -739,6 +740,13 @@ parse_T_opt(char *option) {
|
|||
dns_adb_entrywindow = atoi(option + 15);
|
||||
} else if (!strncmp(option, "adbcachemin=", 12)) {
|
||||
dns_adb_cachemin = atoi(option + 12);
|
||||
} else if (!strncmp(option, "tcppipelining=", 14)) {
|
||||
size_t pipelining = atoi(option + 14);
|
||||
if (pipelining < 1) {
|
||||
named_main_earlyfatal("tcppipelining must be at "
|
||||
"least 1");
|
||||
}
|
||||
dns_dispatch_tcppipelining = pipelining;
|
||||
} else {
|
||||
fprintf(stderr, "unknown -T flag '%s'\n", option);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,13 @@
|
|||
#include <dns/transport.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
/*
|
||||
* Maximum number of queries to pipeline on a single shared TCP dispatch.
|
||||
* Once reached, the dispatch is removed from the hash table so new queries
|
||||
* get a fresh connection. Can be overridden via 'named -T tcppipelining=N'.
|
||||
*/
|
||||
size_t dns_dispatch_tcppipelining = 256;
|
||||
|
||||
typedef ISC_LIST(dns_dispentry_t) dns_displist_t;
|
||||
|
||||
struct dns_dispatchmgr {
|
||||
|
|
@ -1550,6 +1557,19 @@ fail:
|
|||
|
||||
disp->requests++;
|
||||
|
||||
/*
|
||||
* If this shared TCP dispatch has reached the pipelining limit,
|
||||
* remove it from the hash table so new queries get a fresh
|
||||
* connection. The dispatch continues to serve its existing
|
||||
* queries until they complete.
|
||||
*/
|
||||
if (disp->socktype == isc_socktype_tcp &&
|
||||
(disp->options & DNS_DISPATCHOPT_FIXEDID) == 0 &&
|
||||
disp->requests >= dns_dispatch_tcppipelining)
|
||||
{
|
||||
(void)cds_lfht_del(disp->mgr->tcps[isc_tid()], &disp->ht_node);
|
||||
}
|
||||
|
||||
inc_stats(disp->mgr, (disp->socktype == isc_socktype_udp)
|
||||
? dns_resstatscounter_disprequdp
|
||||
: dns_resstatscounter_dispreqtcp);
|
||||
|
|
|
|||
Loading…
Reference in a new issue