for (int i = 0; i < sock->nchildren; i++) {
if (!atomic_load(&sock->children[i].destroying)) {
nmsocket_cleanup(&sock->children[i], false);
+ if (sock->statsindex != NULL) {
+ isc__nm_decstats(sock->mgr, sock->statsindex[STATID_ACTIVE]);
+ }
}
}
sock->children = NULL;
sock->nchildren = 0;
}
+ if (sock->statsindex != NULL) {
+ isc__nm_decstats(sock->mgr, sock->statsindex[STATID_ACTIVE]);
+ }
if (sock->tcphandle != NULL) {
isc_nmhandle_unref(sock->tcphandle);
if (sock->children != NULL) {
for (int i = 0; i < sock->nchildren; i++) {
atomic_store(&sock->children[i].active, false);
- isc__nm_decstats(sock->mgr,
- sock->statsindex[STATID_ACTIVE]);
}
}
}
isc__nm_free_uvbuf(sock, buf);
- if (sock->quota) {
- isc_quota_detach(&sock->quota);
- }
/*
* This might happen if the inner socket is closing. It means that
struct sockaddr_storage ss;
isc_sockaddr_t local;
int r;
+ bool overquota = false;
REQUIRE(VALID_NMSOCK(ssock));
REQUIRE(ssock->tid == isc_nm_tid());
if (ssock->pquota != NULL) {
result = isc_quota_attach(ssock->pquota, "a);
+ /*
+ * 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).
+ */
if (result != ISC_R_SUCCESS) {
- isc__nm_incstats(ssock->mgr,
- ssock->statsindex[STATID_ACCEPTFAIL]);
- return (result);
+ ssock->overquota++;
+ overquota = true;
+ if (ssock->conns > 0) {
+ isc__nm_incstats(
+ ssock->mgr,
+ ssock->statsindex[STATID_ACCEPTFAIL]);
+ 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).
+ */
}
}
}
isc_nmsocket_attach(ssock, &csock->server);
+ ssock->conns++;
handle = isc__nmhandle_get(csock, NULL, &local);
if (csock->quota != NULL) {
isc_quota_detach(&csock->quota);
}
+ if (overquota) {
+ ssock->overquota--;
+ }
/* We need to detach it properly to make sure uv_close is called. */
isc_nmsocket_detach(&csock);
return (result);
result = accept_connection(ssock);
if (result != ISC_R_SUCCESS) {
- if (result == ISC_R_QUOTA || result == ISC_R_SOFTQUOTA) {
- ssock->overquota = true;
- }
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
ISC_LOGMODULE_NETMGR, ISC_LOG_ERROR,
"TCP connection failed: %s",
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
REQUIRE(sock->type == isc_nm_tcpsocket);
+ isc_nmsocket_t *ssock = sock->server;
if (sock->quota != NULL) {
- isc_nmsocket_t *ssock = sock->server;
-
isc_quota_detach(&sock->quota);
-
- if (ssock->overquota) {
+ }
+ if (ssock != NULL) {
+ ssock->conns--;
+ while (ssock->conns == 0 && ssock->overquota > 0) {
+ ssock->overquota--;
isc_result_t result = accept_connection(ssock);
- if (result != ISC_R_QUOTA && result != ISC_R_SOFTQUOTA)
- {
- ssock->overquota = false;
+ if (result != ISC_R_SUCCESS) {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_NETMGR,
+ ISC_LOG_ERROR,
+ "TCP connection failed: %s",
+ isc_result_totext(result));
}
}
}