]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
1539. [bug] Open UDP sockets for notify-source and transfer-source
authorMark Andrews <marka@isc.org>
Mon, 5 Jan 2004 06:56:44 +0000 (06:56 +0000)
committerMark Andrews <marka@isc.org>
Mon, 5 Jan 2004 06:56:44 +0000 (06:56 +0000)
                        that use reserved ports at startup. [RT #9475]

CHANGES
bin/named/include/named/server.h
bin/named/include/named/types.h
bin/named/server.c
bin/named/zoneconf.c

diff --git a/CHANGES b/CHANGES
index 324f5f8493998e62a66700f71cc9b7484ecb9ffe..10ab09935609a971dcbdb196ad0ede564ebcee35 100644 (file)
--- 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
 
index 6c9fa7b1181fd91cb4147e78ee8a71ca8561ae8d..2a8a12cd80f911915b764d436d5463231a9a9960 100644 (file)
@@ -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 */
index 6b8158beb7e7322bbd6fde0e97001a4a5ded6861..0b69feeacd41162952954457b0932639c14fc1c7 100644 (file)
@@ -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 */
index 184cfa28ea4c87d59e175f83dbf60fbefda68256..b7df8666cbef1cbddd0d1aa0115aa97a9ef2f086 100644 (file)
@@ -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 <config.h>
 
                        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",
index 9b7985fdfade5a3fafa987f6cd8c7b6459e237ae..34722f6ab270a9f3983627bfe55171adfe2a0c1e 100644 (file)
@@ -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 <config.h>
 
@@ -38,6 +38,7 @@
 #include <named/config.h>
 #include <named/globals.h>
 #include <named/log.h>
+#include <named/server.h>
 #include <named/zoneconf.h>
 
 /*
@@ -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);