diff -U2 -r /var/lib/copr-rpmbuild/results/i2pd-git/upstream-unpacked/Source0/i2pd-openssl/libi2pd_client/Torrents.cpp /var/lib/copr-rpmbuild/results/i2pd-git/srpm-unpacked/i2pd-openssl.tar.gz-extract/i2pd-openssl/libi2pd_client/Torrents.cpp --- /var/lib/copr-rpmbuild/results/i2pd-git/upstream-unpacked/Source0/i2pd-openssl/libi2pd_client/Torrents.cpp 2026-09-23 00:49:14.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/i2pd-git/srpm-unpacked/i2pd-openssl.tar.gz-extract/i2pd-openssl/libi2pd_client/Torrents.cpp 2026-09-22 18:34:19.000000000 +0000 @@ -176,14 +176,4 @@ } - std::string CreateList (const std::vector& items) - { - std::stringstream s; - s << 'l'; - for (const auto& it: items) - s << it; - s << 'e'; - return s.str (); - } - //------------------------------------ @@ -1077,16 +1067,4 @@ } - std::unordered_set Torrent::GetAllPeers () const - { - std::unordered_set ret; - for (const auto& it: m_TrackerStats) - { - const auto& peers = std::get<0>(it); - for (const auto& it1: peers) - ret.emplace (it1); - } - return ret; - } - uint64_t Torrent::GetNextTrackerRequestTime (size_t trackerID) const { @@ -2158,7 +2136,4 @@ if (m_RemoteMsgIDI2PPEX && m_Stream && m_Stream->IsIncoming ()) NotifyPEXPeers (); - // BEP5 - if (m_RemoteMsgIDI2PDHT) - SendDHTPortAdvertisement (); } else @@ -2198,5 +2173,5 @@ str = CreateDictionary ({ { "m", CreateDictionary ({ - { EXTENSION_NAME_I2P_DHT, CreateInteger (EXTENSION_MSGID_I2P_DHT) }, +// { EXTENSION_NAME_I2P_DHT, CreateInteger (EXTENSION_MSGID_I2P_DHT) }, { EXTENSION_NAME_I2P_PEX, CreateInteger (EXTENSION_MSGID_I2P_PEX) }, { EXTENSION_NAME_UT_METADATA, CreateInteger (EXTENSION_MSGID_UT_METADATA) } @@ -2386,10 +2361,4 @@ } - void PeerConnection::SendDHTPortAdvertisement () - { - auto [port, rport] = GetTorrentsTunnel ()->GetDHTPorts (); - SendExtendedMsg (m_RemoteMsgIDI2PDHT, CreateDictionary ({{ "port", CreateInteger (port) }, { "rport", CreateInteger (rport) }})); - } - std::optional PeerConnection::GetNextBlockToRequest () { diff -U2 -r /var/lib/copr-rpmbuild/results/i2pd-git/upstream-unpacked/Source0/i2pd-openssl/libi2pd_client/Torrents.h /var/lib/copr-rpmbuild/results/i2pd-git/srpm-unpacked/i2pd-openssl.tar.gz-extract/i2pd-openssl/libi2pd_client/Torrents.h --- /var/lib/copr-rpmbuild/results/i2pd-git/upstream-unpacked/Source0/i2pd-openssl/libi2pd_client/Torrents.h 2026-09-23 00:49:14.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/i2pd-git/srpm-unpacked/i2pd-openssl.tar.gz-extract/i2pd-openssl/libi2pd_client/Torrents.h 2026-09-22 18:34:19.000000000 +0000 @@ -45,5 +45,4 @@ std::string CreateInteger (int64_t v); std::string CreateDictionary (const std::vector >& items); - std::string CreateList (const std::vector& items); @@ -286,7 +285,6 @@ std::pair, boost::logic::tribool> CreateBitfield () const; // (bitfield, true - all false - none) bool ApplyBitfield (const std::vector& bitfield); // return true if complete - std::unordered_set GetNonConnectedPeers (); - std::unordered_set GetNonConnectedPeers (size_t trackerID); - std::unordered_set GetAllPeers () const; + std::unordered_set GetNonConnectedPeers (); + std::unordered_set GetNonConnectedPeers (size_t trackerID); RequestedBlock GetNextBlockToRequest (std::shared_ptr conn, bool skipRequested = true); std::vector GetPieceFileFragments (int index) const; @@ -442,5 +440,4 @@ void NotifyPEXPeers (); // BEP11 void HandleI2PDHTExtension (const uint8_t * buf, size_t len); // BEP5 - void SendDHTPortAdvertisement (); std::optional GetNextBlockToRequest (); @@ -448,4 +445,5 @@ bool SendRequestedBlock (const RequestedBlock& requestedBlock); + private: diff -U2 -r /var/lib/copr-rpmbuild/results/i2pd-git/upstream-unpacked/Source0/i2pd-openssl/libi2pd_client/TorrentsDHT.cpp /var/lib/copr-rpmbuild/results/i2pd-git/srpm-unpacked/i2pd-openssl.tar.gz-extract/i2pd-openssl/libi2pd_client/TorrentsDHT.cpp --- /var/lib/copr-rpmbuild/results/i2pd-git/upstream-unpacked/Source0/i2pd-openssl/libi2pd_client/TorrentsDHT.cpp 2026-09-23 00:49:14.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/i2pd-git/srpm-unpacked/i2pd-openssl.tar.gz-extract/i2pd-openssl/libi2pd_client/TorrentsDHT.cpp 2026-09-22 18:34:19.000000000 +0000 @@ -10,5 +10,5 @@ #include -#include +#include "I2PEndian.h" #include "TorrentsTunnel.h" #include "TorrentsDHT.h" @@ -18,14 +18,4 @@ namespace torrents { - std::shared_ptr Bucket::FindNode (const NodeID& id) const - { - auto it = std::find_if (nodes.begin (), nodes.end (), - [&id](std::shared_ptr node) - { - return node->id == id; - }); - return (it != nodes.end ()) ? *it : nullptr; - } - std::optional Bucket::GetMiddleID () const { @@ -118,6 +108,4 @@ auto bucket = FindBucket (id); if (!bucket) return nullptr; - std::shared_ptr node = bucket->FindNode (id); - if (node) return node; if (bucket->IsFull ()) { @@ -130,4 +118,6 @@ while (bucket->IsFull ()); } + + std::shared_ptr node; if (bucket) { @@ -208,9 +198,14 @@ void TorrentsDHT::HandleRawDatagram (const uint8_t * buf, size_t len) { - // response or error + LogPrint (eLogDebug, "TorrentsDHT: Raw datagram received"); + } + + void TorrentsDHT::HandleDatagram (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, + const uint8_t * buf, size_t len, const i2p::util::Mapping * options) + { char type = 0; - std::string transactionID, id; + std::string transactionID, query, id; ParseDictionary (std::string_view ((const char *)buf, len), - [&type, &transactionID, &id](std::string_view key, std::string_view buf)->size_t + [&type, &transactionID, &query, &id](std::string_view key, std::string_view buf)->size_t { if (key == "y") @@ -226,5 +221,11 @@ return l; } - else if (key == "r") + else if (key == "q") + { + auto [value, l] = ExtractByteString (buf); + if (l) query = value; + return l; + } + else if (key == "a" || key == "r") { return ParseDictionary (buf, @@ -246,13 +247,13 @@ switch (type) { + case 'q': + HandleQuery (from.GetIdentHash (), fromPort, transactionID, query, id); + break; case 'r': - HandleResponse (transactionID, id); + LogPrint (eLogDebug, "TorrentsDHT: Response msg received"); break; case 'e': LogPrint (eLogDebug, "TorrentsDHT: Error msg received"); break; - case 'q': - LogPrint (eLogError, "TorrentsDHT: Query can't come as raw datagram"); - break; default: LogPrint (eLogInfo, "TorrentsDHT: Unxpected msg type ", (int)type); @@ -261,117 +262,12 @@ } - void TorrentsDHT::HandleDatagram (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, - const uint8_t * buf, size_t len, const i2p::util::Mapping * options) - { - // query - char type = 0; - std::string transactionID, query, id, infoHash; - ParseDictionary (std::string_view ((const char *)buf, len), - [&type, &transactionID, &query, &id, &infoHash](std::string_view key, std::string_view buf)->size_t - { - if (key == "y") - { - auto [value, l] = ExtractByteString (buf); - if (l && !value.empty ()) type = value[0]; - return l; - } - else if (key == "t") - { - auto [value, l] = ExtractByteString (buf); - if (l) transactionID = value; - return l; - } - else if (key == "q") - { - auto [value, l] = ExtractByteString (buf); - if (l) query = value; - return l; - } - else if (key == "a") - { - return ParseDictionary (buf, - [&id, &infoHash](std::string_view key, std::string_view buf)->size_t - { - if (key == "id") - { - auto [value, l] = ExtractByteString (buf); - if (l) id = value; - return l; - } - else if (key == "info_hash") - { - auto [value, l] = ExtractByteString (buf); - if (l) infoHash = value; - return l; - } - return 0; - }); - } - return 0; - }); - if (type == 'q') - { - if (query == "ping") - HandlePingQuery (from.GetIdentHash (), fromPort, transactionID, id); - else if (query == "get_peers") - HandleGetPeersQuery (from.GetIdentHash (), fromPort, transactionID, id, infoHash); - else - LogPrint (eLogDebug, "TorrentsDHT: Unexpected query ", query); - } - else if (type) - LogPrint (eLogInfo, "TorrentsDHT: Unxpected msg type ", (int)type); - } - - void TorrentsDHT::HandlePingQuery (const i2p::data::IdentHash& fromIdent, uint16_t fromPort, - std::string_view transactionID, std::string_view id) - { - LogPrint (eLogDebug, "TorrentsDHT: Ping query msg received"); - SendPingResponse (transactionID, fromIdent, fromPort + 1); // to rport - } - - void TorrentsDHT::HandleGetPeersQuery (const i2p::data::IdentHash& fromIdent, uint16_t fromPort, - std::string_view transactionID, std::string_view id, std::string_view infoHash) - { - LogPrint (eLogDebug, "TorrentsDHT: Get peers query msg received"); - Torrent::InfoHash hash; - if (infoHash.size () < hash.size ()) - { - LogPrint (eLogInfo, "TorrentsDHT: Requested info hash is too short ", infoHash.size ()); - return; - } - memcpy (hash.data (), infoHash.data (), hash.size ()); - auto torrent = m_Tunnel.FindTorrent (hash); - if (torrent) - { - auto peers = torrent->GetAllPeers (); - if (!peers.empty ()) - SendGetPeersResponse (transactionID, peers, fromIdent, fromPort + 1); // to rport - } - } - - void TorrentsDHT::HandleResponse (std::string_view transactionID, std::string_view id) + void TorrentsDHT::HandleQuery (const i2p::data::IdentHash& fromIdent, uint16_t fromPort, + std::string_view transactionID, std::string_view query, std::string_view id) { - LogPrint (eLogDebug, "TorrentsDHT: Response msg received"); - auto it = m_Queries.find (transactionID); - if (it != m_Queries.end ()) - { - // assume ping for now - if (id.size () < NodeID::len) - { - LogPrint (eLogInfo, "TorrentsDHT: received id is too short ", id.size ()); - return; - } - if (m_RoutingTable) - { - NodeID nodeID; - memcpy (nodeID.data (), id.data (), NodeID::len); - if (m_RoutingTable->AddNode (nodeID, it->second.first, it->second.second)) - LogPrint (eLogDebug, "TorrentsDHT: Node ", it->second.first.ToBase64 (), ":", it->second.second, " added"); - else - LogPrint (eLogError, "TorrentsDHT: Failed to add node ", it->second.first.ToBase64 ()); - } - } + LogPrint (eLogDebug, "TorrentsDHT: Query msg received"); + if (query == "ping") + SendPingResponse (transactionID, fromIdent, fromPort + 1); // to rport else - LogPrint (eLogInfo, "TorrentsDHT: Query now found"); + LogPrint (eLogDebug, "TorrentsDHT: Unexpected query ", query); } @@ -401,19 +297,10 @@ const i2p::data::IdentHash& toIdent, uint16_t toPort) { - std::string transactionID; - if (m_Tunnel.GetLocalDestination ()) - { - transactionID.push_back (m_Tunnel.GetLocalDestination ()->GetRng ()() % ('z' -'a' + 1) + 'a'); - transactionID.push_back (m_Tunnel.GetLocalDestination ()->GetRng ()() % ('z' -'a' + 1) + 'a'); - } - else - transactionID = "xx"; auto msg = CreateDictionary ({ { "a", arguments }, { "q", CreateByteString (query) }, - { "t", CreateByteString (transactionID) }, + { "t", CreateByteString ("xx") }, // TODO: random { "y", CreateByteString ("q") } }); - m_Queries.insert_or_assign (transactionID, std::make_pair (toIdent, toPort)); SendDatagram (msg, toIdent, toPort); } @@ -445,19 +332,4 @@ transactionID, toIdent, toPort); } - - void TorrentsDHT::SendGetPeersResponse (std::string_view transactionID, const std::unordered_set& peers, - const i2p::data::IdentHash& toIdent, uint16_t toPort) - { - std::vector values; - for (auto& it: peers) - values.emplace_back (CreateByteString (std::string_view ((const char *)it.data (), i2p::data::IdentHash::len))); - SendResponseMsg (CreateDictionary ({ - { "id", CreateByteString (std::string_view ((const char *)m_NodeID.data (), m_NodeID.size ())) }, - { "token", CreateByteString ("12345") }, // TODO: - { "values", CreateList (values) } - }), - transactionID, toIdent, toPort); - } - } } diff -U2 -r /var/lib/copr-rpmbuild/results/i2pd-git/upstream-unpacked/Source0/i2pd-openssl/libi2pd_client/TorrentsDHT.h /var/lib/copr-rpmbuild/results/i2pd-git/srpm-unpacked/i2pd-openssl.tar.gz-extract/i2pd-openssl/libi2pd_client/TorrentsDHT.h --- /var/lib/copr-rpmbuild/results/i2pd-git/upstream-unpacked/Source0/i2pd-openssl/libi2pd_client/TorrentsDHT.h 2026-09-23 00:49:14.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/i2pd-git/srpm-unpacked/i2pd-openssl.tar.gz-extract/i2pd-openssl/libi2pd_client/TorrentsDHT.h 2026-09-22 18:34:19.000000000 +0000 @@ -14,10 +14,7 @@ #include #include -#include -#include #include #include #include -#include #include #include @@ -80,5 +77,4 @@ bool IsFull () const { return nodes.size () >= MAX_BUCKET_CAPACITY; } bool IsInBucket (const NodeID& id) const { return id >= start && (!next || id < next->start); } - std::shared_ptr FindNode (const NodeID& id) const; std::optional GetMiddleID () const; bool Split (); @@ -118,5 +114,4 @@ void Stop (); - uint16_t GetPort () const { return m_Port; }; uint16_t GetRPort () const { return m_Port + 1; }; void HandleRawDatagram (const uint8_t * buf, size_t len); @@ -128,9 +123,6 @@ void HandleDatagram (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, const i2p::util::Mapping * options); - void HandlePingQuery (const i2p::data::IdentHash& fromIdent, uint16_t fromPort, - std::string_view transactionID, std::string_view id); - void HandleGetPeersQuery (const i2p::data::IdentHash& fromIdent, uint16_t fromPort, - std::string_view transactionID, std::string_view id, std::string_view infoHash); - void HandleResponse (std::string_view transactionID, std::string_view id); + void HandleQuery (const i2p::data::IdentHash& fromIdent, uint16_t fromPort, + std::string_view transactionID, std::string_view query, std::string_view id); void SendDatagram (std::string_view msg, const i2p::data::IdentHash& toIdent, uint16_t toPort); @@ -139,6 +131,4 @@ void SendResponseMsg (std::string_view response, std::string_view transactionID, const i2p::data::IdentHash& toIdent, uint16_t toPort); void SendPingResponse (std::string_view transactionID, const i2p::data::IdentHash& toIdent, uint16_t toPort); - void SendGetPeersResponse (std::string_view transactionID, const std::unordered_set& peers, - const i2p::data::IdentHash& toIdent, uint16_t toPort); private: @@ -149,5 +139,4 @@ NodeInfo m_NodeInfo; // 20 byte Node ID + 32 byte IdentHash + 2 byte port std::unique_ptr m_RoutingTable; - std::map, std::less<> > m_Queries; }; } diff -U2 -r /var/lib/copr-rpmbuild/results/i2pd-git/upstream-unpacked/Source0/i2pd-openssl/libi2pd_client/TorrentsTunnel.h /var/lib/copr-rpmbuild/results/i2pd-git/srpm-unpacked/i2pd-openssl.tar.gz-extract/i2pd-openssl/libi2pd_client/TorrentsTunnel.h --- /var/lib/copr-rpmbuild/results/i2pd-git/upstream-unpacked/Source0/i2pd-openssl/libi2pd_client/TorrentsTunnel.h 2026-09-23 00:49:14.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/i2pd-git/srpm-unpacked/i2pd-openssl.tar.gz-extract/i2pd-openssl/libi2pd_client/TorrentsTunnel.h 2026-09-22 18:34:19.000000000 +0000 @@ -115,5 +115,4 @@ void ConnectToNewPeers (std::shared_ptr torrent, std::unordered_set& newPeers); void SendDHTPingQuery (const i2p::data::IdentHash& toIdent, uint16_t toPort); - std::pair GetDHTPorts () const { return { m_DHT.GetPort (), m_DHT.GetRPort () }; } const char* GetName() const override { return m_Name.c_str (); }