From d15f51c600ed29b2dc379c433fb226c3a13ac0bb Mon Sep 17 00:00:00 2001 From: Andreas Gustafsson Date: Fri, 22 Sep 2000 00:13:08 +0000 Subject: [PATCH] 484. [bug] When the server was reloaded after removing addresses from the named.conf "listen-on" statement, sockets were still listening on the removed addresses due to reference count loops. [RT #325] Now there is one client manager object per interface instead of a single global one; when an interface goes away, it simply destroys the associated client manager, which will cause all its clients to be shut down in an orderly fashion. --- CHANGES | 5 +++ bin/named/client.c | 5 +-- bin/named/include/named/interfacemgr.h | 21 +++++---- bin/named/include/named/server.h | 3 +- bin/named/interfacemgr.c | 59 ++++++++++++++------------ bin/named/server.c | 9 +--- 6 files changed, 51 insertions(+), 51 deletions(-) diff --git a/CHANGES b/CHANGES index efdb0fd75c..2336812112 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ + 484. [bug] When the server was reloaded after removing addresses + from the named.conf "listen-on" statement, sockets + were still listening on the removed addresses due + to reference count loops. [RT #325] + 483. [bug] nslookup: "set all" showed search but it was not settable. diff --git a/bin/named/client.c b/bin/named/client.c index 8f4df4e05e..a35b0289b0 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: client.c,v 1.114 2000/09/18 22:54:08 gson Exp $ */ +/* $Id: client.c,v 1.115 2000/09/22 00:13:03 gson Exp $ */ #include @@ -1711,9 +1711,8 @@ ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, break; } - client->state = NS_CLIENTSTATE_READY; - ns_interface_attach(ifp, &client->interface); + client->state = NS_CLIENTSTATE_READY; if (tcp) { client->attributes |= NS_CLIENTATTR_TCP; diff --git a/bin/named/include/named/interfacemgr.h b/bin/named/include/named/interfacemgr.h index 0e25d998c9..71d07f330d 100644 --- a/bin/named/include/named/interfacemgr.h +++ b/bin/named/include/named/interfacemgr.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: interfacemgr.h,v 1.19 2000/08/01 01:12:05 tale Exp $ */ +/* $Id: interfacemgr.h,v 1.20 2000/09/22 00:13:07 gson Exp $ */ #ifndef NAMED_INTERFACEMGR_H #define NAMED_INTERFACEMGR_H 1 @@ -73,13 +73,13 @@ struct ns_interface { unsigned int generation; /* Generation number. */ isc_sockaddr_t addr; /* Address and port. */ char name[32]; /* Null terminated. */ - isc_socket_t * udpsocket; /* UDP socket. */ dns_dispatch_t * udpdispatch; /* UDP dispatcher. */ isc_socket_t * tcpsocket; /* TCP socket. */ isc_task_t * task; int ntcptarget; /* Desired number of concurrent TCP accepts */ int ntcpcurrent; /* Current ditto, locked */ + ns_clientmgr_t * clientmgr; /* Client manager. */ ISC_LINK(ns_interface_t) link; }; @@ -91,7 +91,7 @@ isc_result_t ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_socketmgr_t *socketmgr, dns_dispatchmgr_t *dispatchmgr, - ns_clientmgr_t *clientmgr, ns_interfacemgr_t **mgrp); + ns_interfacemgr_t **mgrp); /* * Create a new interface manager. * @@ -135,14 +135,6 @@ ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value); * The previous IPv6 listen-on list is freed. */ -isc_result_t -ns_interfacemgr_findudpdispatcher(ns_interfacemgr_t *mgr, - isc_sockaddr_t *address, - dns_dispatch_t **dispatchp); -/* - * Find a UDP dispatcher matching 'address', if it exists. - */ - dns_aclenv_t * ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr); @@ -152,4 +144,11 @@ ns_interface_attach(ns_interface_t *source, ns_interface_t **target); void ns_interface_detach(ns_interface_t **targetp); +void +ns_interface_shutdown(ns_interface_t *ifp); +/* + * Stop listening for queries on interface 'ifp'. + * May safely be called multiple times. + */ + #endif /* NAMED_INTERFACEMGR_H */ diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h index 4ae8cfa75b..a7e10155f3 100644 --- a/bin/named/include/named/server.h +++ b/bin/named/include/named/server.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.h,v 1.36 2000/09/05 03:35:16 marka Exp $ */ +/* $Id: server.h,v 1.37 2000/09/22 00:13:08 gson Exp $ */ #ifndef NAMED_SERVER_H #define NAMED_SERVER_H 1 @@ -55,7 +55,6 @@ struct ns_server { /* Server data structures. */ dns_loadmgr_t * loadmgr; dns_zonemgr_t * zonemgr; - ns_clientmgr_t * clientmgr; dns_viewlist_t viewlist; ns_interfacemgr_t * interfacemgr; dns_db_t * in_roothints; diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c index 419a047f57..ce84ac0e44 100644 --- a/bin/named/interfacemgr.c +++ b/bin/named/interfacemgr.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: interfacemgr.c,v 1.49 2000/08/26 01:42:26 bwelling Exp $ */ +/* $Id: interfacemgr.c,v 1.50 2000/09/22 00:13:04 gson Exp $ */ #include @@ -45,7 +45,6 @@ struct ns_interfacemgr { isc_taskmgr_t * taskmgr; /* Task manager. */ isc_socketmgr_t * socketmgr; /* Socket manager. */ dns_dispatchmgr_t * dispatchmgr; - ns_clientmgr_t * clientmgr; /* Client manager. */ unsigned int generation; /* Current generation no. */ ns_listenlist_t * listenon4; ns_listenlist_t * listenon6; @@ -60,7 +59,7 @@ isc_result_t ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_socketmgr_t *socketmgr, dns_dispatchmgr_t *dispatchmgr, - ns_clientmgr_t *clientmgr, ns_interfacemgr_t **mgrp) + ns_interfacemgr_t **mgrp) { isc_result_t result; ns_interfacemgr_t *mgr; @@ -81,10 +80,10 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, mgr->taskmgr = taskmgr; mgr->socketmgr = socketmgr; mgr->dispatchmgr = dispatchmgr; - mgr->clientmgr = clientmgr; mgr->generation = 1; mgr->listenon4 = NULL; mgr->listenon6 = NULL; + ISC_LIST_INIT(mgr->interfaces); /* @@ -185,6 +184,7 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, ifp->addr = *addr; strncpy(ifp->name, name, sizeof(ifp->name)); ifp->name[sizeof(ifp->name)-1] = '\0'; + ifp->clientmgr = NULL; result = isc_mutex_init(&ifp->lock); if (result != ISC_R_SUCCESS) @@ -203,6 +203,16 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, } isc_task_setname(ifp->task, "ifp", ifp); + result = ns_clientmgr_create(mgr->mctx, mgr->taskmgr, + ns_g_timermgr, + &ifp->clientmgr); + if (result != ISC_R_SUCCESS) { + isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, + "ns_clientmgr_create() failed: %s", + isc_result_totext(result)); + goto clientmgr_create_failure; + } + ifp->udpdispatch = NULL; ifp->tcpsocket = NULL; @@ -215,6 +225,8 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, ifp->ntcptarget = 1; ifp->ntcpcurrent = 0; + ISC_LINK_INIT(ifp, link); + ns_interfacemgr_attach(mgr, &ifp->mgr); ISC_LIST_APPEND(mgr->interfaces, ifp, link); @@ -224,6 +236,8 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, return (ISC_R_SUCCESS); + clientmgr_create_failure: + isc_task_destroy(&ifp->task); task_create_failure: DESTROYLOCK(&ifp->lock); lock_create_failure: @@ -259,7 +273,7 @@ ns_interface_listenudp(ns_interface_t *ifp) { goto udp_dispatch_failure; } - result = ns_clientmgr_createclients(ifp->mgr->clientmgr, ns_g_cpus, + result = ns_clientmgr_createclients(ifp->clientmgr, ns_g_cpus, ifp, ISC_FALSE); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, @@ -307,7 +321,7 @@ ns_interface_accepttcp(ns_interface_t *ifp) { goto tcp_listen_failure; } - result = ns_clientmgr_createclients(ifp->mgr->clientmgr, + result = ns_clientmgr_createclients(ifp->clientmgr, ifp->ntcptarget, ifp, ISC_TRUE); if (result != ISC_R_SUCCESS) { @@ -361,18 +375,26 @@ ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, return (result); } +void +ns_interface_shutdown(ns_interface_t *ifp) { + if (ifp->clientmgr != NULL) + ns_clientmgr_destroy(&ifp->clientmgr); +} + static void ns_interface_destroy(ns_interface_t *ifp) { isc_mem_t *mctx = ifp->mgr->mctx; REQUIRE(NS_INTERFACE_VALID(ifp)); + ns_interface_shutdown(ifp); + if (ifp->udpdispatch != NULL) dns_dispatch_detach(&ifp->udpdispatch); - if (ifp->tcpsocket != NULL) { + if (ifp->tcpsocket != NULL) isc_socket_detach(&ifp->tcpsocket); - } + if (ifp->task != NULL) + isc_task_detach(&ifp->task); - isc_task_detach(&ifp->task); DESTROYLOCK(&ifp->lock); ns_interfacemgr_detach(&ifp->mgr); @@ -439,6 +461,7 @@ purge_old_interfaces(ns_interfacemgr_t *mgr) { isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_INFO, "no longer listening on %s", sabuf); + ns_interface_shutdown(ifp); ns_interface_detach(&ifp); } } @@ -708,21 +731,3 @@ ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value) { UNLOCK(&mgr->lock); } -isc_result_t -ns_interfacemgr_findudpdispatcher(ns_interfacemgr_t *mgr, - isc_sockaddr_t *address, - dns_dispatch_t **dispatchp) -{ - ns_interface_t *ifp; - - /* - * Find a UDP dispatcher matching 'address', if it exists. - */ - - ifp = find_matching_interface(mgr, address); - if (ifp == NULL || ifp->udpdispatch == NULL) - return (ISC_R_NOTFOUND); - dns_dispatch_attach(ifp->udpdispatch, dispatchp); - - return (ISC_R_SUCCESS); -} diff --git a/bin/named/server.c b/bin/named/server.c index 8c2b72d348..b26130febc 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.221 2000/09/12 10:08:56 bwelling Exp $ */ +/* $Id: server.c,v 1.222 2000/09/22 00:13:05 gson Exp $ */ #include @@ -1618,13 +1618,8 @@ run_server(isc_task_t *task, isc_event_t *event) { &ns_g_dispatchmgr), "creating dispatch manager"); - CHECKFATAL(ns_clientmgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr, - &server->clientmgr), - "creating client manager"); - CHECKFATAL(ns_interfacemgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_socketmgr, ns_g_dispatchmgr, - server->clientmgr, &server->interfacemgr), "creating interface manager"); @@ -1664,7 +1659,6 @@ shutdown_server(isc_task_t *task, isc_event_t *event) { dns_view_detach(&view); } - ns_clientmgr_destroy(&server->clientmgr); isc_timer_detach(&server->interface_timer); ns_interfacemgr_shutdown(server->interfacemgr); @@ -1710,7 +1704,6 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { /* Initialize server data structures. */ server->loadmgr = NULL; server->zonemgr = NULL; - server->clientmgr = NULL; server->interfacemgr = NULL; ISC_LIST_INIT(server->viewlist); server->in_roothints = NULL;