From 62700b67eb8abb7d13f9c3c1bc4b60a1477d35d8 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Mon, 5 Jan 2004 06:56:44 +0000 Subject: [PATCH] 1539. [bug] Open UDP sockets for notify-source and transfer-source that use reserved ports at startup. [RT #9475] --- CHANGES | 3 +- bin/named/include/named/server.h | 11 ++- bin/named/include/named/types.h | 4 +- bin/named/server.c | 120 ++++++++++++++++++++++++++++++- bin/named/zoneconf.c | 7 +- 5 files changed, 139 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 324f5f8493..10ab099356 100644 --- a/CHANGES +++ b/CHANGES @@ -18,7 +18,8 @@ 1540. [placeholder] rt8934 -1539. [placeholder] rt9475 +1539. [bug] Open UDP sockets for notify-source and transfer-source + that use reserved ports at startup. [RT #9475] 1538. [placeholder] rt9997 diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h index 6c9fa7b118..2a8a12cd80 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.71 2003/01/20 05:46:10 marka Exp $ */ +/* $Id: server.h,v 1.72 2004/01/05 06:56:44 marka Exp $ */ #ifndef NAMED_SERVER_H #define NAMED_SERVER_H 1 @@ -89,6 +89,9 @@ struct ns_server { isc_uint64_t * querystats; /* Query statistics counters */ ns_controls_t * controls; /* Control channels */ + unsigned int dispatchgen; + ns_dispatchlist_t dispatches; + }; #define NS_SERVER_MAGIC ISC_MAGIC('S','V','E','R') @@ -201,4 +204,10 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args); isc_result_t ns_server_dumprecursing(ns_server_t *server); +/* + * Maintain a list of dispatches that require reserved ports. + */ +void +ns_add_reserved_dispatch(ns_server_t *server, isc_sockaddr_t *addr); + #endif /* NAMED_SERVER_H */ diff --git a/bin/named/include/named/types.h b/bin/named/include/named/types.h index 6b8158beb7..0b69feeacd 100644 --- a/bin/named/include/named/types.h +++ b/bin/named/include/named/types.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: types.h,v 1.19 2001/05/08 03:42:34 gson Exp $ */ +/* $Id: types.h,v 1.20 2004/01/05 06:56:44 marka Exp $ */ #ifndef NAMED_TYPES_H #define NAMED_TYPES_H 1 @@ -35,5 +35,7 @@ typedef struct ns_lwdclientmgr ns_lwdclientmgr_t; typedef struct ns_lwsearchlist ns_lwsearchlist_t; typedef struct ns_lwsearchctx ns_lwsearchctx_t; typedef struct ns_controls ns_controls_t; +typedef struct ns_dispatch ns_dispatch_t; +typedef ISC_LIST(ns_dispatch_t) ns_dispatchlist_t; #endif /* NAMED_TYPES_H */ diff --git a/bin/named/server.c b/bin/named/server.c index 184cfa28ea..b7df8666cb 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.406 2003/10/26 21:33:44 marka Exp $ */ +/* $Id: server.c,v 1.407 2004/01/05 06:56:44 marka Exp $ */ #include @@ -120,6 +120,13 @@ fatal(msg, result); \ } while (0) \ +struct ns_dispatch { + isc_sockaddr_t addr; + unsigned int dispatchgen; + dns_dispatch_t *dispatch; + ISC_LINK(struct ns_dispatch) link; +}; + static void fatal(const char *msg, isc_result_t result); @@ -148,6 +155,9 @@ configure_zone(cfg_obj_t *config, cfg_obj_t *zconfig, cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view, ns_aclconfctx_t *aclconf); +static void +end_reserved_dispatches(ns_server_t *server, isc_boolean_t all); + /* * Configure a single view ACL at '*aclp'. Get its configuration by * calling 'getvcacl' (for per-view configuration) and maybe 'getscacl' @@ -2619,6 +2629,7 @@ shutdown_server(isc_task_t *task, isc_event_t *event) { flush ? ": flushing changes" : ""); ns_controls_shutdown(server->controls); + end_reserved_dispatches(server, ISC_TRUE); cfg_obj_destroy(ns_g_parser, &ns_g_config); cfg_parser_destroy(&ns_g_parser); @@ -2760,6 +2771,8 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { server->controls = NULL; CHECKFATAL(ns_controls_create(server, &server->controls), "ns_controls_create"); + server->dispatchgen = 0; + ISC_LIST_INIT(server->dispatches); server->magic = NS_SERVER_MAGIC; *serverp = server; @@ -2819,14 +2832,117 @@ fatal(const char *msg, isc_result_t result) { exit(1); } +static void +start_reserved_dispatches(ns_server_t *server) { + + REQUIRE(NS_SERVER_VALID(server)); + + server->dispatchgen++; +} + +static void +end_reserved_dispatches(ns_server_t *server, isc_boolean_t all) { + ns_dispatch_t *dispatch; + + REQUIRE(NS_SERVER_VALID(server)); + + for (dispatch = ISC_LIST_HEAD(server->dispatches); + dispatch != NULL; + dispatch = ISC_LIST_NEXT(dispatch, link)) { + if (!all && server->dispatchgen == dispatch-> dispatchgen) + continue; + dns_dispatch_detach(&dispatch->dispatch); + isc_mem_put(server->mctx, dispatch, sizeof(*dispatch)); + } +} + +void +ns_add_reserved_dispatch(ns_server_t *server, isc_sockaddr_t *addr) { + ns_dispatch_t *dispatch; + in_port_t port; + char addrbuf[ISC_SOCKADDR_FORMATSIZE]; + isc_result_t result; + unsigned int attrs, attrmask; + + REQUIRE(NS_SERVER_VALID(server)); + + port = isc_sockaddr_getport(addr); + if (port == 0 || port >= 1024) + return; + + for (dispatch = ISC_LIST_HEAD(server->dispatches); + dispatch != NULL; + dispatch = ISC_LIST_NEXT(dispatch, link)) { + if (isc_sockaddr_equal(&dispatch->addr, addr)) + break; + } + if (dispatch != NULL) { + dispatch->dispatchgen = server->dispatchgen; + return; + } + + dispatch = isc_mem_get(server->mctx, sizeof(*dispatch)); + if (dispatch == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + + dispatch->addr = *addr; + dispatch->dispatchgen = server->dispatchgen; + dispatch->dispatch = NULL; + + attrs = 0; + attrs |= DNS_DISPATCHATTR_UDP; + switch (isc_sockaddr_pf(addr)) { + case AF_INET: + attrs |= DNS_DISPATCHATTR_IPV4; + break; + case AF_INET6: + attrs |= DNS_DISPATCHATTR_IPV6; + break; + default: + result = ISC_R_NOTIMPLEMENTED; + goto cleanup; + } + attrmask = 0; + attrmask |= DNS_DISPATCHATTR_UDP; + attrmask |= DNS_DISPATCHATTR_TCP; + attrmask |= DNS_DISPATCHATTR_IPV4; + attrmask |= DNS_DISPATCHATTR_IPV6; + + result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr, + ns_g_taskmgr, &dispatch->addr, 4096, + 1000, 32768, 16411, 16433, + attrs, attrmask, &dispatch->dispatch); + if (result != ISC_R_SUCCESS) + goto cleanup; + + ISC_LIST_INITANDPREPEND(server->dispatches, dispatch, link); + + return; + + cleanup: + if (dispatch != NULL) + isc_mem_put(server->mctx, dispatch, sizeof(*dispatch)); + isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf)); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_WARNING, + "unable to create dispatch for reserved port %s: %s", + addrbuf, isc_result_totext(result)); +} + + static isc_result_t loadconfig(ns_server_t *server) { isc_result_t result; + start_reserved_dispatches(server); result = load_configuration(ns_g_lwresdonly ? lwresd_g_conffile : ns_g_conffile, server, ISC_FALSE); - if (result != ISC_R_SUCCESS) + if (result == ISC_R_SUCCESS) + end_reserved_dispatches(server, ISC_FALSE); + else isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "reloading configuration failed: %s", diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index 9b7985fdfa..34722f6ab2 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zoneconf.c,v 1.107 2003/08/08 22:46:37 jinmei Exp $ */ +/* $Id: zoneconf.c,v 1.108 2004/01/05 06:56:44 marka Exp $ */ #include @@ -38,6 +38,7 @@ #include #include #include +#include #include /* @@ -461,11 +462,13 @@ ns_zone_configure(cfg_obj_t *config, cfg_obj_t *vconfig, cfg_obj_t *zconfig, result = ns_config_get(maps, "notify-source", &obj); INSIST(result == ISC_R_SUCCESS); RETERR(dns_zone_setnotifysrc4(zone, cfg_obj_assockaddr(obj))); + ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); obj = NULL; result = ns_config_get(maps, "notify-source-v6", &obj); INSIST(result == ISC_R_SUCCESS); RETERR(dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj))); + ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); RETERR(configure_zone_acl(zconfig, vconfig, config, "allow-transfer", ac, zone, @@ -625,11 +628,13 @@ ns_zone_configure(cfg_obj_t *config, cfg_obj_t *vconfig, cfg_obj_t *zconfig, result = ns_config_get(maps, "transfer-source", &obj); INSIST(result == ISC_R_SUCCESS); RETERR(dns_zone_setxfrsource4(zone, cfg_obj_assockaddr(obj))); + ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); obj = NULL; result = ns_config_get(maps, "transfer-source-v6", &obj); INSIST(result == ISC_R_SUCCESS); RETERR(dns_zone_setxfrsource6(zone, cfg_obj_assockaddr(obj))); + ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); obj = NULL; result = ns_config_get(maps, "alt-transfer-source", &obj);