update unbound from upstream

This commit is contained in:
Riccardo Spagni 2014-12-04 23:10:49 +02:00
parent 9f74cc8e19
commit 831933425b
No known key found for this signature in database
GPG key ID: 55432DF31CCD4FCD
72 changed files with 1261 additions and 2655 deletions

View file

@ -80,7 +80,7 @@ LINTFLAGS+="-Dsigset_t=long"
# FreeBSD
LINTFLAGS+="-D__uint16_t=uint16_t" "-DEVP_PKEY_ASN1_METHOD=int" "-D_RuneLocale=int" "-D__va_list=va_list"
INSTALL=$(srcdir)/install-sh
INSTALL=$(SHELL) $(srcdir)/install-sh
#pythonmod.c is not here, it is mentioned by itself in its own rules,
#makedepend fails on missing interface.h otherwise.
@ -397,7 +397,7 @@ libunbound/python/libunbound_wrap.c: $(srcdir)/libunbound/python/libunbound.i un
# Pyunbound python unbound wrapper
_unbound.la: libunbound_wrap.lo libunbound.la
$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -version-info @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) L. -L.libs -lunbound $(LIBS)
$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -avoid-version -no-undefined -shared -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) L. -L.libs -lunbound
util/config_file.c: util/configparser.h
util/configlexer.c: $(srcdir)/util/configlexer.lex util/configparser.h

View file

@ -53,8 +53,10 @@ static int arc4lockinit = 0;
void _ARC4_LOCK(void)
{
if(!arc4lockinit)
if(!arc4lockinit) {
arc4lockinit = 1;
lock_quick_init(&arc4lock);
}
lock_quick_lock(&arc4lock);
}

View file

@ -48,6 +48,7 @@
#include <time.h>
#include <openssl/sha.h>
#include <linux/types.h>
#include <linux/random.h>
#include <linux/sysctl.h>
#ifdef HAVE_GETAUXVAL
@ -77,7 +78,7 @@ extern int main(int, char *argv[]);
#endif
static int gotdata(char *buf, size_t len);
static int getentropy_urandom(void *buf, size_t len);
#ifdef CTL_MAXNAME
#ifdef SYS__sysctl
static int getentropy_sysctl(void *buf, size_t len);
#endif
static int getentropy_fallback(void *buf, size_t len);
@ -102,7 +103,7 @@ getentropy(void *buf, size_t len)
if (ret != -1)
return (ret);
#ifdef CTL_MAXNAME
#ifdef SYS__sysctl
/*
* Try to use sysctl CTL_KERN, KERN_RANDOM, RANDOM_UUID.
* sysctl is a failsafe API, so it guarantees a result. This
@ -124,7 +125,7 @@ getentropy(void *buf, size_t len)
ret = getentropy_sysctl(buf, len);
if (ret != -1)
return (ret);
#endif /* CTL_MAXNAME */
#endif /* SYS__sysctl */
/*
* Entropy collection via /dev/urandom and sysctl have failed.
@ -235,7 +236,7 @@ nodevrandom:
return -1;
}
#ifdef CTL_MAXNAME
#ifdef SYS__sysctl
static int
getentropy_sysctl(void *buf, size_t len)
{
@ -265,7 +266,7 @@ sysctlfailed:
errno = EIO;
return -1;
}
#endif /* CTL_MAXNAME */
#endif /* SYS__sysctl */
static int cl[] = {
CLOCK_REALTIME,

View file

@ -41,9 +41,9 @@ getentropy(void *buf, size_t len)
}
if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT) != 0)
CRYPT_VERIFYCONTEXT) == 0)
goto fail;
if (CryptGenRandom(provider, len, buf) != 0) {
if (CryptGenRandom(provider, len, buf) == 0) {
CryptReleaseContext(provider, 0);
goto fail;
}

View file

@ -103,7 +103,7 @@ inet_aton(const char *cp, struct in_addr *addr)
* Values are specified as for C:
* 0x=hex, 0=octal, isdigit=decimal.
*/
if (!isdigit(c))
if (!isdigit((unsigned char)c))
return (0);
val = 0; base = 10;
if (c == '0') {
@ -114,12 +114,12 @@ inet_aton(const char *cp, struct in_addr *addr)
base = 8;
}
for (;;) {
if (isascii(c) && isdigit(c)) {
if (isascii((unsigned char)c) && isdigit((unsigned char)c)) {
val = (val * base) + (c - '0');
c = *++cp;
} else if (base == 16 && isascii(c) && isxdigit(c)) {
} else if (base == 16 && isascii((unsigned char)c) && isxdigit((unsigned char)c)) {
val = (val << 4) |
(c + 10 - (islower(c) ? 'a' : 'A'));
(c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
c = *++cp;
} else
break;
@ -141,7 +141,7 @@ inet_aton(const char *cp, struct in_addr *addr)
/*
* Check for trailing characters.
*/
if (c != '\0' && (!isascii(c) || !isspace(c)))
if (c != '\0' && (!isascii((unsigned char)c) || !isspace((unsigned char)c)))
return (0);
/*
* Concoct the address according to

View file

@ -28,7 +28,7 @@ void *memmove(void *dest, const void *src, size_t n)
to[i] = from[i];
return dest;
}
if (from > to && from-to < (int)n) {
if (from > to && from-to < (int)n) {
/* to overlaps with from */
/* <from......> */
/* <to........> */

View file

@ -89,7 +89,7 @@ str2int(const char **buf, int max)
{
int ret=0, count=0;
while (*buf[0] != '\0' && isdigit(*buf[0]) && count<max) {
while (*buf[0] != '\0' && isdigit((unsigned char)*buf[0]) && count<max) {
ret = ret*10 + (*buf[0] - '0');
(*buf)++;
count++;
@ -111,11 +111,11 @@ unbound_strptime(const char *s, const char *format, struct tm *tm)
while ((c = *format) != '\0') {
/* whitespace, literal or format */
if (isspace(c)) { /* whitespace */
if (isspace((unsigned char)c)) { /* whitespace */
/** whitespace matches zero or more whitespace characters in the
* input string.
**/
while (isspace(*s))
while (isspace((unsigned char)*s))
s++;
}
else if (c == '%') { /* format */
@ -221,7 +221,7 @@ unbound_strptime(const char *s, const char *format, struct tm *tm)
break;
case 'n': /* arbitrary whitespace */
case 't':
while (isspace(*s))
while (isspace((unsigned char)*s))
s++;
break;
case 'p': /* am pm */

View file

@ -1,8 +1,5 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* define if a library can reference the 'main' symbol */
#undef CAN_REFERENCE_MAIN
/* Directory to chroot to */
#undef CHROOT_DIR

File diff suppressed because it is too large Load diff

View file

@ -9,16 +9,16 @@ sinclude(dnstap/dnstap.m4)
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[4])
m4_define([VERSION_MICRO],[23])
m4_define([VERSION_MINOR],[5])
m4_define([VERSION_MICRO],[1])
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound)
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=4
LIBUNBOUND_CURRENT=5
LIBUNBOUND_REVISION=3
LIBUNBOUND_AGE=2
LIBUNBOUND_AGE=3
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
# 1.0.2 had 0:14:0
@ -56,7 +56,8 @@ LIBUNBOUND_AGE=2
# 1.4.20 had 4:0:2 # adds libunbound.ttl # but shipped 3:5:1
# 1.4.21 had 4:1:2
# 1.4.22 had 4:1:2
# 1.4.23 had 4:3:2
# 1.5.0 had 5:3:3 # adds ub_ctx_add_ta_autr
# 1.5.1 had 5:4:3
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@ -1022,39 +1023,6 @@ if test "$USE_NSS" = "no"; then
AC_SEARCH_LIBS([clock_gettime], [rt])
;;
esac
# generate libtool to test if linking main
# from a dynamic library works.
LT_OUTPUT
AC_MSG_CHECKING([if dynamic lib can refer to main])
cat >tmp.$$.def <<EOF
myfunc
EOF
cat >tmp.$$.c <<EOF
int myfunc(void);
extern int main(int, char *argv[]);
int myfunc(void)
{
return ((int)main) + 1;
}
EOF
mylibtool=./libtool
mylibdir=/usr/local/lib
myok=yes
$mylibtool --quiet --tag=CC --mode=compile $CC $CFLAGS -o tmp.$$.lo -c tmp.$$.c >/dev/null 2>&1
if test $? = 0; then myok=yes; else myok=no; fi
if test "$myok" = "yes"; then
$mylibtool --quiet --tag=CC --mode=link $CC $CFLAGS -version-info 1:0:0 -no-undefined -export-symbols tmp.$$.def -o libtmp$$.la tmp.$$.lo $LDFLAGS -rpath $mylibdir $LIBS >/dev/null 2>&1
if test $? = 0; then myok=yes; else myok=no; fi
fi
if test "$myok" = "yes"; then
AC_MSG_RESULT(yes)
AC_DEFINE(CAN_REFERENCE_MAIN, [1], [define if a library can reference the 'main' symbol])
else
AC_MSG_RESULT(no)
fi
$mylibtool --quiet --mode=clean rm -rf libtmp$$.la tmp.$$.lo
rm -f tmp.$$.def tmp.$$.c libtmp$$.la tmp.$$.lo tmp.$$.o
fi
])
fi
@ -1365,6 +1333,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
])
dnl if we build from source tree, the man pages need @date@ and @version@
dnl if this is a distro tarball, that was already done by makedist.sh
AC_SUBST(version, [VERSION_MAJOR.VERSION_MINOR.VERSION_MICRO])
AC_SUBST(date, [`date +'%b %e, %Y'`])
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h])
AC_CONFIG_HEADER([config.h])
AC_OUTPUT

View file

@ -25,4 +25,8 @@ distribution but may be helpful.
* unbound_cache.cmd: windows script to save and load the cache.
* warmup.sh: shell script to warm up DNS cache by your own MRU domains.
* warmup.cmd: windows script to warm up DNS cache by your own MRU domains.
* aaaa-filter-iterator.patch: adds config option aaaa-filter: yes that
works like the BIND feature (removes AAAA records unless AAAA-only domain).
Useful for certain 'broken IPv6 default route' scenarios.
Patch from Stephane Lapie for ASAHI Net.

View file

@ -0,0 +1,394 @@
--- unbound-1.4.17.orig/doc/unbound.conf.5.in
+++ unbound-1.4.17/doc/unbound.conf.5.in
@@ -519,6 +519,13 @@ authority servers and checks if the repl
Disabled by default.
This feature is an experimental implementation of draft dns\-0x20.
.TP
+.B aaaa\-filter: \fI<yes or no>
+Activate behavior similar to BIND's AAAA-filter.
+This forces the dropping of all AAAA records, unless in the case of
+explicit AAAA queries, when no A records have been confirmed.
+This also causes an additional A query to be sent for each AAAA query.
+This breaks DNSSEC!
+.TP
.B private\-address: \fI<IP address or subnet>
Give IPv4 of IPv6 addresses or classless subnets. These are addresses
on your private network, and are not allowed to be returned for public
--- unbound-1.4.17.orig/util/config_file.c
+++ unbound-1.4.17/util/config_file.c
@@ -160,6 +160,7 @@ config_create(void)
cfg->harden_below_nxdomain = 0;
cfg->harden_referral_path = 0;
cfg->use_caps_bits_for_id = 0;
+ cfg->aaaa_filter = 0; /* ASN: default is disabled */
cfg->private_address = NULL;
cfg->private_domain = NULL;
cfg->unwanted_threshold = 0;
--- unbound-1.4.17.orig/iterator/iter_scrub.c
+++ unbound-1.4.17/iterator/iter_scrub.c
@@ -580,6 +580,32 @@ static int sanitize_nsec_is_overreach(st
}
/**
+ * ASN: Lookup A records from rrset cache.
+ * @param qinfo: the question originally asked.
+ * @param env: module environment with config and cache.
+ * @param ie: iterator environment with private address data.
+ * @return 0 if no A record found, 1 if A record found.
+ */
+static int
+asn_lookup_a_record_from_cache(struct query_info* qinfo,
+ struct module_env* env, struct iter_env* ie)
+{
+ struct ub_packed_rrset_key* akey;
+
+ /* get cached A records for queried name */
+ akey = rrset_cache_lookup(env->rrset_cache, qinfo->qname,
+ qinfo->qname_len, LDNS_RR_TYPE_A, qinfo->qclass,
+ 0, *env->now, 0);
+ if(akey) { /* we had some. */
+ log_rrset_key(VERB_ALGO, "ASN-AAAA-filter: found A record",
+ akey);
+ lock_rw_unlock(&akey->entry.lock);
+ return 1;
+ }
+ return 0;
+}
+
+/**
* Given a response event, remove suspect RRsets from the response.
* "Suspect" rrsets are potentially poison. Note that this routine expects
* the response to be in a "normalized" state -- that is, all "irrelevant"
@@ -598,6 +625,7 @@ scrub_sanitize(ldns_buffer* pkt, struct
struct query_info* qinfo, uint8_t* zonename, struct module_env* env,
struct iter_env* ie)
{
+ int found_a_record = 0; /* ASN: do we have a A record? */
int del_addi = 0; /* if additional-holding rrsets are deleted, we
do not trust the normalized additional-A-AAAA any more */
struct rrset_parse* rrset, *prev;
@@ -633,6 +661,13 @@ scrub_sanitize(ldns_buffer* pkt, struct
rrset = rrset->rrset_all_next;
}
+ /* ASN: Locate any A record we can find */
+ if((ie->aaaa_filter) && (qinfo->qtype == LDNS_RR_TYPE_AAAA)) {
+ found_a_record = asn_lookup_a_record_from_cache(qinfo,
+ env, ie);
+ }
+ /* ASN: End of added code */
+
/* At this point, we brutally remove ALL rrsets that aren't
* children of the originating zone. The idea here is that,
* as far as we know, the server that we contacted is ONLY
@@ -644,6 +679,24 @@ scrub_sanitize(ldns_buffer* pkt, struct
rrset = msg->rrset_first;
while(rrset) {
+ /* ASN: For AAAA records only... */
+ if((ie->aaaa_filter) && (rrset->type == LDNS_RR_TYPE_AAAA)) {
+ /* ASN: If this is not a AAAA query, then remove AAAA
+ * records, no questions asked. If this IS a AAAA query
+ * then remove AAAA records if we have an A record.
+ * Otherwise, leave things be. */
+ if((qinfo->qtype != LDNS_RR_TYPE_AAAA) ||
+ (found_a_record)) {
+ remove_rrset("ASN-AAAA-filter: removing AAAA "
+ "for record", pkt, msg, prev, &rrset);
+ continue;
+ }
+ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: "
+ "keep AAAA for", zonename,
+ LDNS_RR_TYPE_AAAA, qinfo->qclass);
+ }
+ /* ASN: End of added code */
+
/* remove private addresses */
if( (rrset->type == LDNS_RR_TYPE_A ||
rrset->type == LDNS_RR_TYPE_AAAA) &&
--- unbound-1.4.17.orig/iterator/iterator.c
+++ unbound-1.4.17/iterator/iterator.c
@@ -1579,6 +1579,53 @@ processDSNSFind(struct module_qstate* qs
return 0;
}
+
+/**
+ * ASN: This event state was added as an intermediary step between
+ * QUERYTARGETS_STATE and the next step, in order to cast a subquery for the
+ * purpose of caching A records for the queried name.
+ *
+ * @param qstate: query state.
+ * @param iq: iterator query state.
+ * @param ie: iterator shared global environment.
+ * @param id: module id.
+ * @return true if the event requires more request processing immediately,
+ * false if not. This state only returns true when it is generating
+ * a SERVFAIL response because the query has hit a dead end.
+ */
+static int
+asn_processQueryAAAA(struct module_qstate* qstate, struct iter_qstate* iq,
+ struct iter_env* ie, int id)
+{
+ struct module_qstate* subq = NULL;
+
+ log_assert(iq->fetch_a_for_aaaa == 0);
+
+ /* flag the query properly in order to not loop */
+ iq->fetch_a_for_aaaa = 1;
+
+ /* re-throw same query, but with a different type */
+ if(!generate_sub_request(iq->qchase.qname,
+ iq->qchase.qname_len, LDNS_RR_TYPE_A,
+ iq->qchase.qclass, qstate, id, iq,
+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
+ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: failed "
+ "preloading of A record for",
+ iq->qchase.qname, LDNS_RR_TYPE_A,
+ iq->qchase.qclass);
+ return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
+ }
+ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: "
+ "preloading records in cache for",
+ iq->qchase.qname, LDNS_RR_TYPE_A,
+ iq->qchase.qclass);
+
+ /* set this query as waiting */
+ qstate->ext_state[id] = module_wait_subquery;
+ /* at this point break loop */
+ return 0;
+}
+/* ASN: End of added code */
/**
* This is the request event state where the request will be sent to one of
@@ -1626,6 +1673,13 @@ processQueryTargets(struct module_qstate
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
+ /* ASN: If we have a AAAA query, then also query for A records */
+ if((ie->aaaa_filter) && (iq->qchase.qtype == LDNS_RR_TYPE_AAAA) &&
+ (iq->fetch_a_for_aaaa == 0)) {
+ return next_state(iq, ASN_FETCH_A_FOR_AAAA_STATE);
+ }
+ /* ASN: End of added code */
+
/* Make sure we have a delegation point, otherwise priming failed
* or another failure occurred */
if(!iq->dp) {
@@ -2568,6 +2622,62 @@ processFinished(struct module_qstate* qs
return 0;
}
+/**
+ * ASN: Do final processing on responses to A queries originated from AAAA
+ * queries. Events reach this state after the iterative resolution algorithm
+ * terminates.
+ * This is required down the road to decide whether to scrub AAAA records
+ * from the results or not.
+ *
+ * @param qstate: query state.
+ * @param id: module id.
+ * @param forq: super query state.
+ */
+static void
+asn_processAAAAResponse(struct module_qstate* qstate, int id,
+ struct module_qstate* super)
+{
+ struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id];
+ struct iter_qstate* super_iq = (struct iter_qstate*)super->minfo[id];
+ struct ub_packed_rrset_key* rrset;
+ struct delegpt_ns* dpns = NULL;
+ int error = (qstate->return_rcode != LDNS_RCODE_NOERROR);
+
+ log_assert(super_iq->fetch_a_for_aaaa > 0);
+
+ /* let super go to evaluation of targets after this */
+ super_iq->state = QUERYTARGETS_STATE;
+
+ log_query_info(VERB_ALGO, "ASN-AAAA-filter: processAAAAResponse",
+ &qstate->qinfo);
+ log_query_info(VERB_ALGO, "ASN-AAAA-filter: processAAAAResponse super",
+ &super->qinfo);
+
+ if(super_iq->dp)
+ dpns = delegpt_find_ns(super_iq->dp,
+ qstate->qinfo.qname, qstate->qinfo.qname_len);
+ if (!dpns) {
+ /* not interested */
+ verbose(VERB_ALGO, "ASN-AAAA-filter: subq: %s, but parent not "
+ "interested%s", (error ? "error, but" : "success"),
+ (super_iq->dp ? "anymore" : " (was reset)"));
+ log_query_info(VERB_ALGO, "ASN-AAAA-filter: superq", &super->qinfo);
+ if(super_iq->dp && error)
+ delegpt_log(VERB_ALGO, super_iq->dp);
+ return;
+ } else if (error) {
+ verbose(VERB_ALGO, "ASN-AAAA-filter: mark as failed, "
+ "and go to target query.");
+ /* see if the failure did get (parent-lame) info */
+ if(!cache_fill_missing(super->env,
+ super_iq->qchase.qclass, super->region,
+ super_iq->dp))
+ log_err("ASN-AAAA-filter: out of memory adding missing");
+ dpns->resolved = 1; /* mark as failed */
+ }
+}
+/* ASN: End of added code */
+
/*
* Return priming query results to interestes super querystates.
*
@@ -2587,6 +2697,9 @@ iter_inform_super(struct module_qstate*
else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*)
super->minfo[id])->state == DSNS_FIND_STATE)
processDSNSResponse(qstate, id, super);
+ else if (super->qinfo.qtype == LDNS_RR_TYPE_AAAA && ((struct iter_qstate*)
+ super->minfo[id])->state == ASN_FETCH_A_FOR_AAAA_STATE)
+ asn_processAAAAResponse(qstate, id, super);
else if(qstate->return_rcode != LDNS_RCODE_NOERROR)
error_supers(qstate, id, super);
else if(qstate->is_priming)
@@ -2624,6 +2737,9 @@ iter_handle(struct module_qstate* qstate
case INIT_REQUEST_3_STATE:
cont = processInitRequest3(qstate, iq, id);
break;
+ case ASN_FETCH_A_FOR_AAAA_STATE:
+ cont = asn_processQueryAAAA(qstate, iq, ie, id);
+ break;
case QUERYTARGETS_STATE:
cont = processQueryTargets(qstate, iq, ie, id);
break;
@@ -2863,6 +2979,8 @@ iter_state_to_string(enum iter_state sta
return "INIT REQUEST STATE (stage 2)";
case INIT_REQUEST_3_STATE:
return "INIT REQUEST STATE (stage 3)";
+ case ASN_FETCH_A_FOR_AAAA_STATE:
+ return "ASN_FETCH_A_FOR_AAAA_STATE";
case QUERYTARGETS_STATE :
return "QUERY TARGETS STATE";
case PRIME_RESP_STATE :
@@ -2887,6 +3005,7 @@ iter_state_is_responsestate(enum iter_st
case INIT_REQUEST_STATE :
case INIT_REQUEST_2_STATE :
case INIT_REQUEST_3_STATE :
+ case ASN_FETCH_A_FOR_AAAA_STATE :
case QUERYTARGETS_STATE :
case COLLECT_CLASS_STATE :
return 0;
--- unbound-1.4.17.orig/iterator/iter_utils.c
+++ unbound-1.4.17/iterator/iter_utils.c
@@ -128,6 +128,7 @@ iter_apply_cfg(struct iter_env* iter_env
}
iter_env->supports_ipv6 = cfg->do_ip6;
iter_env->supports_ipv4 = cfg->do_ip4;
+ iter_env->aaaa_filter = cfg->aaaa_filter;
return 1;
}
--- unbound-1.4.17.orig/iterator/iterator.h
+++ unbound-1.4.17/iterator/iterator.h
@@ -110,6 +110,9 @@ struct iter_env {
* array of max_dependency_depth+1 size.
*/
int* target_fetch_policy;
+
+ /** ASN: AAAA-filter flag */
+ int aaaa_filter;
};
/**
@@ -135,6 +138,14 @@ enum iter_state {
INIT_REQUEST_3_STATE,
/**
+ * This state is responsible for intercepting AAAA queries,
+ * and launch a A subquery on the same target, to populate the
+ * cache with A records, so the AAAA filter scrubbing logic can
+ * work.
+ */
+ ASN_FETCH_A_FOR_AAAA_STATE,
+
+ /**
* Each time a delegation point changes for a given query or a
* query times out and/or wakes up, this state is (re)visited.
* This state is reponsible for iterating through a list of
@@ -309,6 +320,13 @@ struct iter_qstate {
*/
int refetch_glue;
+ /**
+ * ASN: This is a flag that, if true, means that this query is
+ * for fetching A records to populate cache and determine if we must
+ * return AAAA records or not.
+ */
+ int fetch_a_for_aaaa;
+
/** list of pending queries to authoritative servers. */
struct outbound_list outlist;
};
--- unbound-1.4.17.orig/util/config_file.h
+++ unbound-1.4.17/util/config_file.h
@@ -169,6 +169,8 @@ struct config_file {
int harden_referral_path;
/** use 0x20 bits in query as random ID bits */
int use_caps_bits_for_id;
+ /** ASN: enable AAAA filter? */
+ int aaaa_filter;
/** strip away these private addrs from answers, no DNS Rebinding */
struct config_strlist* private_address;
/** allow domain (and subdomains) to use private address space */
--- unbound-1.4.17.orig/util/configlexer.lex
+++ unbound-1.4.17/util/configlexer.lex
@@ -177,6 +177,7 @@ harden-below-nxdomain{COLON} { YDVAR(1,
harden-referral-path{COLON} { YDVAR(1, VAR_HARDEN_REFERRAL_PATH) }
use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) }
+aaaa-filter{COLON} { YDVAR(1, VAR_AAAA_FILTER) }
private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) }
private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) }
prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) }
--- unbound-1.4.17.orig/util/configparser.y
+++ unbound-1.4.17/util/configparser.y
@@ -92,6 +92,7 @@ extern struct config_parser_state* cfg_p
%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
%token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR
%token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS
+%token VAR_AAAA_FILTER
%token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
%token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
@@ -151,6 +152,7 @@ content_server: server_num_threads | ser
server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
server_harden_referral_path | server_private_address |
server_private_domain | server_extended_statistics |
+ server_aaaa_filter |
server_local_data_ptr | server_jostle_timeout |
server_unwanted_reply_threshold | server_log_time_ascii |
server_domain_insecure | server_val_sig_skew_min |
@@ -802,6 +803,15 @@ server_use_caps_for_id: VAR_USE_CAPS_FOR
free($2);
}
;
+server_aaaa_filter: VAR_AAAA_FILTER STRING_ARG
+ {
+ OUTYY(("P(server_aaaa_filter:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->aaaa_filter = (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG
{
OUTYY(("P(server_private_address:%s)\n", $2));
--- unbound-1.4.17.orig/pythonmod/interface.i
+++ unbound-1.4.17/pythonmod/interface.i
@@ -626,6 +626,7 @@ struct config_file {
int harden_dnssec_stripped;
int harden_referral_path;
int use_caps_bits_for_id;
+ int aaaa_filter; /* ASN */
struct config_strlist* private_address;
struct config_strlist* private_domain;
size_t unwanted_threshold;

View file

@ -664,7 +664,7 @@ load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
if(!go_on)
return 1; /* skip this one, not all references satisfied */
if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL)) {
if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL, flags)) {
log_warn("error out of memory");
return 0;
}

View file

@ -38,8 +38,8 @@
*
* This file contains the remote control functionality for the daemon.
* The remote control can be performed using either the commandline
* unbound-control tool, or a SSLv3/TLS capable web browser.
* The channel is secured using SSLv3 or TLSv1, and certificates.
* unbound-control tool, or a TLS capable web browser.
* The channel is secured using TLSv1, and certificates.
* Both the server and the client(control tool) have their own keys.
*/
#include "config.h"
@ -154,12 +154,17 @@ daemon_remote_create(struct config_file* cfg)
free(rc);
return NULL;
}
/* no SSLv2 because has defects */
/* no SSLv2, SSLv3 because has defects */
if(!(SSL_CTX_set_options(rc->ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)){
log_crypto_err("could not set SSL_OP_NO_SSLv2");
daemon_remote_delete(rc);
return NULL;
}
if(!(SSL_CTX_set_options(rc->ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)){
log_crypto_err("could not set SSL_OP_NO_SSLv3");
daemon_remote_delete(rc);
return NULL;
}
s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
s_key = fname_after_chroot(cfg->server_key_file, cfg, 1);
if(!s_cert || !s_key) {
@ -558,7 +563,7 @@ static char*
skipwhite(char* str)
{
/* EOS \0 is not a space */
while( isspace(*str) )
while( isspace((unsigned char)*str) )
str++;
return str;
}
@ -849,7 +854,8 @@ print_ext(SSL* ssl, struct stats_info* s)
/* RCODE */
for(i=0; i<STATS_RCODE_NUM; i++) {
if(inhibit_zero && s->svr.ans_rcode[i] == 0)
/* Always include RCODEs 0-5 */
if(inhibit_zero && i > LDNS_RCODE_REFUSED && s->svr.ans_rcode[i] == 0)
continue;
lt = sldns_lookup_by_id(sldns_rcodes, i);
if(lt && lt->name) {
@ -1089,8 +1095,13 @@ do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen,
k.qname_len = nmlen;
k.qtype = t;
k.qclass = c;
h = query_info_hash(&k);
h = query_info_hash(&k, 0);
slabhash_remove(worker->env.msg_cache, h, &k);
if(t == LDNS_RR_TYPE_AAAA) {
/* for AAAA also flush dns64 bit_cd packet */
h = query_info_hash(&k, BIT_CD);
slabhash_remove(worker->env.msg_cache, h, &k);
}
}
/** flush a type */

View file

@ -287,7 +287,7 @@ checkrlimits(struct config_file* cfg)
#ifdef HAVE_SETRLIMIT
}
#endif
log_warn("increased limit(open files) from %u to %u",
verbose(VERB_ALGO, "increased limit(open files) from %u to %u",
(unsigned)avail, (unsigned)total+10);
}
#else

View file

@ -935,7 +935,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
&repinfo->addr, repinfo->addrlen);
goto send_reply;
}
h = query_info_hash(&qinfo);
h = query_info_hash(&qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) {
/* answer from cache - we have acquired a readlock on it */
if(answer_from_cache(worker, &qinfo,

View file

@ -399,7 +399,7 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id)
/* Create the new sub-query. */
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0,
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0, 0,
&subq))
return module_error;
if (subq) {
@ -451,7 +451,7 @@ generate_type_A_query(struct module_qstate* qstate, int id)
/* Start the sub-query. */
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0,
&subq))
0, &subq))
{
verbose(VERB_ALGO, "dns64: sub-query creation failed");
return module_error;
@ -520,11 +520,13 @@ handle_event_moddone(struct module_qstate* qstate, int id)
*
* - An internal query.
* - A query for a record type other than AAAA.
* - CD FLAG was set on querier
* - An AAAA query for which an error was returned.
* - A successful AAAA query with an answer.
*/
if ( (enum dns64_qstate)qstate->minfo[id] == DNS64_INTERNAL_QUERY
|| qstate->qinfo.qtype != LDNS_RR_TYPE_AAAA
|| (qstate->query_flags & BIT_CD)
|| qstate->return_rcode != LDNS_RCODE_NOERROR
|| (qstate->return_msg &&
qstate->return_msg->rep &&
@ -813,7 +815,7 @@ dns64_inform_super(struct module_qstate* qstate, int id,
/* Store the generated response in cache. */
if (!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
0, 0, 0, NULL))
0, 0, 0, NULL, super->query_flags))
log_err("out of memory");
}

View file

@ -37,6 +37,7 @@
#ifdef USE_DNSTAP
#include "config.h"
#include <string.h>
#include <sys/time.h>
#include "ldns/sbuffer.h"
#include "util/config_file.h"
@ -65,6 +66,7 @@ dt_pack(const Dnstap__Dnstap *d, void **buf, size_t *sz)
{
ProtobufCBufferSimple sbuf;
memset(&sbuf, 0, sizeof(sbuf));
sbuf.base.append = protobuf_c_buffer_simple_append;
sbuf.len = 0;
sbuf.alloced = DNSTAP_INITIAL_BUF_SIZE;
@ -87,9 +89,9 @@ dt_send(const struct dt_env *env, void *buf, size_t len_buf)
fstrm_res res;
if (!buf)
return;
res = fstrm_io_submit(env->fio, env->fq, buf, len_buf,
fstrm_free_wrapper, NULL);
if (res != FSTRM_RES_SUCCESS)
res = fstrm_iothr_submit(env->iothr, env->ioq, buf, len_buf,
fstrm_free_wrapper, NULL);
if (res != fstrm_res_success)
free(buf);
}
@ -119,10 +121,12 @@ dt_msg_init(const struct dt_env *env,
struct dt_env *
dt_create(const char *socket_path, unsigned num_workers)
{
char *fio_err;
fstrm_res res;
struct dt_env *env;
struct fstrm_io_options *fopt;
struct fstrm_iothr_options *fopt;
struct fstrm_unix_writer_options *fuwopt;
struct fstrm_writer *fw;
struct fstrm_writer_options *fwopt;
verbose(VERB_OPS, "opening dnstap socket %s", socket_path);
log_assert(socket_path != NULL);
@ -132,24 +136,29 @@ dt_create(const char *socket_path, unsigned num_workers)
if (!env)
return NULL;
fwopt = fstrm_writer_options_init();
res = fstrm_writer_options_add_content_type(fwopt,
DNSTAP_CONTENT_TYPE, sizeof(DNSTAP_CONTENT_TYPE) - 1);
log_assert(res == fstrm_res_success);
fuwopt = fstrm_unix_writer_options_init();
fstrm_unix_writer_options_set_socket_path(fuwopt, socket_path);
fopt = fstrm_io_options_init();
fstrm_io_options_set_content_type(fopt,
DNSTAP_CONTENT_TYPE,
sizeof(DNSTAP_CONTENT_TYPE) - 1);
fstrm_io_options_set_num_queues(fopt, num_workers);
fstrm_io_options_set_writer(fopt, fstrm_unix_writer, fuwopt);
env->fio = fstrm_io_init(fopt, &fio_err);
if (env->fio == NULL) {
verbose(VERB_DETAIL, "dt_create: fstrm_io_init() failed: %s",
fio_err);
free(fio_err);
fw = fstrm_unix_writer_init(fuwopt, fwopt);
log_assert(fw != NULL);
fopt = fstrm_iothr_options_init();
fstrm_iothr_options_set_num_input_queues(fopt, num_workers);
env->iothr = fstrm_iothr_init(fopt, &fw);
if (env->iothr == NULL) {
verbose(VERB_DETAIL, "dt_create: fstrm_iothr_init() failed");
fstrm_writer_destroy(&fw);
free(env);
env = NULL;
}
fstrm_io_options_destroy(&fopt);
fstrm_iothr_options_destroy(&fopt);
fstrm_unix_writer_options_destroy(&fuwopt);
fstrm_writer_options_destroy(&fwopt);
return env;
}
@ -238,8 +247,8 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
int
dt_init(struct dt_env *env)
{
env->fq = fstrm_io_get_queue(env->fio);
if (env->fq == NULL)
env->ioq = fstrm_iothr_get_input_queue(env->iothr);
if (env->ioq == NULL)
return 0;
return 1;
}
@ -250,7 +259,7 @@ dt_delete(struct dt_env *env)
if (!env)
return;
verbose(VERB_OPS, "closing dnstap socket");
fstrm_io_destroy(&env->fio);
fstrm_iothr_destroy(&env->iothr);
free(env->identity);
free(env->version);
free(env);

View file

@ -45,11 +45,11 @@ struct fstrm_queue;
struct sldns_buffer;
struct dt_env {
/** dnstap I/O socket */
struct fstrm_io *fio;
/** dnstap I/O thread */
struct fstrm_iothr *iothr;
/** dnstap I/O queue */
struct fstrm_queue *fq;
/** dnstap I/O thread input queue */
struct fstrm_iothr_queue *ioq;
/** dnstap "identity" field, NULL if disabled */
char *identity;

View file

@ -22,7 +22,7 @@ AC_DEFUN([dt_DNSTAP],
fi
AC_ARG_WITH([protobuf-c], AC_HELP_STRING([--with-protobuf-c=path],
[Path where protobuf-c is installed, for dnstap]), [
# workaround for protobuf includes at old dir before protobuf-1.0.0
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f $withval/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I$withval/include/google"
else
@ -30,7 +30,7 @@ AC_DEFUN([dt_DNSTAP],
fi
LDFLAGS="$LDFLAGS -L$withval/lib"
], [
# workaround for protobuf includes at old dir before protobuf-1.0.0
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/include/google"
else
@ -41,12 +41,14 @@ AC_DEFUN([dt_DNSTAP],
fi
])
AC_ARG_WITH([libfstrm], AC_HELP_STRING([--with-libfstrm=path],
[Path where libfstrm in installed, for dnstap]), [
[Path where libfstrm is installed, for dnstap]), [
CFLAGS="$CFLAGS -I$withval/include"
LDFLAGS="$LDFLAGS -L$withval/lib"
])
AC_SEARCH_LIBS([fstrm_io_init], [fstrm])
AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c])
AC_SEARCH_LIBS([fstrm_iothr_init], [fstrm], [],
AC_MSG_ERROR([The fstrm library was not found. Please install fstrm!]))
AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c], [],
AC_MSG_ERROR([The protobuf-c library was not found. Please install protobuf-c!]))
$2
else
$3

View file

@ -1,518 +0,0 @@
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
/* Do not generate deprecated warnings for self */
#ifndef PROTOBUF_C_NO_DEPRECATED
#define PROTOBUF_C_NO_DEPRECATED
#endif
#include "dnstap/dnstap.pb-c.h"
void dnstap__dnstap__init
(Dnstap__Dnstap *message)
{
static Dnstap__Dnstap init_value = DNSTAP__DNSTAP__INIT;
*message = init_value;
}
size_t dnstap__dnstap__get_packed_size
(const Dnstap__Dnstap *message)
{
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__dnstap__descriptor);
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
}
size_t dnstap__dnstap__pack
(const Dnstap__Dnstap *message,
uint8_t *out)
{
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__dnstap__descriptor);
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
}
size_t dnstap__dnstap__pack_to_buffer
(const Dnstap__Dnstap *message,
ProtobufCBuffer *buffer)
{
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__dnstap__descriptor);
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
}
Dnstap__Dnstap *
dnstap__dnstap__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data)
{
return (Dnstap__Dnstap *)
protobuf_c_message_unpack (&dnstap__dnstap__descriptor,
allocator, len, data);
}
void dnstap__dnstap__free_unpacked
(Dnstap__Dnstap *message,
ProtobufCAllocator *allocator)
{
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__dnstap__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
void dnstap__message__init
(Dnstap__Message *message)
{
static Dnstap__Message init_value = DNSTAP__MESSAGE__INIT;
*message = init_value;
}
size_t dnstap__message__get_packed_size
(const Dnstap__Message *message)
{
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__message__descriptor);
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
}
size_t dnstap__message__pack
(const Dnstap__Message *message,
uint8_t *out)
{
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__message__descriptor);
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
}
size_t dnstap__message__pack_to_buffer
(const Dnstap__Message *message,
ProtobufCBuffer *buffer)
{
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__message__descriptor);
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
}
Dnstap__Message *
dnstap__message__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data)
{
return (Dnstap__Message *)
protobuf_c_message_unpack (&dnstap__message__descriptor,
allocator, len, data);
}
void dnstap__message__free_unpacked
(Dnstap__Message *message,
ProtobufCAllocator *allocator)
{
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__message__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
const ProtobufCEnumValue dnstap__dnstap__type__enum_values_by_number[1] =
{
{ "MESSAGE", "DNSTAP__DNSTAP__TYPE__MESSAGE", 1 },
};
static const ProtobufCIntRange dnstap__dnstap__type__value_ranges[] = {
{1, 0},{0, 1}
};
const ProtobufCEnumValueIndex dnstap__dnstap__type__enum_values_by_name[1] =
{
{ "MESSAGE", 0 },
};
const ProtobufCEnumDescriptor dnstap__dnstap__type__descriptor =
{
PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC,
"dnstap.Dnstap.Type",
"Type",
"Dnstap__Dnstap__Type",
"dnstap",
1,
dnstap__dnstap__type__enum_values_by_number,
1,
dnstap__dnstap__type__enum_values_by_name,
1,
dnstap__dnstap__type__value_ranges,
NULL,NULL,NULL,NULL /* reserved[1234] */
};
static const ProtobufCFieldDescriptor dnstap__dnstap__field_descriptors[5] =
{
{
"identity",
1,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_BYTES,
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, has_identity),
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, identity),
NULL,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"version",
2,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_BYTES,
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, has_version),
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, version),
NULL,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"extra",
3,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_BYTES,
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, has_extra),
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, extra),
NULL,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"message",
14,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_MESSAGE,
0, /* quantifier_offset */
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, message),
&dnstap__message__descriptor,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"type",
15,
PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_ENUM,
0, /* quantifier_offset */
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, type),
&dnstap__dnstap__type__descriptor,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
};
static const unsigned dnstap__dnstap__field_indices_by_name[] = {
2, /* field[2] = extra */
0, /* field[0] = identity */
3, /* field[3] = message */
4, /* field[4] = type */
1, /* field[1] = version */
};
static const ProtobufCIntRange dnstap__dnstap__number_ranges[2 + 1] =
{
{ 1, 0 },
{ 14, 3 },
{ 0, 5 }
};
const ProtobufCMessageDescriptor dnstap__dnstap__descriptor =
{
PROTOBUF_C_MESSAGE_DESCRIPTOR_MAGIC,
"dnstap.Dnstap",
"Dnstap",
"Dnstap__Dnstap",
"dnstap",
sizeof(Dnstap__Dnstap),
5,
dnstap__dnstap__field_descriptors,
dnstap__dnstap__field_indices_by_name,
2, dnstap__dnstap__number_ranges,
(ProtobufCMessageInit) dnstap__dnstap__init,
NULL,NULL,NULL /* reserved[123] */
};
const ProtobufCEnumValue dnstap__message__type__enum_values_by_number[10] =
{
{ "AUTH_QUERY", "DNSTAP__MESSAGE__TYPE__AUTH_QUERY", 1 },
{ "AUTH_RESPONSE", "DNSTAP__MESSAGE__TYPE__AUTH_RESPONSE", 2 },
{ "RESOLVER_QUERY", "DNSTAP__MESSAGE__TYPE__RESOLVER_QUERY", 3 },
{ "RESOLVER_RESPONSE", "DNSTAP__MESSAGE__TYPE__RESOLVER_RESPONSE", 4 },
{ "CLIENT_QUERY", "DNSTAP__MESSAGE__TYPE__CLIENT_QUERY", 5 },
{ "CLIENT_RESPONSE", "DNSTAP__MESSAGE__TYPE__CLIENT_RESPONSE", 6 },
{ "FORWARDER_QUERY", "DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY", 7 },
{ "FORWARDER_RESPONSE", "DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE", 8 },
{ "STUB_QUERY", "DNSTAP__MESSAGE__TYPE__STUB_QUERY", 9 },
{ "STUB_RESPONSE", "DNSTAP__MESSAGE__TYPE__STUB_RESPONSE", 10 },
};
static const ProtobufCIntRange dnstap__message__type__value_ranges[] = {
{1, 0},{0, 10}
};
const ProtobufCEnumValueIndex dnstap__message__type__enum_values_by_name[10] =
{
{ "AUTH_QUERY", 0 },
{ "AUTH_RESPONSE", 1 },
{ "CLIENT_QUERY", 4 },
{ "CLIENT_RESPONSE", 5 },
{ "FORWARDER_QUERY", 6 },
{ "FORWARDER_RESPONSE", 7 },
{ "RESOLVER_QUERY", 2 },
{ "RESOLVER_RESPONSE", 3 },
{ "STUB_QUERY", 8 },
{ "STUB_RESPONSE", 9 },
};
const ProtobufCEnumDescriptor dnstap__message__type__descriptor =
{
PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC,
"dnstap.Message.Type",
"Type",
"Dnstap__Message__Type",
"dnstap",
10,
dnstap__message__type__enum_values_by_number,
10,
dnstap__message__type__enum_values_by_name,
1,
dnstap__message__type__value_ranges,
NULL,NULL,NULL,NULL /* reserved[1234] */
};
static const ProtobufCFieldDescriptor dnstap__message__field_descriptors[14] =
{
{
"type",
1,
PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_ENUM,
0, /* quantifier_offset */
PROTOBUF_C_OFFSETOF(Dnstap__Message, type),
&dnstap__message__type__descriptor,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"socket_family",
2,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_ENUM,
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_socket_family),
PROTOBUF_C_OFFSETOF(Dnstap__Message, socket_family),
&dnstap__socket_family__descriptor,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"socket_protocol",
3,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_ENUM,
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_socket_protocol),
PROTOBUF_C_OFFSETOF(Dnstap__Message, socket_protocol),
&dnstap__socket_protocol__descriptor,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"query_address",
4,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_BYTES,
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_address),
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_address),
NULL,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"response_address",
5,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_BYTES,
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_address),
PROTOBUF_C_OFFSETOF(Dnstap__Message, response_address),
NULL,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"query_port",
6,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_UINT32,
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_port),
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_port),
NULL,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"response_port",
7,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_UINT32,
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_port),
PROTOBUF_C_OFFSETOF(Dnstap__Message, response_port),
NULL,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"query_time_sec",
8,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_UINT64,
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_time_sec),
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_time_sec),
NULL,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"query_time_nsec",
9,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_FIXED32,
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_time_nsec),
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_time_nsec),
NULL,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"query_message",
10,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_BYTES,
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_message),
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_message),
NULL,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"query_zone",
11,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_BYTES,
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_zone),
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_zone),
NULL,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"response_time_sec",
12,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_UINT64,
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_time_sec),
PROTOBUF_C_OFFSETOF(Dnstap__Message, response_time_sec),
NULL,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"response_time_nsec",
13,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_FIXED32,
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_time_nsec),
PROTOBUF_C_OFFSETOF(Dnstap__Message, response_time_nsec),
NULL,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"response_message",
14,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_BYTES,
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_message),
PROTOBUF_C_OFFSETOF(Dnstap__Message, response_message),
NULL,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
};
static const unsigned dnstap__message__field_indices_by_name[] = {
3, /* field[3] = query_address */
9, /* field[9] = query_message */
5, /* field[5] = query_port */
8, /* field[8] = query_time_nsec */
7, /* field[7] = query_time_sec */
10, /* field[10] = query_zone */
4, /* field[4] = response_address */
13, /* field[13] = response_message */
6, /* field[6] = response_port */
12, /* field[12] = response_time_nsec */
11, /* field[11] = response_time_sec */
1, /* field[1] = socket_family */
2, /* field[2] = socket_protocol */
0, /* field[0] = type */
};
static const ProtobufCIntRange dnstap__message__number_ranges[1 + 1] =
{
{ 1, 0 },
{ 0, 14 }
};
const ProtobufCMessageDescriptor dnstap__message__descriptor =
{
PROTOBUF_C_MESSAGE_DESCRIPTOR_MAGIC,
"dnstap.Message",
"Message",
"Dnstap__Message",
"dnstap",
sizeof(Dnstap__Message),
14,
dnstap__message__field_descriptors,
dnstap__message__field_indices_by_name,
1, dnstap__message__number_ranges,
(ProtobufCMessageInit) dnstap__message__init,
NULL,NULL,NULL /* reserved[123] */
};
const ProtobufCEnumValue dnstap__socket_family__enum_values_by_number[2] =
{
{ "INET", "DNSTAP__SOCKET_FAMILY__INET", 1 },
{ "INET6", "DNSTAP__SOCKET_FAMILY__INET6", 2 },
};
static const ProtobufCIntRange dnstap__socket_family__value_ranges[] = {
{1, 0},{0, 2}
};
const ProtobufCEnumValueIndex dnstap__socket_family__enum_values_by_name[2] =
{
{ "INET", 0 },
{ "INET6", 1 },
};
const ProtobufCEnumDescriptor dnstap__socket_family__descriptor =
{
PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC,
"dnstap.SocketFamily",
"SocketFamily",
"Dnstap__SocketFamily",
"dnstap",
2,
dnstap__socket_family__enum_values_by_number,
2,
dnstap__socket_family__enum_values_by_name,
1,
dnstap__socket_family__value_ranges,
NULL,NULL,NULL,NULL /* reserved[1234] */
};
const ProtobufCEnumValue dnstap__socket_protocol__enum_values_by_number[2] =
{
{ "UDP", "DNSTAP__SOCKET_PROTOCOL__UDP", 1 },
{ "TCP", "DNSTAP__SOCKET_PROTOCOL__TCP", 2 },
};
static const ProtobufCIntRange dnstap__socket_protocol__value_ranges[] = {
{1, 0},{0, 2}
};
const ProtobufCEnumValueIndex dnstap__socket_protocol__enum_values_by_name[2] =
{
{ "TCP", 1 },
{ "UDP", 0 },
};
const ProtobufCEnumDescriptor dnstap__socket_protocol__descriptor =
{
PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC,
"dnstap.SocketProtocol",
"SocketProtocol",
"Dnstap__SocketProtocol",
"dnstap",
2,
dnstap__socket_protocol__enum_values_by_number,
2,
dnstap__socket_protocol__enum_values_by_name,
1,
dnstap__socket_protocol__value_ranges,
NULL,NULL,NULL,NULL /* reserved[1234] */
};

View file

@ -1,158 +0,0 @@
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
#ifndef PROTOBUF_C_dnstap_2fdnstap_2eproto__INCLUDED
#define PROTOBUF_C_dnstap_2fdnstap_2eproto__INCLUDED
#include <google/protobuf-c/protobuf-c.h>
PROTOBUF_C_BEGIN_DECLS
typedef struct _Dnstap__Dnstap Dnstap__Dnstap;
typedef struct _Dnstap__Message Dnstap__Message;
/* --- enums --- */
typedef enum _Dnstap__Dnstap__Type {
DNSTAP__DNSTAP__TYPE__MESSAGE = 1
} Dnstap__Dnstap__Type;
typedef enum _Dnstap__Message__Type {
DNSTAP__MESSAGE__TYPE__AUTH_QUERY = 1,
DNSTAP__MESSAGE__TYPE__AUTH_RESPONSE = 2,
DNSTAP__MESSAGE__TYPE__RESOLVER_QUERY = 3,
DNSTAP__MESSAGE__TYPE__RESOLVER_RESPONSE = 4,
DNSTAP__MESSAGE__TYPE__CLIENT_QUERY = 5,
DNSTAP__MESSAGE__TYPE__CLIENT_RESPONSE = 6,
DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY = 7,
DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE = 8,
DNSTAP__MESSAGE__TYPE__STUB_QUERY = 9,
DNSTAP__MESSAGE__TYPE__STUB_RESPONSE = 10
} Dnstap__Message__Type;
typedef enum _Dnstap__SocketFamily {
DNSTAP__SOCKET_FAMILY__INET = 1,
DNSTAP__SOCKET_FAMILY__INET6 = 2
} Dnstap__SocketFamily;
typedef enum _Dnstap__SocketProtocol {
DNSTAP__SOCKET_PROTOCOL__UDP = 1,
DNSTAP__SOCKET_PROTOCOL__TCP = 2
} Dnstap__SocketProtocol;
/* --- messages --- */
struct _Dnstap__Dnstap
{
ProtobufCMessage base;
protobuf_c_boolean has_identity;
ProtobufCBinaryData identity;
protobuf_c_boolean has_version;
ProtobufCBinaryData version;
protobuf_c_boolean has_extra;
ProtobufCBinaryData extra;
Dnstap__Dnstap__Type type;
Dnstap__Message *message;
};
#define DNSTAP__DNSTAP__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&dnstap__dnstap__descriptor) \
, 0,{0,NULL}, 0,{0,NULL}, 0,{0,NULL}, 0, NULL }
struct _Dnstap__Message
{
ProtobufCMessage base;
Dnstap__Message__Type type;
protobuf_c_boolean has_socket_family;
Dnstap__SocketFamily socket_family;
protobuf_c_boolean has_socket_protocol;
Dnstap__SocketProtocol socket_protocol;
protobuf_c_boolean has_query_address;
ProtobufCBinaryData query_address;
protobuf_c_boolean has_response_address;
ProtobufCBinaryData response_address;
protobuf_c_boolean has_query_port;
uint32_t query_port;
protobuf_c_boolean has_response_port;
uint32_t response_port;
protobuf_c_boolean has_query_time_sec;
uint64_t query_time_sec;
protobuf_c_boolean has_query_time_nsec;
uint32_t query_time_nsec;
protobuf_c_boolean has_query_message;
ProtobufCBinaryData query_message;
protobuf_c_boolean has_query_zone;
ProtobufCBinaryData query_zone;
protobuf_c_boolean has_response_time_sec;
uint64_t response_time_sec;
protobuf_c_boolean has_response_time_nsec;
uint32_t response_time_nsec;
protobuf_c_boolean has_response_message;
ProtobufCBinaryData response_message;
};
#define DNSTAP__MESSAGE__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&dnstap__message__descriptor) \
, 0, 0,0, 0,0, 0,{0,NULL}, 0,{0,NULL}, 0,0, 0,0, 0,0, 0,0, 0,{0,NULL}, 0,{0,NULL}, 0,0, 0,0, 0,{0,NULL} }
/* Dnstap__Dnstap methods */
void dnstap__dnstap__init
(Dnstap__Dnstap *message);
size_t dnstap__dnstap__get_packed_size
(const Dnstap__Dnstap *message);
size_t dnstap__dnstap__pack
(const Dnstap__Dnstap *message,
uint8_t *out);
size_t dnstap__dnstap__pack_to_buffer
(const Dnstap__Dnstap *message,
ProtobufCBuffer *buffer);
Dnstap__Dnstap *
dnstap__dnstap__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void dnstap__dnstap__free_unpacked
(Dnstap__Dnstap *message,
ProtobufCAllocator *allocator);
/* Dnstap__Message methods */
void dnstap__message__init
(Dnstap__Message *message);
size_t dnstap__message__get_packed_size
(const Dnstap__Message *message);
size_t dnstap__message__pack
(const Dnstap__Message *message,
uint8_t *out);
size_t dnstap__message__pack_to_buffer
(const Dnstap__Message *message,
ProtobufCBuffer *buffer);
Dnstap__Message *
dnstap__message__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void dnstap__message__free_unpacked
(Dnstap__Message *message,
ProtobufCAllocator *allocator);
/* --- per-message closures --- */
typedef void (*Dnstap__Dnstap_Closure)
(const Dnstap__Dnstap *message,
void *closure_data);
typedef void (*Dnstap__Message_Closure)
(const Dnstap__Message *message,
void *closure_data);
/* --- services --- */
/* --- descriptors --- */
extern const ProtobufCEnumDescriptor dnstap__socket_family__descriptor;
extern const ProtobufCEnumDescriptor dnstap__socket_protocol__descriptor;
extern const ProtobufCMessageDescriptor dnstap__dnstap__descriptor;
extern const ProtobufCEnumDescriptor dnstap__dnstap__type__descriptor;
extern const ProtobufCMessageDescriptor dnstap__message__descriptor;
extern const ProtobufCEnumDescriptor dnstap__message__type__descriptor;
PROTOBUF_C_END_DECLS
#endif /* PROTOBUF_dnstap_2fdnstap_2eproto__INCLUDED */

View file

@ -1,3 +1,102 @@
1 December 2014: Wouter
- Fix bug#632: unbound fails to build on AArch64, protects
getentropy compat code from calling sysctl if it is has been removed.
29 November 2014: Wouter
- Add include to getentropy_linux.c, hopefully fixing debian build.
28 November 2014: Wouter
- Fix makefile for build from noexec source tree.
26 November 2014: Wouter
- Fix libunbound undefined symbol errors for main.
Referencing main does not seem to be possible for libunbound.
24 November 2014: Wouter
- Fix log at high verbosity and memory allocation failure.
- iana portlist update.
21 November 2014: Wouter
- Fix crash on multiple thread random usage on systems without
arc4random.
20 November 2014: Wouter
- fix compat/getentropy_win.c check if CryptGenRandom works and no
immediate exit on windows.
19 November 2014: Wouter
- Fix cdflag dns64 processing.
18 November 2014: Wouter
- Fix that CD flag disables DNS64 processing, returning the DNSSEC
signed AAAA denial.
- iana portlist update.
17 November 2014: Wouter
- Fix #627: SSL_CTX_load_verify_locations return code not properly
checked.
14 November 2014: Wouter
- parser with bison 2.7
13 November 2014: Wouter
- Patch from Stephane Lapie for ASAHI Net that implements aaaa-filter,
added to contrib/aaaa-filter-iterator.patch.
12 November 2014: Wouter
- trunk has 1.5.1 in development.
- Patch from Robert Edmonds to build pyunbound python module
differently. No versioninfo, with -shared and without $(LIBS).
- Patch from Robert Edmonds fixes hyphens in unbound-anchor man page.
- Removed 'increased limit open files' log message that is written
to console. It is only written on verbosity 4 and higher.
This keeps system bootup console cleaner.
- Patch from James Raftery, always print stats for rcodes 0..5.
11 November 2014: Wouter
- iana portlist update.
- Fix bug where forward or stub addresses with same address but
different port number were not tried.
- version number in svn trunk is 1.5.0
- tag 1.5.0rc1
- review fix from Ralph.
7 November 2014: Wouter
- dnstap fixes by Robert Edmonds:
dnstap/dnstap.m4: cosmetic fixes
dnstap/: Remove compiled protoc-c output files
dnstap/dnstap.m4: Error out if required libraries are not found
dnstap: Fix ProtobufCBufferSimple usage that is incorrect as of
protobuf-c 1.0.0
dnstap/: Adapt to API changes in latest libfstrm (>= 0.2.0)
4 November 2014: Wouter
- Add ub_ctx_add_ta_autr function to add a RFC5011 automatically
tracked trust anchor to libunbound.
- Redefine internal minievent symbols to unique symbols that helps
linking on platforms where the linker leaks names across modules.
27 October 2014: Wouter
- Disabled use of SSLv3 in remote-control and ssl-upstream.
- iana portlist update.
16 October 2014: Wouter
- Documented dns64 configuration in unbound.conf man page.
13 October 2014: Wouter
- Fix #617: in ldns in unbound, lowercase WKS services.
- Fix ctype invocation casts.
10 October 2014: Wouter
- Fix unbound-checkconf check for module config with dns64 module.
- Fix unbound capsforid fallback, it ignores TTLs in comparison.
6 October 2014: Wouter
- Fix #614: man page variable substitution bug.
6 October 2014: Willem
- Whitespaces after $ORIGIN are not part of the origin dname (ldns).
- $TTL's value starts at position 5 (ldns).
1 October 2014: Wouter
- fix #613: Allow tab ws in var length last rdfs (in ldns str2wire).

View file

@ -22,6 +22,7 @@
.B ub_ctx_resolvconf,
.B ub_ctx_hosts,
.B ub_ctx_add_ta,
.B ub_ctx_add_ta_autr,
.B ub_ctx_add_ta_file,
.B ub_ctx_trustedkeys,
.B ub_ctx_debugout,
@ -73,6 +74,9 @@
\fBub_ctx_add_ta\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR ta);
.LP
\fIint\fR
\fBub_ctx_add_ta_autr\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
.LP
\fIint\fR
\fBub_ctx_add_ta_file\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
.LP
\fIint\fR
@ -231,6 +235,15 @@ first resolve is done.
The format is a string, similar to the zone\-file format,
[domainname] [type] [rdata contents]. Both DS and DNSKEY records are accepted.
.TP
.B ub_ctx_add_ta_autr
Add filename with automatically tracked trust anchor to the given context.
Pass name of a file with the managed trust anchor. You can create this
file with \fIunbound\-anchor\fR(8) for the root anchor. You can also
create it with an initial file with one line with a DNSKEY or DS record.
If the file is writable, it is updated when the trust anchor changes.
At this time it is only possible to add trusted keys before the
first resolve is done.
.TP
.B ub_ctx_add_ta_file
Add trust anchors to the given context.
Pass name of a file with DS and DNSKEY records in zone file format.

View file

@ -24,14 +24,14 @@ Suggested usage:
.nf
# in the init scripts.
# provide or update the root anchor (if necessary)
unbound-anchor -a "@UNBOUND_ROOTKEY_FILE@"
unbound-anchor \-a "@UNBOUND_ROOTKEY_FILE@"
# Please note usage of this root anchor is at your own risk
# and under the terms of our LICENSE (see source).
#
# start validating resolver
# the unbound.conf contains:
# auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@"
unbound -c unbound.conf
unbound \-c unbound.conf
.fi
.P
This tool provides builtin default contents for the root anchor and root
@ -138,7 +138,7 @@ tracking, or if an error occurred.
.P
You can check the exit value in this manner:
.nf
unbound-anchor -a "root.key" || logger "Please check root.key"
unbound-anchor \-a "root.key" || logger "Please check root.key"
.fi
Or something more suitable for your operational environment.
.SH "TRUST"

View file

@ -1082,6 +1082,19 @@ and the word "python" has to be put in the \fBmodule\-config:\fR option
.TP
.B python\-script: \fI<python file>\fR
The script file to load.
.SS "DNS64 Module Options"
.LP
The dns64 module must be configured in the \fBmodule\-config:\fR "dns64
validator iterator" directive and be compiled into the daemon to be
enabled. These settings go in the \fBserver:\fR section.
.TP
.B dns64\-prefix: \fI<IPv6 prefix>\fR
This sets the DNS64 prefix to use to synthesize AAAA records with.
It must be /96 or shorter. The default prefix is 64:ff9b::/96.
.TP
.B dns64\-synthall: \fI<yes or no>\fR
Debug option, default no. If enabled, synthesize all AAAA records
despite the presence of actual AAAA records.
.SH "MEMORY CONTROL EXAMPLE"
In the example config settings below memory usage is reduced. Some service
levels are lower, notable very large data and a high TCP load are no longer

View file

@ -147,7 +147,9 @@ delegpt_find_addr(struct delegpt* dp, struct sockaddr_storage* addr,
{
struct delegpt_addr* p = dp->target_list;
while(p) {
if(sockaddr_cmp_addr(addr, addrlen, &p->addr, p->addrlen)==0) {
if(sockaddr_cmp_addr(addr, addrlen, &p->addr, p->addrlen)==0
&& ((struct sockaddr_in*)addr)->sin_port ==
((struct sockaddr_in*)&p->addr)->sin_port) {
return p;
}
p = p->next_target;

View file

@ -425,10 +425,10 @@ dns_copy_msg(struct dns_msg* from, struct regional* region)
void
iter_dns_store(struct module_env* env, struct query_info* msgqinf,
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
struct regional* region)
struct regional* region, uint16_t flags)
{
if(!dns_cache_store(env, msgqinf, msgrep, is_referral, leeway,
pside, region))
pside, region, flags))
log_err("out of memory: cannot store data in cache");
}
@ -457,7 +457,8 @@ causes_cycle(struct module_qstate* qstate, uint8_t* name, size_t namelen,
fptr_ok(fptr_whitelist_modenv_detect_cycle(
qstate->env->detect_cycle));
return (*qstate->env->detect_cycle)(qstate, &qinf,
(uint16_t)(BIT_RD|BIT_CD), qstate->is_priming);
(uint16_t)(BIT_RD|BIT_CD), qstate->is_priming,
qstate->is_valrec);
}
void
@ -666,7 +667,7 @@ rrset_equal(struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2)
k1->rk.rrset_class != k2->rk.rrset_class ||
query_dname_compare(k1->rk.dname, k2->rk.dname) != 0)
return 0;
if(d1->ttl != d2->ttl ||
if( /* do not check ttl: d1->ttl != d2->ttl || */
d1->count != d2->count ||
d1->rrsig_count != d2->rrsig_count ||
d1->trust != d2->trust ||
@ -675,7 +676,7 @@ rrset_equal(struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2)
t = d1->count + d1->rrsig_count;
for(i=0; i<t; i++) {
if(d1->rr_len[i] != d2->rr_len[i] ||
d1->rr_ttl[i] != d2->rr_ttl[i] ||
/* no ttl check: d1->rr_ttl[i] != d2->rr_ttl[i] ||*/
memcmp(d1->rr_data[i], d2->rr_data[i],
d1->rr_len[i]) != 0)
return 0;
@ -689,8 +690,11 @@ reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region)
size_t i;
if(p->flags != q->flags ||
p->qdcount != q->qdcount ||
/* do not check TTL, this may differ */
/*
p->ttl != q->ttl ||
p->prefetch_ttl != q->prefetch_ttl ||
*/
p->security != q->security ||
p->an_numrrsets != q->an_numrrsets ||
p->ns_numrrsets != q->ns_numrrsets ||

View file

@ -124,6 +124,7 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional);
* @param pside: true if dp is parentside, thus message is 'fresh' and NS
* can be prefetch-updates.
* @param region: to copy modified (cache is better) rrs back to.
* @param flags: with BIT_CD for dns64 AAAA translated queries.
* @return void, because we are not interested in alloc errors,
* the iterator and validator can operate on the results in their
* scratch space (the qstate.region) and are not dependent on the cache.
@ -132,7 +133,7 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional);
*/
void iter_dns_store(struct module_env* env, struct query_info* qinf,
struct reply_info* rep, int is_referral, time_t leeway, int pside,
struct regional* region);
struct regional* region, uint16_t flags);
/**
* Select randomly with n/m probability.

View file

@ -257,7 +257,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
verbose(VERB_ALGO, "error response for prefetch in cache");
/* attempt to adjust the cache entry prefetch */
if(dns_cache_prefetch_adjust(qstate->env, &qstate->qinfo,
NORR_TTL))
NORR_TTL, qstate->query_flags))
return error_response(qstate, id, rcode);
/* if that fails (not in cache), fall through to store err */
}
@ -270,7 +270,8 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
/* do not waste time trying to validate this servfail */
err.security = sec_status_indeterminate;
verbose(VERB_ALGO, "store error response in message cache");
iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL);
iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL,
qstate->query_flags);
return error_response(qstate, id, rcode);
}
@ -486,6 +487,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
uint16_t qflags = 0; /* OPCODE QUERY, no flags */
struct query_info qinf;
int prime = (finalstate == PRIME_RESP_STATE)?1:0;
int valrec = 0;
qinf.qname = qname;
qinf.qname_len = qnamelen;
qinf.qtype = qtype;
@ -499,12 +501,15 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
* the resolution chain, which might have a validator. We are
* uninterested in validating things not on the direct resolution
* path. */
if(!v)
if(!v) {
qflags |= BIT_CD;
valrec = 1;
}
/* attach subquery, lookup existing or make a new one */
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, &subq)) {
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec,
&subq)) {
return 0;
}
*subq_ret = subq;
@ -938,7 +943,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
} else {
msg = dns_cache_lookup(qstate->env, iq->qchase.qname,
iq->qchase.qname_len, iq->qchase.qtype,
iq->qchase.qclass, qstate->region, qstate->env->scratch);
iq->qchase.qclass, qstate->query_flags,
qstate->region, qstate->env->scratch);
if(!msg && qstate->env->neg_cache) {
/* lookup in negative cache; may result in
* NOERROR/NODATA or NXDOMAIN answers that need validation */
@ -1991,7 +1997,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iter_dns_store(qstate->env, &iq->response->qinfo,
iq->response->rep, 0, qstate->prefetch_leeway,
iq->dp&&iq->dp->has_parent_side_NS,
qstate->region);
qstate->region, qstate->query_flags);
/* close down outstanding requests to be discarded */
outbound_list_clear(&iq->outlist);
iq->num_current_queries = 0;
@ -2029,7 +2035,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* Store the referral under the current query */
/* no prefetch-leeway, since its not the answer */
iter_dns_store(qstate->env, &iq->response->qinfo,
iq->response->rep, 1, 0, 0, NULL);
iq->response->rep, 1, 0, 0, NULL, 0);
if(iq->store_parent_NS)
iter_store_parentside_NS(qstate->env,
iq->response->rep);
@ -2128,7 +2134,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* prefetchleeway applied because this updates answer parts */
iter_dns_store(qstate->env, &iq->response->qinfo,
iq->response->rep, 1, qstate->prefetch_leeway,
iq->dp&&iq->dp->has_parent_side_NS, NULL);
iq->dp&&iq->dp->has_parent_side_NS, NULL,
qstate->query_flags);
/* set the current request's qname to the new value. */
iq->qchase.qname = sname;
iq->qchase.qname_len = snamelen;
@ -2209,7 +2216,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
}
/**
* Return priming query results to interestes super querystates.
* Return priming query results to interested super querystates.
*
* Sets the delegation point and delegation message (not nonRD queries).
* This is a callback from walk_supers.
@ -2640,7 +2647,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
iter_dns_store(qstate->env, &qstate->qinfo,
iq->response->rep, 0, qstate->prefetch_leeway,
iq->dp&&iq->dp->has_parent_side_NS,
qstate->region);
qstate->region, qstate->query_flags);
}
}
qstate->return_rcode = LDNS_RCODE_NOERROR;

View file

@ -324,8 +324,10 @@ sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
ec = EC_KEY_new_by_curve_name(NID_secp384r1);
} else ec = NULL;
if(!ec) return NULL;
if(keylen+1 > sizeof(buf))
return NULL; /* sanity check */
if(keylen+1 > sizeof(buf)) { /* sanity check */
EC_KEY_free(ec);
return NULL;
}
/* prepend the 0x02 (from docs) (or actually 0x04 from implementation
* of openssl) for uncompressed data */
buf[0] = POINT_CONVERSION_UNCOMPRESSED;

View file

@ -288,9 +288,9 @@ sldns_parse_escape(uint8_t *ch_p, const char** str_p)
{
uint16_t val;
if ((*str_p)[0] && isdigit((*str_p)[0]) &&
(*str_p)[1] && isdigit((*str_p)[1]) &&
(*str_p)[2] && isdigit((*str_p)[2])) {
if ((*str_p)[0] && isdigit((unsigned char)(*str_p)[0]) &&
(*str_p)[1] && isdigit((unsigned char)(*str_p)[1]) &&
(*str_p)[2] && isdigit((unsigned char)(*str_p)[2])) {
val = (uint16_t)(((*str_p)[0] - '0') * 100 +
((*str_p)[1] - '0') * 10 +
@ -303,7 +303,7 @@ sldns_parse_escape(uint8_t *ch_p, const char** str_p)
*str_p += 3;
return 1;
} else if ((*str_p)[0] && !isdigit((*str_p)[0])) {
} else if ((*str_p)[0] && !isdigit((unsigned char)(*str_p)[0])) {
*ch_p = (uint8_t)*(*str_p)++;
return 1;
@ -467,7 +467,7 @@ sldns_b32_pton_base(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz,
ch = *src++;
--src_sz;
} while (isspace(ch) && src_sz > 0);
} while (isspace((unsigned char)ch) && src_sz > 0);
if (ch == '=' || ch == '\0')
break;
@ -572,7 +572,7 @@ sldns_b32_pton_base(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz,
ch = *src++;
src_sz--;
} while (isspace(ch));
} while (isspace((unsigned char)ch));
if (ch != '=')
return -1;

View file

@ -35,9 +35,9 @@ INLINE uint16_t
sldns_read_uint16(const void *src)
{
#ifdef ALLOW_UNALIGNED_ACCESSES
return ntohs(*(uint16_t *) src);
return ntohs(*(const uint16_t *) src);
#else
uint8_t *p = (uint8_t *) src;
const uint8_t *p = (const uint8_t *) src;
return ((uint16_t) p[0] << 8) | (uint16_t) p[1];
#endif
}
@ -46,9 +46,9 @@ INLINE uint32_t
sldns_read_uint32(const void *src)
{
#ifdef ALLOW_UNALIGNED_ACCESSES
return ntohl(*(uint32_t *) src);
return ntohl(*(const uint32_t *) src);
#else
uint8_t *p = (uint8_t *) src;
const uint8_t *p = (const uint8_t *) src;
return ( ((uint32_t) p[0] << 24)
| ((uint32_t) p[1] << 16)
| ((uint32_t) p[2] << 8)

View file

@ -245,7 +245,7 @@ rrinternal_get_ttl(sldns_buffer* strbuf, char* token, size_t token_len,
}
*ttl = (uint32_t) sldns_str2period(token, &endptr);
if (strlen(token) > 0 && !isdigit((int)token[0])) {
if (strlen(token) > 0 && !isdigit((unsigned char)token[0])) {
*not_there = 1;
/* ah, it's not there or something */
if (default_ttl == 0) {
@ -384,11 +384,11 @@ rrinternal_spool_hex(char* token, uint8_t* rr, size_t rr_len,
{
char* p = token;
while(*p) {
if(isspace(*p)) {
if(isspace((unsigned char)*p)) {
p++;
continue;
}
if(!isxdigit(*p))
if(!isxdigit((unsigned char)*p))
return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_RDATA,
p-token);
if(*cur_hex_data_size >= hex_data_size)
@ -827,6 +827,20 @@ const char* sldns_get_errorstr_parse(int e)
return lt?lt->name:"unknown error";
}
/* Strip whitespace from the start and the end of <line>. */
static char *
sldns_strip_ws(char *line)
{
char *s = line, *e;
for (s = line; *s && isspace((unsigned char)*s); s++)
;
for (e = strchr(s, 0); e > s+2 && isspace((unsigned char)e[-1]) && e[-2] != '\\'; e--)
;
*e = 0;
return s;
}
int sldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
struct sldns_file_parse_state* parse_state)
{
@ -852,28 +866,23 @@ int sldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
return LDNS_WIREPARSE_ERR_OK;
}
if(strncmp(line, "$ORIGIN", 7) == 0 && isspace(line[7])) {
size_t off = 8;
if(strncmp(line, "$ORIGIN", 7) == 0 && isspace((unsigned char)line[7])) {
int s;
*len = 0;
*dname_len = 0;
if(!parse_state) return LDNS_WIREPARSE_ERR_OK;
while(isspace(line[off]))
off++;
parse_state->origin_len = sizeof(parse_state->origin);
s = sldns_str2wire_dname_buf(line+off, parse_state->origin,
&parse_state->origin_len);
s = sldns_str2wire_dname_buf(sldns_strip_ws(line+8),
parse_state->origin, &parse_state->origin_len);
if(s) parse_state->origin_len = 0;
return s;
} else if(strncmp(line, "$TTL", 4) == 0 && isspace(line[4])) {
} else if(strncmp(line, "$TTL", 4) == 0 && isspace((unsigned char)line[4])) {
const char* end = NULL;
size_t off = 8;
*len = 0;
*dname_len = 0;
if(!parse_state) return LDNS_WIREPARSE_ERR_OK;
while(isspace(line[off]))
off++;
parse_state->default_ttl = sldns_str2period(line+off, &end);
parse_state->default_ttl = sldns_str2period(
sldns_strip_ws(line+5), &end);
} else if (strncmp(line, "$INCLUDE", 8) == 0) {
*len = 0;
*dname_len = 0;
@ -1188,11 +1197,11 @@ int sldns_str2wire_hex_buf(const char* str, uint8_t* rd, size_t* len)
const char* s = str;
size_t dlen = 0; /* number of hexdigits parsed */
while(*s) {
if(isspace(*s)) {
if(isspace((unsigned char)*s)) {
s++;
continue;
}
if(!isxdigit(*s))
if(!isxdigit((unsigned char)*s))
return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_HEX, s-str);
if(*len < dlen/2 + 1)
return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL,
@ -1392,7 +1401,7 @@ static int
loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e)
{
uint32_t meters = 0, cm = 0, val;
while (isblank(*my_str)) {
while (isblank((unsigned char)*my_str)) {
my_str++;
}
meters = (uint32_t)strtol(my_str, &my_str, 10);
@ -1443,17 +1452,17 @@ int sldns_str2wire_loc_buf(const char* str, uint8_t* rd, size_t* len)
char *my_str = (char *) str;
if (isdigit((int) *my_str)) {
if (isdigit((unsigned char) *my_str)) {
h = (uint32_t) strtol(my_str, &my_str, 10);
} else {
return LDNS_WIREPARSE_ERR_INVALID_STR;
}
while (isblank((int) *my_str)) {
while (isblank((unsigned char) *my_str)) {
my_str++;
}
if (isdigit((int) *my_str)) {
if (isdigit((unsigned char) *my_str)) {
m = (uint32_t) strtol(my_str, &my_str, 10);
} else if (*my_str == 'N' || *my_str == 'S') {
goto north;
@ -1461,16 +1470,16 @@ int sldns_str2wire_loc_buf(const char* str, uint8_t* rd, size_t* len)
return LDNS_WIREPARSE_ERR_INVALID_STR;
}
while (isblank((int) *my_str)) {
while (isblank((unsigned char) *my_str)) {
my_str++;
}
if (isdigit((int) *my_str)) {
if (isdigit((unsigned char) *my_str)) {
s = strtod(my_str, &my_str);
}
/* skip blanks before norterness */
while (isblank((int) *my_str)) {
while (isblank((unsigned char) *my_str)) {
my_str++;
}
@ -1497,21 +1506,21 @@ north:
} else {
latitude = equator - latitude;
}
while (isblank(*my_str)) {
while (isblank((unsigned char)*my_str)) {
my_str++;
}
if (isdigit((int) *my_str)) {
if (isdigit((unsigned char) *my_str)) {
h = (uint32_t) strtol(my_str, &my_str, 10);
} else {
return LDNS_WIREPARSE_ERR_INVALID_STR;
}
while (isblank((int) *my_str)) {
while (isblank((unsigned char) *my_str)) {
my_str++;
}
if (isdigit((int) *my_str)) {
if (isdigit((unsigned char) *my_str)) {
m = (uint32_t) strtol(my_str, &my_str, 10);
} else if (*my_str == 'E' || *my_str == 'W') {
goto east;
@ -1519,16 +1528,16 @@ north:
return LDNS_WIREPARSE_ERR_INVALID_STR;
}
while (isblank(*my_str)) {
while (isblank((unsigned char)*my_str)) {
my_str++;
}
if (isdigit((int) *my_str)) {
if (isdigit((unsigned char) *my_str)) {
s = strtod(my_str, &my_str);
}
/* skip blanks before easterness */
while (isblank(*my_str)) {
while (isblank((unsigned char)*my_str)) {
my_str++;
}
@ -1591,6 +1600,17 @@ east:
return LDNS_WIREPARSE_ERR_OK;
}
static void
ldns_tolower_str(char* s)
{
if(s) {
while(*s) {
*s = (char)tolower((unsigned char)*s);
s++;
}
}
}
int sldns_str2wire_wks_buf(const char* str, uint8_t* rd, size_t* len)
{
int rd_len = 1;
@ -1605,6 +1625,7 @@ int sldns_str2wire_wks_buf(const char* str, uint8_t* rd, size_t* len)
return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
while(sldns_bget_token(&strbuf, token, "\t\n ", sizeof(token)) > 0) {
ldns_tolower_str(token);
if(!have_proto) {
struct protoent *p = getprotobyname(token);
have_proto = 1;
@ -1682,11 +1703,11 @@ int sldns_str2wire_nsap_buf(const char* str, uint8_t* rd, size_t* len)
if(slen > LDNS_MAX_RDFLEN*2)
return LDNS_WIREPARSE_ERR_LABEL_OVERFLOW;
while(*s) {
if(isspace(*s) || *s == '.') {
if(isspace((unsigned char)*s) || *s == '.') {
s++;
continue;
}
if(!isxdigit(*s))
if(!isxdigit((unsigned char)*s))
return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_HEX, s-str);
if(*len < dlen/2 + 1)
return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL,
@ -1713,11 +1734,11 @@ int sldns_str2wire_atma_buf(const char* str, uint8_t* rd, size_t* len)
if(slen > LDNS_MAX_RDFLEN*2)
return LDNS_WIREPARSE_ERR_LABEL_OVERFLOW;
while(*s) {
if(isspace(*s) || *s == '.') {
if(isspace((unsigned char)*s) || *s == '.') {
s++;
continue;
}
if(!isxdigit(*s))
if(!isxdigit((unsigned char)*s))
return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_HEX, s-str);
if(*len < dlen/2 + 1)
return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL,
@ -1820,7 +1841,8 @@ int sldns_str2wire_nsec3_salt_buf(const char* str, uint8_t* rd, size_t* len)
return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
rd[0] = (uint8_t) (salt_length_str / 2);
for (i = 0; i < salt_length_str; i += 2) {
if (isxdigit((int)str[i]) && isxdigit((int)str[i+1])) {
if (isxdigit((unsigned char)str[i]) &&
isxdigit((unsigned char)str[i+1])) {
rd[1+i/2] = (uint8_t)(sldns_hexdigit_to_int(str[i])*16
+ sldns_hexdigit_to_int(str[i+1]));
} else {
@ -1907,7 +1929,7 @@ int sldns_str2wire_tag_buf(const char* str, uint8_t* rd, size_t* len)
if(*len < slen+1)
return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
for (ptr = str; *ptr; ptr++) {
if(!isalnum(*ptr))
if(!isalnum((unsigned char)*ptr))
return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_TAG, ptr-str);
}
rd[0] = slen;

View file

@ -722,7 +722,7 @@ static int dname_char_print(char** s, size_t* slen, uint8_t c)
{
if(c == '.' || c == ';' || c == '(' || c == ')' || c == '\\')
return sldns_str_print(s, slen, "\\%c", c);
else if(!(isascii((int)c) && isgraph((int)c)))
else if(!(isascii((unsigned char)c) && isgraph((unsigned char)c)))
return sldns_str_print(s, slen, "\\%03u", (unsigned)c);
/* plain printout */
if(*slen) {
@ -1064,7 +1064,7 @@ int sldns_wire2str_aaaa_scan(uint8_t** d, size_t* dl, char** s, size_t* sl)
/** printout escaped TYPE_STR character */
static int str_char_print(char** s, size_t* sl, uint8_t c)
{
if(isprint((int)c) || c == '\t') {
if(isprint((unsigned char)c) || c == '\t') {
if(c == '\"' || c == '\\')
return sldns_str_print(s, sl, "\\%c", c);
if(*sl) {
@ -1625,7 +1625,7 @@ int sldns_wire2str_tag_scan(uint8_t** d, size_t* dl, char** s, size_t* sl)
if(*dl < 1+n)
return -1;
for(i=0; i<n; i++)
if(!isalnum((int)(*d)[i]))
if(!isalnum((unsigned char)(*d)[i]))
return -1;
for(i=0; i<n; i++)
w += sldns_str_print(s, sl, "%c", (char)(*d)[i]);
@ -1713,7 +1713,7 @@ int sldns_wire2str_edns_nsid_print(char** s, size_t* sl, uint8_t* data,
size_t i, printed=0;
w += print_hex_buf(s, sl, data, len);
for(i=0; i<len; i++) {
if(isprint((int)data[i]) || data[i] == '\t') {
if(isprint((unsigned char)data[i]) || data[i] == '\t') {
if(!printed) {
w += sldns_str_print(s, sl, " (");
printed = 1;

View file

@ -363,6 +363,26 @@ ub_ctx_add_ta_file(struct ub_ctx* ctx, const char* fname)
return UB_NOERROR;
}
int ub_ctx_add_ta_autr(struct ub_ctx* ctx, const char* fname)
{
char* dup = strdup(fname);
if(!dup) return UB_NOMEM;
lock_basic_lock(&ctx->cfglock);
if(ctx->finalized) {
lock_basic_unlock(&ctx->cfglock);
free(dup);
return UB_AFTERFINAL;
}
if(!cfg_strlist_insert(&ctx->env->cfg->auto_trust_anchor_file_list,
dup)) {
lock_basic_unlock(&ctx->cfglock);
free(dup);
return UB_NOMEM;
}
lock_basic_unlock(&ctx->cfglock);
return UB_NOERROR;
}
int
ub_ctx_trustedkeys(struct ub_ctx* ctx, const char* fname)
{
@ -959,7 +979,7 @@ ub_ctx_resolvconf(struct ub_ctx* ctx, const char* fname)
parse++;
addr = parse;
/* skip [0-9a-fA-F.:]*, i.e. IP4 and IP6 address */
while(isxdigit(*parse) || *parse=='.' || *parse==':')
while(isxdigit((unsigned char)*parse) || *parse=='.' || *parse==':')
parse++;
/* terminate after the address, remove newline */
*parse = 0;
@ -1031,7 +1051,7 @@ ub_ctx_hosts(struct ub_ctx* ctx, const char* fname)
/* format: <addr> spaces <name> spaces <name> ... */
addr = parse;
/* skip addr */
while(isxdigit(*parse) || *parse == '.' || *parse == ':')
while(isxdigit((unsigned char)*parse) || *parse == '.' || *parse == ':')
parse++;
if(*parse == '\n' || *parse == 0)
continue;

View file

@ -8,6 +8,7 @@ ub_ctx_set_fwd
ub_ctx_resolvconf
ub_ctx_hosts
ub_ctx_add_ta
ub_ctx_add_ta_autr
ub_ctx_add_ta_file
ub_ctx_trustedkeys
ub_ctx_debugout

View file

@ -356,6 +356,21 @@ int ub_ctx_add_ta(struct ub_ctx* ctx, const char* ta);
*/
int ub_ctx_add_ta_file(struct ub_ctx* ctx, const char* fname);
/**
* Add trust anchor to the given context that is tracked with RFC5011
* automated trust anchor maintenance. The file is written to when the
* trust anchor is changed.
* Pass the name of a file that was output from eg. unbound-anchor,
* or you can start it by providing a trusted DNSKEY or DS record on one
* line in the file.
* @param ctx: context.
* At this time it is only possible to add trusted keys before the
* first resolve is done.
* @param fname: filename of file with trust anchor.
* @return 0 if OK, else error.
*/
int ub_ctx_add_ta_autr(struct ub_ctx* ctx, const char* fname);
/**
* Add trust anchors to the given context.
* Pass the name of a bind-style config file with trusted-keys{}.
@ -508,7 +523,7 @@ void ub_resolve_free(struct ub_result* result);
/**
* Convert error value to a human readable string.
* @param err: error code from one of the ub_val* functions.
* @param err: error code from one of the libunbound functions.
* @return pointer to constant text string, zero terminated.
*/
const char* ub_strerror(int err);

View file

@ -1,3 +0,0 @@
#!/bin/bash
./configure --prefix=${CMAKE_FIND_ROOT_PATH} --build=${GCC_PREFIX} --host=${GCC_PREFIX} --disable-shared --enable-static --sysconfdir=${CMAKE_FIND_ROOT_PATH}/etc --localstatedir=${CMAKE_FIND_ROOT_PATH}/var --sbindir=${CMAKE_FIND_ROOT_PATH}/bin --disable-gost --disable-rpath --with-libevent=no --with-libexpat=${CMAKE_FIND_ROOT_PATH} --without-pyunbound --without-pythonmodule --with-ssl=${CMAKE_FIND_ROOT_PATH} --without-pthreads --with-libunbound-only

View file

@ -67,7 +67,7 @@ int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, st
}
return dns_cache_store(qstate->env, qinfo, msgrep, is_referral,
qstate->prefetch_leeway, 0, NULL);
qstate->prefetch_leeway, 0, NULL, qstate->query_flags);
}
/* Invalidate the message associated with query_info stored in message cache */
@ -78,7 +78,7 @@ void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qin
struct reply_info *r;
size_t i, j;
h = query_info_hash(qinfo);
h = query_info_hash(qinfo, qstate->query_flags);
if ((e=slabhash_lookup(qstate->env->msg_cache, h, qinfo, 0)))
{
r = (struct reply_info*)(e->data);

View file

@ -184,7 +184,7 @@ addr_to_additional(struct ub_packed_rrset_key* rrset, struct regional* region,
/** lookup message in message cache */
static struct msgreply_entry*
msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen,
uint16_t qtype, uint16_t qclass, time_t now, int wr)
uint16_t qtype, uint16_t qclass, uint16_t flags, time_t now, int wr)
{
struct lruhash_entry* e;
struct query_info k;
@ -194,7 +194,7 @@ msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen,
k.qname_len = qnamelen;
k.qtype = qtype;
k.qclass = qclass;
h = query_info_hash(&k);
h = query_info_hash(&k, flags);
e = slabhash_lookup(env->msg_cache, h, &k, wr);
if(!e) return NULL;
@ -226,8 +226,10 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
addr_to_additional(akey, region, *msg, now);
lock_rw_unlock(&akey->entry.lock);
} else {
/* BIT_CD on false because delegpt lookup does
* not use dns64 translation */
neg = msg_cache_lookup(env, ns->name, ns->namelen,
LDNS_RR_TYPE_A, qclass, now, 0);
LDNS_RR_TYPE_A, qclass, 0, now, 0);
if(neg) {
delegpt_add_neg_msg(dp, neg);
lock_rw_unlock(&neg->entry.lock);
@ -244,8 +246,10 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
addr_to_additional(akey, region, *msg, now);
lock_rw_unlock(&akey->entry.lock);
} else {
/* BIT_CD on false because delegpt lookup does
* not use dns64 translation */
neg = msg_cache_lookup(env, ns->name, ns->namelen,
LDNS_RR_TYPE_AAAA, qclass, now, 0);
LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
if(neg) {
delegpt_add_neg_msg(dp, neg);
lock_rw_unlock(&neg->entry.lock);
@ -276,8 +280,10 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
ns->name, LDNS_RR_TYPE_A, qclass);
lock_rw_unlock(&akey->entry.lock);
} else {
/* BIT_CD on false because delegpt lookup does
* not use dns64 translation */
neg = msg_cache_lookup(env, ns->name, ns->namelen,
LDNS_RR_TYPE_A, qclass, now, 0);
LDNS_RR_TYPE_A, qclass, 0, now, 0);
if(neg) {
delegpt_add_neg_msg(dp, neg);
lock_rw_unlock(&neg->entry.lock);
@ -294,8 +300,10 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
ns->name, LDNS_RR_TYPE_AAAA, qclass);
lock_rw_unlock(&akey->entry.lock);
} else {
/* BIT_CD on false because delegpt lookup does
* not use dns64 translation */
neg = msg_cache_lookup(env, ns->name, ns->namelen,
LDNS_RR_TYPE_AAAA, qclass, now, 0);
LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
if(neg) {
delegpt_add_neg_msg(dp, neg);
lock_rw_unlock(&neg->entry.lock);
@ -626,7 +634,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
struct dns_msg*
dns_cache_lookup(struct module_env* env,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
struct regional* region, struct regional* scratch)
uint16_t flags, struct regional* region, struct regional* scratch)
{
struct lruhash_entry* e;
struct query_info k;
@ -639,7 +647,7 @@ dns_cache_lookup(struct module_env* env,
k.qname_len = qnamelen;
k.qtype = qtype;
k.qclass = qclass;
h = query_info_hash(&k);
h = query_info_hash(&k, flags);
e = slabhash_lookup(env->msg_cache, h, &k, 0);
if(e) {
struct msgreply_entry* key = (struct msgreply_entry*)e->key;
@ -716,7 +724,7 @@ dns_cache_lookup(struct module_env* env,
if(env->cfg->harden_below_nxdomain)
while(!dname_is_root(k.qname)) {
dname_remove_label(&k.qname, &k.qname_len);
h = query_info_hash(&k);
h = query_info_hash(&k, flags);
e = slabhash_lookup(env->msg_cache, h, &k, 0);
if(e) {
struct reply_info* data = (struct reply_info*)e->data;
@ -741,7 +749,7 @@ dns_cache_lookup(struct module_env* env,
int
dns_cache_store(struct module_env* env, struct query_info* msgqinf,
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
struct regional* region)
struct regional* region, uint16_t flags)
{
struct reply_info* rep = NULL;
/* alloc, malloc properly (not in region, like msg is) */
@ -786,7 +794,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
* Not AA from cache. Not CD in cache (depends on client bit). */
rep->flags |= (BIT_RA | BIT_QR);
rep->flags &= ~(BIT_AA | BIT_CD);
h = query_info_hash(&qinf);
h = query_info_hash(&qinf, flags);
dns_cache_store_msg(env, &qinf, h, rep, leeway, pside, msgrep,
region);
/* qname is used inside query_info_entrysetup, and set to
@ -798,11 +806,11 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
int
dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo,
time_t adjust)
time_t adjust, uint16_t flags)
{
struct msgreply_entry* msg;
msg = msg_cache_lookup(env, qinfo->qname, qinfo->qname_len,
qinfo->qtype, qinfo->qclass, *env->now, 1);
qinfo->qtype, qinfo->qclass, flags, *env->now, 1);
if(msg) {
struct reply_info* rep = (struct reply_info*)msg->entry.data;
if(rep) {

View file

@ -79,11 +79,12 @@ struct dns_msg {
* can be updated to full TTL even in prefetch situations.
* @param region: region to allocate better entries from cache into.
* (used when is_referral is false).
* @param flags: flags with BIT_CD for AAAA queries in dns64 translation.
* @return 0 on alloc error (out of memory).
*/
int dns_cache_store(struct module_env* env, struct query_info* qinf,
struct reply_info* rep, int is_referral, time_t leeway, int pside,
struct regional* region);
struct regional* region, uint16_t flags);
/**
* Store message in the cache. Stores in message cache and rrset cache.
@ -132,6 +133,7 @@ struct delegpt* dns_cache_find_delegation(struct module_env* env,
* @param qnamelen: length of qname.
* @param qtype: query type.
* @param qclass: query class.
* @param flags: flags with BIT_CD for AAAA queries in dns64 translation.
* @param region: where to allocate result.
* @param scratch: where to allocate temporary data.
* @return new response message (alloced in region, rrsets do not have IDs).
@ -140,7 +142,7 @@ struct delegpt* dns_cache_find_delegation(struct module_env* env,
*/
struct dns_msg* dns_cache_lookup(struct module_env* env,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
struct regional* region, struct regional* scratch);
uint16_t flags, struct regional* region, struct regional* scratch);
/**
* find and add A and AAAA records for missing nameservers in delegpt
@ -186,9 +188,10 @@ int dns_msg_authadd(struct dns_msg* msg, struct regional* region,
* @param env: module environment with caches and time.
* @param qinfo: query info for the query that needs adjustment.
* @param adjust: time in seconds to add to the prefetch_leeway.
* @param flags: flags with BIT_CD for AAAA queries in dns64 translation.
* @return false if not in cache. true if added.
*/
int dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo,
time_t adjust);
time_t adjust, uint16_t flags);
#endif /* SERVICES_CACHE_DNS_H */

View file

@ -132,6 +132,11 @@ mesh_state_compare(const void* ap, const void* bp)
if(!a->s.is_priming && b->s.is_priming)
return 1;
if(a->s.is_valrec && !b->s.is_valrec)
return -1;
if(!a->s.is_valrec && b->s.is_valrec)
return 1;
if((a->s.query_flags&BIT_RD) && !(b->s.query_flags&BIT_RD))
return -1;
if(!(a->s.query_flags&BIT_RD) && (b->s.query_flags&BIT_RD))
@ -277,11 +282,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
uint16_t qflags, struct edns_data* edns, struct comm_reply* rep,
uint16_t qid)
{
/* do not use CD flag from user for mesh state, we want the CD-query
* to receive validation anyway, to protect out cache contents and
* avoid bad-data in this cache that a downstream validator cannot
* remove from this cache */
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0);
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
int was_detached = 0;
int was_noreply = 0;
int added = 0;
@ -311,7 +312,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
#ifdef UNBOUND_DEBUG
struct rbnode_t* n;
#endif
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0);
s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
if(!s) {
log_err("mesh_state_create: out of memory; SERVFAIL");
error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
@ -375,7 +376,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
uint16_t qflags, struct edns_data* edns, sldns_buffer* buf,
uint16_t qid, mesh_cb_func_t cb, void* cb_arg)
{
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0);
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
int was_detached = 0;
int was_noreply = 0;
int added = 0;
@ -386,7 +387,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
#ifdef UNBOUND_DEBUG
struct rbnode_t* n;
#endif
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0);
s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
if(!s) {
return 0;
}
@ -428,7 +429,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
uint16_t qflags, time_t leeway)
{
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0);
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
#ifdef UNBOUND_DEBUG
struct rbnode_t* n;
#endif
@ -447,7 +448,7 @@ void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
mesh->stats_dropped ++;
return;
}
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0);
s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
if(!s) {
log_err("prefetch mesh_state_create: out of memory");
return;
@ -496,7 +497,7 @@ void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e,
struct mesh_state*
mesh_state_create(struct module_env* env, struct query_info* qinfo,
uint16_t qflags, int prime)
uint16_t qflags, int prime, int valrec)
{
struct regional* region = alloc_reg_obtain(env->alloc);
struct mesh_state* mstate;
@ -533,6 +534,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
/* remove all weird bits from qflags */
mstate->s.query_flags = (qflags & (BIT_RD|BIT_CD));
mstate->s.is_priming = prime;
mstate->s.is_valrec = valrec;
mstate->s.reply = NULL;
mstate->s.region = region;
mstate->s.curmod = 0;
@ -679,11 +681,12 @@ void mesh_detach_subs(struct module_qstate* qstate)
}
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, struct module_qstate** newq)
uint16_t qflags, int prime, int valrec, struct module_qstate** newq)
{
/* find it, if not, create it */
struct mesh_area* mesh = qstate->env->mesh;
struct mesh_state* sub = mesh_area_find(mesh, qinfo, qflags, prime);
struct mesh_state* sub = mesh_area_find(mesh, qinfo, qflags, prime,
valrec);
int was_detached;
if(mesh_detect_cycle_found(qstate, sub)) {
verbose(VERB_ALGO, "attach failed, cycle detected");
@ -694,7 +697,8 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
struct rbnode_t* n;
#endif
/* create a new one */
sub = mesh_state_create(qstate->env, qinfo, qflags, prime);
sub = mesh_state_create(qstate->env, qinfo, qflags, prime,
valrec);
if(!sub) {
log_err("mesh_attach_sub: out of memory");
return 0;
@ -941,13 +945,14 @@ void mesh_walk_supers(struct mesh_area* mesh, struct mesh_state* mstate)
}
struct mesh_state* mesh_area_find(struct mesh_area* mesh,
struct query_info* qinfo, uint16_t qflags, int prime)
struct query_info* qinfo, uint16_t qflags, int prime, int valrec)
{
struct mesh_state key;
struct mesh_state* result;
key.node.key = &key;
key.s.is_priming = prime;
key.s.is_valrec = valrec;
key.s.qinfo = *qinfo;
key.s.query_flags = qflags;
@ -1107,8 +1112,9 @@ mesh_log_list(struct mesh_area* mesh)
struct mesh_state* m;
int num = 0;
RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
snprintf(buf, sizeof(buf), "%d%s%s%s%s%s mod%d %s%s",
snprintf(buf, sizeof(buf), "%d%s%s%s%s%s%s mod%d %s%s",
num++, (m->s.is_priming)?"p":"", /* prime */
(m->s.is_valrec)?"v":"", /* prime */
(m->s.query_flags&BIT_RD)?"RD":"",
(m->s.query_flags&BIT_CD)?"CD":"",
(m->super_set.count==0)?"d":"", /* detached */
@ -1178,10 +1184,11 @@ mesh_get_mem(struct mesh_area* mesh)
int
mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t flags, int prime)
uint16_t flags, int prime, int valrec)
{
struct mesh_area* mesh = qstate->env->mesh;
struct mesh_state* dep_m = mesh_area_find(mesh, qinfo, flags, prime);
struct mesh_state* dep_m = mesh_area_find(mesh, qinfo, flags, prime,
valrec);
return mesh_detect_cycle_found(qstate, dep_m);
}

View file

@ -353,12 +353,13 @@ void mesh_detach_subs(struct module_qstate* qstate);
* @param qinfo: what to query for (copied).
* @param qflags: what flags to use (RD / CD flag or not).
* @param prime: if it is a (stub) priming query.
* @param valrec: if it is a validation recursion query (lookup of key, DS).
* @param newq: If the new subquery needs initialisation, it is returned,
* otherwise NULL is returned.
* @return: false on error, true if success (and init may be needed).
*/
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, struct module_qstate** newq);
uint16_t qflags, int prime, int valrec, struct module_qstate** newq);
/**
* Query state is done, send messages to reply entries.
@ -406,10 +407,12 @@ void mesh_state_delete(struct module_qstate* qstate);
* @param qinfo: query info that the mesh is for.
* @param qflags: flags for query (RD / CD flag).
* @param prime: if true, it is a priming query, set is_priming on mesh state.
* @param valrec: if true, it is a validation recursion query, and sets
* is_valrec on the mesh state.
* @return: new mesh state or NULL on allocation error.
*/
struct mesh_state* mesh_state_create(struct module_env* env,
struct query_info* qinfo, uint16_t qflags, int prime);
struct query_info* qinfo, uint16_t qflags, int prime, int valrec);
/**
* Cleanup a mesh state and its query state. Does not do rbtree or
@ -432,10 +435,11 @@ void mesh_delete_all(struct mesh_area* mesh);
* @param qinfo: what query
* @param qflags: if RD / CD bit is set or not.
* @param prime: if it is a priming query.
* @param valrec: if it is a validation-recursion query.
* @return: mesh state or NULL if not found.
*/
struct mesh_state* mesh_area_find(struct mesh_area* mesh,
struct query_info* qinfo, uint16_t qflags, int prime);
struct query_info* qinfo, uint16_t qflags, int prime, int valrec);
/**
* Setup attachment super/sub relation between super and sub mesh state.
@ -523,13 +527,14 @@ size_t mesh_get_mem(struct mesh_area* mesh);
* @param qinfo: query info for dependency.
* @param flags: query flags of dependency.
* @param prime: if dependency is a priming query or not.
* @param valrec: if it is a validation recursion query (lookup of key, DS).
* @return true if the name,type,class exists and the given qstate mesh exists
* as a dependency of that name. Thus if qstate becomes dependent on
* name,type,class then a cycle is created, this is return value 1.
* Too large to search is value 2 (also true).
*/
int mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t flags, int prime);
uint16_t flags, int prime, int valrec);
/** compare two mesh_states */
int mesh_state_compare(const void* ap, const void* bp);

View file

@ -60,12 +60,12 @@ count_modules(const char* s)
return 0;
while(*s) {
/* skip whitespace */
while(*s && isspace((int)*s))
while(*s && isspace((unsigned char)*s))
s++;
if(*s && !isspace((int)*s)) {
if(*s && !isspace((unsigned char)*s)) {
/* skip identifier */
num++;
while(*s && !isspace((int)*s))
while(*s && !isspace((unsigned char)*s))
s++;
}
}
@ -152,7 +152,7 @@ module_func_block* module_factory(const char** str)
const char* s = *str;
const char** names = module_list_avail();
fbgetfunctype* fb = module_funcs_avail();
while(*s && isspace((int)*s))
while(*s && isspace((unsigned char)*s))
s++;
while(names[i]) {
if(strncmp(names[i], s, strlen(names[i])) == 0) {

View file

@ -1334,16 +1334,16 @@ serviced_perturb_qname(struct ub_randstate* rnd, uint8_t* qbuf, size_t len)
while(lablen) {
while(lablen--) {
/* only perturb A-Z, a-z */
if(isalpha((int)*d)) {
if(isalpha((unsigned char)*d)) {
/* get a random bit */
if(bits == 0) {
random = ub_random(rnd);
bits = 30;
}
if(random & 0x1) {
*d = (uint8_t)toupper((int)*d);
*d = (uint8_t)toupper((unsigned char)*d);
} else {
*d = (uint8_t)tolower((int)*d);
*d = (uint8_t)tolower((unsigned char)*d);
}
random >>= 1;
bits--;

View file

@ -392,10 +392,17 @@ morechecks(struct config_file* cfg, const char* fname)
if(strcmp(cfg->module_conf, "iterator") != 0
&& strcmp(cfg->module_conf, "validator iterator") != 0
&& strcmp(cfg->module_conf, "dns64 validator iterator") != 0
&& strcmp(cfg->module_conf, "dns64 iterator") != 0
#ifdef WITH_PYTHONMODULE
&& strcmp(cfg->module_conf, "python iterator") != 0
&& strcmp(cfg->module_conf, "python validator iterator") != 0
&& strcmp(cfg->module_conf, "validator python iterator") != 0
&& strcmp(cfg->module_conf, "dns64 python iterator") != 0
&& strcmp(cfg->module_conf, "dns64 python validator iterator") != 0
&& strcmp(cfg->module_conf, "dns64 validator python iterator") != 0
&& strcmp(cfg->module_conf, "python dns64 iterator") != 0
&& strcmp(cfg->module_conf, "python dns64 validator iterator") != 0
#endif
) {
fatal_exit("module conf '%s' is not known to work",

View file

@ -149,6 +149,8 @@ setup_ctx(struct config_file* cfg)
ssl_err("could not allocate SSL_CTX pointer");
if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2))
ssl_err("could not set SSL_OP_NO_SSLv2");
if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3))
ssl_err("could not set SSL_OP_NO_SSLv3");
if(!SSL_CTX_use_certificate_file(ctx,c_cert,SSL_FILETYPE_PEM) ||
!SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM)
|| !SSL_CTX_check_private_key(ctx))

View file

@ -409,7 +409,7 @@ extern int optind;
/** getopt global, in case header files fail to declare it. */
extern char* optarg;
/** Main routine for checkconf */
/** Main routine for unbound-host */
int main(int argc, char* argv[])
{
int c;

View file

@ -235,6 +235,7 @@ setup_ctx(char* key, char* cert)
SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
if(!ctx) print_exit("out of memory");
(void)SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
(void)SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
if(!SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM))
print_exit("cannot read cert");
if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM))

View file

@ -49,7 +49,7 @@ static void
skip_whites(const char** p)
{
while(1) {
while(isspace((int)**p))
while(isspace((unsigned char)**p))
(*p)++;
if(**p == ';') {
/* comment, skip until newline */
@ -71,11 +71,11 @@ void hex_to_buf(sldns_buffer* pkt, const char* hex)
skip_whites(&p);
if(sldns_buffer_position(pkt) == sldns_buffer_limit(pkt))
fatal_exit("hex_to_buf: buffer too small");
if(!isalnum((int)*p))
if(!isalnum((unsigned char)*p))
break;
val = sldns_hexdigit_to_int(*p++) << 4;
skip_whites(&p);
log_assert(*p && isalnum((int)*p));
log_assert(*p && isalnum((unsigned char)*p));
val |= sldns_hexdigit_to_int(*p++);
sldns_buffer_write_u8(pkt, (uint8_t)val);
skip_whites(&p);

View file

@ -130,7 +130,7 @@ strip_end_white(char* p)
{
size_t i;
for(i = strlen(p); i > 0; i--) {
if(isspace((int)p[i-1]))
if(isspace((unsigned char)p[i-1]))
p[i-1] = 0;
else return;
}
@ -170,14 +170,14 @@ replay_range_read(char* remain, FILE* in, const char* name,
while(fgets(line, MAX_LINE_LEN-1, in)) {
pstate->lineno++;
parse = line;
while(isspace((int)*parse))
while(isspace((unsigned char)*parse))
parse++;
if(!*parse || *parse == ';') {
pos = ftello(in);
continue;
}
if(parse_keyword(&parse, "ADDRESS")) {
while(isspace((int)*parse))
while(isspace((unsigned char)*parse))
parse++;
strip_end_white(parse);
if(!extstrtoaddr(parse, &rng->addr, &rng->addrlen)) {
@ -281,7 +281,7 @@ replay_moment_read(char* remain, FILE* in, const char* name,
return NULL;
}
remain += skip;
while(isspace((int)*remain))
while(isspace((unsigned char)*remain))
remain++;
if(parse_keyword(&remain, "NOTHING")) {
mom->evt_type = repevt_nothing;
@ -303,10 +303,10 @@ replay_moment_read(char* remain, FILE* in, const char* name,
mom->evt_type = repevt_timeout;
} else if(parse_keyword(&remain, "TIME_PASSES")) {
mom->evt_type = repevt_time_passes;
while(isspace((int)*remain))
while(isspace((unsigned char)*remain))
remain++;
if(parse_keyword(&remain, "EVAL")) {
while(isspace((int)*remain))
while(isspace((unsigned char)*remain))
remain++;
mom->string = strdup(remain);
if(!mom->string) fatal_exit("out of memory");
@ -316,7 +316,7 @@ replay_moment_read(char* remain, FILE* in, const char* name,
}
} else if(parse_keyword(&remain, "CHECK_AUTOTRUST")) {
mom->evt_type = repevt_autotrust_check;
while(isspace((int)*remain))
while(isspace((unsigned char)*remain))
remain++;
if(strlen(remain)>0 && remain[strlen(remain)-1]=='\n')
remain[strlen(remain)-1] = 0;
@ -333,20 +333,20 @@ replay_moment_read(char* remain, FILE* in, const char* name,
} else if(parse_keyword(&remain, "INFRA_RTT")) {
char *s, *m;
mom->evt_type = repevt_infra_rtt;
while(isspace((int)*remain))
while(isspace((unsigned char)*remain))
remain++;
s = remain;
remain = strchr(s, ' ');
if(!remain) fatal_exit("expected three args for INFRA_RTT");
remain[0] = 0;
remain++;
while(isspace((int)*remain))
while(isspace((unsigned char)*remain))
remain++;
m = strchr(remain, ' ');
if(!m) fatal_exit("expected three args for INFRA_RTT");
m[0] = 0;
m++;
while(isspace((int)*m))
while(isspace((unsigned char)*m))
m++;
if(!extstrtoaddr(s, &mom->addr, &mom->addrlen))
fatal_exit("bad infra_rtt address %s", s);
@ -361,10 +361,10 @@ replay_moment_read(char* remain, FILE* in, const char* name,
free(mom);
return NULL;
}
while(isspace((int)*remain))
while(isspace((unsigned char)*remain))
remain++;
if(parse_keyword(&remain, "ADDRESS")) {
while(isspace((int)*remain))
while(isspace((unsigned char)*remain))
remain++;
if(strlen(remain) > 0) /* remove \n */
remain[strlen(remain)-1] = 0;
@ -408,7 +408,7 @@ static struct replay_scenario*
make_scenario(char* line)
{
struct replay_scenario* scen;
while(isspace((int)*line))
while(isspace((unsigned char)*line))
line++;
if(!*line) {
log_err("scenario: no title given");
@ -442,7 +442,7 @@ replay_scenario_read(FILE* in, const char* name, int* lineno)
parse=line;
pstate.lineno++;
(*lineno)++;
while(isspace((int)*parse))
while(isspace((unsigned char)*parse))
parse++;
if(!*parse)
continue; /* empty line */
@ -651,7 +651,7 @@ do_macro_variable(rbtree_t* store, char* buf, size_t remain)
char sv;
if(at[0]==0)
return NULL; /* no variable name after $ */
while(*at && (isalnum((int)*at) || *at=='_')) {
while(*at && (isalnum((unsigned char)*at) || *at=='_')) {
at++;
}
/* terminator, we are working in macro_expand() buffer */
@ -724,7 +724,7 @@ do_macro_arith(char* orig, size_t remain, char** arithstart)
/* remember start pos of expr, skip the first number */
at = orig;
*arithstart = at;
while(*at && (isdigit((int)*at) || *at == '.'))
while(*at && (isdigit((unsigned char)*at) || *at == '.'))
at++;
return at;
}
@ -737,7 +737,7 @@ do_macro_arith(char* orig, size_t remain, char** arithstart)
*arithstart = NULL;
return do_macro_arith(orig, remain, arithstart);
}
if(isdigit((int)operator)) {
if(isdigit((unsigned char)operator)) {
*arithstart = orig;
return at+skip; /* do nothing, but setup for later number */
}
@ -820,13 +820,13 @@ macro_expand(rbtree_t* store, struct replay_runtime* runtime, char** text)
at = do_macro_recursion(store, runtime, at, remain);
} else if(*at == '$') {
at = do_macro_variable(store, at, remain);
} else if(isdigit((int)*at)) {
} else if(isdigit((unsigned char)*at)) {
at = do_macro_arith(at, remain, &arithstart);
} else {
/* copy until whitespace or operator */
if(*at && (isalnum((int)*at) || *at=='_')) {
if(*at && (isalnum((unsigned char)*at) || *at=='_')) {
at++;
while(*at && (isalnum((int)*at) || *at=='_'))
while(*at && (isalnum((unsigned char)*at) || *at=='_'))
at++;
} else at++;
}

View file

@ -97,7 +97,7 @@ add_opts(const char* args, int* pass_argc, char* pass_argv[])
{
const char *p = args, *np;
size_t len;
while(p && isspace((int)*p))
while(p && isspace((unsigned char)*p))
p++;
while(p && *p) {
/* find location of next string and length of this one */
@ -115,7 +115,7 @@ add_opts(const char* args, int* pass_argc, char* pass_argv[])
(*pass_argc)++;
/* go to next option */
p = np;
while(p && isspace((int)*p))
while(p && isspace((unsigned char)*p))
p++;
}
}
@ -140,7 +140,7 @@ spool_auto_file(FILE* in, int* lineno, FILE* cfg, char* id)
char* parse;
FILE* spool;
/* find filename for new file */
while(isspace((int)*id))
while(isspace((unsigned char)*id))
id++;
if(strlen(id)==0)
fatal_exit("AUTROTRUST_FILE must have id, line %d", *lineno);
@ -158,7 +158,7 @@ spool_auto_file(FILE* in, int* lineno, FILE* cfg, char* id)
while(fgets(line, MAX_LINE_LEN-1, in)) {
parse = line;
(*lineno)++;
while(isspace((int)*parse))
while(isspace((unsigned char)*parse))
parse++;
if(strncmp(parse, "AUTOTRUST_END", 13) == 0) {
fclose(spool);
@ -197,7 +197,7 @@ setup_config(FILE* in, int* lineno, int* pass_argc, char* pass_argv[])
while(fgets(line, MAX_LINE_LEN-1, in)) {
parse = line;
(*lineno)++;
while(isspace((int)*parse))
while(isspace((unsigned char)*parse))
parse++;
if(!*parse || parse[0] == ';')
continue;

View file

@ -81,7 +81,7 @@ static int str_keyword(char** str, const char* keyword)
if(strncmp(*str, keyword, len) != 0)
return 0;
*str += len;
while(isspace((int)**str))
while(isspace((unsigned char)**str))
(*str)++;
return 1;
}
@ -138,7 +138,7 @@ static void matchline(char* line, struct entry* e)
error("expected = or : in MATCH: %s", line);
parse++;
e->ixfr_soa_serial = (uint32_t)strtol(parse, (char**)&parse, 10);
while(isspace((int)*parse))
while(isspace((unsigned char)*parse))
parse++;
} else {
error("could not parse MATCH: '%s'", parse);
@ -226,11 +226,11 @@ static void adjustline(char* line, struct entry* e,
e->copy_query = 1;
} else if(str_keyword(&parse, "sleep=")) {
e->sleeptime = (unsigned int) strtol(parse, (char**)&parse, 10);
while(isspace((int)*parse))
while(isspace((unsigned char)*parse))
parse++;
} else if(str_keyword(&parse, "packet_sleep=")) {
pkt->packet_sleep = (unsigned int) strtol(parse, (char**)&parse, 10);
while(isspace((int)*parse))
while(isspace((unsigned char)*parse))
parse++;
} else {
error("could not parse ADJUST: '%s'", parse);
@ -344,7 +344,7 @@ hex_buffer2wire(sldns_buffer *data_buffer)
for (data_buf_pos = 0; data_buf_pos < sldns_buffer_position(data_buffer); data_buf_pos++) {
c = (int) data_wire[data_buf_pos];
if (state < 2 && !isascii(c)) {
if (state < 2 && !isascii((unsigned char)c)) {
/*verbose("non ascii character found in file: (%d) switching to raw mode\n", c);*/
state = 2;
}
@ -422,7 +422,7 @@ get_origin(const char* name, struct sldns_file_parse_state* pstate, char* parse)
int status;
end=parse;
while(!isspace((int)*end) && !isendline(*end))
while(!isspace((unsigned char)*end) && !isendline(*end))
end++;
store = *end;
*end = 0;
@ -518,7 +518,7 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
parse = line;
pstate->lineno++;
while(isspace((int)*parse))
while(isspace((unsigned char)*parse))
parse++;
/* test for keywords */
if(isendline(*parse))

View file

@ -1105,7 +1105,7 @@ cfg_count_numbers(const char* s)
/* sp ::= (space|tab)* */
int num = 0;
while(*s) {
while(*s && isspace((int)*s))
while(*s && isspace((unsigned char)*s))
s++;
if(!*s) /* end of string */
break;
@ -1113,9 +1113,9 @@ cfg_count_numbers(const char* s)
s++;
if(!*s) /* only - not allowed */
return 0;
if(!isdigit((int)*s)) /* bad character */
if(!isdigit((unsigned char)*s)) /* bad character */
return 0;
while(*s && isdigit((int)*s))
while(*s && isdigit((unsigned char)*s))
s++;
num++;
}
@ -1127,7 +1127,7 @@ static int isalldigit(const char* str, size_t l)
{
size_t i;
for(i=0; i<l; i++)
if(!isdigit(str[i]))
if(!isdigit((unsigned char)str[i]))
return 0;
return 1;
}
@ -1153,13 +1153,13 @@ cfg_parse_memsize(const char* str, size_t* res)
else if(len > 1 && str[len-1] == 'B')
len--;
if(len > 1 && tolower(str[len-1]) == 'g')
if(len > 1 && tolower((unsigned char)str[len-1]) == 'g')
mult = 1024*1024*1024;
else if(len > 1 && tolower(str[len-1]) == 'm')
else if(len > 1 && tolower((unsigned char)str[len-1]) == 'm')
mult = 1024*1024;
else if(len > 1 && tolower(str[len-1]) == 'k')
else if(len > 1 && tolower((unsigned char)str[len-1]) == 'k')
mult = 1024;
else if(len > 0 && isdigit(str[len-1]))
else if(len > 0 && isdigit((unsigned char)str[len-1]))
mult = 1;
else {
log_err("unknown size specifier: '%s'", str);
@ -1322,7 +1322,7 @@ cfg_parse_local_zone(struct config_file* cfg, const char* val)
/* parse it as: [zone_name] [between stuff] [zone_type] */
name = val;
while(*name && isspace(*name))
while(*name && isspace((unsigned char)*name))
name++;
if(!*name) {
log_err("syntax error: too short: %s", val);
@ -1341,7 +1341,7 @@ cfg_parse_local_zone(struct config_file* cfg, const char* val)
buf[name_end-name] = '\0';
type = last_space_pos(name_end);
while(type && *type && isspace(*type))
while(type && *type && isspace((unsigned char)*type))
type++;
if(!type || !*type) {
log_err("syntax error: expected zone type: %s", val);
@ -1368,7 +1368,7 @@ char* cfg_ptr_reverse(char* str)
/* parse it as: [IP] [between stuff] [name] */
ip = str;
while(*ip && isspace(*ip))
while(*ip && isspace((unsigned char)*ip))
ip++;
if(!*ip) {
log_err("syntax error: too short: %s", str);
@ -1423,7 +1423,7 @@ char* cfg_ptr_reverse(char* str)
}
/* printed the reverse address, now the between goop and name on end */
while(*ip_end && isspace(*ip_end))
while(*ip_end && isspace((unsigned char)*ip_end))
ip_end++;
if(name>ip_end) {
snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%.*s",

View file

@ -10,7 +10,7 @@
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
#define YY_FLEX_SUBMINOR_VERSION 36
#define YY_FLEX_SUBMINOR_VERSION 37
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
@ -3787,7 +3787,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
int i;
yy_size_t i;
/* Get memory for full buffer, including space for trailing EOB's. */
n = _yybytes_len + 2;

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 2.6.1. */
/* A Bison parser, made by GNU Bison 2.7. */
/* Bison interface for Yacc-like parsers in C
@ -30,8 +30,8 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
#ifndef YY_UTIL_CONFIGPARSER_H
# define YY_UTIL_CONFIGPARSER_H
#ifndef YY_YY_UTIL_CONFIGPARSER_H_INCLUDED
# define YY_YY_UTIL_CONFIGPARSER_H_INCLUDED
/* Enabling traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
@ -347,13 +347,13 @@ extern int yydebug;
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
/* Line 2049 of yacc.c */
/* Line 2058 of yacc.c */
#line 64 "./util/configparser.y"
char* str;
/* Line 2049 of yacc.c */
/* Line 2058 of yacc.c */
#line 358 "util/configparser.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
@ -377,4 +377,4 @@ int yyparse ();
#endif
#endif /* ! YYPARSE_PARAM */
#endif /* !YY_UTIL_CONFIGPARSER_H */
#endif /* !YY_YY_UTIL_CONFIGPARSER_H_INCLUDED */

View file

@ -114,8 +114,8 @@ query_dname_compare(register uint8_t* d1, register uint8_t* d2)
while(lab1--) {
/* compare bytes first for speed */
if(*d1 != *d2 &&
tolower((int)*d1) != tolower((int)*d2)) {
if(tolower((int)*d1) < tolower((int)*d2))
tolower((unsigned char)*d1) != tolower((unsigned char)*d2)) {
if(tolower((unsigned char)*d1) < tolower((unsigned char)*d2))
return -1;
return 1;
}
@ -138,7 +138,7 @@ query_dname_tolower(uint8_t* dname)
while(labellen) {
dname++;
while(labellen--) {
*dname = (uint8_t)tolower((int)*dname);
*dname = (uint8_t)tolower((unsigned char)*dname);
dname++;
}
labellen = *dname;
@ -167,7 +167,7 @@ pkt_dname_tolower(sldns_buffer* pkt, uint8_t* dname)
if(dname+lablen >= sldns_buffer_end(pkt))
return;
while(lablen--) {
*dname = (uint8_t)tolower((int)*dname);
*dname = (uint8_t)tolower((unsigned char)*dname);
dname++;
}
if(dname >= sldns_buffer_end(pkt))
@ -256,8 +256,8 @@ dname_pkt_compare(sldns_buffer* pkt, uint8_t* d1, uint8_t* d2)
log_assert(len1 == len2 && len1 != 0);
/* compare labels */
while(len1--) {
if(tolower((int)*d1++) != tolower((int)*d2++)) {
if(tolower((int)d1[-1]) < tolower((int)d2[-1]))
if(tolower((unsigned char)*d1++) != tolower((unsigned char)*d2++)) {
if(tolower((unsigned char)d1[-1]) < tolower((unsigned char)d2[-1]))
return -1;
return 1;
}
@ -282,7 +282,7 @@ dname_query_hash(uint8_t* dname, hashvalue_t h)
labuf[0] = lablen;
i=0;
while(lablen--)
labuf[++i] = (uint8_t)tolower((int)*dname++);
labuf[++i] = (uint8_t)tolower((unsigned char)*dname++);
h = hashlittle(labuf, labuf[0] + 1, h);
lablen = *dname++;
}
@ -310,7 +310,7 @@ dname_pkt_hash(sldns_buffer* pkt, uint8_t* dname, hashvalue_t h)
labuf[0] = lablen;
i=0;
while(lablen--)
labuf[++i] = (uint8_t)tolower((int)*dname++);
labuf[++i] = (uint8_t)tolower((unsigned char)*dname++);
h = hashlittle(labuf, labuf[0] + 1, h);
lablen = *dname++;
}
@ -423,8 +423,8 @@ static int
memlowercmp(uint8_t* p1, uint8_t* p2, uint8_t len)
{
while(len--) {
if(*p1 != *p2 && tolower((int)*p1) != tolower((int)*p2)) {
if(tolower((int)*p1) < tolower((int)*p2))
if(*p1 != *p2 && tolower((unsigned char)*p1) != tolower((unsigned char)*p2)) {
if(tolower((unsigned char)*p1) < tolower((unsigned char)*p2))
return -1;
return 1;
}
@ -480,10 +480,10 @@ dname_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, int* mlabs)
* lastdiff = c;
* lastmlabs = atlabel; } apart from d1++,d2++ */
while(len1) {
if(*d1 != *d2 && tolower((int)*d1)
!= tolower((int)*d2)) {
if(tolower((int)*d1) <
tolower((int)*d2)) {
if(*d1 != *d2 && tolower((unsigned char)*d1)
!= tolower((unsigned char)*d2)) {
if(tolower((unsigned char)*d1) <
tolower((unsigned char)*d2)) {
lastdiff = -1;
lastmlabs = atlabel;
d1 += len1;
@ -561,7 +561,7 @@ void dname_str(uint8_t* dname, char* str)
return;
}
while(lablen--) {
if(isalnum((int)*dname)
if(isalnum((unsigned char)*dname)
|| *dname == '-' || *dname == '_'
|| *dname == '*')
*s++ = *(char*)dname++;

View file

@ -576,10 +576,12 @@ reply_info_delete(void* d, void* ATTR_UNUSED(arg))
}
hashvalue_t
query_info_hash(struct query_info *q)
query_info_hash(struct query_info *q, uint16_t flags)
{
hashvalue_t h = 0xab;
h = hashlittle(&q->qtype, sizeof(q->qtype), h);
if(q->qtype == LDNS_RR_TYPE_AAAA && (flags&BIT_CD))
h++;
h = hashlittle(&q->qclass, sizeof(q->qclass), h);
h = dname_query_hash(q->qname, h);
return h;
@ -771,15 +773,14 @@ log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep)
region, 65535, 1)) {
log_info("%s: log_dns_msg: out of memory", str);
} else {
char* str = sldns_wire2str_pkt(sldns_buffer_begin(buf),
char* s = sldns_wire2str_pkt(sldns_buffer_begin(buf),
sldns_buffer_limit(buf));
if(!str) {
if(!s) {
log_info("%s: log_dns_msg: ldns tostr failed", str);
} else {
log_info("%s %s",
str, (char*)sldns_buffer_begin(buf));
log_info("%s %s", str, s);
}
free(str);
free(s);
}
sldns_buffer_free(buf);
regional_destroy(region);

View file

@ -305,8 +305,9 @@ void query_entry_delete(void *q, void* arg);
/** delete reply_info data structure */
void reply_info_delete(void* d, void* arg);
/** calculate hash value of query_info, lowercases the qname */
hashvalue_t query_info_hash(struct query_info *q);
/** calculate hash value of query_info, lowercases the qname,
* uses CD flag for AAAA qtype */
hashvalue_t query_info_hash(struct query_info *q, uint16_t flags);
/**
* Setup query info entry

View file

@ -280,7 +280,7 @@ fptr_whitelist_modenv_detach_subs(void (*fptr)(
int
fptr_whitelist_modenv_attach_sub(int (*fptr)(
struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, struct module_qstate** newq))
uint16_t qflags, int prime, int valrec, struct module_qstate** newq))
{
if(fptr == &mesh_attach_sub) return 1;
return 0;
@ -296,7 +296,7 @@ fptr_whitelist_modenv_kill_sub(void (*fptr)(struct module_qstate* newq))
int
fptr_whitelist_modenv_detect_cycle(int (*fptr)(
struct module_qstate* qstate, struct query_info* qinfo,
uint16_t flags, int prime))
uint16_t flags, int prime, int valrec))
{
if(fptr == &mesh_detect_cycle) return 1;
return 0;

View file

@ -233,7 +233,7 @@ int fptr_whitelist_modenv_detach_subs(void (*fptr)(
*/
int fptr_whitelist_modenv_attach_sub(int (*fptr)(
struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, struct module_qstate** newq));
uint16_t qflags, int prime, int valrec, struct module_qstate** newq));
/**
* Check function pointer whitelist for module_env kill_sub callback values.
@ -251,7 +251,7 @@ int fptr_whitelist_modenv_kill_sub(void (*fptr)(struct module_qstate* newq));
*/
int fptr_whitelist_modenv_detect_cycle(int (*fptr)(
struct module_qstate* qstate, struct query_info* qinfo,
uint16_t flags, int prime));
uint16_t flags, int prime, int valrec));
/**
* Check function pointer whitelist for module init call values.

View file

@ -2061,6 +2061,7 @@
2423,
2424,
2425,
2426,
2427,
2428,
2429,
@ -3964,6 +3965,7 @@
4785,
4789,
4790,
4791,
4800,
4801,
4802,
@ -4225,6 +4227,7 @@
5463,
5464,
5465,
5474,
5500,
5501,
5502,
@ -5351,9 +5354,11 @@
35004,
35355,
36001,
36411,
36865,
37475,
37654,
38002,
38201,
38202,
38203,

View file

@ -58,6 +58,21 @@
#define HAVE_EVENT_BASE_FREE
#endif
/* redefine to use our own namespace so that on platforms where
* linkers crosslink library-private symbols with other symbols, it works */
#define event_init minievent_init
#define event_get_version minievent_get_version
#define event_get_method minievent_get_method
#define event_base_dispatch minievent_base_dispatch
#define event_base_loopexit minievent_base_loopexit
#define event_base_free minievent_base_free
#define event_set minievent_set
#define event_base_set minievent_base_set
#define event_add minievent_add
#define event_del minievent_del
#define signal_add minisignal_add
#define signal_del minisignal_del
/** event timeout */
#define EV_TIMEOUT 0x01
/** event fd readable */

View file

@ -256,13 +256,14 @@ struct module_env {
* @param qinfo: what to query for (copied).
* @param qflags: what flags to use (RD, CD flag or not).
* @param prime: if it is a (stub) priming query.
* @param valrec: validation lookup recursion, does not need validation
* @param newq: If the new subquery needs initialisation, it is
* returned, otherwise NULL is returned.
* @return: false on error, true if success (and init may be needed).
*/
int (*attach_sub)(struct module_qstate* qstate,
struct query_info* qinfo, uint16_t qflags, int prime,
struct module_qstate** newq);
int valrec, struct module_qstate** newq);
/**
* Kill newly attached sub. If attach_sub returns newq for
@ -280,13 +281,15 @@ struct module_env {
* @param qinfo: query info for dependency.
* @param flags: query flags of dependency, RD/CD flags.
* @param prime: if dependency is a priming query or not.
* @param valrec: validation lookup recursion, does not need validation
* @return true if the name,type,class exists and the given
* qstate mesh exists as a dependency of that name. Thus
* if qstate becomes dependent on name,type,class then a
* cycle is created.
*/
int (*detect_cycle)(struct module_qstate* qstate,
struct query_info* qinfo, uint16_t flags, int prime);
struct query_info* qinfo, uint16_t flags, int prime,
int valrec);
/** region for temporary usage. May be cleared after operate() call. */
struct regional* scratch;
@ -397,6 +400,9 @@ struct module_qstate {
uint16_t query_flags;
/** if this is a (stub or root) priming query (with hints) */
int is_priming;
/** if this is a validation recursion query that does not get
* validation itself */
int is_valrec;
/** comm_reply contains server replies */
struct comm_reply* reply;

View file

@ -613,12 +613,17 @@ void* listen_sslctx_create(char* key, char* pem, char* verifypem)
log_crypto_err("could not SSL_CTX_new");
return NULL;
}
/* no SSLv2 because has defects */
/* no SSLv2, SSLv3 because has defects */
if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)){
log_crypto_err("could not set SSL_OP_NO_SSLv2");
SSL_CTX_free(ctx);
return NULL;
}
if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)){
log_crypto_err("could not set SSL_OP_NO_SSLv3");
SSL_CTX_free(ctx);
return NULL;
}
if(!SSL_CTX_use_certificate_file(ctx, pem, SSL_FILETYPE_PEM)) {
log_err("error for cert file: %s", pem);
log_crypto_err("error in SSL_CTX use_certificate_file");
@ -668,6 +673,11 @@ void* connect_sslctx_create(char* key, char* pem, char* verifypem)
SSL_CTX_free(ctx);
return NULL;
}
if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)) {
log_crypto_err("could not set SSL_OP_NO_SSLv3");
SSL_CTX_free(ctx);
return NULL;
}
if(key && key[0]) {
if(!SSL_CTX_use_certificate_file(ctx, pem, SSL_FILETYPE_PEM)) {
log_err("error in client certificate %s", pem);
@ -689,7 +699,7 @@ void* connect_sslctx_create(char* key, char* pem, char* verifypem)
}
}
if(verifypem && verifypem[0]) {
if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL) != 1) {
if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) {
log_crypto_err("error in SSL_CTX verify");
SSL_CTX_free(ctx);
return NULL;

View file

@ -90,6 +90,21 @@
#define HAVE_EVENT_BASE_FREE
#endif
/* redefine the calls to different names so that there is no name
* collision with other code that uses libevent names. (that uses libunbound)*/
#define event_init winsockevent_init
#define event_get_version winsockevent_get_version
#define event_get_method winsockevent_get_method
#define event_base_dispatch winsockevent_base_dispatch
#define event_base_loopexit winsockevent_base_loopexit
#define event_base_free winsockevent_base_free
#define event_set winsockevent_set
#define event_base_set winsockevent_base_set
#define event_add winsockevent_add
#define event_del winsockevent_del
#define signal_add winsocksignal_add
#define signal_del winsocksignal_del
/** event timeout */
#define EV_TIMEOUT 0x01
/** event fd readable */

View file

@ -902,13 +902,13 @@ static int
handle_origin(char* line, uint8_t** origin, size_t* origin_len)
{
size_t len = 0;
while(isspace((int)*line))
while(isspace((unsigned char)*line))
line++;
if(strncmp(line, "$ORIGIN", 7) != 0)
return 0;
free(*origin);
line += 7;
while(isspace((int)*line))
while(isspace((unsigned char)*line))
line++;
*origin = sldns_str2wire_dname(line, &len);
*origin_len = len;

View file

@ -563,7 +563,7 @@ readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments)
/* not a comment, complete the keyword */
if(numdone > 0) {
/* check same type */
if(isspace(c)) {
if(isspace((unsigned char)c)) {
ungetc(c, in);
return numdone;
}
@ -582,12 +582,12 @@ readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments)
}
sldns_buffer_write_u8(buf, (uint8_t)c);
numdone++;
if(isspace(c)) {
if(isspace((unsigned char)c)) {
/* collate whitespace into ' ' */
while((c = getc(in)) != EOF ) {
if(c == '\n')
(*line)++;
if(!isspace(c)) {
if(!isspace((unsigned char)c)) {
ungetc(c, in);
break;
}
@ -607,7 +607,7 @@ skip_to_special(FILE* in, sldns_buffer* buf, int* line, int spec)
int rdlen;
sldns_buffer_clear(buf);
while((rdlen=readkeyword_bindfile(in, buf, line, 1))) {
if(rdlen == 1 && isspace((int)*sldns_buffer_begin(buf))) {
if(rdlen == 1 && isspace((unsigned char)*sldns_buffer_begin(buf))) {
sldns_buffer_clear(buf);
continue;
}
@ -648,7 +648,7 @@ process_bind_contents(struct val_anchors* anchors, sldns_buffer* buf,
sldns_buffer_clear(buf);
while((rdlen=readkeyword_bindfile(in, buf, line, comments))) {
if(rdlen == 1 && sldns_buffer_position(buf) == 1
&& isspace((int)*sldns_buffer_begin(buf))) {
&& isspace((unsigned char)*sldns_buffer_begin(buf))) {
/* starting whitespace is removed */
sldns_buffer_clear(buf);
continue;
@ -703,7 +703,7 @@ process_bind_contents(struct val_anchors* anchors, sldns_buffer* buf,
}
return 1;
} else if(rdlen == 1 &&
isspace((int)sldns_buffer_current(buf)[-1])) {
isspace((unsigned char)sldns_buffer_current(buf)[-1])) {
/* leave whitespace here */
} else {
/* not space or whatnot, so actual content */

View file

@ -731,8 +731,8 @@ label_compare_lower(uint8_t* lab1, uint8_t* lab2, size_t lablen)
{
size_t i;
for(i=0; i<lablen; i++) {
if(tolower((int)*lab1) != tolower((int)*lab2)) {
if(tolower((int)*lab1) < tolower((int)*lab2))
if(tolower((unsigned char)*lab1) != tolower((unsigned char)*lab2)) {
if(tolower((unsigned char)*lab1) < tolower((unsigned char)*lab2))
return -1;
return 1;
}

View file

@ -283,12 +283,25 @@ needs_validation(struct module_qstate* qstate, int ret_rc,
{
int rcode;
/* If the CD bit is on in the original request, then we don't bother to
* validate anything.*/
/* If the CD bit is on in the original request, then you could think
* that we don't bother to validate anything.
* But this is signalled internally with the valrec flag.
* User queries are validated with BIT_CD to make our cache clean
* so that bogus messages get retried by the upstream also for
* downstream validators that set BIT_CD.
* For DNS64 bit_cd signals no dns64 processing, but we want to
* provide validation there too */
/*
if(qstate->query_flags & BIT_CD) {
verbose(VERB_ALGO, "not validating response due to CD bit");
return 0;
}
*/
if(qstate->is_valrec) {
verbose(VERB_ALGO, "not validating response, is valrec"
"(validation recursion lookup)");
return 0;
}
if(ret_rc != LDNS_RCODE_NOERROR || !ret_msg)
rcode = ret_rc;
@ -351,14 +364,20 @@ generate_request(struct module_qstate* qstate, int id, uint8_t* name,
struct val_qstate* vq = (struct val_qstate*)qstate->minfo[id];
struct module_qstate* newq;
struct query_info ask;
int valrec;
ask.qname = name;
ask.qname_len = namelen;
ask.qtype = qtype;
ask.qclass = qclass;
log_query_info(VERB_ALGO, "generate request", &ask);
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
/* enable valrec flag to avoid recursion to the same validation
* routine, this lookup is simply a lookup. DLVs need validation */
if(qtype == LDNS_RR_TYPE_DLV)
valrec = 0;
else valrec = 1;
if(!(*qstate->env->attach_sub)(qstate, &ask,
(uint16_t)(BIT_RD|flags), 0, &newq)){
(uint16_t)(BIT_RD|flags), 0, valrec, &newq)){
log_err("Could not generate request: out of memory");
return 0;
}
@ -2005,14 +2024,16 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
/* if secure, this will override cache anyway, no need
* to check if from parentNS */
if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo,
vq->orig_msg->rep, 0, qstate->prefetch_leeway, 0, NULL)) {
vq->orig_msg->rep, 0, qstate->prefetch_leeway, 0, NULL,
qstate->query_flags)) {
log_err("out of memory caching validator results");
}
} else {
/* for a referral, store the verified RRsets */
/* and this does not get prefetched, so no leeway */
if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo,
vq->orig_msg->rep, 1, 0, 0, NULL)) {
vq->orig_msg->rep, 1, 0, 0, NULL,
qstate->query_flags)) {
log_err("out of memory caching validator results");
}
}