From 80a5c9f5c87c5be3ad31d56a772a72308d83873d Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Sun, 5 Jan 2020 01:02:12 -0800 Subject: [PATCH 1/4] associate socket stats counters with netmgr socket objects - the socket stat counters have been moved from socket.h to stats.h. - isc_nm_t now attaches to the same stats counter group as isc_socketmgr_t, so that both managers can increment the same set of statistics - isc__nmsocket_init() now takes an interface as a paramter so that the address family can be determined when initializing the socket. - based on the address family and socket type, a group of statistics counters will be associated with the socket - for example, UDP4Active with IPv4 UDP sockets and TCP6Active with IPv6 TCP sockets. note that no counters are currently associated with TCPDNS sockets; those stats will be handled by the underlying TCP socket. - the counters are not actually used by netmgr sockets yet; counter increment and decrement calls will be added in a later commit. --- bin/named/server.c | 1 + lib/isc/include/isc/netmgr.h | 12 +++ lib/isc/include/isc/socket.h | 81 ------------------- lib/isc/include/isc/stats.h | 84 ++++++++++++++++++++ lib/isc/netmgr/netmgr-int.h | 144 +++++++++++++++++++++------------- lib/isc/netmgr/netmgr.c | 146 ++++++++++++++++++++++++++++++++++- lib/isc/netmgr/tcp.c | 10 +-- lib/isc/netmgr/tcpdns.c | 7 +- lib/isc/netmgr/udp.c | 6 +- lib/isc/win32/libisc.def.in | 1 + 10 files changed, 343 insertions(+), 149 deletions(-) diff --git a/bin/named/server.c b/bin/named/server.c index 2bfc1a44b0..31bec0ec50 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -9941,6 +9941,7 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) { isc_sockstatscounter_max), "isc_stats_create"); isc_socketmgr_setstats(named_g_socketmgr, server->sockstats); + isc_nm_setstats(named_g_nm, server->sockstats); CHECKFATAL(isc_stats_create(named_g_mctx, &server->zonestats, dns_zonestatscounter_max), diff --git a/lib/isc/include/isc/netmgr.h b/lib/isc/include/isc/netmgr.h index d3000036c4..c01d3e2225 100644 --- a/lib/isc/include/isc/netmgr.h +++ b/lib/isc/include/isc/netmgr.h @@ -357,3 +357,15 @@ isc_nm_maxudp(isc_nm_t *mgr, uint32_t maxudp); * Simulate a broken firewall that blocks UDP messages larger than a given * size. */ + +void +isc_nm_setstats(isc_nm_t *mgr, isc_stats_t *stats); +/*%< + * Set a socket statistics counter set 'stats' for 'mgr'. + * + * Requires: + *\li 'mgr' is valid and doesn't have stats already set. + * + *\li stats is a valid set of statistics counters supporting the + * full range of socket-related stats counter numbers. + */ diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h index 8d0c621ddf..e90d2da241 100644 --- a/lib/isc/include/isc/socket.h +++ b/lib/isc/include/isc/socket.h @@ -85,87 +85,6 @@ typedef enum { } isc_socket_options_t; /*@}*/ -/*% - * Statistics counters. Used as isc_statscounter_t values. - */ -enum { - isc_sockstatscounter_udp4open = 0, - isc_sockstatscounter_udp6open = 1, - isc_sockstatscounter_tcp4open = 2, - isc_sockstatscounter_tcp6open = 3, - isc_sockstatscounter_unixopen = 4, - - isc_sockstatscounter_udp4openfail = 5, - isc_sockstatscounter_udp6openfail = 6, - isc_sockstatscounter_tcp4openfail = 7, - isc_sockstatscounter_tcp6openfail = 8, - isc_sockstatscounter_unixopenfail = 9, - - isc_sockstatscounter_udp4close = 10, - isc_sockstatscounter_udp6close = 11, - isc_sockstatscounter_tcp4close = 12, - isc_sockstatscounter_tcp6close = 13, - isc_sockstatscounter_unixclose = 14, - isc_sockstatscounter_fdwatchclose = 15, - - isc_sockstatscounter_udp4bindfail = 16, - isc_sockstatscounter_udp6bindfail = 17, - isc_sockstatscounter_tcp4bindfail = 18, - isc_sockstatscounter_tcp6bindfail = 19, - isc_sockstatscounter_unixbindfail = 20, - isc_sockstatscounter_fdwatchbindfail = 21, - - isc_sockstatscounter_udp4connect = 22, - isc_sockstatscounter_udp6connect = 23, - isc_sockstatscounter_tcp4connect = 24, - isc_sockstatscounter_tcp6connect = 25, - isc_sockstatscounter_unixconnect = 26, - isc_sockstatscounter_fdwatchconnect = 27, - - isc_sockstatscounter_udp4connectfail = 28, - isc_sockstatscounter_udp6connectfail = 29, - isc_sockstatscounter_tcp4connectfail = 30, - isc_sockstatscounter_tcp6connectfail = 31, - isc_sockstatscounter_unixconnectfail = 32, - isc_sockstatscounter_fdwatchconnectfail = 33, - - isc_sockstatscounter_tcp4accept = 34, - isc_sockstatscounter_tcp6accept = 35, - isc_sockstatscounter_unixaccept = 36, - - isc_sockstatscounter_tcp4acceptfail = 37, - isc_sockstatscounter_tcp6acceptfail = 38, - isc_sockstatscounter_unixacceptfail = 39, - - isc_sockstatscounter_udp4sendfail = 40, - isc_sockstatscounter_udp6sendfail = 41, - isc_sockstatscounter_tcp4sendfail = 42, - isc_sockstatscounter_tcp6sendfail = 43, - isc_sockstatscounter_unixsendfail = 44, - isc_sockstatscounter_fdwatchsendfail = 45, - - isc_sockstatscounter_udp4recvfail = 46, - isc_sockstatscounter_udp6recvfail = 47, - isc_sockstatscounter_tcp4recvfail = 48, - isc_sockstatscounter_tcp6recvfail = 49, - isc_sockstatscounter_unixrecvfail = 50, - isc_sockstatscounter_fdwatchrecvfail = 51, - - isc_sockstatscounter_udp4active = 52, - isc_sockstatscounter_udp6active = 53, - isc_sockstatscounter_tcp4active = 54, - isc_sockstatscounter_tcp6active = 55, - isc_sockstatscounter_unixactive = 56, - - isc_sockstatscounter_rawopen = 57, - isc_sockstatscounter_rawopenfail = 58, - isc_sockstatscounter_rawclose = 59, - isc_sockstatscounter_rawrecvfail = 60, - isc_sockstatscounter_rawactive = 61, - - isc_sockstatscounter_max = 62 -}; - /*@{*/ /*! * _ATTACHED: Internal use only. diff --git a/lib/isc/include/isc/stats.h b/lib/isc/include/isc/stats.h index 2c6f811785..1c959fab92 100644 --- a/lib/isc/include/isc/stats.h +++ b/lib/isc/include/isc/stats.h @@ -19,6 +19,90 @@ #include +/*% + * Statistics counters. Used as isc_statscounter_t values. + */ +enum { + /*% + * Socket statistics counters. + */ + isc_sockstatscounter_udp4open = 0, + isc_sockstatscounter_udp6open = 1, + isc_sockstatscounter_tcp4open = 2, + isc_sockstatscounter_tcp6open = 3, + isc_sockstatscounter_unixopen = 4, + + isc_sockstatscounter_udp4openfail = 5, + isc_sockstatscounter_udp6openfail = 6, + isc_sockstatscounter_tcp4openfail = 7, + isc_sockstatscounter_tcp6openfail = 8, + isc_sockstatscounter_unixopenfail = 9, + + isc_sockstatscounter_udp4close = 10, + isc_sockstatscounter_udp6close = 11, + isc_sockstatscounter_tcp4close = 12, + isc_sockstatscounter_tcp6close = 13, + isc_sockstatscounter_unixclose = 14, + isc_sockstatscounter_fdwatchclose = 15, + + isc_sockstatscounter_udp4bindfail = 16, + isc_sockstatscounter_udp6bindfail = 17, + isc_sockstatscounter_tcp4bindfail = 18, + isc_sockstatscounter_tcp6bindfail = 19, + isc_sockstatscounter_unixbindfail = 20, + isc_sockstatscounter_fdwatchbindfail = 21, + + isc_sockstatscounter_udp4connect = 22, + isc_sockstatscounter_udp6connect = 23, + isc_sockstatscounter_tcp4connect = 24, + isc_sockstatscounter_tcp6connect = 25, + isc_sockstatscounter_unixconnect = 26, + isc_sockstatscounter_fdwatchconnect = 27, + + isc_sockstatscounter_udp4connectfail = 28, + isc_sockstatscounter_udp6connectfail = 29, + isc_sockstatscounter_tcp4connectfail = 30, + isc_sockstatscounter_tcp6connectfail = 31, + isc_sockstatscounter_unixconnectfail = 32, + isc_sockstatscounter_fdwatchconnectfail = 33, + + isc_sockstatscounter_tcp4accept = 34, + isc_sockstatscounter_tcp6accept = 35, + isc_sockstatscounter_unixaccept = 36, + + isc_sockstatscounter_tcp4acceptfail = 37, + isc_sockstatscounter_tcp6acceptfail = 38, + isc_sockstatscounter_unixacceptfail = 39, + + isc_sockstatscounter_udp4sendfail = 40, + isc_sockstatscounter_udp6sendfail = 41, + isc_sockstatscounter_tcp4sendfail = 42, + isc_sockstatscounter_tcp6sendfail = 43, + isc_sockstatscounter_unixsendfail = 44, + isc_sockstatscounter_fdwatchsendfail = 45, + + isc_sockstatscounter_udp4recvfail = 46, + isc_sockstatscounter_udp6recvfail = 47, + isc_sockstatscounter_tcp4recvfail = 48, + isc_sockstatscounter_tcp6recvfail = 49, + isc_sockstatscounter_unixrecvfail = 50, + isc_sockstatscounter_fdwatchrecvfail = 51, + + isc_sockstatscounter_udp4active = 52, + isc_sockstatscounter_udp6active = 53, + isc_sockstatscounter_tcp4active = 54, + isc_sockstatscounter_tcp6active = 55, + isc_sockstatscounter_unixactive = 56, + + isc_sockstatscounter_rawopen = 57, + isc_sockstatscounter_rawopenfail = 58, + isc_sockstatscounter_rawclose = 59, + isc_sockstatscounter_rawrecvfail = 60, + isc_sockstatscounter_rawactive = 61, + + isc_sockstatscounter_max = 62 +}; + ISC_LANG_BEGINDECLS /*%< diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index a451012e16..1930927a5e 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include "uv-compat.h" @@ -265,6 +266,8 @@ struct isc_nm { isc_condition_t wkstatecond; isc__networker_t *workers; + isc_stats_t *stats; + isc_mempool_t *reqpool; isc_mutex_t reqlock; @@ -320,13 +323,30 @@ typedef enum isc_nmsocket_type { #define NMSOCK_MAGIC ISC_MAGIC('N', 'M', 'S', 'K') #define VALID_NMSOCK(t) ISC_MAGIC_VALID(t, NMSOCK_MAGIC) +/*% + * Index into socket stat counter arrays. + */ +enum { + STATID_OPEN = 0, + STATID_OPENFAIL = 1, + STATID_CLOSE = 2, + STATID_BINDFAIL = 3, + STATID_CONNECTFAIL = 4, + STATID_CONNECT = 5, + STATID_ACCEPTFAIL = 6, + STATID_ACCEPT = 7, + STATID_SENDFAIL = 8, + STATID_RECVFAIL = 9, + STATID_ACTIVE = 10 +}; + struct isc_nmsocket { /*% Unlocked, RO */ - int magic; - int tid; - isc_nmsocket_type type; - isc_nm_t *mgr; - isc_nmsocket_t *parent; + int magic; + int tid; + isc_nmsocket_type type; + isc_nm_t *mgr; + isc_nmsocket_t *parent; /*% * quota is the TCP client, attached when a TCP connection @@ -334,53 +354,58 @@ struct isc_nmsocket { * TCP client quota, stored in listening sockets but only * attached in connected sockets. */ - isc_quota_t *quota; - isc_quota_t *pquota; - bool overquota; + isc_quota_t *quota; + isc_quota_t *pquota; + bool overquota; + + /*% + * Socket statistics + */ + const isc_statscounter_t *statsindex; /*% * TCP read timeout timer. */ - uv_timer_t timer; - bool timer_initialized; - uint64_t read_timeout; + uv_timer_t timer; + bool timer_initialized; + uint64_t read_timeout; /*% outer socket is for 'wrapped' sockets - e.g. tcpdns in tcp */ - isc_nmsocket_t *outer; + isc_nmsocket_t *outer; /*% server socket for connections */ - isc_nmsocket_t *server; + isc_nmsocket_t *server; /*% Child sockets for multi-socket setups */ - isc_nmsocket_t *children; - int nchildren; - isc_nmiface_t *iface; - isc_nmhandle_t *tcphandle; + isc_nmsocket_t *children; + int nchildren; + isc_nmiface_t *iface; + isc_nmhandle_t *tcphandle; /*% Extra data allocated at the end of each isc_nmhandle_t */ - size_t extrahandlesize; + size_t extrahandlesize; /*% TCP backlog */ - int backlog; + int backlog; /*% libuv data */ - uv_os_sock_t fd; - union uv_any_handle uv_handle; + uv_os_sock_t fd; + union uv_any_handle uv_handle; /*% Peer address */ - isc_sockaddr_t peer; + isc_sockaddr_t peer; /* Atomic */ /*% Number of running (e.g. listening) child sockets */ - atomic_int_fast32_t rchildren; + atomic_int_fast32_t rchildren; /*% * Socket is active if it's listening, working, etc. If it's * closing, then it doesn't make a sense, for example, to * push handles or reqs for reuse. */ - atomic_bool active; - atomic_bool destroying; + atomic_bool active; + atomic_bool destroying; /*% * Socket is closed if it's not active and all the possible @@ -388,59 +413,59 @@ struct isc_nmsocket { * If active==false but closed==false, that means the socket * is closing. */ - atomic_bool closed; - atomic_bool listening; - atomic_bool listen_error; - isc_refcount_t references; + atomic_bool closed; + atomic_bool listening; + atomic_bool listen_error; + isc_refcount_t references; /*% * TCPDNS socket has been set not to pipeliine. */ - atomic_bool sequential; + atomic_bool sequential; /*% * TCPDNS socket has exceeded the maximum number of * simultaneous requests per connecton, so will be temporarily * restricted from pipelining. */ - atomic_bool overlimit; + atomic_bool overlimit; /*% * TCPDNS socket in sequential mode is currently processing a packet, * we need to wait until it finishes. */ - atomic_bool processing; + atomic_bool processing; /*% * A TCP socket has had isc_nm_pauseread() called. */ - atomic_bool readpaused; + atomic_bool readpaused; /*% * A TCP or TCPDNS socket has been set to use the keepalive * timeout instead of the default idle timeout. */ - atomic_bool keepalive; + atomic_bool keepalive; /*% * 'spare' handles for that can be reused to avoid allocations, * for UDP. */ - isc_astack_t *inactivehandles; - isc_astack_t *inactivereqs; + isc_astack_t *inactivehandles; + isc_astack_t *inactivereqs; /*% * Used to wait for TCP listening events to complete, and * for the number of running children to reach zero during * shutdown. */ - isc_mutex_t lock; - isc_condition_t cond; + isc_mutex_t lock; + isc_condition_t cond; /*% * Used to pass a result back from TCP listening events. */ - isc_result_t result; + isc_result_t result; /*% * List of active handles. @@ -463,28 +488,28 @@ struct isc_nmsocket { * might want to change it to something lockless in the * future. */ - atomic_int_fast32_t ah; - size_t ah_size; - size_t *ah_frees; - isc_nmhandle_t **ah_handles; + atomic_int_fast32_t ah; + size_t ah_size; + size_t *ah_frees; + isc_nmhandle_t **ah_handles; /*% Buffer for TCPDNS processing */ - size_t buf_size; - size_t buf_len; - unsigned char *buf; + size_t buf_size; + size_t buf_len; + unsigned char *buf; /*% * This function will be called with handle->sock * as the argument whenever a handle's references drop * to zero, after its reset callback has been called. */ - isc_nm_opaquecb_t closehandle_cb; + isc_nm_opaquecb_t closehandle_cb; - isc__nm_readcb_t rcb; - void *rcbarg; + isc__nm_readcb_t rcb; + void *rcbarg; - isc__nm_cb_t accept_cb; - void *accept_cbarg; + isc__nm_cb_t accept_cb; + void *accept_cbarg; }; bool @@ -561,9 +586,10 @@ isc__nm_uvreq_put(isc__nm_uvreq_t **req, isc_nmsocket_t *sock); void isc__nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, - isc_nmsocket_type type); + isc_nmsocket_type type, isc_nmiface_t *iface); /*%< - * Initialize socket 'sock', attach it to 'mgr', and set it to type 'type'. + * Initialize socket 'sock', attach it to 'mgr', and set it to type 'type' + * and its interface to 'iface'. */ void @@ -691,3 +717,15 @@ isc__nm_acquire_interlocked_force(isc_nm_t *mgr); /*%< * Actively wait for interlocked state. */ + +void +isc__nm_incstats(isc_nm_t *mgr, isc_statscounter_t counterid); +/*%< + * Increment socket-related statistics counters. + */ + +void +isc__nm_decstats(isc_nm_t *mgr, isc_statscounter_t counterid); +/*%< + * Decrement socket-related statistics counters. + */ diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index 90a2015bc4..4f94e11a95 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -26,12 +26,90 @@ #include #include #include +#include #include #include #include "uv-compat.h" #include "netmgr-int.h" +/*% + * Shortcut index arrays to get access to statistics counters. + */ + +static const isc_statscounter_t udp4statsindex[] = { + isc_sockstatscounter_udp4open, + isc_sockstatscounter_udp4openfail, + isc_sockstatscounter_udp4close, + isc_sockstatscounter_udp4bindfail, + isc_sockstatscounter_udp4connectfail, + isc_sockstatscounter_udp4connect, + -1, + -1, + isc_sockstatscounter_udp4sendfail, + isc_sockstatscounter_udp4recvfail, + isc_sockstatscounter_udp4active +}; + +static const isc_statscounter_t udp6statsindex[] = { + isc_sockstatscounter_udp6open, + isc_sockstatscounter_udp6openfail, + isc_sockstatscounter_udp6close, + isc_sockstatscounter_udp6bindfail, + isc_sockstatscounter_udp6connectfail, + isc_sockstatscounter_udp6connect, + -1, + -1, + isc_sockstatscounter_udp6sendfail, + isc_sockstatscounter_udp6recvfail, + isc_sockstatscounter_udp6active +}; + +static const isc_statscounter_t tcp4statsindex[] = { + isc_sockstatscounter_tcp4open, + isc_sockstatscounter_tcp4openfail, + isc_sockstatscounter_tcp4close, + isc_sockstatscounter_tcp4bindfail, + isc_sockstatscounter_tcp4connectfail, + isc_sockstatscounter_tcp4connect, + isc_sockstatscounter_tcp4acceptfail, + isc_sockstatscounter_tcp4accept, + isc_sockstatscounter_tcp4sendfail, + isc_sockstatscounter_tcp4recvfail, + isc_sockstatscounter_tcp4active +}; + +static const isc_statscounter_t tcp6statsindex[] = { + isc_sockstatscounter_tcp6open, + isc_sockstatscounter_tcp6openfail, + isc_sockstatscounter_tcp6close, + isc_sockstatscounter_tcp6bindfail, + isc_sockstatscounter_tcp6connectfail, + isc_sockstatscounter_tcp6connect, + isc_sockstatscounter_tcp6acceptfail, + isc_sockstatscounter_tcp6accept, + isc_sockstatscounter_tcp6sendfail, + isc_sockstatscounter_tcp6recvfail, + isc_sockstatscounter_tcp6active +}; + +#if 0 +/* XXX: not currently used */ +static const isc_statscounter_t unixstatsindex[] = { + isc_sockstatscounter_unixopen, + isc_sockstatscounter_unixopenfail, + isc_sockstatscounter_unixclose, + isc_sockstatscounter_unixbindfail, + isc_sockstatscounter_unixconnectfail, + isc_sockstatscounter_unixconnect, + isc_sockstatscounter_unixacceptfail, + isc_sockstatscounter_unixaccept, + isc_sockstatscounter_unixsendfail, + isc_sockstatscounter_unixrecvfail, + isc_sockstatscounter_unixactive +}; +#endif + /* * libuv is not thread safe, but has mechanisms to pass messages * between threads. Each socket is owned by a thread. For UDP @@ -206,6 +284,10 @@ nm_destroy(isc_nm_t **mgr0) { isc_thread_join(worker->thread, NULL); } + if (mgr->stats != NULL) { + isc_stats_detach(&mgr->stats); + } + isc_condition_destroy(&mgr->wkstatecond); isc_mutex_destroy(&mgr->lock); @@ -828,15 +910,25 @@ isc_nmsocket_detach(isc_nmsocket_t **sockp) { void isc__nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, - isc_nmsocket_type type) + isc_nmsocket_type type, isc_nmiface_t *iface) { + uint16_t family; + + REQUIRE(sock != NULL); + REQUIRE(mgr != NULL); + REQUIRE(iface!= NULL); + + family = iface->addr.type.sa.sa_family; + *sock = (isc_nmsocket_t) { .type = type, + .iface = iface, .fd = -1, .ah_size = 32, .inactivehandles = isc_astack_new(mgr->mctx, 60), .inactivereqs = isc_astack_new(mgr->mctx, 60) }; + isc_nm_attach(mgr, &sock->mgr); sock->uv_handle.handle.data = sock; @@ -850,6 +942,28 @@ isc__nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, sock->ah_handles[i] = NULL; } + switch (type) { + case isc_nm_udpsocket: + case isc_nm_udplistener: + if (family == AF_INET) { + sock->statsindex = udp4statsindex; + } else { + sock->statsindex = udp6statsindex; + } + break; + case isc_nm_tcpsocket: + case isc_nm_tcplistener: + case isc_nm_tcpchildlistener: + if (family == AF_INET) { + sock->statsindex = tcp4statsindex; + } else { + sock->statsindex = tcp6statsindex; + } + break; + default: + break; + } + isc_mutex_init(&sock->lock); isc_condition_init(&sock->cond); isc_refcount_init(&sock->references, 1); @@ -1291,3 +1405,33 @@ isc__nm_acquire_interlocked_force(isc_nm_t *mgr) { } UNLOCK(&mgr->lock); } + +void +isc_nm_setstats(isc_nm_t *mgr, isc_stats_t *stats) { + REQUIRE(VALID_NM(mgr)); + REQUIRE(mgr->stats == NULL); + REQUIRE(isc_stats_ncounters(stats) == isc_sockstatscounter_max); + + isc_stats_attach(stats, &mgr->stats); +} + + +void +isc__nm_incstats(isc_nm_t *mgr, isc_statscounter_t counterid) { + REQUIRE(VALID_NM(mgr)); + REQUIRE(counterid != -1); + + if (mgr->stats != NULL) { + isc_stats_increment(mgr->stats, counterid); + } +} + +void +isc__nm_decstats(isc_nm_t *mgr, isc_statscounter_t counterid) { + REQUIRE(VALID_NM(mgr)); + REQUIRE(counterid != -1); + + if (mgr->stats != NULL) { + isc_stats_decrement(mgr->stats, counterid); + } +} diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index bab631533f..4aee40a084 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -147,8 +147,7 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface, REQUIRE(VALID_NM(mgr)); nsock = isc_mem_get(mgr->mctx, sizeof(*nsock)); - isc__nmsocket_init(nsock, mgr, isc_nm_tcplistener); - nsock->iface = iface; + isc__nmsocket_init(nsock, mgr, isc_nm_tcplistener, iface); nsock->nchildren = mgr->nworkers; atomic_init(&nsock->rchildren, mgr->nworkers); nsock->children = isc_mem_get(mgr->mctx, @@ -223,9 +222,9 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) { for (int i = 0; i < sock->nchildren; i++) { isc_nmsocket_t *csock = &sock->children[i]; - isc__nmsocket_init(csock, sock->mgr, isc_nm_tcpchildlistener); + isc__nmsocket_init(csock, sock->mgr, + isc_nm_tcpchildlistener, sock->iface); csock->parent = sock; - csock->iface = sock->iface; csock->tid = i; csock->pquota = sock->pquota; csock->backlog = sock->backlog; @@ -680,10 +679,9 @@ accept_connection(isc_nmsocket_t *ssock) { } csock = isc_mem_get(ssock->mgr->mctx, sizeof(isc_nmsocket_t)); - isc__nmsocket_init(csock, ssock->mgr, isc_nm_tcpsocket); + isc__nmsocket_init(csock, ssock->mgr, isc_nm_tcpsocket, ssock->iface); csock->tid = isc_nm_tid(); csock->extrahandlesize = ssock->extrahandlesize; - csock->iface = ssock->iface; csock->quota = quota; quota = NULL; diff --git a/lib/isc/netmgr/tcpdns.c b/lib/isc/netmgr/tcpdns.c index a6cf921490..7aa90fefcd 100644 --- a/lib/isc/netmgr/tcpdns.c +++ b/lib/isc/netmgr/tcpdns.c @@ -118,7 +118,8 @@ dnslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) { /* We need to create a 'wrapper' dnssocket for this connection */ dnssock = isc_mem_get(handle->sock->mgr->mctx, sizeof(*dnssock)); - isc__nmsocket_init(dnssock, handle->sock->mgr, isc_nm_tcpdnssocket); + isc__nmsocket_init(dnssock, handle->sock->mgr, + isc_nm_tcpdnssocket, handle->sock->iface); /* We need to copy read callbacks from outer socket */ dnssock->rcb.recv = dnslistensock->rcb.recv; @@ -126,7 +127,6 @@ dnslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) { dnssock->extrahandlesize = dnslistensock->extrahandlesize; isc_nmsocket_attach(handle->sock, &dnssock->outer); dnssock->peer = handle->sock->peer; - dnssock->iface = handle->sock->iface; dnssock->read_timeout = handle->sock->mgr->init; dnssock->tid = isc_nm_tid(); dnssock->closehandle_cb = resume_processing; @@ -293,8 +293,7 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface, REQUIRE(VALID_NM(mgr)); - isc__nmsocket_init(dnslistensock, mgr, isc_nm_tcpdnslistener); - dnslistensock->iface = iface; + isc__nmsocket_init(dnslistensock, mgr, isc_nm_tcpdnslistener, iface); dnslistensock->rcb.recv = cb; dnslistensock->rcbarg = cbarg; dnslistensock->accept_cb.accept = accept_cb; diff --git a/lib/isc/netmgr/udp.c b/lib/isc/netmgr/udp.c index 2731ce2497..5b870a13ed 100644 --- a/lib/isc/netmgr/udp.c +++ b/lib/isc/netmgr/udp.c @@ -54,8 +54,7 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, * socket for each worker thread. */ nsock = isc_mem_get(mgr->mctx, sizeof(isc_nmsocket_t)); - isc__nmsocket_init(nsock, mgr, isc_nm_udplistener); - nsock->iface = iface; + isc__nmsocket_init(nsock, mgr, isc_nm_udplistener, iface); nsock->nchildren = mgr->nworkers; atomic_init(&nsock->rchildren, mgr->nworkers); nsock->children = isc_mem_get(mgr->mctx, @@ -74,9 +73,8 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc__netievent_udplisten_t *ievent = NULL; isc_nmsocket_t *csock = &nsock->children[i]; - isc__nmsocket_init(csock, mgr, isc_nm_udpsocket); + isc__nmsocket_init(csock, mgr, isc_nm_udpsocket, iface); csock->parent = nsock; - csock->iface = iface; csock->tid = i; csock->extrahandlesize = extrahandlesize; diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index 618737983a..5d5b939ea9 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -450,6 +450,7 @@ isc_nm_listentcpdns isc_nm_listenudp isc_nm_maxudp isc_nm_send +isc_nm_setstats isc_nm_start isc_nm_tcp_gettimeouts isc_nm_tcp_settimeouts From 90a1dabe7428ace035675816f0e8607026d64219 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Mon, 6 Jan 2020 20:26:47 -0800 Subject: [PATCH 2/4] count statistics in netmgr UDP code - also restored a test in the statistics test which was changed when the netmgr was introduced because active sockets were not being counted. --- bin/tests/system/statistics/tests.sh | 2 +- lib/isc/netmgr/netmgr.c | 4 +++ lib/isc/netmgr/udp.c | 37 ++++++++++++++++++++-------- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/bin/tests/system/statistics/tests.sh b/bin/tests/system/statistics/tests.sh index ce82d0d2a8..1a4c5a5778 100644 --- a/bin/tests/system/statistics/tests.sh +++ b/bin/tests/system/statistics/tests.sh @@ -71,7 +71,7 @@ $RNDCCMD -s 10.53.0.3 stats > /dev/null 2>&1 [ -f ns3/named.stats ] || ret=1 if [ ! "$CYGWIN" ]; then nsock0nstat=`grep "UDP/IPv4 sockets active" ns3/named.stats | awk '{print $1}'` - [ 0 -eq ${nsock0nstat:-0} ] || ret=1 + [ 0 -ne ${nsock0nstat:-0} ] || ret=1 fi if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index 4f94e11a95..80af9f09b3 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -855,6 +855,8 @@ isc__nmsocket_prep_destroy(isc_nmsocket_t *sock) { 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]); } } @@ -950,6 +952,7 @@ isc__nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, } else { sock->statsindex = udp6statsindex; } + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_ACTIVE]); break; case isc_nm_tcpsocket: case isc_nm_tcplistener: @@ -960,6 +963,7 @@ isc__nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, sock->statsindex = tcp6statsindex; } break; + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_ACTIVE]); default: break; } diff --git a/lib/isc/netmgr/udp.c b/lib/isc/netmgr/udp.c index 5b870a13ed..6b79d8e0bc 100644 --- a/lib/isc/netmgr/udp.c +++ b/lib/isc/netmgr/udp.c @@ -117,6 +117,7 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) { isc__netievent_udplisten_t *ievent = (isc__netievent_udplisten_t *) ev0; isc_nmsocket_t *sock = ievent->sock; + int r, flags = 0; REQUIRE(sock->type == isc_nm_udpsocket); REQUIRE(sock->iface != NULL); @@ -127,19 +128,30 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) { isc_nmsocket_attach(sock, (isc_nmsocket_t **)&sock->uv_handle.udp.data); - uv_udp_open(&sock->uv_handle.udp, sock->fd); - int flags = 0; + r = uv_udp_open(&sock->uv_handle.udp, sock->fd); + if (r == 0) { + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_OPEN]); + } else { + isc__nm_incstats(sock->mgr, + sock->statsindex[STATID_OPENFAIL]); + } + if (sock->iface->addr.type.sa.sa_family == AF_INET6) { flags = UV_UDP_IPV6ONLY; } - uv_udp_bind(&sock->uv_handle.udp, - &sock->parent->iface->addr.type.sa, flags); + + r = uv_udp_bind(&sock->uv_handle.udp, + &sock->parent->iface->addr.type.sa, flags); + if (r < 0) { + isc__nm_incstats(sock->mgr, + sock->statsindex[STATID_BINDFAIL]); + } + uv_recv_buffer_size(&sock->uv_handle.handle, &(int){16 * 1024 * 1024}); uv_send_buffer_size(&sock->uv_handle.handle, &(int){16 * 1024 * 1024}); - uv_udp_recv_start(&sock->uv_handle.udp, isc__nm_alloc_cb, - udp_recv_cb); + uv_udp_recv_start(&sock->uv_handle.udp, isc__nm_alloc_cb, udp_recv_cb); } static void @@ -157,6 +169,8 @@ stop_udp_child(isc_nmsocket_t *sock) { uv_udp_recv_stop(&sock->uv_handle.udp); uv_close((uv_handle_t *) &sock->uv_handle.udp, udp_close_cb); + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_CLOSE]); + LOCK(&sock->parent->lock); atomic_fetch_sub(&sock->parent->rchildren, 1); UNLOCK(&sock->parent->lock); @@ -258,10 +272,9 @@ isc__nm_async_udpstop(isc__networker_t *worker, isc__netievent_t *ev0) { } /* - * udp_recv_cb handles incoming UDP packet from uv. - * The buffer here is reused for a series of packets, - * so we need to allocate a new one. This new one can - * be reused to send the response then. + * udp_recv_cb handles incoming UDP packet from uv. The buffer here is + * reused for a series of packets, so we need to allocate a new one. This + * new one can be reused to send the response then. */ static void udp_recv_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf, @@ -434,6 +447,8 @@ udp_send_cb(uv_udp_send_t *req, int status) { if (status < 0) { result = isc__nm_uverr2result(status); + isc__nm_incstats(uvreq->sock->mgr, + uvreq->sock->statsindex[STATID_SENDFAIL]); } uvreq->cb.send(uvreq->handle, result, uvreq->cbarg); @@ -459,6 +474,8 @@ udp_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req, &sock->uv_handle.udp, &req->uvbuf, 1, &peer->type.sa, udp_send_cb); if (rv < 0) { + isc__nm_incstats(req->sock->mgr, + req->sock->statsindex[STATID_SENDFAIL]); return (isc__nm_uverr2result(rv)); } From 5234a8e00a6ae1df738020f27544594ccb8d5215 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Tue, 7 Jan 2020 10:13:30 -0800 Subject: [PATCH 3/4] count statistics in netmgr TCP code --- lib/isc/netmgr/tcp.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index 4aee40a084..c4dd1a31e8 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -68,12 +68,15 @@ tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) { r = uv_tcp_init(&worker->loop, &sock->uv_handle.tcp); if (r != 0) { + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_OPENFAIL]); return (r); } if (req->local.length != 0) { r = uv_tcp_bind(&sock->uv_handle.tcp, &req->local.type.sa, 0); if (r != 0) { + isc__nm_incstats(sock->mgr, + sock->statsindex[STATID_BINDFAIL]); tcp_close_direct(sock); return (r); } @@ -115,6 +118,7 @@ tcp_connect_cb(uv_connect_t *uvreq, int status) { isc_nmhandle_t *handle = NULL; struct sockaddr_storage ss; + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_CONNECT]); uv_tcp_getpeername(&sock->uv_handle.tcp, (struct sockaddr *) &ss, &(int){sizeof(ss)}); @@ -129,6 +133,8 @@ tcp_connect_cb(uv_connect_t *uvreq, int status) { * TODO: * Handle the connect error properly and free the socket. */ + isc__nm_incstats(sock->mgr, + sock->statsindex[STATID_CONNECTFAIL]); req->cb.connect(NULL, isc__nm_uverr2result(status), req->cbarg); } @@ -239,11 +245,15 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) { r = uv_tcp_init(&worker->loop, &sock->uv_handle.tcp); if (r != 0) { /* It was never opened */ + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_OPENFAIL]); atomic_store(&sock->closed, true); sock->result = isc__nm_uverr2result(r); atomic_store(&sock->listen_error, true); goto done; } + + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_OPEN]); + if (sock->iface->addr.type.sa.sa_family == AF_INET6) { flags = UV_TCP_IPV6ONLY; } @@ -251,6 +261,7 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) { r = uv_tcp_bind(&sock->uv_handle.tcp, &sock->iface->addr.type.sa, flags); if (r != 0) { + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_BINDFAIL]); uv_close(&sock->uv_handle.handle, tcp_close_cb); sock->result = isc__nm_uverr2result(r); atomic_store(&sock->listen_error, true); @@ -514,6 +525,7 @@ isc__nm_async_startread(isc__networker_t *worker, isc__netievent_t *ev0) { isc__netievent_startread_t *ievent = (isc__netievent_startread_t *) ev0; isc_nmsocket_t *sock = ievent->sock; + int r; REQUIRE(worker->id == isc_nm_tid()); if (sock->read_timeout != 0) { @@ -526,7 +538,10 @@ isc__nm_async_startread(isc__networker_t *worker, isc__netievent_t *ev0) { sock->read_timeout, 0); } - uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb, read_cb); + r = uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb, read_cb); + if (r != 0) { + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_RECVFAIL]); + } } isc_result_t @@ -610,14 +625,11 @@ read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { .base = (unsigned char *) buf->base, .length = nread }; - /* - * This might happen if the inner socket is closing. - * It means that it's detached, so the socket will - * be closed. - */ + if (sock->rcb.recv != NULL) { sock->rcb.recv(sock->tcphandle, ®ion, sock->rcbarg); } + sock->read_timeout = (atomic_load(&sock->keepalive) ? sock->mgr->keepalive : sock->mgr->idle); @@ -627,6 +639,7 @@ read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { uv_timer_start(&sock->timer, readtimeout_cb, sock->read_timeout, 0); } + isc__nm_free_uvbuf(sock, buf); return; } @@ -635,14 +648,16 @@ read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { if (sock->quota) { isc_quota_detach(&sock->quota); } + /* - * This might happen if the inner socket is closing. - * It means that it's detached, so the socket will - * be closed. + * This might happen if the inner socket is closing. It means that + * it's detached, so the socket will be closed. */ if (sock->rcb.recv != NULL) { + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_RECVFAIL]); sock->rcb.recv(sock->tcphandle, NULL, sock->rcbarg); } + /* * We don't need to clean up now; the socket will be closed and * resources and quota reclaimed when handle is freed in @@ -674,10 +689,14 @@ accept_connection(isc_nmsocket_t *ssock) { if (ssock->pquota != NULL) { result = isc_quota_attach(ssock->pquota, "a); if (result != ISC_R_SUCCESS) { + isc__nm_incstats(ssock->mgr, + ssock->statsindex[STATID_ACCEPTFAIL]); return (result); } } + isc__nm_incstats(ssock->mgr, ssock->statsindex[STATID_ACCEPT]); + csock = isc_mem_get(ssock->mgr->mctx, sizeof(isc_nmsocket_t)); isc__nmsocket_init(csock, ssock->mgr, isc_nm_tcpsocket, ssock->iface); csock->tid = isc_nm_tid(); @@ -790,6 +809,8 @@ tcp_send_cb(uv_write_t *req, int status) { if (status < 0) { result = isc__nm_uverr2result(status); + isc__nm_incstats(uvreq->sock->mgr, + uvreq->sock->statsindex[STATID_SENDFAIL]); } uvreq->cb.send(uvreq->handle, result, uvreq->cbarg); @@ -830,6 +851,8 @@ tcp_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) { r = uv_write(&req->uv_req.write, &sock->uv_handle.stream, &req->uvbuf, 1, tcp_send_cb); if (r < 0) { + isc__nm_incstats(sock->mgr, + sock->statsindex[STATID_SENDFAIL]); req->cb.send(NULL, isc__nm_uverr2result(r), req->cbarg); isc__nm_uvreq_put(&req, sock); return (isc__nm_uverr2result(r)); @@ -844,6 +867,7 @@ tcp_close_cb(uv_handle_t *uvhandle) { REQUIRE(VALID_NMSOCK(sock)); + isc__nm_incstats(sock->mgr, sock->statsindex[STATID_CLOSE]); atomic_store(&sock->closed, true); isc__nmsocket_prep_destroy(sock); } From c3ed086cf012514710d08f492fc7ee5efb2f09eb Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Thu, 9 Jan 2020 17:44:19 -0800 Subject: [PATCH 4/4] CHANGES --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index 74ff154cde..f08444f602 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +5343. [func] Add statistics counters to the netmgr. [GL #1311] + 5342. [bug] Disable pktinfo for ipv6 - bind to all interfaces explicitly as libuv doesn't pass us pktinfo structure, [GL #1558]