From e26055ab51f18f38ec5a478ffe78625e99ebd0a0 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 21 Sep 2026 21:06:18 -0400 Subject: [PATCH] don't split not full bucket. Check if middleID bit >= 160 --- libi2pd_client/TorrentsDHT.cpp | 33 +++++++++++++++++++-------------- libi2pd_client/TorrentsDHT.h | 5 +++-- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/libi2pd_client/TorrentsDHT.cpp b/libi2pd_client/TorrentsDHT.cpp index 3f1e1888..d70d3e83 100644 --- a/libi2pd_client/TorrentsDHT.cpp +++ b/libi2pd_client/TorrentsDHT.cpp @@ -17,25 +17,27 @@ namespace i2p { namespace torrents { - NodeID Bucket::GetMiddleID () const + std::optional Bucket::GetMiddleID () const { + uint8_t bit = std::max (start.FindLowestBit (), next ? next->start.FindLowestBit () : -1) + 1; + if (bit >= NodeID::len * 8) return {}; NodeID middleID = start; - int bit = std::max (start.FindLowestBit (), next ? next->start.FindLowestBit () : -1) + 1; middleID[bit >> 3] |= (0x80 >> (bit & 0x07)); - return middleID; + return { middleID }; } - void Bucket::Split () + bool Bucket::Split () { auto middleID = GetMiddleID (); - auto newBucket = new Bucket (middleID); + if (!middleID) return false; + auto newBucket = new Bucket (*middleID); newBucket->next = next; next = newBucket; // move some nodes auto it = nodes.begin (); while (it != nodes.end ()) { - if ((*it)->id < middleID) + if ((*it)->id < *middleID) it++; // stay in old bucket else { @@ -45,6 +47,7 @@ namespace torrents newBucket->nodes.push_back (node); } } + return true; } RoutingTable::RoutingTable (const NodeID& ourNode): @@ -104,16 +107,18 @@ namespace torrents if (id == m_OurNode) return nullptr; auto bucket = FindBucket (id); if (!bucket) return nullptr; - if (bucket->IsFull () && !bucket->IsInBucket (m_OurNode)) return nullptr; + if (bucket->IsFull ()) + { + if (!bucket->IsInBucket (m_OurNode)) return nullptr; + do + { + if (!bucket->Split ()) return nullptr; + bucket = FindBucket (id); + } + while (bucket->IsFull ()); + } std::shared_ptr node; - do - { - bucket->Split (); - bucket = FindBucket (id); - } - while (bucket->IsFull ()); - if (bucket) { node = std::make_shared(id, peer, port); diff --git a/libi2pd_client/TorrentsDHT.h b/libi2pd_client/TorrentsDHT.h index eee4e3fb..a47312c7 100644 --- a/libi2pd_client/TorrentsDHT.h +++ b/libi2pd_client/TorrentsDHT.h @@ -18,6 +18,7 @@ #include #include #include +#include #include "Identity.h" #include "I2PService.h" #include "util.h" @@ -75,8 +76,8 @@ namespace torrents Bucket (const NodeID& start1): next (nullptr), start (start1) {} bool IsFull () const { return nodes.size () >= MAX_BUCKET_CAPACITY; } bool IsInBucket (const NodeID& id) const { return id >= start && (!next || id < next->start); } - NodeID GetMiddleID () const; - void Split (); + std::optional GetMiddleID () const; + bool Split (); }; class RoutingTable