From daaa336276c2a959a12c24ec8256614152d1d0bb Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 28 Sep 2026 12:01:11 -0400 Subject: [PATCH] generate random nodeid in bucket --- libi2pd_client/TorrentsDHT.cpp | 39 ++++++++++++++++++++++++++++------ libi2pd_client/TorrentsDHT.h | 1 + 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/libi2pd_client/TorrentsDHT.cpp b/libi2pd_client/TorrentsDHT.cpp index 4f44ff9a..1670cc6f 100644 --- a/libi2pd_client/TorrentsDHT.cpp +++ b/libi2pd_client/TorrentsDHT.cpp @@ -59,6 +59,31 @@ namespace torrents return { middleID }; } + NodeID Bucket::GetRandomID (std::mt19937& rng) const + { + /*NodeID randomID; + bool isStart = true, isNext = true; + for (size_t i = 0; i < randomID.size (); i++) + { + auto m1 = isStart ? start[i] : 0x00; + auto m2 = (isNext && next) ? next->start[i] : 0xFF; + randomID[i] = (m1 != m2) ? (rng () % std::abs (m2 - m1)) : m1; + if (randomID[i] > start[i]) isStart = false; + if (next && randomID[i] < next->start[i]) isNext = false; + } + return randomID;*/ + uint8_t bit = std::max (start.FindLowestBit (), next ? next->start.FindLowestBit () : -1) + 1; + if (bit >= NodeID::len * 8) return start; + + NodeID randomID; + auto d = div (bit, 8); + memcpy (randomID.data (), start.data (), d.quot); + randomID[d.quot] = (start[d.quot] & (0xFF00 >> d.rem)) | (rng () & (0xFF >> d.rem)); + for (int i = d.quot + 1; i < 20; i++) + randomID[i] = rng (); + return randomID; + } + bool Bucket::Split () { auto middleID = GetMiddleID (); @@ -250,13 +275,13 @@ namespace torrents { if (!bucket->IsFull () && !bucket->nodes.empty ()) { - auto middleID = bucket->GetMiddleID (); - if (middleID) // TODO: pick another id - { - auto it = bucket->nodes.begin (); - std::advance (it, rng () % bucket->nodes.size ()); - ret.emplace_back (std::make_pair(*middleID, it->first)); - } + auto randomID = bucket->GetRandomID (rng); + auto it = bucket->nodes.begin (); + while (it != bucket->nodes.end () && randomID > it->first) it++; + if (it != bucket->nodes.end ()) + ret.emplace_back (std::make_pair (randomID, it->first)); + else + ret.emplace_back (std::make_pair (randomID, bucket->nodes.rbegin ()->first)); } bucket = bucket->next; } diff --git a/libi2pd_client/TorrentsDHT.h b/libi2pd_client/TorrentsDHT.h index 4c2d812c..7363ef97 100644 --- a/libi2pd_client/TorrentsDHT.h +++ b/libi2pd_client/TorrentsDHT.h @@ -100,6 +100,7 @@ namespace torrents bool ContainsNode (const NodeID& id) const; void UpdateNode (const NodeID& id); std::optional GetMiddleID () const; + NodeID GetRandomID (std::mt19937& rng) const; bool Split (); };