1758. [func] Don't send notify messages to self. [RT #12933]

This commit is contained in:
Mark Andrews 2005-02-10 05:53:43 +00:00
parent 1ae9abe209
commit 3aca8e5bf3
10 changed files with 220 additions and 9 deletions

View file

@ -145,7 +145,7 @@
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'.

View 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).

View 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 */

View 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 */

View 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);
}

View 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,

View 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 */

View 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 */

View 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

View 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));