summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordimitri staessens <[email protected]>2017-08-13 01:06:59 +0200
committerdimitri staessens <[email protected]>2017-08-13 01:13:14 +0200
commit18a8b448aaa46cd56e8e1c6ed4685bac116ee11d (patch)
tree3ef8e3215de9597dfd73e8a24787a97d8301496d
parent7729888c3fe454733759903a56c0e3e82ac3f31b (diff)
downloadouroboros-18a8b448aaa46cd56e8e1c6ed4685bac116ee11d.tar.gz
ouroboros-18a8b448aaa46cd56e8e1c6ed4685bac116ee11d.zip
ipcpd: Fix tracking of outstanding DHT requests
The DHT failed when receiving multiple responses in a short timeframe. The lookup struct now keeps track of the number of outstanding requests.
-rw-r--r--src/ipcpd/normal/dht.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/src/ipcpd/normal/dht.c b/src/ipcpd/normal/dht.c
index 5c294c00..1f85e4f2 100644
--- a/src/ipcpd/normal/dht.c
+++ b/src/ipcpd/normal/dht.c
@@ -115,6 +115,8 @@ struct lookup {
struct list_head contacts;
size_t n_contacts;
+ size_t out;
+
uint64_t * addrs;
size_t n_addrs;
@@ -571,6 +573,7 @@ static struct lookup * lookup_create(struct dht * dht,
lu->state = LU_INIT;
lu->addrs = NULL;
lu->n_addrs = 0;
+ lu->out = 0;
lu->key = dht_dup_key(id, dht->b);
if (lu->key == NULL)
goto fail_id;
@@ -609,6 +612,16 @@ static struct lookup * lookup_create(struct dht * dht,
return NULL;
}
+static void lookup_add_out(struct lookup * lu,
+ size_t n)
+{
+ pthread_mutex_lock(&lu->lock);
+
+ lu->out += n;
+
+ pthread_mutex_unlock(&lu->lock);
+}
+
static void lookup_destroy(struct lookup * lu)
{
struct list_head * p;
@@ -676,6 +689,8 @@ static void lookup_update(struct dht * dht,
pthread_mutex_lock(&lu->lock);
+ --lu->out;
+
if (msg->n_addrs > 0) {
if (lu->addrs == NULL) {
lu->addrs = malloc(sizeof(*lu->addrs) * msg->n_addrs);
@@ -730,7 +745,11 @@ static void lookup_update(struct dht * dht,
}
}
- lu->state = LU_UPDATE;
+ if (lu->out == 0)
+ lu->state = LU_COMPLETE;
+ else
+ lu->state = LU_UPDATE;
+
pthread_cond_signal(&lu->cond);
pthread_mutex_unlock(&lu->lock);
return;
@@ -829,7 +848,7 @@ static enum lookup_state lookup_wait(struct lookup * lu)
pthread_cleanup_push((void (*)(void *)) lookup_destroy, (void *) lu);
- while (lu->state == LU_PENDING)
+ while (lu->state == LU_PENDING && ret != -ETIMEDOUT)
ret = -pthread_cond_timedwait(&lu->cond, &lu->lock, &abs);
pthread_cleanup_pop(false);
@@ -1493,7 +1512,7 @@ static struct lookup * kad_lookup(struct dht * dht,
uint64_t addrs[KAD_ALPHA + 1];
enum lookup_state state;
struct lookup * lu;
- size_t out = 0;
+ size_t out;
lu = lookup_create(dht, id);
if (lu == NULL)
@@ -1509,7 +1528,7 @@ static struct lookup * kad_lookup(struct dht * dht,
return NULL;
}
- out += kad_find(dht, id, addrs, code);
+ out = kad_find(dht, id, addrs, code);
if (out == 0) {
pthread_rwlock_wrlock(&dht->lock);
list_del(&lu->next);
@@ -1518,19 +1537,21 @@ static struct lookup * kad_lookup(struct dht * dht,
return lu;
}
+ lookup_add_out(lu, out);
+
while ((state = lookup_wait(lu)) != LU_COMPLETE) {
- --out;
switch (state) {
case LU_UPDATE:
lookup_new_addrs(lu, addrs);
- if (addrs[0] == 0 && out == 0) {
+ if (addrs[0] == 0) {
pthread_rwlock_wrlock(&dht->lock);
list_del(&lu->next);
pthread_rwlock_unlock(&dht->lock);
return lu;
}
- out += kad_find(dht, id, addrs, code);
+ out = kad_find(dht, id, addrs, code);
+ lookup_add_out(lu, out);
break;
case LU_DESTROY:
pthread_rwlock_wrlock(&dht->lock);