From da1bdf9d4c4e31e7cbb5e46bf4707d2b9905a088 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com>
Date: Sun, 16 Oct 2016 22:36:07 -0400
Subject: [PATCH] dht: retry nodes more aggressively in case of failure

---
 src/dht.cpp       | 32 ++++++++++++++++++++++++--------
 src/dhtrunner.cpp |  3 ++-
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/src/dht.cpp b/src/dht.cpp
index 0a334b8c..08753f96 100644
--- a/src/dht.cpp
+++ b/src/dht.cpp
@@ -852,12 +852,25 @@ Dht::onNewNode(const std::shared_ptr<Node>& node, int confirm)
         //scheduler.edit(nextNodesConfirmation, now);
     }
 
-    /* Try to get rid of an expired node. */
-    for (auto& n : b->nodes) {
-        if (not n->isExpired())
-            continue;
-        n = node;
-        return;
+    unsigned expired_count = 0;
+    for (auto& n : b->nodes)
+        if (n->isExpired())
+            expired_count++;
+    if (/*confirm < 2 && */b->nodes.size() - expired_count == 0) {
+        // No good or dubious node in this bucket
+        // Try to confirm this one
+        DHT_LOG_DEBUG("[node %s] Sending find node to new node.", node->toString().c_str());
+        network_engine.sendFindNode(node, list.randomId(b), -1, nullptr, nullptr);
+        if (confirm >= 2)
+            scheduler.edit(nextNodesConfirmation, scheduler.time());
+    }
+    if (expired_count > 0)  {
+        // Try to get rid of an expired node.
+        for (auto& n : b->nodes)
+            if (n->isExpired()) {
+                n = node;
+                return;
+            }
     }
 
     if (b->nodes.size() >= TARGET_NODES) {
@@ -2748,8 +2761,11 @@ Dht::bucketMaintenance(RoutingTable& list)
                         want = WANT4 | WANT6;
                 }
 
-                DHT_LOG.DEBUG("[node %s] sending find %s for bucket maintenance.", n->toString().c_str(), id.toString().c_str());
-                network_engine.sendFindNode(n, id, want, nullptr, nullptr);
+                DHT_LOG_DEBUG("[node %s] sending find %s for bucket maintenance.", n->toString().c_str(), id.toString().c_str());
+                network_engine.sendFindNode(n, id, want, nullptr, [&](const Request&, bool ok){
+                    if (not ok)
+                        scheduler.edit(nextNodesConfirmation, scheduler.time());
+                });
                 /* In order to avoid sending queries back-to-back,
                    give up for now and reschedule us soon. */
                 return true;
diff --git a/src/dhtrunner.cpp b/src/dhtrunner.cpp
index f4b7c655..0d5e2b2b 100644
--- a/src/dhtrunner.cpp
+++ b/src/dhtrunner.cpp
@@ -625,7 +625,8 @@ DhtRunner::tryBootstrapCoutinuously()
                 // wait at least until the next BOOTSTRAP_PERIOD
                 cv.wait_until(blck, next, [&]() { return not running; });
                 // wait for bootstrap requests to end.
-                cv.wait(blck, [&]() { return not running or ping_count == 0; });
+                if (running)
+                    cv.wait(blck, [&]() { return not running or ping_count == 0; });
             }
             // update state
             {
-- 
GitLab