Commit 37354ee2 authored by Witold Krecicki's avatar Witold Krecicki Committed by Evan Hunt
Browse files

netmgr: fix TCP backlog and client quota count

 - add support for TCP backlog, using the value provided by config.
 - don't attach to TCP client quota for listening sockets, only
   connected sockets.
parent c4ad0466
......@@ -115,7 +115,7 @@ n=$((n + 1))
echo_i "TCP high-water: check initial statistics ($n)"
ret=0
refresh_tcp_stats
assert_int_equal "${TCP_CUR}" 1 "current TCP clients count" || ret=1
assert_int_equal "${TCP_CUR}" 0 "current TCP clients count" || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
......
......@@ -223,7 +223,8 @@ isc_nm_send(isc_nmhandle_t *handle, isc_region_t *region,
isc_result_t
isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
isc_nm_cb_t cb, void *cbarg,
size_t extrahandlesize, isc_quota_t *quota,
size_t extrahandlesize, int backlog,
isc_quota_t *quota,
isc_nmsocket_t **sockp);
/*%<
* Start listening for raw messages over the TCP interface 'iface', using
......@@ -255,7 +256,8 @@ isc_nm_tcp_stoplistening(isc_nmsocket_t *sock);
isc_result_t
isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface,
isc_nm_recv_cb_t cb, void *arg,
size_t extrahandlesize, isc_quota_t *quota,
size_t extrahandlesize, int backlog,
isc_quota_t *quota,
isc_nmsocket_t **sockp);
/*%<
* Start listening for DNS messages over the TCP interface 'iface', using
......
......@@ -286,8 +286,20 @@ struct isc_nmsocket {
isc_nmsocket_type type;
isc_nm_t *mgr;
isc_nmsocket_t *parent;
/*
* quota is the TCP client, attached when a TCP connection
* is established. pquota is a non-attached pointer to the
* TCP client quota, stored in listening sockets but only
* attached in connected sockets.
*/
isc_quota_t *quota;
isc_quota_t *pquota;
bool overquota;
/*
* TCP read timeout timer.
*/
uv_timer_t timer;
bool timer_initialized;
uint64_t read_timeout;
......@@ -307,6 +319,9 @@ struct isc_nmsocket {
/*% extra data allocated at the end of each isc_nmhandle_t */
size_t extrahandlesize;
/*% TCP backlog */
int backlog;
/*% libuv data */
uv_os_sock_t fd;
union uv_any_handle uv_handle;
......
......@@ -617,6 +617,8 @@ nmsocket_cleanup(isc_nmsocket_t *sock, bool dofree) {
isc_quota_detach(&sock->quota);
}
sock->pquota = NULL;
if (sock->timer_initialized) {
uv_close((uv_handle_t *)&sock->timer, NULL);
sock->timer_initialized = false;
......
......@@ -130,7 +130,8 @@ tcp_connect_cb(uv_connect_t *uvreq, int status) {
isc_result_t
isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
isc_nm_cb_t cb, void *cbarg,
size_t extrahandlesize, isc_quota_t *quota,
size_t extrahandlesize, int backlog,
isc_quota_t *quota,
isc_nmsocket_t **sockp)
{
isc__netievent_tcplisten_t *ievent = NULL;
......@@ -144,15 +145,13 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
nsock->rcb.accept = cb;
nsock->rcbarg = cbarg;
nsock->extrahandlesize = extrahandlesize;
nsock->backlog = backlog;
if (quota != NULL) {
/*
* We need to force it to make sure we get it attached.
* An example failure mode would be server under attack
* reconfiguring interfaces - that might cause weak attach
* to fail and leave this listening socket without limits.
* We can ignore the result.
* We don't attach to quota, just assign - to avoid
* increasing quota unnecesarily.
*/
isc_quota_force(quota, &nsock->quota);
nsock->pquota = quota;
}
nsock->tid = isc_random_uniform(mgr->nworkers);
......@@ -185,7 +184,7 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ievent0) {
}
uv_tcp_bind(&sock->uv_handle.tcp, &sock->iface->addr.type.sa, 0);
r = uv_listen((uv_stream_t *) &sock->uv_handle.tcp, 10,
r = uv_listen((uv_stream_t *) &sock->uv_handle.tcp, sock->backlog,
tcp_connection_cb);
if (r != 0) {
return;
......@@ -219,9 +218,7 @@ stoplistening_cb(uv_handle_t *handle) {
SIGNAL(&sock->cond);
UNLOCK(&sock->lock);
if (sock->quota != NULL) {
isc_quota_detach(&sock->quota);
}
sock->pquota = NULL;
isc_nmsocket_detach(&sock);
}
......@@ -446,8 +443,8 @@ accept_connection(isc_nmsocket_t *ssock) {
return (ISC_R_CANCELED);
}
if (ssock->quota != NULL) {
result = isc_quota_attach(ssock->quota, &quota);
if (ssock->pquota != NULL) {
result = isc_quota_attach(ssock->pquota, &quota);
if (result != ISC_R_SUCCESS) {
return (result);
}
......
......@@ -275,7 +275,8 @@ dnslisten_readcb(isc_nmhandle_t *handle, isc_region_t *region, void *arg) {
isc_result_t
isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface,
isc_nm_recv_cb_t cb, void *cbarg,
size_t extrahandlesize, isc_quota_t *quota,
size_t extrahandlesize, int backlog,
isc_quota_t *quota,
isc_nmsocket_t **sockp)
{
/* A 'wrapper' socket object with outer set to true TCP socket */
......@@ -293,7 +294,7 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface,
/* We set dnslistensock->outer to a true listening socket */
result = isc_nm_listentcp(mgr, iface, dnslisten_acceptcb,
dnslistensock, extrahandlesize,
dnslistensock, extrahandlesize, backlog,
quota, &dnslistensock->outer);
atomic_store(&dnslistensock->listening, true);
......
......@@ -461,6 +461,7 @@ ns_interface_listentcp(ns_interface_t *ifp) {
(isc_nmiface_t *) &ifp->addr,
ns__client_request, ifp,
sizeof(ns_client_t),
ifp->mgr->backlog,
&ifp->mgr->sctx->tcpquota,
&ifp->tcplistensocket);
if (result != ISC_R_SUCCESS) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment