From b99b7511ecad1148dbe6b5907b282b28077cbe06 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 4 Jul 2016 12:58:23 +0200 Subject: [PATCH 01/24] Generalize str2ipaddr_dict conversion --- src/test/getdns_query.c | 84 ++++++++++++++++++++++++++++---------- src/test/getdns_str2dict.c | 57 ++++++++++++++++++-------- src/test/getdns_str2dict.h | 2 - src/test/jsmn | 2 +- 4 files changed, 104 insertions(+), 41 deletions(-) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index f38306a8..a2a463c0 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -499,8 +499,23 @@ getdns_return_t parse_args(int argc, char **argv) continue; } else if (arg[0] == '@') { - getdns_dict *upstream = _getdns_ipaddr_dict(arg + 1); - if (upstream) { + getdns_dict *upstream; + getdns_bindata *address; + + if ((r = getdns_str2dict(arg + 1, &upstream))) + fprintf(stderr, "Could not convert \"%s\" to " + "an IP dict: %s\n", arg + 1, + getdns_get_errorstr_by_id(r)); + + else if ((r = getdns_dict_get_bindata( + upstream, "address_data", &address))) { + + fprintf(stderr, "\"%s\" did not translate to " + "an IP dict: %s\n", arg + 1, + getdns_get_errorstr_by_id(r)); + + getdns_dict_destroy(upstream); + } else { if (!upstream_list && !(upstream_list = getdns_list_create_with_context(context))){ @@ -521,6 +536,9 @@ getdns_return_t parse_args(int argc, char **argv) continue; } for (c = arg+1; *c; c++) { + getdns_dict *downstream; + getdns_bindata *address; + switch (*c) { case 'a': async = 1; @@ -896,23 +914,33 @@ getdns_return_t parse_args(int argc, char **argv) DEBUG_SERVER("Clear listen list\n"); break; } - getdns_dict *downstream = - _getdns_ipaddr_dict(argv[i]); - if (!downstream) { - fprintf(stderr, "could not parse " - "listen address: %s", argv[i]); + + if ((r = getdns_str2dict(argv[i], &downstream))) + fprintf(stderr, "Could not convert \"%s\" to " + "an IP dict: %s\n", argv[i], + getdns_get_errorstr_by_id(r)); + + else if ((r = getdns_dict_get_bindata( + downstream, "address_data", &address))) { + + fprintf(stderr, "\"%s\" did not translate to " + "an IP dict: %s\n", argv[i], + getdns_get_errorstr_by_id(r)); + + getdns_dict_destroy(downstream); + } else { + if (!listen_list && + !(listen_list = + getdns_list_create_with_context(context))){ + fprintf(stderr, "Could not create " + "downstream list\n"); + return GETDNS_RETURN_MEMORY_ERROR; + } + getdns_list_set_dict(listen_list, + listen_count++, downstream); + getdns_dict_destroy(downstream); + touched_listen_list = 1; } - if (!listen_list && - !(listen_list = - getdns_list_create_with_context(context))){ - fprintf(stderr, "Could not create " - "downstram list\n"); - return GETDNS_RETURN_MEMORY_ERROR; - } - getdns_list_set_dict(listen_list, - listen_count++, downstream); - getdns_dict_destroy(downstream); - touched_listen_list = 1; break; default: fprintf(stderr, "Unknown option " @@ -976,14 +1004,26 @@ getdns_return_t do_the_call(void) { getdns_return_t r; getdns_dict *address = NULL; + getdns_bindata *address_bindata; getdns_dict *response = NULL; char *response_str; uint32_t status; - if (calltype == HOSTNAME && - !(address = _getdns_ipaddr_dict(name))) { - fprintf(stderr, "Could not convert \"%s\" " - "to an IP address", name); + if (calltype != HOSTNAME) + ; /* pass */ + + else if ((r = getdns_str2dict(name, &address))) { + + fprintf(stderr, "Could not convert \"%s\" to an IP dict: %s\n" + , name, getdns_get_errorstr_by_id(r)); + return GETDNS_RETURN_GOOD; + + } else if ((r = getdns_dict_get_bindata( + address, "address_data", &address_bindata))) { + + fprintf(stderr, "Could not convert \"%s\" to an IP dict: %s\n" + , name, getdns_get_errorstr_by_id(r)); + getdns_dict_destroy(address); return GETDNS_RETURN_GOOD; } if (async) { diff --git a/src/test/getdns_str2dict.c b/src/test/getdns_str2dict.c index 7cfc875c..ae5fb1d9 100644 --- a/src/test/getdns_str2dict.c +++ b/src/test/getdns_str2dict.c @@ -233,21 +233,6 @@ static int _jsmn_get_ipdict(struct mem_funcs *mf, const char *js, jsmntok_t *t, return *value != NULL; } -getdns_dict * -_getdns_ipaddr_dict(const char *ipstr) -{ - char value_str[3072]; - size_t size = strlen(ipstr); - - if (size >= sizeof(value_str)) - return NULL; - - (void) memcpy(value_str, ipstr, size); - value_str[size] = '\0'; - - return _getdns_ipaddr_dict_mf(&_getdns_plain_mem_funcs, value_str); -} - static int _jsmn_get_data(struct mem_funcs *mf, const char *js, jsmntok_t *t, getdns_bindata **value) { @@ -658,8 +643,48 @@ getdns_str2dict(const char *str, getdns_dict **dict) return r; else if (item.dtype != t_dict) { + uint8_t buf[16]; + getdns_dict *dict_r; + + if (item.dtype != t_bindata) + r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; + + else if (item.data.bindata->size == 4 && + inet_pton(AF_INET, str, buf) == 1) { + + if (!(dict_r = getdns_dict_create())) + r = GETDNS_RETURN_MEMORY_ERROR; + + else if ((r = getdns_dict_util_set_string( + dict_r, "address_type", "IPv4"))) + getdns_dict_destroy(dict_r); + + else if ((r = getdns_dict_set_bindata( + dict_r, "address_data", item.data.bindata))) + getdns_dict_destroy(dict_r); + else + *dict = dict_r; + + } else if (item.data.bindata->size == 16 && + inet_pton(AF_INET6, str, buf) == 1) { + + if (!(dict_r = getdns_dict_create())) + r = GETDNS_RETURN_MEMORY_ERROR; + + else if ((r = getdns_dict_util_set_string( + dict_r, "address_type", "IPv6"))) + getdns_dict_destroy(dict_r); + + else if ((r = getdns_dict_set_bindata( + dict_r, "address_data", item.data.bindata))) + getdns_dict_destroy(dict_r); + else + *dict = dict_r; + } else + r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; + _getdns_destroy_item_data(&_getdns_plain_mem_funcs, &item); - return GETDNS_RETURN_WRONG_TYPE_REQUESTED; + return r; } *dict = item.data.dict; return GETDNS_RETURN_GOOD; diff --git a/src/test/getdns_str2dict.h b/src/test/getdns_str2dict.h index f8d7e926..71cb26c8 100644 --- a/src/test/getdns_str2dict.h +++ b/src/test/getdns_str2dict.h @@ -29,8 +29,6 @@ #define GETDNS_STR2DICT_H_ #include "getdns/getdns.h" -getdns_dict *_getdns_ipaddr_dict(const char *ipstr); - getdns_return_t getdns_str2dict(const char *str, getdns_dict **dict); getdns_return_t getdns_str2list(const char *str, getdns_list **list); getdns_return_t getdns_str2bindata(const char *str, getdns_bindata **bindata); diff --git a/src/test/jsmn b/src/test/jsmn index daa17063..49024a6e 160000 --- a/src/test/jsmn +++ b/src/test/jsmn @@ -1 +1 @@ -Subproject commit daa17063c67f0dfe873af25ab6b664641c8cf90c +Subproject commit 49024a6e11739c866bce0e9f3617278b98906ad0 From 91f3494a8ad0d66819b9ae4d5f59cfc77fd66c97 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 4 Jul 2016 14:49:45 +0200 Subject: [PATCH 02/24] Bumb version to 1.0.0b2 --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index cddf86ac..da1dccd3 100644 --- a/configure.ac +++ b/configure.ac @@ -37,7 +37,7 @@ sinclude(./m4/ax_check_compile_flag.m4) sinclude(./m4/pkg.m4) AC_INIT([getdns], [1.0.0], [users@getdnsapi.net], [], [https://getdnsapi.net]) -AC_SUBST(RELEASE_CANDIDATE, [b1]) +AC_SUBST(RELEASE_CANDIDATE, [b2]) # Set current date from system if not set AC_ARG_WITH([current-date], @@ -47,7 +47,7 @@ AC_ARG_WITH([current-date], [CURRENT_DATE="`date -u +%Y-%m-%dT%H:%M:%SZ`"]) AC_SUBST(GETDNS_VERSION, ["AC_PACKAGE_VERSION$RELEASE_CANDIDATE"]) -AC_SUBST(GETDNS_NUMERIC_VERSION, [0x00100100]) +AC_SUBST(GETDNS_NUMERIC_VERSION, [0x00100200]) AC_SUBST(API_VERSION, ["December 2015"]) AC_SUBST(API_NUMERIC_VERSION, [0x07df0c00]) GETDNS_COMPILATION_COMMENT="AC_PACKAGE_NAME $GETDNS_VERSION configured on $CURRENT_DATE for the $API_VERSION version of the API" From 92fd79ff5501ac66c08b94bb4ef947178285cc5d Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 4 Jul 2016 14:50:02 +0200 Subject: [PATCH 03/24] Update Changelog --- ChangeLog | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b3a1dbc1..8459cd74 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,47 @@ -* 2016-??-??: Version 1.0.0 +* 2016-??-??: Version 1.0.0b2 + * Collect coverage information from the unit tests + Thanks Shane Kerr + * pkg-config for the getdns_ext_event library + Thanks Tom Pusateri + * Bugfix: Multiple requests on the same upstream with a transport + that keeps connections open in synchronous stub mode. + * Canonicalized DNSSEC chain with dnssec_return_validation_chain + (when validated) + * A dnssec_return_full_validation_chain extension which includes + then validated resource records. + * Bugfix: Callbacks fired while scheduling (answer from cache) + with the unbound plugable event API + * header extension to set opcode and flags in stub mode + * Unit tests that cover more code + * Static checking with the clang analyzer + * getdns_pretty_print_dict prints dname's as primitives + * Accept just bindata's instead of address dicts. + Allow misshing "address_type" in address dicts. + * TLS session resumption + * -C option to getdns_query to configure context + from a json like formated file. The output of -i (print API + information) can be used as config file directly. + Settings may also be given in this format as arguments of + the getdns_query command directly. + * DNS server mode for getdns_query. Enable by providing addresses + to listen on, either by giving "-z " options or by + providing "listen_addresses" in the config file or settings. + * Bugfixes from deckard testing: CNAME loop protection. + * "srv_addresses" in response dict with getdns_service() + * use libbsd when available + Thanks Guillem Jover + * Bugfix: DNSSEC wildcard validation issue + * Bugfix: TLS timeouts not re-using a connection + * A getdns_context_get_eventloop(), to get the current + (pluggable) eventloop from context + * getdns_query now uses the default event loop (instead of custom) + * Return call_reporting info in case of timeout + Thanks Robert Groenenberg + * Bugfix: Build fails with autoconf 2.63, works with 2.68. + Thanks Robert Groenenberg + * Doxygen output for getdns.h and getdns_extra.h only + +* 2016-03-31: Version 1.0.0b1 * openssl 1.1.0 support * GETDNS_APPEND_NAME_TO_SINGLE_LABEL_FIRST default suffix handling * getdns_context_set_follow_redirects() From cc104320e8dad93d4186aa50c54064c96cd2447d Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 4 Jul 2016 15:54:05 +0200 Subject: [PATCH 04/24] Get RR types and classes from constant names --- src/test/getdns_query.c | 536 ++++------------------------------------ 1 file changed, 53 insertions(+), 483 deletions(-) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index a2a463c0..09184e6d 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #ifndef USE_WINSOCK @@ -70,7 +71,55 @@ static int timeout, edns0_size, padding_blocksize; static int async = 0, interactive = 0; static enum { GENERAL, ADDRESS, HOSTNAME, SERVICE } calltype = GENERAL; -int get_rrtype(const char *t); +static int get_rrtype(const char *t) +{ + char buf[1024] = "GETDNS_RRTYPE_"; + uint32_t rrtype; + long int l; + size_t i; + char *endptr; + + if (strlen(t) > sizeof(buf) - 15) + return -1; + for (i = 14; *t && i < sizeof(buf) - 1; i++, t++) + buf[i] = toupper(*t); + buf[i] = '\0'; + + if (!getdns_str2int(buf, &rrtype)) + return (int)rrtype; + + if (strncasecmp(buf + 14, "TYPE", 4) == 0) { + l = strtol(buf + 18, &endptr, 10); + if (!*endptr && l >= 0 && l < 65536) + return l; + } + return -1; +} + +static int get_rrclass(const char *t) +{ + char buf[1024] = "GETDNS_RRCLASS_"; + uint32_t rrclass; + long int l; + size_t i; + char *endptr; + + if (strlen(t) > sizeof(buf) - 16) + return -1; + for (i = 15; *t && i < sizeof(buf) - 1; i++, t++) + buf[i] = toupper(*t); + buf[i] = '\0'; + + if (!getdns_str2int(buf, &rrclass)) + return (int)rrclass; + + if (strncasecmp(buf + 15, "CLASS", 5) == 0) { + l = strtol(buf + 20, &endptr, 10); + if (!*endptr && l >= 0 && l < 65536) + return l; + } + return -1; +} static getdns_return_t fill_transport_list(getdns_context *context, char *transport_list_str, @@ -457,34 +506,13 @@ getdns_return_t parse_args(int argc, char **argv) break; } } else if (strncmp(arg+1, "specify_class=", 14) == 0) { - if (strncasecmp(arg+15, "IN", 3) == 0) + if ((klass = get_rrclass(arg+15)) >= 0) r = getdns_dict_set_int(extensions, - "specify_class", GETDNS_RRCLASS_IN); - else if (strncasecmp(arg+15, "CH", 3) == 0) - r = getdns_dict_set_int(extensions, - "specify_class", GETDNS_RRCLASS_CH); - else if (strncasecmp(arg+15, "HS", 3) == 0) - r = getdns_dict_set_int(extensions, - "specify_class", GETDNS_RRCLASS_HS); - else if (strncasecmp(arg+15, "NONE", 5) == 0) - r = getdns_dict_set_int(extensions, - "specify_class", GETDNS_RRCLASS_NONE); - else if (strncasecmp(arg+15, "ANY", 4) == 0) - r = getdns_dict_set_int(extensions, - "specify_class", GETDNS_RRCLASS_ANY); - else if (strncasecmp(arg+15, "CLASS", 5) == 0) { - klass = strtol(arg + 20, &endptr, 10); - if (*endptr || klass > 255) - fprintf(stderr, - "Unknown class: %s\n", - arg+15); - else - r = getdns_dict_set_int(extensions, "specify_class", klass); - - } else + else fprintf(stderr, "Unknown class: %s\n", arg+15); + } else if (arg[1] == '0') { /* Unset all existing extensions*/ getdns_dict_destroy(extensions); @@ -1503,462 +1531,4 @@ done_destroy_context: return r; } -int get_rrtype(const char *t) { - char *endptr; - int r; - - switch (t[0]) { - case 'A': - case 'a': switch (t[1]) { - case '\0': return GETDNS_RRTYPE_A; - case '6': if (t[2] == '\0') return GETDNS_RRTYPE_A6; - return -1; - case 'A': - case 'a': /* before "AA", final "AA" (GETDNS_RRTYPE_AAAA) */ - if ((t[2]|0x20) == 'a' && (t[3]|0x20) == 'a' && t[4] == '\0') - return GETDNS_RRTYPE_AAAA; - return -1; - case 'F': - case 'f': /* before "AF", final "SDB" (GETDNS_RRTYPE_AFSDB) */ - if ((t[2]|0x20) == 's' && (t[3]|0x20) == 'd' && (t[4]|0x20) == 'b' && t[5] == '\0') - return GETDNS_RRTYPE_AFSDB; - return -1; - case 'P': - case 'p': /* before "AP", final "L" (GETDNS_RRTYPE_APL) */ - if ((t[2]|0x20) == 'l' && t[3] == '\0') - return GETDNS_RRTYPE_APL; - return -1; - case 'T': - case 't': /* before "AT", final "MA" (GETDNS_RRTYPE_ATMA) */ - if ((t[2]|0x20) == 'm' && (t[3]|0x20) == 'a' && t[4] == '\0') - return GETDNS_RRTYPE_ATMA; - return -1; - case 'X': - case 'x': /* before "AX", final "FR" (GETDNS_RRTYPE_AXFR) */ - if ((t[2]|0x20) == 'f' && (t[3]|0x20) == 'r' && t[4] == '\0') - return GETDNS_RRTYPE_AXFR; - return -1; - default : return -1; - }; - case 'C': - case 'c': switch (t[1]) { - case 'A': - case 'a': /* before "CA", final "A" (GETDNS_RRTYPE_CAA) */ - if ((t[2]|0x20) == 'a' && t[3] == '\0') - return GETDNS_RRTYPE_CAA; - return -1; - case 'D': - case 'd': switch (t[2]) { - case 'N': - case 'n': /* before "CDN", final "SKEY" (GETDNS_RRTYPE_CDNSKEY) */ - if ((t[3]|0x20) == 's' && (t[4]|0x20) == 'k' && (t[5]|0x20) == 'e' && (t[6]|0x20) == 'y' && t[7] == '\0') - return GETDNS_RRTYPE_CDNSKEY; - return -1; - case 'S': - case 's': if (t[3] == '\0') return GETDNS_RRTYPE_CDS; - return -1; - default : return -1; - }; - case 'E': - case 'e': /* before "CE", final "RT" (GETDNS_RRTYPE_CERT) */ - if ((t[2]|0x20) == 'r' && (t[3]|0x20) == 't' && t[4] == '\0') - return GETDNS_RRTYPE_CERT; - return -1; - case 'N': - case 'n': /* before "CN", final "AME" (GETDNS_RRTYPE_CNAME) */ - if ((t[2]|0x20) == 'a' && (t[3]|0x20) == 'm' && (t[4]|0x20) == 'e' && t[5] == '\0') - return GETDNS_RRTYPE_CNAME; - return -1; - case 'S': - case 's': /* before "CS", final "YNC" (GETDNS_RRTYPE_CSYNC) */ - if ((t[2]|0x20) == 'y' && (t[3]|0x20) == 'n' && (t[4]|0x20) == 'c' && t[5] == '\0') - return GETDNS_RRTYPE_CSYNC; - return -1; - - default : return -1; - }; - case 'D': - case 'd': switch (t[1]) { - case 'H': - case 'h': /* before "DH", final "CID" (GETDNS_RRTYPE_DHCID) */ - if ((t[2]|0x20) == 'c' && (t[3]|0x20) == 'i' && (t[4]|0x20) == 'd' && t[5] == '\0') - return GETDNS_RRTYPE_DHCID; - return -1; - case 'L': - case 'l': /* before "DL", final "V" (GETDNS_RRTYPE_DLV) */ - if ((t[2]|0x20) == 'v' && t[3] == '\0') - return GETDNS_RRTYPE_DLV; - return -1; - case 'N': - case 'n': switch (t[2]) { - case 'A': - case 'a': /* before "DNA", final "ME" (GETDNS_RRTYPE_DNAME) */ - if ((t[3]|0x20) == 'm' && (t[4]|0x20) == 'e' && t[5] == '\0') - return GETDNS_RRTYPE_DNAME; - return -1; - case 'S': - case 's': /* before "DNS", final "KEY" (GETDNS_RRTYPE_DNSKEY) */ - if ((t[3]|0x20) == 'k' && (t[4]|0x20) == 'e' && (t[5]|0x20) == 'y' && t[6] == '\0') - return GETDNS_RRTYPE_DNSKEY; - return -1; - default : return -1; - }; - case 'S': - case 's': if (t[2] == '\0') return GETDNS_RRTYPE_DS; - return -1; - default : return -1; - }; - case 'E': - case 'e': switch (t[1]) { - case 'I': - case 'i': /* before "EI", final "D" (GETDNS_RRTYPE_EID) */ - if ((t[2]|0x20) == 'd' && t[3] == '\0') - return GETDNS_RRTYPE_EID; - return -1; - case 'U': - case 'u': /* before "EU", next "I" */ - if ((t[2]|0x20) != 'i') - return -1; - switch (t[3]) { - case '4': /* before "EUI4", final "8" (GETDNS_RRTYPE_EUI48) */ - if (t[4] == '8' && t[5] == '\0') - return GETDNS_RRTYPE_EUI48; - return -1; - case '6': /* before "EUI6", final "4" (GETDNS_RRTYPE_EUI64) */ - if (t[4] == '4' && t[5] == '\0') - return GETDNS_RRTYPE_EUI64; - return -1; - default : return -1; - }; - default : return -1; - }; - case 'G': - case 'g': switch (t[1]) { - case 'I': - case 'i': /* before "GI", final "D" (GETDNS_RRTYPE_GID) */ - if ((t[2]|0x20) == 'd' && t[3] == '\0') - return GETDNS_RRTYPE_GID; - return -1; - case 'P': - case 'p': /* before "GP", final "OS" (GETDNS_RRTYPE_GPOS) */ - if ((t[2]|0x20) == 'o' && (t[3]|0x20) == 's' && t[4] == '\0') - return GETDNS_RRTYPE_GPOS; - return -1; - default : return -1; - }; - case 'H': - case 'h': /* before "H", next "I" */ - if ((t[1]|0x20) != 'i') - return -1; - switch (t[2]) { - case 'N': - case 'n': /* before "HIN", final "FO" (GETDNS_RRTYPE_HINFO) */ - if ((t[3]|0x20) == 'f' && (t[4]|0x20) == 'o' && t[5] == '\0') - return GETDNS_RRTYPE_HINFO; - return -1; - case 'P': - case 'p': if (t[3] == '\0') return GETDNS_RRTYPE_HIP; - return -1; - default : return -1; - }; - case 'I': - case 'i': switch (t[1]) { - case 'P': - case 'p': /* before "IP", final "SECKEY" (GETDNS_RRTYPE_IPSECKEY) */ - if ((t[2]|0x20) == 's' && (t[3]|0x20) == 'e' && (t[4]|0x20) == 'c' && (t[5]|0x20) == 'k' && (t[6]|0x20) == 'e' && (t[7]|0x20) == 'y' && t[8] == '\0') - return GETDNS_RRTYPE_IPSECKEY; - return -1; - case 'S': - case 's': /* before "IS", final "DN" (GETDNS_RRTYPE_ISDN) */ - if ((t[2]|0x20) == 'd' && (t[3]|0x20) == 'n' && t[4] == '\0') - return GETDNS_RRTYPE_ISDN; - return -1; - case 'X': - case 'x': /* before "IX", final "FR" (GETDNS_RRTYPE_IXFR) */ - if ((t[2]|0x20) == 'f' && (t[3]|0x20) == 'r' && t[4] == '\0') - return GETDNS_RRTYPE_IXFR; - return -1; - default : return -1; - }; - case 'K': - case 'k': switch (t[1]) { - case 'E': - case 'e': /* before "KE", final "Y" (GETDNS_RRTYPE_KEY) */ - if ((t[2]|0x20) == 'y' && t[3] == '\0') - return GETDNS_RRTYPE_KEY; - return -1; - case 'X': - case 'x': if (t[2] == '\0') return GETDNS_RRTYPE_KX; - return -1; - default : return -1; - }; - case 'L': - case 'l': switch (t[1]) { - case '3': /* before "L3", final "2" (GETDNS_RRTYPE_L32) */ - if (t[2] == '2' && t[3] == '\0') - return GETDNS_RRTYPE_L32; - return -1; - case '6': /* before "L6", final "4" (GETDNS_RRTYPE_L64) */ - if (t[2] == '4' && t[3] == '\0') - return GETDNS_RRTYPE_L64; - return -1; - case 'O': - case 'o': /* before "LO", final "C" (GETDNS_RRTYPE_LOC) */ - if ((t[2]|0x20) == 'c' && t[3] == '\0') - return GETDNS_RRTYPE_LOC; - return -1; - case 'P': - case 'p': if (t[2] == '\0') return GETDNS_RRTYPE_LP; - return -1; - default : return -1; - }; - case 'M': - case 'm': switch (t[1]) { - case 'A': - case 'a': /* before "MA", next "IL" */ - if ((t[2]|0x20) != 'i' && (t[3]|0x20) != 'l') - return -1; - switch (t[4]) { - case 'A': - case 'a': if (t[5] == '\0') return GETDNS_RRTYPE_MAILA; - return -1; - case 'B': - case 'b': if (t[5] == '\0') return GETDNS_RRTYPE_MAILB; - return -1; - default : return -1; - }; - case 'B': - case 'b': if (t[2] == '\0') return GETDNS_RRTYPE_MB; - return -1; - case 'D': - case 'd': if (t[2] == '\0') return GETDNS_RRTYPE_MD; - return -1; - case 'F': - case 'f': if (t[2] == '\0') return GETDNS_RRTYPE_MF; - return -1; - case 'G': - case 'g': if (t[2] == '\0') return GETDNS_RRTYPE_MG; - return -1; - case 'I': - case 'i': /* before "MI", final "NFO" (GETDNS_RRTYPE_MINFO) */ - if ((t[2]|0x20) == 'n' && (t[3]|0x20) == 'f' && (t[4]|0x20) == 'o' && t[5] == '\0') - return GETDNS_RRTYPE_MINFO; - return -1; - case 'R': - case 'r': if (t[2] == '\0') return GETDNS_RRTYPE_MR; - return -1; - case 'X': - case 'x': if (t[2] == '\0') return GETDNS_RRTYPE_MX; - return -1; - default : return -1; - }; - case 'N': - case 'n': switch (t[1]) { - case 'A': - case 'a': /* before "NA", final "PTR" (GETDNS_RRTYPE_NAPTR) */ - if ((t[2]|0x20) == 'p' && (t[3]|0x20) == 't' && (t[4]|0x20) == 'r' && t[5] == '\0') - return GETDNS_RRTYPE_NAPTR; - return -1; - case 'I': - case 'i': switch (t[2]) { - case 'D': - case 'd': if (t[3] == '\0') return GETDNS_RRTYPE_NID; - return -1; - case 'M': - case 'm': /* before "NIM", final "LOC" (GETDNS_RRTYPE_NIMLOC) */ - if ((t[3]|0x20) == 'l' && (t[4]|0x20) == 'o' && (t[5]|0x20) == 'c' && t[6] == '\0') - return GETDNS_RRTYPE_NIMLOC; - return -1; - case 'N': - case 'n': /* before "NIN", final "FO" (GETDNS_RRTYPE_NINFO) */ - if ((t[3]|0x20) == 'f' && (t[4]|0x20) == 'o' && t[5] == '\0') - return GETDNS_RRTYPE_NINFO; - return -1; - default : return -1; - }; - case 'S': - case 's': switch (t[2]) { - case '\0': return GETDNS_RRTYPE_NS; - case 'A': - case 'a': /* before "NSA", final "P" (GETDNS_RRTYPE_NSAP) */ - if ((t[3]|0x20) == 'p' && t[4] == '\0') - return GETDNS_RRTYPE_NSAP; - return -1; - case 'E': - case 'e': /* before "NSE", final "C3PARAM" (GETDNS_RRTYPE_NSEC3PARAM) */ - if ((t[3]|0x20) == 'c' && t[4] == '3' && (t[5]|0x20) == 'p' && (t[6]|0x20) == 'a' && (t[7]|0x20) == 'r' && (t[8]|0x20) == 'a' && (t[9]|0x20) == 'm' && t[10] == '\0') - return GETDNS_RRTYPE_NSEC3PARAM; - return -1; - default : return -1; - }; - case 'U': - case 'u': /* before "NU", final "LL" (GETDNS_RRTYPE_NULL) */ - if ((t[2]|0x20) == 'l' && (t[3]|0x20) == 'l' && t[4] == '\0') - return GETDNS_RRTYPE_NULL; - return -1; - case 'X': - case 'x': /* before "NX", final "T" (GETDNS_RRTYPE_NXT) */ - if ((t[2]|0x20) == 't' && t[3] == '\0') - return GETDNS_RRTYPE_NXT; - return -1; - default : return -1; - }; - case 'O': - case 'o': /* before "O", next "P" */ - if ((t[1]|0x20) != 'p') - return -1; - switch (t[2]) { - case 'E': - case 'e': /* before "OPE", final "NPGPKEY" (GETDNS_RRTYPE_OPENPGPKEY) */ - if ((t[3]|0x20) == 'n' && (t[4]|0x20) == 'p' && (t[5]|0x20) == 'g' && (t[6]|0x20) == 'p' && (t[7]|0x20) == 'k' && (t[8]|0x20) == 'e' && (t[9]|0x20) == 'y' && t[10] == '\0') - return GETDNS_RRTYPE_OPENPGPKEY; - return -1; - case 'T': - case 't': if (t[3] == '\0') return GETDNS_RRTYPE_OPT; - return -1; - default : return -1; - }; - case 'P': - case 'p': switch (t[1]) { - case 'T': - case 't': /* before "PT", final "R" (GETDNS_RRTYPE_PTR) */ - if ((t[2]|0x20) == 'r' && t[3] == '\0') - return GETDNS_RRTYPE_PTR; - return -1; - case 'X': - case 'x': if (t[2] == '\0') return GETDNS_RRTYPE_PX; - return -1; - default : return -1; - }; - case 'R': - case 'r': switch (t[1]) { - case 'K': - case 'k': /* before "RK", final "EY" (GETDNS_RRTYPE_RKEY) */ - if ((t[2]|0x20) == 'e' && (t[3]|0x20) == 'y' && t[4] == '\0') - return GETDNS_RRTYPE_RKEY; - return -1; - case 'P': - case 'p': if (t[2] == '\0') return GETDNS_RRTYPE_RP; - return -1; - case 'R': - case 'r': /* before "RR", final "SIG" (GETDNS_RRTYPE_RRSIG) */ - if ((t[2]|0x20) == 's' && (t[3]|0x20) == 'i' && (t[4]|0x20) == 'g' && t[5] == '\0') - return GETDNS_RRTYPE_RRSIG; - return -1; - case 'T': - case 't': if (t[2] == '\0') return GETDNS_RRTYPE_RT; - return -1; - default : return -1; - }; - case 'S': - case 's': switch (t[1]) { - case 'I': - case 'i': switch (t[2]) { - case 'G': - case 'g': if (t[3] == '\0') return GETDNS_RRTYPE_SIG; - return -1; - case 'N': - case 'n': /* before "SIN", final "K" (GETDNS_RRTYPE_SINK) */ - if ((t[3]|0x20) == 'k' && t[4] == '\0') - return GETDNS_RRTYPE_SINK; - return -1; - default : return -1; - }; - case 'O': - case 'o': /* before "SO", final "A" (GETDNS_RRTYPE_SOA) */ - if ((t[2]|0x20) == 'a' && t[3] == '\0') - return GETDNS_RRTYPE_SOA; - return -1; - case 'P': - case 'p': /* before "SP", final "F" (GETDNS_RRTYPE_SPF) */ - if ((t[2]|0x20) == 'f' && t[3] == '\0') - return GETDNS_RRTYPE_SPF; - return -1; - case 'R': - case 'r': /* before "SR", final "V" (GETDNS_RRTYPE_SRV) */ - if ((t[2]|0x20) == 'v' && t[3] == '\0') - return GETDNS_RRTYPE_SRV; - return -1; - case 'S': - case 's': /* before "SS", final "HFP" (GETDNS_RRTYPE_SSHFP) */ - if ((t[2]|0x20) == 'h' && (t[3]|0x20) == 'f' && (t[4]|0x20) == 'p' && t[5] == '\0') - return GETDNS_RRTYPE_SSHFP; - return -1; - default : return -1; - }; - case 'T': - case 't': switch (t[1]) { - case 'A': - case 'a': /* before "TA", final "LINK" (GETDNS_RRTYPE_TALINK) */ - if ((t[2]|0x20) == 'l' && (t[3]|0x20) == 'i' && (t[4]|0x20) == 'n' && (t[5]|0x20) == 'k' && t[6] == '\0') - return GETDNS_RRTYPE_TALINK; - return -1; - case 'K': - case 'k': /* before "TK", final "EY" (GETDNS_RRTYPE_TKEY) */ - if ((t[2]|0x20) == 'e' && (t[3]|0x20) == 'y' && t[4] == '\0') - return GETDNS_RRTYPE_TKEY; - return -1; - case 'L': - case 'l': /* before "TL", final "SA" (GETDNS_RRTYPE_TLSA) */ - if ((t[2]|0x20) == 's' && (t[3]|0x20) == 'a' && t[4] == '\0') - return GETDNS_RRTYPE_TLSA; - return -1; - case 'S': - case 's': /* before "TS", final "IG" (GETDNS_RRTYPE_TSIG) */ - if ((t[2]|0x20) == 'i' && (t[3]|0x20) == 'g' && t[4] == '\0') - return GETDNS_RRTYPE_TSIG; - return -1; - case 'X': - case 'x': /* before "TX", final "T" (GETDNS_RRTYPE_TXT) */ - if ((t[2]|0x20) == 't' && t[3] == '\0') - return GETDNS_RRTYPE_TXT; - return -1; - case 'Y': - case 'y': /* before "TY", then "PE" followed by a number */ - if ((t[2]|0x20) == 'p' && (t[3]|0x20) == 'e' && t[4] != '\0') { - r = (int) strtol(t + 4, &endptr, 10); - if (*endptr == '\0') return r; - } - return -1; - default : return -1; - }; - case 'U': - case 'u': switch (t[1]) { - case 'I': - case 'i': switch (t[2]) { - case 'D': - case 'd': if (t[3] == '\0') return GETDNS_RRTYPE_UID; - return -1; - case 'N': - case 'n': /* before "UIN", final "FO" (GETDNS_RRTYPE_UINFO) */ - if ((t[3]|0x20) == 'f' && (t[4]|0x20) == 'o' && t[5] == '\0') - return GETDNS_RRTYPE_UINFO; - return -1; - default : return -1; - }; - case 'N': - case 'n': /* before "UN", final "SPEC" (GETDNS_RRTYPE_UNSPEC) */ - if ((t[2]|0x20) == 's' && (t[3]|0x20) == 'p' && (t[4]|0x20) == 'e' && (t[5]|0x20) == 'c' && t[6] == '\0') - return GETDNS_RRTYPE_UNSPEC; - return -1; - case 'R': - case 'r': /* before "UR", final "I" (GETDNS_RRTYPE_URI) */ - if ((t[2]|0x20) == 'i' && t[3] == '\0') - return GETDNS_RRTYPE_URI; - return -1; - default : return -1; - }; - case 'W': - case 'w': /* before "W", final "KS" (GETDNS_RRTYPE_WKS) */ - if ((t[1]|0x20) == 'k' && (t[2]|0x20) == 's' && t[3] == '\0') - return GETDNS_RRTYPE_WKS; - return -1; - case 'X': - case 'x': /* before "X", final "25" (GETDNS_RRTYPE_X25) */ - if (t[1] == '2' && t[2] == '5' && t[3] == '\0') - return GETDNS_RRTYPE_X25; - return -1; - default : return -1; - }; -} From 7e614bc534b2c69ae70dbf7a93d4441b7b42da46 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 11 Jul 2016 15:13:40 +0200 Subject: [PATCH 05/24] More conventional server DNSSEC behaviour + documentation of behaviour --- project-doc/getdns_query-deamon-behaviour.ods | Bin 0 -> 17609 bytes project-doc/getdns_query-deamon-behaviour.pdf | Bin 0 -> 13995 bytes src/convert.c | 35 ++++- .../getdns_context_set_listen_addresses.c | 66 +++++++++ src/test/getdns_query.c | 128 ++++++++++++++---- 5 files changed, 202 insertions(+), 27 deletions(-) create mode 100644 project-doc/getdns_query-deamon-behaviour.ods create mode 100644 project-doc/getdns_query-deamon-behaviour.pdf diff --git a/project-doc/getdns_query-deamon-behaviour.ods b/project-doc/getdns_query-deamon-behaviour.ods new file mode 100644 index 0000000000000000000000000000000000000000..041cebc754bfe60ac255409c9d2c70f5e6687f21 GIT binary patch literal 17609 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 N4ML`+l~e*F|3AzLS^@w7 literal 0 HcmV?d00001 diff --git a/src/convert.c b/src/convert.c index 2539d7bd..5eb1a513 100644 --- a/src/convert.c +++ b/src/convert.c @@ -611,6 +611,15 @@ _getdns_wire2msg_dict_scan(struct mem_funcs *mf, if (!wire || !*wire || !wire_len || !msg_dict) return GETDNS_RETURN_INVALID_PARAMETER; +#if 0 && defined(SERVER_DEBUG) && SERVER_DEBUG + do { + char *str = gldns_wire2str_pkt((uint8_t *)*wire, *wire_len); + DEBUG_SERVER("_getdns_wire2msg_dict_scan for a packet size: %d: %s\n", + (int)*wire_len, str); + free(str); + } while(0); +#endif + if (!(result = _getdns_dict_create_with_mf(mf)) || !(header = _getdns_dict_create_with_mf(mf)) || !(sections[SECTION_ANSWER] @@ -768,11 +777,12 @@ _getdns_reply_dict2wire( const getdns_dict *reply, gldns_buffer *buf, int reuse_header) { uint8_t header_spc[GLDNS_HEADER_SIZE], *header; - uint32_t n, qtype, qclass = GETDNS_RRCLASS_IN; + uint32_t n, qtype, qclass = GETDNS_RRCLASS_IN, rr_type; size_t pkt_start, i; getdns_list *section; getdns_dict *rr_dict; getdns_bindata *qname; + int remove_dnssec; pkt_start = gldns_buffer_position(buf); if (reuse_header) { @@ -814,11 +824,18 @@ _getdns_reply_dict2wire( buf, pkt_start+GLDNS_ARCOUNT_OFF, 0); } } + remove_dnssec = !getdns_dict_get_int(reply, "/header/do", &n) && n == 0; + DEBUG_SERVER("remove_dnssec: %d\n", remove_dnssec); + if (!getdns_dict_get_list(reply, "answer", §ion)) { for ( n = 0, i = 0 ; !getdns_list_get_dict(section, i, &rr_dict); i++) { - if (!_getdns_rr_dict2wire(rr_dict, buf)) + if (remove_dnssec && + !getdns_dict_get_int(rr_dict, "type", &rr_type) && + rr_type == GETDNS_RRTYPE_RRSIG) + continue; + if (!_getdns_rr_dict2wire(rr_dict, buf)) n++; } gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_ANCOUNT_OFF, n); @@ -827,7 +844,15 @@ _getdns_reply_dict2wire( for ( n = 0, i = 0 ; !getdns_list_get_dict(section, i, &rr_dict); i++) { - if (!_getdns_rr_dict2wire(rr_dict, buf)) + if (remove_dnssec && + !getdns_dict_get_int(rr_dict, "type", &rr_type) && + ( rr_type == GETDNS_RRTYPE_RRSIG + || rr_type == GETDNS_RRTYPE_NSEC + || rr_type == GETDNS_RRTYPE_NSEC3 + || rr_type == GETDNS_RRTYPE_DS + )) + continue; + if (!_getdns_rr_dict2wire(rr_dict, buf)) n++; } gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_NSCOUNT_OFF, n); @@ -836,6 +861,10 @@ _getdns_reply_dict2wire( for ( n = 0, i = 0 ; !getdns_list_get_dict(section, i, &rr_dict); i++) { + if (remove_dnssec && + !getdns_dict_get_int(rr_dict, "type", &rr_type) && + rr_type == GETDNS_RRTYPE_RRSIG) + continue; if (!_getdns_rr_dict2wire(rr_dict, buf)) n++; } diff --git a/src/test/getdns_context_set_listen_addresses.c b/src/test/getdns_context_set_listen_addresses.c index eeeac3ad..fcfe9057 100644 --- a/src/test/getdns_context_set_listen_addresses.c +++ b/src/test/getdns_context_set_listen_addresses.c @@ -503,6 +503,72 @@ static void udp_read_cb(void *userarg) close(l->fd); l->fd = -1; +#if 0 && defined(SERVER_DEBUG) && SERVER_DEBUG + } else { + char addrbuf[100]; + char hexbuf[4096], *hexptr; + size_t l, i, j; + + if (conn->remote_in.ss_family == AF_INET) { + if (inet_ntop(AF_INET, + &((struct sockaddr_in*)&conn->remote_in)->sin_addr, + addrbuf, sizeof(addrbuf))) { + + l = strlen(addrbuf); + (void) snprintf(addrbuf + l, + sizeof(addrbuf) - l, ":%d", + (int)((struct sockaddr_in*) + &conn->remote_in)->sin_port); + } else + (void) strncpy( + addrbuf, "error ipv4", sizeof(addrbuf)); + + } else if (conn->remote_in.ss_family == AF_INET6) { + addrbuf[0] = '['; + if (inet_ntop(AF_INET6, + &((struct sockaddr_in6*) + &conn->remote_in)->sin6_addr, + addrbuf, sizeof(addrbuf))) { + + l = strlen(addrbuf); + (void) snprintf(addrbuf + l, + sizeof(addrbuf) - l, ":%d", + (int)((struct sockaddr_in6*) + &conn->remote_in)->sin6_port); + } else + (void) strncpy( + addrbuf, "error ipv6", sizeof(addrbuf)); + + } else { + (void) strncpy( + addrbuf, "unknown address", sizeof(addrbuf)); + } + *(hexptr = hexbuf) = 0; + for (i = 0; i < len; i++) { + if (i % 12 == 0) { + hexptr += snprintf(hexptr, + sizeof(hexbuf) - (hexptr - hexbuf) - 1, + "\n%.4x", (int)i); + } else if (i % 4 == 0) { + hexptr += snprintf(hexptr, + sizeof(hexbuf) - (hexptr - hexbuf) - 1, + " "); + } + if (hexptr - hexbuf > sizeof(hexbuf)) + break; + hexptr += snprintf(hexptr, + sizeof(hexbuf) - (hexptr - hexbuf) - 1, + " %.2x", (int)buf[i]); + if (hexptr - hexbuf > sizeof(hexbuf)) + break; + } + DEBUG_SERVER("Received %d bytes from %s: %s\n", + (int)len, addrbuf, hexbuf); + } + if (len == -1) { + ; /* pass */ +#endif + } else if ((r = getdns_wire2msg_dict(buf, len, &request_dict))) ; /* FROMERR on input, ignore */ diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 09184e6d..54464bcd 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -1200,8 +1200,10 @@ typedef struct dns_msg { getdns_transaction_t request_id; getdns_dict *request; uint32_t rt; + uint32_t ad_bit; uint32_t do_bit; uint32_t cd_bit; + int has_edns0; } dns_msg; #if defined(SERVER_DEBUG) && SERVER_DEBUG @@ -1236,15 +1238,53 @@ void servfail(dns_msg *msg, getdns_dict **resp_p) (void) getdns_dict_set_int(*resp_p, "/header/ad", 0); } -void request_cb(getdns_context *context, getdns_callback_type_t callback_type, +static getdns_return_t _handle_edns0( + getdns_dict *response, int has_edns0, uint32_t do_bit) +{ + getdns_return_t r; + getdns_list *additional; + size_t len, i; + getdns_dict *rr; + uint32_t rr_type; + char remove_str[100] = "/replies_tree/0/additional/"; + + if ((r = getdns_dict_set_int( + response, "/replies_tree/0/header/do", do_bit))) + return r; + if (has_edns0) + return GETDNS_RETURN_GOOD; + if ((r = getdns_dict_get_list(response, "/replies_tree/0/additional", + &additional))) + return r; + if ((r = getdns_list_get_length(additional, &len))) + return r; + for (i = 0; i < len; i++) { + if ((r = getdns_list_get_dict(additional, i, &rr))) + return r; + if ((r = getdns_dict_get_int(rr, "type", &rr_type))) + return r; + if (rr_type != GETDNS_RRTYPE_OPT) + continue; + (void) snprintf(remove_str + 27, 60, "%d", (int)i); + if ((r = getdns_dict_remove_name(response, remove_str))) + return r; + break; + } + return GETDNS_RETURN_GOOD; +} + +static void request_cb( + getdns_context *context, getdns_callback_type_t callback_type, getdns_dict *response, void *userarg, getdns_transaction_t transaction_id) { dns_msg *msg = (dns_msg *)userarg; uint32_t qid; getdns_return_t r = GETDNS_RETURN_GOOD; - uint32_t n; + uint32_t n, rcode, dnssec_status; - DEBUG_SERVER("reply for: %p %"PRIu64" %d\n", msg, transaction_id, (int)callback_type); + DEBUG_SERVER("reply for: %p %"PRIu64" %d (edns0: %d, do: %d, ad: %d," + " cd: %d)\n", msg, transaction_id, (int)callback_type, + msg->has_edns0, msg->do_bit, msg->ad_bit, msg->cd_bit); assert(msg); #if 0 @@ -1263,21 +1303,36 @@ void request_cb(getdns_context *context, getdns_callback_type_t callback_type, SERVFAIL("Could not copy QID", r, msg, &response); else if (getdns_dict_get_int( - response, "/replies_tree/0/header/rcode", &n)) + response, "/replies_tree/0/header/rcode", &rcode)) SERVFAIL("No reply in replies tree", 0, msg, &response); - else if (msg->cd_bit != 1 && !getdns_dict_get_int( - response, "/replies_tree/0/dnssec_status", &n) - && n == GETDNS_DNSSEC_BOGUS) + /* ansers when CD or not BOGUS */ + else if (!msg->cd_bit && !getdns_dict_get_int( + response, "/replies_tree/0/dnssec_status", &dnssec_status) + && dnssec_status == GETDNS_DNSSEC_BOGUS) SERVFAIL("DNSSEC status was bogus", 0, msg, &response); - else if ((r = getdns_dict_get_int( - response, "/replies_tree/0/header/rcode", &n))) - SERVFAIL("Could not get rcode from reply", r, msg, &response); - - else if (n == GETDNS_RCODE_SERVFAIL) + else if (rcode == GETDNS_RCODE_SERVFAIL) servfail(msg, &response); + /* RRsigs when DO and (CD or not BOGUS) + * Implemented in conversion to wireformat function by checking for DO + * bit. In recursing resolution mode we have to copy the do bit from + * the request, because libunbound has it in the answer always. + */ + else if (msg->rt == GETDNS_RESOLUTION_RECURSING && + (r = _handle_edns0(response, msg->has_edns0, msg->do_bit))) + SERVFAIL("Could not handle EDNS0", r, msg, &response); + + /* AD when (DO or AD) and SECURE */ + else if ((r = getdns_dict_set_int(response,"/replies_tree/0/header/ad", + ((msg->do_bit || msg->ad_bit) + && ( (!msg->cd_bit && dnssec_status == GETDNS_DNSSEC_SECURE) + || ( msg->cd_bit && !getdns_dict_get_int(response, + "/replies_tree/0/dnssec_status", &dnssec_status) + && dnssec_status == GETDNS_DNSSEC_SECURE ))) ? 1 : 0))) + SERVFAIL("Could not set AD bit", r, msg, &response); + else if (msg->rt == GETDNS_RESOLUTION_STUB) ; /* following checks are for RESOLUTION_RECURSING only */ @@ -1324,6 +1379,10 @@ static void incoming_request_handler(getdns_context *context, getdns_dict *qext = NULL; dns_msg *msg = NULL; getdns_dict *response = NULL; + size_t i, len; + getdns_list *additional; + getdns_dict *rr; + uint32_t rr_type; if (!query_extensions_spc && !(query_extensions_spc = getdns_dict_create())) @@ -1345,10 +1404,26 @@ static void incoming_request_handler(getdns_context *context, n = 0; msg->request_id = request_id; msg->request = request; - msg->do_bit = msg->cd_bit = 0; - msg->rt = GETDNS_RESOLUTION_STUB; - (void) getdns_dict_get_int(request, "/additional/0/do", &msg->do_bit); + msg->ad_bit = msg->do_bit = msg->cd_bit = 0; + msg->has_edns0 = 0; + msg->rt = GETDNS_RESOLUTION_RECURSING; + (void) getdns_dict_get_int(request, "/header/ad", &msg->ad_bit); (void) getdns_dict_get_int(request, "/header/cd", &msg->cd_bit); + if (!getdns_dict_get_list(request, "additional", &additional)) { + if (getdns_list_get_length(additional, &len)) + len = 0; + for (i = 0; i < len; i++) { + if (getdns_list_get_dict(additional, i, &rr)) + break; + if (getdns_dict_get_int(rr, "type", &rr_type)) + break; + if (rr_type != GETDNS_RRTYPE_OPT) + continue; + msg->has_edns0 = 1; + (void) getdns_dict_get_int(rr, "do", &msg->do_bit); + break; + } + } if ((r = getdns_context_get_resolution_type(context, &msg->rt))) fprintf(stderr, "Could get resolution type from context: %s\n", getdns_get_errorstr_by_id(r)); @@ -1359,15 +1434,10 @@ static void incoming_request_handler(getdns_context *context, if (!getdns_dict_get_dict(request, "header", &header)) (void)getdns_dict_set_dict(qext, "header", header); - } else if (getdns_dict_get_int(extensions,"dnssec_return_status",&n) || - n == GETDNS_EXTENSION_FALSE) - (void)getdns_dict_set_int(qext, "dnssec_return_status", - msg->do_bit ? GETDNS_EXTENSION_TRUE : GETDNS_EXTENSION_FALSE); - - if (!getdns_dict_get_int(qext, "dnssec_return_status", &n) && - n == GETDNS_EXTENSION_TRUE) - (void) getdns_dict_set_int(qext, "dnssec_return_all_statuses", - msg->cd_bit ? GETDNS_EXTENSION_TRUE : GETDNS_EXTENSION_FALSE); + } + if (msg->cd_bit) + getdns_dict_set_int(qext, "dnssec_return_all_statuses", + GETDNS_EXTENSION_TRUE); if (!getdns_dict_get_int(request, "/additional/0/extended_rcode",&n)) (void)getdns_dict_set_int( @@ -1431,6 +1501,16 @@ error: if (qname_str) free(qname_str); servfail(msg, &response); +#if defined(SERVER_DEBUG) && SERVER_DEBUG + do { + char *request_str = getdns_pretty_print_dict(request); + char *response_str = getdns_pretty_print_dict(response); + DEBUG_SERVER("request error, request: %s\n, response: %s\n" + , request_str, response_str); + free(response_str); + free(request_str); + } while(0); +#endif if (!response) /* No response, no reply */ _getdns_cancel_reply(context, request_id); From b98d91f7455cd951ecf72c0e5a1d09709f989261 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 11 Jul 2016 15:43:42 +0200 Subject: [PATCH 06/24] Daemon edns0 handling bugfix --- src/convert.c | 1 + src/test/getdns_query.c | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/convert.c b/src/convert.c index 5eb1a513..9ce2fa39 100644 --- a/src/convert.c +++ b/src/convert.c @@ -51,6 +51,7 @@ #include "dict.h" #include "list.h" #include "convert.h" +#include "debug.h" /* stuff to make it compile pedantically */ #define UNUSED_PARAM(x) ((void)(x)) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 54464bcd..99f04ca5 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -1239,7 +1239,7 @@ void servfail(dns_msg *msg, getdns_dict **resp_p) } static getdns_return_t _handle_edns0( - getdns_dict *response, int has_edns0, uint32_t do_bit) + getdns_dict *response, int has_edns0) { getdns_return_t r; getdns_list *additional; @@ -1249,10 +1249,8 @@ static getdns_return_t _handle_edns0( char remove_str[100] = "/replies_tree/0/additional/"; if ((r = getdns_dict_set_int( - response, "/replies_tree/0/header/do", do_bit))) + response, "/replies_tree/0/header/do", 0))) return r; - if (has_edns0) - return GETDNS_RETURN_GOOD; if ((r = getdns_dict_get_list(response, "/replies_tree/0/additional", &additional))) return r; @@ -1265,6 +1263,10 @@ static getdns_return_t _handle_edns0( return r; if (rr_type != GETDNS_RRTYPE_OPT) continue; + if (has_edns0) { + (void) getdns_dict_set_int(rr, "do", 0); + break; + } (void) snprintf(remove_str + 27, 60, "%d", (int)i); if ((r = getdns_dict_remove_name(response, remove_str))) return r; @@ -1320,8 +1322,8 @@ static void request_cb( * bit. In recursing resolution mode we have to copy the do bit from * the request, because libunbound has it in the answer always. */ - else if (msg->rt == GETDNS_RESOLUTION_RECURSING && - (r = _handle_edns0(response, msg->has_edns0, msg->do_bit))) + else if (msg->rt == GETDNS_RESOLUTION_RECURSING && !msg->do_bit && + (r = _handle_edns0(response, msg->has_edns0))) SERVFAIL("Could not handle EDNS0", r, msg, &response); /* AD when (DO or AD) and SECURE */ From a523838cc6a7f651005756498f3a5921855f1cc0 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 11 Jul 2016 16:05:05 +0200 Subject: [PATCH 07/24] set_listen_addresses does not change listen_list --- src/test/getdns_context_set_listen_addresses.c | 3 ++- src/test/getdns_context_set_listen_addresses.h | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/test/getdns_context_set_listen_addresses.c b/src/test/getdns_context_set_listen_addresses.c index fcfe9057..3b05e803 100644 --- a/src/test/getdns_context_set_listen_addresses.c +++ b/src/test/getdns_context_set_listen_addresses.c @@ -739,7 +739,8 @@ static getdns_return_t add_listeners(listen_set *set) } getdns_return_t getdns_context_set_listen_addresses(getdns_context *context, - getdns_request_handler_t request_handler, getdns_list *listen_addresses) + getdns_request_handler_t request_handler, + const getdns_list *listen_addresses) { static const getdns_transport_list_t listen_transports[] = { GETDNS_TRANSPORT_UDP, GETDNS_TRANSPORT_TCP }; diff --git a/src/test/getdns_context_set_listen_addresses.h b/src/test/getdns_context_set_listen_addresses.h index 116634f4..fac16f48 100644 --- a/src/test/getdns_context_set_listen_addresses.h +++ b/src/test/getdns_context_set_listen_addresses.h @@ -35,8 +35,9 @@ typedef void (*getdns_request_handler_t)( getdns_transaction_t request_id ); -getdns_return_t getdns_context_set_listen_addresses(getdns_context *context, - getdns_request_handler_t request_handler, getdns_list *listen_addresses); +getdns_return_t getdns_context_set_listen_addresses( + getdns_context *context, getdns_request_handler_t request_handler, + const getdns_list *listen_addresses); getdns_return_t getdns_reply(getdns_context *context, getdns_transaction_t request_id, getdns_dict *reply); From 9f7ceeded32ffe935a89015c876ac2932ec46c71 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 13 Jul 2016 15:28:08 +0200 Subject: [PATCH 08/24] Don't SSL_library_init() on every context create It will not be called when the second bit from the set_from_os parameter is set. This deals with issue #117 --- ChangeLog | 2 ++ src/context.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8459cd74..4dae9ffb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -40,6 +40,8 @@ * Bugfix: Build fails with autoconf 2.63, works with 2.68. Thanks Robert Groenenberg * Doxygen output for getdns.h and getdns_extra.h only + * Do not call SSL_library_init() from getdns_context_create() when + the second bit from the set_from_os parameter is set. * 2016-03-31: Version 1.0.0b1 * openssl 1.1.0 support diff --git a/src/context.c b/src/context.c index b46dc3bd..b0c9a198 100644 --- a/src/context.c +++ b/src/context.c @@ -1297,7 +1297,9 @@ getdns_context_create_with_extended_memory_functions( /* Unbound needs SSL to be init'ed this early when TLS is used. However we * don't know that till later so we will have to do this every time. */ - SSL_library_init(); + if (set_from_os & 2 == 0) + SSL_library_init(); + #ifdef HAVE_LIBUNBOUND result->unbound_ctx = NULL; if ((r = rebuild_ub_ctx(result))) From 74b57d4679abe9d1d7deaad175229f3036c61b25 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Jul 2016 13:33:11 +0200 Subject: [PATCH 09/24] Resync utils with unbound source --- src/util/import.sh | 4 ++ src/util/val_secalgo.c | 96 +++++++++++++++++++++++++----------------- src/util/val_secalgo.h | 12 +++++- 3 files changed, 72 insertions(+), 40 deletions(-) diff --git a/src/util/import.sh b/src/util/import.sh index ee903681..82f03921 100755 --- a/src/util/import.sh +++ b/src/util/import.sh @@ -44,6 +44,10 @@ do -e 's/secalgo_ds_digest/_getdns_secalgo_ds_digest/g' \ -e 's/dnskey_algo_id_is_supported/_getdns_dnskey_algo_id_is_supported/g' \ -e 's/verify_canonrrset/_getdns_verify_canonrrset/g' \ + -e 's/nsec3_hash_algo_size_supported/_getdns_nsec3_hash_algo_size_supported/g' \ + -e 's/secalgo_nsec3_hash/_getdns_secalgo_nsec3_hash/g' \ + -e 's/secalgo_hash_sha256/_getdns_secalgo_hash_sha256/g' \ + -e 's/ecdsa_evp_workaround_init/_getdns_ecdsa_evp_workaround_init/g' \ -e 's/LDNS_/GLDNS_/g' \ -e 's/enum sec_status/int/g' \ -e 's/sec_status_bogus/0/g' \ diff --git a/src/util/val_secalgo.c b/src/util/val_secalgo.c index b04400cc..edbf538b 100644 --- a/src/util/val_secalgo.c +++ b/src/util/val_secalgo.c @@ -72,7 +72,7 @@ /* return size of digest if supported, or 0 otherwise */ size_t -nsec3_hash_algo_size_supported(int id) +_getdns_nsec3_hash_algo_size_supported(int id) { switch(id) { case NSEC3_HASH_SHA1: @@ -84,7 +84,7 @@ nsec3_hash_algo_size_supported(int id) /* perform nsec3 hash. return false on failure */ int -secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, +_getdns_secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, unsigned char* res) { switch(algo) { @@ -96,6 +96,12 @@ secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, } } +void +_getdns_secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res) +{ + (void)SHA256(buf, len, res); +} + /** * Return size of DS digest according to its hash algorithm. * @param algo: DS digest algo. @@ -342,6 +348,23 @@ i * the '44' is the total remaining length. } #endif /* USE_ECDSA */ +#ifdef USE_ECDSA_EVP_WORKAROUND +static EVP_MD ecdsa_evp_256_md; +static EVP_MD ecdsa_evp_384_md; +void _getdns_ecdsa_evp_workaround_init(void) +{ + /* openssl before 1.0.0 fixes RSA with the SHA256 + * hash in EVP. We create one for ecdsa_sha256 */ + ecdsa_evp_256_md = *EVP_sha256(); + ecdsa_evp_256_md.required_pkey_type[0] = EVP_PKEY_EC; + ecdsa_evp_256_md.verify = (void*)ECDSA_verify; + + ecdsa_evp_384_md = *EVP_sha384(); + ecdsa_evp_384_md.required_pkey_type[0] = EVP_PKEY_EC; + ecdsa_evp_384_md.verify = (void*)ECDSA_verify; +} +#endif /* USE_ECDSA_EVP_WORKAROUND */ + /** * Setup key and digest for verification. Adjust sig if necessary. * @@ -470,20 +493,7 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, return 0; } #ifdef USE_ECDSA_EVP_WORKAROUND - /* openssl before 1.0.0 fixes RSA with the SHA256 - * hash in EVP. We create one for ecdsa_sha256 */ - { - static int md_ecdsa_256_done = 0; - static EVP_MD md; - if(!md_ecdsa_256_done) { - EVP_MD m = *EVP_sha256(); - md_ecdsa_256_done = 1; - m.required_pkey_type[0] = (*evp_key)->type; - m.verify = (void*)ECDSA_verify; - md = m; - } - *digest_type = &md; - } + *digest_type = &ecdsa_evp_256_md; #else *digest_type = EVP_sha256(); #endif @@ -497,20 +507,7 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, return 0; } #ifdef USE_ECDSA_EVP_WORKAROUND - /* openssl before 1.0.0 fixes RSA with the SHA384 - * hash in EVP. We create one for ecdsa_sha384 */ - { - static int md_ecdsa_384_done = 0; - static EVP_MD md; - if(!md_ecdsa_384_done) { - EVP_MD m = *EVP_sha384(); - md_ecdsa_384_done = 1; - m.required_pkey_type[0] = (*evp_key)->type; - m.verify = (void*)ECDSA_verify; - md = m; - } - *digest_type = &md; - } + *digest_type = &ecdsa_evp_384_md; #else *digest_type = EVP_sha384(); #endif @@ -544,7 +541,7 @@ _getdns_verify_canonrrset(gldns_buffer* buf, int algo, unsigned char* sigblock, { const EVP_MD *digest_type; EVP_MD_CTX* ctx; - int res, dofree = 0; + int res, dofree = 0, docrypto_free = 0; EVP_PKEY *evp_key = NULL; if(!setup_key_digest(algo, &evp_key, &digest_type, key, keylen)) { @@ -563,7 +560,7 @@ _getdns_verify_canonrrset(gldns_buffer* buf, int algo, unsigned char* sigblock, EVP_PKEY_free(evp_key); return 0; } - dofree = 1; + docrypto_free = 1; } #endif #if defined(USE_ECDSA) && defined(USE_DSA) @@ -593,6 +590,7 @@ _getdns_verify_canonrrset(gldns_buffer* buf, int algo, unsigned char* sigblock, log_err("EVP_MD_CTX_new: malloc failure"); EVP_PKEY_free(evp_key); if(dofree) free(sigblock); + else if(docrypto_free) CRYPTO_free(sigblock); return 0; } if(EVP_VerifyInit(ctx, digest_type) == 0) { @@ -600,6 +598,7 @@ _getdns_verify_canonrrset(gldns_buffer* buf, int algo, unsigned char* sigblock, EVP_MD_CTX_destroy(ctx); EVP_PKEY_free(evp_key); if(dofree) free(sigblock); + else if(docrypto_free) CRYPTO_free(sigblock); return 0; } if(EVP_VerifyUpdate(ctx, (unsigned char*)gldns_buffer_begin(buf), @@ -608,15 +607,21 @@ _getdns_verify_canonrrset(gldns_buffer* buf, int algo, unsigned char* sigblock, EVP_MD_CTX_destroy(ctx); EVP_PKEY_free(evp_key); if(dofree) free(sigblock); + else if(docrypto_free) CRYPTO_free(sigblock); return 0; } res = EVP_VerifyFinal(ctx, sigblock, sigblock_len, evp_key); +#ifdef HAVE_EVP_MD_CTX_NEW EVP_MD_CTX_destroy(ctx); +#else + EVP_MD_CTX_cleanup(ctx); + free(ctx); +#endif EVP_PKEY_free(evp_key); - if(dofree) - free(sigblock); + if(dofree) free(sigblock); + else if(docrypto_free) CRYPTO_free(sigblock); if(res == 1) { return 1; @@ -644,7 +649,7 @@ _getdns_verify_canonrrset(gldns_buffer* buf, int algo, unsigned char* sigblock, /* return size of digest if supported, or 0 otherwise */ size_t -nsec3_hash_algo_size_supported(int id) +_getdns_nsec3_hash_algo_size_supported(int id) { switch(id) { case NSEC3_HASH_SHA1: @@ -656,7 +661,7 @@ nsec3_hash_algo_size_supported(int id) /* perform nsec3 hash. return false on failure */ int -secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, +_getdns_secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, unsigned char* res) { switch(algo) { @@ -668,6 +673,12 @@ secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, } } +void +_getdns_secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res) +{ + (void)HASH_HashBuf(HASH_AlgSHA256, res, buf, (unsigned long)len); +} + size_t _getdns_ds_digest_size_supported(int algo) { @@ -1185,6 +1196,9 @@ _getdns_verify_canonrrset(gldns_buffer* buf, int algo, unsigned char* sigblock, #include "macros.h" #include "rsa.h" #include "dsa.h" +#ifdef HAVE_NETTLE_DSA_COMPAT_H +#include "dsa-compat.h" +#endif #include "asn1.h" #ifdef USE_ECDSA #include "ecdsa.h" @@ -1236,7 +1250,7 @@ _digest_nettle(int algo, uint8_t* buf, size_t len, /* return size of digest if supported, or 0 otherwise */ size_t -nsec3_hash_algo_size_supported(int id) +_getdns_nsec3_hash_algo_size_supported(int id) { switch(id) { case NSEC3_HASH_SHA1: @@ -1248,7 +1262,7 @@ nsec3_hash_algo_size_supported(int id) /* perform nsec3 hash. return false on failure */ int -secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, +_getdns_secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, unsigned char* res) { switch(algo) { @@ -1260,6 +1274,12 @@ secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, } } +void +_getdns_secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res) +{ + _digest_nettle(SHA256_DIGEST_SIZE, (uint8_t*)buf, len, res); +} + /** * Return size of DS digest according to its hash algorithm. * @param algo: DS digest algo. diff --git a/src/util/val_secalgo.h b/src/util/val_secalgo.h index 917ebc00..704449ec 100644 --- a/src/util/val_secalgo.h +++ b/src/util/val_secalgo.h @@ -45,7 +45,7 @@ struct gldns_buffer; /** Return size of nsec3 hash algorithm, 0 if not supported */ -size_t nsec3_hash_algo_size_supported(int id); +size_t _getdns_nsec3_hash_algo_size_supported(int id); /** * Hash a single hash call of an NSEC3 hash algorithm. @@ -56,9 +56,17 @@ size_t nsec3_hash_algo_size_supported(int id); * @param res: result stored here (must have sufficient space). * @return false on failure. */ -int secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, +int _getdns_secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, unsigned char* res); +/** + * Calculate the sha256 hash for the data buffer into the result. + * @param buf: buffer to digest. + * @param len: length of the buffer to digest. + * @param res: result is stored here (space 256/8 bytes). + */ +void _getdns_secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res); + /** * Return size of DS digest according to its hash algorithm. * @param algo: DS digest algo. From b4e7a82e11d644e7309d9de1fa9989feaf81635b Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Jul 2016 13:40:49 +0200 Subject: [PATCH 10/24] EDNS0 padding is RFC --- src/gldns/rrdef.h | 3 ++- src/gldns/wire2str.c | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/gldns/rrdef.h b/src/gldns/rrdef.h index 703ee31e..b13580ea 100644 --- a/src/gldns/rrdef.h +++ b/src/gldns/rrdef.h @@ -421,7 +421,8 @@ enum gldns_enum_edns_option GLDNS_EDNS_DHU = 6, /* RFC6975 */ GLDNS_EDNS_N3U = 7, /* RFC6975 */ GLDNS_EDNS_CLIENT_SUBNET = 8, /* draft-vandergaast-edns-client-subnet */ - GLDNS_EDNS_KEEPALIVE = 11 /* draft-ietf-dnsop-edns-tcp-keepalive*/ + GLDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/ + GLDNS_EDNS_PADDING = 12 /* RFC7830 */ }; typedef enum gldns_enum_edns_option gldns_edns_option; diff --git a/src/gldns/wire2str.c b/src/gldns/wire2str.c index b9a979eb..abc055d7 100644 --- a/src/gldns/wire2str.c +++ b/src/gldns/wire2str.c @@ -166,6 +166,7 @@ static gldns_lookup_table gldns_edns_options_data[] = { { 7, "N3U" }, { 8, "edns-client-subnet" }, { 11, "edns-tcp-keepalive"}, + { 12, "Padding" }, { 0, NULL} }; gldns_lookup_table* gldns_edns_options = gldns_edns_options_data; @@ -1886,7 +1887,10 @@ int gldns_wire2str_edns_option_print(char** s, size_t* sl, break; case GLDNS_EDNS_KEEPALIVE: w += gldns_wire2str_edns_keepalive_print(s, sl, optdata, optlen); - break; + break; + case GLDNS_EDNS_PADDING: + w += print_hex_buf(s, sl, optdata, optlen); + break; default: /* unknown option code */ w += print_hex_buf(s, sl, optdata, optlen); From af706716412503707267b3fa8eacf2155fe15126 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Jul 2016 13:46:12 +0200 Subject: [PATCH 11/24] =?UTF-8?q?parentheses=20around=20comparison=20in=20?= =?UTF-8?q?operand=20of=20=E2=80=98&=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/context.c b/src/context.c index b0c9a198..edea6aef 100644 --- a/src/context.c +++ b/src/context.c @@ -1297,7 +1297,7 @@ getdns_context_create_with_extended_memory_functions( /* Unbound needs SSL to be init'ed this early when TLS is used. However we * don't know that till later so we will have to do this every time. */ - if (set_from_os & 2 == 0) + if ((set_from_os & 2) == 0) SSL_library_init(); #ifdef HAVE_LIBUNBOUND From 2485c11e32d7b617b9dc8bb7eadf9ac38b62f309 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Jul 2016 14:02:29 +0200 Subject: [PATCH 12/24] Include jsmn in dist tarball --- Makefile.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile.in b/Makefile.in index 331c889e..3f727468 100644 --- a/Makefile.in +++ b/Makefile.in @@ -178,6 +178,7 @@ $(distdir): mkdir -p $(distdir)/src mkdir -p $(distdir)/src/getdns mkdir -p $(distdir)/src/test + mkdir -p $(distdir)/src/test/jsmn mkdir -p $(distdir)/src/extension mkdir -p $(distdir)/src/compat mkdir -p $(distdir)/src/util @@ -224,6 +225,9 @@ $(distdir): cp $(srcdir)/spec/*.tgz $(distdir)/spec || true cp $(srcdir)/spec/example/Makefile.in $(distdir)/spec/example cp $(srcdir)/spec/example/*.[ch] $(distdir)/spec/example + cp $(srcdir)/src/test/jsmn/*.[ch] $(distdir)/src/test/jsmn + cp $(srcdir)/src/test/jsmn/LICENSE $(distdir)/src/test/jsmn + cp $(srcdir)/src/test/jsmn/README.md $(distdir)/src/test/jsmn rm -f $(distdir)/Makefile $(distdir)/src/Makefile $(distdir)/src/getdns/getdns.h $(distdir)/spec/example/Makefile $(distdir)/src/test/Makefile $(distdir)/doc/Makefile $(distdir)/src/config.h distcheck: $(distdir).tar.gz From 906a8d68c241c15b9d4812e4340a8af53603cc52 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Jul 2016 14:06:00 +0200 Subject: [PATCH 13/24] fix for converting empty lists and dicts --- src/test/getdns_str2dict.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/test/getdns_str2dict.c b/src/test/getdns_str2dict.c index ae5fb1d9..28323d9d 100644 --- a/src/test/getdns_str2dict.c +++ b/src/test/getdns_str2dict.c @@ -410,7 +410,10 @@ static int _jsmn_get_dict(struct mem_funcs *mf, const char *js, jsmntok_t *t, char key_spc[1024], *key = NULL; getdns_item child_item; - for (i = 0; i < t->size; i++) { + if (t->size <= 0) + *r = GETDNS_RETURN_GOOD; + + else for (i = 0; i < t->size; i++) { if (t[j].type != JSMN_STRING && t[j].type != JSMN_PRIMITIVE) { @@ -484,7 +487,10 @@ static int _jsmn_get_list(struct mem_funcs *mf, const char *js, jsmntok_t *t, size_t i, j = 1, index = 0; getdns_item child_item; - for (i = 0; i < t->size; i++) { + if (t->size <= 0) + *r = GETDNS_RETURN_GOOD; + + else for (i = 0; i < t->size; i++) { j += _jsmn_get_item(mf, js, t + j, count - j, &child_item, r); if (*r) break; From bae426a0e224c3ac54ac672431493261bb054e58 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Jul 2016 14:09:08 +0200 Subject: [PATCH 14/24] Unread assignment --- src/test/getdns_query.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 6ff6097c..05645a5f 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -442,12 +442,11 @@ static void parse_config(const char *config_str) * will get destroyed. */ if (!listen_dict && - !(listen_dict = getdns_dict_create())) { + !(listen_dict = getdns_dict_create())) fprintf(stderr, "Could not create " "listen_dict"); - r = GETDNS_RETURN_MEMORY_ERROR; - } else if ((r = getdns_dict_set_list( + else if ((r = getdns_dict_set_list( listen_dict, "listen_list", list))) fprintf(stderr, "Could not set listen_list"); From 689fc02fd2fe37a29301ad9d4ee2b664f0a76f02 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Jul 2016 14:14:15 +0200 Subject: [PATCH 15/24] Allow errors while setting up listeners --- src/test/getdns_context_set_listen_addresses.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/getdns_context_set_listen_addresses.c b/src/test/getdns_context_set_listen_addresses.c index 3b05e803..9246b640 100644 --- a/src/test/getdns_context_set_listen_addresses.c +++ b/src/test/getdns_context_set_listen_addresses.c @@ -804,6 +804,8 @@ getdns_return_t getdns_context_set_listen_addresses(getdns_context *context, new_set->count = new_set_count * n_transports; (void) memset(new_set->items, 0, sizeof(listener) * new_set_count * n_transports); + for (i = 0; i < new_set->count; i++) + new_set->items[i].fd = -1; (void) memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; @@ -906,7 +908,7 @@ getdns_return_t getdns_context_set_listen_addresses(getdns_context *context, /* So the event can be rescheduled */ } } - if ((r = add_listeners(new_set))) { + if (r || (r = add_listeners(new_set))) { for (i = 0; i < new_set->count; i++) new_set->items[i].action = to_remove; From 99d8672bee82ad5358be501dd3c66e98f8b200ed Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Jul 2016 14:24:32 +0200 Subject: [PATCH 16/24] Fix few possible NULL dereference issues --- src/dnssec.c | 6 ++++-- src/rr-iter.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/dnssec.c b/src/dnssec.c index b46be44b..f567b96b 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -2049,7 +2049,8 @@ static int find_nsec_covering_name( , SECTION_NO_ADDITIONAL) ; i ; i = _getdns_rrset_iter_next(i)) { - if ((n = _getdns_rrset_iter_value(i))->rr_type == GETDNS_RRTYPE_NSEC3 + if ((n = _getdns_rrset_iter_value(i)) + && n->rr_type == GETDNS_RRTYPE_NSEC3 /* Get the bitmap rdata field */ && (nsec_rr = _getdns_rrtype_iter_init(&nsec_spc, n)) @@ -2085,7 +2086,8 @@ static int find_nsec_covering_name( return keytag; } - if ((n = _getdns_rrset_iter_value(i))->rr_type == GETDNS_RRTYPE_NSEC + if ((n = _getdns_rrset_iter_value(i)) + && n->rr_type == GETDNS_RRTYPE_NSEC && nsec_covers_name(n, name, NULL) /* Get the bitmap rdata field */ diff --git a/src/rr-iter.c b/src/rr-iter.c index e6a711de..9b332603 100644 --- a/src/rr-iter.c +++ b/src/rr-iter.c @@ -306,7 +306,7 @@ static int rr_owner_equal(_getdns_rr_iter *rr, const uint8_t *name) return (owner = _getdns_owner_if_or_as_decompressed(rr, owner_spc ,&owner_len)) - && _getdns_dname_equal(owner, name); + && name && _getdns_dname_equal(owner, name); } /* First a few filter functions that filter a RR iterator to point only From 9cb38bc82236721e125802c5a3b2b69b2712ac8c Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Jul 2016 15:18:27 +0200 Subject: [PATCH 17/24] Release today --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4dae9ffb..e154f85e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -* 2016-??-??: Version 1.0.0b2 +* 2016-07-14: Version 1.0.0b2 * Collect coverage information from the unit tests Thanks Shane Kerr * pkg-config for the getdns_ext_event library From 255cc9ab36f791c25ad04166d3268e83934de623 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Jul 2016 15:42:49 +0200 Subject: [PATCH 18/24] First bit of set_from_os loads OS defaults --- src/context.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/context.c b/src/context.c index edea6aef..a93e6f14 100644 --- a/src/context.c +++ b/src/context.c @@ -1277,10 +1277,10 @@ getdns_context_create_with_extended_memory_functions( // resolv.conf does not exist on Windows, handle differently #ifndef USE_WINSOCK - if (set_from_os && (r = set_os_defaults(result))) + if ((set_from_os & 1) && (r = set_os_defaults(result))) goto error; #else - if (set_from_os && (r = set_os_defaults_windows(result))) + if ((set_from_os & 1) && (r = set_os_defaults_windows(result))) goto error; #endif From 0736453bed0654a8f54270086391bd9666a51b46 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Jul 2016 15:53:53 +0200 Subject: [PATCH 19/24] Doxygen fixes --- src/getdns/getdns.h.in | 14 +++++++++----- src/getdns/getdns_extra.h.in | 36 ++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/getdns/getdns.h.in b/src/getdns/getdns.h.in index fedf9f2f..2a8f7f2a 100644 --- a/src/getdns/getdns.h.in +++ b/src/getdns/getdns.h.in @@ -965,7 +965,8 @@ getdns_service(getdns_context *context, * If used multi-threaded, user must define appropriate OpenSSL callback locking functions * (e.g. CRYPTO_THREADID_set_call) depending on the library version used. * @param context context that can be used immediately with other API calls - * @param set_from_os select to use os defaults or to specify user defined values + * @param set_from_os set to 1 to initialize the context with os defaults + * the second bit set (2) prevents OpenSSL library initialization. * @return GETDNS_RETURN_GOOD on success */ getdns_return_t @@ -977,10 +978,11 @@ getdns_context_create(getdns_context ** context, int set_from_os); * If used multi-threaded, user must define appropriate OpenSSL callback locking functions * (e.g. CRYPTO_THREADID_set_call) depending on the library version used. * @param context context that can be used immediately with other API calls - * @param set_from_os select to use os defaults or to specify user defined values + * @param set_from_os set to 1 to initialize the context with os defaults + * the second bit set (2) prevents OpenSSL library initialization. * @param malloc custom malloc function * @param realloc custom realloc function - * @param malloc custom free function + * @param free custom free function * @return GETDNS_RETURN_GOOD on success */ getdns_return_t @@ -998,10 +1000,12 @@ getdns_context_create_with_memory_functions( * If used multi-threaded, user must define appropriate OpenSSL callback locking functions * (e.g. CRYPTO_THREADID_set_call) depending on the library version used. * @param context context that can be used immediately with other API calls - * @param set_from_os select to use os defaults or to specify user defined values + * @param set_from_os set to 1 to initialize the context with os defaults + * the second bit set (2) prevents OpenSSL library initialization. + * @param userarg parameter passed to the custom malloc, realloc and free functions * @param malloc custom malloc function * @param realloc custom realloc function - * @param malloc custom free function + * @param free custom free function * @return GETDNS_RETURN_GOOD on success */ getdns_return_t diff --git a/src/getdns/getdns_extra.h.in b/src/getdns/getdns_extra.h.in index 3f7647d4..752076a9 100644 --- a/src/getdns/getdns_extra.h.in +++ b/src/getdns/getdns_extra.h.in @@ -361,9 +361,9 @@ getdns_context_get_tls_authentication(getdns_context *context, * "chain" context update callbacks and in this way create a subscription * service catering multiple interested parties. * @param context The context to monitor for changes - * @return userarg A user defined argument to be passed to the callback + * @param userarg A user defined argument to be passed to the callback * function. - * @return value The callback function to be called on context value + * @param value The callback function to be called on context value * changes. * @return GETDNS_RETURN_GOOD on success or an error code on failure. */ @@ -484,7 +484,7 @@ getdns_dict* getdns_pubkey_pin_create_from_string( * * @param pinset the set of public key pins to check for sanity. This * should be a list of dicts. - * @return errorlist if not NULL, a list of human-readable strings is + * @param errorlist if not NULL, a list of human-readable strings is * appended to errorlist. * @return GETDNS_RETURN_GOOD if the pinset passes the sanity check. */ @@ -592,8 +592,8 @@ getdns_snprint_json_list( * Convert rr_dict to wireformat representation of the resource record. * * @param rr_dict The getdns dict representation of the resource record - * @return wire A newly allocated buffer which will contain the wireformat. - * @return wire_sz The size of the allocated buffer and the wireformat. + * @param wire A newly allocated buffer which will contain the wireformat. + * @param wire_sz The size of the allocated buffer and the wireformat. * @return GETDNS_RETURN_GOOD on success or an error code on failure. */ getdns_return_t @@ -644,7 +644,7 @@ getdns_rr_dict2wire_scan( * * @param wire Buffer containing the wireformat rr * @param wire_sz Size of the wire buffer - * @return rr_dict The returned rr_dict + * @param rr_dict The returned rr_dict * @return GETDNS_RETURN_GOOD on success or an error code on failure. */ getdns_return_t @@ -657,7 +657,7 @@ getdns_wire2rr_dict( * @param wire Buffer containing the wireformat rr * @param wire_sz On input the size of the wire buffer * On output the length of the wireformat rr. - * @return rr_dict The returned rr_dict + * @param rr_dict The returned rr_dict * @return GETDNS_RETURN_GOOD on success or an error code on failure. */ getdns_return_t @@ -673,7 +673,7 @@ getdns_wire2rr_dict_buf( * @param wire_sz On input the size of the wire buffer * On output the size is decreased with the length * of the wireformat resource record. - * @return rr_dict The returned rr_dict + * @param rr_dict The returned rr_dict * @return GETDNS_RETURN_GOOD on success or an error code on failure. */ getdns_return_t @@ -685,7 +685,7 @@ getdns_wire2rr_dict_scan( * Convert rr_dict to the string representation of the resource record. * * @param rr_dict The getdns dict representation of the resource record - * @return str A newly allocated string representation of the rr + * @param str A newly allocated string representation of the rr * @return GETDNS_RETURN_GOOD on success or an error code on failure. */ getdns_return_t @@ -735,7 +735,7 @@ getdns_rr_dict2str_scan( * Convert the string representation of the resource record to rr_dict format. * * @param str String representation of the resource record. - * @return rr_dict The result getdns dict representation of the resource record + * @param rr_dict The result getdns dict representation of the resource record * @param origin Default suffix for not fully qualified domain names * @param default_ttl Default ttl * @return GETDNS_RETURN_GOOD on success or an error code on failure. @@ -748,8 +748,8 @@ getdns_str2rr_dict( /** * Read the zonefile and convert to a list of rr_dict's. * - * @param FILE An opened FILE pointer on the zone file. - * @return rr_list The result list of rr_dicts representing the zone file. + * @param in An opened FILE pointer on the zone file. + * @param rr_list The result list of rr_dicts representing the zone file. * @param origin Default suffix for not fully qualified domain names * @param default_ttl Default ttl * @return GETDNS_RETURN_GOOD on success or an error code on failure. @@ -763,8 +763,8 @@ getdns_fp2rr_list( * Convert DNS message dict to wireformat representation. * * @param msg_dict The getdns dict representation of a DNS message - * @return wire A newly allocated buffer which will contain the wireformat. - * @return wire_sz The size of the allocated buffer and the wireformat. + * @param wire A newly allocated buffer which will contain the wireformat. + * @param wire_sz The size of the allocated buffer and the wireformat. * @return GETDNS_RETURN_GOOD on success or an error code on failure. */ getdns_return_t @@ -815,7 +815,7 @@ getdns_msg_dict2wire_scan( * * @param wire Buffer containing the wireformat rr * @param wire_sz Size of the wire buffer - * @return msg_dict The returned DNS message + * @param msg_dict The returned DNS message * @return GETDNS_RETURN_GOOD on success or an error code on failure. */ getdns_return_t @@ -828,7 +828,7 @@ getdns_wire2msg_dict( * @param wire Buffer containing the wireformat rr * @param wire_sz On input the size of the wire buffer * On output the length of the wireformat rr. - * @return msg_dict The returned DNS message + * @param msg_dict The returned DNS message * @return GETDNS_RETURN_GOOD on success or an error code on failure. */ getdns_return_t @@ -844,7 +844,7 @@ getdns_wire2msg_dict_buf( * @param wire_sz On input the size of the wire buffer * On output the size is decreased with the length * of the wireformat DNS message. - * @return msg_dict The returned DNS message + * @param msg_dict The returned DNS message * @return GETDNS_RETURN_GOOD on success or an error code on failure. */ getdns_return_t @@ -856,7 +856,7 @@ getdns_wire2msg_dict_scan( * Convert msg_dict to the string representation of the DNS message. * * @param msg_dict The getdns dict representation of the DNS message - * @return str A newly allocated string representation of the rr + * @param str A newly allocated string representation of the rr * @return GETDNS_RETURN_GOOD on success or an error code on failure. */ getdns_return_t From d9a089a6a0b6cb189d5a178eefa0305711a844d7 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Jul 2016 16:00:55 +0200 Subject: [PATCH 20/24] Update .so versioning --- configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index da1dccd3..483c2964 100644 --- a/configure.ac +++ b/configure.ac @@ -76,7 +76,8 @@ GETDNS_COMPILATION_COMMENT="AC_PACKAGE_NAME $GETDNS_VERSION configured on $CURRE # getdns-0.3.3 had libversion 3:6:2 # getdns-0.5.0 had libversion 4:0:3 # getdns-0.5.1 had libversion 4:1:3 (but should have been getdns-0.6.0) -# getdns-0.9.0 will have libversion 5:0:4 +# getdns-0.9.0 had libversion 5:0:4 +# getdns-1.0.0 will have libversion 5:1:4 # GETDNS_LIBVERSION=5:0:4 From f685a0c8b85b89f56c3d179439e8763f58708031 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Jul 2016 16:18:50 +0200 Subject: [PATCH 21/24] Unsigned expression >= 0 is always true --- src/test/getdns_query.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 05645a5f..5c98d8f9 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -475,7 +475,7 @@ static void parse_config(const char *config_str) getdns_return_t parse_args(int argc, char **argv) { getdns_return_t r = GETDNS_RETURN_GOOD; - size_t i, j; + size_t i, j, klass; char *arg, *c, *endptr; int t, print_api_info = 0, print_trust_anchors = 0; getdns_list *upstream_list = NULL; @@ -486,7 +486,6 @@ getdns_return_t parse_args(int argc, char **argv) getdns_bindata bindata; size_t upstream_count = 0; FILE *fh; - uint32_t klass; char *config_file = NULL; long config_file_sz; @@ -507,7 +506,7 @@ getdns_return_t parse_args(int argc, char **argv) } else if (strncmp(arg+1, "specify_class=", 14) == 0) { if ((klass = get_rrclass(arg+15)) >= 0) r = getdns_dict_set_int(extensions, - "specify_class", klass); + "specify_class", (uint32_t )klass); else fprintf(stderr, "Unknown class: %s\n", arg+15); From d67507fff82cddbac6fb8b714ded9dad8f95035d Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Jul 2016 16:24:02 +0200 Subject: [PATCH 22/24] Actually do lib versioning too! --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 483c2964..b2c066a2 100644 --- a/configure.ac +++ b/configure.ac @@ -79,7 +79,7 @@ GETDNS_COMPILATION_COMMENT="AC_PACKAGE_NAME $GETDNS_VERSION configured on $CURRE # getdns-0.9.0 had libversion 5:0:4 # getdns-1.0.0 will have libversion 5:1:4 # -GETDNS_LIBVERSION=5:0:4 +GETDNS_LIBVERSION=5:1:4 AC_SUBST(GETDNS_COMPILATION_COMMENT) AC_SUBST(GETDNS_LIBVERSION) From 22c1eb7f3f5471b8697421c9e2bfe00b9f84fb01 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 14 Jul 2016 20:08:02 +0200 Subject: [PATCH 23/24] Update list of contributors --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 28a4d6ab..b1507f61 100644 --- a/README.md +++ b/README.md @@ -315,6 +315,7 @@ To configure: Contributors ============ +* Claus Assman * Theogene Bucuti * Andrew Cathrow, Verisign Labs * Neil Cook @@ -322,26 +323,34 @@ Contributors * Craig Despeaux, Verisign, Inc. * John Dickinson, Sinodun * Sara Dickinson, Sinodun +* Robert Edmonds * Angelique Finan, Verisign, Inc. +* Simson Garfinkel * Daniel Kahn Gillmor * Neel Goyal, Verisign, Inc. * Bryan Graham, Verisign, Inc. +* Robert Groenenberg * Paul Hoffman * Scott Hollenbeck, Verising, Inc. * Shumon Huque, Verisign Labs +* Jelte Janssen +* Guillem Jover * Shane Kerr * Anthony Kirby * Olaf Kolkman, NLnet Labs * Sanjay Mahurpawar, Verisign, Inc. * Allison Mankin, Verisign, Inc. - Verisign Labs. * Sai Mogali, Verisign, Inc. +* Linus Nordberg * Benno Overeinder, NLnet Labs * Joel Purra +* Tom Pusateri * Prithvi Ranganath, Verisign, Inc. * Rushi Shah, Verisign, Inc. * Vinay Soni, Verisign, Inc. * Melinda Shore, No Mountain Software LLC * Bob Steagall, Verisign, Inc. +* Ondřej Surý * Willem Toorop, NLnet Labs * Gowri Visweswaran, Verisign Labs * Wouter Wijngaards, NLnet Labs From 8c54142790f05e59a566003c28e16452fd290c11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jerry=20Lundstr=C3=B6m?= Date: Sun, 17 Jul 2016 11:44:34 +0200 Subject: [PATCH 24/24] Use type and not struct --- src/getdns/getdns_extra.h.in | 4 ++-- src/util-internal.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/getdns/getdns_extra.h.in b/src/getdns/getdns_extra.h.in index 752076a9..7e2a16e3 100644 --- a/src/getdns/getdns_extra.h.in +++ b/src/getdns/getdns_extra.h.in @@ -399,11 +399,11 @@ const char *getdns_get_errorstr_by_id(uint16_t err); /* dict util */ /* set a string as bindata */ -getdns_return_t getdns_dict_util_set_string(struct getdns_dict * dict, +getdns_return_t getdns_dict_util_set_string(getdns_dict * dict, char *name, const char *value); /* get a string from a dict. the result must be freed if valid */ -getdns_return_t getdns_dict_util_get_string(struct getdns_dict * dict, +getdns_return_t getdns_dict_util_get_string(getdns_dict * dict, char *name, char **result); /** diff --git a/src/util-internal.c b/src/util-internal.c index 47a3fd21..6934958d 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -54,7 +54,7 @@ getdns_return_t -getdns_dict_util_get_string(struct getdns_dict * dict, char *name, char **result) +getdns_dict_util_get_string(getdns_dict * dict, char *name, char **result) { struct getdns_bindata *bindata = NULL; if (!result) {