From e3be45ec50c930b65ccc7cdb1fec8dd8694051ec Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 9 Sep 2026 10:45:52 -0400 Subject: [PATCH] receive I2P_PEX messages --- libi2pd_client/Torrents.cpp | 33 +++++++++++++++++++++++++++++++-- libi2pd_client/Torrents.h | 5 ++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/libi2pd_client/Torrents.cpp b/libi2pd_client/Torrents.cpp index cd95c260..26599ed2 100644 --- a/libi2pd_client/Torrents.cpp +++ b/libi2pd_client/Torrents.cpp @@ -932,8 +932,8 @@ namespace torrents m_IsHandshakeSent (false), m_IsEstablished (false), m_IsChoked (true), m_IsRemoteChoked (true), m_IsInterested (false), m_IsRemoteInterested (false), m_LastReceiveTime (0), m_LastSendTime (0), m_NumRequests (0), m_NumPieces (0), m_LastRequestedPieceIndex (-1), - m_RemoteMsgIDUtMetadata (0), m_RemoteMetadataSize (0), m_IsFast (false), - m_SuggestedPieceIndex (-1), m_Downloaded (0), m_Uploaded (0) + m_RemoteMsgIDUtMetadata (0), m_RemoteMsgIDI2PPEX (0), m_RemoteMetadataSize (0), + m_IsFast (false), m_SuggestedPieceIndex (-1), m_Downloaded (0), m_Uploaded (0) { ResetStats (); } @@ -1830,6 +1830,11 @@ namespace torrents m_ExtendedMessageHandlers.emplace (EXTENSION_MSGID_UT_METADATA, &PeerConnection::HandleUtMetadataExtension); m_RemoteMsgIDUtMetadata = msgID; } + else if (extensionName == EXTENSION_NAME_I2P_PEX) + { + m_ExtendedMessageHandlers.emplace (EXTENSION_MSGID_I2P_PEX, &PeerConnection::HandleI2PPEXExtension); + m_RemoteMsgIDI2PPEX = msgID; + } } void PeerConnection::SendExtendedMsg (uint8_t extendedMsgID, std::string_view payload, std::string_view data) @@ -1839,6 +1844,7 @@ namespace torrents { str = CreateDictionary ({ { "m", CreateDictionary ({ + { EXTENSION_NAME_I2P_PEX, CreateInteger (EXTENSION_MSGID_I2P_PEX) }, { EXTENSION_NAME_UT_METADATA, CreateInteger (EXTENSION_MSGID_UT_METADATA) } }) }, { "metadata_size", CreateInteger (m_Torrent->GetInfo ().size ()) }, @@ -1902,6 +1908,7 @@ namespace torrents } case 1: // data { + if (m_Torrent->GetLength ()) break; // we have info size_t offset = piece*REQUEST_BLOCK_SIZE; if (offset > m_RemoteMetadataSize) break; size_t size = m_RemoteMetadataSize - offset; @@ -1938,6 +1945,28 @@ namespace torrents } } + void PeerConnection::HandleI2PPEXExtension (const uint8_t * buf, size_t len) + { + std::unordered_set newPeers; + ParseDictionary (std::string_view ((const char *)buf, len), + [&newPeers](std::string_view key, std::string_view buf)->size_t + { + if (key == "added") + { + auto [idents, l] = ExtractByteString (buf); + if (l && !(l & 0x20)) + while (!idents.empty ()) + { + newPeers.emplace (i2p::data::IdentHash ((const uint8_t *)idents.substr (0, i2p::data::IdentHash::len).data ())); + idents = idents.substr (i2p::data::IdentHash::len); + }; + return l; + } + return 0; + }); + LogPrint (eLogDebug, "Torrents: I2P_PEX ", newPeers.size (), " added peers received"); + } + std::optional PeerConnection::GetNextBlockToRequest () { auto block = m_Torrent->GetNextBlockToRequest (shared_from_this (), true); // skip already requested pieces diff --git a/libi2pd_client/Torrents.h b/libi2pd_client/Torrents.h index e6f1b555..91fce6c2 100644 --- a/libi2pd_client/Torrents.h +++ b/libi2pd_client/Torrents.h @@ -64,6 +64,8 @@ namespace torrents // extensions constexpr std::string_view EXTENSION_NAME_UT_METADATA { "ut_metadata" }; constexpr uint8_t EXTENSION_MSGID_UT_METADATA = 1; + constexpr std::string_view EXTENSION_NAME_I2P_PEX { "i2p_pex" }; + constexpr uint8_t EXTENSION_MSGID_I2P_PEX = 2; enum MessageType { @@ -354,6 +356,7 @@ namespace torrents void SendExtendedMsg (uint8_t extendedMsgID = 0, std::string_view payload = "", std::string_view data = ""); void AddExtendedMsgHandler (std::string_view extensionName, int64_t msgID); void HandleUtMetadataExtension (const uint8_t * buf, size_t len); // BEP9 + void HandleI2PPEXExtension (const uint8_t * buf, size_t len); // BEP11 std::optional GetNextBlockToRequest (); bool RequestNextBlocks (); @@ -378,7 +381,7 @@ namespace torrents std::unique_ptr m_HandshakeReceiveTimer; // BEP10 std::unordered_map m_ExtendedMessageHandlers; - uint8_t m_RemoteMsgIDUtMetadata; + uint8_t m_RemoteMsgIDUtMetadata, m_RemoteMsgIDI2PPEX; // BEP9 size_t m_RemoteMetadataSize; std::vector m_RemoteMetadata;