diff --git a/.travis.yml b/.travis.yml index 60a37347..2cace3f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,4 +21,4 @@ script: - mkdir tests - cd tests - ../src/test/tpkg/run-all.sh -# - ../src/test/tpkg/run-one.sh 400-static-analysis -V +# - ../src/test/tpkg/run-one.sh 225-stub-only-valgrind-checks diff --git a/ChangeLog b/ChangeLog index 69d8872b..133ccbdb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +* 201?-??-??: Version 1.?.? + * Bugfix #359: edns_client_subnet_private should set family + Thanks Daniel Areiza + * 2017-11-11: Version 1.2.1 * Handle more I/O error cases. Also, when an I/O error does occur, never stop listening (with servers), and diff --git a/src/context.c b/src/context.c index 09718efb..9f84248a 100644 --- a/src/context.c +++ b/src/context.c @@ -1570,10 +1570,6 @@ getdns_context_create_with_extended_memory_functions2( result->fchg_resolvconf = NULL; result->fchg_hosts = NULL; - // resolv.conf does not exist on Windows, handle differently - if (resolvconf_file && (r = set_os_defaults(result, resolvconf_file))) - goto error; - result->dnssec_allowed_skew = 0; result->edns_maximum_udp_payload_size = -1; if ((r = create_default_dns_transports(result))) @@ -1625,6 +1621,14 @@ getdns_context_create_with_extended_memory_functions2( create_local_hosts(result); + // resolv.conf does not exist on Windows, handle differently +#ifndef USE_WINSOCK + if ((set_from_os & 1) && (r = set_os_defaults(result, resolvconf_file))) + goto error; +#else + if ((set_from_os & 1) && (r = set_os_defaults_windows(result))) + goto error; +#endif *context = result; return GETDNS_RETURN_GOOD; diff --git a/src/dnssec.c b/src/dnssec.c index 4e1fc392..d4c6375b 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -3160,12 +3160,19 @@ static void check_chain_complete(chain_head *chain) _getdns_context_update_root_ksk(context,&node->dnskey); } else if (_getdns_bogus(dnsreq)) { + _getdns_rrsig_iter rrsig_spc; DEBUG_ANCHOR("Request was bogus!\n"); if ((head = chain) && (node = _to_the_root(head->parent)) + /* The root DNSKEY rrset */ && node->dnskey.name && *node->dnskey.name == 0 + /* We queried it and had a response */ && node->dnskey_req - && node->dnskey_req->dnssec_status == GETDNS_DNSSEC_BOGUS){ + /* The response was bogus */ + && node->dnskey_req->dnssec_status == GETDNS_DNSSEC_BOGUS + /* The response was bogus, but not because it has no rrsigs */ + && _getdns_rrsig_iter_init(&rrsig_spc, &node->dnskey) + ){ DEBUG_ANCHOR("root DNSKEY set was bogus!\n"); if (!dnsreq->waiting_for_ta) { @@ -3395,10 +3402,21 @@ void _getdns_validation_chain_timeout(getdns_dns_req *dnsreq) void _getdns_cancel_validation_chain(getdns_dns_req *dnsreq) { - chain_head *head = dnsreq->chain, *next, *dnskey_head; + chain_head *head, *next; chain_node *node; size_t node_count; + /* Clear nodes under direct DNSKEY queries. + * They share the DNSKEY lookup netreq, but _dnskey_query() can not + * be used because we're free'ing the heads. + */ + for (head = dnsreq->chain; head; head = head->next) { + if ( head->rrset.rr_type == GETDNS_RRTYPE_DNSKEY + && head->node_count + && head->netreq == head->parent->dnskey_req) + head->parent->dnskey_req = NULL; + } + head = dnsreq->chain; dnsreq->chain = NULL; while (head) { next = head->next; @@ -3407,10 +3425,7 @@ void _getdns_cancel_validation_chain(getdns_dns_req *dnsreq) ; node_count ; node_count--, node = node->parent ) { - if (node->dnskey_req && - !( (dnskey_head = _dnskey_query(node)) - && dnskey_head->netreq == node->dnskey_req)) - + if (node->dnskey_req) _getdns_context_cancel_request( node->dnskey_req->owner); diff --git a/src/general.c b/src/general.c index b263c0a9..80b40a2c 100644 --- a/src/general.c +++ b/src/general.c @@ -116,7 +116,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) /* Do we have to check more suffixes on nxdomain/nodata? */ - if (dns_req->is_dns_request && + if (dns_req->is_dns_request == 1 && dns_req->suffix_appended && /* Something was appended */ dns_req->suffix_len > 1 && /* Next suffix available */ no_answer(dns_req)) { @@ -153,7 +153,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) return; } } else if ( - dns_req->is_dns_request && + dns_req->is_dns_request == 1 && ( dns_req->append_name == GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE || dns_req->append_name == @@ -206,7 +206,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) } else if (! results_found) _getdns_call_user_callback(dns_req, NULL); else if ( - dns_req->is_dns_request && + dns_req->is_dns_request == 1 && (dns_req->dnssec_return_validation_chain #ifdef DNSSEC_ROADBLOCK_AVOIDANCE || ( dns_req->dnssec_roadblock_avoidance @@ -343,7 +343,7 @@ _getdns_netreq_change_state( if (!netreq) return; - if (!netreq->owner->is_dns_request) { + if (netreq->owner->is_dns_request == 0) { netreq->state = new_state; return; } diff --git a/src/request-internal.c b/src/request-internal.c index c9f27db0..b78c19ab 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -866,6 +866,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, if (! (region = GETDNS_XMALLOC(context->mf, uint8_t, dnsreq_base_sz + (a_aaaa_query ? 2 : 1) * netreq_sz))) return NULL; + (void) memset(region, 0, sizeof(getdns_dns_req)); result = (getdns_dns_req *)region; result->netreqs[0] = (getdns_network_req *)(region + dnsreq_base_sz); diff --git a/src/stub.c b/src/stub.c index 10745928..d8da9a9c 100644 --- a/src/stub.c +++ b/src/stub.c @@ -151,15 +151,19 @@ calc_new_cookie(getdns_upstream *upstream, uint8_t *cookie) static getdns_return_t attach_edns_client_subnet_private(getdns_network_req *req) { - /* see - * https://tools.ietf.org/html/draft-ietf-dnsop-edns-client-subnet-04#section-6 */ - /* all-zeros is a request to not leak the data further: */ - /* "\x00\x00" FAMILY: 0 (because no address) */ - /* "\x00" SOURCE PREFIX-LENGTH: 0 */ - /* "\x00"; SCOPE PREFIX-LENGTH: 0 */ - return _getdns_network_req_add_upstream_option(req, - GLDNS_EDNS_CLIENT_SUBNET, - 4, NULL); + /* see https://tools.ietf.org/html/rfc7871#section-7.1.2 + * all-zeros is a request to not leak the data further: + * A two byte FAMILY field is a SHOULD even when SOURCE + * and SCOPE are 0. + * "\x00\x02" FAMILY: 2 for IPv6 upstreams in network byte order, or + * "\x00\x01" FAMILY: 1 for IPv4 upstreams in network byte order, then: + * "\x00" SOURCE PREFIX-LENGTH: 0 + * "\x00"; SCOPE PREFIX-LENGTH: 0 + */ + return _getdns_network_req_add_upstream_option( + req, GLDNS_EDNS_CLIENT_SUBNET, 4, + ( req->upstream->addr.ss_family == AF_INET6 + ? "\x00\x02\x00\x00" : "\x00\x01\x00\x00" )); } static getdns_return_t diff --git a/src/test/tpkg/125-valgrind-checks.tpkg/125-valgrind-checks.test b/src/test/tpkg/125-valgrind-checks.tpkg/125-valgrind-checks.test index 0e7c4981..4ea22337 100644 --- a/src/test/tpkg/125-valgrind-checks.tpkg/125-valgrind-checks.test +++ b/src/test/tpkg/125-valgrind-checks.tpkg/125-valgrind-checks.test @@ -32,3 +32,9 @@ then cat output exit 1 fi +if ! awk '/^==.* ERROR SUMMARY/{print;if($4>0)exit(1)}' valgrind.log +then + cat valgrind.log + cat output + exit 1 +fi diff --git a/src/test/tpkg/225-stub-only-valgrind-checks.tpkg/225-stub-only-valgrind-checks.test b/src/test/tpkg/225-stub-only-valgrind-checks.tpkg/225-stub-only-valgrind-checks.test index 94bd6d2f..1c957404 100644 --- a/src/test/tpkg/225-stub-only-valgrind-checks.tpkg/225-stub-only-valgrind-checks.test +++ b/src/test/tpkg/225-stub-only-valgrind-checks.tpkg/225-stub-only-valgrind-checks.test @@ -11,6 +11,7 @@ qwerlkjhasdfpuiqwyerm.1234kjhrqwersv.com -G TXT bogus.nlnetlabs.nl -H 8.8.8.8 -H 2a04:b900:0:100::37 +-A _acme-challenge.getdnsapi.net EOT ( if ! "${BUILDDIR}/build-stub-only/libtool" exec valgrind -v --log-file=valgrind.log --leak-check=full --error-exitcode=1 --track-origins=yes "${GETDNS_STUB_QUERY}" -F queries -f "${TPKG_NAME}.ds" +dnssec_return_validation_chain @@ -24,3 +25,9 @@ then cat output exit 1 fi +if ! awk '/^==.* ERROR SUMMARY/{print;if($4>0)exit(1)}' valgrind.log +then + cat valgrind.log + cat output + exit 1 +fi diff --git a/src/test/tpkg/run-one.sh b/src/test/tpkg/run-one.sh index 4c2ca485..10795374 100755 --- a/src/test/tpkg/run-one.sh +++ b/src/test/tpkg/run-one.sh @@ -8,3 +8,4 @@ ONE_TEST=$1 shift "${TPKG}" $* exe ${SRCDIR}/${ONE_TEST}.tpkg +"${TPKG}" -n -1 r