]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- stream reuse, do not explicitly wait for a free pending_tcp if a reuse
authorGeorge Thessalonikefs <george@nlnetlabs.nl>
Sat, 24 Jul 2021 14:16:19 +0000 (16:16 +0200)
committerGeorge Thessalonikefs <george@nlnetlabs.nl>
Mon, 26 Jul 2021 08:47:20 +0000 (10:47 +0200)
  could be used.

services/outside_network.c
testcode/unittcpreuse.c

index 5207a704278ed5c122b7ef36bf4eda3e72198d7e..37f97d3dd4232d5f9484995370c38d7d354cb394 100644 (file)
@@ -801,13 +801,59 @@ waiting_tcp_callback(struct waiting_tcp* w, struct comm_point* c, int error,
        }
 }
 
+/** add waiting_tcp element to the outnet tcp waiting list */
+static void
+outnet_add_tcp_waiting(struct outside_network* outnet, struct waiting_tcp* w)
+{
+       struct timeval tv;
+       log_assert(!w->on_tcp_waiting_list);
+       if(w->on_tcp_waiting_list)
+               return;
+       w->next_waiting = NULL;
+       if(outnet->tcp_wait_last)
+               outnet->tcp_wait_last->next_waiting = w;
+       else    outnet->tcp_wait_first = w;
+       outnet->tcp_wait_last = w;
+       w->on_tcp_waiting_list = 1;
+#ifndef S_SPLINT_S
+       tv.tv_sec = w->timeout/1000;
+       tv.tv_usec = (w->timeout%1000)*1000;
+#endif
+       comm_timer_set(w->timer, &tv);
+}
+
+/** add waiting_tcp element as first to the outnet tcp waiting list */
+static void
+outnet_add_tcp_waiting_first(struct outside_network* outnet,
+       struct waiting_tcp* w, int reset_timer)
+{
+       struct timeval tv;
+       log_assert(!w->on_tcp_waiting_list);
+       if(w->on_tcp_waiting_list)
+               return;
+       w->next_waiting = outnet->tcp_wait_first;
+       if(!outnet->tcp_wait_last)
+               outnet->tcp_wait_last = w;
+       outnet->tcp_wait_first = w;
+       w->on_tcp_waiting_list = 1;
+       if(reset_timer) {
+#ifndef S_SPLINT_S
+               tv.tv_sec = w->timeout/1000;
+               tv.tv_usec = (w->timeout%1000)*1000;
+#endif
+               comm_timer_set(w->timer, &tv);
+       }
+       log_assert(
+               (!outnet->tcp_reuse_first && !outnet->tcp_reuse_last) ||
+               (outnet->tcp_reuse_first && outnet->tcp_reuse_last));
+}
+
 /** see if buffers can be used to service TCP queries */
 static void
 use_free_buffer(struct outside_network* outnet)
 {
        struct waiting_tcp* w;
-       while(outnet->tcp_free && outnet->tcp_wait_first 
-               && !outnet->want_to_quit) {
+       while(outnet->tcp_wait_first && !outnet->want_to_quit) {
 #ifdef USE_DNSTAP
                struct pending_tcp* pend_tcp = NULL;
 #endif
@@ -848,7 +894,7 @@ use_free_buffer(struct outside_network* outnet)
                                        reuse->pending->c->fd, reuse->pending,
                                        w);
                        }
-               } else {
+               } else if(outnet->tcp_free) {
                        struct pending_tcp* pend = w->outnet->tcp_free;
                        rbtree_init(&pend->reuse.tree_by_id, reuse_id_cmp);
                        pend->reuse.pending = pend;
@@ -865,11 +911,15 @@ use_free_buffer(struct outside_network* outnet)
 #ifdef USE_DNSTAP
                        pend_tcp = pend;
 #endif
+               } else {
+                       /* no reuse and no free buffer, put back at the start */
+                       outnet_add_tcp_waiting_first(outnet, w, 0);
+                       break;
                }
 #ifdef USE_DNSTAP
                if(outnet->dtenv && pend_tcp && w && w->sq &&
-                  (outnet->dtenv->log_resolver_query_messages ||
-                   outnet->dtenv->log_forwarder_query_messages)) {
+                       (outnet->dtenv->log_resolver_query_messages ||
+                       outnet->dtenv->log_forwarder_query_messages)) {
                        sldns_buffer tmp;
                        sldns_buffer_init_frm_data(&tmp, w->pkt, w->pkt_len);
                        dt_msg_send_outside_query(outnet->dtenv, &w->sq->addr,
@@ -880,27 +930,6 @@ use_free_buffer(struct outside_network* outnet)
        }
 }
 
-/** add waiting_tcp element to the outnet tcp waiting list */
-static void
-outnet_add_tcp_waiting(struct outside_network* outnet, struct waiting_tcp* w)
-{
-       struct timeval tv;
-       log_assert(!w->on_tcp_waiting_list);
-       if(w->on_tcp_waiting_list)
-               return;
-       w->next_waiting = NULL;
-       if(outnet->tcp_wait_last)
-               outnet->tcp_wait_last->next_waiting = w;
-       else    outnet->tcp_wait_first = w;
-       outnet->tcp_wait_last = w;
-       w->on_tcp_waiting_list = 1;
-#ifndef S_SPLINT_S
-       tv.tv_sec = w->timeout/1000;
-       tv.tv_usec = (w->timeout%1000)*1000;
-#endif
-       comm_timer_set(w->timer, &tv);
-}
-
 /** delete element from tree by id */
 static void
 reuse_tree_by_id_delete(struct reuse_tcp* reuse, struct waiting_tcp* w)
index ddb865b68a6ac723762f911c0a8dd40413c8a1fc..b93e7def13fa6ceaefbdc3754da22d3ef1852f1f 100644 (file)
@@ -128,7 +128,7 @@ static int create_pending_tcp(struct outside_network* outnet)
                        outnet->num_tcp, sizeof(struct pending_tcp*))))
                return 0;
        for(i=0; i<outnet->num_tcp; i++) {
-               if(!(outnet->tcp_conns[i] = (struct pending_tcp*)calloc(1, 
+               if(!(outnet->tcp_conns[i] = (struct pending_tcp*)calloc(1,
                        sizeof(struct pending_tcp))))
                        return 0;
                outnet->tcp_conns[i]->next_free = outnet->tcp_free;
@@ -216,7 +216,6 @@ static void tcp_reuse_tree_list_test(void)
        check_removal(&outnet, 2, 5);
        check_removal(&outnet, 1, 3);
        check_removal(&outnet, 1, 2);
-       
        /* check snip */
        unit_show_func("services/outside_network.c", "reuse_tcp_lru_snip");
        check_snip(&outnet, 4);