mirror of https://github.com/getdnsapi/getdns.git
Fix for TCP stub mode
Stupid mistake. One can not clear an freshly "cleared" initialized event!
This commit is contained in:
parent
fa02e3ae70
commit
e9548fc5fb
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
31
src/stub.c
31
src/stub.c
|
@ -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 (upstream->event.read_cb || upstream->event.write_cb)
|
||||
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
|
||||
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
||||
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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue