diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 315173c3..26d21037 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -1047,6 +1047,7 @@ namespace client std::string trackers = section.second.get (TORRENTS_TUNNEL_TRACKERS, ""); i2p::data::SigningKeyType sigType = section.second.get (TORRENTS_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); if (sigType > i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519) sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519; + bool dht = section.second.get (TORRENTS_TUNNEL_DHT, true); // I2CP i2p::util::Mapping options; @@ -1077,7 +1078,7 @@ namespace client else localDestination->SetPublic (true); } - auto torrentsTunnel = std::make_shared (name, localDestination, torrentsDir, trackers); + auto torrentsTunnel = std::make_shared (name, localDestination, torrentsDir, trackers, dht); auto [iit, inserted] = m_TorrentsTunnels.emplace (localDestination->GetIdentHash (), torrentsTunnel); if (inserted) { @@ -1098,7 +1099,7 @@ namespace client else LogPrint (eLogError, "Clients: Failed to create torrents tunnel ", name, ". Duplicate keys ", keys); #else - LogPrint (eLogError, "Clients: Torrents tunnels are not supported. Comppile without NO_TORRENTS"); + LogPrint (eLogError, "Clients: Torrents tunnels are not supported. Compile without NO_TORRENTS"); #endif } else diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index a726d29c..09fa97f9 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -81,6 +81,7 @@ namespace client const char TORRENTS_TUNNEL_RPC_PORT[] = "rpcport"; const char TORRENTS_TUNNEL_RPC_PATH[] = "rpcpath"; const char TORRENTS_TUNNEL_RPC_ADDRESS[] = "rpcaddress"; + const char TORRENTS_TUNNEL_DHT[] = "dht"; constexpr int STOP_DESTINATIONS_TIMEOUT = 8; // in seconds diff --git a/libi2pd_client/Torrents.cpp b/libi2pd_client/Torrents.cpp index fc1bae9f..1f669d1b 100644 --- a/libi2pd_client/Torrents.cpp +++ b/libi2pd_client/Torrents.cpp @@ -2146,7 +2146,7 @@ namespace torrents if (m_RemoteMsgIDI2PPEX && m_Stream && m_Stream->IsIncoming ()) NotifyPEXPeers (); // BEP5 - if (m_RemoteMsgIDI2PDHT) + if (m_RemoteMsgIDI2PDHT && GetTorrentsTunnel ()->SupportsDHT ()) SendDHTPortAdvertisement (); } else @@ -2180,15 +2180,21 @@ namespace torrents void PeerConnection::SendExtendedMsg (uint8_t extendedMsgID, std::string_view payload, std::string_view data) { + const static std::string messages = GetTorrentsTunnel ()->SupportsDHT () ? + CreateDictionary ({ + { 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) } + }): + CreateDictionary ({ + { EXTENSION_NAME_I2P_PEX, CreateInteger (EXTENSION_MSGID_I2P_PEX) }, + { EXTENSION_NAME_UT_METADATA, CreateInteger (EXTENSION_MSGID_UT_METADATA) } + }); std::string str; if (!extendedMsgID) // handshake { str = CreateDictionary ({ - { "m", CreateDictionary ({ - { 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) } - }) }, + { "m", messages }, { "metadata_size", CreateInteger (m_Torrent->GetInfo ().size ()) }, { "reqq", CreateInteger (MAX_INCOMING_REQUESTS_QUEUE_SIZE) }, { "v", CreateByteString ("i2pd") } diff --git a/libi2pd_client/TorrentsDHT.cpp b/libi2pd_client/TorrentsDHT.cpp index 561daba7..00d76cc0 100644 --- a/libi2pd_client/TorrentsDHT.cpp +++ b/libi2pd_client/TorrentsDHT.cpp @@ -501,7 +501,7 @@ namespace torrents m_Torrents.emplace (hash, torrent); } uint64_t token = m_Tunnel.GetLocalDestination () ? m_Tunnel.GetLocalDestination ()->GetRng ()() : 1; - it->second->AddIncomingGetPeerNode (token, node); + torrent->AddIncomingGetPeerNode (token, node); if (m_RoutingTable) { diff --git a/libi2pd_client/TorrentsTunnel.cpp b/libi2pd_client/TorrentsTunnel.cpp index cc02e9c4..4fa0659b 100644 --- a/libi2pd_client/TorrentsTunnel.cpp +++ b/libi2pd_client/TorrentsTunnel.cpp @@ -25,12 +25,11 @@ namespace i2p namespace torrents { TorrentsTunnel::TorrentsTunnel (std::string_view name, std::shared_ptr localDestination, - std::string_view torrentsDir, std::string_view trackers): + std::string_view torrentsDir, std::string_view trackers, bool dht): 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, TORRENT_PORT + (localDestination ? localDestination->GetRng()() % (65535 - TORRENT_PORT - 1) : 1)) + m_TorrentsStatusUpdateTimer (GetService ()) { if (localDestination) m_PeerID += localDestination->GetIdentHash ().ToBase64 (); @@ -59,13 +58,15 @@ namespace torrents for (const auto& it: hosts) m_Trackers.emplace_back (TrackerInfo{ it.second, true, 0, 0, 0 }); } + if (dht) + m_DHT = std::make_unique(*this, TORRENT_PORT + (localDestination ? localDestination->GetRng()() % (65535 - TORRENT_PORT - 1) : 1)); } void TorrentsTunnel::Start () { i2p::client::I2PService::Start (); m_DiskIOService.Start (); - m_DHT.Start (); + if (m_DHT) m_DHT->Start (); auto dgramDest = GetLocalDestination ()->CreateDatagramDestination (true, i2p::datagram::eDatagramV1); // V1 for DHT if (dgramDest) @@ -106,7 +107,7 @@ namespace torrents for (auto it: m_Torrents) StopTorrent (it.second); m_Torrents.clear (); - m_DHT.Stop (); + if (m_DHT) m_DHT->Stop (); m_DiskIOService.Stop (); i2p::client::I2PService::ClearHandlers (); // close connections i2p::client::I2PService::Stop (); @@ -873,9 +874,9 @@ namespace torrents void TorrentsTunnel::HandleRecvFromI2PRaw (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) { - if (toPort == m_DHT.GetRPort ()) + if (m_DHT && toPort == m_DHT->GetRPort ()) { - m_DHT.HandleRawDatagram (buf, len); + m_DHT->HandleRawDatagram (buf, len); return; } // response from tracker @@ -931,7 +932,7 @@ namespace torrents uint32_t transactionID = localDestination->GetRng()(); htobe32buf (connectRequest + 12, transactionID); // transactionID uint16_t fromPort = localDestination->GetRng()() % 1000 + 6000; - if (fromPort == m_DHT.GetRPort ()) fromPort++; + if (m_DHT && fromPort == m_DHT->GetRPort ()) fromPort++; auto session = dgramDest->GetSession (address->identHash); if (session) { @@ -1091,7 +1092,7 @@ namespace torrents { boost::asio::post (GetService (), [this, toIdent, toPort]() { - m_DHT.SendPingQuery (toIdent, toPort); + if (m_DHT) m_DHT->SendPingQuery (toIdent, toPort); }); } } diff --git a/libi2pd_client/TorrentsTunnel.h b/libi2pd_client/TorrentsTunnel.h index 3dde9c77..a5238c8c 100644 --- a/libi2pd_client/TorrentsTunnel.h +++ b/libi2pd_client/TorrentsTunnel.h @@ -91,7 +91,7 @@ namespace torrents public: TorrentsTunnel (std::string_view name, std::shared_ptr localDestination, - std::string_view torrentsDir, std::string_view trackers = ""); + std::string_view torrentsDir, std::string_view trackers = "", bool dht = true); void Start () override; void Stop () override; @@ -114,7 +114,8 @@ namespace torrents bool StartTorrent (int id); 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 () }; } + std::pair GetDHTPorts () const { return { m_DHT ? m_DHT->GetPort () : 0, m_DHT ? m_DHT->GetRPort () : 0 }; } + bool SupportsDHT () const { return (bool)m_DHT; } const char* GetName() const override { return m_Name.c_str (); } @@ -175,7 +176,7 @@ namespace torrents DiskIOService m_DiskIOService; std::unordered_map, uint64_t > > m_DatragramTrackerTransactions; // transactionID->(trackerID, from_port, torrent, timestamp monotonic milliseconds) - TorrentsDHT m_DHT; + std::unique_ptr m_DHT; }; }