]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
1758. [func] Don't send notify messages to self. [RT #12933]
authorMark Andrews <marka@isc.org>
Thu, 10 Feb 2005 05:53:43 +0000 (05:53 +0000)
committerMark Andrews <marka@isc.org>
Thu, 10 Feb 2005 05:53:43 +0000 (05:53 +0000)
CHANGES
bin/named/client.c
bin/named/include/named/client.h
bin/named/include/named/interfacemgr.h
bin/named/interfacemgr.c
bin/named/zoneconf.c
lib/dns/include/dns/types.h
lib/dns/include/dns/zone.h
lib/dns/win32/libdns.def
lib/dns/zone.c

diff --git a/CHANGES b/CHANGES
index f234543682f2ef6f7d929d1490627256dc674209..0b31ccc29b0c1970596ff32b604a0e362dc9a1ef 100644 (file)
--- a/CHANGES
+++ b/CHANGES
 1759.  [bug]           Named failed to startup if the OS supported IPv6
                        but had no IPv6 interfaces configured. [RT #12942]
 
-1758.  [placeholder]   rt12933
+1758.  [func]          Don't send notify messages to self. [RT #12933]
 
 1757.  [func]          host now can turn on memory debugging flags with '-m'.
 
index b7533fe12d597577bdd23f254e8a220ae3b33af6..689306a85007e87fb0ac14fbfd83cdee1b7660b6 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: client.c,v 1.222 2004/09/26 22:34:32 marka Exp $ */
+/* $Id: client.c,v 1.223 2005/02/10 05:53:41 marka Exp $ */
 
 #include <config.h>
 
@@ -1110,6 +1110,64 @@ allowed(isc_netaddr_t *addr, dns_name_t *signer, dns_acl_t *acl) {
        return (ISC_FALSE);
 }
 
+/*
+ * Callback to see if a non-recursive query coming from 'srcaddr' to
+ * 'destaddr', with optional key 'mykey' for class 'rdclass' would be
+ * delivered to 'myview'.
+ *
+ * We run this unlocked as both the view list and the interface list
+ * are updated when the approprite task has exclusivity.
+ */
+isc_boolean_t
+ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey,
+                isc_sockaddr_t *srcaddr, isc_sockaddr_t *dstaddr,
+                dns_rdataclass_t rdclass, void *arg)
+{
+       dns_view_t *view;
+       dns_tsigkey_t *key;
+       isc_netaddr_t netsrc;
+       isc_netaddr_t netdst;
+
+       UNUSED(arg);
+
+       if (!ns_interfacemgr_listeningon(ns_g_server->interfacemgr, dstaddr))
+               return (ISC_FALSE);
+
+       isc_netaddr_fromsockaddr(&netsrc, srcaddr);
+       isc_netaddr_fromsockaddr(&netdst, dstaddr);
+
+       for (view = ISC_LIST_HEAD(ns_g_server->viewlist);
+            view != NULL;
+            view = ISC_LIST_NEXT(view, link)) {
+               dns_name_t *tsig = NULL;
+
+               if (view->matchrecursiveonly)
+                       continue;
+
+               if (rdclass != view->rdclass)
+                       continue;
+
+               if (mykey != NULL) {
+                       isc_boolean_t match;
+                       isc_result_t result;
+
+                       tsig = &mykey->name;
+                       result = dns_view_gettsig(view, tsig, &key);
+                       if (result != ISC_R_SUCCESS)
+                               continue;
+                       match = dst_key_compare(mykey->key, key->key);
+                       dns_tsigkey_detach(&key);
+                       if (!match)
+                               continue;
+               }
+
+               if (allowed(&netsrc, tsig, view->matchclients) &&
+                   allowed(&netdst, tsig, view->matchdestinations))
+                       break;
+       }
+       return (ISC_TF(view == myview));
+}
+
 /*
  * Handle an incoming request event from the socket (UDP case)
  * or tcpmsg (TCP case).
index dbbc77ce274d267281007f87ea92dcdd054d8f56..9dc9d7d52a89d43e8ab766a5b36b9f8b498b2d7e 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: client.h,v 1.70 2004/07/23 02:57:27 marka Exp $ */
+/* $Id: client.h,v 1.71 2005/02/10 05:53:42 marka Exp $ */
 
 #ifndef NAMED_CLIENT_H
 #define NAMED_CLIENT_H 1
@@ -334,4 +334,12 @@ ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager);
  * Dump the outstanding recursive queries to 'f'.
  */
 
+isc_boolean_t
+ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey,
+                 isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
+                 dns_rdataclass_t rdclass, void *arg);
+/*
+ * Isself callback.
+ */
+
 #endif /* NAMED_CLIENT_H */
index 9c4d422ef7ced4be6d7848ee581a40d97ec243c0..2e98aab3dc8e12bbe32a2018049209062f5a9086 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: interfacemgr.h,v 1.27 2004/04/29 01:37:13 marka Exp $ */
+/* $Id: interfacemgr.h,v 1.28 2005/02/10 05:53:42 marka Exp $ */
 
 #ifndef NAMED_INTERFACEMGR_H
 #define NAMED_INTERFACEMGR_H 1
@@ -170,4 +170,7 @@ ns_interface_shutdown(ns_interface_t *ifp);
 void
 ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr);
 
+isc_boolean_t
+ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr);
+
 #endif /* NAMED_INTERFACEMGR_H */
index 3b58baa171f38373d5a3a1edc36f2d6f1824d47b..3cd8739e7d852379b660aae79c23b4b0ea3461f7 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: interfacemgr.c,v 1.78 2004/08/10 04:55:39 jinmei Exp $ */
+/* $Id: interfacemgr.c,v 1.79 2005/02/10 05:53:41 marka Exp $ */
 
 #include <config.h>
 
@@ -50,11 +50,15 @@ struct ns_interfacemgr {
        ns_listenlist_t *       listenon6;
        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 +89,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 +122,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));
@@ -536,6 +542,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)
@@ -552,6 +595,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;
@@ -642,6 +686,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);
@@ -687,6 +732,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 +769,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 +960,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);
+}
index e02427219ef24c6b68d5697c33ccbafbce6c60e3..cd026617ead5a8e294e2685d11180d48d6c1264d 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zoneconf.c,v 1.118 2005/01/11 23:10:04 marka Exp $ */
+/* $Id: zoneconf.c,v 1.119 2005/02/10 05:53:42 marka Exp $ */
 
 #include <config.h>
 
@@ -35,6 +35,7 @@
 #include <dns/view.h>
 #include <dns/zone.h>
 
+#include <named/client.h>
 #include <named/config.h>
 #include <named/globals.h>
 #include <named/log.h>
@@ -494,6 +495,8 @@ ns_zone_configure(cfg_obj_t *config, cfg_obj_t *vconfig, cfg_obj_t *zconfig,
                RETERR(dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj)));
                ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
 
+               dns_zone_setisself(zone, ns_client_isself, NULL);
+
                RETERR(configure_zone_acl(zconfig, vconfig, config,
                                          "allow-transfer", ac, zone,
                                          dns_zone_setxfracl,
index 625380b41722bb932abfba6673049d3b76360ac6..d64d18225313ee5b5d9179fbbfee2d8f93f17361 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: types.h,v 1.111 2004/12/21 10:45:19 jinmei Exp $ */
+/* $Id: types.h,v 1.112 2005/02/10 05:53:43 marka Exp $ */
 
 #ifndef DNS_TYPES_H
 #define DNS_TYPES_H 1
@@ -299,4 +299,8 @@ typedef void
 typedef int 
 (*dns_rdatasetorderfunc_t)(dns_rdata_t *rdata, void *arg);
 
+typedef isc_boolean_t
+(*dns_isselffunc_t)(dns_view_t *, dns_tsigkey_t *, isc_sockaddr_t *,
+                   isc_sockaddr_t *, dns_rdataclass_t, void *);
+
 #endif /* DNS_TYPES_H */
index 78a3e2858754b3a37a3bc49f1a3473a781cb00df..3df380b58892c327d27ae5f0ea9a57740a4415b2 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.h,v 1.131 2005/01/11 23:10:05 marka Exp $ */
+/* $Id: zone.h,v 1.132 2005/02/10 05:53:43 marka Exp $ */
 
 #ifndef DNS_ZONE_H
 #define DNS_ZONE_H 1
@@ -1464,6 +1464,20 @@ dns_zone_getnotifydelay(dns_zone_t *zone);
  *     'zone' to be valid.
  */
 
+void
+dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg);
+/*
+ * Set the isself callback function and arguement.
+ *
+ * isc_boolean_t
+ * isself(dns_view_t *myview, dns_tsigkey_t *mykey, isc_netaddr_t *srcaddr,
+ *       isc_netaddr_t *destaddr, dns_rdataclass_t rdclass, void *arg);
+ *
+ * 'isself' returns ISC_TRUE if a non-recursive query from 'srcaddr' to
+ * 'destaddr' with optional key 'mykey' for class 'rdclass' would be
+ * delivered to 'myview'.
+ */
+
 ISC_LANG_ENDDECLS
 
 #endif /* DNS_ZONE_H */
index e8f5fa3a07e36cefa0ab3d97a4efdb280927657e..f4be1fd88f4df20d96ffd415125b32170ac5769b 100644 (file)
@@ -659,6 +659,7 @@ dns_zone_setflag
 dns_zone_setforwardacl
 dns_zone_setidlein
 dns_zone_setidleout
+dns_zone_setisself
 dns_zone_setjournal
 dns_zone_setjournalsize
 dns_zone_setkeydirectory
index 7d3a664eba7ae0f96c5cb8e80d189d54ef611106..9dcea3dae181fccda882f095530ff393cb16129c 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.c,v 1.430 2005/02/03 05:07:35 marka Exp $ */
+/* $Id: zone.c,v 1.431 2005/02/10 05:53:42 marka Exp $ */
 
 #include <config.h>
 
@@ -223,6 +223,8 @@ struct dns_zone {
         */
        isc_uint64_t            *counters;
        isc_uint32_t            notifydelay;
+       dns_isselffunc_t        isself;
+       void                    *isselfarg;
 };
 
 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
@@ -586,6 +588,8 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
        zone->statelist = NULL;
        zone->counters = NULL;
        zone->notifydelay = 5;
+       zone->isself = NULL;
+       zone->isselfarg = NULL;
 
        zone->magic = ZONE_MAGIC;
 
@@ -2741,6 +2745,46 @@ notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
        return (ISC_FALSE);
 }
 
+static isc_boolean_t
+notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
+       dns_tsigkey_t *key = NULL;
+       isc_sockaddr_t src;
+       isc_sockaddr_t any;
+       isc_boolean_t isself;
+       isc_netaddr_t dstaddr;
+
+       if (zone->view == NULL || zone->isself == NULL)
+               return (ISC_FALSE);
+
+       switch (isc_sockaddr_pf(dst)) {
+       case PF_INET:
+               src = zone->notifysrc4;
+               isc_sockaddr_any(&any);
+               break;
+       case PF_INET6:
+               src = zone->notifysrc6;
+               isc_sockaddr_any6(&any);
+               break;
+       default:
+               return (ISC_FALSE);
+       }
+
+       /*
+        * When sending from any the kernel will assign a source address
+        * that matches the destination address.
+        */
+       if (isc_sockaddr_eqaddr(&any, &src))
+               src = *dst;
+
+       isc_netaddr_fromsockaddr(&dstaddr, dst);
+       (void)dns_view_getpeertsig(zone->view, &dstaddr, &key);
+       isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
+                               zone->isselfarg);
+       if (key != NULL)
+               dns_tsigkey_detach(&key);
+       return (isself);
+}
+
 static void
 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
        isc_mem_t *mctx;
@@ -2988,6 +3032,8 @@ notify_send(dns_notify_t *notify) {
                dst = ai->sockaddr;
                if (notify_isqueued(notify->zone, NULL, &dst))
                        continue;
+               if (notify_isself(notify->zone, &dst))
+                       continue;
                new = NULL;
                result = notify_create(notify->mctx,
                                       (notify->flags & DNS_NOTIFY_NOSOA),
@@ -7013,6 +7059,16 @@ dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
        return (ISC_R_SUCCESS);
 }
 
+void
+dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
+       REQUIRE(DNS_ZONE_VALID(zone));
+
+       LOCK_ZONE(zone);
+       zone->isself = isself;
+       zone->isselfarg = arg;
+       UNLOCK_ZONE(zone);
+}
+
 void
 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
        REQUIRE(DNS_ZONE_VALID(zone));