mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2026-10-23 23:45:03 +00:00
FindClosestNodes, select DHT port from wider range
This commit is contained in:
1 parent
814fa61d05
commit
7a826ed069
3 files changed
+47
-38
No files matched your search
@@ -17,18 +17,6 @@ namespace i2p
|
||||
{
|
||||
namespace torrents
|
||||
{
|
||||
NodeDistance operator^(const NodeID& node1, const NodeID& node2)
|
||||
{
|
||||
NodeDistance d;
|
||||
|
||||
d.l[0] = node1.l[0] ^ node2.l[0];
|
||||
d.l[1] = node1.l[1] ^ node2.l[1];
|
||||
d.l[2] = node1.l[2] ^ node2.l[2];
|
||||
d.l[3] = node1.l[3] ^ node2.l[3];
|
||||
d.l[4] = node1.l[4] ^ node2.l[4];
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
RoutingTable::RoutingTable (const NodeID& ourNode):
|
||||
m_OurNode (ourNode)
|
||||
@@ -36,7 +24,7 @@ namespace torrents
|
||||
m_Buckets.push_back (std::make_shared<Bucket> ());
|
||||
}
|
||||
|
||||
std::shared_ptr<Bucket> RoutingTable::FindBucket (const NodeID& id)
|
||||
std::shared_ptr<Bucket> RoutingTable::FindBucket (const Torrent::InfoHash& id) const
|
||||
{
|
||||
if (m_Buckets.empty ()) return nullptr;
|
||||
auto it = m_Buckets.begin ();
|
||||
@@ -59,23 +47,47 @@ namespace torrents
|
||||
return node;
|
||||
}
|
||||
|
||||
std::list<std::pair<std::shared_ptr<Node>, Distance> > RoutingTable::FindClosestNodes (const Torrent::InfoHash& infoHash, size_t num) const
|
||||
{
|
||||
std::list<std::pair<std::shared_ptr<Node>, Distance> > ret;
|
||||
if (num > 0)
|
||||
{
|
||||
auto bucket = FindBucket (infoHash);
|
||||
if (bucket)
|
||||
{
|
||||
for (auto it: bucket->nodes)
|
||||
{
|
||||
auto nodeDistance = it->id ^ infoHash;
|
||||
auto it1 = std::find_if (ret.begin (), ret.end (),
|
||||
[&nodeDistance](const std::pair<std::shared_ptr<Node>, Distance>& alreadyFound)
|
||||
{
|
||||
return nodeDistance < alreadyFound.second;
|
||||
});
|
||||
ret.insert (it1, { it, nodeDistance } );
|
||||
}
|
||||
if (ret.size () > num) ret.resize (num);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
TorrentsDHT::TorrentsDHT (TorrentsTunnel& tunnel, uint16_t port):
|
||||
m_Tunnel (tunnel), m_Port (port)
|
||||
{
|
||||
auto dest = tunnel.GetLocalDestination ();
|
||||
if (dest)
|
||||
{
|
||||
memcpy (m_NodeID.buf, dest->GetIdentHash (), m_NodeID.len);
|
||||
m_NodeID.buf[4] ^= (port >> 8);
|
||||
m_NodeID.buf[5] ^= (port & 0xFF);
|
||||
memcpy (m_NodeInfo.data (), m_NodeID.buf, m_NodeID.len);
|
||||
memcpy (m_NodeInfo.data () + m_NodeID.len, dest->GetIdentHash (), i2p::data::IdentHash::len);
|
||||
memcpy (m_NodeID.data (), dest->GetIdentHash (), m_NodeID.size ());
|
||||
m_NodeID[4] ^= (port >> 8);
|
||||
m_NodeID[5] ^= (port & 0xFF);
|
||||
memcpy (m_NodeInfo.data (), m_NodeID.data (), m_NodeID.size ());
|
||||
memcpy (m_NodeInfo.data () + m_NodeID.size (), dest->GetIdentHash (), i2p::data::IdentHash::len);
|
||||
htobe16buf (m_NodeInfo.data () + m_NodeInfo.size () - 2, port);
|
||||
m_RoutingTable = std::make_unique<RoutingTable> (m_NodeID);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (m_NodeID.buf, 0, m_NodeID.len);
|
||||
m_NodeID.fill (0);
|
||||
m_NodeInfo.fill (0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,34 +17,29 @@
|
||||
#include <array>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include "Identity.h"
|
||||
#include "I2PService.h"
|
||||
#include "util.h"
|
||||
#include "Torrents.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace torrents
|
||||
{
|
||||
struct NodeID
|
||||
using Distance = Torrent::InfoHash;
|
||||
struct NodeID: public Torrent::InfoHash
|
||||
{
|
||||
static constexpr size_t len = SHA_DIGEST_LENGTH;
|
||||
|
||||
union // 4 bytes aligned
|
||||
static constexpr size_t len = std::tuple_size<Torrent::InfoHash>::value;
|
||||
constexpr Distance operator^(const Torrent::InfoHash& hash)
|
||||
{
|
||||
uint8_t buf[len];
|
||||
uint32_t l[len/4];
|
||||
};
|
||||
|
||||
auto operator<=>(const NodeID& other) const { return memcmp (buf, other.buf, len) <=> 0; }
|
||||
bool operator==(const NodeID& other) const { return !memcmp (buf, other.buf, len); }
|
||||
static constexpr NodeID Zero () { NodeID n; std::fill_n (n.buf, len, 0); return n; }
|
||||
Distance d;
|
||||
for (size_t i = 0; i < size (); i++)
|
||||
d[i] = (*this)[i] ^ hash[i];
|
||||
return d;
|
||||
}
|
||||
};
|
||||
|
||||
struct NodeDistance: public NodeID
|
||||
{
|
||||
};
|
||||
NodeDistance operator^(const NodeID& node1, const NodeID& node2);
|
||||
|
||||
struct Node
|
||||
{
|
||||
NodeID id;
|
||||
@@ -61,7 +56,7 @@ namespace torrents
|
||||
std::list<std::shared_ptr<Node> > nodes;
|
||||
NodeID start;
|
||||
|
||||
Bucket (): start (NodeID::Zero ()) {}
|
||||
Bucket (): start{} {}
|
||||
};
|
||||
|
||||
class RoutingTable
|
||||
@@ -71,10 +66,11 @@ namespace torrents
|
||||
RoutingTable (const NodeID& ourNode);
|
||||
|
||||
std::shared_ptr<Node> AddNode (const NodeID& id, i2p::data::IdentHash& peer, uint16_t port);
|
||||
std::list<std::pair<std::shared_ptr<Node>, Distance> > FindClosestNodes (const Torrent::InfoHash& infoHash, size_t num) const;
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<Bucket> FindBucket (const NodeID& id);
|
||||
std::shared_ptr<Bucket> FindBucket (const Torrent::InfoHash& id) const;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@ namespace torrents
|
||||
i2p::client::I2PService (localDestination), m_Name (name), m_PeerID ("-I2PD-"),
|
||||
m_TorrentsDir (torrentsDir), m_TrackerRequestsCheckTimer (GetService ()),
|
||||
m_KeepAliveCheckTimer (GetService ()), m_ReconnectCheckTimer (GetService ()),
|
||||
m_TorrentsStatusUpdateTimer (GetService ()), m_DHT (*this, localDestination->GetRng()() % 1000 + 6000)
|
||||
m_TorrentsStatusUpdateTimer (GetService ()),
|
||||
m_DHT (*this, TORRENT_PORT + (localDestination ? localDestination->GetRng()() % (65535 - TORRENT_PORT - 1) : 1))
|
||||
{
|
||||
if (localDestination)
|
||||
m_PeerID += localDestination->GetIdentHash ().ToBase64 ();
|
||||
|
||||
Reference in new issue
Block a user