From 48fea8d9e0283700104cf8984b41d53df1a552c6 Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Thu, 20 Feb 2014 15:42:10 -0500 Subject: [PATCH 1/4] Add getdns_context_set_return_dnssec_status --- src/context.c | 10 ++++++++++ src/context.h | 2 ++ src/getdns/getdns_extra.h | 39 +++++++++++++++++++++++++++++++++++++++ src/request-internal.c | 1 + src/rr-dict.c | 5 ++++- src/types-internal.h | 3 +++ src/util-internal.c | 5 +++-- 7 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 src/getdns/getdns_extra.h diff --git a/src/context.c b/src/context.c index b9d6c08e..3beb4dee 100644 --- a/src/context.c +++ b/src/context.c @@ -1734,5 +1734,15 @@ getdns_context_get_api_information(getdns_context* context) { return result; } +getdns_return_t +getdns_context_set_return_dnssec_status(getdns_context* context, int enabled) { + RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); + if (enabled != GETDNS_EXTENSION_TRUE || + enabled != GETDNS_EXTENSION_FALSE) { + return GETDNS_RETURN_INVALID_PARAMETER; + } + context->return_dnssec_status = enabled; + return GETDNS_RETURN_GOOD; +} /* context.c */ diff --git a/src/context.h b/src/context.h index 4ee96a21..1bc03987 100644 --- a/src/context.h +++ b/src/context.h @@ -38,6 +38,7 @@ #define _GETDNS_CONTEXT_H_ #include +#include #include "types-internal.h" struct getdns_dns_req; @@ -96,6 +97,7 @@ struct getdns_context { * the real work */ struct ub_ctx *unbound_ctx; int has_ta; /* No DNSSEC without trust anchor */ + int return_dnssec_status; /* which resolution type the contexts are configured for * 0 means nothing set diff --git a/src/getdns/getdns_extra.h b/src/getdns/getdns_extra.h new file mode 100644 index 00000000..62a0a079 --- /dev/null +++ b/src/getdns/getdns_extra.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013, NLNet Labs, Versign, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _GETDNS_CONTEXT_H_ +#define _GETDNS_CONTEXT_H_ + +#include + +/* Enable the return_dnssec_status extension on every request. + value is either GETDNS_EXTENSION_TRUE or GETDNS_EXTENSION_FALSE + returns GETDNS_RETURN_GOOD on success or GETDNS_RETURN_INVALID_PARAMETER + if context or value is invalid */ +getdns_return_t getdns_context_set_return_dnssec_status(getdns_context* context, int enabled); + +#endif diff --git a/src/request-internal.c b/src/request-internal.c index 8a2f4f1a..b13ae197 100644 --- a/src/request-internal.c +++ b/src/request-internal.c @@ -130,6 +130,7 @@ dns_req_new(struct getdns_context *context, result->trans_id = ldns_get_random(); getdns_dict_copy(extensions, &result->extensions); + result->return_dnssec_status = context->return_dnssec_status; /* will be set by caller */ result->user_pointer = NULL; diff --git a/src/rr-dict.c b/src/rr-dict.c index 199b6fcc..7d81409a 100644 --- a/src/rr-dict.c +++ b/src/rr-dict.c @@ -660,7 +660,7 @@ priv_getdns_equip_dict_with_hip_rdfs(struct getdns_dict* rdata, ldns_rr* rr, r |= getdns_dict_set_bindata(rdata, def->rdata[1].name, &hit_data); r |= getdns_dict_set_bindata(rdata, def->rdata[2].name, &key_data); if (r != GETDNS_RETURN_GOOD) { - return r; + return GETDNS_RETURN_GENERIC_ERROR; } if (ldns_rr_rd_count(rr) > 1) { @@ -682,6 +682,9 @@ priv_getdns_equip_dict_with_hip_rdfs(struct getdns_dict* rdata, ldns_rr* rr, } /* always clean up */ getdns_list_destroy(servers); + if (r != GETDNS_RETURN_GOOD) { + return GETDNS_RETURN_GENERIC_ERROR; + } } return r; diff --git a/src/types-internal.h b/src/types-internal.h index ccfe4fc1..73d80e40 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -180,6 +180,9 @@ typedef struct getdns_dns_req /* local timeout id */ getdns_transaction_t local_timeout_id; + /* dnssec status */ + int return_dnssec_status; + } getdns_dns_req; #define MF_PLAIN ((void *)&plain_mem_funcs_user_arg) diff --git a/src/util-internal.c b/src/util-internal.c index 3a8c98dc..e6566226 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -551,7 +551,8 @@ create_getdns_response(struct getdns_dns_req * completed_request) dnssec_return_only_secure = is_extension_set( completed_request->extensions, "dnssec_return_only_secure"); dnssec_return_status = dnssec_return_only_secure || is_extension_set( - completed_request->extensions, "dnssec_return_status"); + completed_request->extensions, "dnssec_return_status") || + completed_request->return_dnssec_status == GETDNS_EXTENSION_TRUE; if (completed_request->first_req->request_class == GETDNS_RRTYPE_A || completed_request->first_req->request_class == @@ -617,7 +618,7 @@ create_getdns_response(struct getdns_dns_req * completed_request) } if (dnssec_return_status || dnssec_return_validation_chain) { r = getdns_dict_set_int(reply, "dnssec_status", - ( netreq->secure ? GETDNS_DNSSEC_SECURE + ( netreq->secure ? GETDNS_DNSSEC_SECURE : netreq->bogus ? GETDNS_DNSSEC_BOGUS : rrsigs_in_answer(netreq->result) && completed_request->context->has_ta From 4f266d1a88ddfa58320c2f2d5bd49ac11386ab87 Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Thu, 20 Feb 2014 15:51:51 -0500 Subject: [PATCH 2/4] Change make test to only call check_getdns --- src/test/Makefile.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/Makefile.in b/src/test/Makefile.in index 6bc8e71f..ee9bffd9 100644 --- a/src/test/Makefile.in +++ b/src/test/Makefile.in @@ -3,7 +3,7 @@ # # Copyright (c) 2013, Versign, Inc., NLNet Labs # All rights reserved. -# +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright @@ -14,7 +14,7 @@ # * Neither the name of the nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. -# +# # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -77,7 +77,7 @@ tests_dnssec: tests_dnssec.o testmessages.o test: all - ./testscript.sh + ./check_getdns @echo "All tests OK" clean: From 524783804c1a269486471fc60e5199ce8c8744c5 Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Thu, 20 Feb 2014 16:17:41 -0500 Subject: [PATCH 3/4] Fix some issues per code review --- src/context.c | 31 +++++++++++++++++++++---------- src/context.h | 2 ++ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/context.c b/src/context.c index 3beb4dee..049546cb 100644 --- a/src/context.c +++ b/src/context.c @@ -53,7 +53,7 @@ void *plain_mem_funcs_user_arg = MF_PLAIN; /* Private functions */ getdns_return_t create_default_namespaces(struct getdns_context *context); -static struct getdns_list *create_default_root_servers(); +static struct getdns_list *create_default_root_servers(void); static getdns_return_t add_ip_str(struct getdns_dict *); static struct getdns_dict *create_ipaddr_dict_from_rdf(struct getdns_context *, ldns_rdf *); @@ -292,9 +292,9 @@ set_os_defaults(struct getdns_context *context) if(context->fchg_resolvconf == NULL) { - context->fchg_resolvconf = (struct filechg *) malloc(sizeof(struct filechg)); + context->fchg_resolvconf = GETDNS_MALLOC(context->my_mf, struct filechg); if(context->fchg_resolvconf == NULL) - return GETDNS_RETURN_GENERIC_ERROR; + return GETDNS_RETURN_MEMORY_ERROR; context->fchg_resolvconf->fn = "/etc/resolv.conf"; context->fchg_resolvconf->prevstat = NULL; context->fchg_resolvconf->changes = GETDNS_FCHG_NOCHANGES; @@ -405,6 +405,7 @@ getdns_context_create_with_extended_memory_functions( if (!result) { return GETDNS_RETURN_GENERIC_ERROR; } + result->destroying = 0; result->my_mf.mf_arg = userarg; result->my_mf.mf.ext.malloc = malloc; result->my_mf.mf.ext.realloc = realloc; @@ -515,6 +516,10 @@ getdns_context_destroy(struct getdns_context *context) if (context == NULL) { return; } + context->destroying = 1; + cancel_outstanding_requests(context, 1); + getdns_extension_detach_eventloop(context); + if (context->namespaces) GETDNS_FREE(context->my_mf, context->namespaces); if(context->fchg_resolvconf) @@ -530,9 +535,6 @@ getdns_context_destroy(struct getdns_context *context) GETDNS_FREE(context->my_mf, context->fchg_hosts); } - cancel_outstanding_requests(context, 1); - getdns_extension_detach_eventloop(context); - getdns_list_destroy(context->dns_root_servers); getdns_list_destroy(context->suffix); getdns_list_destroy(context->dnssec_trust_anchors); @@ -1056,7 +1058,7 @@ getdns_return_t getdns_context_set_edns_do_bit(struct getdns_context *context, uint8_t value) { RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - /* 0 or 1 */ + /* only allow 1 */ if (value != 1) { return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; } @@ -1299,7 +1301,9 @@ getdns_context_prepare_for_resolution(struct getdns_context *context, getdns_return_t r; RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); - + if (context->destroying) { + return GETDNS_RETURN_BAD_CONTEXT; + } if (context->resolution_type_set == context->resolution_type) /* already set and no config changes * have caused this to be bad. @@ -1450,9 +1454,16 @@ getdns_context_get_num_pending_requests(struct getdns_context* context, (timeout_data->timeout_time.tv_sec == now.tv_sec && timeout_data->timeout_time.tv_usec >= now.tv_usec)) { next_timeout->tv_sec = timeout_data->timeout_time.tv_sec - now.tv_sec; - next_timeout->tv_usec = timeout_data->timeout_time.tv_usec - now.tv_usec; + if (timeout_data->timeout_time.tv_usec < now.tv_usec) { + /* we only enter this condition when timeout_data.tv_sec > now.tv_sec */ + next_timeout->tv_usec = (timeout_data->timeout_time.tv_usec + 100000) - now.tv_usec; + next_timeout->tv_sec--; + } else { + next_timeout->tv_usec = timeout_data->timeout_time.tv_usec - now.tv_usec; + } } else { /* timeout passed already */ + /* usec already 0 per setting default */ next_timeout->tv_sec = 0; } } @@ -1493,7 +1504,7 @@ getdns_return_t getdns_context_process_async(struct getdns_context* context) { /* get the next_timeout */ next_timeout = ldns_rbtree_next(next_timeout); /* delete the node */ - /* timeout data is freed in the clear_timeout */ + /* timeout data and the timeouts_by_id node are freed in the clear_timeout */ ldns_rbnode_t* to_del = ldns_rbtree_delete(context->timeouts_by_time, timeout_data); if (to_del) { /* should always exist .. */ diff --git a/src/context.h b/src/context.h index 1bc03987..77838f44 100644 --- a/src/context.h +++ b/src/context.h @@ -90,6 +90,8 @@ struct getdns_context { getdns_update_callback update_callback; + int destroying; + struct mem_funcs mf; struct mem_funcs my_mf; From abebc0e2b66a328327ac034897b39177657a28c2 Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Thu, 20 Feb 2014 17:05:15 -0500 Subject: [PATCH 4/4] Create ldns_rbtree structs with mem functs --- src/context.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/context.c b/src/context.c index 049546cb..83d691f3 100644 --- a/src/context.c +++ b/src/context.c @@ -376,6 +376,17 @@ timeout_cmp(const void *to1, const void *to2) } } +static ldns_rbtree_t* +create_ldns_rbtree(getdns_context * context, + int(*cmpf)(const void *, const void *)) { + ldns_rbtree_t* result = GETDNS_MALLOC(context->mf, ldns_rbtree_t); + if (!result) { + return NULL; + } + ldns_rbtree_init(result, cmpf); + return result; +} + /* * getdns_context_create * @@ -420,7 +431,10 @@ getdns_context_create_with_extended_memory_functions( result->resolution_type_set = 0; - result->outbound_requests = ldns_rbtree_create(transaction_id_cmp); + result->outbound_requests = create_ldns_rbtree(result, transaction_id_cmp); + result->timeouts_by_time = create_ldns_rbtree(result, timeout_cmp); + result->timeouts_by_id = create_ldns_rbtree(result, transaction_id_cmp); + result->resolution_type = GETDNS_RESOLUTION_RECURSING; if(create_default_namespaces(result) != GETDNS_RETURN_GOOD) @@ -441,8 +455,6 @@ getdns_context_create_with_extended_memory_functions( result->extension = NULL; result->extension_data = NULL; - result->timeouts_by_time = ldns_rbtree_create(timeout_cmp); - result->timeouts_by_id = ldns_rbtree_create(transaction_id_cmp); result->fchg_resolvconf = NULL; result->fchg_hosts = NULL; @@ -457,13 +469,19 @@ getdns_context_create_with_extended_memory_functions( result->dns_transport = GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP; result->limit_outstanding_queries = 0; result->has_ta = priv_getdns_parse_ta_file(NULL, NULL); - + if (!result->outbound_requests || + !result->timeouts_by_id || + !result->timeouts_by_time) { + getdns_context_destroy(result); + return GETDNS_RETURN_MEMORY_ERROR; + } /* unbound context is initialized here */ result->unbound_ctx = NULL; if (GETDNS_RETURN_GOOD != rebuild_ub_ctx(result)) { getdns_context_destroy(result); return GETDNS_RETURN_GENERIC_ERROR; } + *context = result; return GETDNS_RETURN_GOOD; @@ -544,9 +562,12 @@ getdns_context_destroy(struct getdns_context *context) if (context->unbound_ctx) ub_ctx_delete(context->unbound_ctx); - ldns_rbtree_free(context->outbound_requests); - ldns_rbtree_free(context->timeouts_by_id); - ldns_rbtree_free(context->timeouts_by_time); + if (context->outbound_requests) + GETDNS_FREE(context->my_mf, context->outbound_requests); + if (context->timeouts_by_id) + GETDNS_FREE(context->my_mf, context->timeouts_by_id); + if (context->timeouts_by_time) + GETDNS_FREE(context->my_mf, context->timeouts_by_time); GETDNS_FREE(context->my_mf, context); return;