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'.
* 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>
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).
* 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
* 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 */
* 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
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 */
* 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>
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,
mgr->listenon6 = NULL;
ISC_LIST_INIT(mgr->interfaces);
+ ISC_LIST_INIT(mgr->listenon);
/*
* The listen-on lists are initially empty.
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));
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)
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;
result = clearacl(mgr->mctx, &mgr->aclenv.localnets);
if (result != ISC_R_SUCCESS)
goto cleanup_iter;
+ clearlistenon(mgr);
}
for (result = isc_interfaceiter_first(iter);
}
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))
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.
}
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);
+}
* 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>
#include <dns/view.h>
#include <dns/zone.h>
+#include <named/client.h>
#include <named/config.h>
#include <named/globals.h>
#include <named/log.h>
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,
* 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
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 */
* 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
* '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 */
dns_zone_setforwardacl
dns_zone_setidlein
dns_zone_setidleout
+dns_zone_setisself
dns_zone_setjournal
dns_zone_setjournalsize
dns_zone_setkeydirectory
* 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>
*/
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))
zone->statelist = NULL;
zone->counters = NULL;
zone->notifydelay = 5;
+ zone->isself = NULL;
+ zone->isselfarg = NULL;
zone->magic = ZONE_MAGIC;
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;
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),
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));