]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Attempt to fix NULL keys in the reuse_tcp tree; relates to #411.
authorGeorge Thessalonikefs <george@nlnetlabs.nl>
Mon, 1 Feb 2021 15:57:56 +0000 (16:57 +0100)
committerGeorge Thessalonikefs <george@nlnetlabs.nl>
Mon, 1 Feb 2021 15:57:56 +0000 (16:57 +0100)
doc/Changelog
services/outside_network.c

index af53d783682b99a9974d6ad675502e1bdf45c06e..4a095a0768e8f5295c2e596f051ad3cc20d92b05 100644 (file)
@@ -1,3 +1,6 @@
+1 February 2022: George
+       - Attempt to fix NULL keys in the reuse_tcp tree; relates to #411.
+
 26 January 2022: George
        - Merge PR #408 from fobser: Prevent a few more yacc clashes.
        - Merge PR #275 from Roland van Rijswijk-Deij: Add feature to return the
index 11559ffac1a993c3ae8939c5dc67c320da5ffda5..6c6b42ccbdb8aa184d7f07171fa83405b244abdf 100644 (file)
@@ -90,6 +90,10 @@ static int randomize_and_send_udp(struct pending* pend, sldns_buffer* packet,
 static void waiting_list_remove(struct outside_network* outnet,
        struct waiting_tcp* w);
 
+/** remove reused element from tree and lru list */
+static void reuse_tcp_remove_tree_list(struct outside_network* outnet,
+       struct reuse_tcp* reuse);
+
 int 
 pending_cmp(const void* key1, const void* key2)
 {
@@ -424,8 +428,11 @@ static int
 reuse_tcp_insert(struct outside_network* outnet, struct pending_tcp* pend_tcp)
 {
        log_reuse_tcp(VERB_CLIENT, "reuse_tcp_insert", &pend_tcp->reuse);
-       if(pend_tcp->reuse.item_on_lru_list)
+       if(pend_tcp->reuse.item_on_lru_list) {
+               if(!pend_tcp->reuse.node.key)
+                       log_err("internal error: reuse_tcp_insert: on lru list without key");
                return 1;
+       }
        pend_tcp->reuse.node.key = &pend_tcp->reuse;
        pend_tcp->reuse.pending = pend_tcp;
        if(!rbtree_insert(&outnet->tcp_reuse, &pend_tcp->reuse.node)) {
@@ -477,7 +484,7 @@ reuse_tcp_find(struct outside_network* outnet, struct sockaddr_storage* addr,
        if(outnet->tcp_reuse.root == NULL ||
                outnet->tcp_reuse.root == RBTREE_NULL)
                return NULL;
-       if(rbtree_find_less_equal(&outnet->tcp_reuse, &key_p.reuse.node,
+       if(rbtree_find_less_equal(&outnet->tcp_reuse, &key_p.reuse,
                &result)) {
                /* exact match */
                /* but the key is on stack, and ptr is compared, impossible */
@@ -661,6 +668,14 @@ outnet_tcp_take_into_use(struct waiting_tcp* w)
        pend->reuse.cp_more_write_again = 0;
        memcpy(&pend->c->repinfo.addr, &w->addr, w->addrlen);
        pend->reuse.pending = pend;
+
+       /* Remove from tree in case the is_ssl will be different and causes the
+        * identity of the reuse_tcp to change; could result in nodes not being
+        * deleted from the tree (because the new identity does not match the
+        * previous node) but their ->key would be changed to NULL. */
+       if(pend->reuse.node.key)
+               reuse_tcp_remove_tree_list(w->outnet, &pend->reuse);
+
        if(pend->c->ssl)
                pend->reuse.is_ssl = 1;
        else    pend->reuse.is_ssl = 0;
@@ -677,8 +692,10 @@ outnet_tcp_take_into_use(struct waiting_tcp* w)
 static void
 reuse_tcp_lru_touch(struct outside_network* outnet, struct reuse_tcp* reuse)
 {
-       if(!reuse->item_on_lru_list)
+       if(!reuse->item_on_lru_list) {
+               log_err("internal error: we need to touch the lru_list but item not in list");
                return; /* not on the list, no lru to modify */
+       }
        if(!reuse->lru_prev)
                return; /* already first in the list */
        /* remove at current position */
@@ -847,7 +864,7 @@ reuse_tcp_remove_tree_list(struct outside_network* outnet,
        verbose(VERB_CLIENT, "reuse_tcp_remove_tree_list");
        if(reuse->node.key) {
                /* delete it from reuse tree */
-               (void)rbtree_delete(&outnet->tcp_reuse, &reuse->node);
+               (void)rbtree_delete(&outnet->tcp_reuse, reuse);
                reuse->node.key = NULL;
        }
        /* delete from reuse list */