diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2024-10-04 01:49:38 +0000 |
---|---|---|
committer | Laurent Bercot <ska@appnovation.com> | 2024-10-04 01:49:38 +0000 |
commit | 87b2868edd955dc884a6650250a4ee0fa4595683 (patch) | |
tree | 3db630dd8c3accec75836dae7392f5c15971792a | |
parent | faa51484fb1ea5f57d00004ab3ed74aa03fdd892 (diff) | |
download | dnsfunnel-87b2868edd955dc884a6650250a4ee0fa4595683.tar.gz dnsfunnel-87b2868edd955dc884a6650250a4ee0fa4595683.tar.xz dnsfunnel-87b2868edd955dc884a6650250a4ee0fa4595683.zip |
Turn queries into a doubly linked list
Signed-off-by: Laurent Bercot <ska@appnovation.com>
-rw-r--r-- | src/dnsfunnel/dnsfunneld.c | 49 | ||||
-rw-r--r-- | src/dnsfunnel/dnsfunneld.h | 4 |
2 files changed, 28 insertions, 25 deletions
diff --git a/src/dnsfunnel/dnsfunneld.c b/src/dnsfunnel/dnsfunneld.c index 6b830de..43db2b1 100644 --- a/src/dnsfunnel/dnsfunneld.c +++ b/src/dnsfunnel/dnsfunneld.c @@ -119,6 +119,7 @@ void query_new (s6dns_domain_t const *d, uint16_t qtype, uint16_t id, char const { dfquery_t q = { + .prev = sentinel, .next = QUERY(sentinel)->next, .xindex = 0, .procid = procid, @@ -132,14 +133,26 @@ void query_new (s6dns_domain_t const *d, uint16_t qtype, uint16_t id, char const memcpy(q.ip, ip, ipsz) ; if (!gensetdyn_new(&queries, &i)) strerr_diefu1sys(111, "create new query") ; + LOLDEBUG("pid %lld: query_new(): created %u, inflight is %zu", getpid(), i, inflight) ; s6dns_domain_encode(&dd) ; tain_add_g(&deadline, &globaltto) ; if (!s6dns_engine_init_g(&q.dt, &cachelist, S6DNS_O_RECURSIVE, dd.s, dd.len, qtype, &deadline)) strerr_diefu1sys(111, "start new query") ; *QUERY(i) = q ; + QUERY(q.next)->prev = i ; QUERY(sentinel)->next = i ; } +uint32_t query_remove (uint32_t i) +{ + dfquery_t *q = QUERY(i) ; + uint32_t j = q->prev ; + QUERY(j)->next = q->next ; + QUERY(q->next)->prev = j ; + gensetdyn_delete(&queries, i) ; + return j ; +} + static inline void sanitize_and_new (char const *buf, unsigned int len, char const *ip, uint16_t port) { s6dns_domain_t d ; @@ -172,6 +185,7 @@ int main (int argc, char const *const *argv) int notif = 0 ; int fd ; unsigned int t = 0 ; + dfquery_t *p ; subgetopt l = SUBGETOPT_ZERO ; uint16_t port = 53 ; ip46 ip ; @@ -277,8 +291,9 @@ int main (int argc, char const *const *argv) } if (!gensetdyn_new(&queries, &sentinel)) strerr_diefu1sys(111, "initialize query structure") ; - *QUERY(sentinel) = dfquery_zero ; - QUERY(sentinel)->next = sentinel ; + p = QUERY(sentinel) ; + *p = dfquery_zero ; + p->prev = p->next = sentinel ; if (!query_process_init()) strerr_diefu1sys(111, "initialize query processing") ; tain_now_set_stopwatch_g() ; @@ -296,7 +311,6 @@ int main (int argc, char const *const *argv) for (;;) { tain deadline = TAIN_INFINITE ; - uint32_t i = QUERY(sentinel)->next ; uint32_t j = 2 ; int r ; iopause_fd x[2 + inflight] ; @@ -305,10 +319,10 @@ int main (int argc, char const *const *argv) x[0].events = IOPAUSE_READ ; x[1].fd = 0 ; x[1].events = (cont ? IOPAUSE_READ : 0) | (dfanswer_pending() ? IOPAUSE_WRITE : 0) ; - LOLDEBUG("loop: cont = %d, x[1].events = %u, inflight = %zu, pendingbytes = %zu", cont, (unsigned int)x[1].events, inflight, dfanswer_pending()) ; + LOLDEBUG("pid %lld: loop: cont = %d, x[1].events = %u, inflight = %zu, pendingbytes = %zu", (int64_t)getpid(), cont, (unsigned int)x[1].events, inflight, dfanswer_pending()) ; if (!x[1].events && !inflight) break ; - while (i != sentinel) + for (uint32_t i = QUERY(sentinel)->next ; i != sentinel ; i = QUERY(i)->next) { dfquery_t *q = QUERY(i) ; s6dns_engine_nextdeadline(&q->dt, &deadline) ; @@ -317,7 +331,6 @@ int main (int argc, char const *const *argv) if (s6dns_engine_isreadable(&q->dt)) x[j].events |= IOPAUSE_READ ; if (s6dns_engine_iswritable(&q->dt)) x[j].events |= IOPAUSE_WRITE ; q->xindex = j++ ; - i = q->next ; } r = iopause_g(x, j, &deadline) ; @@ -325,21 +338,16 @@ int main (int argc, char const *const *argv) if (!r) { - i = QUERY(sentinel)->next ; - j = sentinel ; - while (i != sentinel) + for (uint32_t i = QUERY(sentinel)->next ; i != sentinel ; i = QUERY(i)->next) { dfquery_t *q = QUERY(i) ; - uint32_t k = q->next ; if (s6dns_engine_timeout_g(&q->dt)) { query_process_response_failure(ops, q) ; - QUERY(j)->next = k ; stralloc_free(&q->dt.sa) ; - gensetdyn_delete(&queries, i) ; + LOLDEBUG("pid %lld: loop: query %u timed out", (int64_t)getpid(), i) ; + i = query_remove(i) ; } - else j = i ; - i = k ; } continue ; } @@ -351,13 +359,10 @@ int main (int argc, char const *const *argv) int r = dfanswer_flush() ; if (r < 0) strerr_diefu1sys(111, "send DNS answer to client") ; } - - i = QUERY(sentinel)->next ; - j = sentinel ; - while (i != sentinel) + + for (uint32_t i = QUERY(sentinel)->next ; i != sentinel ; i = QUERY(i)->next) { dfquery_t *q = QUERY(i) ; - uint32_t k = q->next ; if (x[q->xindex].events && x[q->xindex].revents) { int r = s6dns_engine_event_g(&q->dt) ; @@ -365,14 +370,12 @@ int main (int argc, char const *const *argv) { if (r > 0) query_process_response_success(ops, q) ; else query_process_response_failure(ops, q) ; - QUERY(j)->next = k ; if (r > 0) s6dns_engine_free(&q->dt) ; else stralloc_free(&q->dt.sa) ; - gensetdyn_delete(&queries, i) ; + LOLDEBUG("pid %lld: loop: query %u arrived", (int64_t)getpid(), i) ; + i = query_remove(i) ; } - else j = i ; } - i = k ; } if (x[1].revents & IOPAUSE_READ) diff --git a/src/dnsfunnel/dnsfunneld.h b/src/dnsfunnel/dnsfunneld.h index e4d5d64..83f1757 100644 --- a/src/dnsfunnel/dnsfunneld.h +++ b/src/dnsfunnel/dnsfunneld.h @@ -15,6 +15,7 @@ typedef struct dfquery_s dfquery_t, *dfquery_t_ref ; struct dfquery_s { + uint32_t prev ; uint32_t next ; uint32_t xindex ; uint32_t procid ; @@ -23,7 +24,7 @@ struct dfquery_s uint16_t id ; s6dns_engine_t dt ; } ; -#define DFQUERY_ZERO { .next = 0, .xindex = 0, .procid = 0, .ip = { 0 }, .port = 0, .id = 0, .dt = S6DNS_ENGINE_ZERO } +#define DFQUERY_ZERO { .prev = 0, .next = 0, .xindex = 0, .procid = 0, .ip = { 0 }, .port = 0, .id = 0, .dt = S6DNS_ENGINE_ZERO } extern unsigned int verbosity ; extern unsigned int ipsz ; @@ -34,7 +35,6 @@ extern void dfanswer_nxdomain (dfquery_t const *, int) ; extern void dfanswer_nodata (dfquery_t const *, int) ; extern void dfanswer_pass (dfquery_t const *, char *, unsigned int) ; - extern void query_new (s6dns_domain_t const *, uint16_t, uint16_t, char const *, uint16_t, uint32_t) ; extern int query_process_init (void) ; |