diff --git a/include/opendht/dht.h b/include/opendht/dht.h index e2768a1d7ac536efaa92a8f21a42cb23d5071904..f49afbb35e81a6fd455daf0c38ec6f3fec563ebb 100644 --- a/include/opendht/dht.h +++ b/include/opendht/dht.h @@ -364,7 +364,7 @@ private: const bool is_bootstrap {false}; // the stuff - RoutingTable buckets {}; + RoutingTable buckets4 {}; RoutingTable buckets6 {}; std::map<InfoHash, Storage> store; @@ -416,12 +416,14 @@ private: size_t maintainStorage(InfoHash id, bool force=false, DoneCallback donecb=nullptr); // Buckets + RoutingTable& buckets(sa_family_t af) { return af == AF_INET ? buckets4 : buckets6; } + const RoutingTable& buckets(sa_family_t af) const { return af == AF_INET ? buckets4 : buckets6; } Bucket* findBucket(const InfoHash& id, sa_family_t af) { RoutingTable::iterator b; switch (af) { case AF_INET: - b = buckets.findBucket(id); - return b == buckets.end() ? nullptr : &(*b); + b = buckets4.findBucket(id); + return b == buckets4.end() ? nullptr : &(*b); case AF_INET6: b = buckets6.findBucket(id); return b == buckets6.end() ? nullptr : &(*b); diff --git a/src/dht.cpp b/src/dht.cpp index 49590284766e6177788858f11d29b5c4854b2ecd..d7759347eaa644fc36d3ab0f611258b28be9180c 100644 --- a/src/dht.cpp +++ b/src/dht.cpp @@ -824,7 +824,7 @@ Dht::reportedAddr(const SockAddr& addr) void Dht::onNewNode(const std::shared_ptr<Node>& node, int confirm) { - auto& list = node->getFamily() == AF_INET ? buckets : buckets6; + auto& list = buckets(node->getFamily()); auto b = list.findBucket(node->id); if (b == list.end()) return; @@ -2256,7 +2256,7 @@ Dht::storageAddListener(const InfoHash& id, const std::shared_ptr<Node>& node, s auto vals = st->second.get(query.where.getFilter()); if (not vals.empty()) { network_engine.tellListener(node, rid, id, WANT4 | WANT6, makeToken((sockaddr*)&node->addr.first, false), - buckets.findClosestNodes(id, now, TARGET_NODES), buckets6.findClosestNodes(id, now, TARGET_NODES), + buckets4.findClosestNodes(id, now, TARGET_NODES), buckets6.findClosestNodes(id, now, TARGET_NODES), std::move(vals), query); } st->second.listeners.emplace(node, Listener {rid, now, std::forward<Query>(query)}); @@ -2322,14 +2322,16 @@ Dht::connectivityChanged(sa_family_t af) scheduler.edit(nextNodesConfirmation, now); auto& bucket_grow_time = (af == AF_INET) ? mybucket_grow_time : mybucket6_grow_time; bucket_grow_time = now; - reported_addr.erase(std::remove_if(reported_addr.begin(), reported_addr.end(), [&](const ReportedAddr& addr){ - return addr.second.getFamily() == af; - })); + for (auto& b : buckets(af)) + b.time = time_point::min(); network_engine.connectivityChanged(af); auto& searches = (af == AF_INET) ? searches4 : searches6; for (auto& sp : searches) for (auto& sn : sp.second->nodes) sn.listenStatus.clear(); + reported_addr.erase(std::remove_if(reported_addr.begin(), reported_addr.end(), [&](const ReportedAddr& addr){ + return addr.second.getFamily() == af; + })); } void @@ -2402,9 +2404,7 @@ Dht::getNodesStats(sa_family_t af, unsigned *good_return, unsigned *dubious_retu { const auto& now = scheduler.time(); unsigned good = 0, dubious = 0, cached = 0, incoming = 0; - auto& list = (af == AF_INET) ? buckets : buckets6; - - for (const auto& b : list) { + for (const auto& b : buckets(af)) { for (auto& n : b.nodes) { if (n->isGood(now)) { good++; @@ -2547,7 +2547,7 @@ Dht::dumpTables() const out << "My id " << myid << std::endl; out << "Buckets IPv4 :" << std::endl; - for (const auto& b : buckets) + for (const auto& b : buckets4) dumpBucket(b, out); out << "Buckets IPv6 :" << std::endl; for (const auto& b : buckets6) @@ -2593,9 +2593,8 @@ Dht::getStorageLog() const std::string Dht::getRoutingTablesLog(sa_family_t af) const { - auto& list = (af == AF_INET) ? buckets : buckets6; std::stringstream out; - for (const auto& b : list) + for (const auto& b : buckets(af)) dumpBucket(b, out); return out.str(); } @@ -2641,7 +2640,7 @@ Dht::Dht(int s, int s6, Config config) return; if (s >= 0) { - buckets = {Bucket {AF_INET}}; + buckets4 = {Bucket {AF_INET}}; if (!set_nonblocking(s, 1)) throw DhtException("Can't set socket to non-blocking mode"); } @@ -2787,7 +2786,7 @@ Dht::maintainStorage(InfoHash id, bool force, DoneCallback donecb) { bool want4 = true, want6 = true; - auto nodes = buckets.findClosestNodes(id, now); + auto nodes = buckets4.findClosestNodes(id, now); if (!nodes.empty()) { if (force || id.xorCmp(nodes.back()->id, myid) < 0) { for (auto &value : local_storage->second.getValues()) { @@ -2864,7 +2863,7 @@ Dht::expire() uniform_duration_distribution<> time_dis(std::chrono::minutes(2), std::chrono::minutes(6)); auto expire_stuff_time = scheduler.time() + duration(time_dis(rd)); - expireBuckets(buckets); + expireBuckets(buckets4); expireBuckets(buckets6); expireStorage(); expireSearches(); @@ -2887,12 +2886,12 @@ Dht::confirmNodes() search(myid, AF_INET6); } - soon |= bucketMaintenance(buckets); + soon |= bucketMaintenance(buckets4); soon |= bucketMaintenance(buckets6); if (!soon) { if (mybucket_grow_time >= now - seconds(150)) - soon |= neighbourhoodMaintenance(buckets); + soon |= neighbourhoodMaintenance(buckets4); if (mybucket6_grow_time >= now - seconds(150)) soon |= neighbourhoodMaintenance(buckets6); } @@ -2978,8 +2977,8 @@ Dht::exportNodes() { const auto& now = scheduler.time(); std::vector<NodeExport> nodes; - const auto b4 = buckets.findBucket(myid); - if (b4 != buckets.end()) { + const auto b4 = buckets4.findBucket(myid); + if (b4 != buckets4.end()) { for (auto& n : b4->nodes) if (n->isGood(now)) nodes.push_back(n->exportNode()); @@ -2990,7 +2989,7 @@ Dht::exportNodes() if (n->isGood(now)) nodes.push_back(n->exportNode()); } - for (auto b = buckets.begin(); b != buckets.end(); ++b) { + for (auto b = buckets4.begin(); b != buckets4.end(); ++b) { if (b == b4) continue; for (auto& n : b->nodes) if (n->isGood(now)) @@ -3056,7 +3055,7 @@ Dht::onError(std::shared_ptr<Request> req, DhtProtocolException e) { void Dht::onReportedAddr(const InfoHash& id, const SockAddr& addr) { - const auto& b = (addr.getFamily() == AF_INET ? buckets : buckets6).findBucket(id); + const auto& b = buckets(addr.getFamily()).findBucket(id); b->time = scheduler.time(); if (addr.second) reportedAddr(addr); @@ -3075,7 +3074,7 @@ Dht::onFindNode(std::shared_ptr<Node> node, InfoHash& target, want_t want) NetworkEngine::RequestAnswer answer; answer.ntoken = makeToken((sockaddr*)&node->addr.first, false); if (want & WANT4) - answer.nodes4 = buckets.findClosestNodes(target, now, TARGET_NODES); + answer.nodes4 = buckets4.findClosestNodes(target, now, TARGET_NODES); if (want & WANT6) answer.nodes6 = buckets6.findClosestNodes(target, now, TARGET_NODES); return answer; @@ -3095,7 +3094,7 @@ Dht::onGetValues(std::shared_ptr<Node> node, InfoHash& hash, want_t, const Query NetworkEngine::RequestAnswer answer {}; auto st = store.find(hash); answer.ntoken = makeToken((sockaddr*)&node->addr.first, false); - answer.nodes4 = buckets.findClosestNodes(hash, now, TARGET_NODES); + answer.nodes4 = buckets4.findClosestNodes(hash, now, TARGET_NODES); answer.nodes6 = buckets6.findClosestNodes(hash, now, TARGET_NODES); if (st != store.end() && not st->second.empty()) { answer.values = st->second.get(query.where.getFilter()); @@ -3239,8 +3238,7 @@ Dht::onAnnounce(std::shared_ptr<Node> node, { // We store a value only if we think we're part of the // SEARCH_NODES nodes around the target id. - auto closest_nodes = (node->getFamily() == AF_INET ? buckets : buckets6) - .findClosestNodes(hash, scheduler.time(), SEARCH_NODES); + auto closest_nodes = buckets(node->getFamily()).findClosestNodes(hash, scheduler.time(), SEARCH_NODES); if (closest_nodes.size() >= TARGET_NODES and hash.xorCmp(closest_nodes.back()->id, myid) < 0) { DHT_LOG.WARN("[node %s] announce too far from the target. Dropping value.", node->toString().c_str()); return {};