From c14c6fe9934d24f76304674b416e9d3f0af6a960 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Tue, 3 May 2016 13:35:01 +0200 Subject: [PATCH 01/41] Print dname's as primitive type --- src/dict.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dict.c b/src/dict.c index 58b10631..3d84bc52 100644 --- a/src/dict.c +++ b/src/dict.c @@ -764,7 +764,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) From 9f3ad7d603ca18f3bf878c0a3d553719107abe55 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Tue, 3 May 2016 13:38:40 +0200 Subject: [PATCH 02/41] Add our version of jsmn as submodule --- .gitmodules | 4 ++++ src/test/jsmn | 1 + 2 files changed, 5 insertions(+) create mode 100644 .gitmodules create mode 160000 src/test/jsmn diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..0d2dfd4d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "src/test/jsmn"] + path = src/test/jsmn + url = github.com:getdnsapi/jsmn.git + branch = getdns diff --git a/src/test/jsmn b/src/test/jsmn new file mode 160000 index 00000000..73132efb --- /dev/null +++ b/src/test/jsmn @@ -0,0 +1 @@ +Subproject commit 73132efb1e2156b7755514cd94cf7e826961665f From 5085af0d28474316f0bce7a621f669b2fcc3f1a3 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Tue, 3 May 2016 14:52:30 +0200 Subject: [PATCH 03/41] Abit more leniency in what to accept for upstreams address_type no longer necessary instead of address dicts, just bindata is now also ok --- src/context.c | 89 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 31 deletions(-) diff --git a/src/context.c b/src/context.c index cc059f6f..0beaaca3 100644 --- a/src/context.c +++ b/src/context.c @@ -2301,34 +2301,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)]; @@ -2341,13 +2363,14 @@ 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 && getdns_dict_get_bindata( + dict, "tsig_name", &tsig_name)) tsig_alg = GETDNS_NO_TSIG; /* No name, no TSIG */ else if (tsig_name->size == 0) @@ -2387,7 +2410,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. @@ -2402,10 +2426,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)) @@ -2423,7 +2450,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, @@ -2431,7 +2458,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? */ From a80afd357eca98df2934b771e3e1ed12ea13ead8 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 4 May 2016 09:38:26 +0200 Subject: [PATCH 04/41] Initial UDP only server for getdns_query Provide listening addresses in the same way as upstreams, but with the initial character '~' instead of '@'. --- src/test/getdns_query.c | 292 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 289 insertions(+), 3 deletions(-) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 44af2b5a..6067cc2d 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -33,6 +33,18 @@ #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 @@ -264,7 +276,9 @@ static char *name; static getdns_context *context; static getdns_dict *extensions; static getdns_list *pubkey_pinset = NULL; +static getdns_list *listen_list = 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; @@ -512,9 +526,9 @@ print_usage(FILE *out, const char *progname) fprintf(out, "\t-m\tSet TLS authentication mode to REQUIRED\n"); fprintf(out, "\t-p\tPretty print response dict\n"); fprintf(out, "\t-P \tPad TLS queries to a multiple of blocksize\n"); + fprintf(out, "\t-q\tQuiet mode - don't print response\n"); fprintf(out, "\t-r\tSet recursing resolution type\n"); fprintf(out, "\t-R \tRead root hints from \n"); - fprintf(out, "\t-q\tQuiet mode - don't print response\n"); fprintf(out, "\t-s\tSet stub resolution type (default = recursing)\n"); fprintf(out, "\t-S\tservice lookup ( is ignored)\n"); fprintf(out, "\t-t \tSet timeout in miliseconds\n"); @@ -800,6 +814,19 @@ getdns_return_t parse_args(int argc, char **argv) upstream_count++, upstream); } continue; + } else if (arg[0] == '~') { + getdns_dict *ipaddr = ipaddr_dict(context, arg + 1); + if (ipaddr) { + if (!listen_list && + !(listen_list = + getdns_list_create_with_context(context))){ + fprintf(stderr, "Could not create upstream list\n"); + return GETDNS_RETURN_MEMORY_ERROR; + } + getdns_list_set_dict(listen_list, + listen_count++, ipaddr); + } + continue; } else if (arg[0] != '-') { name = arg; continue; @@ -1313,6 +1340,260 @@ void read_line_cb(void *userarg) } } +typedef struct listen_data { + socklen_t addr_len; + struct sockaddr_storage addr; + int fd; + getdns_transport_list_t transport; + getdns_eventloop_event event; +} listen_data; + + +listen_data *listening = NULL; + +typedef struct dns_msg { + listen_data *ld; + getdns_dict *query; + getdns_transaction_t transaction_id; +} dns_msg; + +typedef struct udp_msg { + dns_msg super; + struct sockaddr_storage remote_in; + socklen_t addrlen; +} udp_msg; + +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; + uint8_t buf[65536]; + size_t len = sizeof(buf); + + if (callback_type != GETDNS_CALLBACK_COMPLETE) { + if (response) + getdns_dict_destroy(response); + return; + } + if ((r = getdns_dict_get_int(msg->query, "/header/id", &qid))) + fprintf(stderr, "Could not get qid: %s\n", + getdns_get_errorstr_by_id(r)); + + else if (!response) + fprintf(stderr, "No response in request_cb\n"); + + else if ((r = getdns_dict_set_int(response, + "/replies_tree/0/header/id", qid))) + fprintf(stderr, "Could not set qid: %s\n", + getdns_get_errorstr_by_id(r)); + + else if ((r = getdns_msg_dict2wire_buf(response, buf, &len))) + fprintf(stderr, "Could not convert reply: %s\n", + getdns_get_errorstr_by_id(r)); + + else if (msg->ld->transport == GETDNS_TRANSPORT_UDP) { + udp_msg *msg = (udp_msg *)userarg; + + fprintf(stderr, "fd: %d, len: %d, reply: %s\n", msg->super.ld->fd, (int)len, + getdns_pretty_print_dict(response)); + + if (sendto(msg->super.ld->fd, buf, len, 0, + (struct sockaddr *)&msg->remote_in, msg->addrlen) == -1) + perror("sendto"); + } + if (msg) { + getdns_dict_destroy(msg->query); + free(msg); + } + if (response) + getdns_dict_destroy(response); + +} + +getdns_return_t schedule_request(dns_msg *msg) +{ + getdns_bindata *qname; + char *qname_str = NULL; + uint32_t qtype; + getdns_return_t r; + + if ((r = getdns_dict_get_bindata(msg->query,"/question/qname",&qname))) + fprintf(stderr, "Could not get qname from query: %s\n", + getdns_get_errorstr_by_id(r)); + + else if ((r = getdns_convert_dns_name_to_fqdn(qname, &qname_str))) + fprintf(stderr, "Could not convert qname: %s\n", + getdns_get_errorstr_by_id(r)); + + else if ((r=getdns_dict_get_int(msg->query,"/question/qtype",&qtype))) + fprintf(stderr, "Could get qtype from query: %s\n", + getdns_get_errorstr_by_id(r)); + + else if ((r = getdns_general(context, qname_str, qtype, + extensions, msg, &msg->transaction_id, request_cb))) + fprintf(stderr, "Could not schedule query: %s\n", + getdns_get_errorstr_by_id(r)); + + return r; +} + +void udp_read_cb(void *userarg) +{ + listen_data *ld = (listen_data *)userarg; + udp_msg *msg; + uint8_t buf[65536]; + ssize_t len; + getdns_return_t r; + + assert(userarg); + + if (!(msg = malloc(sizeof(udp_msg)))) + return; + + msg->super.ld = ld; + msg->addrlen = sizeof(msg->remote_in); + if ((len = recvfrom(ld->fd, buf, sizeof(buf), 0, + (struct sockaddr *)&msg->remote_in, &msg->addrlen)) == -1) + perror("recvfrom"); + + else if ((r = getdns_wire2msg_dict(buf, len, &msg->super.query))) + fprintf(stderr, "Error converting query dns msg: %s\n", + getdns_get_errorstr_by_id(r)); + + else if ((r = schedule_request(&msg->super))) { + fprintf(stderr, "Error scheduling query: %s\n", + getdns_get_errorstr_by_id(r)); + + getdns_dict_destroy(msg->super.query); + } else + return; + free(msg); +} + +getdns_return_t start_daemon() +{ + static const getdns_transport_list_t listen_transports[] + = { GETDNS_TRANSPORT_UDP, GETDNS_TRANSPORT_TCP }; + static const uint32_t transport_ports[] = { 53, 53 }; + static const size_t n_transports = sizeof( listen_transports) + / sizeof(*listen_transports); + + size_t i; + size_t t; + struct addrinfo hints; + getdns_return_t r = GETDNS_RETURN_GOOD; + char addrstr[1024], portstr[1024], *eos; + + if (!listen_count) + return GETDNS_RETURN_GOOD; + + if (!(listening = malloc( + sizeof(listen_data) * n_transports * listen_count))) + return GETDNS_RETURN_MEMORY_ERROR; + + (void) memset(listening, 0, + sizeof(listen_data) * n_transports * listen_count); + (void) memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_NUMERICHOST; + + for (i = 0; !r && i < listen_count; i++) { + getdns_dict *dict; + getdns_bindata *address_data; + struct sockaddr_storage addr; + getdns_bindata *scope_id; + + if ((r = getdns_list_get_dict(listen_list, i, &dict))) + break; + if ((r = getdns_dict_get_bindata( + dict, "address_data", &address_data))) + break; + if (address_data->size == 4) + addr.ss_family = AF_INET; + else if (address_data->size == 16) + addr.ss_family = AF_INET6; + else { + r = GETDNS_RETURN_INVALID_PARAMETER; + break; + } + if (inet_ntop(addr.ss_family, + address_data->data, addrstr, 1024) == NULL) { + r = GETDNS_RETURN_INVALID_PARAMETER; + break; + } + if (dict && getdns_dict_get_bindata(dict,"scope_id",&scope_id) + == GETDNS_RETURN_GOOD) { + if (strlen(addrstr) + scope_id->size > 1022) { + r = GETDNS_RETURN_INVALID_PARAMETER; + break; + } + eos = &addrstr[strlen(addrstr)]; + *eos++ = '%'; + (void) memcpy(eos, scope_id->data, scope_id->size); + eos[scope_id->size] = 0; + } + for (t = 0; !r && t < n_transports; t++) { + getdns_transport_list_t transport + = listen_transports[t]; + uint32_t port = transport_ports[t]; + struct addrinfo *ai; + listen_data *ld = &listening[i * n_transports + t]; + + ld->fd = -1; + (void) getdns_dict_get_int(dict, + ( transport == GETDNS_TRANSPORT_TLS + ? "tls_port" : "port" ), &port); + + (void) snprintf(portstr, 1024, "%d", (int)port); + + if (getaddrinfo(addrstr, portstr, &hints, &ai)) { + r = GETDNS_RETURN_INVALID_PARAMETER; + break; + } + if (!ai) + continue; + + ld->addr.ss_family = addr.ss_family; + ld->addr_len = ai->ai_addrlen; + (void) memcpy(&ld->addr, ai->ai_addr, ai->ai_addrlen); + ld->transport = transport; + freeaddrinfo(ai); + } + + } + if (r) { + free(listening); + listening = NULL; + } else for (i = 0; !r && i < listen_count * n_transports; i++) { + listen_data *ld = &listening[i]; + + if (ld->transport != GETDNS_TRANSPORT_UDP && + ld->transport != GETDNS_TRANSPORT_TCP) + continue; + + if ((ld->fd = socket(ld->addr.ss_family, + ( ld->transport == GETDNS_TRANSPORT_UDP + ? SOCK_DGRAM : SOCK_STREAM), 0)) == -1) + perror("socket"); + + else if (bind(ld->fd, (struct sockaddr *)&ld->addr, + ld->addr_len) == -1) + perror("bind"); + + else if (ld->transport == GETDNS_TRANSPORT_UDP) { + ld->event.userarg = ld; + ld->event.read_cb = udp_read_cb; + (void) my_eventloop_schedule( + &my_loop.base, ld->fd, -1, &ld->event); + + } else if (listen(ld->fd, 16) == -1) + perror("listen"); + } + return r; +} + int main(int argc, char **argv) { @@ -1344,6 +1625,11 @@ main(int argc, char **argv) } else fp = stdin; + if (listen_count || interactive) { + if ((r = getdns_context_set_eventloop(context, &my_loop.base))) + goto done_destroy_context; + } + start_daemon(); /* Make the call */ if (interactive) { @@ -1351,8 +1637,6 @@ main(int argc, char **argv) &read_line_ev, read_line_cb, NULL, NULL, NULL }; (void) my_eventloop_schedule( &my_loop.base, fileno(fp), -1, &read_line_ev); - if ((r = getdns_context_set_eventloop(context, &my_loop.base))) - goto done_destroy_context; if (!query_file) { printf("> "); @@ -1360,6 +1644,8 @@ main(int argc, char **argv) } my_eventloop_run(&my_loop.base); } + else if (listen_count) + my_eventloop_run(&my_loop.base); else r = do_the_call(); From e6b5a291962d3bffbc6c5a335875a78e126c3ccf Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 4 May 2016 11:11:30 +0200 Subject: [PATCH 05/41] jsmn submodule via https --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 0d2dfd4d..06b16b93 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "src/test/jsmn"] path = src/test/jsmn - url = github.com:getdnsapi/jsmn.git + url = https://github.com/getdnsapi/jsmn.git branch = getdns From 78a6a47b058f1c9f28e18e641c7a71db9179c5e5 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 4 May 2016 15:25:18 +0200 Subject: [PATCH 06/41] Anticipate new pretty print format in tpkg tests --- .../260-conversion-functions.good | 294 +++++++++--------- .../270-header-extension.dsc | 2 +- .../270-header-extension.good | 4 +- 3 files changed, 150 insertions(+), 150 deletions(-) diff --git a/src/test/tpkg/260-conversion-functions.tpkg/260-conversion-functions.good b/src/test/tpkg/260-conversion-functions.tpkg/260-conversion-functions.good index f6c4f2a7..47278b10 100644 --- a/src/test/tpkg/260-conversion-functions.tpkg/260-conversion-functions.good +++ b/src/test/tpkg/260-conversion-functions.tpkg/260-conversion-functions.good @@ -1,6 +1,6 @@ { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -39,7 +39,7 @@ www.getdnsapi.net. 0 IN A 185.49.141.37 { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "hit": , @@ -47,8 +47,8 @@ www.getdnsapi.net. 0 IN A 185.49.141.37 "public_key": , "rendezvous_servers": [ - , - + , + ] }, "ttl": 3600, @@ -59,7 +59,7 @@ hip0.nlnetlabs.nl. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSu { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "apitems": @@ -103,16 +103,16 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. [ { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "expire": 345600, "minimum": 300, - "mname": , + "mname": , "rdata_raw": , "refresh": 450, "retry": 600, - "rname": , + "rname": , "serial": 2015081800 }, "ttl": 30, @@ -120,51 +120,51 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { - "nsdname": , - "rdata_raw": + "nsdname": , + "rdata_raw": }, "ttl": 30, "type": GETDNS_RRTYPE_NS }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { - "nsdname": , - "rdata_raw": + "nsdname": , + "rdata_raw": }, "ttl": 30, "type": GETDNS_RRTYPE_NS }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { - "nsdname": , - "rdata_raw": + "nsdname": , + "rdata_raw": }, "ttl": 30, "type": GETDNS_RRTYPE_NS }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { - "nsdname": , - "rdata_raw": + "nsdname": , + "rdata_raw": }, "ttl": 30, "type": GETDNS_RRTYPE_NS }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "ipv4_address": , @@ -175,7 +175,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "ipv6_address": , @@ -186,10 +186,10 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { - "exchange": , + "exchange": , "preference": 10, "rdata_raw": }, @@ -198,10 +198,10 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { - "exchange": , + "exchange": , "preference": 20, "rdata_raw": }, @@ -210,7 +210,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -224,7 +224,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "certificate_association_data": , @@ -238,7 +238,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "certificate_association_data": , @@ -252,7 +252,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -267,7 +267,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "ipv4_address": , @@ -278,7 +278,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "ipv4_address": , @@ -289,7 +289,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -303,7 +303,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -317,7 +317,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -331,7 +331,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -345,7 +345,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -359,7 +359,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -373,7 +373,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -387,7 +387,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -401,7 +401,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -415,7 +415,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -429,7 +429,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -443,7 +443,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -457,7 +457,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -471,7 +471,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -485,7 +485,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -499,7 +499,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -513,7 +513,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -527,7 +527,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -541,7 +541,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -555,7 +555,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -569,7 +569,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -583,7 +583,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -597,7 +597,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -611,7 +611,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -625,7 +625,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -639,7 +639,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -653,7 +653,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -667,7 +667,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -681,7 +681,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -695,7 +695,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -709,7 +709,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -723,7 +723,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -737,7 +737,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -751,7 +751,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -765,7 +765,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -779,7 +779,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -793,7 +793,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -807,7 +807,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -821,7 +821,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -835,7 +835,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -849,7 +849,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -863,7 +863,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -877,7 +877,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -891,7 +891,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -905,7 +905,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -919,7 +919,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -933,7 +933,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -947,7 +947,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -961,7 +961,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -975,7 +975,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -989,7 +989,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1003,7 +1003,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1017,7 +1017,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1031,7 +1031,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1045,7 +1045,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1059,7 +1059,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1073,7 +1073,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1087,7 +1087,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1101,7 +1101,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1115,7 +1115,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1129,7 +1129,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1143,7 +1143,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1157,7 +1157,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "ipv4_address": , @@ -1168,7 +1168,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "ipv4_address": , @@ -1179,21 +1179,21 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { - "cname": , - "rdata_raw": + "cname": , + "rdata_raw": }, "ttl": 30, "type": GETDNS_RRTYPE_CNAME }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { - "exchange": , + "exchange": , "preference": 10, "rdata_raw": }, @@ -1202,10 +1202,10 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { - "exchange": , + "exchange": , "preference": 10, "rdata_raw": }, @@ -1214,10 +1214,10 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { - "exchange": , + "exchange": , "preference": 15, "rdata_raw": }, @@ -1226,7 +1226,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1240,7 +1240,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1255,7 +1255,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1269,7 +1269,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1285,7 +1285,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1301,7 +1301,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1319,7 +1319,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "ipv4_address": , @@ -1330,7 +1330,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "ipv6_address": , @@ -1341,73 +1341,73 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { - "cname": , - "rdata_raw": + "cname": , + "rdata_raw": }, "ttl": 30, "type": GETDNS_RRTYPE_CNAME }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { - "cname": , - "rdata_raw": + "cname": , + "rdata_raw": }, "ttl": 30, "type": GETDNS_RRTYPE_CNAME }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { - "cname": , - "rdata_raw": + "cname": , + "rdata_raw": }, "ttl": 30, "type": GETDNS_RRTYPE_CNAME }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { - "cname": , - "rdata_raw": + "cname": , + "rdata_raw": }, "ttl": 30, "type": GETDNS_RRTYPE_CNAME }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { - "cname": , - "rdata_raw": + "cname": , + "rdata_raw": }, "ttl": 30, "type": GETDNS_RRTYPE_CNAME }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { - "cname": , - "rdata_raw": + "cname": , + "rdata_raw": }, "ttl": 30, "type": GETDNS_RRTYPE_CNAME }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "ipv4_address": , @@ -1418,7 +1418,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "ipv6_address": , @@ -1429,7 +1429,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "apitems": @@ -1472,7 +1472,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "algorithm": 10, @@ -1485,7 +1485,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "algorithm": 10, @@ -1500,7 +1500,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "algorithm": 10, @@ -1515,11 +1515,11 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "algorithm": 10, - "gateway": , + "gateway": , "gateway_type": 3, "precedence": 2, "public_key": , @@ -1530,7 +1530,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "algorithm": 10, @@ -1543,7 +1543,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "algorithm": 10, @@ -1558,7 +1558,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "algorithm": 10, @@ -1573,11 +1573,11 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "algorithm": 10, - "gateway": , + "gateway": , "gateway_type": 3, "precedence": 2, "public_key": , @@ -1588,7 +1588,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1602,7 +1602,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , @@ -1616,7 +1616,7 @@ apl.net-dns.org. 3600 IN APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42. }, { "class": GETDNS_RRCLASS_IN, - "name": , + "name": , "rdata": { "rdata_raw": , diff --git a/src/test/tpkg/270-header-extension.tpkg/270-header-extension.dsc b/src/test/tpkg/270-header-extension.tpkg/270-header-extension.dsc index 2ac9ae37..f083f1b2 100644 --- a/src/test/tpkg/270-header-extension.tpkg/270-header-extension.dsc +++ b/src/test/tpkg/270-header-extension.tpkg/270-header-extension.dsc @@ -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: diff --git a/src/test/tpkg/270-header-extension.tpkg/270-header-extension.good b/src/test/tpkg/270-header-extension.tpkg/270-header-extension.good index 2419d76b..0e829f2b 100644 --- a/src/test/tpkg/270-header-extension.tpkg/270-header-extension.good +++ b/src/test/tpkg/270-header-extension.tpkg/270-header-extension.good @@ -1,6 +1,6 @@ { "answer_type": GETDNS_NAMETYPE_DNS, - "canonical_name": , + "canonical_name": , "replies_tree": [ { @@ -8,7 +8,7 @@ "answer": [], "answer_type": GETDNS_NAMETYPE_DNS, "authority": [], - "canonical_name": , + "canonical_name": , "header": { "aa": 0, From 4b7e79cc35e46c66d37adf201d4910387c050a6c Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Fri, 6 May 2016 17:30:05 +0200 Subject: [PATCH 07/41] TCP server now also working --- src/test/getdns_query.c | 261 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 253 insertions(+), 8 deletions(-) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 6067cc2d..d0a6410c 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -1352,17 +1352,103 @@ typedef struct listen_data { listen_data *listening = NULL; typedef struct dns_msg { - listen_data *ld; - getdns_dict *query; + listen_data *ld; + getdns_dict *query; getdns_transaction_t transaction_id; } dns_msg; typedef struct udp_msg { - dns_msg super; + dns_msg super; struct sockaddr_storage remote_in; - socklen_t addrlen; + socklen_t addrlen; } udp_msg; +typedef struct tcp_to_write tcp_to_write; +struct tcp_to_write { + size_t write_buf_len; + size_t written; + tcp_to_write *next; + uint8_t write_buf[]; +}; + +#define DOWNSTREAM_IDLE_TIMEOUT 5000 +typedef struct downstream { + listen_data *ld; + struct sockaddr_storage remote_in; + socklen_t addrlen; + int fd; + getdns_eventloop_event event; + + uint8_t *read_buf; + size_t read_buf_len; + uint8_t *read_pos; + size_t to_read; + + tcp_to_write *to_write; + size_t to_answer; +} downstream; + +typedef struct tcp_msg { + dns_msg super; + downstream *conn; +} tcp_msg; + +void downstream_destroy(downstream *conn) +{ + tcp_to_write *cur, *next; + + if (conn->event.read_cb||conn->event.write_cb||conn->event.timeout_cb) + my_eventloop_clear(&my_loop.base, &conn->event); + if (conn->fd >= 0) { + if (close(conn->fd) == -1) + perror("close"); + } + free(conn->read_buf); + for (cur = conn->to_write; cur; cur = next) { + next = cur->next; + free(cur); + } + free(conn); +} + +void tcp_write_cb(void *userarg) +{ + downstream *conn = (downstream *)userarg; + tcp_to_write *to_write; + ssize_t written; + + assert(userarg); + + /* Reset downstream idle timeout */ + my_eventloop_clear(&my_loop.base, &conn->event); + + if (!conn->to_write) { + conn->event.write_cb = NULL; + (void) my_eventloop_schedule(&my_loop.base, conn->fd, + DOWNSTREAM_IDLE_TIMEOUT, &conn->event); + return; + } + to_write = conn->to_write; + if ((written = write(conn->fd, &to_write->write_buf[to_write->written], + to_write->write_buf_len - to_write->written)) == -1) { + + perror("write"); + conn->event.read_cb = conn->event.write_cb = + conn->event.timeout_cb = NULL; + downstream_destroy(conn); + return; + } + to_write->written += written; + if (to_write->written == to_write->write_buf_len) { + conn->to_write = to_write->next; + free(to_write); + } + if (!conn->to_write) + conn->event.write_cb = NULL; + (void) my_eventloop_schedule(&my_loop.base, conn->fd, + DOWNSTREAM_IDLE_TIMEOUT, &conn->event); +} + void request_cb(getdns_context *context, getdns_callback_type_t callback_type, getdns_dict *response, void *userarg, getdns_transaction_t transaction_id) { @@ -1396,12 +1482,39 @@ void request_cb(getdns_context *context, getdns_callback_type_t callback_type, else if (msg->ld->transport == GETDNS_TRANSPORT_UDP) { udp_msg *msg = (udp_msg *)userarg; - fprintf(stderr, "fd: %d, len: %d, reply: %s\n", msg->super.ld->fd, (int)len, - getdns_pretty_print_dict(response)); - if (sendto(msg->super.ld->fd, buf, len, 0, (struct sockaddr *)&msg->remote_in, msg->addrlen) == -1) perror("sendto"); + + } else if (msg->ld->transport == GETDNS_TRANSPORT_TCP) { + tcp_msg *msg = (tcp_msg *)userarg; + tcp_to_write **to_write_p; + tcp_to_write *to_write = malloc(sizeof(tcp_to_write) + len + 2); + + if (!to_write) + fprintf(stderr, "Could not allocate memory for" + "message to write on tcp stream\n"); + else { + to_write->write_buf_len = len + 2; + to_write->write_buf[0] = (len >> 8) & 0xFF; + to_write->write_buf[1] = len & 0xFF; + to_write->written = 0; + to_write->next = NULL; + (void) memcpy(to_write->write_buf + 2, buf, len); + + /* Appen to_write to conn->to_write list */ + for ( to_write_p = &msg->conn->to_write + ; *to_write_p + ; to_write_p = &(*to_write_p)->next) + ; /* pass */ + *to_write_p = to_write; + + my_eventloop_clear(&my_loop.base, &msg->conn->event); + msg->conn->event.write_cb = tcp_write_cb; + (void) my_eventloop_schedule(&my_loop.base, + msg->conn->fd, DOWNSTREAM_IDLE_TIMEOUT, + &msg->conn->event); + } } if (msg) { getdns_dict_destroy(msg->query); @@ -1409,7 +1522,6 @@ void request_cb(getdns_context *context, getdns_callback_type_t callback_type, } if (response) getdns_dict_destroy(response); - } getdns_return_t schedule_request(dns_msg *msg) @@ -1439,6 +1551,132 @@ getdns_return_t schedule_request(dns_msg *msg) return r; } +void tcp_read_cb(void *userarg) +{ + downstream *conn = (downstream *)userarg; + ssize_t bytes_read; + tcp_msg *msg; + getdns_return_t r; + + assert(userarg); + + /* Reset downstream idle timeout */ + my_eventloop_clear(&my_loop.base, &conn->event); + (void) my_eventloop_schedule(&my_loop.base, conn->fd, + DOWNSTREAM_IDLE_TIMEOUT, &conn->event); + + if ((bytes_read = read(conn->fd, conn->read_pos, conn->to_read)) == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) + return; + perror("read"); + downstream_destroy(conn); + return; + } + if (bytes_read == 0) { + /* fprintf(stderr, "Remote end closed connection\n"); */ + downstream_destroy(conn); + return; + } + assert(bytes_read <= conn->to_read); + + conn->to_read -= bytes_read; + conn->read_pos += bytes_read; + if (conn->to_read) + return; /* More to read */ + + if (conn->read_pos - conn->read_buf == 2) { + /* read length of dns msg to read */ + conn->to_read = (conn->read_buf[0] << 8) | conn->read_buf[1]; + if (conn->to_read > conn->read_buf_len) { + free(conn->read_buf); + while (conn->to_read > conn->read_buf_len) + conn->read_buf_len *= 2; + if (!(conn->read_buf = malloc(conn->read_buf_len))) { + fprintf(stderr, "Could not enlarge " + "downstream read buffer\n"); + downstream_destroy(conn); + return; + } + } + if (conn->to_read < 12) { + fprintf(stderr, "Request smaller than DNS header\n"); + downstream_destroy(conn); + return; + } + conn->read_pos = conn->read_buf; + return; /* Read DNS message */ + } + if (!(msg = malloc(sizeof(tcp_msg)))) { + fprintf(stderr, "Could not allocate tcp_msg\n"); + downstream_destroy(conn); + return; + } + msg->super.ld = conn->ld; + msg->conn = conn; + if ((r = getdns_wire2msg_dict(conn->read_buf, + (conn->read_pos - conn->read_buf), &msg->super.query))) + fprintf(stderr, "Error converting query dns msg: %s\n", + getdns_get_errorstr_by_id(r)); + + else if ((r = schedule_request(&msg->super))) { + fprintf(stderr, "Error scheduling query: %s\n", + getdns_get_errorstr_by_id(r)); + + getdns_dict_destroy(msg->super.query); + } else { + conn->to_answer += 1; + conn->read_pos = conn->read_buf; + conn->to_read = 2; + return; /* Read more requests */ + } + free(msg); + conn->read_pos = conn->read_buf; + conn->to_read = 2; + /* Read more requests */ +} + +void tcp_timeout_cb(void *userarg) +{ + downstream *conn = (downstream *)userarg; + + assert(userarg); + + downstream_destroy(conn); +} + +void tcp_accept_cb(void *userarg) +{ + listen_data *ld = (listen_data *)userarg; + downstream *conn; + + assert(userarg); + + if (!(conn = malloc(sizeof(downstream)))) + return; + + (void) memset(conn, 0, sizeof(downstream)); + + conn->ld = ld; + conn->addrlen = sizeof(conn->remote_in); + if ((conn->fd = accept(ld->fd, + (struct sockaddr *)&conn->remote_in, &conn->addrlen)) == -1) { + perror("accept"); + free(conn); + } + if (!(conn->read_buf = malloc(4096))) { + fprintf(stderr, "Could not allocate downstream read buffer.\n"); + free(conn); + } + conn->read_buf_len = 4096; + conn->read_pos = conn->read_buf; + conn->to_read = 2; + conn->event.userarg = conn; + conn->event.read_cb = tcp_read_cb; + conn->event.timeout_cb = tcp_timeout_cb; + (void) my_eventloop_schedule(&my_loop.base, conn->fd, + DOWNSTREAM_IDLE_TIMEOUT, &conn->event); +} + void udp_read_cb(void *userarg) { listen_data *ld = (listen_data *)userarg; @@ -1590,6 +1828,13 @@ getdns_return_t start_daemon() } else if (listen(ld->fd, 16) == -1) perror("listen"); + + else { + ld->event.userarg = ld; + ld->event.read_cb = tcp_accept_cb; + (void) my_eventloop_schedule( + &my_loop.base, ld->fd, -1, &ld->event); + } } return r; } From 22328703cc6a6807930a1e6a3f493afc5aa47736 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 9 May 2016 15:17:26 +0200 Subject: [PATCH 08/41] Convert constant name to value --- src/const-info.c | 210 +++++++++++++++++++++++++++++++++++++++++ src/const-info.h | 1 + src/mk-const-info.c.sh | 27 ++++++ 3 files changed, 238 insertions(+) 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/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) { From 1d5446f1171d095e08538d75ce03b59a6db20dcd Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 11 May 2016 12:07:27 +0200 Subject: [PATCH 09/41] First pass at parsing getdns dicts in text format --- src/libgetdns.symbols | 1 + src/mk-symfiles.sh | 1 + src/test/Makefile.in | 7 +- src/test/getdns_query.c | 293 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 300 insertions(+), 2 deletions(-) diff --git a/src/libgetdns.symbols b/src/libgetdns.symbols index 7fde49c7..8e3f038b 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/mk-symfiles.sh b/src/mk-symfiles.sh index 590a6c18..2ddcdcf6 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/test/Makefile.in b/src/test/Makefile.in index fbc72f8d..262cafb1 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) -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) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index d0a6410c..c84c6b98 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -27,6 +27,8 @@ #include "config.h" #include "debug.h" +#include "const-info.h" +#include "jsmn/jsmn.h" #include #include #include @@ -729,6 +731,252 @@ done: return r; } +static int _jsmn_get_integer(char *js, jsmntok_t *t, uint32_t *num) +{ + char c = js[t->end]; + ;unsigned long int value; + char *endptr; + + js[t->end] = '\0'; + value = strtoul(js + t->start, &endptr, 10); + if (js[t->start] != '\0' && *endptr == '\0') { + js[t->end] = c; + *num = value; + return 1; + } + js[t->end] = c; + return 0; +} + +static int _jsmn_get_constant(char *js, jsmntok_t *t, uint32_t *num) +{ + char c = js[t->end]; + int code; + + js[t->end] = '\0'; + if (_getdns_get_const_name_info(js + t->start, &code)) { + js[t->end] = c; + *num = code; + return 1; + } + js[t->end] = c; + return 0; +} + +static int _jsmn_get_dict(char *js, jsmntok_t *t, size_t count, + getdns_dict **dict, getdns_return_t *r); + +static int _jsmn_get_list(char *js, jsmntok_t *t, size_t count, + getdns_list **list, getdns_return_t *r) +{ + getdns_list *new_list, *child_list; + getdns_dict *child_dict; + size_t i, j; + getdns_bindata bindata; + size_t index = 0; + uint32_t num; + + if (t->type != JSMN_ARRAY) { + *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; + return 0; + } + new_list = getdns_list_create(); + j = 1; + for (i = 0; i < t->size; i++) { + switch (t[j].type) { + case JSMN_OBJECT: + j += _jsmn_get_dict(js, t+j, count-j, &child_dict, r); + if (*r) { + getdns_list_destroy(new_list); + return 0; + } + *r = getdns_list_set_dict(new_list, index++, child_dict); + getdns_dict_destroy(child_dict); + if (*r) { + getdns_list_destroy(new_list); + return 0; + } + break; + case JSMN_ARRAY: + j += _jsmn_get_list(js, t+j, count-j, &child_list, r); + if (*r) { + getdns_list_destroy(new_list); + return 0; + } + *r = getdns_list_set_list(new_list, index++, child_list); + getdns_list_destroy(child_list); + if (*r) { + getdns_list_destroy(new_list); + return 0; + } + break; + case JSMN_STRING: + bindata.size = t[j].end - t[j].start; + bindata.data = (uint8_t *)js + t[j].start; + *r = getdns_list_set_bindata( + new_list, index++, &bindata); + if (*r) { + getdns_list_destroy(new_list); + return 0; + } + j += 1; + break; + case JSMN_PRIMITIVE: + if (_jsmn_get_integer(js, t+j, &num) || + _jsmn_get_constant(js, t+j, &num)) { + *r = getdns_list_set_int( + new_list, index++, num); + } else { + *r = getdns_list_set_int( + new_list, index++, 123456789); + } + if (*r) { + getdns_list_destroy(new_list); + return 0; + } + j += 1; + break; + + default: + *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; + getdns_list_destroy(new_list); + return 0; + } + } + *list = new_list; + *r = GETDNS_RETURN_GOOD; + return j; +} + +static int _jsmn_get_dict(char *js, jsmntok_t *t, size_t count, + getdns_dict **dict, getdns_return_t *r) +{ + getdns_dict *new_dict, *child_dict; + getdns_list *child_list; + size_t i, j; + getdns_bindata bindata; + char *key; + uint32_t num; + + if (t->type != JSMN_OBJECT) { + *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; + return 0; + } + new_dict = getdns_dict_create(); + j = 1; + for (i = 0; i < t->size; i++) { + if (t[j].type != JSMN_STRING) { + *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; + getdns_dict_destroy(new_dict); + return 0; + } + key = js + t[j].start; + js[t[j].end] = '\0'; + j += 1; + switch (t[j].type) { + case JSMN_OBJECT: + j += _jsmn_get_dict(js, t+j, count-j, &child_dict, r); + if (*r) { + getdns_dict_destroy(new_dict); + return 0; + } + *r = getdns_dict_set_dict(new_dict, key, child_dict); + getdns_dict_destroy(child_dict); + if (*r) { + getdns_dict_destroy(new_dict); + return 0; + } + break; + case JSMN_ARRAY: + j += _jsmn_get_list(js, t+j, count-j, &child_list, r); + if (*r) { + getdns_dict_destroy(new_dict); + return 0; + } + *r = getdns_dict_set_list(new_dict, key, child_list); + getdns_list_destroy(child_list); + if (*r) { + getdns_dict_destroy(new_dict); + return 0; + } + break; + case JSMN_STRING: + bindata.size = t[j].end - t[j].start; + bindata.data = (uint8_t *)js + t[j].start; + *r = getdns_dict_set_bindata( + new_dict, key, &bindata); + if (*r) { + getdns_dict_destroy(new_dict); + return 0; + } + j += 1; + break; + case JSMN_PRIMITIVE: + if (_jsmn_get_integer(js, t+j, &num) || + _jsmn_get_constant(js, t+j, &num)) { + *r = getdns_dict_set_int( + new_dict, key, num); + } else { + *r = getdns_dict_set_int( + new_dict, key, 123456789); + + } + if (*r) { + getdns_dict_destroy(new_dict); + return 0; + } + j += 1; + break; + + default: + *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; + getdns_dict_destroy(new_dict); + return 0; + } + } + *dict = new_dict; + *r = GETDNS_RETURN_GOOD; + return j; +} + +void parse_config(char *config) +{ + jsmn_parser p; + jsmntok_t *tok = NULL, *new_tok; + size_t tokcount = 100; + int r; + getdns_return_t gr; + getdns_dict *d; + + jsmn_init(&p); + tok = malloc(sizeof(*tok) * tokcount); + do { + r = jsmn_parse(&p, config, strlen(config), tok, tokcount); + if (r == JSMN_ERROR_NOMEM) { + fprintf(stderr, "new tokcount: %d\n", (int)tokcount); + tokcount *= 2; + if (!(new_tok = realloc(tok, sizeof(*tok)*tokcount))){ + free(tok); + fprintf(stderr, + "Memory error during config parsing\n"); + return; + } + tok = new_tok; + } + } while (r == JSMN_ERROR_NOMEM); + if (r < 0) + fprintf(stderr, "Config parse error: %d\n", r); + else { + (void) _jsmn_get_dict(config, tok, p.toknext, &d, &gr); + if (gr) + fprintf(stderr, "Config parse error: %d\n", (int)gr); + else + fprintf(stderr, "config dict: %s\n", + getdns_pretty_print_dict(d)); + } + free(tok); +} + getdns_return_t parse_args(int argc, char **argv) { getdns_return_t r = GETDNS_RETURN_GOOD; @@ -744,6 +992,8 @@ getdns_return_t parse_args(int argc, char **argv) size_t upstream_count = 0; FILE *fh; uint32_t klass; + char *config_file = NULL; + long config_file_sz; for (i = 1; i < argc; i++) { arg = argv[i]; @@ -859,6 +1109,49 @@ getdns_return_t parse_args(int argc, char **argv) if (getdns_context_set_edns_client_subnet_private(context, 1)) return GETDNS_RETURN_GENERIC_ERROR; break; + case 'C': + if (c[1] != 0 || ++i >= argc || !*argv[i]) { + fprintf(stderr, "file name expected " + "after -C\n"); + return GETDNS_RETURN_GENERIC_ERROR; + } + if (!(fh = fopen(argv[i], "r"))) { + fprintf(stderr, "Could not open \"%s\"" + ": %s\n",argv[i], strerror(errno)); + return GETDNS_RETURN_GENERIC_ERROR; + } + if (fseek(fh, 0,SEEK_END) == -1) { + perror("fseek"); + fclose(fh); + return GETDNS_RETURN_GENERIC_ERROR; + } + config_file_sz = ftell(fh); + if (config_file_sz <= 0) { + /* Empty config is no config */ + fclose(fh); + break; + } + if (!(config_file=malloc(config_file_sz + 1))){ + fclose(fh); + fprintf(stderr, "Could not allocate me" + "mory for \"%s\"\n", argv[i]); + return GETDNS_RETURN_MEMORY_ERROR; + } + rewind(fh); + if (fread(config_file, 1, config_file_sz, fh) + != config_file_sz) { + fprintf(stderr, "An error occurred whil" + "e reading \"%s\": %s\n",argv[i], + strerror(errno)); + fclose(fh); + return GETDNS_RETURN_MEMORY_ERROR; + } + config_file[config_file_sz] = 0; + fclose(fh); + parse_config(config_file); + free(config_file); + config_file = NULL; + break; case 'D': (void) getdns_context_set_edns_do_bit(context, 1); break; From 11a063bad078be89083a4e5a954b3bba3e0793cd Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 18 May 2016 15:21:24 +0200 Subject: [PATCH 10/41] Parse IPv4, IPv6 and dnames as primitives --- src/test/Makefile.in | 4 +- src/test/getdns_query.c | 96 ++++++++++++++++++++++++++++++++++++++--- src/test/jsmn | 2 +- 3 files changed, 94 insertions(+), 8 deletions(-) diff --git a/src/test/Makefile.in b/src/test/Makefile.in index 262cafb1..ed79ad0c 100644 --- a/src/test/Makefile.in +++ b/src/test/Makefile.in @@ -95,7 +95,7 @@ $(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) -c $(srcdir)/jsmn/jsmn.c -o $@ + $(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 @@ -268,7 +268,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 + ../const-info.h 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 c84c6b98..0cfd1b32 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -731,6 +731,71 @@ done: return r; } +static int _jsmn_get_dname(char *js, jsmntok_t *t, getdns_bindata **value) +{ + char c = js[t->end]; + getdns_return_t r; + + if (t->end <= t->start || js[t->end - 1] != '.') + return 0; + + js[t->end] = '\0'; + r = getdns_convert_fqdn_to_dns_name(js + t->start, value); + js[t->end] = c; + + return r == GETDNS_RETURN_GOOD; +} + +static int _jsmn_get_ipv4(char *js, jsmntok_t *t, getdns_bindata **value) +{ + char c = js[t->end]; + uint8_t buf[4]; + + js[t->end] = '\0'; + if (inet_pton(AF_INET, js + t->start, buf) <= 0) + ; /* pass */ + + else if (!(*value = malloc(sizeof(getdns_bindata)))) + ; /* pass */ + + else if (!((*value)->data = malloc(4))) + free(*value); + + else { + js[t->end] = c; + (*value)->size = 4; + (void) memcpy((*value)->data, buf, 4); + return 1; + } + js[t->end] = c; + return 0; +} + +static int _jsmn_get_ipv6(char *js, jsmntok_t *t, getdns_bindata **value) +{ + char c = js[t->end]; + uint8_t buf[16]; + + js[t->end] = '\0'; + if (inet_pton(AF_INET6, js + t->start, buf) <= 0) + ; /* pass */ + + else if (!(*value = malloc(sizeof(getdns_bindata)))) + ; /* pass */ + + else if (!((*value)->data = malloc(16))) + free(*value); + + else { + js[t->end] = c; + (*value)->size = 16; + (void) memcpy((*value)->data, buf, 16); + return 1; + } + js[t->end] = c; + return 0; +} + static int _jsmn_get_integer(char *js, jsmntok_t *t, uint32_t *num) { char c = js[t->end]; @@ -775,6 +840,7 @@ static int _jsmn_get_list(char *js, jsmntok_t *t, size_t count, getdns_bindata bindata; size_t index = 0; uint32_t num; + getdns_bindata *value; if (t->type != JSMN_ARRAY) { *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; @@ -826,9 +892,19 @@ static int _jsmn_get_list(char *js, jsmntok_t *t, size_t count, _jsmn_get_constant(js, t+j, &num)) { *r = getdns_list_set_int( new_list, index++, num); + } else if (_jsmn_get_dname(js, t+j, &value) || + _jsmn_get_ipv4(js, t+j, &value) || + _jsmn_get_ipv6(js, t+j, &value)) { + + *r = getdns_list_set_bindata( + new_list, index++, value); + + free(value->data); + free(value); } else { - *r = getdns_list_set_int( - new_list, index++, 123456789); + fprintf(stderr, "Could not convert primitive %.*s\n", + t[j].end - t[j].start, js+t[j].start); + *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; } if (*r) { getdns_list_destroy(new_list); @@ -857,6 +933,7 @@ static int _jsmn_get_dict(char *js, jsmntok_t *t, size_t count, getdns_bindata bindata; char *key; uint32_t num; + getdns_bindata *value; if (t->type != JSMN_OBJECT) { *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; @@ -916,10 +993,19 @@ static int _jsmn_get_dict(char *js, jsmntok_t *t, size_t count, _jsmn_get_constant(js, t+j, &num)) { *r = getdns_dict_set_int( new_dict, key, num); - } else { - *r = getdns_dict_set_int( - new_dict, key, 123456789); + } else if (_jsmn_get_dname(js, t+j, &value) || + _jsmn_get_ipv4(js, t+j, &value) || + _jsmn_get_ipv6(js, t+j, &value)) { + *r = getdns_dict_set_bindata( + new_dict, key, value); + + free(value->data); + free(value); + } else { + *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; + fprintf(stderr, "Could not convert primitive %.*s\n", + t[j].end - t[j].start, js+t[j].start); } if (*r) { getdns_dict_destroy(new_dict); diff --git a/src/test/jsmn b/src/test/jsmn index 73132efb..7f9f06a8 160000 --- a/src/test/jsmn +++ b/src/test/jsmn @@ -1 +1 @@ -Subproject commit 73132efb1e2156b7755514cd94cf7e826961665f +Subproject commit 7f9f06a8b23d22723c03a85465b15059ff4bd626 From 7fd9d1e342d9d9c750969d86e38517c50822d3d0 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 18 May 2016 15:47:57 +0200 Subject: [PATCH 11/41] const-info.h is relative to $(srcdir) --- src/test/Makefile.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/Makefile.in b/src/test/Makefile.in index ed79ad0c..f61cda76 100644 --- a/src/test/Makefile.in +++ b/src/test/Makefile.in @@ -215,6 +215,7 @@ 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!\(.*\)\.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 ) @@ -268,7 +269,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 \ - ../const-info.h jsmn/jsmn.h ../getdns/getdns.h ../getdns/getdns_extra.h + $(srcdir)/../const-info.h 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 From 4c3888b18ecebd588077679fed76330c65cffcb7 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 18 May 2016 15:56:54 +0200 Subject: [PATCH 12/41] jsmn.h is relative to $(srcdir) too --- src/test/Makefile.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/Makefile.in b/src/test/Makefile.in index f61cda76..76dfc173 100644 --- a/src/test/Makefile.in +++ b/src/test/Makefile.in @@ -216,6 +216,7 @@ depend: -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 ) @@ -269,7 +270,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 \ - $(srcdir)/../const-info.h jsmn/jsmn.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 From 14a950bc295c031e6133b397222beaef128ff7b2 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Sun, 22 May 2016 15:35:32 +0200 Subject: [PATCH 13/41] getdns_query -C for settings via config file --- src/context.c | 36 +++--- src/dict.c | 2 +- src/test/getdns_query.c | 279 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 297 insertions(+), 20 deletions(-) diff --git a/src/context.c b/src/context.c index cc5ef264..7531fe44 100644 --- a/src/context.c +++ b/src/context.c @@ -1948,7 +1948,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 */ /* @@ -2093,22 +2093,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 */ /* @@ -2369,7 +2370,10 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context, else tsig_alg = GETDNS_HMAC_MD5; - if (dict && getdns_dict_get_bindata( + 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 */ diff --git a/src/dict.c b/src/dict.c index cbaacec3..e8b04ae8 100644 --- a/src/dict.c +++ b/src/dict.c @@ -281,7 +281,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); + strlen(item->node.key), item->node.key); } return GETDNS_RETURN_GOOD; } /* getdns_dict_get_names */ diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 7af080e4..eca363f7 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -1025,7 +1025,281 @@ static int _jsmn_get_dict(char *js, jsmntok_t *t, size_t count, return j; } -void parse_config(char *config) +static int _streq(const getdns_bindata *name, const char *str) +{ + if (strlen(str) != name->size) + return 0; + else return strncmp((const char *)name->data, str, name->size) == 0; +} + +static getdns_return_t configure_with_config_dict(const getdns_dict *config); +static getdns_return_t configure_setting_with_config_dict( + const getdns_dict *config, const getdns_bindata *setting) +{ + getdns_return_t r = GETDNS_RETURN_GOOD; + getdns_dict *dict; + getdns_list *list; + getdns_namespace_t namespaces[100]; + getdns_transport_list_t transports[100]; + size_t count, i; + uint32_t n; + + if (_streq(setting, "all_context")) { + if ((r = getdns_dict_get_dict(config, "all_context", &dict))) + fprintf(stderr, "Could not get \"all_context\""); + + else if ((r = configure_with_config_dict(dict))) + fprintf( stderr + ,"Error configuring with \"all_context\""); + + } else if (_streq(setting, "resolution_type")) { + if ((r = getdns_dict_get_int(config, "resolution_type", &n))) + fprintf(stderr, "Could not get \"resolution_type\""); + + else if ((r = getdns_context_set_resolution_type(context, n))) + fprintf( stderr + ,"Error configuring \"resolution_type\""); + + } else if (_streq(setting, "namespaces")) { + if ((r = getdns_dict_get_list(config, "namespaces", &list))) + fprintf(stderr, "Could not get \"namespaces\""); + + else if ((r = getdns_list_get_length(list, &count))) + fprintf(stderr, "Could not length of \"namespaces\""); + + else for ( i = 0 + ; i < count && + i < sizeof(namespaces) / sizeof(*namespaces); i++) { + + if ((r = getdns_list_get_int(list, i, &n))) { + fprintf( stderr + , "Could not get namespaces[%zu]", i); + break; + } + namespaces[i] = (getdns_namespace_t)n; + } + if (!r && (r = getdns_context_set_namespaces( + context, count, namespaces))) + fprintf(stderr,"Error configuring \"namespaces\""); + + } else if (_streq(setting, "dns_transport")) { + if ((r = getdns_dict_get_int(config, "dns_transport", &n))) + fprintf(stderr, "Could not get \"dns_transport\""); + + else if ((r = getdns_context_set_dns_transport(context, n))) + fprintf( stderr + ,"Error configuring \"dns_transport\""); + + } else if (_streq(setting, "dns_transport_list")) { + if ((r = getdns_dict_get_list( + config, "dns_transport_list", &list))) + fprintf( stderr + ,"Could not get \"dns_transport_list\""); + + else if ((r = getdns_list_get_length(list, &count))) + fprintf( stderr + ,"Could not length of \"dns_transport_list\""); + + else for ( i = 0 + ; i < count && + i < sizeof(transports) / sizeof(*transports); i++) { + + if ((r = getdns_list_get_int(list, i, &n))) { + fprintf(stderr, "Could not get " + "dns_transport_list[%zu]", i); + break; + } + transports[i] = (getdns_transport_list_t)n; + } + if (!r && (r = getdns_context_set_dns_transport_list( + context, count, transports))) + fprintf( stderr + ,"Error configuring \"dns_transport_list\""); + + } else if (_streq(setting, "idle_timeout")) { + if ((r = getdns_dict_get_int(config, "idle_timeout", &n))) + fprintf(stderr, "Could not get \"idle_timeout\""); + + else if ((r = getdns_context_set_idle_timeout(context, n))) + fprintf( stderr + ,"Error configuring \"idle_timeout\""); + + } else if (_streq(setting, "limit_outstanding_queries")) { + if ((r = getdns_dict_get_int( + config, "limit_outstanding_queries", &n))) + fprintf( stderr + ,"Could not get \"limit_outstanding_queries\""); + + else if ((r = getdns_context_set_limit_outstanding_queries( + context, n))) + fprintf(stderr, "Error configuring " + "\"limit_outstanding_queries\""); + + } else if (_streq(setting, "timeout")) { + if ((r = getdns_dict_get_int(config, "timeout", &n))) + fprintf(stderr, "Could not get \"timeout\""); + + else if ((r = getdns_context_set_timeout(context, n))) + fprintf( stderr + ,"Error configuring \"timeout\""); + + } else if (_streq(setting, "follow_redirects")) { + if ((r = getdns_dict_get_int(config, "follow_redirects", &n))) + fprintf(stderr, "Could not get \"follow_redirects\""); + + else if ((r = getdns_context_set_follow_redirects(context, n))) + fprintf( stderr + ,"Error configuring \"follow_redirects\""); + + } else if (_streq(setting, "dns_root_servers")) { + if ((r = getdns_dict_get_list( + config, "dns_root_servers", &list))) + fprintf(stderr, "Could not get \"dns_root_servers\""); + + else if ((r = getdns_context_set_dns_root_servers( + context, list))) + fprintf( stderr + ,"Error configuring \"dns_root_servers\""); + + } else if (_streq(setting, "append_name")) { + if ((r = getdns_dict_get_int(config, "append_name", &n))) + fprintf(stderr, "Could not get \"append_name\""); + + else if ((r = getdns_context_set_append_name(context, n))) + fprintf( stderr + ,"Error configuring \"append_name\""); + + } else if (_streq(setting, "suffix")) { + if ((r = getdns_dict_get_list( + config, "suffix", &list))) + fprintf(stderr, "Could not get \"suffix\""); + + else if ((r = getdns_context_set_suffix( + context, list))) + fprintf( stderr + ,"Error configuring \"suffix\""); + + } else if (_streq(setting, "dnssec_trust_anchors")) { + if ((r = getdns_dict_get_list( + config, "dnssec_trust_anchors", &list))) + fprintf( stderr + ,"Could not get \"dnssec_trust_anchors\""); + + else if ((r = getdns_context_set_dnssec_trust_anchors( + context, list))) + fprintf( stderr + ,"Error configuring \"dnssec_trust_anchors\""); + + } else if (_streq(setting, "dnssec_allowed_skew")) { + if ((r = getdns_dict_get_int(config,"dnssec_allowed_skew",&n))) + fprintf( stderr + ,"Could not get \"dnssec_allowed_skew\""); + + else if ((r=getdns_context_set_dnssec_allowed_skew(context,n))) + fprintf( stderr + ,"Error configuring \"dnssec_allowed_skew\""); + + } else if (_streq(setting, "upstream_recursive_servers")) { + if ((r = getdns_dict_get_list( + config, "upstream_recursive_servers", &list))) + fprintf(stderr , "Could not get " + "\"upstream_recursive_servers\""); + + else if ((r = getdns_context_set_upstream_recursive_servers( + context, list))) + fprintf(stderr, "Error configuring " + "\"upstream_recursive_servers\""); + + } else if (_streq(setting, "edns_maximum_udp_payload_size")) { + if ((r = getdns_dict_get_int( + config, "edns_maximum_udp_payload_size", &n))) + fprintf(stderr, "Could not get " + "\"edns_maximum_udp_payload_size\""); + + else if ((r = getdns_context_set_edns_maximum_udp_payload_size( + context, n))) + fprintf(stderr, "Error configuring " + "\"edns_maximum_udp_payload_size\""); + + } else if (_streq(setting, "edns_extended_rcode")) { + if ((r = getdns_dict_get_int(config,"edns_extended_rcode",&n))) + fprintf( stderr + ,"Could not get \"edns_extended_rcode\""); + + else if ((r = getdns_context_set_edns_extended_rcode( + context, n))) + fprintf( stderr + ,"Error configuring \"edns_extended_rcode\""); + + } else if (_streq(setting, "edns_version")) { + if ((r = getdns_dict_get_int(config, "edns_version", &n))) + fprintf(stderr, "Could not get \"edns_version\""); + + else if ((r = getdns_context_set_edns_version(context, n))) + fprintf( stderr + ,"Error configuring \"edns_version\""); + + } else if (_streq(setting, "edns_do_bit")) { + if ((r = getdns_dict_get_int(config, "edns_do_bit", &n))) + fprintf(stderr, "Could not get \"edns_do_bit\""); + + else if ((r = getdns_context_set_edns_do_bit(context, n))) + fprintf( stderr + ,"Error configuring \"edns_do_bit\""); + + + /***************************************/ + /**** ****/ + /**** Unofficial context settings ****/ + /**** ****/ + /***************************************/ + } else if (_streq(setting, "tls_authentication")) { + if ((r = getdns_dict_get_int(config,"tls_authentication", &n))) + fprintf(stderr,"Could not get \"tls_authentication\""); + + else if ((r=getdns_context_set_tls_authentication(context, n))) + fprintf( stderr + ,"Error configuring \"tls_authentication\""); + + + /************************************/ + /**** ****/ + /**** Ignored context settings ****/ + /**** ****/ + /************************************/ + } else if (!_streq(setting, "implementation_string") && + !_streq(setting, "version_string")) { + fprintf( stderr, "Unknown configuration key \"%.*s\"" + , (int)setting->size, (const char *)setting->data); + r = GETDNS_RETURN_NOT_IMPLEMENTED; + } + if (r) + fprintf(stderr, ": %s\n", getdns_get_errorstr_by_id(r)); + return r; +} + +static getdns_return_t configure_with_config_dict(const getdns_dict *config) +{ + getdns_list *names; + getdns_return_t r; + getdns_bindata *name; + size_t i; + + if ((r = getdns_dict_get_names(config, &names))) + return r; + + for (i = 0; !(r = getdns_list_get_bindata(names, i, &name)); i++) { + if ((r = configure_setting_with_config_dict(config, name))) + break; + } + if (r == GETDNS_RETURN_NO_SUCH_LIST_ITEM) + r = GETDNS_RETURN_GOOD; + + getdns_list_destroy(names); + return r; +} + +static void parse_config(char *config) { jsmn_parser p; jsmntok_t *tok = NULL, *new_tok; @@ -1057,8 +1331,7 @@ void parse_config(char *config) if (gr) fprintf(stderr, "Config parse error: %d\n", (int)gr); else - fprintf(stderr, "config dict: %s\n", - getdns_pretty_print_dict(d)); + configure_with_config_dict(d); } free(tok); } From 959f1e54960b35d666139839b315d92d71cecb09 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Sun, 22 May 2016 17:35:14 +0200 Subject: [PATCH 14/41] listen_addresses setting in config file --- src/test/getdns_query.c | 200 ++++++++++++++++++++++++++++++++++------ 1 file changed, 170 insertions(+), 30 deletions(-) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index eca363f7..634317ac 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -279,6 +279,7 @@ static getdns_context *context; static getdns_dict *extensions; 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; @@ -360,6 +361,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; @@ -369,6 +371,22 @@ 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, ':')))) + p = c; + + else if ((*ipstr == '*') && (c = strchr(ipstr+1, ':'))) + p = c; + if (s) { *s = 0; scope_id_str = s + 1; @@ -401,7 +419,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) { @@ -482,7 +504,9 @@ print_usage(FILE *out, const char *progname) "stub" #endif ", synchronous resolution of NS record using UDP with TCP fallback\n"); - fprintf(out, "\nupstreams: @[%%][@][#][~][^]\n"); + fprintf(out, "\nupstreams: @[%%][@][#][~][^]"); + fprintf(out, "\n @ may be given as :"); + fprintf(out, "\n or \'[\'[%%]\']\': too\n"); fprintf(out, "\ntsig spec: [:]:\n"); fprintf(out, "\nextensions:\n"); fprintf(out, "\t+add_warning_for_bad_dns\n"); @@ -552,7 +576,10 @@ print_usage(FILE *out, const char *progname) fprintf(out, "\t-U\tSet transport to UDP only\n"); fprintf(out, "\t-l \tSet transport list. List can contain 1 of each of the characters\n"); fprintf(out, "\t\t\t U T L S for UDP, TCP or TLS e.g 'UT' or 'LTU' \n"); - + fprintf(out, "\t-z \n"); + fprintf(out, "\t\tListen for DNS requests on the given IP address\n"); + fprintf(out, "\t\t is in the same format as upstreams.\n"); + fprintf(out, "\t\tThis option can be given more than once.\n"); } static getdns_return_t validate_chain(getdns_dict *response) @@ -731,6 +758,16 @@ done: return r; } +static int _jsmn_get_ipdict(char *js, jsmntok_t *t, getdns_dict **value) +{ + char c = js[t->end]; + + js[t->end] = '\0'; + *value = ipaddr_dict(context, js + t->start); + js[t->end] = c; + return *value != NULL; +} + static int _jsmn_get_dname(char *js, jsmntok_t *t, getdns_bindata **value) { char c = js[t->end]; @@ -901,6 +938,11 @@ static int _jsmn_get_list(char *js, jsmntok_t *t, size_t count, free(value->data); free(value); + + } else if (_jsmn_get_ipdict(js, t+j, &child_dict)) { + *r = getdns_list_set_dict( + new_list, index++, child_dict); + getdns_dict_destroy(child_dict); } else { fprintf(stderr, "Could not convert primitive %.*s\n", t[j].end - t[j].start, js+t[j].start); @@ -1002,6 +1044,11 @@ static int _jsmn_get_dict(char *js, jsmntok_t *t, size_t count, free(value->data); free(value); + + } else if (_jsmn_get_ipdict(js, t+j, &child_dict)) { + *r = getdns_dict_set_dict( + new_dict, key, child_dict); + getdns_dict_destroy(child_dict); } else { *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; fprintf(stderr, "Could not convert primitive %.*s\n", @@ -1032,6 +1079,44 @@ static int _streq(const getdns_bindata *name, const char *str) else return strncmp((const char *)name->data, str, name->size) == 0; } +static getdns_return_t _get_list_or_read_file(const getdns_dict *config, + const char *setting, getdns_list **r_list, int *destroy_list) +{ + getdns_bindata *fn_bd; + char fn[FILENAME_MAX]; + FILE *fh; + getdns_return_t r; + + assert(r_list); + assert(destroy_list); + + *destroy_list = 0; + if (!(r = getdns_dict_get_list(config, setting, r_list))) + return GETDNS_RETURN_GOOD; + + else if ((r = getdns_dict_get_bindata(config, setting, &fn_bd))) + return r; + + else if (fn_bd->size >= FILENAME_MAX) + return GETDNS_RETURN_INVALID_PARAMETER; + + (void)memcpy(fn, fn_bd->data, fn_bd->size); + fn[fn_bd->size] = 0; + + if (!(fh = fopen(fn, "r"))) { + fprintf(stderr, "Could not open \"%s\": %s\n" + , fn, strerror(errno)); + return GETDNS_RETURN_GENERIC_ERROR; + } + if ((r = getdns_fp2rr_list(fh, r_list, NULL, 3600))) + fprintf(stderr,"Could not parse \"%s\"\n", fn); + + else *destroy_list = 1; + + fclose(fh); + return r; +} + static getdns_return_t configure_with_config_dict(const getdns_dict *config); static getdns_return_t configure_setting_with_config_dict( const getdns_dict *config, const getdns_bindata *setting) @@ -1043,6 +1128,7 @@ static getdns_return_t configure_setting_with_config_dict( getdns_transport_list_t transports[100]; size_t count, i; uint32_t n; + int destroy_list = 0; if (_streq(setting, "all_context")) { if ((r = getdns_dict_get_dict(config, "all_context", &dict))) @@ -1152,8 +1238,8 @@ static getdns_return_t configure_setting_with_config_dict( ,"Error configuring \"follow_redirects\""); } else if (_streq(setting, "dns_root_servers")) { - if ((r = getdns_dict_get_list( - config, "dns_root_servers", &list))) + if ((r = _get_list_or_read_file( + config, "dns_root_servers", &list, &destroy_list))) fprintf(stderr, "Could not get \"dns_root_servers\""); else if ((r = getdns_context_set_dns_root_servers( @@ -1161,6 +1247,9 @@ static getdns_return_t configure_setting_with_config_dict( fprintf( stderr ,"Error configuring \"dns_root_servers\""); + if (destroy_list) + getdns_list_destroy(list); + } else if (_streq(setting, "append_name")) { if ((r = getdns_dict_get_int(config, "append_name", &n))) fprintf(stderr, "Could not get \"append_name\""); @@ -1180,8 +1269,8 @@ static getdns_return_t configure_setting_with_config_dict( ,"Error configuring \"suffix\""); } else if (_streq(setting, "dnssec_trust_anchors")) { - if ((r = getdns_dict_get_list( - config, "dnssec_trust_anchors", &list))) + if ((r = _get_list_or_read_file( + config, "dnssec_trust_anchors", &list, &destroy_list))) fprintf( stderr ,"Could not get \"dnssec_trust_anchors\""); @@ -1190,6 +1279,9 @@ static getdns_return_t configure_setting_with_config_dict( fprintf( stderr ,"Error configuring \"dnssec_trust_anchors\""); + if (destroy_list) + getdns_list_destroy(list); + } else if (_streq(setting, "dnssec_allowed_skew")) { if ((r = getdns_dict_get_int(config,"dnssec_allowed_skew",&n))) fprintf( stderr @@ -1261,6 +1353,40 @@ static getdns_return_t configure_setting_with_config_dict( fprintf( stderr ,"Error configuring \"tls_authentication\""); + } else if (_streq(setting, "listen_addresses")) { + if ((r = getdns_dict_get_list( + config, "listen_addresses", &list))) + fprintf(stderr, "Could not get \"listen_addresses\""); + + else { + if (listen_list && !listen_dict) { + /* TODO: Stop listening */ + getdns_list_destroy(listen_list); + listen_count = 0; + listen_list = NULL; + } + /* Strange construction to copy the list. + * Needs to be done, because config dict + * will get destroyed. + */ + if (!listen_dict && + !(listen_dict = getdns_dict_create())) { + fprintf(stderr, "Could not create " + "listen_dict"); + r = GETDNS_RETURN_MEMORY_ERROR; + + } else if ((r = getdns_dict_set_list( + listen_dict, "listen_list", list))) + fprintf(stderr, "Could not set listen_list"); + + else if ((r = getdns_dict_get_list( + listen_dict, "listen_list", &listen_list))) + fprintf(stderr, "Could not get listen_list"); + + else if ((r = getdns_list_get_length( + listen_list, &listen_count))) + fprintf(stderr, "Could not get listen_count"); + } /************************************/ /**** ****/ @@ -1269,7 +1395,7 @@ static getdns_return_t configure_setting_with_config_dict( /************************************/ } else if (!_streq(setting, "implementation_string") && !_streq(setting, "version_string")) { - fprintf( stderr, "Unknown configuration key \"%.*s\"" + fprintf( stderr, "Unknown setting \"%.*s\"" , (int)setting->size, (const char *)setting->data); r = GETDNS_RETURN_NOT_IMPLEMENTED; } @@ -1330,8 +1456,10 @@ static void parse_config(char *config) (void) _jsmn_get_dict(config, tok, p.toknext, &d, &gr); if (gr) fprintf(stderr, "Config parse error: %d\n", (int)gr); - else + else { configure_with_config_dict(d); + getdns_dict_destroy(d); + } } free(tok); } @@ -1423,19 +1551,6 @@ getdns_return_t parse_args(int argc, char **argv) upstream_count++, upstream); } continue; - } else if (arg[0] == '~') { - getdns_dict *ipaddr = ipaddr_dict(context, arg + 1); - if (ipaddr) { - if (!listen_list && - !(listen_list = - getdns_list_create_with_context(context))){ - fprintf(stderr, "Could not create upstream list\n"); - return GETDNS_RETURN_MEMORY_ERROR; - } - getdns_list_set_dict(listen_list, - listen_count++, ipaddr); - } - continue; } else if (arg[0] != '-') { name = arg; continue; @@ -1800,7 +1915,29 @@ getdns_return_t parse_args(int argc, char **argv) batch_mode = 1; break; - + case 'z': + if (c[1] != 0 || ++i >= argc || !*argv[i]) { + fprintf(stderr, "listed address " + "expected after -z\n"); + return GETDNS_RETURN_GENERIC_ERROR; + } + getdns_dict *downstream = + ipaddr_dict(context, argv[i]); + if (!downstream) { + fprintf(stderr, "could not parse " + "listen address: %s", argv[i]); + } + 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); + break; default: fprintf(stderr, "Unknown option " "\"%c\"\n", *c); @@ -2390,14 +2527,16 @@ getdns_return_t start_daemon() hints.ai_flags = AI_NUMERICHOST; for (i = 0; !r && i < listen_count; i++) { - getdns_dict *dict; + getdns_dict *dict = NULL; getdns_bindata *address_data; struct sockaddr_storage addr; getdns_bindata *scope_id; - if ((r = getdns_list_get_dict(listen_list, i, &dict))) - break; - if ((r = getdns_dict_get_bindata( + if ((r = getdns_list_get_dict(listen_list, i, &dict))) { + if ((r = getdns_list_get_bindata( + listen_list, i, &address_data))) + break; + } else if ((r = getdns_dict_get_bindata( dict, "address_data", &address_data))) break; if (address_data->size == 4) @@ -2432,9 +2571,10 @@ getdns_return_t start_daemon() listen_data *ld = &listening[i * n_transports + t]; ld->fd = -1; - (void) getdns_dict_get_int(dict, - ( transport == GETDNS_TRANSPORT_TLS - ? "tls_port" : "port" ), &port); + if (dict) + (void) getdns_dict_get_int(dict, + ( transport == GETDNS_TRANSPORT_TLS + ? "tls_port" : "port" ), &port); (void) snprintf(portstr, 1024, "%d", (int)port); From 382a5ec4524028e2e5753de9185e7a60723250bc Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Sun, 22 May 2016 18:23:15 +0200 Subject: [PATCH 15/41] getdns_query daemon pass through header options (Enables DNSSEC for stub mode, but not for recursive) --- src/test/getdns_query.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 634317ac..3f05a7ec 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -2319,6 +2319,36 @@ getdns_return_t schedule_request(dns_msg *msg) char *qname_str = NULL; uint32_t qtype; getdns_return_t r; + getdns_dict *header; + uint32_t n; + getdns_list *list; + + /* pass through the header and the OPT record */ + if (!getdns_dict_get_dict(msg->query, "header", &header)) + (void)getdns_dict_set_dict(extensions, "header", header); + + if (!getdns_dict_get_int(msg->query, "/additional/0/do", &n)) + (void)getdns_dict_set_int( + extensions, "/add_opt_parameters/do_bit", n); + + if (!getdns_dict_get_int(msg->query,"/additional/0/extended_rcode",&n)) + (void)getdns_dict_set_int( + extensions, "/add_opt_parameters/extended_rcode", n); + + if (!getdns_dict_get_int(msg->query, "/additional/0/version", &n)) + (void)getdns_dict_set_int( + extensions, "/add_opt_parameters/version", n); + + if (!getdns_dict_get_int( + msg->query, "/additional/0/udp_payload_size", &n)) + (void)getdns_dict_set_int(extensions, + "/add_opt_parameters/maximum_udp_payload_size", n); + + if (!getdns_dict_get_list( + msg->query, "/additional/0/rdata/options", &list)) + (void)getdns_dict_set_list(extensions, + "/add_opt_parameters/options", list); + if ((r = getdns_dict_get_bindata(msg->query,"/question/qname",&qname))) fprintf(stderr, "Could not get qname from query: %s\n", From 7b47e82eae7869649f9d4762bc0dfb0ab537c032 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Sun, 22 May 2016 20:49:52 +0200 Subject: [PATCH 16/41] DNSSEC in server working with recursive mode too --- src/test/getdns_query.c | 44 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 3f05a7ec..158ea60f 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -2143,6 +2143,7 @@ listen_data *listening = NULL; typedef struct dns_msg { listen_data *ld; getdns_dict *query; + getdns_resolution_t rt; getdns_transaction_t transaction_id; } dns_msg; @@ -2246,6 +2247,8 @@ void request_cb(getdns_context *context, getdns_callback_type_t callback_type, getdns_return_t r; uint8_t buf[65536]; size_t len = sizeof(buf); + uint32_t n; + getdns_dict *dict; if (callback_type != GETDNS_CALLBACK_COMPLETE) { if (response) @@ -2259,6 +2262,26 @@ void request_cb(getdns_context *context, getdns_callback_type_t callback_type, else if (!response) fprintf(stderr, "No response in request_cb\n"); + else if (getdns_dict_get_int( + response, "/replies_tree/0/header/rcode", &n) && ( + (r = getdns_dict_get_dict(msg->query, "header", &dict)) || + (r = getdns_dict_set_dict(response, "/replies_tree/0/header", dict)) || + (r = getdns_dict_get_dict(msg->query, "question", &dict)) || + (r = getdns_dict_set_dict(response, "/replies_tree/0/question", dict)) || + (r = getdns_dict_set_int(response, "/replies_tree/0/header/rcode", GETDNS_RCODE_SERVFAIL)) || + (r = getdns_dict_set_int(response, "/replies_tree/0/header/qr", 1)) || + (r = getdns_dict_set_int(response, "/replies_tree/0/header/ad", 0)) + )) + fprintf(stderr, "Could not set answer rcode: %s\n", + getdns_get_errorstr_by_id(r)); + + else if (!getdns_dict_get_int( + response, "/replies_tree/0/dnssec_status", &n) && + n == GETDNS_DNSSEC_BOGUS && + (r = getdns_dict_set_int(response, "/replies_tree/0/header/rcode", GETDNS_RCODE_SERVFAIL))) + fprintf(stderr, "Could not set answer rcode: %s\n", + getdns_get_errorstr_by_id(r)); + else if ((r = getdns_dict_set_int(response, "/replies_tree/0/header/id", qid))) fprintf(stderr, "Could not set qid: %s\n", @@ -2324,13 +2347,22 @@ getdns_return_t schedule_request(dns_msg *msg) getdns_list *list; /* pass through the header and the OPT record */ - if (!getdns_dict_get_dict(msg->query, "header", &header)) - (void)getdns_dict_set_dict(extensions, "header", header); - - if (!getdns_dict_get_int(msg->query, "/additional/0/do", &n)) + n = 0; + (void) getdns_dict_get_int(msg->query, "/additional/0/do", &n); + if (msg->rt == GETDNS_RESOLUTION_STUB) { (void)getdns_dict_set_int( extensions, "/add_opt_parameters/do_bit", n); + if (!getdns_dict_get_dict(msg->query, "header", &header)) + (void)getdns_dict_set_dict(extensions, "header", header); + } else { + (void)getdns_dict_set_int(extensions, "dnssec_return_status", + n ? GETDNS_EXTENSION_TRUE : GETDNS_EXTENSION_FALSE); + n = 0; + (void) getdns_dict_get_int(msg->query, "/header/cd", &n); + r = getdns_dict_set_int(extensions, "dnssec_return_all_statuses", + n ? GETDNS_EXTENSION_TRUE : GETDNS_EXTENSION_FALSE); + } if (!getdns_dict_get_int(msg->query,"/additional/0/extended_rcode",&n)) (void)getdns_dict_set_int( extensions, "/add_opt_parameters/extended_rcode", n); @@ -2362,6 +2394,10 @@ getdns_return_t schedule_request(dns_msg *msg) fprintf(stderr, "Could get qtype from query: %s\n", getdns_get_errorstr_by_id(r)); + else 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)); + else if ((r = getdns_general(context, qname_str, qtype, extensions, msg, &msg->transaction_id, request_cb))) fprintf(stderr, "Could not schedule query: %s\n", From 938eef1b00b53d6181502ca3cd2f70a293fd7dd4 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Sun, 22 May 2016 21:58:50 +0200 Subject: [PATCH 17/41] String bindata's secretly contain final '\0' --- src/dict.c | 26 +++++++++++++++++++++----- src/list.c | 22 +++++++++++++++++++--- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/dict.c b/src/dict.c index e8b04ae8..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), 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 */ 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 */ From 4479d06ebdef53eb2f00712b5742e9aaec2bb7ab Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 23 May 2016 11:27:27 +0200 Subject: [PATCH 18/41] Allow keys without quotes in config file + help text that show config file option --- src/test/getdns_query.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 158ea60f..22ce20b8 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -533,6 +533,9 @@ print_usage(FILE *out, const char *progname) fprintf(out, "\t-B\tBatch mode. Schedule all messages before processing responses.\n"); fprintf(out, "\t-b \tSet edns0 max_udp_payload size\n"); fprintf(out, "\t-c\tSend Client Subnet privacy request\n"); + fprintf(out, "\t-C\t\n"); + fprintf(out, "\t\tRead settings from config file \n"); + fprintf(out, "\t\tThe getdns context will be configured with these settings\n"); fprintf(out, "\t-D\tSet edns0 do bit\n"); fprintf(out, "\t-d\tclear edns0 do bit\n"); fprintf(out, "\t-e \tSet idle timeout in miliseconds\n"); @@ -984,13 +987,17 @@ static int _jsmn_get_dict(char *js, jsmntok_t *t, size_t count, new_dict = getdns_dict_create(); j = 1; for (i = 0; i < t->size; i++) { - if (t[j].type != JSMN_STRING) { + if (t[j].type == JSMN_UNDEFINED) + /* Happend when primitives are used as keys */ + break; + + if (t[j].type != JSMN_STRING && t[j].type != JSMN_PRIMITIVE) { *r = GETDNS_RETURN_WRONG_TYPE_REQUESTED; getdns_dict_destroy(new_dict); return 0; } key = js + t[j].start; - js[t[j].end] = '\0'; + js[t[j].type == JSMN_STRING ? t[j].end : t[j].end - 1] = '\0'; j += 1; switch (t[j].type) { case JSMN_OBJECT: From 584193eb39bc9660ecd3b3ef5c2482c7ace34a80 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 23 May 2016 11:35:50 +0200 Subject: [PATCH 19/41] Stub daemon mode forwards the request header --- src/test/getdns_query.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 22ce20b8..99710662 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -2356,6 +2356,10 @@ getdns_return_t schedule_request(dns_msg *msg) /* pass through the header and the OPT record */ n = 0; (void) getdns_dict_get_int(msg->query, "/additional/0/do", &n); + 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)); + if (msg->rt == GETDNS_RESOLUTION_STUB) { (void)getdns_dict_set_int( extensions, "/add_opt_parameters/do_bit", n); @@ -2388,7 +2392,9 @@ getdns_return_t schedule_request(dns_msg *msg) (void)getdns_dict_set_list(extensions, "/add_opt_parameters/options", list); - +#if 0 + fprintf(stderr, "query with extensions: %s\n", getdns_pretty_print_dict(extensions)); +#endif if ((r = getdns_dict_get_bindata(msg->query,"/question/qname",&qname))) fprintf(stderr, "Could not get qname from query: %s\n", getdns_get_errorstr_by_id(r)); @@ -2401,10 +2407,6 @@ getdns_return_t schedule_request(dns_msg *msg) fprintf(stderr, "Could get qtype from query: %s\n", getdns_get_errorstr_by_id(r)); - else 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)); - else if ((r = getdns_general(context, qname_str, qtype, extensions, msg, &msg->transaction_id, request_cb))) fprintf(stderr, "Could not schedule query: %s\n", From acad5296542336d9c5ca96e6ca6dd55369f2f2bb Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 23 May 2016 12:22:23 +0200 Subject: [PATCH 20/41] Default extensions settings via config file --- src/test/getdns_query.c | 44 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 99710662..de96eb64 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -997,7 +997,11 @@ static int _jsmn_get_dict(char *js, jsmntok_t *t, size_t count, return 0; } key = js + t[j].start; - js[t[j].type == JSMN_STRING ? t[j].end : t[j].end - 1] = '\0'; + if (t[j].type== JSMN_PRIMITIVE) { + js[t[j].end - 1] = '\0'; + i++; + } else + js[t[j].end] = '\0'; j += 1; switch (t[j].type) { case JSMN_OBJECT: @@ -1124,6 +1128,20 @@ static getdns_return_t _get_list_or_read_file(const getdns_dict *config, return r; } +#define EXTENSION_SETTING_INT(X) \ + } else if (_streq(setting, #X )) { \ + if ((r = getdns_dict_get_int(config, #X , &n))) \ + fprintf(stderr, "Could not get \"" #X "\""); \ + else if ((r = getdns_dict_set_int(extensions, #X , n))) \ + fprintf(stderr,"Error setting \"" #X "\""); + +#define EXTENSION_SETTING_DICT(X) \ + } else if (_streq(setting, #X )) { \ + if ((r = getdns_dict_get_dict(config, #X , &dict))) \ + fprintf(stderr, "Could not get \"" #X "\""); \ + else if ((r = getdns_dict_set_dict(extensions, #X , dict))) \ + fprintf(stderr,"Error setting \"" #X "\""); + static getdns_return_t configure_with_config_dict(const getdns_dict *config); static getdns_return_t configure_setting_with_config_dict( const getdns_dict *config, const getdns_bindata *setting) @@ -1395,6 +1413,30 @@ static getdns_return_t configure_setting_with_config_dict( fprintf(stderr, "Could not get listen_count"); } + /**************************************/ + /**** ****/ + /**** Default extensions setting ****/ + /**** ****/ + /**************************************/ + EXTENSION_SETTING_DICT(add_opt_parameters) + EXTENSION_SETTING_INT(add_warning_for_bad_dns) + EXTENSION_SETTING_INT(dnssec_return_all_statuses) + EXTENSION_SETTING_INT(dnssec_return_full_validation_chain) + EXTENSION_SETTING_INT(dnssec_return_only_secure) + EXTENSION_SETTING_INT(dnssec_return_status) + EXTENSION_SETTING_INT(dnssec_return_validation_chain) +#if defined(DNSSEC_ROADBLOCK_AVOIDANCE) && defined(HAVE_LIBUNBOUND) + EXTENSION_SETTING_INT(dnssec_roadblock_avoidance) +#endif +#ifdef EDNS_COOKIES + EXTENSION_SETTING_INT(edns_cookies) +#endif + EXTENSION_SETTING_DICT(header) + EXTENSION_SETTING_INT(return_api_information) + EXTENSION_SETTING_INT(return_both_v4_and_v6) + EXTENSION_SETTING_INT(return_call_reporting) + EXTENSION_SETTING_INT(specify_class) + /************************************/ /**** ****/ /**** Ignored context settings ****/ From 7b861ecbbc912b430e22c46febebf9c426fa5099 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 23 May 2016 12:41:46 +0200 Subject: [PATCH 21/41] Allow arbitrary bindata with json dict primitives --- src/test/getdns_query.c | 43 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index de96eb64..44bbd5b9 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -761,6 +761,43 @@ done: return r; } +static int _jsmn_get_data(char *js, jsmntok_t *t, getdns_bindata **value) +{ + size_t i, j; + uint8_t h, l; + + if ((t->end - t->start) < 4 || (t->end - t->start) % 2 == 1 || + js[t->start] != '0' || js[t->start + 1] != 'x') + return 0; + + for (i = t->start + 2; i < t->end; i++) + if (!((js[i] >= '0' && js[i] <= '9') + ||(js[i] >= 'a' && js[i] <= 'f') + ||(js[i] >= 'A' && js[i] <= 'F'))) + return 0; + + if (!(*value = malloc(sizeof(getdns_bindata)))) + return 0; + + else if (!((*value)->data = malloc((t->end - t->start) / 2 - 1))) { + free(*value); + return 0; + } + for (i = t->start + 2, j = 0; i < t->end; i++, j++) { + h = js[i] >= '0' && js[i] <= '9' ? js[i] - '0' + : js[i] >= 'A' && js[i] <= 'F' ? js[i] + 10 - 'A' + : js[i] + 10 - 'a'; + h <<= 4; + i++; + l = js[i] >= '0' && js[i] <= '9' ? js[i] - '0' + : js[i] >= 'A' && js[i] <= 'F' ? js[i] + 10 - 'A' + : js[i] + 10 - 'a'; + (*value)->data[j] = h | l; + } + (*value)->size = j; + return 1; +} + static int _jsmn_get_ipdict(char *js, jsmntok_t *t, getdns_dict **value) { char c = js[t->end]; @@ -934,7 +971,8 @@ static int _jsmn_get_list(char *js, jsmntok_t *t, size_t count, new_list, index++, num); } else if (_jsmn_get_dname(js, t+j, &value) || _jsmn_get_ipv4(js, t+j, &value) || - _jsmn_get_ipv6(js, t+j, &value)) { + _jsmn_get_ipv6(js, t+j, &value) || + _jsmn_get_data(js, t+j, &value)) { *r = getdns_list_set_bindata( new_list, index++, value); @@ -1048,7 +1086,8 @@ static int _jsmn_get_dict(char *js, jsmntok_t *t, size_t count, new_dict, key, num); } else if (_jsmn_get_dname(js, t+j, &value) || _jsmn_get_ipv4(js, t+j, &value) || - _jsmn_get_ipv6(js, t+j, &value)) { + _jsmn_get_ipv6(js, t+j, &value) || + _jsmn_get_data(js, t+j, &value)) { *r = getdns_dict_set_bindata( new_dict, key, value); From eef421fb63502166cbcacc0bfea2f62b2410fcfd Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 23 May 2016 14:33:56 +0200 Subject: [PATCH 22/41] Allow configuration passed on command line too --- src/test/getdns_query.c | 273 ++++++++++------------------------------ 1 file changed, 64 insertions(+), 209 deletions(-) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 44bbd5b9..eeb3ca04 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -1167,6 +1167,45 @@ static getdns_return_t _get_list_or_read_file(const getdns_dict *config, return r; } +#define CONTEXT_SETTING_INT(X) \ + } else if (_streq(setting, #X)) { \ + if ((r = getdns_dict_get_int(config, #X , &n))) \ + fprintf(stderr, "Could not get \"" #X "\""); \ + else if ((r = getdns_context_set_ ## X (context, n))) \ + fprintf(stderr,"Error configuring \"" #X "\""); + +#define CONTEXT_SETTING_LIST(X) \ + } else if (_streq(setting, #X)) { \ + if ((r = getdns_dict_get_list(config, #X , &list))) \ + fprintf(stderr, "Could not get \"" #X "\""); \ + else if ((r = getdns_context_set_ ## X (context, list))) \ + fprintf(stderr,"Error configuring \"" #X "\""); + +#define CONTEXT_SETTING_LIST_OR_ZONEFILE(X) \ + } else if (_streq(setting, #X)) { \ + if ((r = _get_list_or_read_file( \ + config, #X , &list, &destroy_list))) \ + fprintf(stderr, "Could not get \"" #X "\""); \ + else if ((r = getdns_context_set_ ## X(context, list))) \ + fprintf(stderr, "Error configuring \"" #X "\""); \ + if (destroy_list) getdns_list_destroy(list); + +#define CONTEXT_SETTING_ARRAY(X, T) \ + } else if (_streq(setting, #X )) { \ + if ((r = getdns_dict_get_list(config, #X , &list))) \ + fprintf(stderr, "Could not get \"" #X "\""); \ + else if ((r = getdns_list_get_length(list, &count))) \ + fprintf(stderr, "Could not length of \"" #X "\""); \ + else for (i=0; iquery,"/question/qname",&qname))) From 77af32d121b4166897b88c977abee947dab910eb Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 23 May 2016 14:43:05 +0200 Subject: [PATCH 23/41] Two more missing unofficial settings options --- src/test/getdns_query.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index eeb3ca04..7824c9c1 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -1266,7 +1266,9 @@ static getdns_return_t configure_setting_with_config_dict( /**** ****/ /***************************************/ + CONTEXT_SETTING_INT(edns_client_subnet_private) CONTEXT_SETTING_INT(tls_authentication) + CONTEXT_SETTING_INT(tls_query_padding_blocksize) } else if (_streq(setting, "listen_addresses")) { if ((r = getdns_dict_get_list( From 95718c94746205752cfe1b96decc75db32043d70 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Mon, 23 May 2016 15:03:51 +0200 Subject: [PATCH 24/41] Mention format of the settings --- src/test/getdns_query.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 7824c9c1..40f48602 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -496,14 +496,14 @@ void print_usage(FILE *out, const char *progname) { fprintf(out, "usage: %s [