Merge pull request #179 from getdnsapi/features/create_dict_with_json

A daemon mode for getdns_query
This commit is contained in:
Melinda Shore 2016-06-06 19:42:24 -08:00
commit 15a2c1b591
22 changed files with 2041 additions and 256 deletions

4
.gitmodules vendored Normal file
View File

@ -0,0 +1,4 @@
[submodule "src/test/jsmn"]
path = src/test/jsmn
url = https://github.com/getdnsapi/jsmn.git
branch = getdns

View File

@ -143,12 +143,14 @@ ACX_ARG_RPATH
AC_ARG_ENABLE(debug-sched, AC_HELP_STRING([--enable-debug-sched], [Enable scheduling debugging messages]))
AC_ARG_ENABLE(debug-stub, AC_HELP_STRING([--enable-debug-stub], [Enable stub debugging messages]))
AC_ARG_ENABLE(debug-sec, AC_HELP_STRING([--enable-debug-sec], [Enable dnssec debugging messages]))
AC_ARG_ENABLE(debug-trace, AC_HELP_STRING([--enable-debug-trace], [Enable trace debugging of individual dns messages]))
AC_ARG_ENABLE(all-debugging, AC_HELP_STRING([--enable-all-debugging], [Enable scheduling, stub and dnssec debugging]))
case "$enable_all_debugging" in
yes)
enable_debug_sched=yes
enable_debug_stub=yes
enable_debug_sec=yes
enable_debug_trace=yes
;;
no|*)
;;
@ -174,6 +176,25 @@ case "$enable_debug_sec" in
no|*)
;;
esac
case "$enable_debug_trace" in
yes)
AC_DEFINE_UNQUOTED([TRACE_DEBUG], [1], [Define this enable printing of transaction ids of individual dns messages.])
;;
no|*)
;;
esac
dnl Hidden debugging options
dnl
AC_ARG_ENABLE(debug-keep-connections-open,[])
case "$enable_debug_keep_connections_open" in
yes)
AC_DEFINE_UNQUOTED([KEEP_CONNECTIONS_OPEN_DEBUG], [1], [Do not set this])
;;
no)
;;
esac
AC_ARG_ENABLE(tcp-fastopen, AC_HELP_STRING([--disable-tcp-fastopen], Disable TCP Fast Open (default=enabled if available)),
enable_tcp_fastopen="$enableval", enable_tcp_fastopen=yes)
@ -1005,6 +1026,8 @@ FreeBSD)
esac
AC_SUBST(C99COMPATFLAGS)
AC_DEFINE_UNQUOTED([MAX_CNAME_REFERRALS], [100], [The maximum number of cname referrals.])
AH_BOTTOM([
#ifdef GETDNS_ON_WINDOWS

View File

@ -5,6 +5,7 @@
#include "getdns/getdns.h"
#include "getdns/getdns_extra.h"
#include "const-info.h"
#include <string.h>
static struct const_info consts_info[] = {
{ -1, NULL, "/* <unknown getdns value> */" },
@ -94,6 +95,196 @@ static struct const_info consts_info[] = {
{ 1301, "GETDNS_AUTHENTICATION_REQUIRED", GETDNS_AUTHENTICATION_REQUIRED_TEXT },
};
struct const_name_info { const char *name; int code; };
static struct const_name_info consts_name_info[] = {
{ "GETDNS_APPEND_NAME_ALWAYS", 550 },
{ "GETDNS_APPEND_NAME_NEVER", 553 },
{ "GETDNS_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE", 552 },
{ "GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE", 551 },
{ "GETDNS_APPEND_NAME_TO_SINGLE_LABEL_FIRST", 554 },
{ "GETDNS_AUTHENTICATION_NONE", 1300 },
{ "GETDNS_AUTHENTICATION_REQUIRED", 1301 },
{ "GETDNS_BAD_DNS_ALL_NUMERIC_LABEL", 1101 },
{ "GETDNS_BAD_DNS_CNAME_IN_TARGET", 1100 },
{ "GETDNS_BAD_DNS_CNAME_RETURNED_FOR_OTHER_TYPE", 1102 },
{ "GETDNS_CALLBACK_CANCEL", 701 },
{ "GETDNS_CALLBACK_COMPLETE", 700 },
{ "GETDNS_CALLBACK_ERROR", 703 },
{ "GETDNS_CALLBACK_TIMEOUT", 702 },
{ "GETDNS_CONTEXT_CODE_APPEND_NAME", 607 },
{ "GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW", 614 },
{ "GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS", 609 },
{ "GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS", 604 },
{ "GETDNS_CONTEXT_CODE_DNS_TRANSPORT", 605 },
{ "GETDNS_CONTEXT_CODE_EDNS_CLIENT_SUBNET_PRIVATE", 619 },
{ "GETDNS_CONTEXT_CODE_EDNS_DO_BIT", 613 },
{ "GETDNS_CONTEXT_CODE_EDNS_EXTENDED_RCODE", 611 },
{ "GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE", 610 },
{ "GETDNS_CONTEXT_CODE_EDNS_VERSION", 612 },
{ "GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS", 602 },
{ "GETDNS_CONTEXT_CODE_IDLE_TIMEOUT", 617 },
{ "GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES", 606 },
{ "GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS", 615 },
{ "GETDNS_CONTEXT_CODE_NAMESPACES", 600 },
{ "GETDNS_CONTEXT_CODE_PUBKEY_PINSET", 621 },
{ "GETDNS_CONTEXT_CODE_RESOLUTION_TYPE", 601 },
{ "GETDNS_CONTEXT_CODE_SUFFIX", 608 },
{ "GETDNS_CONTEXT_CODE_TIMEOUT", 616 },
{ "GETDNS_CONTEXT_CODE_TLS_AUTHENTICATION", 618 },
{ "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", 620 },
{ "GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS", 603 },
{ "GETDNS_DNSSEC_BOGUS", 401 },
{ "GETDNS_DNSSEC_INDETERMINATE", 402 },
{ "GETDNS_DNSSEC_INSECURE", 403 },
{ "GETDNS_DNSSEC_NOT_PERFORMED", 404 },
{ "GETDNS_DNSSEC_SECURE", 400 },
{ "GETDNS_EXTENSION_FALSE", 1001 },
{ "GETDNS_EXTENSION_TRUE", 1000 },
{ "GETDNS_NAMESPACE_DNS", 500 },
{ "GETDNS_NAMESPACE_LOCALNAMES", 501 },
{ "GETDNS_NAMESPACE_MDNS", 503 },
{ "GETDNS_NAMESPACE_NETBIOS", 502 },
{ "GETDNS_NAMESPACE_NIS", 504 },
{ "GETDNS_NAMETYPE_DNS", 800 },
{ "GETDNS_NAMETYPE_WINS", 801 },
{ "GETDNS_OPCODE_IQUERY", 1 },
{ "GETDNS_OPCODE_NOTIFY", 4 },
{ "GETDNS_OPCODE_QUERY", 0 },
{ "GETDNS_OPCODE_STATUS", 2 },
{ "GETDNS_OPCODE_UPDATE", 5 },
{ "GETDNS_RCODE_BADALG", 21 },
{ "GETDNS_RCODE_BADKEY", 17 },
{ "GETDNS_RCODE_BADMODE", 19 },
{ "GETDNS_RCODE_BADNAME", 20 },
{ "GETDNS_RCODE_BADSIG", 16 },
{ "GETDNS_RCODE_BADTIME", 18 },
{ "GETDNS_RCODE_BADTRUNC", 22 },
{ "GETDNS_RCODE_BADVERS", 16 },
{ "GETDNS_RCODE_FORMERR", 1 },
{ "GETDNS_RCODE_NOERROR", 0 },
{ "GETDNS_RCODE_NOTAUTH", 9 },
{ "GETDNS_RCODE_NOTIMP", 4 },
{ "GETDNS_RCODE_NOTZONE", 10 },
{ "GETDNS_RCODE_NXDOMAIN", 3 },
{ "GETDNS_RCODE_NXRRSET", 8 },
{ "GETDNS_RCODE_REFUSED", 5 },
{ "GETDNS_RCODE_SERVFAIL", 2 },
{ "GETDNS_RCODE_YXDOMAIN", 6 },
{ "GETDNS_RCODE_YXRRSET", 7 },
{ "GETDNS_REDIRECTS_DO_NOT_FOLLOW", 531 },
{ "GETDNS_REDIRECTS_FOLLOW", 530 },
{ "GETDNS_RESOLUTION_RECURSING", 521 },
{ "GETDNS_RESOLUTION_STUB", 520 },
{ "GETDNS_RESPSTATUS_ALL_BOGUS_ANSWERS", 904 },
{ "GETDNS_RESPSTATUS_ALL_TIMEOUT", 902 },
{ "GETDNS_RESPSTATUS_GOOD", 900 },
{ "GETDNS_RESPSTATUS_NO_NAME", 901 },
{ "GETDNS_RESPSTATUS_NO_SECURE_ANSWERS", 903 },
{ "GETDNS_RETURN_BAD_CONTEXT", 301 },
{ "GETDNS_RETURN_BAD_DOMAIN_NAME", 300 },
{ "GETDNS_RETURN_CONTEXT_UPDATE_FAIL", 302 },
{ "GETDNS_RETURN_DNSSEC_WITH_STUB_DISALLOWED", 309 },
{ "GETDNS_RETURN_EXTENSION_MISFORMAT", 308 },
{ "GETDNS_RETURN_GENERIC_ERROR", 1 },
{ "GETDNS_RETURN_GOOD", 0 },
{ "GETDNS_RETURN_INVALID_PARAMETER", 311 },
{ "GETDNS_RETURN_MEMORY_ERROR", 310 },
{ "GETDNS_RETURN_NEED_MORE_SPACE", 399 },
{ "GETDNS_RETURN_NOT_IMPLEMENTED", 312 },
{ "GETDNS_RETURN_NO_SUCH_DICT_NAME", 305 },
{ "GETDNS_RETURN_NO_SUCH_EXTENSION", 307 },
{ "GETDNS_RETURN_NO_SUCH_LIST_ITEM", 304 },
{ "GETDNS_RETURN_UNKNOWN_TRANSACTION", 303 },
{ "GETDNS_RETURN_WRONG_TYPE_REQUESTED", 306 },
{ "GETDNS_RRCLASS_ANY", 255 },
{ "GETDNS_RRCLASS_CH", 3 },
{ "GETDNS_RRCLASS_HS", 4 },
{ "GETDNS_RRCLASS_IN", 1 },
{ "GETDNS_RRCLASS_NONE", 254 },
{ "GETDNS_RRTYPE_A", 1 },
{ "GETDNS_RRTYPE_AAAA", 28 },
{ "GETDNS_RRTYPE_AFSDB", 18 },
{ "GETDNS_RRTYPE_ANY", 255 },
{ "GETDNS_RRTYPE_APL", 42 },
{ "GETDNS_RRTYPE_ATMA", 34 },
{ "GETDNS_RRTYPE_AXFR", 252 },
{ "GETDNS_RRTYPE_CAA", 257 },
{ "GETDNS_RRTYPE_CDNSKEY", 60 },
{ "GETDNS_RRTYPE_CDS", 59 },
{ "GETDNS_RRTYPE_CERT", 37 },
{ "GETDNS_RRTYPE_CNAME", 5 },
{ "GETDNS_RRTYPE_CSYNC", 62 },
{ "GETDNS_RRTYPE_DHCID", 49 },
{ "GETDNS_RRTYPE_DLV", 32769 },
{ "GETDNS_RRTYPE_DNAME", 39 },
{ "GETDNS_RRTYPE_DNSKEY", 48 },
{ "GETDNS_RRTYPE_DS", 43 },
{ "GETDNS_RRTYPE_EID", 31 },
{ "GETDNS_RRTYPE_GID", 102 },
{ "GETDNS_RRTYPE_GPOS", 27 },
{ "GETDNS_RRTYPE_HINFO", 13 },
{ "GETDNS_RRTYPE_HIP", 55 },
{ "GETDNS_RRTYPE_IPSECKEY", 45 },
{ "GETDNS_RRTYPE_ISDN", 20 },
{ "GETDNS_RRTYPE_IXFR", 251 },
{ "GETDNS_RRTYPE_KEY", 25 },
{ "GETDNS_RRTYPE_KX", 36 },
{ "GETDNS_RRTYPE_LOC", 29 },
{ "GETDNS_RRTYPE_LP", 107 },
{ "GETDNS_RRTYPE_MAILA", 254 },
{ "GETDNS_RRTYPE_MAILB", 253 },
{ "GETDNS_RRTYPE_MB", 7 },
{ "GETDNS_RRTYPE_MD", 3 },
{ "GETDNS_RRTYPE_MF", 4 },
{ "GETDNS_RRTYPE_MG", 8 },
{ "GETDNS_RRTYPE_MINFO", 14 },
{ "GETDNS_RRTYPE_MR", 9 },
{ "GETDNS_RRTYPE_MX", 15 },
{ "GETDNS_RRTYPE_NAPTR", 35 },
{ "GETDNS_RRTYPE_NID", 104 },
{ "GETDNS_RRTYPE_NIMLOC", 32 },
{ "GETDNS_RRTYPE_NINFO", 56 },
{ "GETDNS_RRTYPE_NS", 2 },
{ "GETDNS_RRTYPE_NSAP", 22 },
{ "GETDNS_RRTYPE_NSEC", 47 },
{ "GETDNS_RRTYPE_NULL", 10 },
{ "GETDNS_RRTYPE_NXT", 30 },
{ "GETDNS_RRTYPE_OPENPGPKEY", 61 },
{ "GETDNS_RRTYPE_OPT", 41 },
{ "GETDNS_RRTYPE_PTR", 12 },
{ "GETDNS_RRTYPE_PX", 26 },
{ "GETDNS_RRTYPE_RKEY", 57 },
{ "GETDNS_RRTYPE_RP", 17 },
{ "GETDNS_RRTYPE_RRSIG", 46 },
{ "GETDNS_RRTYPE_RT", 21 },
{ "GETDNS_RRTYPE_SIG", 24 },
{ "GETDNS_RRTYPE_SINK", 40 },
{ "GETDNS_RRTYPE_SOA", 6 },
{ "GETDNS_RRTYPE_SPF", 99 },
{ "GETDNS_RRTYPE_SRV", 33 },
{ "GETDNS_RRTYPE_SSHFP", 44 },
{ "GETDNS_RRTYPE_TA", 32768 },
{ "GETDNS_RRTYPE_TALINK", 58 },
{ "GETDNS_RRTYPE_TKEY", 249 },
{ "GETDNS_RRTYPE_TLSA", 52 },
{ "GETDNS_RRTYPE_TSIG", 250 },
{ "GETDNS_RRTYPE_TXT", 16 },
{ "GETDNS_RRTYPE_UID", 101 },
{ "GETDNS_RRTYPE_UINFO", 100 },
{ "GETDNS_RRTYPE_UNSPEC", 103 },
{ "GETDNS_RRTYPE_URI", 256 },
{ "GETDNS_RRTYPE_WKS", 11 },
{ "GETDNS_TRANSPORT_TCP", 1201 },
{ "GETDNS_TRANSPORT_TCP_ONLY", 542 },
{ "GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN", 543 },
{ "GETDNS_TRANSPORT_TLS", 1202 },
{ "GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN", 545 },
{ "GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN", 544 },
{ "GETDNS_TRANSPORT_UDP", 1200 },
{ "GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP", 540 },
{ "GETDNS_TRANSPORT_UDP_ONLY", 541 },
};
static int const_info_cmp(const void *a, const void *b)
{
return ((struct const_info *) a)->code - ((struct const_info *) b)->code;
@ -110,6 +301,25 @@ _getdns_get_const_info(int value)
return consts_info;
}
static int const_name_info_cmp(const void *a, const void *b)
{
return strcmp( ((struct const_name_info *) a)->name
, ((struct const_name_info *) b)->name );
}
int
_getdns_get_const_name_info(const char *name, int *code)
{
struct const_name_info key = { name, 0 };
struct const_name_info *i = bsearch(&key, consts_name_info,
sizeof(consts_name_info) / sizeof(struct const_name_info),
sizeof(struct const_name_info), const_name_info_cmp);
if (!i)
return 0;
if (code)
*code = i->code;
return 1;
}
const char *
getdns_get_errorstr_by_id(uint16_t err)
{

View File

@ -46,6 +46,7 @@ struct const_info {
};
struct const_info *_getdns_get_const_info(int value);
int _getdns_get_const_name_info(const char *name, int *code);
#endif

View File

@ -1951,7 +1951,7 @@ getdns_context_set_follow_redirects(
dispatch_updated(context, GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS);
return GETDNS_RETURN_NOT_IMPLEMENTED;
return GETDNS_RETURN_GOOD;
} /* getdns_context_set_follow_redirects */
/*
@ -1971,7 +1971,7 @@ getdns_context_set_dns_root_servers(
# endif
size_t i;
getdns_dict *rr_dict;
getdns_return_t r;
getdns_return_t r = GETDNS_RETURN_GOOD;
getdns_bindata *addr_bd;
char dst[2048];
#endif
@ -2002,19 +2002,28 @@ getdns_context_set_dns_root_servers(
#ifdef HAVE_LIBUNBOUND
# ifdef HAVE_UB_CTX_SET_STUB
for (i=0; (!(r = getdns_list_get_dict(addresses, i, &rr_dict))); i++) {
if (getdns_dict_get_bindata(
for (i=0; !r; i++) {
if (!(r = getdns_list_get_bindata(addresses, i, &addr_bd)))
/* success! */
;
else if ((r = getdns_list_get_dict(addresses, i, &rr_dict)))
/* Not a bindata, not a dict? ERROR! */
break;
else if (getdns_dict_get_bindata(
rr_dict, "address_data", &addr_bd) &&
getdns_dict_get_bindata(
rr_dict, "/rdata/ipv4_address", &addr_bd) &&
getdns_dict_get_bindata(
rr_dict, "/rdata/ipv6_address", &addr_bd))
; /* Not a parsable address,
* pass because we allow root.hint's files as input
*/
/* Not a parsable address,
* pass because we allow root.hint's files as input
*/
continue;
else if (addr_bd->size == 16 &&
if (addr_bd->size == 16 &&
inet_ntop(AF_INET6, addr_bd->data, dst, sizeof(dst))) {
if (ub_ctx_set_stub(context->unbound_ctx,".",dst,1)) {
@ -2034,22 +2043,34 @@ getdns_context_set_dns_root_servers(
if (!(fh = fdopen(fd, "w")))
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
for (i=0; (!(r = getdns_list_get_dict(addresses, i, &rr_dict))); i++) {
for (i=0; !r; i++) {
dst_len = sizeof(dst);
if (!getdns_rr_dict2str_buf(rr_dict, dst, &dst_len))
if (!(r = getdns_list_get_bindata(addresses, i, &addr_bd)))
/* success! */
;
else if ((r = getdns_list_get_dict(addresses, i, &rr_dict)))
/* Not a bindata, not a dict? ERROR! */
break;
else if (!getdns_rr_dict2str_buf(rr_dict, dst, &dst_len)) {
fprintf(fh, "%s", dst);
continue;
else if (getdns_dict_get_bindata(
} else if (getdns_dict_get_bindata(
rr_dict, "address_data", &addr_bd) &&
getdns_dict_get_bindata(
rr_dict, "/rdata/ipv4_address", &addr_bd) &&
getdns_dict_get_bindata(
rr_dict, "/rdata/ipv6_address", &addr_bd))
; /* pass */
/* Not a parsable address,
* pass because we allow root.hint's files as input
*/
continue;
else if (addr_bd->size == 16 &&
if (addr_bd->size == 16 &&
inet_ntop(AF_INET6, addr_bd->data, dst, sizeof(dst)))
fprintf(fh,". NS "PRIsz".root-servers.getdnsapi.net.\n"
@ -2096,22 +2117,23 @@ getdns_context_set_dns_root_servers(
*
*/
getdns_return_t
getdns_context_set_append_name(struct getdns_context *context,
getdns_append_name_t value)
getdns_context_set_append_name(
getdns_context *context, getdns_append_name_t value)
{
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
if (value != GETDNS_APPEND_NAME_ALWAYS &&
value != GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE &&
value != GETDNS_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE
&& value != GETDNS_APPEND_NAME_NEVER) {
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
if (!context)
return GETDNS_RETURN_INVALID_PARAMETER;
context->append_name = value;
dispatch_updated(context, GETDNS_CONTEXT_CODE_APPEND_NAME);
return GETDNS_RETURN_GOOD;
switch ((int)value) {
case GETDNS_APPEND_NAME_ALWAYS:
case GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE:
case GETDNS_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE:
case GETDNS_APPEND_NAME_NEVER:
case GETDNS_APPEND_NAME_TO_SINGLE_LABEL_FIRST:
context->append_name = value;
dispatch_updated(context, GETDNS_CONTEXT_CODE_APPEND_NAME);
return GETDNS_RETURN_GOOD;
}
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
} /* getdns_context_set_append_name */
/*
@ -2304,34 +2326,56 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
uint8_t tsig_dname_spc[256], *tsig_dname;
size_t tsig_dname_len;
if ((r = getdns_list_get_dict(upstream_list, i, &dict)))
goto error;
if ((r = getdns_list_get_dict(upstream_list, i, &dict))) {
dict = NULL;
if ((r = getdns_dict_get_bindata(
dict, "address_type",&address_type)))
goto error;
if (address_type->size < 4)
goto invalid_parameter;
if (strncmp((char *)address_type->data, "IPv4", 4) == 0)
addr.ss_family = AF_INET;
else if (strncmp((char *)address_type->data, "IPv6", 4) == 0)
addr.ss_family = AF_INET6;
else goto invalid_parameter;
if ((r = getdns_list_get_bindata(
upstream_list, i, &address_data)))
goto error;
if ((r = getdns_dict_get_bindata(
dict, "address_data", &address_data)))
goto error;
if ((addr.ss_family == AF_INET &&
address_data->size != 4) ||
(addr.ss_family == AF_INET6 &&
address_data->size != 16))
goto invalid_parameter;
if (address_data->size == 4)
addr.ss_family = AF_INET;
else if (address_data->size == 16)
addr.ss_family = AF_INET6;
else goto invalid_parameter;
} else if ((r = getdns_dict_get_bindata(
dict, "address_type",&address_type))) {
/* Just address_data is also okay */
if ((r = getdns_dict_get_bindata(
dict, "address_data", &address_data)))
goto error;
if (address_data->size == 4)
addr.ss_family = AF_INET;
else if (address_data->size == 16)
addr.ss_family = AF_INET6;
else goto invalid_parameter;
} else {
if (address_type->size < 4)
goto invalid_parameter;
else if (!strncmp((char*)address_type->data,"IPv4",4))
addr.ss_family = AF_INET;
else if (!strncmp((char*)address_type->data,"IPv6",4))
addr.ss_family = AF_INET6;
else goto invalid_parameter;
if ((r = getdns_dict_get_bindata(
dict, "address_data", &address_data)))
goto error;
if ((addr.ss_family == AF_INET &&
address_data->size != 4) ||
(addr.ss_family == AF_INET6 &&
address_data->size != 16))
goto invalid_parameter;
}
if (inet_ntop(addr.ss_family, address_data->data,
addrstr, 1024) == NULL)
goto invalid_parameter;
if (getdns_dict_get_bindata(dict, "scope_id", &scope_id) ==
GETDNS_RETURN_GOOD) {
if (dict && getdns_dict_get_bindata(dict,"scope_id",&scope_id)
== GETDNS_RETURN_GOOD) {
if (strlen(addrstr) + scope_id->size > 1022)
goto invalid_parameter;
eos = &addrstr[strlen(addrstr)];
@ -2344,13 +2388,17 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
tsig_dname = NULL;
tsig_dname_len = 0;
if (getdns_dict_get_bindata(dict,
if (dict && getdns_dict_get_bindata(dict,
"tsig_algorithm", &tsig_alg_name) == GETDNS_RETURN_GOOD)
tsig_alg = _getdns_get_tsig_algo(tsig_alg_name);
else
tsig_alg = GETDNS_HMAC_MD5;
if (getdns_dict_get_bindata(dict, "tsig_name", &tsig_name))
if (!dict)
tsig_alg = GETDNS_NO_TSIG; /* No name, no TSIG */
else if (getdns_dict_get_bindata(
dict, "tsig_name", &tsig_name))
tsig_alg = GETDNS_NO_TSIG; /* No name, no TSIG */
else if (tsig_name->size == 0)
@ -2390,7 +2438,8 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
, tsig_name->size);
tsig_dname_len = tsig_name->size;
}
if (getdns_dict_get_bindata(dict, "tsig_secret", &tsig_key))
if (dict && getdns_dict_get_bindata(
dict, "tsig_secret", &tsig_key))
tsig_alg = GETDNS_NO_TSIG; /* No key, no TSIG */
/* Don't check TSIG length contraints here.
@ -2405,10 +2454,13 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
if (port == GETDNS_PORT_ZERO)
continue;
if (getdns_upstream_transports[j] != GETDNS_TRANSPORT_TLS)
(void) getdns_dict_get_int(dict, "port", &port);
else
(void) getdns_dict_get_int(dict, "tls_port", &port);
if (getdns_upstream_transports[j] != GETDNS_TRANSPORT_TLS) {
if (dict)
(void) getdns_dict_get_int(dict, "port", &port);
} else {
if (dict)
(void) getdns_dict_get_int(dict, "tls_port", &port);
}
(void) snprintf(portstr, 1024, "%d", (int)port);
if (getaddrinfo(addrstr, portstr, &hints, &ai))
@ -2426,7 +2478,7 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
upstream->transport = getdns_upstream_transports[j];
if (getdns_upstream_transports[j] == GETDNS_TRANSPORT_TLS) {
getdns_list *pubkey_pinset = NULL;
if ((r = getdns_dict_get_bindata(
if (dict && (r = getdns_dict_get_bindata(
dict, "tls_auth_name", &tls_auth_name)) == GETDNS_RETURN_GOOD) {
/*TODO: VALIDATE THIS STRING!*/
memcpy(upstream->tls_auth_name,
@ -2434,7 +2486,7 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
tls_auth_name->size);
upstream->tls_auth_name[tls_auth_name->size] = '\0';
}
if ((r = getdns_dict_get_list(dict, "tls_pubkey_pinset",
if (dict && (r = getdns_dict_get_list(dict, "tls_pubkey_pinset",
&pubkey_pinset)) == GETDNS_RETURN_GOOD) {
/* TODO: what if the user supplies tls_pubkey_pinset with
* something other than a list? */

View File

@ -95,5 +95,12 @@
#define DEBUG_SEC(...) DEBUG_OFF(__VA_ARGS__)
#endif
#if defined(TRACE_DEBUG) && TRACE_DEBUG
#include <time.h>
#define DEBUG_TRACE(...) DEBUG_ON(__VA_ARGS__)
#else
#define DEBUG_TRACE(...) DEBUG_OFF(__VA_ARGS__)
#endif
#endif
/* debug.h */

View File

@ -280,8 +280,7 @@ getdns_dict_get_names(const getdns_dict *dict, getdns_list **answer)
RBTREE_FOR(item, struct getdns_dict_item *,
(_getdns_rbtree_t *)&(dict->root)) {
_getdns_list_append_const_bindata(*answer,
strlen(item->node.key) + 1, item->node.key);
_getdns_list_append_string(*answer, item->node.key);
}
return GETDNS_RETURN_GOOD;
} /* getdns_dict_get_names */
@ -657,9 +656,26 @@ getdns_dict_set_bindata(
getdns_return_t
getdns_dict_util_set_string(getdns_dict *dict, char *name, const char *value)
{
return value
? _getdns_dict_set_const_bindata(dict, name, strlen(value), value)
: GETDNS_RETURN_INVALID_PARAMETER;
getdns_item *item;
getdns_bindata *newbindata;
getdns_return_t r;
if (!dict || !name || !value)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!(newbindata = _getdns_bindata_copy(
&dict->mf, strlen(value) + 1, (uint8_t *)value)))
return GETDNS_RETURN_MEMORY_ERROR;
newbindata->size -= 1;
if ((r = _getdns_dict_find_and_add(dict, name, &item))) {
_getdns_bindata_destroy(&dict->mf, newbindata);
return r;
}
item->dtype = t_bindata;
item->data.bindata = newbindata;
return GETDNS_RETURN_GOOD;
} /* getdns_dict_util_set_dict */
/*---------------------------------------- getdns_dict_set_int */
@ -766,7 +782,7 @@ getdns_pp_bindata(gldns_buffer *buf, size_t indent,
(void)gldns_wire2str_dname_buf(
bindata->data, bindata->size, spc, sizeof(spc));
if (gldns_buffer_printf(
buf, (json ? "\"%s\"" : "of \"%s\">"), spc) < 0)
buf, (json ? "\"%s\"" : "for %s>"), spc) < 0)
return -1;
} else if (json) {
if (gldns_buffer_printf(buf, "[") < 0)

View File

@ -210,9 +210,6 @@
#include "list.h"
#include "util/val_secalgo.h"
/* Maximum number of canonical name redirections for one name */
#define MAX_CNAMES 100
#define SIGNATURE_VERIFIED 0x10000
#define NSEC3_ITERATION_COUNT_HIGH 0x20000
#define NO_SUPPORTED_ALGORITHMS 0x40000
@ -1069,7 +1066,7 @@ static void add_question2val_chain(struct mem_funcs *mf,
q_rrset.pkt = pkt;
q_rrset.pkt_len = pkt_len;
for (anti_loop = MAX_CNAMES; anti_loop; anti_loop--) {
for (anti_loop = MAX_CNAME_REFERRALS; anti_loop; anti_loop--) {
if (!(rr = rrtype_iter_init(&rr_spc, &q_rrset)))
break;
if (!(rdf = _getdns_rdf_iter_init(&rdf_spc, &rr->rr_i)))

View File

@ -84,7 +84,7 @@ static int
no_answer(getdns_dns_req *dns_req)
{
getdns_network_req **netreq_p, *netreq;
int new_canonical = 0;
int new_canonical = 0, cnames_followed;
uint8_t canon_spc[256];
const uint8_t *canon;
size_t canon_len;
@ -103,7 +103,7 @@ no_answer(getdns_dns_req *dns_req)
canon_len = netreq->owner->name_len;
if (netreq->request_type != GETDNS_RRTYPE_CNAME
&& GLDNS_ANCOUNT(netreq->response) > 1) do {
new_canonical = 0;
new_canonical = 0, cnames_followed = 0;
for ( rr = _getdns_rr_iter_init(&rr_spc
, netreq->response
, netreq->response_len)
@ -131,8 +131,9 @@ no_answer(getdns_dns_req *dns_req)
canon = _getdns_rdf_if_or_as_decompressed(
rdf, canon_spc, &canon_len);
new_canonical = 1;
cnames_followed++;
}
} while (new_canonical);
} while (new_canonical && cnames_followed<MAX_CNAME_REFERRALS);
for ( rr = _getdns_rr_iter_init(&rr_spc
, netreq->response
, netreq->response_len)

View File

@ -145,3 +145,4 @@ getdns_wire2rr_dict_buf
getdns_wire2rr_dict_scan
plain_mem_funcs_user_arg
priv_getdns_context_mf
_getdns_get_const_name_info

View File

@ -602,9 +602,25 @@ getdns_list_set_bindata(
static getdns_return_t
getdns_list_set_string(getdns_list *list, size_t index, const char *value)
{
return value
? _getdns_list_set_const_bindata(list, index, strlen(value), value)
: GETDNS_RETURN_INVALID_PARAMETER;
getdns_bindata *newbindata;
getdns_return_t r;
if (!list || !value)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!(newbindata = _getdns_bindata_copy(
&list->mf, strlen(value) + 1, (uint8_t *)value)))
return GETDNS_RETURN_MEMORY_ERROR;
newbindata->size -= 1;
if ((r = _getdns_list_request_index(list, index))) {
_getdns_bindata_destroy(&list->mf, newbindata);
return r;
}
list->items[index].dtype = t_bindata;
list->items[index].data.bindata = newbindata;
return GETDNS_RETURN_GOOD;
} /* getdns_list_set_string */
/*---------------------------------------- getdns_list_set_int */

View File

@ -8,11 +8,19 @@ cat > const-info.c << END_OF_HEAD
#include "getdns/getdns.h"
#include "getdns/getdns_extra.h"
#include "const-info.h"
#include <string.h>
static struct const_info consts_info[] = {
{ -1, NULL, "/* <unknown getdns value> */" },
END_OF_HEAD
gawk '/^[ ]+GETDNS_[A-Z_]+[ ]+=[ ]+[0-9]+/{ key = sprintf("%4d", $3); consts[key] = $1; }/^#define GETDNS_[A-Z_]+[ ]+[0-9]+/ && !/^#define GETDNS_RRTYPE/ && !/^#define GETDNS_RRCLASS/ && !/^#define GETDNS_OPCODE/ && !/^#define GETDNS_RCODE/ && !/_TEXT/{ key = sprintf("%4d", $3); consts[key] = $2; }/^#define GETDNS_[A-Z_]+[ ]+\(\(getdns_(return|append_name)_t) [0-9]+ \)/{ key = sprintf("%4d", $4); consts[key] = $2; }END{ n = asorti(consts, const_vals); for ( i = 1; i <= n; i++) { val = const_vals[i]; name = consts[val]; print "\t{ "val", \""name"\", "name"_TEXT },"}}' getdns/getdns.h.in getdns/getdns_extra.h.in | sed 's/,,/,/g' >> const-info.c
cat >> const-info.c << END_OF_MIDDLE
};
struct const_name_info { const char *name; int code; };
static struct const_name_info consts_name_info[] = {
END_OF_MIDDLE
gawk '/^[ ]+GETDNS_[A-Z_]+[ ]+=[ ]+[0-9]+/{ key = sprintf("%d", $3); consts[$1] = key; }/^#define GETDNS_[A-Z_]+[ ]+[0-9]+/ && !/_TEXT/{ key = sprintf("%d", $3); consts[$2] = key; }/^#define GETDNS_[A-Z_]+[ ]+\(\(getdns_(return|append_name)_t) [0-9]+ \)/{ key = sprintf("%d", $4); consts[$2] = key; }END{ n = asorti(consts, const_vals); for ( i = 1; i <= n; i++) { val = const_vals[i]; name = consts[val]; print "\t{ \""val"\", "name" },"}}' getdns/getdns.h.in getdns/getdns_extra.h.in | sed 's/,,/,/g' >> const-info.c
cat >> const-info.c << END_OF_TAIL
};
@ -32,6 +40,25 @@ _getdns_get_const_info(int value)
return consts_info;
}
static int const_name_info_cmp(const void *a, const void *b)
{
return strcmp( ((struct const_name_info *) a)->name
, ((struct const_name_info *) b)->name );
}
int
_getdns_get_const_name_info(const char *name, int *code)
{
struct const_name_info key = { name, 0 };
struct const_name_info *i = bsearch(&key, consts_name_info,
sizeof(consts_name_info) / sizeof(struct const_name_info),
sizeof(struct const_name_info), const_name_info_cmp);
if (!i)
return 0;
if (code)
*code = i->code;
return 1;
}
const char *
getdns_get_errorstr_by_id(uint16_t err)
{

View File

@ -10,6 +10,7 @@ write_symbols() {
write_symbols libgetdns.symbols getdns/getdns.h.in getdns/getdns_extra.h.in
echo plain_mem_funcs_user_arg >> libgetdns.symbols
echo priv_getdns_context_mf >> libgetdns.symbols
echo _getdns_get_const_name_info >> libgetdns.symbols
write_symbols extension/libevent.symbols getdns/getdns_ext_libevent.h
write_symbols extension/libev.symbols getdns/getdns_ext_libev.h
write_symbols extension/libuv.symbols getdns/getdns_ext_libuv.h

View File

@ -197,8 +197,6 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
buf = net_req->query;
gldns_write_uint16(buf + 2, 0); /* reset all flags */
GLDNS_RD_SET(buf);
if (dnssec_extension_set) /* We will do validation ourselves */
GLDNS_CD_SET(buf);
GLDNS_OPCODE_SET(buf, GLDNS_PACKET_QUERY);
gldns_write_uint16(buf + GLDNS_QDCOUNT_OFF, 1); /* 1 query */
gldns_write_uint16(buf + GLDNS_ANCOUNT_OFF, 0); /* 0 answers */
@ -209,6 +207,8 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
gldns_buffer_init_frm_data(
&gbuf, net_req->query, net_req->wire_data_sz - 2);
_getdns_reply_dict2wire(extensions, &gbuf, 1);
if (dnssec_extension_set) /* We will do validation ourselves */
GLDNS_CD_SET(net_req->query);
if (with_opt) {
net_req->opt = buf;

View File

@ -324,7 +324,11 @@ process_keepalive(
if (netreq->keepalive_sent == 1)
/* If no keepalive sent back, then we must use 0 idle timeout
as server does not support it.*/
#if defined(KEEP_CONNECTIONS_OPEN_DEBUG) && KEEP_CONNECTIONS_OPEN_DEBUG
upstream->keepalive_timeout = netreq->owner->context->idle_timeout;
#else
upstream->keepalive_timeout = 0;
#endif
return;
}
/* Use server sent value unless the client specified a shorter one.

View File

@ -94,6 +94,9 @@ $(ALL_OBJS):
$(NON_C99_OBJS):
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -D_POSIX_C_SOURCE=200112L -D_XOPEN_SOURCE=600 -c $(srcdir)/$(@:.lo=.c) -o $@
jsmn.lo:
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -DJSMN_GETDNS -c $(srcdir)/jsmn/jsmn.c -o $@
tests_dict: tests_dict.lo testmessages.lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ tests_dict.lo testmessages.lo
@ -124,8 +127,8 @@ check_getdns_uv: check_getdns.lo check_getdns_common.lo check_getdns_context_set
check_getdns_ev: check_getdns.lo check_getdns_common.lo check_getdns_context_set_timeout.lo check_getdns_transport.lo check_getdns_libev.lo ../libgetdns_ext_ev.la
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ check_getdns.lo check_getdns_common.lo check_getdns_context_set_timeout.lo check_getdns_transport.lo check_getdns_libev.lo $(LDFLAGS) $(LDLIBS) $(CHECK_CFLAGS) $(CHECK_LIBS) ../libgetdns_ext_ev.la $(EXTENSION_LIBEV_LDFLAGS) $(EXTENSION_LIBEV_EXT_LIBS)
getdns_query: getdns_query.lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ getdns_query.lo $(LDFLAGS) $(LDLIBS)
getdns_query: getdns_query.lo jsmn.lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ getdns_query.lo jsmn.lo $(LDFLAGS) $(LDLIBS)
scratchpad: scratchpad.lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ scratchpad.lo $(LDFLAGS) $(LDLIBS)
@ -212,6 +215,8 @@ depend:
-e 's? \.\./getdns/getdns_ext_libev\.h? $$(srcdir)/../getdns/getdns_ext_libev.h?g' \
-e 's? \.\./getdns/getdns_ext_libuv\.h? $$(srcdir)/../getdns/getdns_ext_libuv.h?g' \
-e 's? \.\./debug\.h? $$(srcdir)/../debug.h?g' \
-e 's? \.\./const-info\.h? $$(srcdir)/../const-info.h?g' \
-e 's? jsmn/jsmn\.h? $$(srcdir)/jsmn/jsmn.h?g' \
-e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' >> Makefile.in.new )
(cd $(srcdir) ; diff Makefile.in.new Makefile.in && rm Makefile.in.new \
|| mv Makefile.in.new Makefile.in )
@ -222,27 +227,28 @@ depend:
# Dependencies for the unit tests
check_getdns.lo check_getdns.o: $(srcdir)/check_getdns.c ../getdns/getdns.h $(srcdir)/check_getdns_common.h \
../getdns/getdns_extra.h $(srcdir)/check_getdns_general.h \
$(srcdir)/check_getdns_general_sync.h $(srcdir)/check_getdns_address.h \
$(srcdir)/check_getdns_address_sync.h $(srcdir)/check_getdns_hostname.h \
$(srcdir)/check_getdns_hostname_sync.h $(srcdir)/check_getdns_context_create.h \
$(srcdir)/check_getdns_context_destroy.h $(srcdir)/check_getdns_cancel_callback.h \
$(srcdir)/check_getdns_list_get_length.h $(srcdir)/check_getdns_list_get_data_type.h \
$(srcdir)/check_getdns_list_get_dict.h $(srcdir)/check_getdns_list_get_list.h \
$(srcdir)/check_getdns_list_get_int.h $(srcdir)/check_getdns_list_get_bindata.h \
$(srcdir)/check_getdns_dict_get_names.h $(srcdir)/check_getdns_dict_get_data_type.h \
$(srcdir)/check_getdns_dict_get_dict.h $(srcdir)/check_getdns_dict_get_list.h \
$(srcdir)/check_getdns_dict_get_bindata.h $(srcdir)/check_getdns_dict_get_int.h \
$(srcdir)/check_getdns_dict_destroy.h $(srcdir)/check_getdns_dict_set_dict.h \
$(srcdir)/check_getdns_dict_set_list.h $(srcdir)/check_getdns_dict_set_bindata.h \
$(srcdir)/check_getdns_dict_set_int.h $(srcdir)/check_getdns_convert_ulabel_to_alabel.h \
$(srcdir)/check_getdns_convert_alabel_to_ulabel.h $(srcdir)/check_getdns_pretty_print_dict.h \
$(srcdir)/check_getdns_display_ip_address.h \
../getdns/getdns_extra.h $(srcdir)/check_getdns_address.h \
$(srcdir)/check_getdns_address_sync.h $(srcdir)/check_getdns_cancel_callback.h \
$(srcdir)/check_getdns_context_create.h $(srcdir)/check_getdns_context_destroy.h \
$(srcdir)/check_getdns_context_set_context_update_callback.h \
$(srcdir)/check_getdns_context_set_dns_transport.h \
$(srcdir)/check_getdns_context_set_timeout.h \
$(srcdir)/check_getdns_context_set_upstream_recursive_servers.h \
$(srcdir)/check_getdns_convert_alabel_to_ulabel.h \
$(srcdir)/check_getdns_convert_ulabel_to_alabel.h $(srcdir)/check_getdns_dict_destroy.h \
$(srcdir)/check_getdns_dict_get_bindata.h $(srcdir)/check_getdns_dict_get_data_type.h \
$(srcdir)/check_getdns_dict_get_dict.h $(srcdir)/check_getdns_dict_get_int.h \
$(srcdir)/check_getdns_dict_get_list.h $(srcdir)/check_getdns_dict_get_names.h \
$(srcdir)/check_getdns_dict_set_bindata.h $(srcdir)/check_getdns_dict_set_dict.h \
$(srcdir)/check_getdns_dict_set_int.h $(srcdir)/check_getdns_dict_set_list.h \
$(srcdir)/check_getdns_display_ip_address.h $(srcdir)/check_getdns_general.h \
$(srcdir)/check_getdns_general_sync.h $(srcdir)/check_getdns_hostname.h \
$(srcdir)/check_getdns_hostname_sync.h $(srcdir)/check_getdns_list_get_bindata.h \
$(srcdir)/check_getdns_list_get_data_type.h $(srcdir)/check_getdns_list_get_dict.h \
$(srcdir)/check_getdns_list_get_int.h $(srcdir)/check_getdns_list_get_length.h \
$(srcdir)/check_getdns_list_get_list.h $(srcdir)/check_getdns_pretty_print_dict.h \
$(srcdir)/check_getdns_service.h $(srcdir)/check_getdns_service_sync.h \
$(srcdir)/check_getdns_transport.h $(srcdir)/check_getdns_context_set_dns_transport.h
$(srcdir)/check_getdns_transport.h
check_getdns_common.lo check_getdns_common.o: $(srcdir)/check_getdns_common.c ../getdns/getdns.h \
../config.h $(srcdir)/check_getdns_common.h ../getdns/getdns_extra.h \
$(srcdir)/check_getdns_eventloop.h
@ -265,7 +271,7 @@ check_getdns_transport.lo check_getdns_transport.o: $(srcdir)/check_getdns_trans
$(srcdir)/check_getdns_transport.h $(srcdir)/check_getdns_common.h ../getdns/getdns.h \
../getdns/getdns_extra.h
getdns_query.lo getdns_query.o: $(srcdir)/getdns_query.c ../config.h $(srcdir)/../debug.h ../config.h \
../getdns/getdns.h ../getdns/getdns_extra.h
$(srcdir)/../const-info.h $(srcdir)/jsmn/jsmn.h ../getdns/getdns.h ../getdns/getdns_extra.h
scratchpad.template.lo scratchpad.template.o: scratchpad.template.c ../getdns/getdns.h \
../getdns/getdns_extra.h
testmessages.lo testmessages.o: $(srcdir)/testmessages.c $(srcdir)/testmessages.h

File diff suppressed because it is too large Load Diff

1
src/test/jsmn Submodule

@ -0,0 +1 @@
Subproject commit daa17063c67f0dfe873af25ab6b664641c8cf90c

View File

@ -1,6 +1,6 @@
BaseName: 270-header-extension
Version: 1.0
Description: Test json pointers
Description: Set values in the DNS header with the header extension
CreationDate: do 28 apr 2016 13:48:05 CEST
Maintainer: Willem Toorop
Category:

View File

@ -1,6 +1,6 @@
{
"answer_type": GETDNS_NAMETYPE_DNS,
"canonical_name": <bindata of "bogus.nlnetlabs.nl.">,
"canonical_name": <bindata for bogus.nlnetlabs.nl.>,
"replies_tree":
[
{
@ -8,7 +8,7 @@
"answer": [],
"answer_type": GETDNS_NAMETYPE_DNS,
"authority": [],
"canonical_name": <bindata of "bogus.nlnetlabs.nl.">,
"canonical_name": <bindata for bogus.nlnetlabs.nl.>,
"header":
{
"aa": 0,

View File

@ -707,7 +707,7 @@ _getdns_create_reply_dict(getdns_context *context, getdns_network_req *req,
goto error;
cnames_followed = new_canonical;
while (new_canonical) {
while (cnames_followed < MAX_CNAME_REFERRALS && new_canonical) {
new_canonical = 0;
for ( rr_iter = _getdns_rr_iter_init(&rr_iter_storage
@ -737,6 +737,7 @@ _getdns_create_reply_dict(getdns_context *context, getdns_network_req *req,
canonical_name = _getdns_rdf_if_or_as_decompressed(
rdf_iter,canonical_name_space,&canonical_name_len);
new_canonical = 1;
cnames_followed++;
}
}
if (_getdns_dict_set_const_bindata(