mirror of https://github.com/getdnsapi/getdns.git
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:
parent
768d8fbf4d
commit
a1be0c985d
|
@ -98,14 +98,14 @@ UTIL_OBJ=mini_event.lo rbtree.lo
|
|||
.c.lo:
|
||||
$(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
|
||||
|
||||
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) -m 755 -d $(DESTDIR)$(includedir)
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(includedir)/getdns
|
||||
|
|
|
@ -260,7 +260,7 @@ upstreams_resize(getdns_upstreams *upstreams, size_t size)
|
|||
static void
|
||||
upstreams_dereference(getdns_upstreams *upstreams)
|
||||
{
|
||||
if (--upstreams->referenced == 0)
|
||||
if (upstreams && --upstreams->referenced == 0)
|
||||
GETDNS_FREE(upstreams->mf, upstreams);
|
||||
}
|
||||
|
||||
|
@ -583,6 +583,7 @@ getdns_context_create_with_extended_memory_functions(
|
|||
result->suffix = NULL;
|
||||
|
||||
result->dnssec_trust_anchors = NULL;
|
||||
result->upstreams = NULL;
|
||||
|
||||
result->edns_extended_rcode = 0;
|
||||
result->edns_version = 0;
|
||||
|
@ -599,7 +600,7 @@ getdns_context_create_with_extended_memory_functions(
|
|||
goto error;
|
||||
|
||||
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->limit_outstanding_queries = 0;
|
||||
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
|
||||
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, ub_fd(context->unbound_ctx),
|
||||
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, &context->ub_event);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -769,8 +782,20 @@ getdns_context_ub_read_cb(void *userarg)
|
|||
{
|
||||
getdns_context *context = (getdns_context *)userarg;
|
||||
|
||||
if (getdns_context_process_async(context)) return;
|
||||
(void) getdns_context_get_num_pending_requests(context, NULL);
|
||||
/* getdns_context_process_async, but without reinvoking an eventloop
|
||||
* (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);
|
||||
}
|
||||
|
||||
|
@ -800,10 +825,11 @@ rebuild_ub_ctx(struct getdns_context* context) {
|
|||
context->unbound_ctx, TRUST_ANCHOR_FILE);
|
||||
}
|
||||
|
||||
context->ub_event.userarg = context;
|
||||
context->ub_event.read_cb = getdns_context_ub_read_cb;
|
||||
context->ub_event.write_cb = NULL;
|
||||
context->ub_event.userarg = context;
|
||||
context->ub_event.read_cb = getdns_context_ub_read_cb;
|
||||
context->ub_event.write_cb = NULL;
|
||||
context->ub_event.timeout_cb = NULL;
|
||||
context->ub_event.ev = NULL;
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
@ -1300,7 +1326,7 @@ invalid_parameter:
|
|||
r = GETDNS_RETURN_INVALID_PARAMETER;
|
||||
error:
|
||||
upstreams_dereference(upstreams);
|
||||
return r;
|
||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||
} /* getdns_context_set_upstream_recursive_servers */
|
||||
|
||||
|
||||
|
@ -1491,6 +1517,24 @@ getdns_context_cancel_request(struct getdns_context *context,
|
|||
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
|
||||
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,
|
||||
struct timeval* next_timeout)
|
||||
{
|
||||
struct timeval dispose;
|
||||
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
@ -1836,7 +1882,9 @@ getdns_context_process_async(struct getdns_context* context)
|
|||
void
|
||||
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 {
|
||||
|
|
|
@ -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;
|
||||
assert(el_ev->write_cb);
|
||||
el_ev->read_cb(el_ev->userarg);
|
||||
el_ev->write_cb(el_ev->userarg);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -169,20 +169,18 @@ getdns_extension_set_libev_loop(getdns_context *context,
|
|||
getdns_libev_run_once
|
||||
};
|
||||
getdns_libev *ext;
|
||||
getdns_return_t r;
|
||||
|
||||
if (!context)
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
if (!loop)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if ((r = getdns_context_detach_eventloop(context)))
|
||||
return r;
|
||||
|
||||
ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), getdns_libev);
|
||||
if (!ext)
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
ext->vmt = &getdns_libev_vmt;
|
||||
ext->loop = loop;
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -177,20 +177,19 @@ getdns_extension_set_libevent_base(getdns_context *context,
|
|||
getdns_libevent_run_once
|
||||
};
|
||||
getdns_libevent *ext;
|
||||
getdns_return_t r;
|
||||
|
||||
if (!context)
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
if (!base)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if ((r = getdns_context_detach_eventloop(context)))
|
||||
return r;
|
||||
|
||||
ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), getdns_libevent);
|
||||
if (!ext)
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
ext->vmt = &getdns_libevent_vmt;
|
||||
ext->base = base;
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -107,19 +107,20 @@ getdns_mini_event_run_once(getdns_eventloop *loop, int blocking)
|
|||
static getdns_return_t
|
||||
getdns_mini_event_clear(getdns_eventloop *loop, getdns_eventloop_event *el_ev)
|
||||
{
|
||||
getdns_return_t r;
|
||||
getdns_mini_event *ext = (getdns_mini_event *)loop;
|
||||
|
||||
assert(el_ev->ev);
|
||||
|
||||
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);
|
||||
el_ev->ev = NULL;
|
||||
|
||||
ext->n_events--;
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -75,6 +75,8 @@ getdns_libuv_clear(getdns_eventloop *loop, getdns_eventloop_event *el_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) {
|
||||
uv_poll_stop(&my_ev->read);
|
||||
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_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_close((uv_handle_t *)&my_ev->timer, NULL);
|
||||
|
||||
}
|
||||
GETDNS_FREE(ext->mf, el_ev->ev);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
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);
|
||||
DEBUG_SCHED("exit libuv_read_cb(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
DEBUG_SCHED("exit libuv_write_cb(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
DEBUG_SCHED("exit libuv_timeout_cb(el_ev = %p, el_ev->ev = %p)\n", el_ev, el_ev->ev);
|
||||
}
|
||||
|
||||
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 || 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)))
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
|
@ -152,6 +163,7 @@ getdns_libuv_schedule(getdns_eventloop *loop,
|
|||
my_timer->data = el_ev;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -166,20 +178,18 @@ getdns_extension_set_libuv_loop(getdns_context *context, uv_loop_t *loop)
|
|||
getdns_libuv_run_once
|
||||
};
|
||||
getdns_libuv *ext;
|
||||
getdns_return_t r;
|
||||
|
||||
if (!context)
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
if (!loop)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if ((r = getdns_context_detach_eventloop(context)))
|
||||
return r;
|
||||
|
||||
ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), getdns_libuv);
|
||||
if (!ext)
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
ext->vmt = &getdns_libuv_vmt;
|
||||
ext->loop = loop;
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ ub_resolve_callback(void* arg, int err, struct ub_result* ub_res)
|
|||
// char *bogus)
|
||||
{
|
||||
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;
|
||||
if (err != 0) {
|
||||
|
@ -141,14 +141,14 @@ ub_resolve_callback(void* arg, int err, struct ub_result* ub_res)
|
|||
}
|
||||
ub_resolve_free(ub_res);
|
||||
|
||||
netreq = dnsreq->first_req;
|
||||
netreq = dns_req->first_req;
|
||||
while (netreq) {
|
||||
if (netreq->state != NET_REQ_FINISHED &&
|
||||
netreq->state != NET_REQ_CANCELED)
|
||||
return;
|
||||
netreq = netreq->next;
|
||||
}
|
||||
handle_dns_request_complete(dnsreq);
|
||||
handle_dns_request_complete(dns_req);
|
||||
} /* ub_resolve_callback */
|
||||
|
||||
getdns_return_t
|
||||
|
@ -163,7 +163,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
getdns_dict *localnames_response;
|
||||
size_t i;
|
||||
|
||||
if (!context || !name)
|
||||
if (!context || !name || !callbackfn)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
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 (!(r = getdns_context_local_namespace_resolve(
|
||||
req, &localnames_response, context)))
|
||||
req, &localnames_response, context))) {
|
||||
|
||||
priv_getdns_call_user_callback
|
||||
( req, localnames_response);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
} else if (context->namespaces[i] == GETDNS_NAMESPACE_DNS) {
|
||||
|
||||
/* TODO: We will get a good return code here even if
|
||||
the name is not found (NXDOMAIN). We should consider
|
||||
if this means we go onto the next namespace instead
|
||||
of returning */
|
||||
|
||||
r = GETDNS_RETURN_GOOD;
|
||||
netreq = req->first_req;
|
||||
while (!r && netreq) {
|
||||
r = submit_network_request(netreq);
|
||||
|
@ -289,6 +290,7 @@ getdns_general(getdns_context *context,
|
|||
void *userarg, getdns_transaction_t * transaction_id,
|
||||
getdns_callback_t callback)
|
||||
{
|
||||
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
return getdns_general_loop(context, context->extension,
|
||||
name, request_type, extensions,
|
||||
userarg, transaction_id, callback);
|
||||
|
@ -304,6 +306,7 @@ getdns_address(getdns_context *context,
|
|||
const char *name, getdns_dict *extensions, void *userarg,
|
||||
getdns_transaction_t *transaction_id, getdns_callback_t callback)
|
||||
{
|
||||
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
return getdns_address_loop(context, context->extension,
|
||||
name, extensions, userarg,
|
||||
transaction_id, callback);
|
||||
|
|
|
@ -96,6 +96,7 @@ getdns_hostname(getdns_context *context,
|
|||
getdns_dict *address, getdns_dict *extensions, void *userarg,
|
||||
getdns_transaction_t *transaction_id, getdns_callback_t callback)
|
||||
{
|
||||
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
return getdns_hostname_loop(context, context->extension,
|
||||
address, extensions, userarg, transaction_id, callback);
|
||||
} /* getdns_hostname */
|
||||
|
|
|
@ -98,3 +98,5 @@ getdns_context_process_async
|
|||
getdns_context_set_eventloop
|
||||
getdns_context_detach_eventloop
|
||||
getdns_context_run
|
||||
plain_mem_funcs_user_arg
|
||||
priv_getdns_context_mf
|
||||
|
|
|
@ -8,6 +8,8 @@ write_symbols() {
|
|||
}
|
||||
|
||||
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/libev.symbols getdns/getdns_ext_libev.h
|
||||
write_symbols extension/libuv.symbols getdns/getdns_ext_libuv.h
|
||||
|
|
|
@ -125,7 +125,7 @@ dns_req_new(struct getdns_context *context, getdns_eventloop *loop,
|
|||
result->canceled = 0;
|
||||
result->current_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);
|
||||
|
||||
getdns_dict_copy(extensions, &result->extensions);
|
||||
|
|
|
@ -60,6 +60,7 @@ getdns_service(getdns_context *context,
|
|||
const char *name, getdns_dict *extensions, void *userarg,
|
||||
getdns_transaction_t *transaction_id, getdns_callback_t callback)
|
||||
{
|
||||
if (!context) return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
return getdns_service_loop(context, context->extension,
|
||||
name, extensions, userarg, transaction_id, callback);
|
||||
} /* getdns_service */
|
||||
|
|
|
@ -118,6 +118,10 @@ query_ns(stub_resolver *resolver)
|
|||
*/
|
||||
|
||||
/* 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,
|
||||
IPPROTO_UDP);
|
||||
|
|
|
@ -72,6 +72,9 @@ default: all
|
|||
|
||||
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
|
||||
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ tests_dict.lo testmessages.lo
|
||||
|
||||
|
|
|
@ -201,8 +201,7 @@
|
|||
|
||||
void verify_getdns_address_7(struct extracted_response *ex_response)
|
||||
{
|
||||
assert_noerror(ex_response);
|
||||
assert_address_in_answer(ex_response, TRUE, TRUE);
|
||||
assert_address_in_just_address_answers(ex_response);
|
||||
}
|
||||
|
||||
START_TEST (getdns_address_8)
|
||||
|
|
|
@ -49,10 +49,22 @@ int event_loop_type = 0;
|
|||
*/
|
||||
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),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"top answer_type\"");
|
||||
ck_assert_msg(response != NULL, "Response should not be NULL");
|
||||
/* 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),
|
||||
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\"");
|
||||
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),
|
||||
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");
|
||||
|
@ -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),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"question\"");
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* was returned for the DNS query meaning:
|
||||
|
|
|
@ -183,6 +183,12 @@
|
|||
*/
|
||||
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
|
||||
* was returned for the DNS query meaning rcode == 3.
|
||||
|
|
|
@ -37,21 +37,9 @@
|
|||
#include "getdns/getdns_extra.h"
|
||||
|
||||
void run_event_loop_impl(struct getdns_context* context, void* eventloop) {
|
||||
struct timeval tv;
|
||||
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;
|
||||
}
|
||||
}
|
||||
getdns_context_run(context);
|
||||
}
|
||||
|
||||
|
||||
void* create_eventloop_impl(struct getdns_context* context) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -257,4 +257,22 @@ void dns_req_free(getdns_dns_req * req);
|
|||
|
||||
#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 */
|
||||
|
|
Loading…
Reference in New Issue