diff --git a/configure.ac b/configure.ac index b4409fa3..439bbc4d 100644 --- a/configure.ac +++ b/configure.ac @@ -392,7 +392,14 @@ case "$enable_ecdsa" in ;; esac - +AC_ARG_ENABLE(draft-dnssec-roadblock-avoidance, AC_HELP_STRING([--enable-draft-dnssec-roadblock-avoidance], [Enable experimental dnssec roadblock avoidance])) +case "$enable_draft_dnssec_roadblock_avoidance" in + yes) + AC_DEFINE_UNQUOTED([DNSSEC_ROADBLOCK_AVOIDANCE], [1], [Define this to enable the experimental draft dnssec roadblock avoidance.]) + ;; + no|*) + ;; +esac AC_ARG_ENABLE(draft-edns-cookies, AC_HELP_STRING([--enable-draft-edns-cookies], [Enable experimental edns cookies])) case "$enable_draft_edns_cookies" in diff --git a/src/dnssec.c b/src/dnssec.c index 780ac6de..1629764e 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -3088,6 +3088,25 @@ static void check_chain_complete(chain_head *chain) chain, rrset_iter_init( &tas_iter , context->trust_anchors , context->trust_anchors_len)); +#endif +#ifdef DNSSEC_ROADBLOCK_AVOIDANCE + if ( dnsreq->dnssec_roadblock_avoidance + && dnsreq->netreqs[0]->dnssec_status == GETDNS_DNSSEC_BOGUS) { + + getdns_return_t r = GETDNS_RETURN_GOOD; + getdns_network_req **netreq_p, *netreq; + + dnsreq->avoid_dnssec_roadblocks = 1; + + for ( netreq_p = dnsreq->netreqs + ; !r && (netreq = *netreq_p) + ; netreq_p++) { + + netreq->state = NET_REQ_NOT_SENT; + (void) _getdns_submit_netreq(netreq); + } + return; + } #endif val_chain_list = dnsreq->dnssec_return_validation_chain ? getdns_list_create_with_context(context) : NULL; diff --git a/src/general.c b/src/general.c index 2cb9b0f0..37688a09 100644 --- a/src/general.c +++ b/src/general.c @@ -128,14 +128,20 @@ ub_resolve_callback(void* arg, int err, struct ub_result* ub_res) #endif -static getdns_return_t -submit_network_request(getdns_network_req *netreq) +getdns_return_t +_getdns_submit_netreq(getdns_network_req *netreq) { getdns_return_t r; getdns_dns_req *dns_req = netreq->owner; char name[1024]; - if (dns_req->context->resolution_type == GETDNS_RESOLUTION_RECURSING + if ( +#ifdef STUB_NATIVE_DNSSEC +#ifdef DNSSEC_ROADBLOCK_AVOIDANCE + ( +#endif +#endif + dns_req->context->resolution_type == GETDNS_RESOLUTION_RECURSING /* TODO: Until DNSSEC with the new async stub resolver is finished, * use unbound when we need DNSSEC. */ @@ -143,6 +149,11 @@ submit_network_request(getdns_network_req *netreq) || dns_req->dnssec_return_status || dns_req->dnssec_return_only_secure || dns_req->dnssec_return_validation_chain +#else +#ifdef DNSSEC_ROADBLOCK_AVOIDANCE + && !dns_req->dnssec_roadblock_avoidance + ) || dns_req->avoid_dnssec_roadblocks +#endif #endif ) { @@ -217,7 +228,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, for ( netreq_p = req->netreqs ; !r && (netreq = *netreq_p) ; netreq_p++) - r = submit_network_request(netreq); + r = _getdns_submit_netreq(netreq); else for (i = 0; i < context->namespace_count; i++) { if (context->namespaces[i] == GETDNS_NAMESPACE_LOCALNAMES) { @@ -239,7 +250,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, for ( netreq_p = req->netreqs ; !r && (netreq = *netreq_p) ; netreq_p++) - r = submit_network_request(netreq); + r = _getdns_submit_netreq(netreq); break; } else r = GETDNS_RETURN_BAD_CONTEXT; diff --git a/src/general.h b/src/general.h index 94c32219..58201056 100644 --- a/src/general.h +++ b/src/general.h @@ -44,6 +44,8 @@ void _getdns_call_user_callback(getdns_dns_req *, getdns_dict *); void _getdns_check_dns_req_complete(getdns_dns_req *dns_req); +getdns_return_t _getdns_submit_netreq(getdns_network_req *netreq); + getdns_return_t _getdns_general_loop(getdns_context *context, getdns_eventloop *loop, diff --git a/src/request-internal.c b/src/request-internal.c index 30156724..a7e1b20c 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -372,6 +372,11 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, result->dnssec_return_only_secure = dnssec_return_only_secure; result->dnssec_return_validation_chain = dnssec_return_validation_chain; result->edns_cookies = edns_cookies; +#ifdef DNSSEC_ROADBLOCK_AVOIDANCE + result->dnssec_roadblock_avoidance = is_extension_set( + extensions, "dnssec_roadblock_avoidance"); + result->avoid_dnssec_roadblocks = 0; +#endif /* will be set by caller */ result->user_pointer = NULL; diff --git a/src/types-internal.h b/src/types-internal.h index 93b97973..11629d84 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -261,6 +261,10 @@ typedef struct getdns_dns_req { int dnssec_return_status; int dnssec_return_only_secure; int dnssec_return_validation_chain; +#ifdef DNSSEC_ROADBLOCK_AVOIDANCE + int dnssec_roadblock_avoidance; + int avoid_dnssec_roadblocks; +#endif int edns_cookies; /* Internally used by return_validation_chain */ diff --git a/src/util-internal.c b/src/util-internal.c index d6e9299e..48eefa17 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -63,6 +63,9 @@ static getdns_extension_format extformats[] = { {"dnssec_return_only_secure", t_int}, {"dnssec_return_status", t_int}, {"dnssec_return_validation_chain", t_int}, +#ifdef DNSSEC_ROADBLOCK_AVOIDANCE + {"dnssec_roadblock_avoidance", t_int}, +#endif #ifdef EDNS_COOKIES {"edns_cookies", t_int}, #endif