diff --git a/CHANGES b/CHANGES index a158ff6495..73b49c57df 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,6 @@ + 405. [func] Add support for selective forwarding (forward zones) + 404. [bug] The request library didn't completely work with IPv6. 403. [bug] "host" did not use the search list. diff --git a/bin/named/lwresd.c b/bin/named/lwresd.c index 6b73feb3d4..f2d87f7437 100644 --- a/bin/named/lwresd.c +++ b/bin/named/lwresd.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: lwresd.c,v 1.13 2000/08/01 01:11:50 tale Exp $ */ +/* $Id: lwresd.c,v 1.14 2000/08/24 22:15:26 bwelling Exp $ */ /* * Main program for the Lightweight Resolver Daemon. @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -268,14 +269,16 @@ ns_lwresd_createview(ns_lwresd_t *lwresd, dns_view_t **viewp) { if (ISC_LIST_HEAD(forwarders) != NULL) { isc_sockaddr_t *sa; - dns_resolver_setforwarders(view->resolver, &forwarders); - dns_resolver_setfwdpolicy(view->resolver, dns_fwdpolicy_only); + result = dns_fwdtable_add(view->fwdtable, dns_rootname, + &forwarders, dns_fwdpolicy_only); sa = ISC_LIST_HEAD(forwarders); while (sa != NULL) { ISC_LIST_UNLINK(forwarders, sa, link); isc_mem_put(lwresd->mctx, sa, sizeof (*sa)); sa = ISC_LIST_HEAD(forwarders); } + if (result != ISC_R_SUCCESS) + goto out; } dns_view_freeze(view); diff --git a/bin/named/server.c b/bin/named/server.c index e2d04f03b7..ca31f3d01d 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.215 2000/08/24 19:02:06 gson Exp $ */ +/* $Id: server.c,v 1.216 2000/08/24 22:15:28 bwelling Exp $ */ #include @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -107,6 +108,11 @@ ns_listenlist_fromconfig(dns_c_lstnlist_t *clist, dns_c_ctx_t *cctx, dns_aclconfctx_t *actx, isc_mem_t *mctx, ns_listenlist_t **target); +static isc_result_t +configure_forward(dns_c_ctx_t *cctx, dns_c_zone_t *czone, dns_c_view_t *cview, + dns_view_t *view, dns_name_t *origin, + dns_c_iplist_t *forwarders); + /* * Configure a single view ACL at '*aclp'. Get its configuration by * calling 'getvcacl' (for per-view configuration) and maybe 'getscacl' @@ -401,13 +407,8 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, dns_c_view_t *cview, isc_result_t result; isc_uint32_t cleaning_interval; dns_tsig_keyring_t *ring; - dns_c_forw_t forward; dns_c_iplist_t *forwarders; - dns_fwdpolicy_t fwdpolicy; - isc_sockaddrlist_t addresses; - isc_sockaddr_t *sa, *next_sa; dns_view_t *pview = NULL; /* Production view */ - unsigned int i; isc_mem_t *cmctx; dns_dispatch_t *dispatch4 = NULL; dns_dispatch_t *dispatch6 = NULL; @@ -415,7 +416,6 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, dns_c_view_t *cview, REQUIRE(DNS_VIEW_VALID(view)); - ISC_LIST_INIT(addresses); cmctx = NULL; RWLOCK(&view->conflock, isc_rwlocktype_write); @@ -508,37 +508,9 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, dns_c_view_t *cview, dns_c_view_getforwarders(cview, &forwarders) == ISC_R_SUCCESS) || (dns_c_ctx_getforwarders(cctx, &forwarders) == ISC_R_SUCCESS)) { - fwdpolicy = dns_fwdpolicy_first; - /* - * Ugh. Convert between list formats. - */ - for (i = 0; i < forwarders->nextidx; i++) { - sa = isc_mem_get(view->mctx, sizeof *sa); - if (sa == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - *sa = forwarders->ips[i]; - isc_sockaddr_setport(sa, port); - ISC_LINK_INIT(sa, link); - ISC_LIST_APPEND(addresses, sa, link); - } - INSIST(!ISC_LIST_EMPTY(addresses)); + result = configure_forward(cctx, NULL, cview, view, + dns_rootname, forwarders); dns_c_iplist_detach(&forwarders); - CHECK(dns_resolver_setforwarders(view->resolver, &addresses)); - /* - * XXXRTH The configuration type 'dns_c_forw_t' should be - * eliminated. - */ - if ((cview != NULL && - dns_c_view_getforward(cview, &forward) == ISC_R_SUCCESS) - || dns_c_ctx_getforward(cctx, &forward) == ISC_R_SUCCESS) { - INSIST(forward == dns_c_forw_first || - forward == dns_c_forw_only); - if (forward == dns_c_forw_only) - fwdpolicy = dns_fwdpolicy_only; - } - CHECK(dns_resolver_setfwdpolicy(view->resolver, fwdpolicy)); } /* @@ -704,13 +676,6 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, dns_c_view_t *cview, cleanup: RWUNLOCK(&view->conflock, isc_rwlocktype_write); - for (sa = ISC_LIST_HEAD(addresses); - sa != NULL; - sa = next_sa) { - next_sa = ISC_LIST_NEXT(sa, link); - isc_mem_put(view->mctx, sa, sizeof *sa); - } - if (cmctx != NULL) isc_mem_detach(&cmctx); @@ -931,6 +896,74 @@ configure_hints(dns_view_t *view, const char *filename) { return (result); } +static isc_result_t +configure_forward(dns_c_ctx_t *cctx, dns_c_zone_t *czone, dns_c_view_t *cview, + dns_view_t *view, dns_name_t *origin, + dns_c_iplist_t *forwarders) +{ + dns_c_forw_t forward; + dns_fwdpolicy_t fwdpolicy; + isc_sockaddrlist_t addresses; + isc_sockaddr_t *sa; + isc_result_t result; + in_port_t port; + unsigned int i; + + result = dns_c_ctx_getport(cctx, &port); + if (result != ISC_R_SUCCESS) + port = 53; + + ISC_LIST_INIT(addresses); + + if (forwarders != NULL) { + for (i = 0; i < forwarders->nextidx; i++) { + sa = isc_mem_get(view->mctx, sizeof(isc_sockaddr_t)); + if (sa == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + *sa = forwarders->ips[i]; + isc_sockaddr_setport(sa, port); + ISC_LINK_INIT(sa, link); + ISC_LIST_APPEND(addresses, sa, link); + } + } + + if (ISC_LIST_EMPTY(addresses)) + fwdpolicy = dns_fwdpolicy_none; + else + fwdpolicy = dns_fwdpolicy_first; + + if ((czone != NULL && + dns_c_zone_getforward(czone, &forward) == ISC_R_SUCCESS) || + (cview != NULL && + dns_c_view_getforward(cview, &forward) == ISC_R_SUCCESS) || + dns_c_ctx_getforward(cctx, &forward) == ISC_R_SUCCESS) + { + INSIST(forward == dns_c_forw_first || + forward == dns_c_forw_only); + if (forward == dns_c_forw_only) + fwdpolicy = dns_fwdpolicy_only; + } + + result = dns_fwdtable_add(view->fwdtable, origin, &addresses, + fwdpolicy); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = ISC_R_SUCCESS; + + cleanup: + + while (!ISC_LIST_EMPTY(addresses)) { + sa = ISC_LIST_HEAD(addresses); + ISC_LIST_UNLINK(addresses, sa, link); + isc_mem_put(view->mctx, sa, sizeof(isc_sockaddr_t)); + } + + return (result); +} + /* * Find an existing view matching the name and class of 'cview' * in 'viewlist', or create a new one and add it to the list. @@ -1064,16 +1097,12 @@ configure_zone(dns_c_ctx_t *cctx, dns_c_zone_t *czone, dns_c_view_t *cview, } /* - * "forward zones" aren't zones either. Eventually we'll - * translate this syntax into the appropriate selective forwarding - * configuration. + * "forward zones" aren't zones either. Translate this syntax into + * the appropriate selective forwarding configuration and return. */ if (czone->ztype == dns_c_zone_forward) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "forward zone '%s': forward zones are not supported in this release", - corigin); - result = ISC_R_SUCCESS; + result = configure_forward(cctx, czone, cview, view, origin, + czone->u.fzone.forwarders); goto cleanup; } diff --git a/lib/dns/Makefile.in b/lib/dns/Makefile.in index ff3ec9c648..a6e3b58803 100644 --- a/lib/dns/Makefile.in +++ b/lib/dns/Makefile.in @@ -13,7 +13,7 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# $Id: Makefile.in,v 1.98 2000/08/22 00:54:57 bwelling Exp $ +# $Id: Makefile.in,v 1.99 2000/08/24 22:15:29 bwelling Exp $ srcdir = @srcdir@ VPATH = @srcdir@ @@ -119,7 +119,7 @@ DNSSAFEOBJS = sec/dnssafe/ahchdig.@O@ sec/dnssafe/ahchencr.@O@ \ OBJS = a6.@O@ acl.@O@ aclconf.@O@ adb.@O@ byaddr.@O@ \ cache.@O@ callbacks.@O@ compress.@O@ \ db.@O@ dbiterator.@O@ dbtable.@O@ dispatch.@O@ dnssec.@O@ \ - journal.@O@ keytable.@O@ lib.@O@ log.@O@ \ + forward.@O@ journal.@O@ keytable.@O@ lib.@O@ log.@O@ \ master.@O@ masterdump.@O@ message.@O@ \ name.@O@ ncache.@O@ nxt.@O@ peer.@O@ \ rbt.@O@ rbtdb.@O@ rbtdb64.@O@ rdata.@O@ rdatalist.@O@ \ @@ -134,7 +134,7 @@ OBJS = a6.@O@ acl.@O@ aclconf.@O@ adb.@O@ byaddr.@O@ \ SRCS = a6.c acl.c aclconf.c adb.c byaddr.c \ cache.c callbacks.c compress.c \ db.c dbiterator.c dbtable.c dispatch.c dnssec.c \ - journal.c keytable.c lib.c log.c \ + forward.c journal.c keytable.c lib.c log.c \ master.c masterdump.c message.c \ name.c ncache.c nxt.c peer.c \ rbt.c rbtdb.c rbtdb64.c rdata.c rdatalist.c \ diff --git a/lib/dns/forward.c b/lib/dns/forward.c new file mode 100644 index 0000000000..3484cde8f2 --- /dev/null +++ b/lib/dns/forward.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2000 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: forward.c,v 1.1 2000/08/24 22:15:30 bwelling Exp $ */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +struct dns_fwdtable { + /* Unlocked. */ + unsigned int magic; + isc_mem_t *mctx; + isc_rwlock_t rwlock; + /* Locked by lock. */ + dns_rbt_t *table; +}; + +#define FWDTABLEMAGIC 0x46776454U /* FwdT */ +#define VALID_FWDTABLE(ft) ISC_MAGIC_VALID(ft, FWDTABLEMAGIC) + +static void +auto_detach(void *, void *); + +isc_result_t +dns_fwdtable_create(isc_mem_t *mctx, dns_fwdtable_t **fwdtablep) { + dns_fwdtable_t *fwdtable; + isc_result_t result; + + REQUIRE(fwdtablep != NULL && *fwdtablep == NULL); + + fwdtable = isc_mem_get(mctx, sizeof(dns_fwdtable_t)); + if (fwdtable == NULL) + return (ISC_R_NOMEMORY); + + fwdtable->table = NULL; + result = dns_rbt_create(mctx, auto_detach, fwdtable, &fwdtable->table); + if (result != ISC_R_SUCCESS) + goto cleanup_fwdtable; + + result = isc_rwlock_init(&fwdtable->rwlock, 0, 0); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_rwlock_init() failed: %s", + isc_result_totext(result)); + result = ISC_R_UNEXPECTED; + goto cleanup_rbt; + } + + fwdtable->mctx = NULL; + isc_mem_attach(mctx, &fwdtable->mctx); + fwdtable->magic = FWDTABLEMAGIC; + *fwdtablep = fwdtable; + + return (ISC_R_SUCCESS); + + cleanup_rbt: + dns_rbt_destroy(&fwdtable->table); + + cleanup_fwdtable: + isc_mem_put(mctx, fwdtable, sizeof(dns_fwdtable_t)); + + return (result); +} + +isc_result_t +dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name, + isc_sockaddrlist_t *addrs, dns_fwdpolicy_t fwdpolicy) +{ + isc_result_t result; + dns_forwarders_t *forwarders; + isc_sockaddr_t *sa, *nsa; + + REQUIRE(VALID_FWDTABLE(fwdtable)); + + forwarders = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarders_t)); + if (forwarders == NULL) + return (ISC_R_NOMEMORY); + + ISC_LIST_INIT(forwarders->addrs); + for (sa = ISC_LIST_HEAD(*addrs); + sa != NULL; + sa = ISC_LIST_NEXT(sa, link)) + { + nsa = isc_mem_get(fwdtable->mctx, sizeof(isc_sockaddr_t)); + if (nsa == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + *nsa = *sa; + ISC_LINK_INIT(nsa, link); + ISC_LIST_APPEND(forwarders->addrs, nsa, link); + } + forwarders->fwdpolicy = fwdpolicy; + + RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write); + result = dns_rbt_addname(fwdtable->table, name, forwarders); + RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write); + + if (result != ISC_R_SUCCESS) + goto cleanup; + + return (ISC_R_SUCCESS); + + cleanup: + while (!ISC_LIST_EMPTY(forwarders->addrs)) { + sa = ISC_LIST_HEAD(forwarders->addrs); + ISC_LIST_UNLINK(forwarders->addrs, sa, link); + isc_mem_put(fwdtable->mctx, sa, sizeof(isc_sockaddr_t)); + } + isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t)); + return (result); +} + +isc_result_t +dns_fwdtable_find(dns_fwdtable_t *fwdtable, dns_name_t *name, + dns_forwarders_t **forwardersp) +{ + isc_result_t result; + + REQUIRE(VALID_FWDTABLE(fwdtable)); + + RWLOCK(&fwdtable->rwlock, isc_rwlocktype_read); + + result = dns_rbt_findname(fwdtable->table, name, 0, NULL, + (void **)forwardersp); + if (result == DNS_R_PARTIALMATCH) + result = ISC_R_SUCCESS; + + RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_read); + + return (result); +} + +void +dns_fwdtable_destroy(dns_fwdtable_t **fwdtablep) { + dns_fwdtable_t *fwdtable; + isc_mem_t *mctx = mctx; + + REQUIRE(fwdtablep != NULL && VALID_FWDTABLE(*fwdtablep)); + + fwdtable = *fwdtablep; + + dns_rbt_destroy(&fwdtable->table); + isc_rwlock_destroy(&fwdtable->rwlock); + fwdtable->magic = 0; + mctx = fwdtable->mctx; + isc_mem_put(mctx, fwdtable, sizeof(dns_fwdtable_t)); + isc_mem_detach(&mctx); + + *fwdtablep = NULL; +} + +/*** + *** Private + ***/ + +static void +auto_detach(void *data, void *arg) { + dns_forwarders_t *forwarders = data; + dns_fwdtable_t *fwdtable = arg; + isc_sockaddr_t *sa; + + UNUSED(arg); + + while (!ISC_LIST_EMPTY(forwarders->addrs)) { + sa = ISC_LIST_HEAD(forwarders->addrs); + ISC_LIST_UNLINK(forwarders->addrs, sa, link); + isc_mem_put(fwdtable->mctx, sa, sizeof(isc_sockaddr_t)); + } + isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t)); +} diff --git a/lib/dns/include/dns/forward.h b/lib/dns/include/dns/forward.h new file mode 100644 index 0000000000..3f2d597817 --- /dev/null +++ b/lib/dns/include/dns/forward.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2000 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: forward.h,v 1.1 2000/08/24 22:15:36 bwelling Exp $ */ + +#ifndef DNS_FORWARD_H +#define DNS_FORWARD_H 1 + +#include +#include + +#include + +ISC_LANG_BEGINDECLS + +struct dns_forwarders { + isc_sockaddrlist_t addrs; + dns_fwdpolicy_t fwdpolicy; +}; + +isc_result_t +dns_fwdtable_create(isc_mem_t *mctx, dns_fwdtable_t **fwdtablep); +/* + * Creates a new forwarding table. + * + * Requires: + * mctx is a valid memory context. + * fwdtablep != NULL && *fwdtablep == NULL + * + * Returns: + * ISC_R_SUCCESS + * ISC_R_NOMEMORY + */ + +isc_result_t +dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name, + isc_sockaddrlist_t *addrs, dns_fwdpolicy_t policy); +/* + * Adds an entry to the forwarding table. The entry associates + * a domain with a list of forwarders and a forwarding policy. The + * addrs list is copied if not empty, so the caller should free its copy. + * + * Requires: + * fwdtable is a valid forwarding table. + * name is a valid name + * addrs is a valid list of sockaddrs, which may be empty. + * + * Returns: + * ISC_R_SUCCESS + * ISC_R_NOMEMORY + */ + +isc_result_t +dns_fwdtable_find(dns_fwdtable_t *fwdtable, dns_name_t *name, + dns_forwarders_t **forwardersp); +/* + * Finds a domain in the forwarding table. The closest matching parent + * domain is returned. + * + * Requires: + * fwdtable is a valid forwarding table. + * name is a valid name + * forwardersp != NULL && *forwardersp == NULL + * + * Returns: + * ISC_R_SUCCESS + * ISC_R_NOTFOUND + */ + +void +dns_fwdtable_destroy(dns_fwdtable_t **fwdtablep); +/* + * Destroys a forwarding table. + * + * Requires: + * fwtablep != NULL && *fwtablep != NULL + * + * Ensures: + * all memory associated with the forwarding table is freed. + */ + +ISC_LANG_ENDDECLS + +#endif /* DNS_FORWARD_H */ diff --git a/lib/dns/include/dns/resolver.h b/lib/dns/include/dns/resolver.h index 6a024b1fe9..223abc2b81 100644 --- a/lib/dns/include/dns/resolver.h +++ b/lib/dns/include/dns/resolver.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.h,v 1.31 2000/08/01 01:24:39 tale Exp $ */ +/* $Id: resolver.h,v 1.32 2000/08/24 22:15:36 bwelling Exp $ */ #ifndef DNS_RESOLVER_H #define DNS_RESOLVER_H 1 @@ -141,40 +141,6 @@ dns_resolver_create(dns_view_t *view, * Anything else Failure. */ -isc_result_t -dns_resolver_setforwarders(dns_resolver_t *res, - isc_sockaddrlist_t *forwarders); -/* - * Set the default forwarders to be used by the resolver. - * - * Requires: - * - * 'res' is a valid, unfrozen resolver. - * - * 'forwarders' is a valid nonempty list. - * - * Returns: - * - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - */ - -isc_result_t -dns_resolver_setfwdpolicy(dns_resolver_t *res, dns_fwdpolicy_t fwdpolicy); -/* - * Set the default forwarding policy to be used by the resolver. - * - * Requires: - * - * 'res' is a valid, unfrozen resolver. - * - * 'fwdpolicy' is a valid dns_fwdpolicy_t. - * - * Returns: - * - * ISC_R_SUCCESS - */ - void dns_resolver_freeze(dns_resolver_t *res); /* @@ -182,9 +148,8 @@ dns_resolver_freeze(dns_resolver_t *res); * * Notes: * - * Certain configuration changes, e.g. setting forwarders, - * cannot be made after the resolver is frozen. Fetches - * cannot be created until the resolver is frozen. + * Certain configuration changes cannot be made after the resolver + * is frozen. Fetches cannot be created until the resolver is frozen. * * Requires: * diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h index 86ce5606cd..8ff5886096 100644 --- a/lib/dns/include/dns/types.h +++ b/lib/dns/include/dns/types.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: types.h,v 1.92 2000/08/15 03:33:52 marka Exp $ */ +/* $Id: types.h,v 1.93 2000/08/24 22:15:37 bwelling Exp $ */ #ifndef DNS_TYPES_H #define DNS_TYPES_H 1 @@ -59,6 +59,7 @@ typedef struct dns_dispentry dns_dispentry_t; typedef struct dns_fetch dns_fetch_t; typedef struct dns_fixedname dns_fixedname_t; typedef struct dns_forwarders dns_forwarders_t; +typedef struct dns_fwdtable dns_fwdtable_t; typedef isc_uint16_t dns_keyflags_t; typedef struct dns_keynode dns_keynode_t; typedef struct dns_keytable dns_keytable_t; diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index 851271de93..d6538049ee 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: view.h,v 1.49 2000/08/17 23:45:12 gson Exp $ */ +/* $Id: view.h,v 1.50 2000/08/24 22:15:38 bwelling Exp $ */ #ifndef DNS_VIEW_H #define DNS_VIEW_H 1 @@ -96,6 +96,7 @@ struct dns_view { dns_tsig_keyring_t * statickeys; dns_tsig_keyring_t * dynamickeys; dns_peerlist_t * peers; + dns_fwdtable_t * fwdtable; isc_boolean_t recursion; isc_boolean_t auth_nxdomain; isc_boolean_t additionalfromcache; diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 8719a12224..66b5812f15 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.165 2000/08/17 00:18:08 gson Exp $ */ +/* $Id: resolver.c,v 1.166 2000/08/24 22:15:33 bwelling Exp $ */ #include @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -169,6 +170,7 @@ struct fetchctx { dns_adbfind_t * find; dns_adbaddrinfolist_t forwaddrs; isc_sockaddrlist_t forwarders; + dns_fwdpolicy_t fwdpolicy; isc_sockaddrlist_t bad; ISC_LIST(dns_validator_t) validators; /* @@ -229,8 +231,6 @@ struct dns_resolver { isc_taskmgr_t * taskmgr; dns_view_t * view; isc_boolean_t frozen; - isc_sockaddrlist_t forwarders; - dns_fwdpolicy_t fwdpolicy; unsigned int options; dns_dispatchmgr_t * dispatchmgr; dns_dispatch_t * dispatchv4; @@ -1333,12 +1333,20 @@ fctx_getaddresses(fetchctx_t *fctx) { INSIST(ISC_LIST_EMPTY(fctx->forwaddrs)); /* - * If this fctx has forwarders, use them; otherwise use the + * If this fctx has forwarders, use them; otherwise use any + * selective forwarders specified in the view; otherwise use the * resolver's forwarders (if any). */ sa = ISC_LIST_HEAD(fctx->forwarders); - if (sa == NULL) - sa = ISC_LIST_HEAD(res->forwarders); + if (sa == NULL) { + dns_forwarders_t *forwarders = NULL; + result = dns_fwdtable_find(fctx->res->view->fwdtable, + &fctx->name, &forwarders); + if (result == ISC_R_SUCCESS) { + sa = ISC_LIST_HEAD(forwarders->addrs); + fctx->fwdpolicy = forwarders->fwdpolicy; + } + } while (sa != NULL) { ai = NULL; @@ -1355,7 +1363,7 @@ fctx_getaddresses(fetchctx_t *fctx) { * If the forwarding policy is "only", we don't need the addresses * of the nameservers. */ - if (res->fwdpolicy == dns_fwdpolicy_only) + if (fctx->fwdpolicy == dns_fwdpolicy_only) goto out; /* @@ -1976,7 +1984,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, dns_name_init(&fctx->domain, NULL); dns_rdataset_init(&fctx->nameservers); if (domain == NULL) { - if (res->fwdpolicy != dns_fwdpolicy_only) { + if (fctx->fwdpolicy != dns_fwdpolicy_only) { /* * The caller didn't supply a query domain and * nameservers, and we're not in forward-only mode, @@ -2033,6 +2041,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, ISC_LIST_INIT(fctx->finds); ISC_LIST_INIT(fctx->forwaddrs); ISC_LIST_INIT(fctx->forwarders); + fctx->fwdpolicy = dns_fwdpolicy_none; ISC_LIST_INIT(fctx->bad); ISC_LIST_INIT(fctx->validators); fctx->find = NULL; @@ -4166,19 +4175,6 @@ resquery_response(isc_task_t *task, isc_event_t *event) { *** Resolver Methods ***/ -static void -free_forwarders(dns_resolver_t *res) { - isc_sockaddr_t *sa, *next_sa; - - for (sa = ISC_LIST_HEAD(res->forwarders); - sa != NULL; - sa = next_sa) { - next_sa = ISC_LIST_NEXT(sa, link); - ISC_LIST_UNLINK(res->forwarders, sa, link); - isc_mem_put(res->mctx, sa, sizeof *sa); - } -} - static void destroy(dns_resolver_t *res) { unsigned int i; @@ -4202,7 +4198,6 @@ destroy(dns_resolver_t *res) { dns_dispatch_detach(&res->dispatchv4); if (res->dispatchv6 != NULL) dns_dispatch_detach(&res->dispatchv6); - free_forwarders(res); res->magic = 0; isc_mem_put(res->mctx, res, sizeof *res); } @@ -4312,12 +4307,6 @@ dns_resolver_create(dns_view_t *view, if (dispatchv6 != NULL) dns_dispatch_attach(dispatchv6, &res->dispatchv6); - /* - * Forwarding. - */ - ISC_LIST_INIT(res->forwarders); - res->fwdpolicy = dns_fwdpolicy_none; - res->references = 1; res->exiting = ISC_FALSE; res->frozen = ISC_FALSE; @@ -4356,55 +4345,6 @@ dns_resolver_create(dns_view_t *view, return (result); } -isc_result_t -dns_resolver_setforwarders(dns_resolver_t *res, - isc_sockaddrlist_t *forwarders) -{ - isc_sockaddr_t *sa, *nsa; - - /* - * Set the default forwarders to be used by the resolver. - */ - - REQUIRE(VALID_RESOLVER(res)); - REQUIRE(!res->frozen); - REQUIRE(!ISC_LIST_EMPTY(*forwarders)); - - if (!ISC_LIST_EMPTY(res->forwarders)) - free_forwarders(res); - - for (sa = ISC_LIST_HEAD(*forwarders); - sa != NULL; - sa = ISC_LIST_NEXT(sa, link)) { - nsa = isc_mem_get(res->mctx, sizeof *nsa); - if (nsa == NULL) { - free_forwarders(res); - return (ISC_R_NOMEMORY); - } - /* XXXRTH Create and use isc_sockaddr_copy(). */ - *nsa = *sa; - ISC_LINK_INIT(nsa, link); - ISC_LIST_APPEND(res->forwarders, nsa, link); - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_resolver_setfwdpolicy(dns_resolver_t *res, dns_fwdpolicy_t fwdpolicy) { - - /* - * Set the default forwarding policy to be used by the resolver. - */ - - REQUIRE(VALID_RESOLVER(res)); - REQUIRE(!res->frozen); - - res->fwdpolicy = fwdpolicy; - - return (ISC_R_SUCCESS); -} - static void prime_done(isc_task_t *task, isc_event_t *event) { dns_resolver_t *res; @@ -4453,13 +4393,6 @@ dns_resolver_prime(dns_resolver_t *res) { RTRACE("dns_resolver_prime"); - /* - * Forwarding-only resolvers don't need to be - * primed. - */ - if (res->fwdpolicy == dns_fwdpolicy_only) - return; - LOCK(&res->lock); if (!res->exiting && !res->priming) { diff --git a/lib/dns/view.c b/lib/dns/view.c index 38f073b786..a8c6d8681b 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: view.c,v 1.76 2000/08/17 23:54:32 gson Exp $ */ +/* $Id: view.c,v 1.77 2000/08/24 22:15:34 bwelling Exp $ */ #include @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -111,6 +112,15 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, result = ISC_R_UNEXPECTED; goto cleanup_secroots; } + view->fwdtable = NULL; + result = dns_fwdtable_create(mctx, &view->fwdtable); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "dns_fwdtable_create() failed: %s", + isc_result_totext(result)); + result = ISC_R_UNEXPECTED; + goto cleanup_trustedkeys; + } view->cache = NULL; view->cachedb = NULL; @@ -131,7 +141,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view->matchclients = NULL; result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys); if (result != ISC_R_SUCCESS) - goto cleanup_trustedkeys; + goto cleanup_fwdtable; view->peers = NULL; /* @@ -172,6 +182,9 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, cleanup_dynkeys: dns_tsigkeyring_destroy(&view->dynamickeys); + cleanup_fwdtable: + dns_fwdtable_destroy(&view->fwdtable); + cleanup_trustedkeys: dns_keytable_detach(&view->trustedkeys); @@ -233,6 +246,7 @@ destroy(dns_view_t *view) { dns_acl_detach(&view->recursionacl); dns_keytable_detach(&view->trustedkeys); dns_keytable_detach(&view->secroots); + dns_fwdtable_destroy(&view->fwdtable); isc_mutex_destroy(&view->lock); isc_mem_free(view->mctx, view->name); isc_mem_put(view->mctx, view, sizeof *view); diff --git a/util/copyrights b/util/copyrights index 70a4e668d0..ac08e88638 100644 --- a/util/copyrights +++ b/util/copyrights @@ -784,6 +784,7 @@ ./lib/dns/dbtable.c C 1999,2000 ./lib/dns/dispatch.c C 1999,2000 ./lib/dns/dnssec.c C 1999,2000 +./lib/dns/forward.c C 2000 ./lib/dns/gen-unix.h C 1999,2000 ./lib/dns/gen-win32.h C 1999,2000 ./lib/dns/gen.c C 1998,1999,2000 @@ -823,6 +824,7 @@ ./lib/dns/include/dns/dnssec.h C 1999,2000 ./lib/dns/include/dns/events.h C 1999,2000 ./lib/dns/include/dns/fixedname.h C 1999,2000 +./lib/dns/include/dns/forward.h C 2000 ./lib/dns/include/dns/journal.h C 1999,2000 ./lib/dns/include/dns/keyflags.h C 1999,2000 ./lib/dns/include/dns/keytable.h C 2000