aboutsummaryrefslogtreecommitdiff
path: root/contrib/bind9/bin/named/interfacemgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/bin/named/interfacemgr.c')
-rw-r--r--contrib/bind9/bin/named/interfacemgr.c91
1 files changed, 79 insertions, 12 deletions
diff --git a/contrib/bind9/bin/named/interfacemgr.c b/contrib/bind9/bin/named/interfacemgr.c
index a3410567e631..db410310147c 100644
--- a/contrib/bind9/bin/named/interfacemgr.c
+++ b/contrib/bind9/bin/named/interfacemgr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,9 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: interfacemgr.c,v 1.59.2.5.8.18 2006/07/19 00:16:28 marka Exp $ */
+/* $Id: interfacemgr.c,v 1.76.18.8 2006/07/20 01:10:30 marka Exp $ */
+
+/*! \file */
#include <config.h>
@@ -37,24 +39,29 @@
#define IFMGR_COMMON_LOGARGS \
ns_g_lctx, NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR
+/*% nameserver interface manager structure */
struct ns_interfacemgr {
- unsigned int magic; /* Magic number. */
+ unsigned int magic; /*%< Magic number. */
int references;
isc_mutex_t lock;
- isc_mem_t * mctx; /* Memory context. */
- isc_taskmgr_t * taskmgr; /* Task manager. */
- isc_socketmgr_t * socketmgr; /* Socket manager. */
+ isc_mem_t * mctx; /*%< Memory context. */
+ isc_taskmgr_t * taskmgr; /*%< Task manager. */
+ isc_socketmgr_t * socketmgr; /*%< Socket manager. */
dns_dispatchmgr_t * dispatchmgr;
- unsigned int generation; /* Current generation no. */
+ unsigned int generation; /*%< Current generation no. */
ns_listenlist_t * listenon4;
ns_listenlist_t * listenon6;
- dns_aclenv_t aclenv; /* Localhost/localnets ACLs */
- ISC_LIST(ns_interface_t) interfaces; /* List of interfaces. */
+ dns_aclenv_t aclenv; /*%< Localhost/localnets ACLs */
+ ISC_LIST(ns_interface_t) interfaces; /*%< List of interfaces. */
+ ISC_LIST(isc_sockaddr_t) listenon;
};
static void
purge_old_interfaces(ns_interfacemgr_t *mgr);
+static void
+clearlistenon(ns_interfacemgr_t *mgr);
+
isc_result_t
ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
isc_socketmgr_t *socketmgr,
@@ -85,6 +92,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
mgr->listenon6 = NULL;
ISC_LIST_INIT(mgr->interfaces);
+ ISC_LIST_INIT(mgr->listenon);
/*
* The listen-on lists are initially empty.
@@ -117,6 +125,7 @@ ns_interfacemgr_destroy(ns_interfacemgr_t *mgr) {
dns_aclenv_destroy(&mgr->aclenv);
ns_listenlist_detach(&mgr->listenon4);
ns_listenlist_detach(&mgr->listenon6);
+ clearlistenon(mgr);
DESTROYLOCK(&mgr->lock);
mgr->magic = 0;
isc_mem_put(mgr->mctx, mgr, sizeof(*mgr));
@@ -158,7 +167,7 @@ void
ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) {
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
- /*
+ /*%
* Shut down and detach all interfaces.
* By incrementing the generation count, we make purge_old_interfaces()
* consider all interfaces "old".
@@ -432,7 +441,7 @@ ns_interface_detach(ns_interface_t **targetp) {
*targetp = NULL;
}
-/*
+/*%
* Search the interface list for an interface whose address and port
* both match those of 'addr'. Return a pointer to it, or NULL if not found.
*/
@@ -447,7 +456,7 @@ find_matching_interface(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) {
return (ifp);
}
-/*
+/*%
* Remove any interfaces whose generation number is not the current one.
*/
static void
@@ -537,6 +546,43 @@ setup_locals(ns_interfacemgr_t *mgr, isc_interface_t *interface) {
return (ISC_R_SUCCESS);
}
+static void
+setup_listenon(ns_interfacemgr_t *mgr, isc_interface_t *interface,
+ in_port_t port)
+{
+ isc_sockaddr_t *addr;
+ isc_sockaddr_t *old;
+
+ addr = isc_mem_get(mgr->mctx, sizeof(*addr));
+ if (addr == NULL)
+ return;
+
+ isc_sockaddr_fromnetaddr(addr, &interface->address, port);
+
+ for (old = ISC_LIST_HEAD(mgr->listenon);
+ old != NULL;
+ old = ISC_LIST_NEXT(old, link))
+ if (isc_sockaddr_equal(addr, old))
+ break;
+
+ if (old != NULL)
+ isc_mem_put(mgr->mctx, addr, sizeof(*addr));
+ else
+ ISC_LIST_APPEND(mgr->listenon, addr, link);
+}
+
+static void
+clearlistenon(ns_interfacemgr_t *mgr) {
+ isc_sockaddr_t *old;
+
+ old = ISC_LIST_HEAD(mgr->listenon);
+ while (old != NULL) {
+ ISC_LIST_UNLINK(mgr->listenon, old, link);
+ isc_mem_put(mgr->mctx, old, sizeof(*old));
+ old = ISC_LIST_HEAD(mgr->listenon);
+ }
+}
+
static isc_result_t
do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
isc_boolean_t verbose)
@@ -553,6 +599,7 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
isc_sockaddr_t listen_addr;
ns_interface_t *ifp;
isc_boolean_t log_explicit = ISC_FALSE;
+ isc_boolean_t dolistenon;
if (ext_listen != NULL)
adjusting = ISC_TRUE;
@@ -643,6 +690,7 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
result = clearacl(mgr->mctx, &mgr->aclenv.localnets);
if (result != ISC_R_SUCCESS)
goto cleanup_iter;
+ clearlistenon(mgr);
}
for (result = isc_interfaceiter_first(iter);
@@ -688,6 +736,7 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
}
ll = (family == AF_INET) ? mgr->listenon4 : mgr->listenon6;
+ dolistenon = ISC_TRUE;
for (le = ISC_LIST_HEAD(ll->elts);
le != NULL;
le = ISC_LIST_NEXT(le, link))
@@ -723,6 +772,11 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
if (match <= 0)
continue;
+ if (adjusting == ISC_FALSE && dolistenon == ISC_TRUE) {
+ setup_listenon(mgr, &interface, le->port);
+ dolistenon = ISC_FALSE;
+ }
+
/*
* The case of "any" IPv6 address will require
* special considerations later, so remember it.
@@ -909,3 +963,16 @@ ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr) {
}
UNLOCK(&mgr->lock);
}
+
+isc_boolean_t
+ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) {
+ isc_sockaddr_t *old;
+
+ old = ISC_LIST_HEAD(mgr->listenon);
+ for (old = ISC_LIST_HEAD(mgr->listenon);
+ old != NULL;
+ old = ISC_LIST_NEXT(old, link))
+ if (isc_sockaddr_equal(old, addr))
+ return (ISC_TRUE);
+ return (ISC_FALSE);
+}