Module Name: src Committed By: he Date: Thu Dec 25 23:19:10 UTC 2014
Modified Files: src/dist/bind/bin/named [netbsd-5]: config.c query.c server.c src/dist/bind/lib/dns [netbsd-5]: adb.c resolver.c src/dist/bind/lib/dns/include/dns [netbsd-5]: adb.h resolver.h src/dist/bind/lib/export/isc [netbsd-5]: Makefile.in src/dist/bind/lib/isc [netbsd-5]: Makefile.in src/dist/bind/lib/isc/include/isc [netbsd-5]: Makefile.in types.h src/dist/bind/lib/isccfg [netbsd-5]: namedconf.c src/lib/libisc [netbsd-5]: Makefile src/usr.sbin/bind [netbsd-5]: Makefile.inc Added Files: src/dist/bind/lib/isc [netbsd-5]: counter.c src/dist/bind/lib/isc/include/isc [netbsd-5]: counter.h Log Message: Apply fix for BIND, backported from the patch for 9.8.8 from ISC. This is a fix for CVE-2014-8500, where a maliciously constructed setup can cause BIND to issue an unlimited sequence of queries to follow a delegation. [spz, ticket #1937] To generate a diff of this commit: cvs rdiff -u -r1.1.1.8.4.4 -r1.1.1.8.4.5 src/dist/bind/bin/named/config.c cvs rdiff -u -r1.8.4.8 -r1.8.4.9 src/dist/bind/bin/named/query.c cvs rdiff -u -r1.1.1.9.4.4 -r1.1.1.9.4.5 src/dist/bind/bin/named/server.c cvs rdiff -u -r1.6.4.4 -r1.6.4.5 src/dist/bind/lib/dns/adb.c cvs rdiff -u -r1.8.4.6 -r1.8.4.7 src/dist/bind/lib/dns/resolver.c cvs rdiff -u -r1.1.1.5.4.3 -r1.1.1.5.4.4 \ src/dist/bind/lib/dns/include/dns/adb.h cvs rdiff -u -r1.1.1.5.4.4 -r1.1.1.5.4.5 \ src/dist/bind/lib/dns/include/dns/resolver.h cvs rdiff -u -r1.1.2.3 -r1.1.2.4 src/dist/bind/lib/export/isc/Makefile.in cvs rdiff -u -r1.1.1.6.4.4 -r1.1.1.6.4.5 src/dist/bind/lib/isc/Makefile.in cvs rdiff -u -r0 -r1.1.2.1 src/dist/bind/lib/isc/counter.c cvs rdiff -u -r1.1.1.5.4.4 -r1.1.1.5.4.5 \ src/dist/bind/lib/isc/include/isc/Makefile.in \ src/dist/bind/lib/isc/include/isc/types.h cvs rdiff -u -r0 -r1.1.2.1 src/dist/bind/lib/isc/include/isc/counter.h cvs rdiff -u -r1.1.1.7.4.4 -r1.1.1.7.4.5 src/dist/bind/lib/isccfg/namedconf.c cvs rdiff -u -r1.2.4.2 -r1.2.4.3 src/lib/libisc/Makefile cvs rdiff -u -r1.32.4.1 -r1.32.4.2 src/usr.sbin/bind/Makefile.inc Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/dist/bind/bin/named/config.c diff -u src/dist/bind/bin/named/config.c:1.1.1.8.4.4 src/dist/bind/bin/named/config.c:1.1.1.8.4.5 --- src/dist/bind/bin/named/config.c:1.1.1.8.4.4 Wed Jul 25 11:57:23 2012 +++ src/dist/bind/bin/named/config.c Thu Dec 25 23:19:09 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: config.c,v 1.1.1.8.4.4 2012/07/25 11:57:23 jdc Exp $ */ +/* $NetBSD: config.c,v 1.1.1.8.4.5 2014/12/25 23:19:09 he Exp $ */ /* * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") @@ -75,6 +75,8 @@ options {\n\ listen-on {any;};\n\ listen-on-v6 {none;};\n\ match-mapped-addresses no;\n\ + max-recursion-depth 7;\n\ + max-recursion-queries 50;\n\ memstatistics-file \"named.memstats\";\n\ multiple-cnames no;\n\ # named-xfer <obsolete>;\n\ Index: src/dist/bind/bin/named/query.c diff -u src/dist/bind/bin/named/query.c:1.8.4.8 src/dist/bind/bin/named/query.c:1.8.4.9 --- src/dist/bind/bin/named/query.c:1.8.4.8 Wed Jan 15 10:11:20 2014 +++ src/dist/bind/bin/named/query.c Thu Dec 25 23:19:09 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: query.c,v 1.8.4.8 2014/01/15 10:11:20 bouyer Exp $ */ +/* $NetBSD: query.c,v 1.8.4.9 2014/12/25 23:19:09 he Exp $ */ /* * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") @@ -3338,11 +3338,11 @@ query_recurse(ns_client_t *client, dns_r peeraddr = &client->peeraddr; else peeraddr = NULL; - result = dns_resolver_createfetch2(client->view->resolver, + result = dns_resolver_createfetch3(client->view->resolver, client->query.qname, qtype, qdomain, nameservers, NULL, peeraddr, client->message->id, - client->query.fetchoptions, + client->query.fetchoptions, 0, NULL, client->task, query_resume, client, rdataset, sigrdataset, Index: src/dist/bind/bin/named/server.c diff -u src/dist/bind/bin/named/server.c:1.1.1.9.4.4 src/dist/bind/bin/named/server.c:1.1.1.9.4.5 --- src/dist/bind/bin/named/server.c:1.1.1.9.4.4 Wed Jul 25 11:57:25 2012 +++ src/dist/bind/bin/named/server.c Thu Dec 25 23:19:10 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: server.c,v 1.1.1.9.4.4 2012/07/25 11:57:25 jdc Exp $ */ +/* $NetBSD: server.c,v 1.1.1.9.4.5 2014/12/25 23:19:10 he Exp $ */ /* * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") @@ -1837,6 +1837,16 @@ configure_view(dns_view_t *view, cfg_obj udpsize = 4096; dns_resolver_setudpsize(view->resolver, (isc_uint16_t)udpsize); + obj = NULL; + result = ns_config_get(maps, "max-recursion-depth", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_resolver_setmaxdepth(view->resolver, cfg_obj_asuint32(obj)); + + obj = NULL; + result = ns_config_get(maps, "max-recursion-queries", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_resolver_setmaxqueries(view->resolver, cfg_obj_asuint32(obj)); + /* * Set the maximum UDP response size. */ Index: src/dist/bind/lib/dns/adb.c diff -u src/dist/bind/lib/dns/adb.c:1.6.4.4 src/dist/bind/lib/dns/adb.c:1.6.4.5 --- src/dist/bind/lib/dns/adb.c:1.6.4.4 Wed Jul 25 11:58:42 2012 +++ src/dist/bind/lib/dns/adb.c Thu Dec 25 23:19:10 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: adb.c,v 1.6.4.4 2012/07/25 11:58:42 jdc Exp $ */ +/* $NetBSD: adb.c,v 1.6.4.5 2014/12/25 23:19:10 he Exp $ */ /* * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") @@ -202,6 +202,7 @@ struct dns_adbfetch { unsigned int magic; dns_fetch_t *fetch; dns_rdataset_t rdataset; + unsigned int depth; }; /*% @@ -310,6 +311,7 @@ static void cancel_fetches_at_name(dns_a static isc_result_t dbfind_name(dns_adbname_t *, isc_stdtime_t, dns_rdatatype_t); static isc_result_t fetch_name(dns_adbname_t *, isc_boolean_t, + unsigned int, isc_counter_t *, dns_rdatatype_t); static inline void check_exit(dns_adb_t *); static void destroy(dns_adb_t *); @@ -2282,6 +2284,19 @@ dns_adb_createfind(dns_adb_t *adb, isc_t isc_stdtime_t now, dns_name_t *target, in_port_t port, dns_adbfind_t **findp) { + return (dns_adb_createfind2(adb, task, action, arg, name, + qname, qtype, options, now, + target, port, 0, NULL, findp)); +} + +isc_result_t +dns_adb_createfind2(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, + void *arg, dns_name_t *name, dns_name_t *qname, + dns_rdatatype_t qtype, unsigned int options, + isc_stdtime_t now, dns_name_t *target, + in_port_t port, unsigned int depth, isc_counter_t *qc, + dns_adbfind_t **findp) +{ dns_adbfind_t *find; dns_adbname_t *adbname; int bucket; @@ -2512,7 +2527,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_t * Start V4. */ if (WANT_INET(wanted_fetches) && - fetch_name(adbname, start_at_zone, + fetch_name(adbname, start_at_zone, depth, qc, dns_rdatatype_a) == ISC_R_SUCCESS) { DP(DEF_LEVEL, "dns_adb_createfind: started A fetch for name %p", @@ -2523,7 +2538,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_t * Start V6. */ if (WANT_INET6(wanted_fetches) && - fetch_name(adbname, start_at_zone, + fetch_name(adbname, start_at_zone, depth, qc, dns_rdatatype_aaaa) == ISC_R_SUCCESS) { DP(DEF_LEVEL, "dns_adb_createfind: " @@ -3256,6 +3271,12 @@ fetch_callback(isc_task_t *task, isc_eve DP(DEF_LEVEL, "adb: fetch of '%s' %s failed: %s", buf, address_type == DNS_ADBFIND_INET ? "A" : "AAAA", dns_result_totext(dev->result)); + /* + * Don't record a failure unless this is the initial + * fetch of a chain. + */ + if (fetch->depth > 1) + goto out; /* XXXMLG Don't pound on bad servers. */ if (address_type == DNS_ADBFIND_INET) { name->expire_v4 = ISC_MIN(name->expire_v4, now + 300); @@ -3295,6 +3316,7 @@ fetch_callback(isc_task_t *task, isc_eve static isc_result_t fetch_name(dns_adbname_t *adbname, isc_boolean_t start_at_zone, + unsigned int depth, isc_counter_t *qc, dns_rdatatype_t type) { isc_result_t result; @@ -3341,9 +3363,11 @@ fetch_name(dns_adbname_t *adbname, goto cleanup; } - result = dns_resolver_createfetch(adb->view->resolver, &adbname->name, + fetch->depth = depth; + result = dns_resolver_createfetch3(adb->view->resolver, &adbname->name, type, name, nameservers, NULL, - options, adb->task, fetch_callback, + NULL, 0, options, depth, qc, + adb->task, fetch_callback, adbname, &fetch->rdataset, NULL, &fetch->fetch); if (result != ISC_R_SUCCESS) Index: src/dist/bind/lib/dns/resolver.c diff -u src/dist/bind/lib/dns/resolver.c:1.8.4.6 src/dist/bind/lib/dns/resolver.c:1.8.4.7 --- src/dist/bind/lib/dns/resolver.c:1.8.4.6 Wed Jul 25 11:58:48 2012 +++ src/dist/bind/lib/dns/resolver.c Thu Dec 25 23:19:10 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: resolver.c,v 1.8.4.6 2012/07/25 11:58:48 jdc Exp $ */ +/* $NetBSD: resolver.c,v 1.8.4.7 2014/12/25 23:19:10 he Exp $ */ /* * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") @@ -23,6 +23,7 @@ #include <config.h> +#include <isc/counter.h> #include <isc/platform.h> #include <isc/print.h> #include <isc/string.h> @@ -107,6 +108,16 @@ #define QTRACE(m) #endif +/* The default maximum number of recursions to follow before giving up. */ +#ifndef DEFAULT_RECURSION_DEPTH +#define DEFAULT_RECURSION_DEPTH 7 +#endif + +/* The default maximum number of iterative queries to allow before giving up. */ +#ifndef DEFAULT_MAX_QUERIES +#define DEFAULT_MAX_QUERIES 50 +#endif + /*% * Maximum EDNS0 input packet size. */ @@ -214,6 +225,7 @@ struct fetchctx { dns_adb_t * adb; isc_boolean_t ns_ttl_ok; isc_uint32_t ns_ttl; + isc_counter_t * qc; /*% * The number of events we're waiting for. @@ -281,6 +293,7 @@ struct fetchctx { isc_boolean_t timeout; dns_adbaddrinfo_t *addrinfo; isc_sockaddr_t *client; + unsigned int depth; }; #define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!') @@ -392,6 +405,8 @@ struct dns_resolver { unsigned int spillatmin; isc_timer_t * spillattimer; isc_boolean_t zero_no_soa_ttl; + unsigned int maxdepth; + unsigned int maxqueries; /* Locked by lock. */ unsigned int references; @@ -2179,9 +2194,9 @@ fctx_finddone(isc_task_t *task, isc_even */ INSIST(!SHUTTINGDOWN(fctx)); fctx->attributes &= ~FCTX_ATTR_ADDRWAIT; - if (event->ev_type == DNS_EVENT_ADBMOREADDRESSES) + if (event->ev_type == DNS_EVENT_ADBMOREADDRESSES) { want_try = ISC_TRUE; - else { + } else { fctx->findfail++; if (fctx->pending == 0) { /* @@ -2210,10 +2225,10 @@ fctx_finddone(isc_task_t *task, isc_even else if (want_done) fctx_done(fctx, ISC_R_FAILURE, __LINE__); else if (destroy) { - fctx_destroy(fctx); + fctx_destroy(fctx); if (bucket_empty) - empty_bucket(res); -} + empty_bucket(res); + } } @@ -2528,12 +2543,13 @@ findname(fetchctx_t *fctx, dns_name_t *n * See what we know about this address. */ find = NULL; - result = dns_adb_createfind(fctx->adb, + result = dns_adb_createfind2(fctx->adb, res->buckets[fctx->bucketnum].task, fctx_finddone, fctx, name, &fctx->name, fctx->type, options, now, NULL, - res->view->dstport, &find); + res->view->dstport, + fctx->depth + 1, fctx->qc, &find); if (result != ISC_R_SUCCESS) { if (result == DNS_R_ALIAS) { /* @@ -2641,6 +2657,14 @@ fctx_getaddresses(fetchctx_t *fctx, isc_ res = fctx->res; + if (fctx->depth > res->maxdepth) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, + DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), + "too much NS indirection resolving '%s'", + fctx->info); + return (DNS_R_SERVFAIL); + } + /* * Forwarders. */ @@ -3116,6 +3140,16 @@ fctx_try(fetchctx_t *fctx, isc_boolean_t } } + result = isc_counter_increment(fctx->qc); + if (result != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, + DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), + "exceeded max queries resolving '%s'", + fctx->info); + fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); + return; + } + result = fctx_query(fctx, addrinfo, fctx->options); if (result != ISC_R_SUCCESS) fctx_done(fctx, result, __LINE__); @@ -3214,6 +3248,7 @@ fctx_destroy(fetchctx_t *fctx) { isc_mem_put(fctx->mctx, sa, sizeof(*sa)); } + isc_counter_detach(&fctx->qc); isc_timer_detach(&fctx->timer); dns_message_destroy(&fctx->rmessage); dns_message_destroy(&fctx->qmessage); @@ -3542,7 +3577,8 @@ log_ns_ttl(fetchctx_t *fctx, const char static isc_result_t fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, dns_name_t *domain, dns_rdataset_t *nameservers, - unsigned int options, unsigned int bucketnum, fetchctx_t **fctxp) + unsigned int options, unsigned int bucketnum, unsigned int depth, + isc_counter_t *qc, fetchctx_t **fctxp) { fetchctx_t *fctx; isc_result_t result; @@ -3564,6 +3600,21 @@ fctx_create(dns_resolver_t *res, dns_nam fctx = isc_mem_get(mctx, sizeof(*fctx)); if (fctx == NULL) return (ISC_R_NOMEMORY); + + fctx->qc = NULL; + if (qc != NULL) { + isc_counter_attach(qc, &fctx->qc); + } else { + result = isc_counter_create(res->mctx, + res->maxqueries, &fctx->qc); + if (result != ISC_R_SUCCESS) + goto cleanup_counter; + } + + /* + * Make fctx->info point to a copy of a formatted string + * "name/type". + */ dns_name_format(name, buf, sizeof(buf)); dns_rdatatype_format(type, typebuf, sizeof(typebuf)); strcat(buf, "/"); /* checked */ @@ -3594,6 +3645,7 @@ fctx_create(dns_resolver_t *res, dns_nam fctx->state = fetchstate_init; fctx->want_shutdown = ISC_FALSE; fctx->cloned = ISC_FALSE; + fctx->depth = depth; ISC_LIST_INIT(fctx->queries); ISC_LIST_INIT(fctx->finds); ISC_LIST_INIT(fctx->altfinds); @@ -3799,6 +3851,9 @@ fctx_create(dns_resolver_t *res, dns_nam cleanup_info: isc_mem_free(mctx, fctx->info); + cleanup_counter: + isc_counter_detach(&fctx->qc); + cleanup_fetch: isc_mem_put(mctx, fctx, sizeof(*fctx)); @@ -5510,7 +5565,7 @@ noanswer_response(fetchctx_t *fctx, dns_ char qbuf[DNS_NAME_FORMATSIZE]; char nbuf[DNS_NAME_FORMATSIZE]; char tbuf[DNS_RDATATYPE_FORMATSIZE]; - dns_rdatatype_format(fctx->type, tbuf, + dns_rdatatype_format(type, tbuf, sizeof(tbuf)); dns_name_format(name, nbuf, sizeof(nbuf)); @@ -5519,7 +5574,7 @@ noanswer_response(fetchctx_t *fctx, dns_ log_formerr(fctx, "unrelated %s %s in " "%s authority section", - tbuf, qbuf, nbuf); + tbuf, nbuf, qbuf); return (DNS_R_FORMERR); } if (type == dns_rdatatype_ns) { @@ -7560,6 +7615,8 @@ dns_resolver_create(dns_view_t *view, res->zero_no_soa_ttl = ISC_FALSE; res->ndisps = 0; res->nextdisp = 0; /* meaningless at this point, but init it */ + res->maxdepth = DEFAULT_RECURSION_DEPTH; + res->maxqueries = DEFAULT_MAX_QUERIES; res->nbuckets = ntasks; res->activebuckets = ntasks; res->buckets = isc_mem_get(view->mctx, @@ -7999,9 +8056,9 @@ dns_resolver_createfetch(dns_resolver_t dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp) { - return (dns_resolver_createfetch2(res, name, type, domain, + return (dns_resolver_createfetch3(res, name, type, domain, nameservers, forwarders, NULL, 0, - options, task, action, arg, + options, 0, NULL, task, action, arg, rdataset, sigrdataset, fetchp)); } @@ -8017,6 +8074,25 @@ dns_resolver_createfetch2(dns_resolver_t dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp) { + return (dns_resolver_createfetch3(res, name, type, domain, + nameservers, forwarders, client, id, + options, 0, NULL, task, action, arg, + rdataset, sigrdataset, fetchp)); +} + +isc_result_t +dns_resolver_createfetch3(dns_resolver_t *res, dns_name_t *name, + dns_rdatatype_t type, + dns_name_t *domain, dns_rdataset_t *nameservers, + dns_forwarders_t *forwarders, + isc_sockaddr_t *client, dns_messageid_t id, + unsigned int options, unsigned int depth, + isc_counter_t *qc, isc_task_t *task, + isc_taskaction_t action, void *arg, + dns_rdataset_t *rdataset, + dns_rdataset_t *sigrdataset, + dns_fetch_t **fetchp) +{ dns_fetch_t *fetch; fetchctx_t *fctx = NULL; isc_result_t result = ISC_R_SUCCESS; @@ -8103,11 +8179,12 @@ dns_resolver_createfetch2(dns_resolver_t if (fctx == NULL) { result = fctx_create(res, name, type, domain, nameservers, - options, bucketnum, &fctx); + options, bucketnum, depth, qc, &fctx); if (result != ISC_R_SUCCESS) goto unlock; new_fctx = ISC_TRUE; - } + } else if (fctx->depth > depth) + fctx->depth = depth; result = fctx_join(fctx, task, client, id, action, arg, rdataset, sigrdataset, fetch); @@ -8858,3 +8935,28 @@ dns_resolver_getoptions(dns_resolver_t * return (resolver->options); } + +void +dns_resolver_setmaxdepth(dns_resolver_t *resolver, unsigned int maxdepth) { + REQUIRE(VALID_RESOLVER(resolver)); + resolver->maxdepth = maxdepth; +} + +unsigned int +dns_resolver_getmaxdepth(dns_resolver_t *resolver) { + REQUIRE(VALID_RESOLVER(resolver)); + return (resolver->maxdepth); +} + +void +dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries) { + REQUIRE(VALID_RESOLVER(resolver)); + resolver->maxqueries = queries; +} + +unsigned int +dns_resolver_getmaxqueries(dns_resolver_t *resolver) { + REQUIRE(VALID_RESOLVER(resolver)); + return (resolver->maxqueries); +} + Index: src/dist/bind/lib/dns/include/dns/adb.h diff -u src/dist/bind/lib/dns/include/dns/adb.h:1.1.1.5.4.3 src/dist/bind/lib/dns/include/dns/adb.h:1.1.1.5.4.4 --- src/dist/bind/lib/dns/include/dns/adb.h:1.1.1.5.4.3 Wed Jul 25 11:58:52 2012 +++ src/dist/bind/lib/dns/include/dns/adb.h Thu Dec 25 23:19:10 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: adb.h,v 1.1.1.5.4.3 2012/07/25 11:58:52 jdc Exp $ */ +/* $NetBSD: adb.h,v 1.1.1.5.4.4 2014/12/25 23:19:10 he Exp $ */ /* * Copyright (C) 2004-2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") @@ -336,6 +336,13 @@ dns_adb_createfind(dns_adb_t *adb, isc_t dns_rdatatype_t qtype, unsigned int options, isc_stdtime_t now, dns_name_t *target, in_port_t port, dns_adbfind_t **find); +isc_result_t +dns_adb_createfind2(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, + void *arg, dns_name_t *name, dns_name_t *qname, + dns_rdatatype_t qtype, unsigned int options, + isc_stdtime_t now, dns_name_t *target, in_port_t port, + unsigned int depth, isc_counter_t *qc, + dns_adbfind_t **find); /*%< * Main interface for clients. The adb will look up the name given in * "name" and will build up a list of found addresses, and perhaps start Index: src/dist/bind/lib/dns/include/dns/resolver.h diff -u src/dist/bind/lib/dns/include/dns/resolver.h:1.1.1.5.4.4 src/dist/bind/lib/dns/include/dns/resolver.h:1.1.1.5.4.5 --- src/dist/bind/lib/dns/include/dns/resolver.h:1.1.1.5.4.4 Wed Jul 25 11:58:53 2012 +++ src/dist/bind/lib/dns/include/dns/resolver.h Thu Dec 25 23:19:10 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: resolver.h,v 1.1.1.5.4.4 2012/07/25 11:58:53 jdc Exp $ */ +/* $NetBSD: resolver.h,v 1.1.1.5.4.5 2014/12/25 23:19:10 he Exp $ */ /* * Copyright (C) 2004-2010, 2012 Internet Systems Consortium, Inc. ("ISC") @@ -273,6 +273,18 @@ dns_resolver_createfetch2(dns_resolver_t dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp); +isc_result_t +dns_resolver_createfetch3(dns_resolver_t *res, dns_name_t *name, + dns_rdatatype_t type, + dns_name_t *domain, dns_rdataset_t *nameservers, + dns_forwarders_t *forwarders, + isc_sockaddr_t *client, isc_uint16_t id, + unsigned int options, unsigned int depth, + isc_counter_t *qc, isc_task_t *task, + isc_taskaction_t action, void *arg, + dns_rdataset_t *rdataset, + dns_rdataset_t *sigrdataset, + dns_fetch_t **fetchp); /*%< * Recurse to answer a question. * @@ -553,6 +565,30 @@ dns_resolver_printbadcache(dns_resolver_ * \li resolver to be valid. */ +void +dns_resolver_setmaxdepth(dns_resolver_t *resolver, unsigned int maxdepth); +unsigned int +dns_resolver_getmaxdepth(dns_resolver_t *resolver); +/*% + * Get and set how many NS indirections will be followed when looking for + * nameserver addresses. + * + * Requires: + * \li resolver to be valid. + */ + +void +dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries); +unsigned int +dns_resolver_getmaxqueries(dns_resolver_t *resolver); +/*% + * Get and set how many iterative queries will be allowed before + * terminating a recursive query. + * + * Requires: + * \li resolver to be valid. + */ + ISC_LANG_ENDDECLS #endif /* DNS_RESOLVER_H */ Index: src/dist/bind/lib/export/isc/Makefile.in diff -u src/dist/bind/lib/export/isc/Makefile.in:1.1.2.3 src/dist/bind/lib/export/isc/Makefile.in:1.1.2.4 --- src/dist/bind/lib/export/isc/Makefile.in:1.1.2.3 Wed Jul 25 11:59:03 2012 +++ src/dist/bind/lib/export/isc/Makefile.in Thu Dec 25 23:19:10 2014 @@ -63,7 +63,7 @@ WIN32OBJS = win32/condition.@O@ win32/d # Alphabetically OBJS = @ISC_EXTRA_OBJS@ \ assertions.@O@ backtrace.@O@ backtrace-emptytbl.@O@ base32.@O@ \ - base64.@O@ buffer.@O@ bufferlist.@O@ \ + base64.@O@ buffer.@O@ bufferlist.@O@ counter.@O@ \ error.@O@ event.@O@ \ hash.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \ inet_aton.@O@ iterated_hash.@O@ lex.@O@ lfsr.@O@ log.@O@ \ @@ -86,7 +86,7 @@ ISCDRIVERSRCS = mem.c task.c lib.c timer SRCS = @ISC_EXTRA_SRCS@ \ assertions.c backtrace.c backtrace-emptytbl.c base32.c \ - base64.c buffer.c bufferlist.c \ + base64.c buffer.c bufferlist.c counter.c \ error.c event.c \ hash.c hex.c hmacmd5.c hmacsha.c \ inet_aton.c iterated_hash.c lex.c log.c lfsr.c \ Index: src/dist/bind/lib/isc/Makefile.in diff -u src/dist/bind/lib/isc/Makefile.in:1.1.1.6.4.4 src/dist/bind/lib/isc/Makefile.in:1.1.1.6.4.5 --- src/dist/bind/lib/isc/Makefile.in:1.1.1.6.4.4 Wed Jul 25 11:59:08 2012 +++ src/dist/bind/lib/isc/Makefile.in Thu Dec 25 23:19:09 2014 @@ -53,7 +53,7 @@ WIN32OBJS = win32/condition.@O@ win32/d OBJS = @ISC_EXTRA_OBJS@ \ assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \ bitstring.@O@ buffer.@O@ bufferlist.@O@ commandline.@O@ \ - error.@O@ event.@O@ \ + counter.@O error.@O@ event.@O@ \ hash.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \ httpd.@O@ inet_aton.@O@ iterated_hash.@O@ \ lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \ @@ -69,7 +69,7 @@ SYMTBLOBJS = backtrace-emptytbl.@O@ # Alphabetically SRCS = @ISC_EXTRA_SRCS@ \ assertions.c backtrace.c base32.c base64.c bitstring.c \ - buffer.c bufferlist.c commandline.c error.c event.c \ + buffer.c bufferlist.c commandline.c counter.c error.c event.c \ heap.c hex.c hmacmd5.c hmacsha.c \ httpd.c inet_aton.c iterated_hash.c \ lex.c lfsr.c lib.c log.c \ Index: src/dist/bind/lib/isc/include/isc/Makefile.in diff -u src/dist/bind/lib/isc/include/isc/Makefile.in:1.1.1.5.4.4 src/dist/bind/lib/isc/include/isc/Makefile.in:1.1.1.5.4.5 --- src/dist/bind/lib/isc/include/isc/Makefile.in:1.1.1.5.4.4 Wed Jul 25 11:59:12 2012 +++ src/dist/bind/lib/isc/include/isc/Makefile.in Thu Dec 25 23:19:09 2014 @@ -27,7 +27,8 @@ top_srcdir = @top_srcdir@ # install target below. # HEADERS = app.h assertions.h base64.h bind9.h bitstring.h boolean.h \ - buffer.h bufferlist.h commandline.h entropy.h error.h event.h \ + buffer.h bufferlist.h commandline.h counter.h \ + entropy.h error.h event.h \ eventclass.h file.h formatcheck.h fsaccess.h \ hash.h heap.h hex.h hmacmd5.h hmacsha.h \ httpd.h \ Index: src/dist/bind/lib/isc/include/isc/types.h diff -u src/dist/bind/lib/isc/include/isc/types.h:1.1.1.5.4.4 src/dist/bind/lib/isc/include/isc/types.h:1.1.1.5.4.5 --- src/dist/bind/lib/isc/include/isc/types.h:1.1.1.5.4.4 Wed Jul 25 11:59:16 2012 +++ src/dist/bind/lib/isc/include/isc/types.h Thu Dec 25 23:19:09 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: types.h,v 1.1.1.5.4.4 2012/07/25 11:59:16 jdc Exp $ */ +/* $NetBSD: types.h,v 1.1.1.5.4.5 2014/12/25 23:19:09 he Exp $ */ /* * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") @@ -52,6 +52,7 @@ typedef struct isc_buffer isc_buffer_t; typedef ISC_LIST(isc_buffer_t) isc_bufferlist_t; /*%< Buffer List */ typedef struct isc_constregion isc_constregion_t; /*%< Const region */ typedef struct isc_consttextregion isc_consttextregion_t; /*%< Const Text Region */ +typedef struct isc_counter isc_counter_t; /*%< Counter */ typedef struct isc_entropy isc_entropy_t; /*%< Entropy */ typedef struct isc_entropysource isc_entropysource_t; /*%< Entropy Source */ typedef struct isc_event isc_event_t; /*%< Event */ Index: src/dist/bind/lib/isccfg/namedconf.c diff -u src/dist/bind/lib/isccfg/namedconf.c:1.1.1.7.4.4 src/dist/bind/lib/isccfg/namedconf.c:1.1.1.7.4.5 --- src/dist/bind/lib/isccfg/namedconf.c:1.1.1.7.4.4 Wed Jul 25 11:59:28 2012 +++ src/dist/bind/lib/isccfg/namedconf.c Thu Dec 25 23:19:10 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: namedconf.c,v 1.1.1.7.4.4 2012/07/25 11:59:28 jdc Exp $ */ +/* $NetBSD: namedconf.c,v 1.1.1.7.4.5 2014/12/25 23:19:10 he Exp $ */ /* * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") @@ -1051,6 +1051,8 @@ view_clauses[] = { { "max-cache-ttl", &cfg_type_uint32, 0 }, { "max-clients-per-query", &cfg_type_uint32, 0 }, { "max-ncache-ttl", &cfg_type_uint32, 0 }, + { "max-recursion-depth", &cfg_type_uint32, 0 }, + { "max-recursion-queries", &cfg_type_uint32, 0 }, { "max-udp-size", &cfg_type_uint32, 0 }, { "min-roots", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTIMP }, { "minimal-responses", &cfg_type_boolean, 0 }, Index: src/lib/libisc/Makefile diff -u src/lib/libisc/Makefile:1.2.4.2 src/lib/libisc/Makefile:1.2.4.3 --- src/lib/libisc/Makefile:1.2.4.2 Thu Jan 6 21:42:49 2011 +++ src/lib/libisc/Makefile Thu Dec 25 23:19:10 2014 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.2.4.2 2011/01/06 21:42:49 riz Exp $ +# $NetBSD: Makefile,v 1.2.4.3 2014/12/25 23:19:10 he Exp $ LIB=isc @@ -23,7 +23,7 @@ NLS_SRCS= msgcat.c PTHREAD_SRCS= condition.c mutex.c thread.c SRCS= assertions.c base32.c base64.c bitstring.c buffer.c \ - bufferlist.c commandline.c error.c event.c \ + bufferlist.c commandline.c counter.c error.c event.c \ hash.c heap.c hex.c hmacmd5.c hmacsha.c httpd.c inet_aton.c \ iterated_hash.c lex.c lfsr.c lib.c log.c md5.c mem.c \ mutexblock.c netaddr.c netscope.c ondestroy.c parseint.c \ Index: src/usr.sbin/bind/Makefile.inc diff -u src/usr.sbin/bind/Makefile.inc:1.32.4.1 src/usr.sbin/bind/Makefile.inc:1.32.4.2 --- src/usr.sbin/bind/Makefile.inc:1.32.4.1 Thu Jan 6 21:42:49 2011 +++ src/usr.sbin/bind/Makefile.inc Thu Dec 25 23:19:10 2014 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.inc,v 1.32.4.1 2011/01/06 21:42:49 riz Exp $ +# $NetBSD: Makefile.inc,v 1.32.4.2 2014/12/25 23:19:10 he Exp $ .if !defined(BIND9_MAKEFILE_INC) BIND9_MAKEFILE_INC=yes @@ -23,7 +23,10 @@ BIND_HTMLDIR= /usr/share/doc/html/bind9 .include "${IDIST}/version" -VERSION=${MAJORVER}.${MINORVER}.${PATCHVER}${RELEASETYPE}${RELEASEVER} +# Packager suffix, for local patches past end of support from ISC +PSUFFIX=nb5 + +VERSION=${MAJORVER}.${MINORVER}.${PATCHVER}${RELEASETYPE}${RELEASEVER}${PSUFFIX} SYSCONFDIR=/etc LOCALSTATEDIR=/var Added files: Index: src/dist/bind/lib/isc/counter.c diff -u /dev/null src/dist/bind/lib/isc/counter.c:1.1.2.1 --- /dev/null Thu Dec 25 23:19:10 2014 +++ src/dist/bind/lib/isc/counter.c Thu Dec 25 23:19:09 2014 @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC 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. + */ + +/*! \file */ + +#include <config.h> + +#include <stddef.h> + +#include <isc/counter.h> +#include <isc/magic.h> +#include <isc/mem.h> +#include <isc/util.h> + +#define COUNTER_MAGIC ISC_MAGIC('C', 'n', 't', 'r') +#define VALID_COUNTER(r) ISC_MAGIC_VALID(r, COUNTER_MAGIC) + +struct isc_counter { + unsigned int magic; + isc_mem_t *mctx; + isc_mutex_t lock; + unsigned int references; + unsigned int limit; + unsigned int used; +}; + +isc_result_t +isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp) { + isc_result_t result; + isc_counter_t *counter; + + REQUIRE(counterp != NULL && *counterp == NULL); + + counter = isc_mem_get(mctx, sizeof(*counter)); + if (counter == NULL) + return (ISC_R_NOMEMORY); + + result = isc_mutex_init(&counter->lock); + if (result != ISC_R_SUCCESS) { + isc_mem_put(mctx, counter, sizeof(*counter)); + return (result); + } + + counter->mctx = NULL; + isc_mem_attach(mctx, &counter->mctx); + + counter->references = 1; + counter->limit = limit; + counter->used = 0; + + counter->magic = COUNTER_MAGIC; + *counterp = counter; + return (ISC_R_SUCCESS); +} + +isc_result_t +isc_counter_increment(isc_counter_t *counter) { + isc_result_t result = ISC_R_SUCCESS; + + LOCK(&counter->lock); + counter->used++; + if (counter->limit != 0 && counter->used >= counter->limit) + result = ISC_R_QUOTA; + UNLOCK(&counter->lock); + + return (result); +} + +unsigned int +isc_counter_used(isc_counter_t *counter) { + REQUIRE(VALID_COUNTER(counter)); + + return (counter->used); +} + +void +isc_counter_setlimit(isc_counter_t *counter, int limit) { + REQUIRE(VALID_COUNTER(counter)); + + LOCK(&counter->lock); + counter->limit = limit; + UNLOCK(&counter->lock); +} + +void +isc_counter_attach(isc_counter_t *source, isc_counter_t **targetp) { + REQUIRE(VALID_COUNTER(source)); + REQUIRE(targetp != NULL && *targetp == NULL); + + LOCK(&source->lock); + source->references++; + INSIST(source->references > 0); + UNLOCK(&source->lock); + + *targetp = source; +} + +static void +destroy(isc_counter_t *counter) { + counter->magic = 0; + isc_mutex_destroy(&counter->lock); + isc_mem_putanddetach(&counter->mctx, counter, sizeof(*counter)); +} + +void +isc_counter_detach(isc_counter_t **counterp) { + isc_counter_t *counter; + isc_boolean_t want_destroy = ISC_FALSE; + + REQUIRE(counterp != NULL && *counterp != NULL); + counter = *counterp; + REQUIRE(VALID_COUNTER(counter)); + + *counterp = NULL; + + LOCK(&counter->lock); + INSIST(counter->references > 0); + counter->references--; + if (counter->references == 0) + want_destroy = ISC_TRUE; + UNLOCK(&counter->lock); + + if (want_destroy) + destroy(counter); +} Index: src/dist/bind/lib/isc/include/isc/counter.h diff -u /dev/null src/dist/bind/lib/isc/include/isc/counter.h:1.1.2.1 --- /dev/null Thu Dec 25 23:19:10 2014 +++ src/dist/bind/lib/isc/include/isc/counter.h Thu Dec 25 23:19:09 2014 @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC 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. + */ + +#ifndef ISC_COUNTER_H +#define ISC_COUNTER_H 1 + +/***** + ***** Module Info + *****/ + +/*! \file isc/counter.h + * + * \brief The isc_counter_t object is a simplified version of the + * isc_quota_t object; it tracks the consumption of limited + * resources, returning an error condition when the quota is + * exceeded. However, unlike isc_quota_t, attaching and detaching + * from a counter object does not increment or decrement the counter. + */ + +/*** + *** Imports. + ***/ + +#include <isc/lang.h> +#include <isc/mutex.h> +#include <isc/types.h> + +/***** + ***** Types. + *****/ + +ISC_LANG_BEGINDECLS + +isc_result_t +isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp); +/*%< + * Allocate and initialize a counter object. + */ + +isc_result_t +isc_counter_increment(isc_counter_t *counter); +/*%< + * Increment the counter. + * + * If the counter limit is nonzero and has been reached, then + * return ISC_R_QUOTA, otherwise ISC_R_SUCCESS. (The counter is + * incremented regardless of return value.) + */ + +unsigned int +isc_counter_used(isc_counter_t *counter); +/*%< + * Return the current counter value. + */ + +void +isc_counter_setlimit(isc_counter_t *counter, int limit); +/*%< + * Set the counter limit. + */ + +void +isc_counter_attach(isc_counter_t *source, isc_counter_t **targetp); +/*%< + * Attach to a counter object, increasing its reference counter. + */ + +void +isc_counter_detach(isc_counter_t **counterp); +/*%< + * Detach (and destroy if reference counter has dropped to zero) + * a counter object. + */ + +ISC_LANG_ENDDECLS + +#endif /* ISC_COUNTER_H */ +