From 7975c98c3fe55d793345089c03b105a70ba1c217 Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Tue, 13 Aug 2013 10:02:09 -0400 Subject: [PATCH 1/3] Remove getdns_address.c. Update context to use copy. --- src/common/Makefile.am | 2 +- src/common/Makefile.in | 11 +++---- src/common/getdns_address.c | 60 ----------------------------------- src/common/getdns_context.c | 28 ++++++++++++++-- src/common/getdns_core_only.h | 6 ++-- src/common/getdns_general.c | 34 ++++++++++++++++++++ 6 files changed, 70 insertions(+), 71 deletions(-) delete mode 100644 src/common/getdns_address.c diff --git a/src/common/Makefile.am b/src/common/Makefile.am index adf45dc0..07665a5b 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -1,6 +1,6 @@ AM_CPPFLAGS = -Wall -Werror -g -fPIC -I$(srcdir)/ -I /usr/local/include -std=c99 lib_LTLIBRARIES = libgetdns.la -libgetdns_la_SOURCES = getdns_address.c getdns_context.c getdns_convert.c \ +libgetdns_la_SOURCES = getdns_context.c getdns_convert.c \ getdns_dict.c getdns_general.c getdns_hostname.c getdns_list.c \ getdns_service.c getdns_sync.c getdns_validate_dnssec.c \ getdns_core_only.h getdns_libevent.h getdns_context.h diff --git a/src/common/Makefile.in b/src/common/Makefile.in index b29760af..71538e12 100644 --- a/src/common/Makefile.in +++ b/src/common/Makefile.in @@ -92,10 +92,10 @@ am__uninstall_files_from_dir = { \ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libgetdns_la_LIBADD = -am_libgetdns_la_OBJECTS = getdns_address.lo getdns_context.lo \ - getdns_convert.lo getdns_dict.lo getdns_general.lo \ - getdns_hostname.lo getdns_list.lo getdns_service.lo \ - getdns_sync.lo getdns_validate_dnssec.lo +am_libgetdns_la_OBJECTS = getdns_context.lo getdns_convert.lo \ + getdns_dict.lo getdns_general.lo getdns_hostname.lo \ + getdns_list.lo getdns_service.lo getdns_sync.lo \ + getdns_validate_dnssec.lo libgetdns_la_OBJECTS = $(am_libgetdns_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp @@ -237,7 +237,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -Wall -Werror -g -fPIC -I$(srcdir)/ -I /usr/local/include -std=c99 lib_LTLIBRARIES = libgetdns.la -libgetdns_la_SOURCES = getdns_address.c getdns_context.c getdns_convert.c \ +libgetdns_la_SOURCES = getdns_context.c getdns_convert.c \ getdns_dict.c getdns_general.c getdns_hostname.c getdns_list.c \ getdns_service.c getdns_sync.c getdns_validate_dnssec.c \ getdns_core_only.h getdns_libevent.h getdns_context.h @@ -320,7 +320,6 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getdns_address.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getdns_context.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getdns_convert.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getdns_dict.Plo@am__quote@ diff --git a/src/common/getdns_address.c b/src/common/getdns_address.c deleted file mode 100644 index d6e85a63..00000000 --- a/src/common/getdns_address.c +++ /dev/null @@ -1,60 +0,0 @@ -/** - * - * /brief getdns core functions - * - * This is the meat of the API - * Originally taken from the getdns API description pseudo implementation. - * - */ -/* The MIT License (MIT) - * Copyright (c) 2013 Verisign, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -/* stuff to make it compile pedantically */ -#define UNUSED_PARAM(x) ((void)(x)) - -/* - * getdns_address - * - */ -getdns_return_t -getdns_address( - getdns_context_t context, - const char *name, - struct getdns_dict *extensions, - void *userarg, - getdns_transaction_t *transaction_id, - getdns_callback_t callback -) -{ - UNUSED_PARAM(context); - UNUSED_PARAM(name); - UNUSED_PARAM(extensions); - UNUSED_PARAM(userarg); - UNUSED_PARAM(transaction_id); - UNUSED_PARAM(callback); - - return GETDNS_RETURN_GOOD; -} /* getdns_address */ - -/* getdns_address.c */ diff --git a/src/common/getdns_context.c b/src/common/getdns_context.c index 0b6c18fd..5fdd33c9 100644 --- a/src/common/getdns_context.c +++ b/src/common/getdns_context.c @@ -386,6 +386,13 @@ getdns_context_set_dns_root_servers( struct getdns_list *addresses ) { + getdns_list *copy = NULL; + if (addresses != NULL) { + if (getdns_list_copy(addresses, ©) != GETDNS_RETURN_GOOD) { + return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; + } + addresses = copy; + } getdns_list_destroy(context->dns_root_servers); context->dns_root_servers = addresses; @@ -429,8 +436,14 @@ getdns_context_set_suffix( struct getdns_list *value ) { + getdns_list *copy = NULL; + if (value != NULL) { + if (getdns_list_copy(value, ©) != GETDNS_RETURN_GOOD) { + return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; + } + value = copy; + } getdns_list_destroy(context->suffix); - context->suffix = value; dispatch_updated(context, GETDNS_CONTEXT_CODE_SUFFIX); @@ -448,8 +461,14 @@ getdns_context_set_dnssec_trust_anchors( struct getdns_list *value ) { + getdns_list *copy = NULL; + if (value != NULL) { + if (getdns_list_copy(value, ©) != GETDNS_RETURN_GOOD) { + return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; + } + value = copy; + } getdns_list_destroy(context->dnssec_trust_anchors); - context->dnssec_trust_anchors = value; dispatch_updated(context, GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS); @@ -487,6 +506,11 @@ getdns_context_set_stub_resolution( if (upstream_list == NULL) { return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; } + getdns_list *copy = NULL; + if (getdns_list_copy(upstream_list, ©) != GETDNS_RETURN_GOOD) { + return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; + } + upstream_list = copy; getdns_context_set_resolution_type(context, GETDNS_CONTEXT_STUB); diff --git a/src/common/getdns_core_only.h b/src/common/getdns_core_only.h index 82a53435..7f1e5964 100644 --- a/src/common/getdns_core_only.h +++ b/src/common/getdns_core_only.h @@ -217,9 +217,9 @@ * \defgroup extvals Values Associated With Extensions * @{ */ -#define GETDNS_EXTENSION_TRUE 1000 +#define GETDNS_EXTENSION_TRUE 1 #define GETDNS_EXTENSION_TRUE_TEXT Turn on the extension -#define GETDNS_EXTENSION_FALSE 1001 +#define GETDNS_EXTENSION_FALSE 0 #define GETDNS_EXTENSION_FALSE_TEXT Do not turn on the extension /** @} */ @@ -245,6 +245,8 @@ #define GETDNS_STR_IPV6 "IPv6" #define GETDNS_STR_ADDRESS_TYPE "address_type" #define GETDNS_STR_ADDRESS_DATA "address_data" +#define GETDNS_STR_EXTENSION_RETURN_BOTH_V4_AND_V6 "return_both_v4_and_v6" + /** @} */ diff --git a/src/common/getdns_general.c b/src/common/getdns_general.c index e525ec7b..84aa39c6 100644 --- a/src/common/getdns_general.c +++ b/src/common/getdns_general.c @@ -57,4 +57,38 @@ getdns_general( return GETDNS_RETURN_GOOD; } /* getdns_general */ + +/* + * getdns_address + * + */ +getdns_return_t +getdns_address( + getdns_context_t context, + const char *name, + struct getdns_dict *extensions, + void *userarg, + getdns_transaction_t *transaction_id, + getdns_callback_t callback +) +{ + int cleanup_extensions = 0; + if (!extensions) { + extensions = getdns_dict_create(); + cleanup_extensions = 1; + } + getdns_dict_set_int(extensions, + GETDNS_STR_EXTENSION_RETURN_BOTH_V4_AND_V6, + GETDNS_EXTENSION_TRUE); + + getdns_return_t result = + getdns_general(context, name, GETDNS_RRTYPE_A, + extensions, userarg, transaction_id, + callback); + if (cleanup_extensions) { + getdns_dict_destroy(extensions); + } + return result; +} + /* getdns_general.c */ From bf92cb6bb48ef1cd6ef0f629efd8e5a634c9625b Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Tue, 13 Aug 2013 16:10:21 -0400 Subject: [PATCH 2/3] Some updates. Need to think about how to not rewrite what ldns and libevent have already done --- src/common/getdns_context.c | 11 ++++++++++- src/common/getdns_context.h | 3 ++- src/common/getdns_general.c | 35 +++++++++++++++++++++++++++++++---- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/common/getdns_context.c b/src/common/getdns_context.c index 5fdd33c9..1870c483 100644 --- a/src/common/getdns_context.c +++ b/src/common/getdns_context.c @@ -141,13 +141,17 @@ getdns_context_create( bool set_from_os ) { - UNUSED_PARAM(set_from_os); getdns_context_t result = NULL; if (context == NULL) { return GETDNS_RETURN_GENERIC_ERROR; } + getdns_dict *outbound_reqs = getdns_dict_create(); + if (outbound_reqs == NULL) { + return GETDNS_RETURN_GENERIC_ERROR; + } + /** default init **/ result = malloc(sizeof(struct getdns_context_t)); result->resolution_type = GETDNS_CONTEXT_RECURSING; @@ -168,6 +172,9 @@ getdns_context_create( result->edns_version = 0; result->edns_do_bit = 0; + result->event_base = NULL; + result->outbound_reqs = outbound_reqs; + result->update_callback = NULL; result->memory_allocator = malloc; result->memory_deallocator = free; @@ -207,6 +214,8 @@ getdns_context_destroy( getdns_list_destroy(context->dnssec_trust_anchors); getdns_list_destroy(context->upstream_list); + getdns_dict_destroy(context->outbound_reqs); + free(context); return; } /* getdns_context_destroy */ diff --git a/src/common/getdns_context.h b/src/common/getdns_context.h index f716d746..2aea8e09 100644 --- a/src/common/getdns_context.h +++ b/src/common/getdns_context.h @@ -40,7 +40,8 @@ struct getdns_context_t { /* Event loop */ struct event_base* event_base; - + + getdns_dict *outbound_reqs; } ; #endif diff --git a/src/common/getdns_general.c b/src/common/getdns_general.c index 84aa39c6..9705b0da 100644 --- a/src/common/getdns_general.c +++ b/src/common/getdns_general.c @@ -28,7 +28,25 @@ * THE SOFTWARE. */ -#include +#include +#include + +/* outbound request */ +typedef struct getdns_outbound_req { + + /* stub or recursive */ + uint16_t req_type; + /* transaction id */ + getdns_transaction_t transaction_id; + /* callback */ + getdns_callback_t callback; + /* user arg to pass to callback */ + void* userarg; + /* list of servers this can send to */ + getdns_list *upstream; + + +} getdns_async_req; /* stuff to make it compile pedantically */ #define UNUSED_PARAM(x) ((void)(x)) @@ -47,13 +65,22 @@ getdns_general( getdns_callback_t callback ) { - UNUSED_PARAM(context); + /* Default to zero */ + if (transaction_id != NULL) { + *transaction_id = 0; + } + if (context->event_base == NULL || + callback == NULL) { + /* Can't do async without an event loop + * or callback + */ + return GETDNS_RETURN_GENERIC_ERROR; + } + UNUSED_PARAM(name); UNUSED_PARAM(request_type); UNUSED_PARAM(extensions); UNUSED_PARAM(userarg); - UNUSED_PARAM(transaction_id); - UNUSED_PARAM(callback); return GETDNS_RETURN_GOOD; } /* getdns_general */ From ad20c23f423d57ec46cfab25906d7e195d3b3854 Mon Sep 17 00:00:00 2001 From: Neel Goyal Date: Wed, 14 Aug 2013 17:19:06 -0400 Subject: [PATCH 3/3] More progress on async --- src/common/getdns_context.c | 12 +- src/common/getdns_context.h | 4 + src/common/getdns_core_only.h | 5 +- src/common/getdns_general.c | 293 +++++++++++++++++++++++++++++++--- src/common/getdns_libevent.h | 3 +- src/test/tests_list.c | 8 +- 6 files changed, 296 insertions(+), 29 deletions(-) diff --git a/src/common/getdns_context.c b/src/common/getdns_context.c index 1870c483..efbdd6c8 100644 --- a/src/common/getdns_context.c +++ b/src/common/getdns_context.c @@ -135,10 +135,9 @@ static getdns_return_t set_os_defaults(getdns_context_t context) { * * call this to initialize the context that is used in other getdns calls */ -getdns_return_t -getdns_context_create( +getdns_return_t getdns_context_create( getdns_context_t *context, - bool set_from_os + int set_from_os ) { getdns_context_t result = NULL; @@ -173,6 +172,7 @@ getdns_context_create( result->edns_do_bit = 0; result->event_base = NULL; + result->resolver_socket = 0; result->outbound_reqs = outbound_reqs; result->update_callback = NULL; @@ -216,6 +216,12 @@ getdns_context_destroy( getdns_dict_destroy(context->outbound_reqs); + /* TODO: cancel all events */ + + if (context->resolver_socket != 0) { + evutil_closesocket(context->resolver_socket); + } + free(context); return; } /* getdns_context_destroy */ diff --git a/src/common/getdns_context.h b/src/common/getdns_context.h index 2aea8e09..7cfdac40 100644 --- a/src/common/getdns_context.h +++ b/src/common/getdns_context.h @@ -41,7 +41,11 @@ struct getdns_context_t { /* Event loop */ struct event_base* event_base; + /* outbound request dict (transaction -> req struct) */ getdns_dict *outbound_reqs; + + /* socket */ + evutil_socket_t resolver_socket; } ; #endif diff --git a/src/common/getdns_core_only.h b/src/common/getdns_core_only.h index 7f1e5964..c7cc3a15 100644 --- a/src/common/getdns_core_only.h +++ b/src/common/getdns_core_only.h @@ -696,10 +696,9 @@ getdns_service( getdns_callback_t callbackfn ); -getdns_return_t -getdns_context_create( +getdns_return_t getdns_context_create( getdns_context_t *context, - bool set_from_os + int set_from_os ); void diff --git a/src/common/getdns_general.c b/src/common/getdns_general.c index 9705b0da..409c5f70 100644 --- a/src/common/getdns_general.c +++ b/src/common/getdns_general.c @@ -28,29 +28,272 @@ * THE SOFTWARE. */ +/** + * Much of this is based on / duplicated code from libevent evdns. Credits to + * Nick Mathewson and Niels Provos + * + * https://github.com/libevent/libevent/ + * + * libevent dns is based on software by Adam Langly. Adam's original message: + * + * Async DNS Library + * Adam Langley + * http://www.imperialviolet.org/eventdns.html + * Public Domain code + * + * This software is Public Domain. To view a copy of the public domain dedication, + * visit http://creativecommons.org/licenses/publicdomain/ or send a letter to + * Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. + * + * I ask and expect, but do not require, that all derivative works contain an + * attribution similar to: + * Parts developed by Adam Langley + * + * You may wish to replace the word "Parts" with something else depending on + * the amount of original code. + * + * (Derivative works does not include programs which link against, run or include + * the source verbatim in their source distributions) + * + * Version: 0.1b + */ + #include #include -/* outbound request */ -typedef struct getdns_outbound_req { +/* useful macros */ +#define gd_malloc(sz) context->memory_allocator(sz) +#define gd_free(ptr) context->memory_deallocator(ptr) - /* stub or recursive */ - uint16_t req_type; - /* transaction id */ - getdns_transaction_t transaction_id; - /* callback */ - getdns_callback_t callback; - /* user arg to pass to callback */ - void* userarg; - /* list of servers this can send to */ - getdns_list *upstream; +struct getdns_dns_req; + +typedef struct getdns_nameserver { + evutil_socket_t socket; /* a connected UDP socket */ + struct sockaddr_storage address; + ev_socklen_t addrlen; + + int failed_times; /* number of times which we have given this server a chance */ + int timedout; /* number of times in a row a request has timed out */ + struct event event; + + struct event timeout_event; /* used to keep the timeout for */ + /* when we next probe this server. */ + /* Valid if state == 0 */ + /* Outstanding probe request for this nameserver, if any */ + struct getdns_dns_req *probe_request; + char state; /* zero if we think that this server is down */ + char choked; /* true if we have an EAGAIN from this server's socket */ + char write_waiting; /* true if we are waiting for EV_WRITE events */ + + /* getdns context */ + getdns_context_t context; + /* Number of currently inflight requests: used + * to track when we should add/del the event. */ + int requests_inflight; +} getdns_nameserver; -} getdns_async_req; +/* network request - state for a network request and referenced + * by the the outbound_req + */ +typedef struct getdns_network_req { + ldns_pkt *pkt; /* the dns packet data */ + uint16_t request_type; /* query type */ + + int reissue_count; + int tx_count; /* the number of times that this packet has been sent */ + + /* not owned */ + struct nameserver *ns; /* the server which we last sent it (unused) */ + getdns_dict *upstream_server; + + struct event timeout_event; + + getdns_transaction_t trans_id; /* the transaction id */ + + unsigned transmit_me :1; /* needs to be transmitted */ + + getdns_context_t context; + + struct getdns_dns_req *owner; + +} getdns_network_req; + +/* outbound request - manages recursion and stub reqs */ +typedef struct getdns_dns_req { + + struct getdns_network_req *current_req; + getdns_context_t context; + + uint16_t resolver_type; + + /* callback data */ + getdns_callback_t user_callback; + void *user_pointer; + + + int pending_cb; /* Waiting for its callback to be invoked; not + * owned by event base any more. */ + + /* search not supported.. yet */ + +} getdns_dns_req; /* stuff to make it compile pedantically */ #define UNUSED_PARAM(x) ((void)(x)) +/* TODO: flags */ +static ldns_pkt *create_new_pkt(getdns_context_t context, + const char* name, + uint16_t request_type, + struct getdns_dict* extensions) { + ldns_pkt *pkt = NULL; + ldns_rr_type type = (ldns_rr_type) request_type; + ldns_pkt_query_new_frm_str(&pkt, name, + type, + LDNS_RR_CLASS_IN, 0); + if (pkt) { + /* id */ + ldns_pkt_set_id(pkt, ldns_get_random()); + } + return pkt; +} + +static void network_req_free(getdns_context_t context, + getdns_network_req* net_req) { + if (!net_req) { + return; + } + if (net_req->pkt) { + ldns_pkt_free(net_req->pkt); + } + gd_free(net_req); +} + +static getdns_network_req* network_req_new(getdns_context_t context, + const char* name, + uint16_t request_type, + struct getdns_dict* extensions, + getdns_transaction_t *transaction_id) { + getdns_network_req *net_req = NULL; + ldns_pkt *pkt = NULL; + net_req = gd_malloc(sizeof(getdns_network_req)); + if (!net_req) { + return NULL; + } + net_req->ns = NULL; + net_req->pkt = NULL; + net_req->context = context; + net_req->request_type = request_type; + + /* create ldns packet */ + pkt = create_new_pkt(context, name, request_type, extensions); + if (!pkt) { + /* free up the req */ + network_req_free(context, net_req); + return NULL; + } + net_req->pkt = pkt; + net_req->trans_id = ldns_pkt_id(pkt); + if (transaction_id) { + *transaction_id = net_req->trans_id; + } + + return net_req; +} + +static void dns_req_free(getdns_context_t context, + getdns_dns_req* req) { + if (!req) { + return; + } + network_req_free(context, req->current_req); + gd_free(req); +} + +/* create a new dns req to be submitted */ +static getdns_dns_req* dns_req_new(getdns_context_t context, + const char* name, + uint16_t request_type, + struct getdns_dict *extensions, + getdns_transaction_t *transaction_id) { + getdns_dns_req *result = NULL; + getdns_network_req *net_req = NULL; + result = gd_malloc(sizeof(getdns_dns_req)); + if (result == NULL) { + return NULL; + } + result->context = context; + result->current_req = NULL; + result->pending_cb = 0; + result->resolver_type = context->resolution_type; + + /* create the initial network request */ + net_req = network_req_new(context, name, request_type, + extensions, transaction_id); + if (!net_req) { + dns_req_free(context, result); + result = NULL; + } + + result->current_req = net_req; + net_req->owner = result; + + return result; +} + +static getdns_return_t dict_to_sockaddr(getdns_dict* ns, struct sockaddr_storage* output) { + struct getdns_bindata *address_type = NULL; + struct getdns_bindata *address_data = NULL; + uint16_t port = htons(53); + memset(output, 0, sizeof(struct sockaddr_storage)); + output->ss_family = AF_UNSPEC; + + getdns_dict_get_bindata(ns, GETDNS_STR_ADDRESS_TYPE, &address_type); + getdns_dict_get_bindata(ns, GETDNS_STR_ADDRESS_DATA, &address_data); + if (!address_type || !address_data) { + return GETDNS_RETURN_GENERIC_ERROR; + } + if (strcmp((char*) address_type->data, GETDNS_STR_IPV4)) { + /* data is an in_addr_t */ + struct sockaddr_in* addr = (struct sockaddr_in*) output; + addr->sin_family = AF_INET; + addr->sin_port = port; + memcpy(&(addr->sin_addr), address_data->data, address_data->size); + } else { + /* data is a v6 addr in host order */ + struct sockaddr_in6* addr = (struct sockaddr_in6*) output; + addr->sin6_family = AF_INET6; + addr->sin6_port = port; + memcpy(&(addr->sin6_addr), address_data->data, address_data->size); + } + return GETDNS_RETURN_GOOD; +} + +/* submit a new request to the event loop */ +static getdns_return_t submit_new_dns_req(getdns_dns_req *request) { + getdns_dict *nameserver = NULL; + getdns_context_t context = request->context; + struct sockaddr_storage sockdata; + + /* get first upstream server */ + getdns_list_get_dict(context->upstream_list, 0, &nameserver); + if (!nameserver) { + return GETDNS_RETURN_GENERIC_ERROR; + } + + /* setup socket */ + if (dict_to_sockaddr(nameserver, &sockdata) != GETDNS_RETURN_GOOD) { + return GETDNS_RETURN_GENERIC_ERROR; + } + evutil_socket_t sock = socket(sockdata.ss_family, SOCK_DGRAM, 0); + evutil_make_socket_closeonexec(sock); + evutil_make_socket_nonblocking(sock); + + return GETDNS_RETURN_GOOD; +} + + /* * getdns_general */ @@ -69,17 +312,31 @@ getdns_general( if (transaction_id != NULL) { *transaction_id = 0; } - if (context->event_base == NULL || - callback == NULL) { + if (!context || context->event_base == NULL || + callback == NULL || + context->resolution_type != GETDNS_CONTEXT_STUB) { /* Can't do async without an event loop * or callback + * + * Only supports stub right now. */ + return GETDNS_RETURN_BAD_CONTEXT; + } + + + /* create a req */ + getdns_dns_req *dns_req = dns_req_new(context, name, request_type, + extensions, transaction_id); + if (dns_req == NULL) { return GETDNS_RETURN_GENERIC_ERROR; } + + dns_req->user_callback = callback; + dns_req->user_pointer = userarg; + + /* submit it */ + submit_new_dns_req(dns_req); - UNUSED_PARAM(name); - UNUSED_PARAM(request_type); - UNUSED_PARAM(extensions); UNUSED_PARAM(userarg); return GETDNS_RETURN_GOOD; } /* getdns_general */ diff --git a/src/common/getdns_libevent.h b/src/common/getdns_libevent.h index d5a17a93..1db26e7d 100644 --- a/src/common/getdns_libevent.h +++ b/src/common/getdns_libevent.h @@ -1,4 +1,5 @@ -#include + +#include #include /* For libevent, which we are using for these examples */ diff --git a/src/test/tests_list.c b/src/test/tests_list.c index 656b58b7..1f0aa06f 100644 --- a/src/test/tests_list.c +++ b/src/test/tests_list.c @@ -45,7 +45,7 @@ void tst_bindatasetget(void) { char msg[TSTMSGBUF]; - size_t index; + size_t index = 0; getdns_return_t retval; struct getdns_list *list = NULL; struct getdns_bindata *new_bindata = NULL; @@ -123,7 +123,7 @@ void tst_dictsetget(void) { char msg[TSTMSGBUF]; - size_t index; + size_t index = 0; uint32_t ans_int; getdns_return_t retval; struct getdns_list *list = NULL; @@ -199,7 +199,7 @@ void tst_listsetget(void) { char msg[TSTMSGBUF]; - size_t index; + size_t index = 0; getdns_return_t retval; uint32_t ans_int; struct getdns_list *list = NULL; @@ -276,7 +276,7 @@ void tst_intsetget(void) { char msg[TSTMSGBUF]; - size_t index; + size_t index = 0; uint32_t ans_int; getdns_return_t retval; struct getdns_list *list = NULL;