2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

Limit TCP connection quota logging to 1/s

This commit is contained in:
Witold Kręcicki
2020-02-28 13:58:13 +01:00
committed by Witold Krecicki
parent fc9e2276ca
commit fc9792eae8
2 changed files with 42 additions and 17 deletions

View File

@@ -719,7 +719,9 @@ nmsocket_cleanup(isc_nmsocket_t *sock, bool dofree) {
if (!atomic_load(&sock->children[i].destroying)) { if (!atomic_load(&sock->children[i].destroying)) {
nmsocket_cleanup(&sock->children[i], false); nmsocket_cleanup(&sock->children[i], false);
if (sock->statsindex != NULL) { if (sock->statsindex != NULL) {
isc__nm_decstats(sock->mgr, sock->statsindex[STATID_ACTIVE]); isc__nm_decstats(
sock->mgr,
sock->statsindex[STATID_ACTIVE]);
} }
} }
} }
@@ -733,7 +735,7 @@ nmsocket_cleanup(isc_nmsocket_t *sock, bool dofree) {
sock->nchildren = 0; sock->nchildren = 0;
} }
if (sock->statsindex != NULL) { if (sock->statsindex != NULL) {
isc__nm_decstats(sock->mgr, sock->statsindex[STATID_ACTIVE]); isc__nm_decstats(sock->mgr, sock->statsindex[STATID_ACTIVE]);
} }
if (sock->tcphandle != NULL) { if (sock->tcphandle != NULL) {

View File

@@ -26,12 +26,28 @@
#include <isc/region.h> #include <isc/region.h>
#include <isc/result.h> #include <isc/result.h>
#include <isc/sockaddr.h> #include <isc/sockaddr.h>
#include <isc/stdtime.h>
#include <isc/thread.h> #include <isc/thread.h>
#include <isc/util.h> #include <isc/util.h>
#include "netmgr-int.h" #include "netmgr-int.h"
#include "uv-compat.h" #include "uv-compat.h"
static atomic_uint_fast32_t last_tcpquota_log = ATOMIC_VAR_INIT(0);
static bool
can_log_tcp_quota() {
isc_stdtime_t now, last;
isc_stdtime_get(&now);
last = atomic_exchange_relaxed(&last_tcpquota_log, now);
if (now != last) {
return (true);
}
return (false);
}
static int static int
tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req); tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req);
@@ -691,10 +707,15 @@ accept_connection(isc_nmsocket_t *ssock) {
if (ssock->pquota != NULL) { if (ssock->pquota != NULL) {
result = isc_quota_attach(ssock->pquota, &quota); result = isc_quota_attach(ssock->pquota, &quota);
/* /*
* We share the quota between sockets - we need to have at * We share the quota between all TCP sockets. Others
* least one active connection here to restart listening * may have used up all the quota slots, in which case
* when the quota is available again (in tcp_close_direct). * this socket could starve. So we only fail here if we
* already had at least one active connection on this
* socket. This guarantees that we'll maintain some level
* of service while over quota, and will resume normal
* service when the quota comes back down.
*/ */
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
ssock->overquota++; ssock->overquota++;
@@ -705,12 +726,6 @@ accept_connection(isc_nmsocket_t *ssock) {
ssock->statsindex[STATID_ACCEPTFAIL]); ssock->statsindex[STATID_ACCEPTFAIL]);
return (result); return (result);
} }
/*
* We share the quota between sockets - we need to have
* at least one active connection here to restart
* listening when the quota is available again (in
* tcp_close_direct).
*/
} }
} }
@@ -792,11 +807,14 @@ tcp_connection_cb(uv_stream_t *server, int status) {
UNUSED(status); UNUSED(status);
result = accept_connection(ssock); result = accept_connection(ssock);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS && result != ISC_R_NOCONN) {
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, if ((result != ISC_R_QUOTA && result != ISC_R_SOFTQUOTA) ||
ISC_LOGMODULE_NETMGR, ISC_LOG_ERROR, can_log_tcp_quota()) {
"TCP connection failed: %s", isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
isc_result_totext(result)); ISC_LOGMODULE_NETMGR, ISC_LOG_ERROR,
"TCP connection failed: %s",
isc_result_totext(result));
}
} }
} }
@@ -935,7 +953,12 @@ tcp_close_direct(isc_nmsocket_t *sock) {
while (ssock->conns == 0 && ssock->overquota > 0) { while (ssock->conns == 0 && ssock->overquota > 0) {
ssock->overquota--; ssock->overquota--;
isc_result_t result = accept_connection(ssock); isc_result_t result = accept_connection(ssock);
if (result != ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS || result == ISC_R_NOCONN) {
continue;
}
if ((result != ISC_R_QUOTA &&
result != ISC_R_SOFTQUOTA) ||
can_log_tcp_quota()) {
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
ISC_LOGMODULE_NETMGR, ISC_LOGMODULE_NETMGR,
ISC_LOG_ERROR, ISC_LOG_ERROR,