diff options
Diffstat (limited to 'lib/dns/resolver.c')
-rw-r--r-- | lib/dns/resolver.c | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 1b4f407..02e96cd 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.384.14.14.8.2 2010/01/07 17:17:19 each Exp $ */ +/* $Id: resolver.c,v 1.384.14.20 2010/01/07 23:47:36 tbox Exp $ */ /*! \file */ @@ -2534,6 +2534,16 @@ findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port, } } +static isc_boolean_t +isstrictsubdomain(dns_name_t *name1, dns_name_t *name2) { + int order; + unsigned int nlabels; + dns_namereln_t namereln; + + namereln = dns_name_fullcompare(name1, name2, &order, &nlabels); + return (ISC_TF(namereln == dns_namereln_subdomain)); +} + static isc_result_t fctx_getaddresses(fetchctx_t *fctx) { dns_rdata_t rdata = DNS_RDATA_INIT; @@ -2579,23 +2589,40 @@ fctx_getaddresses(fetchctx_t *fctx) { dns_name_t *name = &fctx->name; dns_name_t suffix; unsigned int labels; + dns_fixedname_t fixed; + dns_name_t *domain; /* * DS records are found in the parent server. * Strip label to get the correct forwarder (if any). */ - if (fctx->type == dns_rdatatype_ds && + if (dns_rdatatype_atparent(fctx->type) && dns_name_countlabels(name) > 1) { dns_name_init(&suffix, NULL); labels = dns_name_countlabels(name); dns_name_getlabelsequence(name, 1, labels - 1, &suffix); name = &suffix; } - result = dns_fwdtable_find(fctx->res->view->fwdtable, name, - &forwarders); + + dns_fixedname_init(&fixed); + domain = dns_fixedname_name(&fixed); + result = dns_fwdtable_find2(fctx->res->view->fwdtable, name, + domain, &forwarders); if (result == ISC_R_SUCCESS) { sa = ISC_LIST_HEAD(forwarders->addrs); fctx->fwdpolicy = forwarders->fwdpolicy; + if (fctx->fwdpolicy == dns_fwdpolicy_only && + isstrictsubdomain(domain, &fctx->domain)) { + isc_mem_t *mctx; + + mctx = res->buckets[fctx->bucketnum].mctx; + dns_name_free(&fctx->domain, mctx); + dns_name_init(&fctx->domain, NULL); + result = dns_name_dup(domain, mctx, + &fctx->domain); + if (result != ISC_R_SUCCESS) + return (result); + } } } @@ -3477,21 +3504,22 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, if (domain == NULL) { dns_forwarders_t *forwarders = NULL; unsigned int labels; + dns_name_t *fwdname = name; /* * DS records are found in the parent server. * Strip label to get the correct forwarder (if any). */ - if (fctx->type == dns_rdatatype_ds && + if (dns_rdatatype_atparent(fctx->type) && dns_name_countlabels(name) > 1) { dns_name_init(&suffix, NULL); labels = dns_name_countlabels(name); dns_name_getlabelsequence(name, 1, labels - 1, &suffix); - name = &suffix; + fwdname = &suffix; } dns_fixedname_init(&fixed); domain = dns_fixedname_name(&fixed); - result = dns_fwdtable_find2(fctx->res->view->fwdtable, name, + result = dns_fwdtable_find2(fctx->res->view->fwdtable, fwdname, domain, &forwarders); if (result == ISC_R_SUCCESS) fctx->fwdpolicy = forwarders->fwdpolicy; @@ -3502,7 +3530,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, * nameservers, and we're not in forward-only mode, * so find the best nameservers to use. */ - if (dns_rdatatype_atparent(type)) + if (dns_rdatatype_atparent(fctx->type)) findoptions |= DNS_DBFIND_NOEXACT; result = dns_view_findzonecut(res->view, name, domain, 0, findoptions, ISC_TRUE, |