From: Witold Kręcicki Date: Fri, 22 Nov 2019 12:19:45 +0000 (+0100) Subject: netmgr: fix TCP backlog and client quota count X-Git-Tag: v9.15.7~75^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=37354ee225314862a493bc64ac56618327233166;p=thirdparty%2Fbind9.git 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. --- diff --git a/bin/tests/system/tcp/tests.sh b/bin/tests/system/tcp/tests.sh index a3ce32d28b7..2190ec5f40c 100644 --- a/bin/tests/system/tcp/tests.sh +++ b/bin/tests/system/tcp/tests.sh @@ -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)) diff --git a/lib/isc/include/isc/netmgr.h b/lib/isc/include/isc/netmgr.h index 97bb1d6d764..82d32f0dc61 100644 --- a/lib/isc/include/isc/netmgr.h +++ b/lib/isc/include/isc/netmgr.h @@ -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 diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index 1979a01454e..0844cdcbb7d 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -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; diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index 273200a6e32..d7699e6d97e 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -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; diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index 56e8600f578..5283740f5eb 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -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, "a); + if (ssock->pquota != NULL) { + result = isc_quota_attach(ssock->pquota, "a); if (result != ISC_R_SUCCESS) { return (result); } diff --git a/lib/isc/netmgr/tcpdns.c b/lib/isc/netmgr/tcpdns.c index c3f87a3d4d3..d75fdda9439 100644 --- a/lib/isc/netmgr/tcpdns.c +++ b/lib/isc/netmgr/tcpdns.c @@ -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); diff --git a/lib/ns/interfacemgr.c b/lib/ns/interfacemgr.c index 8096d5ffefb..2dd03a0eee9 100644 --- a/lib/ns/interfacemgr.c +++ b/lib/ns/interfacemgr.c @@ -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) {