Miscelaneous fixes that came out of the unit tests

TODO: libuv still has issues.  Do we really need a close callback?
This commit is contained in:
Willem Toorop 2014-10-15 01:13:39 +02:00
parent 768d8fbf4d
commit a1be0c985d
19 changed files with 185 additions and 65 deletions

View File

@ -98,14 +98,14 @@ UTIL_OBJ=mini_event.lo rbtree.lo
.c.lo: .c.lo:
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $< -o $@ $(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $< -o $@
$(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) libmini_event.lo:
@:
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $< -o $@
default: all default: all
all: libgetdns.la $(EXTENSION_LIBEVENT_LIB) $(EXTENSION_LIBUV_LIB) $(EXTENSION_LIBEV_LIB) all: libgetdns.la $(EXTENSION_LIBEVENT_LIB) $(EXTENSION_LIBUV_LIB) $(EXTENSION_LIBEV_LIB)
$(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) libmini_event.lo:
@:
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $< -o $@
install: libgetdns.la install: libgetdns.la
$(INSTALL) -m 755 -d $(DESTDIR)$(includedir) $(INSTALL) -m 755 -d $(DESTDIR)$(includedir)
$(INSTALL) -m 755 -d $(DESTDIR)$(includedir)/getdns $(INSTALL) -m 755 -d $(DESTDIR)$(includedir)/getdns

View File

@ -260,7 +260,7 @@ upstreams_resize(getdns_upstreams *upstreams, size_t size)
static void static void
upstreams_dereference(getdns_upstreams *upstreams) upstreams_dereference(getdns_upstreams *upstreams)
{ {
if (--upstreams->referenced == 0) if (upstreams && --upstreams->referenced == 0)
GETDNS_FREE(upstreams->mf, upstreams); GETDNS_FREE(upstreams->mf, upstreams);
} }
@ -583,6 +583,7 @@ getdns_context_create_with_extended_memory_functions(
result->suffix = NULL; result->suffix = NULL;
result->dnssec_trust_anchors = NULL; result->dnssec_trust_anchors = NULL;
result->upstreams = NULL;
result->edns_extended_rcode = 0; result->edns_extended_rcode = 0;
result->edns_version = 0; result->edns_version = 0;
@ -599,7 +600,7 @@ getdns_context_create_with_extended_memory_functions(
goto error; goto error;
result->dnssec_allowed_skew = 0; result->dnssec_allowed_skew = 0;
result->edns_maximum_udp_payload_size = 512; result->edns_maximum_udp_payload_size = 1232;
result->dns_transport = GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP; result->dns_transport = GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP;
result->limit_outstanding_queries = 0; result->limit_outstanding_queries = 0;
result->has_ta = priv_getdns_parse_ta_file(NULL, NULL); result->has_ta = priv_getdns_parse_ta_file(NULL, NULL);
@ -754,14 +755,26 @@ set_ub_number_opt(struct getdns_context *ctx, char *opt, uint16_t value)
static void static void
getdns_context_request_count_changed(getdns_context *context) getdns_context_request_count_changed(getdns_context *context)
{ {
if (context->outbound_requests->count && !context->ub_event.ev) DEBUG_SCHED("getdns_context_request_count_changed(%d)\n",
(int) context->outbound_requests->count);
if (context->outbound_requests->count) {
if (context->ub_event.ev) return;
DEBUG_SCHED("gc_request_count_changed "
"-> ub schedule(el_ev = %p, el_ev->ev = %p)\n",
&context->ub_event, context->ub_event.ev);
context->extension->vmt->schedule( context->extension->vmt->schedule(
context->extension, ub_fd(context->unbound_ctx), context->extension, ub_fd(context->unbound_ctx),
TIMEOUT_FOREVER, &context->ub_event); TIMEOUT_FOREVER, &context->ub_event);
}
else if (context->ub_event.ev) /* Only test if count == 0! */ {
DEBUG_SCHED("gc_request_count_changed "
"-> ub clear(el_ev = %p, el_ev->ev = %p)\n",
&context->ub_event, context->ub_event.ev);
else if (context->ub_event.ev)
context->extension->vmt->clear( context->extension->vmt->clear(
context->extension, &context->ub_event); context->extension, &context->ub_event);
}
} }
static void static void
@ -769,8 +782,20 @@ getdns_context_ub_read_cb(void *userarg)
{ {
getdns_context *context = (getdns_context *)userarg; getdns_context *context = (getdns_context *)userarg;
if (getdns_context_process_async(context)) return; /* getdns_context_process_async, but without reinvoking an eventloop
(void) getdns_context_get_num_pending_requests(context, NULL); * (with context->extension->vmt->run*), because we are already
* called from a running eventloop.
*/
context->processing = 1;
if (ub_poll(context->unbound_ctx) && ub_process(context->unbound_ctx)){
/* need an async return code? */
context->processing = 0;
return;
}
context->processing = 0;
/* No need to handle timeouts. They are handled by the extension. */
getdns_context_request_count_changed(context); getdns_context_request_count_changed(context);
} }
@ -800,10 +825,11 @@ rebuild_ub_ctx(struct getdns_context* context) {
context->unbound_ctx, TRUST_ANCHOR_FILE); context->unbound_ctx, TRUST_ANCHOR_FILE);
} }
context->ub_event.userarg = context; context->ub_event.userarg = context;
context->ub_event.read_cb = getdns_context_ub_read_cb; context->ub_event.read_cb = getdns_context_ub_read_cb;
context->ub_event.write_cb = NULL; context->ub_event.write_cb = NULL;
context->ub_event.timeout_cb = NULL; context->ub_event.timeout_cb = NULL;
context->ub_event.ev = NULL;
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} }
@ -1300,7 +1326,7 @@ invalid_parameter:
r = GETDNS_RETURN_INVALID_PARAMETER; r = GETDNS_RETURN_INVALID_PARAMETER;
error: error:
upstreams_dereference(upstreams); upstreams_dereference(upstreams);
return r; return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
} /* getdns_context_set_upstream_recursive_servers */ } /* getdns_context_set_upstream_recursive_servers */
@ -1491,6 +1517,24 @@ getdns_context_cancel_request(struct getdns_context *context,
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} }
/*
* getdns_cancel_callback
*
*/
getdns_return_t
getdns_cancel_callback(getdns_context *context,
getdns_transaction_t transaction_id)
{
if (!context)
return GETDNS_RETURN_INVALID_PARAMETER;
context->processing = 1;
getdns_return_t r = getdns_context_cancel_request(context, transaction_id, 1);
context->processing = 0;
getdns_context_request_count_changed(context);
return r;
} /* getdns_cancel_callback */
static getdns_return_t static getdns_return_t
ub_setup_stub(struct ub_ctx *ctx, getdns_upstreams *upstreams) ub_setup_stub(struct ub_ctx *ctx, getdns_upstreams *upstreams)
{ {
@ -1803,6 +1847,8 @@ uint32_t
getdns_context_get_num_pending_requests(struct getdns_context* context, getdns_context_get_num_pending_requests(struct getdns_context* context,
struct timeval* next_timeout) struct timeval* next_timeout)
{ {
struct timeval dispose;
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
if (context->outbound_requests->count) if (context->outbound_requests->count)
@ -1810,7 +1856,7 @@ getdns_context_get_num_pending_requests(struct getdns_context* context,
/* TODO: Remove this when next_timeout is gone */ /* TODO: Remove this when next_timeout is gone */
getdns_handle_timeouts(context->mini_event.base, getdns_handle_timeouts(context->mini_event.base,
&context->mini_event.time_tv, next_timeout); &context->mini_event.time_tv, next_timeout ? next_timeout : &dispose);
return context->outbound_requests->count; return context->outbound_requests->count;
} }
@ -1836,7 +1882,9 @@ getdns_context_process_async(struct getdns_context* context)
void void
getdns_context_run(getdns_context *context) getdns_context_run(getdns_context *context)
{ {
context->extension->vmt->run(context->extension); if (getdns_context_get_num_pending_requests(context, NULL) > 0 &&
!getdns_context_process_async(context))
context->extension->vmt->run(context->extension);
} }
typedef struct timeout_accumulator { typedef struct timeout_accumulator {

View File

@ -106,7 +106,7 @@ getdns_libev_write_cb(struct ev_loop *l, struct ev_io *io, int revents)
{ {
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)io->data; getdns_eventloop_event *el_ev = (getdns_eventloop_event *)io->data;
assert(el_ev->write_cb); assert(el_ev->write_cb);
el_ev->read_cb(el_ev->userarg); el_ev->write_cb(el_ev->userarg);
} }
static void static void
@ -169,20 +169,18 @@ getdns_extension_set_libev_loop(getdns_context *context,
getdns_libev_run_once getdns_libev_run_once
}; };
getdns_libev *ext; getdns_libev *ext;
getdns_return_t r;
if (!context) if (!context)
return GETDNS_RETURN_BAD_CONTEXT; return GETDNS_RETURN_BAD_CONTEXT;
if (!loop) if (!loop)
return GETDNS_RETURN_INVALID_PARAMETER; return GETDNS_RETURN_INVALID_PARAMETER;
if ((r = getdns_context_detach_eventloop(context)))
return r;
ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), getdns_libev); ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), getdns_libev);
if (!ext)
return GETDNS_RETURN_MEMORY_ERROR;
ext->vmt = &getdns_libev_vmt; ext->vmt = &getdns_libev_vmt;
ext->loop = loop; ext->loop = loop;
ext->mf = *priv_getdns_context_mf(context); ext->mf = *priv_getdns_context_mf(context);
return getdns_context_set_eventloop(context, (getdns_eventloop *)&ext); return getdns_context_set_eventloop(context, (getdns_eventloop *)ext);
} }

View File

@ -177,20 +177,19 @@ getdns_extension_set_libevent_base(getdns_context *context,
getdns_libevent_run_once getdns_libevent_run_once
}; };
getdns_libevent *ext; getdns_libevent *ext;
getdns_return_t r;
if (!context) if (!context)
return GETDNS_RETURN_BAD_CONTEXT; return GETDNS_RETURN_BAD_CONTEXT;
if (!base) if (!base)
return GETDNS_RETURN_INVALID_PARAMETER; return GETDNS_RETURN_INVALID_PARAMETER;
if ((r = getdns_context_detach_eventloop(context)))
return r;
ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), getdns_libevent); ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), getdns_libevent);
if (!ext)
return GETDNS_RETURN_MEMORY_ERROR;
ext->vmt = &getdns_libevent_vmt; ext->vmt = &getdns_libevent_vmt;
ext->base = base; ext->base = base;
ext->mf = *priv_getdns_context_mf(context); ext->mf = *priv_getdns_context_mf(context);
return getdns_context_set_eventloop(context, (getdns_eventloop *)&ext); return getdns_context_set_eventloop(context, (getdns_eventloop *)ext);
} }

View File

@ -107,19 +107,20 @@ getdns_mini_event_run_once(getdns_eventloop *loop, int blocking)
static getdns_return_t static getdns_return_t
getdns_mini_event_clear(getdns_eventloop *loop, getdns_eventloop_event *el_ev) getdns_mini_event_clear(getdns_eventloop *loop, getdns_eventloop_event *el_ev)
{ {
getdns_return_t r;
getdns_mini_event *ext = (getdns_mini_event *)loop; getdns_mini_event *ext = (getdns_mini_event *)loop;
assert(el_ev->ev); assert(el_ev->ev);
if (getdns_event_del(el_ev->ev) != 0) if (getdns_event_del(el_ev->ev) != 0)
return GETDNS_RETURN_GENERIC_ERROR; r = GETDNS_RETURN_GENERIC_ERROR;
GETDNS_FREE(ext->mf, el_ev->ev); GETDNS_FREE(ext->mf, el_ev->ev);
el_ev->ev = NULL; el_ev->ev = NULL;
ext->n_events--; ext->n_events--;
return GETDNS_RETURN_GOOD; return r;
} }
static void static void

View File

@ -75,6 +75,8 @@ getdns_libuv_clear(getdns_eventloop *loop, getdns_eventloop_event *el_ev)
assert(my_ev); assert(my_ev);
DEBUG_SCHED("enter libuv_clear(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
if (el_ev->read_cb) { if (el_ev->read_cb) {
uv_poll_stop(&my_ev->read); uv_poll_stop(&my_ev->read);
uv_close((uv_handle_t *)&my_ev->read, NULL); uv_close((uv_handle_t *)&my_ev->read, NULL);
@ -83,12 +85,13 @@ getdns_libuv_clear(getdns_eventloop *loop, getdns_eventloop_event *el_ev)
uv_poll_stop(&my_ev->write); uv_poll_stop(&my_ev->write);
uv_close((uv_handle_t *)&my_ev->write, NULL); uv_close((uv_handle_t *)&my_ev->write, NULL);
} }
if (el_ev->timeout_cb) if (el_ev->timeout_cb) {
uv_timer_stop(&my_ev->timer); uv_timer_stop(&my_ev->timer);
uv_close((uv_handle_t *)&my_ev->timer, NULL); uv_close((uv_handle_t *)&my_ev->timer, NULL);
}
GETDNS_FREE(ext->mf, el_ev->ev); GETDNS_FREE(ext->mf, el_ev->ev);
el_ev->ev = NULL; el_ev->ev = NULL;
DEBUG_SCHED("exit libuv_clear(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} }
@ -97,7 +100,9 @@ getdns_libuv_read_cb(uv_poll_t *poll, int status, int events)
{ {
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)poll->data; getdns_eventloop_event *el_ev = (getdns_eventloop_event *)poll->data;
assert(el_ev->read_cb); assert(el_ev->read_cb);
DEBUG_SCHED("enter libuv_read_cb(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
el_ev->read_cb(el_ev->userarg); el_ev->read_cb(el_ev->userarg);
DEBUG_SCHED("exit libuv_read_cb(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
} }
static void static void
@ -105,7 +110,9 @@ getdns_libuv_write_cb(uv_poll_t *poll, int status, int events)
{ {
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)poll->data; getdns_eventloop_event *el_ev = (getdns_eventloop_event *)poll->data;
assert(el_ev->write_cb); assert(el_ev->write_cb);
DEBUG_SCHED("enter libuv_write_cb(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
el_ev->write_cb(el_ev->userarg); el_ev->write_cb(el_ev->userarg);
DEBUG_SCHED("exit libuv_write_cb(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
} }
static void static void
@ -113,7 +120,9 @@ getdns_libuv_timeout_cb(uv_timer_t *timer, int status)
{ {
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)timer->data; getdns_eventloop_event *el_ev = (getdns_eventloop_event *)timer->data;
assert(el_ev->timeout_cb); assert(el_ev->timeout_cb);
DEBUG_SCHED("enter libuv_timeout_cb(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
el_ev->timeout_cb(el_ev->userarg); el_ev->timeout_cb(el_ev->userarg);
DEBUG_SCHED("exit libuv_timeout_cb(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
} }
static getdns_return_t static getdns_return_t
@ -129,6 +138,8 @@ getdns_libuv_schedule(getdns_eventloop *loop,
assert(!(el_ev->read_cb || el_ev->write_cb) || fd >= 0); assert(!(el_ev->read_cb || el_ev->write_cb) || fd >= 0);
assert( el_ev->read_cb || el_ev->write_cb || el_ev->timeout_cb); assert( el_ev->read_cb || el_ev->write_cb || el_ev->timeout_cb);
DEBUG_SCHED("enter libuv_schedule(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
if (!(my_ev = GETDNS_MALLOC(ext->mf, poll_timer))) if (!(my_ev = GETDNS_MALLOC(ext->mf, poll_timer)))
return GETDNS_RETURN_MEMORY_ERROR; return GETDNS_RETURN_MEMORY_ERROR;
@ -152,6 +163,7 @@ getdns_libuv_schedule(getdns_eventloop *loop,
my_timer->data = el_ev; my_timer->data = el_ev;
uv_timer_start(my_timer, getdns_libuv_timeout_cb, timeout, 0); uv_timer_start(my_timer, getdns_libuv_timeout_cb, timeout, 0);
} }
DEBUG_SCHED("exit libuv_schedule(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} }
@ -166,20 +178,18 @@ getdns_extension_set_libuv_loop(getdns_context *context, uv_loop_t *loop)
getdns_libuv_run_once getdns_libuv_run_once
}; };
getdns_libuv *ext; getdns_libuv *ext;
getdns_return_t r;
if (!context) if (!context)
return GETDNS_RETURN_BAD_CONTEXT; return GETDNS_RETURN_BAD_CONTEXT;
if (!loop) if (!loop)
return GETDNS_RETURN_INVALID_PARAMETER; return GETDNS_RETURN_INVALID_PARAMETER;
if ((r = getdns_context_detach_eventloop(context)))
return r;
ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), getdns_libuv); ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), getdns_libuv);
if (!ext)
return GETDNS_RETURN_MEMORY_ERROR;
ext->vmt = &getdns_libuv_vmt; ext->vmt = &getdns_libuv_vmt;
ext->loop = loop; ext->loop = loop;
ext->mf = *priv_getdns_context_mf(context); ext->mf = *priv_getdns_context_mf(context);
return getdns_context_set_eventloop(context, (getdns_eventloop *)&ext); return getdns_context_set_eventloop(context, (getdns_eventloop *)ext);
} }

View File

@ -126,7 +126,7 @@ ub_resolve_callback(void* arg, int err, struct ub_result* ub_res)
// char *bogus) // char *bogus)
{ {
getdns_network_req *netreq = (getdns_network_req *) arg; getdns_network_req *netreq = (getdns_network_req *) arg;
getdns_dns_req *dnsreq = netreq->owner; getdns_dns_req *dns_req = netreq->owner;
netreq->state = NET_REQ_FINISHED; netreq->state = NET_REQ_FINISHED;
if (err != 0) { if (err != 0) {
@ -141,14 +141,14 @@ ub_resolve_callback(void* arg, int err, struct ub_result* ub_res)
} }
ub_resolve_free(ub_res); ub_resolve_free(ub_res);
netreq = dnsreq->first_req; netreq = dns_req->first_req;
while (netreq) { while (netreq) {
if (netreq->state != NET_REQ_FINISHED && if (netreq->state != NET_REQ_FINISHED &&
netreq->state != NET_REQ_CANCELED) netreq->state != NET_REQ_CANCELED)
return; return;
netreq = netreq->next; netreq = netreq->next;
} }
handle_dns_request_complete(dnsreq); handle_dns_request_complete(dns_req);
} /* ub_resolve_callback */ } /* ub_resolve_callback */
getdns_return_t getdns_return_t
@ -163,7 +163,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
getdns_dict *localnames_response; getdns_dict *localnames_response;
size_t i; size_t i;
if (!context || !name) if (!context || !name || !callbackfn)
return GETDNS_RETURN_INVALID_PARAMETER; return GETDNS_RETURN_INVALID_PARAMETER;
if ((r = validate_dname(name))) if ((r = validate_dname(name)))
@ -210,18 +210,19 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
if (context->namespaces[i] == GETDNS_NAMESPACE_LOCALNAMES) { if (context->namespaces[i] == GETDNS_NAMESPACE_LOCALNAMES) {
if (!(r = getdns_context_local_namespace_resolve( if (!(r = getdns_context_local_namespace_resolve(
req, &localnames_response, context))) req, &localnames_response, context))) {
priv_getdns_call_user_callback priv_getdns_call_user_callback
( req, localnames_response); ( req, localnames_response);
break; break;
}
} else if (context->namespaces[i] == GETDNS_NAMESPACE_DNS) { } else if (context->namespaces[i] == GETDNS_NAMESPACE_DNS) {
/* TODO: We will get a good return code here even if /* TODO: We will get a good return code here even if
the name is not found (NXDOMAIN). We should consider the name is not found (NXDOMAIN). We should consider
if this means we go onto the next namespace instead if this means we go onto the next namespace instead
of returning */ of returning */
r = GETDNS_RETURN_GOOD;
netreq = req->first_req; netreq = req->first_req;
while (!r && netreq) { while (!r && netreq) {
r = submit_network_request(netreq); r = submit_network_request(netreq);
@ -289,6 +290,7 @@ getdns_general(getdns_context *context,
void *userarg, getdns_transaction_t * transaction_id, void *userarg, getdns_transaction_t * transaction_id,
getdns_callback_t callback) getdns_callback_t callback)
{ {
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
return getdns_general_loop(context, context->extension, return getdns_general_loop(context, context->extension,
name, request_type, extensions, name, request_type, extensions,
userarg, transaction_id, callback); userarg, transaction_id, callback);
@ -304,6 +306,7 @@ getdns_address(getdns_context *context,
const char *name, getdns_dict *extensions, void *userarg, const char *name, getdns_dict *extensions, void *userarg,
getdns_transaction_t *transaction_id, getdns_callback_t callback) getdns_transaction_t *transaction_id, getdns_callback_t callback)
{ {
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
return getdns_address_loop(context, context->extension, return getdns_address_loop(context, context->extension,
name, extensions, userarg, name, extensions, userarg,
transaction_id, callback); transaction_id, callback);

View File

@ -96,6 +96,7 @@ getdns_hostname(getdns_context *context,
getdns_dict *address, getdns_dict *extensions, void *userarg, getdns_dict *address, getdns_dict *extensions, void *userarg,
getdns_transaction_t *transaction_id, getdns_callback_t callback) getdns_transaction_t *transaction_id, getdns_callback_t callback)
{ {
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
return getdns_hostname_loop(context, context->extension, return getdns_hostname_loop(context, context->extension,
address, extensions, userarg, transaction_id, callback); address, extensions, userarg, transaction_id, callback);
} /* getdns_hostname */ } /* getdns_hostname */

View File

@ -98,3 +98,5 @@ getdns_context_process_async
getdns_context_set_eventloop getdns_context_set_eventloop
getdns_context_detach_eventloop getdns_context_detach_eventloop
getdns_context_run getdns_context_run
plain_mem_funcs_user_arg
priv_getdns_context_mf

View File

@ -8,6 +8,8 @@ write_symbols() {
} }
write_symbols libgetdns.symbols getdns/getdns.h.in getdns/getdns_extra.h write_symbols libgetdns.symbols getdns/getdns.h.in getdns/getdns_extra.h
echo plain_mem_funcs_user_arg >> libgetdns.symbols
echo priv_getdns_context_mf >> libgetdns.symbols
write_symbols extension/libevent.symbols getdns/getdns_ext_libevent.h write_symbols extension/libevent.symbols getdns/getdns_ext_libevent.h
write_symbols extension/libev.symbols getdns/getdns_ext_libev.h write_symbols extension/libev.symbols getdns/getdns_ext_libev.h
write_symbols extension/libuv.symbols getdns/getdns_ext_libuv.h write_symbols extension/libuv.symbols getdns/getdns_ext_libuv.h

View File

@ -125,7 +125,7 @@ dns_req_new(struct getdns_context *context, getdns_eventloop *loop,
result->canceled = 0; result->canceled = 0;
result->current_req = NULL; result->current_req = NULL;
result->first_req = NULL; result->first_req = NULL;
result->trans_id = (((uint64_t) ldns_get_random()) << 32) result->trans_id = ((uint64_t) ldns_get_random())
^ ((intptr_t) result); ^ ((intptr_t) result);
getdns_dict_copy(extensions, &result->extensions); getdns_dict_copy(extensions, &result->extensions);

View File

@ -60,6 +60,7 @@ getdns_service(getdns_context *context,
const char *name, getdns_dict *extensions, void *userarg, const char *name, getdns_dict *extensions, void *userarg,
getdns_transaction_t *transaction_id, getdns_callback_t callback) getdns_transaction_t *transaction_id, getdns_callback_t callback)
{ {
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
return getdns_service_loop(context, context->extension, return getdns_service_loop(context, context->extension,
name, extensions, userarg, transaction_id, callback); name, extensions, userarg, transaction_id, callback);
} /* getdns_service */ } /* getdns_service */

View File

@ -118,6 +118,10 @@ query_ns(stub_resolver *resolver)
*/ */
/* TODO: Check how to connect first (udp or tcp) */ /* TODO: Check how to connect first (udp or tcp) */
if (resolver->context->dns_transport != GETDNS_TRANSPORT_UDP_ONLY &&
resolver->context->dns_transport !=
GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP)
return GETDNS_RETURN_GENERIC_ERROR;
resolver->udp_fd = socket(upstream->addr.ss_family, SOCK_DGRAM, resolver->udp_fd = socket(upstream->addr.ss_family, SOCK_DGRAM,
IPPROTO_UDP); IPPROTO_UDP);

View File

@ -72,6 +72,9 @@ default: all
all: $(PROGRAMS) all: $(PROGRAMS)
check_getdns_libuv.lo: check_getdns_libuv.c
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -D_GNU_SOURCE -c $< -o $@
tests_dict: tests_dict.lo testmessages.lo tests_dict: tests_dict.lo testmessages.lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ tests_dict.lo testmessages.lo $(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ tests_dict.lo testmessages.lo

View File

@ -201,8 +201,7 @@
void verify_getdns_address_7(struct extracted_response *ex_response) void verify_getdns_address_7(struct extracted_response *ex_response)
{ {
assert_noerror(ex_response); assert_address_in_just_address_answers(ex_response);
assert_address_in_answer(ex_response, TRUE, TRUE);
} }
START_TEST (getdns_address_8) START_TEST (getdns_address_8)

View File

@ -49,10 +49,22 @@ int event_loop_type = 0;
*/ */
void extract_response(struct getdns_dict *response, struct extracted_response *ex_response) void extract_response(struct getdns_dict *response, struct extracted_response *ex_response)
{ {
ck_assert_msg(response != NULL, "Response should not be NULL"); int have_answer_type = 0;
ASSERT_RC(getdns_dict_get_int(response, "answer_type", &ex_response->top_answer_type), ck_assert_msg(response != NULL, "Response should not be NULL");
GETDNS_RETURN_GOOD, "Failed to extract \"top answer_type\""); /* fprintf(stderr, "%s\n", getdns_pretty_print_dict(response)); */
/* answer_type is optional. See spec section 4:
* "The top level of replies_tree can optionally have the following names:
* canonical_name (a bindata), intermediate_aliases (a list),
* answer_ipv4_address (a bindata), answer_ipv6_address (a bindata),
* and answer_type (an int)."
*
* If it is absent, do not try to decompose the replies_tree, because the
* answer most likely came not from DNS.
*/
have_answer_type = getdns_dict_get_int(response, "answer_type", &ex_response->top_answer_type) ==
GETDNS_RETURN_GOOD;
ASSERT_RC(getdns_dict_get_bindata(response, "canonical_name", &ex_response->top_canonical_name), ASSERT_RC(getdns_dict_get_bindata(response, "canonical_name", &ex_response->top_canonical_name),
GETDNS_RETURN_GOOD, "Failed to extract \"top canonical_name\""); GETDNS_RETURN_GOOD, "Failed to extract \"top canonical_name\"");
@ -69,6 +81,21 @@ void extract_response(struct getdns_dict *response, struct extracted_response *e
GETDNS_RETURN_GOOD, "Failed to extract \"replies_tree\""); GETDNS_RETURN_GOOD, "Failed to extract \"replies_tree\"");
ck_assert_msg(ex_response->replies_tree != NULL, "replies_tree should not be NULL"); ck_assert_msg(ex_response->replies_tree != NULL, "replies_tree should not be NULL");
ASSERT_RC(getdns_dict_get_int(response, "status", &ex_response->status),
GETDNS_RETURN_GOOD, "Failed to extract \"status\"");
if (!have_answer_type || ex_response->top_answer_type != GETDNS_NAMETYPE_DNS) {
ex_response->replies_tree_sub_dict = NULL;
ex_response->additional = NULL;
ex_response->answer = NULL;
ex_response->answer_type = 0;
ex_response->authority = NULL;
ex_response->canonical_name = NULL;
ex_response->header = NULL;
ex_response->question = NULL;
return;
}
ASSERT_RC(getdns_list_get_dict(ex_response->replies_tree, 0, &ex_response->replies_tree_sub_dict), ASSERT_RC(getdns_list_get_dict(ex_response->replies_tree, 0, &ex_response->replies_tree_sub_dict),
GETDNS_RETURN_GOOD, "Failed to extract \"replies_tree[0]\""); GETDNS_RETURN_GOOD, "Failed to extract \"replies_tree[0]\"");
ck_assert_msg(ex_response->replies_tree_sub_dict != NULL, "replies_tree[0] dict should not be NULL"); ck_assert_msg(ex_response->replies_tree_sub_dict != NULL, "replies_tree[0] dict should not be NULL");
@ -98,9 +125,6 @@ void extract_response(struct getdns_dict *response, struct extracted_response *e
ASSERT_RC(getdns_dict_get_dict(ex_response->replies_tree_sub_dict, "question", &ex_response->question), ASSERT_RC(getdns_dict_get_dict(ex_response->replies_tree_sub_dict, "question", &ex_response->question),
GETDNS_RETURN_GOOD, "Failed to extract \"question\""); GETDNS_RETURN_GOOD, "Failed to extract \"question\"");
ck_assert_msg(ex_response->question != NULL, "question should not be NULL"); ck_assert_msg(ex_response->question != NULL, "question should not be NULL");
ASSERT_RC(getdns_dict_get_int(response, "status", &ex_response->status),
GETDNS_RETURN_GOOD, "Failed to extract \"status\"");
} }
/* /*
@ -195,6 +219,19 @@ void assert_address_in_answer(struct extracted_response *ex_response, int a, int
ancount, address_records); ancount, address_records);
} }
/*
* assert_address_in_just_address_answers asserts that just_address_answers
* contains at least one address.
*/
void assert_address_in_just_address_answers(struct extracted_response *ex_response)
{
size_t length;
ASSERT_RC(getdns_list_get_length(ex_response->just_address_answers, &length),
GETDNS_RETURN_GOOD, "Failed to extract \"just_address_answers\" length");
ck_assert_msg(length > 0, "Expected \"just_address_answers\" length > 0, got %d", length);
}
/* /*
* assert_nxdomain asserts that an NXDOMAIN response was * assert_nxdomain asserts that an NXDOMAIN response was
* was returned for the DNS query meaning: * was returned for the DNS query meaning:

View File

@ -183,6 +183,12 @@
*/ */
void assert_address_in_answer(struct extracted_response *ex_response, int a, int aaaa); void assert_address_in_answer(struct extracted_response *ex_response, int a, int aaaa);
/*
* assert_address_in_just_address_answers asserts that
* just_address_answers contains at least one address.
*/
void assert_address_in_just_address_answers(struct extracted_response *ex_response);
/* /*
* assert_nxdomain asserts that an NXDOMAIN response was * assert_nxdomain asserts that an NXDOMAIN response was
* was returned for the DNS query meaning rcode == 3. * was returned for the DNS query meaning rcode == 3.

View File

@ -37,21 +37,9 @@
#include "getdns/getdns_extra.h" #include "getdns/getdns_extra.h"
void run_event_loop_impl(struct getdns_context* context, void* eventloop) { void run_event_loop_impl(struct getdns_context* context, void* eventloop) {
struct timeval tv; getdns_context_run(context);
while (getdns_context_get_num_pending_requests(context, &tv) > 0) {
int fd = getdns_context_fd(context);
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(fd, &read_fds);
select(fd + 1, &read_fds, NULL, NULL, &tv);
if (getdns_context_process_async(context) != GETDNS_RETURN_GOOD) {
// context destroyed
break;
}
}
} }
void* create_eventloop_impl(struct getdns_context* context) { void* create_eventloop_impl(struct getdns_context* context) {
return NULL; return NULL;
} }

View File

@ -257,4 +257,22 @@ void dns_req_free(getdns_dns_req * req);
#endif #endif
#define SCHED_DEBUG 0
#if defined(SCHED_DEBUG) && SCHED_DEBUG
#include <time.h>
#define DEBUG_SCHED(...) do { \
struct timeval tv; \
struct tm tm; \
char buf[10]; \
\
gettimeofday(&tv, NULL); \
gmtime_r(&tv.tv_sec, &tm); \
strftime(buf, 10, "%T", &tm); \
fprintf(stderr, "[%s.%.6d] ", buf, (int)tv.tv_usec); \
fprintf(stderr, __VA_ARGS__); \
} while (false)
#else
#define DEBUG_SCHED(...) do {} while (false)
#endif
/* types-internal.h */ /* types-internal.h */