about summary refs log tree commit diff
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
parentfaa51484fb1ea5f57d00004ab3ed74aa03fdd892 (diff)
downloaddnsfunnel-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.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) ;