aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2024-10-04 01:49:38 +0000
committerLaurent Bercot <ska@appnovation.com>2024-10-04 01:49:38 +0000
commit87b2868edd955dc884a6650250a4ee0fa4595683 (patch)
tree3db630dd8c3accec75836dae7392f5c15971792a /src
parentfaa51484fb1ea5f57d00004ab3ed74aa03fdd892 (diff)
downloaddnsfunnel-87b2868edd955dc884a6650250a4ee0fa4595683.tar.gz
Turn queries into a doubly linked list
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src')
-rw-r--r--src/dnsfunnel/dnsfunneld.c49
-rw-r--r--src/dnsfunnel/dnsfunneld.h4
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) ;