summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2026-08-16 18:05:20 +0000
committerSander Vrijders <sander@ouroboros.rocks>2026-08-31 08:31:45 +0200
commit657fdee8e909bd50fcc0b809b454cf1ad551384b (patch)
treeef6f2cfa3abacfe2ff33279f6af034358033a0a1
parent2e06d9b85f2e2eadd94ade6b36d0aa2835a20ce2 (diff)
downloadouroboros-657fdee8e909bd50fcc0b809b454cf1ad551384b.tar.gz
ouroboros-657fdee8e909bd50fcc0b809b454cf1ad551384b.zip
ipcpd: Fix next value iteration in DHT
There was a bug in the loop where only the last entry was checked. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
-rw-r--r--src/ipcpd/unicast/dir/dht.c15
-rw-r--r--src/ipcpd/unicast/dir/tests/dht_test.c63
2 files changed, 70 insertions, 8 deletions
diff --git a/src/ipcpd/unicast/dir/dht.c b/src/ipcpd/unicast/dir/dht.c
index c2cd33aa..9d60ce30 100644
--- a/src/ipcpd/unicast/dir/dht.c
+++ b/src/ipcpd/unicast/dir/dht.c
@@ -3512,7 +3512,7 @@ static int dht_kv_next_values(uint8_t * key,
struct timespec now;
struct list_head * p;
struct list_head * h;
- struct dht_entry * e = NULL;
+ struct dht_entry * e;
assert(key != NULL);
assert(repl != NULL);
@@ -3525,20 +3525,19 @@ static int dht_kv_next_values(uint8_t * key,
pthread_rwlock_rdlock(&dht.db.lock);
- if (llist_is_empty(&dht.db.kv.ll))
- goto no_entries;
-
llist_for_each_safe(p, h, &dht.db.kv.ll) {
e = list_entry(p, struct dht_entry, next);
- if (IS_CLOSER(e->key, key))
+ if (!IS_CLOSER(key, e->key))
continue; /* Already processed */
- }
- if (e != NULL) {
memcpy(key, e->key, dht.id.len);
+
dht_entry_get_repl_lists(e, repl, rebl, &now);
+
+ if (!list_is_empty(repl) || !list_is_empty(rebl))
+ break;
}
- no_entries:
+
pthread_rwlock_unlock(&dht.db.lock);
return list_is_empty(repl) && list_is_empty(rebl) ? -ENOENT : 0;
diff --git a/src/ipcpd/unicast/dir/tests/dht_test.c b/src/ipcpd/unicast/dir/tests/dht_test.c
index 1f7026b3..ee6861a0 100644
--- a/src/ipcpd/unicast/dir/tests/dht_test.c
+++ b/src/ipcpd/unicast/dir/tests/dht_test.c
@@ -796,6 +796,68 @@ static int test_dht_kv_get_values(void)
return TEST_RC_FAIL;
}
+static int test_dht_kv_next_values(void)
+{
+ struct list_head repl;
+ struct list_head rebl;
+ uint8_t * key;
+ size_t n;
+ size_t i;
+
+ TEST_START();
+
+ list_head_init(&repl);
+ list_head_init(&rebl);
+
+ if (dht_init(&test_dht_config) < 0) {
+ printf("Failed to create dht.\n");
+ goto fail_init;
+ }
+
+ if (fill_store_with_random_values(NULL, sizeof(uint64_t), 3) < 0) {
+ printf("Failed to fill store with random values.\n");
+ goto fail_fill;
+ }
+
+ key = dht_dup_key(dht.id.data);
+ if (key == NULL) {
+ printf("Failed to duplicate DHT ID.\n");
+ goto fail_fill;
+ }
+
+ n = 0;
+
+ for (i = 0; i < 5; ++i) {
+ if (dht_kv_next_values(key, &repl, &rebl) < 0)
+ break;
+
+ ++n;
+ value_list_destroy(&repl);
+ value_list_destroy(&rebl);
+ }
+
+ if (n != 3) {
+ printf("Failed to visit each entry once (%zu != 3).\n", n);
+ goto fail_next;
+ }
+
+ free(key);
+
+ dht_fini();
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+
+ fail_next:
+ free(key);
+ fail_fill:
+ dht_fini();
+ fail_init:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
static int test_dht_kv_find_node_req_msg(void)
{
dht_msg_t * msg;
@@ -1894,6 +1956,7 @@ int dht_test(int argc,
rc |= test_dht_kv_contact_list();
rc |= test_dht_kv_update_bucket();
rc |= test_dht_kv_get_values();
+ rc |= test_dht_kv_next_values();
rc |= test_dht_kv_find_node_req_msg();
rc |= test_dht_kv_find_node_rsp_msg();
rc |= test_dht_kv_find_node_rsp_msg_contacts();