diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..06b16b93 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "src/test/jsmn"] + path = src/test/jsmn + url = https://github.com/getdnsapi/jsmn.git + branch = getdns diff --git a/configure.ac b/configure.ac index 63391889..a4713279 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/src/const-info.c b/src/const-info.c index 5a25dd83..9e1b28fc 100644 --- a/src/const-info.c +++ b/src/const-info.c @@ -5,6 +5,7 @@ #include "getdns/getdns.h" #include "getdns/getdns_extra.h" #include "const-info.h" +#include static struct const_info consts_info[] = { { -1, NULL, "/* */" }, @@ -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) { diff --git a/src/const-info.h b/src/const-info.h index 39d7c98e..f41a1c52 100644 --- a/src/const-info.h +++ b/src/const-info.h @@ -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 diff --git a/src/context.c b/src/context.c index cbbcbab0..5acba6cf 100644 --- a/src/context.c +++ b/src/context.c @@ -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? */ diff --git a/src/debug.h b/src/debug.h index a06c95cb..222fbf2d 100644 --- a/src/debug.h +++ b/src/debug.h @@ -95,5 +95,12 @@ #define DEBUG_SEC(...) DEBUG_OFF(__VA_ARGS__) #endif +#if defined(TRACE_DEBUG) && TRACE_DEBUG +#include +#define DEBUG_TRACE(...) DEBUG_ON(__VA_ARGS__) +#else +#define DEBUG_TRACE(...) DEBUG_OFF(__VA_ARGS__) +#endif + #endif /* debug.h */ diff --git a/src/dict.c b/src/dict.c index 910e0d28..8e7eec8f 100644 --- a/src/dict.c +++ b/src/dict.c @@ -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) diff --git a/src/dnssec.c b/src/dnssec.c index 7c851aba..e3a8a65d 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -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))) diff --git a/src/general.c b/src/general.c index 1119106d..8e29fb58 100644 --- a/src/general.c +++ b/src/general.c @@ -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_followedresponse , netreq->response_len) diff --git a/src/libgetdns.symbols b/src/libgetdns.symbols index 71564132..4bab9617 100644 --- a/src/libgetdns.symbols +++ b/src/libgetdns.symbols @@ -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 diff --git a/src/list.c b/src/list.c index 52cccde2..eec2a1c1 100644 --- a/src/list.c +++ b/src/list.c @@ -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 */ diff --git a/src/mk-const-info.c.sh b/src/mk-const-info.c.sh index 631b89c6..a53de949 100755 --- a/src/mk-const-info.c.sh +++ b/src/mk-const-info.c.sh @@ -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 static struct const_info consts_info[] = { { -1, NULL, "/* */" }, 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) { diff --git a/src/mk-symfiles.sh b/src/mk-symfiles.sh index 878196b9..56dc4f43 100755 --- a/src/mk-symfiles.sh +++ b/src/mk-symfiles.sh @@ -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 diff --git a/src/request-internal.c b/src/request-internal.c index b36cb85e..db555266 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -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; diff --git a/src/stub.c b/src/stub.c index ab7f1805..fe35f733 100644 --- a/src/stub.c +++ b/src/stub.c @@ -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. diff --git a/src/test/Makefile.in b/src/test/Makefile.in index d80d8c17..7c5ea114 100644 --- a/src/test/Makefile.in +++ b/src/test/Makefile.in @@ -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 diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 737a3b11..bce8294d 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -27,12 +27,26 @@ #include "config.h" #include "debug.h" +#include "const-info.h" +#include "jsmn/jsmn.h" #include #include #include #include #include #include +#ifndef USE_WINSOCK +#include +#include +#include +#else +#include +#include +typedef unsigned short in_port_t; +#include +#include +#endif + #define MAX_TIMEOUTS FD_SETSIZE @@ -263,8 +277,12 @@ static char *the_root = "."; static char *name; static getdns_context *context; static getdns_dict *extensions; +static getdns_dict *query_extensions_spc = NULL; static getdns_list *pubkey_pinset = NULL; +static getdns_list *listen_list = NULL; +static getdns_dict *listen_dict = NULL; static size_t pincount = 0; +static size_t listen_count = 0; static uint16_t request_type = GETDNS_RRTYPE_NS; static int timeout, edns0_size, padding_blocksize; static int async = 0, interactive = 0; @@ -344,6 +362,7 @@ ipaddr_dict(getdns_context *context, char *ipstr) char *T = strchr(ipstr, '^'), *tsig_name_str = "" , *tsig_secret_str = "" , *tsig_algorithm_str = ""; + char *br, *c; int tsig_secret_size; uint8_t tsig_secret_buf[256]; /* 4 times SHA512 */ getdns_bindata tsig_secret; @@ -353,6 +372,23 @@ ipaddr_dict(getdns_context *context, char *ipstr) addr.data = buf; if (!r) return NULL; + + if (*ipstr == '[') { + char *br = strchr(ipstr, ']'); + if (br) { + ipstr += 1; + *br = 0; + if ((c = strchr(br + 1, ':'))) { + p = c; + } + } + } else if ((br = strchr(ipstr, '.')) && (c = strchr(br + 1, ':')) + && (T == NULL || c < T)) + p = c; + + else if ((*ipstr == '*') && (c = strchr(ipstr+1, ':'))) + p = c; + if (s) { *s = 0; scope_id_str = s + 1; @@ -385,7 +421,11 @@ ipaddr_dict(getdns_context *context, char *ipstr) tsig_name_str = ""; } } - if (strchr(ipstr, ':')) { + if (*ipstr == '*') { + getdns_dict_util_set_string(r, "address_type", "IPv6"); + addr.size = 16; + (void) memset(buf, 0, 16); + } else if (strchr(ipstr, ':')) { getdns_dict_util_set_string(r, "address_type", "IPv6"); addr.size = 16; if (inet_pton(AF_INET6, ipstr, buf) <= 0) { @@ -458,15 +498,17 @@ void print_usage(FILE *out, const char *progname) { fprintf(out, "usage: %s [