Merge branch 'features/dns_root_servers' into develop

This commit is contained in:
Willem Toorop 2015-12-23 17:41:40 +01:00
commit ce1185166c
4 changed files with 168 additions and 63 deletions

View File

@ -96,7 +96,6 @@ getdns_port_str_array[] = {
/* Private functions */
static getdns_return_t create_default_namespaces(struct getdns_context *context);
static getdns_return_t create_default_dns_transports(struct getdns_context *context);
static struct getdns_list *create_default_root_servers(void);
static getdns_return_t set_os_defaults(struct getdns_context *);
static int transaction_id_cmp(const void *, const void *);
static void dispatch_updated(struct getdns_context *, uint16_t);
@ -439,16 +438,6 @@ read_more: ;
}
}
/**
* Helper to get the default root servers.
* TODO: Implement
*/
static struct getdns_list *
create_default_root_servers()
{
return NULL;
}
/**
* check a file for changes since the last check
* and refresh the current data if changes are detected
@ -910,7 +899,8 @@ getdns_context_create_with_extended_memory_functions(
result->timeout = 5000;
result->idle_timeout = 0;
result->follow_redirects = GETDNS_REDIRECTS_FOLLOW;
result->dns_root_servers = create_default_root_servers();
result->dns_root_servers = NULL;
result->root_servers_fn[0] = 0;
result->append_name = GETDNS_APPEND_NAME_ALWAYS;
result->suffix = NULL;
@ -1074,7 +1064,11 @@ getdns_context_destroy(struct getdns_context *context)
if (context->tls_ctx)
SSL_CTX_free(context->tls_ctx);
getdns_list_destroy(context->dns_root_servers);
if (context->dns_root_servers)
getdns_list_destroy(context->dns_root_servers);
if (context->root_servers_fn[0])
unlink(context->root_servers_fn);
getdns_list_destroy(context->suffix);
if (context->trust_anchors &&
@ -1585,49 +1579,97 @@ getdns_context_set_follow_redirects(struct getdns_context *context,
*
*/
getdns_return_t
getdns_context_set_dns_root_servers(struct getdns_context *context,
struct getdns_list * addresses)
getdns_context_set_dns_root_servers(
getdns_context *context, getdns_list *addresses)
{
struct getdns_list *copy = NULL;
size_t count = 0;
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
if (context->resolution_type_set != 0) {
/* already setup */
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
if (addresses != NULL) {
if (_getdns_list_copy(addresses, &copy) != GETDNS_RETURN_GOOD) {
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
addresses = copy;
getdns_list_get_length(addresses, &count);
if (count == 0) {
getdns_list_destroy(addresses);
addresses = NULL;
} else {
size_t i = 0;
getdns_return_t r = GETDNS_RETURN_GOOD;
/* validate and add ip str */
for (i = 0; i < count; ++i) {
struct getdns_dict *dict = NULL;
getdns_list_get_dict(addresses, i, &dict);
if (r != GETDNS_RETURN_GOOD) {
break;
}
}
if (r != GETDNS_RETURN_GOOD) {
getdns_list_destroy(addresses);
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
}
}
char tmpfn[L_tmpnam];
FILE *fh;
size_t i;
getdns_dict *rr_dict;
getdns_return_t r;
getdns_bindata *addr_bd;
char dst[2048];
size_t dst_len;
getdns_list *newlist;
getdns_list_destroy(context->dns_root_servers);
context->dns_root_servers = addresses;
if (!context)
return GETDNS_RETURN_INVALID_PARAMETER;
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS);
if (!addresses) {
#ifdef HAVE_LIBUNBOUND
if (ub_ctx_set_option(
context->unbound_ctx, "root-hints:", ""))
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
#endif
if (context->dns_root_servers)
getdns_list_destroy(context->dns_root_servers);
context->dns_root_servers = NULL;
return GETDNS_RETURN_GOOD;
if (context->root_servers_fn[0])
unlink(context->root_servers_fn);
context->root_servers_fn[0] = 0;
dispatch_updated(
context, GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS);
return GETDNS_RETURN_GOOD;
}
if (!tmpnam(tmpfn))
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
if (!(fh = fopen(tmpfn, "w")))
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
for (i=0; (!(r = getdns_list_get_dict(addresses, i, &rr_dict))); i++) {
dst_len = sizeof(dst);
if (!getdns_rr_dict2str_buf(rr_dict, dst, &dst_len))
fprintf(fh, "%s", dst);
else if (getdns_dict_get_bindata(
rr_dict, "address_data", &addr_bd) &&
getdns_dict_get_bindata(
rr_dict, "/rdata/ipv4_address", &addr_bd) &&
getdns_dict_get_bindata(
rr_dict, "/rdata/ipv6_address", &addr_bd))
; /* pass */
else if (addr_bd->size == 16 &&
inet_ntop(AF_INET6, addr_bd->data, dst, sizeof(dst)))
fprintf(fh, ". NS %zu.root-servers.getdnsapi.net.\n"
"%zu.root-servers.getdnsapi.net. AAAA %s\n",
i, i, dst);
else if (addr_bd->size == 4 &&
inet_ntop(AF_INET, addr_bd->data, dst, sizeof(dst)))
fprintf(fh, ". NS %zu.root-servers.getdnsapi.net.\n"
"%zu.root-servers.getdnsapi.net. A %s\n",
i, i, dst);
}
fclose(fh);
#ifdef HAVE_LIBUNBOUND
if (ub_ctx_set_option(
context->unbound_ctx, "root-hints:", tmpfn)) {
unlink(tmpfn);
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
#endif
if (_getdns_list_copy(addresses, &newlist)) {
unlink(tmpfn);
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
if (context->dns_root_servers)
getdns_list_destroy(context->dns_root_servers);
context->dns_root_servers = newlist;
if (context->root_servers_fn[0])
unlink(context->root_servers_fn);
(void) memcpy(context->root_servers_fn, tmpfn, L_tmpnam);
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS);
return GETDNS_RETURN_GOOD;
} /* getdns_context_set_dns_root_servers */
/*
@ -2317,6 +2359,9 @@ ub_setup_recursing(struct ub_ctx *ctx, getdns_context *context)
/* TODO: use the root servers via root hints file */
(void) ub_ctx_set_fwd(ctx, NULL);
if (!context->unbound_ta_set && context->trust_anchors) {
/* fprintf(stderr, "set root hints %d\n",
ub_ctx_set_option(ctx, "root-hints:", "/home/willem/test.hints")); */
for ( rr = _getdns_rr_iter_init( &rr_spc
, context->trust_anchors
, context->trust_anchors_len)
@ -2995,9 +3040,8 @@ getdns_context_get_dns_root_servers(getdns_context *context,
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER);
*value = NULL;
if (context->dns_root_servers) {
if (context->dns_root_servers)
return _getdns_list_copy(context->dns_root_servers, value);
}
return GETDNS_RETURN_GOOD;
}

View File

@ -168,7 +168,8 @@ struct getdns_context {
uint64_t timeout;
uint64_t idle_timeout;
getdns_redirects_t follow_redirects;
struct getdns_list *dns_root_servers;
getdns_list *dns_root_servers;
char root_servers_fn[L_tmpnam];
getdns_append_name_t append_name;
struct getdns_list *suffix;
uint8_t *trust_anchors;

View File

@ -382,8 +382,9 @@ getdns_rr_dict2str(
if (r != GETDNS_RETURN_GOOD && r != GETDNS_RETURN_NEED_MORE_SPACE)
return r;
if (!(buf = malloc(buf_len + 1)))
buf_len += 1;
if (!(buf = malloc(buf_len)))
return GETDNS_RETURN_MEMORY_ERROR;
if (!r)
@ -393,7 +394,6 @@ getdns_rr_dict2str(
free(buf);
return r;
}
buf[buf_len] = 0;
*str = buf;
return GETDNS_RETURN_GOOD;
}
@ -459,9 +459,10 @@ getdns_rr_dict2str_scan(
*str = prev_str + sz_needed;
*str_len = prev_str_len - sz_needed;
r = GETDNS_RETURN_NEED_MORE_SPACE;
} else
} else {
*str_len = sz;
**str = 0;
}
if (buf != buf_spc)
GETDNS_FREE(rr_dict->mf, buf);
return r;

View File

@ -465,6 +465,7 @@ print_usage(FILE *out, const char *progname)
fprintf(out, "\t-d\tclear edns0 do bit\n");
fprintf(out, "\t-e <idle_timeout>\tSet idle timeout in miliseconds\n");
fprintf(out, "\t-F <filename>\tread the queries from the specified file\n");
fprintf(out, "\t-f <filename>\tRead DNSSEC trust anchors from <filename>\n");
fprintf(out, "\t-G\tgeneral lookup\n");
fprintf(out, "\t-H\thostname lookup. (<name> must be an IP address; <type> is ignored)\n");
fprintf(out, "\t-h\tPrint this help\n");
@ -478,6 +479,7 @@ print_usage(FILE *out, const char *progname)
fprintf(out, "\t-p\tPretty print response dict\n");
fprintf(out, "\t-P <blocksize>\tPad TLS queries to a multiple of blocksize\n");
fprintf(out, "\t-r\tSet recursing resolution type\n");
fprintf(out, "\t-R <filename>\tRead root hints from <filename>\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 (<type> is ignored)\n");
@ -507,7 +509,8 @@ static getdns_return_t validate_chain(getdns_dict *response)
if (!(to_validate = getdns_list_create()))
return GETDNS_RETURN_MEMORY_ERROR;
trust_anchor = getdns_root_trust_anchor(NULL);
if (getdns_context_get_dnssec_trust_anchors(context, &trust_anchor))
trust_anchor = getdns_root_trust_anchor(NULL);
if ((r = getdns_dict_get_list(
response, "validation_chain", &validation_chain)))
@ -677,8 +680,9 @@ getdns_return_t parse_args(int argc, char **argv)
char *arg, *c, *endptr;
int t, print_api_info = 0, print_trust_anchors = 0;
getdns_list *upstream_list = NULL;
getdns_list *tas = NULL;
getdns_list *tas = NULL, *hints = NULL;
size_t upstream_count = 0;
FILE *fh;
for (i = 1; i < argc; i++) {
arg = argv[i];
@ -758,6 +762,33 @@ getdns_return_t parse_args(int argc, char **argv)
case 'd':
(void) getdns_context_set_edns_do_bit(context, 0);
break;
case 'f':
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
fprintf(stderr, "file name expected "
"after -f\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 (getdns_fp2rr_list(fh, &tas, NULL, 3600)) {
fprintf(stderr,"Could not parse "
"\"%s\"\n", argv[i]);
return GETDNS_RETURN_GENERIC_ERROR;
}
fclose(fh);
if (getdns_context_set_dnssec_trust_anchors(
context, tas)) {
fprintf(stderr,"Could not set "
"trust anchors from \"%s\"\n",
argv[i]);
return GETDNS_RETURN_GENERIC_ERROR;
}
getdns_list_destroy(tas);
tas = NULL;
break;
case 'F':
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
fprintf(stderr, "file name expected "
@ -826,6 +857,33 @@ getdns_return_t parse_args(int argc, char **argv)
context,
GETDNS_RESOLUTION_RECURSING);
break;
case 'R':
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
fprintf(stderr, "file name expected "
"after -f\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 (getdns_fp2rr_list(fh, &hints, NULL, 3600)) {
fprintf(stderr,"Could not parse "
"\"%s\"\n", argv[i]);
return GETDNS_RETURN_GENERIC_ERROR;
}
fclose(fh);
if (getdns_context_set_dns_root_servers(
context, hints)) {
fprintf(stderr,"Could not set "
"root servers from \"%s\"\n",
argv[i]);
return GETDNS_RETURN_GENERIC_ERROR;
}
getdns_list_destroy(hints);
hints = NULL;
break;
case 's':
getdns_context_set_resolution_type(
context, GETDNS_RESOLUTION_STUB);
@ -932,7 +990,8 @@ next: ;
return CONTINUE;
}
if (print_trust_anchors) {
if ((tas = getdns_root_trust_anchor(NULL))) {
if (!getdns_context_get_dnssec_trust_anchors(context, &tas)) {
/* if ((tas = getdns_root_trust_anchor(NULL))) { */
fprintf(stdout, "%s\n", getdns_pretty_print_list(tas));
return CONTINUE;
} else