]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
reuse tcp id_cmp function. clear list and tree after delete. clear when
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 24 Jun 2020 14:28:42 +0000 (16:28 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 24 Jun 2020 14:28:42 +0000 (16:28 +0200)
decommisioned. callbacks when closed for lru space, and when closed because
not kept open.

services/outside_network.c
services/outside_network.h
util/fptr_wlist.c

index bec24e571280363f151f6b45d799f9ccc13e72ee..14532b1f42433c641f63397e2f171c4cfdb82bc3 100644 (file)
@@ -168,6 +168,19 @@ reuse_cmp(const void* key1, const void* key2)
        return 0;
 }
 
+int reuse_id_cmp(const void* key1, const void* key2)
+{
+       struct waiting_tcp* w1 = (struct waiting_tcp*)key1;
+       struct waiting_tcp* w2 = (struct waiting_tcp*)key2;
+       struct pending_tcp* p1 = (struct pending_tcp*)w1->next_waiting;
+       struct pending_tcp* p2 = (struct pending_tcp*)w2->next_waiting;
+       if(p1->id < p2->id)
+               return -1;
+       if(p1->id > p2->id)
+               return 1;
+       return 0;
+}
+
 /** delete waiting_tcp entry. Does not unlink from waiting list. 
  * @param w: to delete.
  */
@@ -519,6 +532,39 @@ reuse_tcp_remove_tree_list(struct outside_network* outnet,
        }
 }
 
+/** helper function that deletes an element from the tree of readwait
+ * elements in tcp reuse structure */
+static void reuse_del_readwait_elem(rbnode_type* node, void* ATTR_UNUSED(arg))
+{
+       struct waiting_tcp* w = (struct waiting_tcp*)node->key;
+       waiting_tcp_delete(w);
+}
+
+/** delete readwait waiting_tcp elements, deletes the elements in the list */
+static void reuse_del_readwait(struct pending_tcp* pend)
+{
+       if(pend->reuse.tree_by_id.root == NULL ||
+               pend->reuse.tree_by_id.root == RBTREE_NULL)
+               return;
+       traverse_postorder(&pend->reuse.tree_by_id, &reuse_del_readwait_elem,
+               NULL);
+       rbtree_init(&pend->reuse.tree_by_id, reuse_id_cmp);
+}
+
+/** delete writewait waiting_tcp elements, deletes the elements in the list */
+static void reuse_del_writewait(struct pending_tcp* pend)
+{
+       struct waiting_tcp* w, *n;
+       w = pend->reuse.write_wait_first;
+       while(w) {
+               n = w->write_wait_next;
+               waiting_tcp_delete(w);
+               w = n;
+       }
+       pend->reuse.write_wait_first = NULL;
+       pend->reuse.write_wait_last = NULL;
+}
+
 /** decommission a tcp buffer, closes commpoint and frees waiting_tcp entry */
 static void
 decommission_pending_tcp(struct outside_network* outnet, 
@@ -541,6 +587,8 @@ decommission_pending_tcp(struct outside_network* outnet,
        }
        waiting_tcp_delete(pend->query);
        pend->query = NULL;
+       reuse_del_readwait(pend);
+       reuse_del_writewait(pend);
 }
 
 /** log reuse item addr and ptr with message */
@@ -1497,36 +1545,6 @@ static void reuse_cb_curquery_for_failure(struct pending_tcp* pend, int err)
        }
 }
 
-/** helper function that deletes an element from the tree of readwait
- * elements in tcp reuse structure */
-static void reuse_del_readwait_elem(rbnode_type* node, void* ATTR_UNUSED(arg))
-{
-       struct waiting_tcp* w = (struct waiting_tcp*)node->key;
-       waiting_tcp_delete(w);
-}
-
-/** delete readwait waiting_tcp elements, deletes the elements in the list */
-static void reuse_del_readwait(struct pending_tcp* pend)
-{
-       if(pend->reuse.tree_by_id.root == NULL ||
-               pend->reuse.tree_by_id.root == RBTREE_NULL)
-               return;
-       traverse_postorder(&pend->reuse.tree_by_id, &reuse_del_readwait_elem,
-               NULL);
-}
-
-/** delete writewait waiting_tcp elements, deletes the elements in the list */
-static void reuse_del_writewait(struct pending_tcp* pend)
-{
-       struct waiting_tcp* w, *n;
-       w = pend->reuse.write_wait_first;
-       while(w) {
-               n = w->write_wait_next;
-               waiting_tcp_delete(w);
-               w = n;
-       }
-}
-
 void
 outnet_tcptimer(void* arg)
 {
@@ -1594,6 +1612,9 @@ reuse_tcp_close_oldest(struct outside_network* outnet)
        }
 
        /* free up */
+       reuse_cb_curquery_for_failure(pend, NETEVENT_CLOSED);
+       reuse_cb_readwait_for_failure(pend, NETEVENT_CLOSED);
+       reuse_cb_writewait_for_failure(pend, NETEVENT_CLOSED);
        decommission_pending_tcp(outnet, pend);
 }
 
@@ -1831,6 +1852,7 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
                        verbose(5, "pending_tcp_query: new fd, connect");
                        /* create new fd and connect to addr, setup to
                         * write query */
+                       rbtree_init(&pend->reuse.tree_by_id, reuse_id_cmp);
                        pend->reuse.pending = pend;
                        memcpy(&pend->reuse.addr, &sq->addr, sq->addrlen);
                        pend->reuse.addrlen = sq->addrlen;
@@ -2058,6 +2080,15 @@ serviced_delete(struct serviced_query* sq)
                        if(!p->on_tcp_waiting_list) {
                                verbose(5, "serviced_delete: tcpreusekeep");
                                if(!reuse_tcp_remove_serviced_keep(p, sq)) {
+                                       reuse_cb_curquery_for_failure(
+                                               (struct pending_tcp*)p->
+                                               next_waiting, NETEVENT_CLOSED);
+                                       reuse_cb_readwait_for_failure(
+                                               (struct pending_tcp*)p->
+                                               next_waiting, NETEVENT_CLOSED);
+                                       reuse_cb_writewait_for_failure(
+                                               (struct pending_tcp*)p->
+                                               next_waiting, NETEVENT_CLOSED);
                                        decommission_pending_tcp(sq->outnet,
                                          (struct pending_tcp*)p->next_waiting);
                                        use_free_buffer(sq->outnet);
index dfac321ce6461cff614a4210b1bcbf6c01ad11ba..cefee3b088ca25fed57bdd7762fd6379873e40dc 100644 (file)
@@ -726,7 +726,10 @@ int pending_cmp(const void* key1, const void* key2);
 /** compare function of serviced query rbtree */
 int serviced_cmp(const void* key1, const void* key2);
 
-/** compare function of reuse_tcp rbtree */
+/** compare function of reuse_tcp rbtree in outside_network struct */
 int reuse_cmp(const void* key1, const void* key2);
 
+/** compare function of reuse_tcp tree_by_id rbtree */
+int reuse_id_cmp(const void* key1, const void* key2);
+
 #endif /* OUTSIDE_NETWORK_H */
index ea992860653b07774057598f67c8e7ca4b21f284..e3baec8c25c5631b8a8a9b99f276cabccf133698 100644 (file)
@@ -227,6 +227,7 @@ fptr_whitelist_rbtree_cmp(int (*fptr) (const void *, const void *))
        else if(fptr == &pending_cmp) return 1;
        else if(fptr == &serviced_cmp) return 1;
        else if(fptr == &reuse_cmp) return 1;
+       else if(fptr == &reuse_id_cmp) return 1;
        else if(fptr == &name_tree_compare) return 1;
        else if(fptr == &order_lock_cmp) return 1;
        else if(fptr == &codeline_cmp) return 1;