Fix for TCP stub mode

Stupid mistake.
One can not clear an freshly "cleared" initialized event!
This commit is contained in:
Willem Toorop 2014-10-19 22:51:42 +02:00
parent fa02e3ae70
commit e9548fc5fb
5 changed files with 38 additions and 15 deletions

View File

@ -111,6 +111,7 @@ getdns_mini_event_clear(getdns_eventloop *loop, getdns_eventloop_event *el_ev)
getdns_mini_event *ext = (getdns_mini_event *)loop;
assert(el_ev->ev);
DEBUG_SCHED("1. getdns_mini_event_clear(loop: %p, el_ev: %p[userarg: %p, r: %p, w: %p, t: %p, ev: %p]); n_events: %d, times: %d\n", loop, el_ev, el_ev->userarg, el_ev->read_cb, el_ev->write_cb, el_ev->timeout_cb, el_ev->ev, (int)ext->n_events, (int)ext->base->times->count);
if (getdns_event_del(el_ev->ev) != 0)
r = GETDNS_RETURN_GENERIC_ERROR;
@ -119,6 +120,7 @@ getdns_mini_event_clear(getdns_eventloop *loop, getdns_eventloop_event *el_ev)
el_ev->ev = NULL;
ext->n_events--;
DEBUG_SCHED("2. %d <- getdns_mini_event_clear(loop: %p, el_ev: %p[userarg: %p, r: %p, w: %p, t: %p, ev: %p]); n_events: %d, times: %d\n", r, loop, el_ev, el_ev->userarg, el_ev->read_cb, el_ev->write_cb, el_ev->timeout_cb, el_ev->ev, (int)ext->n_events, (int)ext->base->times->count);
return r;
}
@ -127,6 +129,7 @@ static void
getdns_mini_event_callback(int fd, short bits, void *arg)
{
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)arg;
DEBUG_SCHED("1. getdns_mini_event_callback(fd: %d, bits: %d, el_ev: %p[userarg: %p, r: %p, w: %p, t: %p, ev: %p])\n", fd, (int)bits, el_ev, el_ev->userarg, el_ev->read_cb, el_ev->write_cb, el_ev->timeout_cb, el_ev->ev);
if (bits & EV_READ) {
assert(el_ev->read_cb);
el_ev->read_cb(el_ev->userarg);
@ -156,6 +159,7 @@ getdns_mini_event_schedule(getdns_eventloop *loop,
return GETDNS_RETURN_MEMORY_ERROR;
el_ev->ev = my_ev;
DEBUG_SCHED("1. getdns_mini_event_schedule(loop: %p, fd: %d, timeout: %"PRId64", el_ev: %p[userarg: %p, r: %p, w: %p, t: %p, ev: %p]); n_events: %d\n", loop, fd, timeout, el_ev, el_ev->userarg, el_ev->read_cb, el_ev->write_cb, el_ev->timeout_cb, el_ev->ev, (int)ext->n_events);
getdns_event_set(my_ev, fd, (
(el_ev->read_cb ? EV_READ|EV_PERSIST : 0) |
(el_ev->write_cb ? EV_WRITE|EV_PERSIST : 0) |
@ -170,11 +174,14 @@ getdns_mini_event_schedule(getdns_eventloop *loop,
goto error;
ext->n_events++;
DEBUG_SCHED("2. getdns_mini_event_schedule(loop: %p, fd: %d, timeout: %"PRId64", el_ev: %p[userarg: %p, r: %p, w: %p, t: %p, ev: %p]); n_events: %d\n", loop, fd, timeout, el_ev, el_ev->userarg, el_ev->read_cb, el_ev->write_cb, el_ev->timeout_cb, el_ev->ev, (int)ext->n_events);
return GETDNS_RETURN_GOOD;
error:
GETDNS_FREE(ext->mf, my_ev);
el_ev->ev = NULL;
DEBUG_SCHED("3. getdns_mini_event_schedule(loop: %p, fd: %d, timeout: %"PRId64", el_ev: %p[userarg: %p, r: %p, w: %p, t: %p, ev: %p]); n_events: %d\n", loop, fd, timeout, el_ev, el_ev->userarg, el_ev->read_cb, el_ev->write_cb, el_ev->timeout_cb, el_ev->ev, (int)ext->n_events);
return GETDNS_RETURN_GENERIC_ERROR;
}

View File

@ -131,7 +131,14 @@ submit_network_request(getdns_network_req *netreq)
getdns_return_t r;
getdns_dns_req *dns_req = netreq->owner;
if (dns_req->context->resolution_type == GETDNS_RESOLUTION_RECURSING) {
if (dns_req->context->resolution_type == GETDNS_RESOLUTION_RECURSING ||
/* TODO: Until DNSSEC with the new async stub resolver is finished,
* use unbound when we need DNSSEC.
*/
(dns_req->extensions && (
is_extension_set(dns_req->extensions, "dnssec_return_status") ||
is_extension_set(dns_req->extensions, "dnssec_return_only_secure") ||
is_extension_set(dns_req->extensions, "dnssec_return_validation_chain")))) {
/* schedule the timeout */
if (! dns_req->timeout.timeout_cb) {

View File

@ -137,8 +137,8 @@ getdns_context_run(getdns_context *context);
#define GETDNS_CLEAR_EVENT(loop, event) \
do { if ((event)->ev) (loop)->vmt->clear((loop), (event)); } while(0)
#define GETDNS_SCHEDULE_EVENT(loop, fd, timeout, event) \
do { GETDNS_CLEAR_EVENT((loop), (event)); \
(loop)->vmt->schedule((loop),(fd),(timeout),(event)); } while(0)
do { (loop)->vmt->schedule((loop),(fd),(timeout),(event)); } while(0)
#ifdef __cplusplus
}
#endif

View File

@ -283,7 +283,7 @@ stub_cleanup(getdns_network_req *netreq)
getdns_network_req *r, *prev_r;
getdns_upstream *upstream;
intptr_t query_id_intptr;
int schedule;
int reschedule;
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
@ -314,21 +314,20 @@ stub_cleanup(getdns_network_req *netreq)
prev_r ? prev_r : NULL;
break;
}
schedule = 0;
reschedule = 0;
if (!upstream->write_queue && upstream->event.write_cb) {
upstream->event.write_cb = NULL;
schedule = 1;
reschedule = 1;
}
if (!upstream->netreq_by_query_id.count && upstream->event.read_cb) {
upstream->event.read_cb = NULL;
schedule = 1;
reschedule = 1;
}
if (schedule) {
if (reschedule) {
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
if (upstream->event.read_cb || upstream->event.write_cb)
GETDNS_SCHEDULE_EVENT(upstream->loop,
upstream->fd, TIMEOUT_FOREVER, &upstream->event);
else
GETDNS_CLEAR_EVENT(upstream->loop,&upstream->event);
}
}
@ -339,12 +338,14 @@ upstream_erred(getdns_upstream *upstream)
while ((netreq = upstream->write_queue)) {
stub_cleanup(netreq);
netreq->state = NET_REQ_FINISHED;
priv_getdns_check_dns_req_complete(netreq->owner);
}
while (upstream->netreq_by_query_id.count) {
netreq = (getdns_network_req *)
getdns_rbtree_first(&upstream->netreq_by_query_id);
stub_cleanup(netreq);
netreq->state = NET_REQ_FINISHED;
priv_getdns_check_dns_req_complete(netreq->owner);
}
close(upstream->fd);
@ -364,6 +365,7 @@ stub_erred(getdns_network_req *netreq)
stub_next_upstream(netreq);
stub_cleanup(netreq);
if (netreq->fd >= 0) close(netreq->fd);
netreq->state = NET_REQ_FINISHED;
priv_getdns_check_dns_req_complete(netreq->owner);
}
@ -645,9 +647,8 @@ upstream_read_cb(void *userarg)
/* Nothing more to read? Then, deschedule the reads.*/
if (! upstream->netreq_by_query_id.count) {
upstream->event.read_cb = NULL;
if (!upstream->event.write_cb)
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
else
if (upstream->event.write_cb)
GETDNS_SCHEDULE_EVENT(upstream->loop,
upstream->fd, TIMEOUT_FOREVER, &upstream->event);
}
@ -805,6 +806,7 @@ stub_tcp_write_cb(void *userarg)
default:
netreq->query_id = (uint16_t) q;
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
GETDNS_SCHEDULE_EVENT(
dnsreq->loop, netreq->fd, dnsreq->context->timeout,
getdns_eventloop_event_init(&netreq->event, netreq,
@ -838,19 +840,23 @@ upstream_write_cb(void *userarg)
upstream->event.write_cb = NULL;
/* Reschedule (if already reading) to clear writable */
if (upstream->event.read_cb)
if (upstream->event.read_cb) {
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
GETDNS_SCHEDULE_EVENT(upstream->loop,
upstream->fd, TIMEOUT_FOREVER,
&upstream->event);
}
}
/* Schedule reading (if not already scheduled) */
if (!upstream->event.read_cb) {
upstream->event.read_cb = upstream_read_cb;
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
GETDNS_SCHEDULE_EVENT(upstream->loop,
upstream->fd, TIMEOUT_FOREVER, &upstream->event);
}
/* With synchonous lookups, schedule the read locally too */
if (netreq->event.write_cb) {
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
GETDNS_SCHEDULE_EVENT(
dnsreq->loop, upstream->fd, dnsreq->context->timeout,
getdns_eventloop_event_init(&netreq->event, netreq,
@ -877,6 +883,7 @@ upstream_schedule_netreq(getdns_upstream *upstream, getdns_network_req *netreq)
if (!upstream->write_queue) {
upstream->write_queue = upstream->write_queue_last = netreq;
upstream->event.write_cb = upstream_write_cb;
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
GETDNS_SCHEDULE_EVENT(upstream->loop,
upstream->fd, TIMEOUT_FOREVER, &upstream->event);
} else {

View File

@ -42,6 +42,8 @@
#include "getdns/getdns_extra.h"
#include "util/rbtree.h"
#define SCHED_DEBUG 0
struct getdns_context;
struct getdns_upstreams;
struct getdns_upstream;