From 801b51f5032df38728d9fdbba1386a36fc09a532 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Thu, 20 Jul 2017 13:19:19 +0200 Subject: ipcpd: Fix DHT lookup processing Not all returned contacts were processed when a FIND_NODE or FIND_VALUE message was returned. --- src/ipcpd/normal/dht.c | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/ipcpd/normal/dht.c b/src/ipcpd/normal/dht.c index 0b00e2f5..1b382c1b 100644 --- a/src/ipcpd/normal/dht.c +++ b/src/ipcpd/normal/dht.c @@ -702,7 +702,8 @@ static void lookup_update(struct dht * dht, e = list_entry(p, struct contact, next); if (!memcmp(e->id, c->id, dht->b)) { contact_destroy(c); - goto finish_node; + c = NULL; + break; } if (dist(c->id, lu->key) > dist(e->id, lu->key)) @@ -710,20 +711,24 @@ static void lookup_update(struct dht * dht, pos++; } - } + if (c == NULL) + continue; - if (pos == dht->k) { - contact_destroy(c); - goto finish_node; - } else { - struct contact * d; - d = list_last_entry(&lu->contacts, struct contact, next); - list_del(&d->next); - list_add_tail(&c->next, p); - contact_destroy(d); + if (lu->n_contacts < dht->k) { + list_add_tail(&c->next, p); + ++lu->n_contacts; + } else if (pos == dht->k) { + contact_destroy(c); + continue; + } else { + struct contact * d; + list_add_tail(&c->next, p); + d = list_last_entry(&lu->contacts, struct contact, next); + list_del(&d->next); + contact_destroy(d); + } } - finish_node: lu->state = LU_UPDATE; pthread_cond_signal(&lu->cond); pthread_mutex_unlock(&lu->lock); @@ -771,11 +776,11 @@ static ssize_t lookup_contact_addrs(struct lookup * lu, return n; } -static ssize_t lookup_new_addrs(struct lookup * lu, +static void lookup_new_addrs(struct lookup * lu, uint64_t * addrs) { struct list_head * p; - ssize_t n = 0; + size_t n = 0; assert(lu); assert(addrs); @@ -795,14 +800,14 @@ static ssize_t lookup_new_addrs(struct lookup * lu, break; } + assert(n <= KAD_ALPHA); + + addrs[n] = 0; + if (n == 0) lu->state = LU_DONE; pthread_mutex_unlock(&lu->lock); - - assert(n <= KAD_ALPHA); - - return n; } static enum lookup_state lookup_wait(struct lookup * lu) @@ -1475,7 +1480,7 @@ static struct lookup * kad_lookup(struct dht * dht, if (lu == NULL) return NULL; - addrs[lookup_new_addrs(lu, addrs)] = 0; + lookup_new_addrs(lu, addrs); if (addrs[0] == 0) { pthread_rwlock_wrlock(&dht->lock); @@ -1496,7 +1501,7 @@ static struct lookup * kad_lookup(struct dht * dht, while ((state = lookup_wait(lu)) != LU_COMPLETE) { switch (state) { case LU_UPDATE: - addrs[lookup_new_addrs(lu, addrs)] = 0; + lookup_new_addrs(lu, addrs); if (addrs[0] == 0) { pthread_rwlock_wrlock(&dht->lock); list_del(&lu->next); -- cgit v1.2.3