Fix AVL tree traversal in cache_record_find and cache_host_is_known
authorMartin Röder <mroeder@metz-connect.com>
Wed, 18 Oct 2023 16:32:34 +0000 (18:32 +0200)
committerFelix Fietkau <nbd@nbd.name>
Wed, 18 Oct 2023 16:33:50 +0000 (18:33 +0200)
The AVL tree traversal in both functions systematically misses the last
AVL tree element. This can lead to duplicate cache entries and lookup
failures.

The fix duplicates the correct AVL tree traversal approach of
cache_dump_recursive().

Signed-off-by: Martin Röder <mroeder@metz-connect.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
cache.c

diff --git a/cache.c b/cache.c
index 8c851a39a9cce59e3020cb926e13c90d3df822d1..0ed52d7f17d0dea94bb80229cc477b91b0a1b029 100644 (file)
--- a/cache.c
+++ b/cache.c
@@ -197,13 +197,10 @@ cache_record_find(char *record, int type, int port, int rdlength, uint8_t *rdata
 {
        struct cache_record *l = avl_find_element(&records, record, l, avl);
 
-       if (!l)
-               return NULL;
-
-       while (l && !avl_is_last(&records, &l->avl) && !strcmp(l->record, record)) {
+       while (l && !strcmp(l->record, record)) {
                struct cache_record *r = l;
 
-               l = avl_next_element(l, avl);
+               l = !avl_is_last(&records, &l->avl) ? avl_next_element(l, avl) : NULL;
                if (r->type != type)
                        continue;
 
@@ -233,13 +230,10 @@ cache_host_is_known(char *record)
 {
        struct cache_record *l = avl_find_element(&records, record, l, avl);
 
-       if (!l)
-               return 0;
-
-       while (l && !avl_is_last(&records, &l->avl) && !strcmp(l->record, record)) {
+       while (l && !strcmp(l->record, record)) {
                struct cache_record *r = l;
 
-               l = avl_next_element(l, avl);
+               l = !avl_is_last(&records, &l->avl) ? avl_next_element(l, avl) : NULL;
                if ((r->type != TYPE_A) && (r->type != TYPE_AAAA))
                        continue;
                return 1;