tcp-listen-queue 10;\n\
tcp-primaries-timeout 150;\n\
tcp-receive-buffer 0;\n\
+ tcp-reuse-timeout 50;\n\
tcp-send-buffer 0;\n\
transfer-message-size 20480;\n\
transfers-in 10;\n\
extern unsigned int dns_adb_entrywindow;
extern unsigned int dns_adb_cachemin;
extern size_t dns_dispatch_tcppipelining;
-extern unsigned int dns_dispatch_tcp_idle_timeout;
static bool want_stats = false;
static char absolute_conffile[PATH_MAX];
"least 1");
}
dns_dispatch_tcppipelining = pipelining;
- } else if (!strncmp(option, "tcpidletimeout=", 15)) {
- dns_dispatch_tcp_idle_timeout = atoi(option + 15);
} else {
fprintf(stderr, "unknown -T flag '%s'\n", option);
}
#define MAX_ADVERTISED_TIMEOUT UINT32_C(UINT16_MAX * 100)
#define MIN_PRIMARIES_TIMEOUT UINT32_C(2500) /* 2.5 seconds */
#define MAX_PRIMARIES_TIMEOUT UINT32_C(120000) /* 2 minutes */
+#define MAX_REUSE_TIMEOUT UINT32_C(120000) /* 2 minutes */
/*%
* Check an operation for failure. Assumes that the function
ns_altsecretlist_t altsecrets, tmpaltsecrets;
uint32_t softquota = 0;
uint32_t max;
- uint64_t initial, idle, keepalive, advertised, primaries;
+ uint64_t initial, idle, keepalive, advertised, primaries, reuse;
bool loadbalancesockets;
bool exclusive = false;
dns_aclenv_t *env =
primaries = MIN_PRIMARIES_TIMEOUT;
}
+ obj = NULL;
+ result = named_config_get(maps, "tcp-reuse-timeout", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ reuse = cfg_obj_asuint32(obj) * 100;
+ if (reuse > MAX_REUSE_TIMEOUT) {
+ cfg_obj_log(obj, ISC_LOG_WARNING,
+ "tcp-reuse-timeout value is out of range: "
+ "lowering to %" PRIu32,
+ MAX_REUSE_TIMEOUT / 100);
+ reuse = MAX_REUSE_TIMEOUT;
+ }
+
isc_nm_setinitialtimeout(initial);
isc_nm_setprimariestimeout(primaries);
isc_nm_setidletimeout(idle);
isc_nm_setkeepalivetimeout(keepalive);
isc_nm_setadvertisedtimeout(advertised);
+ dns_dispatchmgr_setreusetimeout(named_g_dispatchmgr, reuse);
+
#define CAP_IF_NOT_ZERO(v, min, max) \
if (v > 0 && v < min) { \
v = min; \
option are expected to use TCP connections for more than one message.
This value can be updated at runtime by using :option:`rndc tcp-timeouts`.
+.. namedconf:statement:: tcp-reuse-timeout
+ :tags: query
+ :short: Sets the amount of time (in milliseconds) that an idle outgoing TCP connection is kept open for reuse.
+
+ This sets the amount of time, in units of 100 milliseconds, that an idle
+ outgoing TCP or TLS connection opened by :iscman:`named` (for example, to a
+ forwarder or an authoritative server) is kept open after its last outstanding
+ response has completed, so that it can be reused by a later query instead of
+ being closed and reopened. The default is 50 (5 seconds), and the maximum is
+ 1200 (two minutes). A value of 0 disables keeping idle outgoing TCP or TLS
+ connections open for reuse; it does not affect sharing of a connection while
+ queries are still outstanding. Values above the maximum are adjusted with a
+ logged warning.
+
.. namedconf:statement:: tcp-advertised-timeout
:tags: query
:short: Sets the timeout value (in milliseconds) that the server sends in responses containing the EDNS TCP keepalive option.
tcp-listen-queue <integer>;
tcp-primaries-timeout <integer>;
tcp-receive-buffer <integer>;
+ tcp-reuse-timeout <integer>;
tcp-send-buffer <integer>;
tkey-gssapi-keytab <quoted_string>;
tls-port <integer>;
*/
size_t dns_dispatch_tcppipelining = 256;
-/*
- * Idle timeout (in milliseconds) for a reused outgoing TCP connection. While a
- * dispatch has no outstanding responses we keep a read pending so a
- * peer-initiated close is noticed promptly; this bounds how long such an idle
- * connection is kept open for reuse. Can be overridden via
- * 'named -T tcpidletimeout=N'.
- */
-unsigned int dns_dispatch_tcp_idle_timeout = 5000;
-
typedef ISC_LIST(dns_dispentry_t) dns_displist_t;
struct dns_dispatchmgr {
dns_acl_t *blackhole;
isc_stats_t *stats;
+ unsigned int reuse_timeout;
+
uint32_t nloops;
struct cds_lfht **tcps;
static void
tcp_startrecv_idle(dns_dispatch_t *disp) {
- REQUIRE(dns_dispatch_tcp_idle_timeout > 0);
+ REQUIRE(disp->mgr->reuse_timeout > 0);
/*
* No outstanding responses, but the connection is still up and
* out again as a dead reused connection.
*/
isc_nmhandle_cleartimeout(disp->handle);
- isc_nmhandle_settimeout(disp->handle, dns_dispatch_tcp_idle_timeout);
+ isc_nmhandle_settimeout(disp->handle, disp->mgr->reuse_timeout);
if (!disp->reading) {
dispatch_log(disp, ISC_LOG_DEBUG(90), "keeping idle read on %p",
disp->handle);
*/
if (ISC_LIST_EMPTY(disp->active) &&
disp->state == DNS_DISPATCHSTATE_CONNECTED &&
- dns_dispatch_tcp_idle_timeout > 0)
+ disp->mgr->reuse_timeout > 0)
{
tcp_startrecv_idle(disp);
}
return setavailports(mgr, v4portset, v6portset);
}
+void
+dns_dispatchmgr_setreusetimeout(dns_dispatchmgr_t *mgr,
+ unsigned int reuse_timeout) {
+ REQUIRE(VALID_DISPATCHMGR(mgr));
+ mgr->reuse_timeout = reuse_timeout;
+}
+
static void
dispatchmgr_destroy(dns_dispatchmgr_t *mgr) {
REQUIRE(VALID_DISPATCHMGR(mgr));
* dispatch is already shutting down, leave it alone so
* it can be torn down.
*/
- if (dns_dispatch_tcp_idle_timeout > 0) {
+ if (disp->mgr->reuse_timeout > 0) {
tcp_startrecv_idle(disp);
} else if (disp->reading) {
dispentry_log(resp, ISC_LOG_DEBUG(90),
*\li v6portset is NULL or a valid port set
*/
+void
+dns_dispatchmgr_setreusetimeout(dns_dispatchmgr_t *mgr, unsigned int timeout);
+/*%<
+ * Sets the idle timeout (in milliseconds) for a reused outgoing TCP connection.
+ * While a dispatch has no outstanding responses we keep a read pending so a
+ * peer-initiated close is noticed promptly; this bounds how long such an idle
+ * connection is kept open for reuse.
+ */
+
void
dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats);
/*%<
{ "tcp-listen-queue", &cfg_type_uint32, 0, NULL },
{ "tcp-primaries-timeout", &cfg_type_uint32, 0, NULL },
{ "tcp-receive-buffer", &cfg_type_uint32, 0, NULL },
+ { "tcp-reuse-timeout", &cfg_type_uint32, 0, NULL },
{ "tcp-send-buffer", &cfg_type_uint32, 0, NULL },
{ "tkey-dhkey", NULL, CFG_CLAUSEFLAG_ANCIENT, NULL },
{ "tkey-domain", &cfg_type_qstring, CFG_CLAUSEFLAG_ANCIENT, NULL },
result = dns_dispatchmgr_create(isc_g_mctx, &test->dispatchmgr);
assert_int_equal(result, ISC_R_SUCCESS);
+ dns_dispatchmgr_setreusetimeout(test->dispatchmgr, 5000);
+
result = dns_dispatch_createtcp(
test->dispatchmgr, &tcp_connect_addr, &tcp_server_addr, NULL,
DNS_DISPATCHTYPE_RESOLVER, 0, &test->dispatch);