I'm very pleased to announce the release of our new website and documentation using the new toolchain with Hugo and AsciiDoctor. To get more information about the new toolchain please read the FreeBSD Documentation Project Primer[1], Hugo docs[2] and AsciiDoctor docs[3]. Acknowledgment: Benedict Reuschling <bcr@> Glen Barber <gjb@> Hiroki Sato <hrs@> Li-Wen Hsu <lwhsu@> Sean Chittenden <seanc@> The FreeBSD Foundation [1] https://docs.FreeBSD.org/en/books/fdp-primer/ [2] https://gohugo.io/documentation/ [3] https://docs.asciidoctor.org/home/ Approved by: doceng, core
956 lines
29 KiB
Diff
956 lines
29 KiB
Diff
Index: contrib/bind9/CHANGES
|
|
===================================================================
|
|
--- contrib/bind9/CHANGES.orig
|
|
+++ contrib/bind9/CHANGES
|
|
@@ -1,3 +1,15 @@
|
|
+4006. [security] A flaw in delegation handling could be exploited
|
|
+ to put named into an infinite loop. This has
|
|
+ been addressed by placing limits on the number
|
|
+ of levels of recursion named will allow (default 7),
|
|
+ and the number of iterative queries that it will
|
|
+ send (default 50) before terminating a recursive
|
|
+ query (CVE-2014-8500).
|
|
+
|
|
+ The recursion depth limit is configured via the
|
|
+ "max-recursion-depth" option, and the query limit
|
|
+ via the "max-recursion-queries" option. [RT #37580]
|
|
+
|
|
--- 9.8.4-P2 released ---
|
|
|
|
3516. [security] Removed the check for regex.h in configure in order
|
|
Index: contrib/bind9/bin/named/config.c
|
|
===================================================================
|
|
--- contrib/bind9/bin/named/config.c.orig
|
|
+++ contrib/bind9/bin/named/config.c
|
|
@@ -15,8 +15,6 @@
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
-/* $Id: config.c,v 1.113.16.2 2011/02/28 01:19:58 tbox Exp $ */
|
|
-
|
|
/*! \file */
|
|
|
|
#include <config.h>
|
|
@@ -158,6 +156,8 @@
|
|
dnssec-accept-expired no;\n\
|
|
clients-per-query 10;\n\
|
|
max-clients-per-query 100;\n\
|
|
+ max-recursion-depth 7;\n\
|
|
+ max-recursion-queries 50;\n\
|
|
zero-no-soa-ttl-cache no;\n\
|
|
nsec3-test-zone no;\n\
|
|
allow-new-zones no;\n\
|
|
Index: contrib/bind9/bin/named/query.c
|
|
===================================================================
|
|
--- contrib/bind9/bin/named/query.c.orig
|
|
+++ contrib/bind9/bin/named/query.c
|
|
@@ -3755,12 +3755,11 @@
|
|
peeraddr = &client->peeraddr;
|
|
else
|
|
peeraddr = NULL;
|
|
- result = dns_resolver_createfetch2(client->view->resolver,
|
|
+ result = dns_resolver_createfetch3(client->view->resolver,
|
|
qname, qtype, qdomain, nameservers,
|
|
NULL, peeraddr, client->message->id,
|
|
- client->query.fetchoptions,
|
|
- client->task,
|
|
- query_resume, client,
|
|
+ client->query.fetchoptions, 0, NULL,
|
|
+ client->task, query_resume, client,
|
|
rdataset, sigrdataset,
|
|
&client->query.fetch);
|
|
|
|
Index: contrib/bind9/bin/named/server.c
|
|
===================================================================
|
|
--- contrib/bind9/bin/named/server.c.orig
|
|
+++ contrib/bind9/bin/named/server.c
|
|
@@ -2580,6 +2580,16 @@
|
|
cfg_obj_asuint32(obj),
|
|
max_clients_per_query);
|
|
|
|
+ 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));
|
|
+
|
|
#ifdef ALLOW_FILTER_AAAA_ON_V4
|
|
obj = NULL;
|
|
result = ns_config_get(maps, "filter-aaaa-on-v4", &obj);
|
|
Index: contrib/bind9/lib/dns/adb.c
|
|
===================================================================
|
|
--- contrib/bind9/lib/dns/adb.c.orig
|
|
+++ contrib/bind9/lib/dns/adb.c
|
|
@@ -201,6 +201,7 @@
|
|
unsigned int magic;
|
|
dns_fetch_t *fetch;
|
|
dns_rdataset_t rdataset;
|
|
+ unsigned int depth;
|
|
};
|
|
|
|
/*%
|
|
@@ -300,8 +301,7 @@
|
|
static inline void violate_locking_hierarchy(isc_mutex_t *, isc_mutex_t *);
|
|
static isc_boolean_t clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *);
|
|
static void clean_target(dns_adb_t *, dns_name_t *);
|
|
-static void clean_finds_at_name(dns_adbname_t *, isc_eventtype_t,
|
|
- unsigned int);
|
|
+static void clean_finds_at_name(dns_adbname_t *, isc_eventtype_t, unsigned int);
|
|
static isc_boolean_t check_expire_namehooks(dns_adbname_t *, isc_stdtime_t);
|
|
static isc_boolean_t check_expire_entry(dns_adb_t *, dns_adbentry_t **,
|
|
isc_stdtime_t);
|
|
@@ -309,6 +309,7 @@
|
|
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 *qc,
|
|
dns_rdatatype_t);
|
|
static inline void check_exit(dns_adb_t *);
|
|
static void destroy(dns_adb_t *);
|
|
@@ -2760,6 +2761,19 @@
|
|
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;
|
|
@@ -2990,7 +3004,7 @@
|
|
* 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",
|
|
@@ -3001,7 +3015,7 @@
|
|
* 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: "
|
|
@@ -3744,6 +3758,12 @@
|
|
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);
|
|
@@ -3781,9 +3801,8 @@
|
|
}
|
|
|
|
static isc_result_t
|
|
-fetch_name(dns_adbname_t *adbname,
|
|
- isc_boolean_t start_at_zone,
|
|
- dns_rdatatype_t type)
|
|
+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;
|
|
dns_adbfetch_t *fetch = NULL;
|
|
@@ -3828,12 +3847,14 @@
|
|
result = ISC_R_NOMEMORY;
|
|
goto cleanup;
|
|
}
|
|
+ fetch->depth = depth;
|
|
|
|
- result = dns_resolver_createfetch(adb->view->resolver, &adbname->name,
|
|
- type, name, nameservers, NULL,
|
|
- options, adb->task, fetch_callback,
|
|
- adbname, &fetch->rdataset, NULL,
|
|
- &fetch->fetch);
|
|
+ result = dns_resolver_createfetch3(adb->view->resolver, &adbname->name,
|
|
+ type, name, nameservers, NULL,
|
|
+ NULL, 0, options, depth, qc,
|
|
+ adb->task, fetch_callback, adbname,
|
|
+ &fetch->rdataset, NULL,
|
|
+ &fetch->fetch);
|
|
if (result != ISC_R_SUCCESS)
|
|
goto cleanup;
|
|
|
|
Index: contrib/bind9/lib/dns/include/dns/adb.h
|
|
===================================================================
|
|
--- contrib/bind9/lib/dns/include/dns/adb.h.orig
|
|
+++ contrib/bind9/lib/dns/include/dns/adb.h
|
|
@@ -334,6 +334,13 @@
|
|
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: contrib/bind9/lib/dns/include/dns/resolver.h
|
|
===================================================================
|
|
--- contrib/bind9/lib/dns/include/dns/resolver.h.orig
|
|
+++ contrib/bind9/lib/dns/include/dns/resolver.h
|
|
@@ -271,6 +271,18 @@
|
|
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.
|
|
*
|
|
@@ -572,6 +584,30 @@
|
|
* \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: contrib/bind9/lib/dns/resolver.c
|
|
===================================================================
|
|
--- contrib/bind9/lib/dns/resolver.c.orig
|
|
+++ contrib/bind9/lib/dns/resolver.c
|
|
@@ -21,6 +21,7 @@
|
|
|
|
#include <config.h>
|
|
|
|
+#include <isc/counter.h>
|
|
#include <isc/platform.h>
|
|
#include <isc/print.h>
|
|
#include <isc/string.h>
|
|
@@ -126,6 +127,16 @@
|
|
#define MAXIMUM_QUERY_TIMEOUT 30 /* The maximum time in seconds for the whole query to live. */
|
|
#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.
|
|
*/
|
|
@@ -227,12 +238,13 @@
|
|
isc_sockaddrlist_t edns;
|
|
isc_sockaddrlist_t edns512;
|
|
isc_sockaddrlist_t bad_edns;
|
|
- dns_validator_t *validator;
|
|
+ dns_validator_t * validator;
|
|
ISC_LIST(dns_validator_t) validators;
|
|
dns_db_t * cache;
|
|
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.
|
|
@@ -300,6 +312,7 @@
|
|
isc_boolean_t timeout;
|
|
dns_adbaddrinfo_t *addrinfo;
|
|
isc_sockaddr_t *client;
|
|
+ unsigned int depth;
|
|
};
|
|
|
|
#define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!')
|
|
@@ -412,6 +425,8 @@
|
|
isc_timer_t * spillattimer;
|
|
isc_boolean_t zero_no_soa_ttl;
|
|
unsigned int query_timeout;
|
|
+ unsigned int maxdepth;
|
|
+ unsigned int maxqueries;
|
|
|
|
/* Locked by lock. */
|
|
unsigned int references;
|
|
@@ -1569,6 +1584,7 @@
|
|
if (result != ISC_R_SUCCESS)
|
|
goto cleanup_dispatch;
|
|
}
|
|
+
|
|
fctx->querysent++;
|
|
|
|
ISC_LIST_APPEND(fctx->queries, query, link);
|
|
@@ -2210,9 +2226,9 @@
|
|
*/
|
|
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) {
|
|
/*
|
|
@@ -2241,7 +2257,7 @@
|
|
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);
|
|
}
|
|
@@ -2495,12 +2511,13 @@
|
|
* See what we know about this address.
|
|
*/
|
|
find = NULL;
|
|
- result = dns_adb_createfind(fctx->adb,
|
|
- res->buckets[fctx->bucketnum].task,
|
|
- fctx_finddone, fctx, name,
|
|
- &fctx->name, fctx->type,
|
|
- options, now, NULL,
|
|
- res->view->dstport, &find);
|
|
+ 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,
|
|
+ fctx->depth + 1, fctx->qc, &find);
|
|
if (result != ISC_R_SUCCESS) {
|
|
if (result == DNS_R_ALIAS) {
|
|
/*
|
|
@@ -2608,6 +2625,14 @@
|
|
|
|
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.
|
|
*/
|
|
@@ -3083,6 +3108,16 @@
|
|
}
|
|
}
|
|
|
|
+ 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__);
|
|
@@ -3181,6 +3216,7 @@
|
|
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);
|
|
@@ -3509,7 +3545,8 @@
|
|
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;
|
|
@@ -3531,6 +3568,21 @@
|
|
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_fetch;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * 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 */
|
|
@@ -3538,7 +3590,7 @@
|
|
fctx->info = isc_mem_strdup(mctx, buf);
|
|
if (fctx->info == NULL) {
|
|
result = ISC_R_NOMEMORY;
|
|
- goto cleanup_fetch;
|
|
+ goto cleanup_counter;
|
|
}
|
|
FCTXTRACE("create");
|
|
dns_name_init(&fctx->name, NULL);
|
|
@@ -3561,6 +3613,7 @@
|
|
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);
|
|
@@ -3766,6 +3819,9 @@
|
|
cleanup_info:
|
|
isc_mem_free(mctx, fctx->info);
|
|
|
|
+ cleanup_counter:
|
|
+ isc_counter_detach(&fctx->qc);
|
|
+
|
|
cleanup_fetch:
|
|
isc_mem_put(mctx, fctx, sizeof(*fctx));
|
|
|
|
@@ -5477,7 +5533,7 @@
|
|
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));
|
|
@@ -5486,7 +5542,7 @@
|
|
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) {
|
|
@@ -7528,6 +7584,8 @@
|
|
res->query_timeout = DEFAULT_QUERY_TIMEOUT;
|
|
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,
|
|
@@ -7967,9 +8025,9 @@
|
|
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));
|
|
}
|
|
|
|
@@ -7985,6 +8043,25 @@
|
|
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;
|
|
@@ -8071,11 +8148,12 @@
|
|
|
|
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);
|
|
@@ -8847,3 +8925,27 @@
|
|
|
|
resolver->query_timeout = seconds;
|
|
}
|
|
+
|
|
+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: contrib/bind9/lib/export/isc/Makefile.in
|
|
===================================================================
|
|
--- contrib/bind9/lib/export/isc/Makefile.in.orig
|
|
+++ contrib/bind9/lib/export/isc/Makefile.in
|
|
@@ -63,7 +63,7 @@
|
|
# 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 @@
|
|
|
|
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: contrib/bind9/lib/isc/Makefile.in
|
|
===================================================================
|
|
--- contrib/bind9/lib/isc/Makefile.in.orig
|
|
+++ contrib/bind9/lib/isc/Makefile.in
|
|
@@ -13,8 +13,6 @@
|
|
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
# PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
-# $Id$
|
|
-
|
|
srcdir = @srcdir@
|
|
VPATH = @srcdir@
|
|
top_srcdir = @top_srcdir@
|
|
@@ -53,7 +51,7 @@
|
|
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,8 +67,8 @@
|
|
# 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 \
|
|
- heap.c hex.c hmacmd5.c hmacsha.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 \
|
|
md5.c mem.c mutexblock.c \
|
|
Index: contrib/bind9/lib/isc/counter.c
|
|
===================================================================
|
|
--- contrib/bind9/lib/isc/counter.c.orig
|
|
+++ contrib/bind9/lib/isc/counter.c
|
|
@@ -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: contrib/bind9/lib/isc/include/isc/Makefile.in
|
|
===================================================================
|
|
--- contrib/bind9/lib/isc/include/isc/Makefile.in.orig
|
|
+++ contrib/bind9/lib/isc/include/isc/Makefile.in
|
|
@@ -13,8 +13,6 @@
|
|
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
# PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
-# $Id$
|
|
-
|
|
srcdir = @srcdir@
|
|
VPATH = @srcdir@
|
|
top_srcdir = @top_srcdir@
|
|
@@ -27,7 +25,8 @@
|
|
# 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: contrib/bind9/lib/isc/include/isc/counter.h
|
|
===================================================================
|
|
--- contrib/bind9/lib/isc/include/isc/counter.h.orig
|
|
+++ contrib/bind9/lib/isc/include/isc/counter.h
|
|
@@ -0,0 +1,90 @@
|
|
+/*
|
|
+ * 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 */
|
|
Index: contrib/bind9/lib/isc/include/isc/types.h
|
|
===================================================================
|
|
--- contrib/bind9/lib/isc/include/isc/types.h.orig
|
|
+++ contrib/bind9/lib/isc/include/isc/types.h
|
|
@@ -50,6 +50,7 @@
|
|
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: contrib/bind9/lib/isccfg/namedconf.c
|
|
===================================================================
|
|
--- contrib/bind9/lib/isccfg/namedconf.c.orig
|
|
+++ contrib/bind9/lib/isccfg/namedconf.c
|
|
@@ -15,8 +15,6 @@
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
-/* $Id$ */
|
|
-
|
|
/*! \file */
|
|
|
|
#include <config.h>
|
|
@@ -1348,6 +1346,8 @@
|
|
{ "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: lib/bind/isc/Makefile
|
|
===================================================================
|
|
--- lib/bind/isc/Makefile.orig
|
|
+++ lib/bind/isc/Makefile
|
|
@@ -28,7 +28,7 @@
|
|
.PATH: ${SRCDIR}
|
|
SRCS+= inet_pton.c \
|
|
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 \
|
|
fsaccess.c hash.c \
|
|
heap.c hex.c hmacmd5.c hmacsha.c \
|
|
httpd.c inet_aton.c \
|
|
@@ -65,6 +65,7 @@
|
|
${SRCDIR}/include/isc/buffer.h \
|
|
${SRCDIR}/include/isc/bufferlist.h \
|
|
${SRCDIR}/include/isc/commandline.h \
|
|
+ ${SRCDIR}/include/isc/counter.h \
|
|
${SRCDIR}/include/isc/entropy.h \
|
|
${SRCDIR}/include/isc/error.h \
|
|
${SRCDIR}/include/isc/event.h \
|