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; getdns_mini_event *ext = (getdns_mini_event *)loop;
assert(el_ev->ev); 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) if (getdns_event_del(el_ev->ev) != 0)
r = GETDNS_RETURN_GENERIC_ERROR; 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; el_ev->ev = NULL;
ext->n_events--; 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; return r;
} }
@ -127,6 +129,7 @@ static void
getdns_mini_event_callback(int fd, short bits, void *arg) getdns_mini_event_callback(int fd, short bits, void *arg)
{ {
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)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) { if (bits & EV_READ) {
assert(el_ev->read_cb); assert(el_ev->read_cb);
el_ev->read_cb(el_ev->userarg); el_ev->read_cb(el_ev->userarg);
@ -156,6 +159,7 @@ getdns_mini_event_schedule(getdns_eventloop *loop,
return GETDNS_RETURN_MEMORY_ERROR; return GETDNS_RETURN_MEMORY_ERROR;
el_ev->ev = my_ev; 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, ( getdns_event_set(my_ev, fd, (
(el_ev->read_cb ? EV_READ|EV_PERSIST : 0) | (el_ev->read_cb ? EV_READ|EV_PERSIST : 0) |
(el_ev->write_cb ? EV_WRITE|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; goto error;
ext->n_events++; 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; return GETDNS_RETURN_GOOD;
error: error:
GETDNS_FREE(ext->mf, my_ev); GETDNS_FREE(ext->mf, my_ev);
el_ev->ev = NULL; 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; return GETDNS_RETURN_GENERIC_ERROR;
} }

View File

@ -131,7 +131,14 @@ submit_network_request(getdns_network_req *netreq)
getdns_return_t r; getdns_return_t r;
getdns_dns_req *dns_req = netreq->owner; 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 */ /* schedule the timeout */
if (! dns_req->timeout.timeout_cb) { if (! dns_req->timeout.timeout_cb) {

View File

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

View File

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

View File

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