From 6d586bde6ca1cc27a1560dc52fbd9ada1d379e1e Mon Sep 17 00:00:00 2001 From: Kill Your TV Date: Thu, 14 May 2015 08:29:17 +0000 Subject: [PATCH 01/67] Note that Boost 1.58 works --- Win32/README-Build.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Win32/README-Build.txt b/Win32/README-Build.txt index dbdc30a2..da5b25de 100644 --- a/Win32/README-Build.txt +++ b/Win32/README-Build.txt @@ -3,8 +3,8 @@ Building i2pd for Windows Requirements for building: -* Visual Studio 2013 (tested with VS2013 Update 1, Update 3, and Update 4 RC) -* Boost (tested with 1.56 and 1.57) +* Visual Studio 2013 (tested with VS2013 Update 1, Update 3, and Update 4) +* Boost (tested with 1.56, 1.57, and 1.58) * Crypto++ (tested with 5.6.2) @@ -31,7 +31,7 @@ After Boost is compiled, set the environment variable `BOOST` to the directory Boost was installed to. If you followed the instructions outlined here, you should set it to `C:\Boost`. Additionally, set the BOOSTVER variable to the version of Boost that you're using, but instead of a '.' use a '_'. For -example, I have `BOOSTVER` set to `1_57`. +example, I have `BOOSTVER` set to `1_58`. Building Crypto++ ----------------- From 2a59ae294dc5bcc8a647448daaae2400edb4ee3e Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 17 May 2015 19:40:46 -0400 Subject: [PATCH 02/67] check length of garlic message --- Garlic.cpp | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/Garlic.cpp b/Garlic.cpp index 3afde6a8..34ed84b3 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -365,23 +365,34 @@ namespace garlic { uint8_t * buf = msg->GetPayload (); uint32_t length = bufbe32toh (buf); + if (length > msg->GetLength ()) + { + LogPrint (eLogError, "Garlic message length ", length, " exceeds I2NP message length ", msg->GetLength ()); + DeleteI2NPMessage (msg); + return; + } buf += 4; // length auto it = m_Tags.find (SessionTag(buf)); if (it != m_Tags.end ()) { // tag found. Use AES - uint8_t iv[32]; // IV is first 16 bytes - CryptoPP::SHA256().CalculateDigest(iv, buf, 32); - it->second->SetIV (iv); - it->second->Decrypt (buf + 32, length - 32, buf + 32); - HandleAESBlock (buf + 32, length - 32, it->second, msg->from); - m_Tags.erase (it); // tag might be used only once + if (length >= 32) + { + uint8_t iv[32]; // IV is first 16 bytes + CryptoPP::SHA256().CalculateDigest(iv, buf, 32); + it->second->SetIV (iv); + it->second->Decrypt (buf + 32, length - 32, buf + 32); + HandleAESBlock (buf + 32, length - 32, it->second, msg->from); + } + else + LogPrint (eLogError, "Garlic message length ", length, " is less than 32 bytes"); + m_Tags.erase (it); // tag might be used only once } else { // tag not found. Use ElGamal ElGamalBlock elGamal; - if (i2p::crypto::ElGamalDecrypt (GetEncryptionPrivateKey (), buf, (uint8_t *)&elGamal, true)) + if (length >= 514 && i2p::crypto::ElGamalDecrypt (GetEncryptionPrivateKey (), buf, (uint8_t *)&elGamal, true)) { auto decryption = std::make_shared(); decryption->SetKey (elGamal.sessionKey); @@ -392,7 +403,7 @@ namespace garlic HandleAESBlock (buf + 514, length - 514, decryption, msg->from); } else - LogPrint ("Failed to decrypt garlic"); + LogPrint (eLogError, "Failed to decrypt garlic"); } DeleteI2NPMessage (msg); From 019af7bd3a2ac84f688edfef35a402f8a159ed78 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 20 May 2015 16:00:09 -0400 Subject: [PATCH 03/67] http server tunnel added --- ClientContext.cpp | 4 ++-- ClientContext.h | 1 + I2PTunnel.cpp | 5 +++++ I2PTunnel.h | 8 ++++++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ClientContext.cpp b/ClientContext.cpp index 4df5fe40..9f14da90 100644 --- a/ClientContext.cpp +++ b/ClientContext.cpp @@ -295,7 +295,7 @@ namespace client LogPrint (eLogError, "I2P client tunnel with port ", port, " already exists"); numClientTunnels++; } - else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER) + else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER || type == I2P_TUNNELS_SECTION_TYPE_HTTP) { // mandatory params std::string host = section.second.get (I2P_SERVER_TUNNEL_HOST); @@ -306,7 +306,7 @@ namespace client std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, ""); auto localDestination = LoadLocalDestination (keys, true); - auto serverTunnel = new I2PServerTunnel (host, port, localDestination, inPort); + I2PServerTunnel * serverTunnel = (type == I2P_TUNNELS_SECTION_TYPE_HTTP) ? new I2PServerTunnelHTTP (host, port, localDestination, inPort) : new I2PServerTunnel (host, port, localDestination, inPort); if (accessList.length () > 0) { std::set idents; diff --git a/ClientContext.h b/ClientContext.h index a034e541..0fe89fb8 100644 --- a/ClientContext.h +++ b/ClientContext.h @@ -20,6 +20,7 @@ namespace client const char I2P_TUNNELS_SECTION_TYPE[] = "type"; const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client"; const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server"; + const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http"; const char I2P_CLIENT_TUNNEL_PORT[] = "port"; const char I2P_CLIENT_TUNNEL_DESTINATION[] = "destination"; const char I2P_CLIENT_TUNNEL_KEYS[] = "keys"; diff --git a/I2PTunnel.cpp b/I2PTunnel.cpp index 4be5517b..4784f73b 100644 --- a/I2PTunnel.cpp +++ b/I2PTunnel.cpp @@ -309,5 +309,10 @@ namespace client conn->Connect (); } } + + I2PServerTunnelHTTP::I2PServerTunnelHTTP (const std::string& host, int port, std::shared_ptr localDestination, int inport): + I2PServerTunnel (host, port, localDestination, inport) + { + } } } diff --git a/I2PTunnel.h b/I2PTunnel.h index e512a319..e89b9088 100644 --- a/I2PTunnel.h +++ b/I2PTunnel.h @@ -104,6 +104,14 @@ namespace client std::set m_AccessList; bool m_IsAccessList; }; + + class I2PServerTunnelHTTP: public I2PServerTunnel + { + public: + + I2PServerTunnelHTTP (const std::string& host, int port, + std::shared_ptr localDestination, int inport = 0); + }; } } From 6a043649f5bce21e65c43702d04e15fb4384185c Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 27 May 2015 13:35:54 -0400 Subject: [PATCH 04/67] use random msg_id for I2NP messages --- I2NPProtocol.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 4ad95d9e..104fdef1 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -41,17 +41,13 @@ namespace i2p return std::shared_ptr(msg, DeleteI2NPMessage); } - static std::atomic I2NPmsgID(0); // TODO: create class void FillI2NPMessageHeader (I2NPMessage * msg, I2NPMessageType msgType, uint32_t replyMsgID) { msg->SetTypeID (msgType); if (replyMsgID) // for tunnel creation msg->SetMsgID (replyMsgID); - else - { - msg->SetMsgID (I2NPmsgID); - I2NPmsgID++; - } + else + msg->SetMsgID (i2p::context.GetRandomNumberGenerator ().GenerateWord32 ()); msg->SetExpiration (i2p::util::GetMillisecondsSinceEpoch () + 5000); // TODO: 5 secs is a magic number msg->UpdateSize (); msg->UpdateChks (); @@ -61,8 +57,7 @@ namespace i2p { if (msg) { - msg->SetMsgID (I2NPmsgID); - I2NPmsgID++; + msg->SetMsgID (i2p::context.GetRandomNumberGenerator ().GenerateWord32 ()); msg->SetExpiration (i2p::util::GetMillisecondsSinceEpoch () + 5000); } } From 8a3c276e663432e3220dbb7cf0a788ee2b136372 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 2 Jun 2015 13:03:22 -0400 Subject: [PATCH 05/67] I2PTunnelConnectionHTTP added --- I2PTunnel.cpp | 44 ++++++++++++++++++++++++++++++++++---------- I2PTunnel.h | 27 ++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/I2PTunnel.cpp b/I2PTunnel.cpp index 4784f73b..97507582 100644 --- a/I2PTunnel.cpp +++ b/I2PTunnel.cpp @@ -129,10 +129,13 @@ namespace client Terminate (); } else - { - boost::asio::async_write (*m_Socket, boost::asio::buffer (m_StreamBuffer, bytes_transferred), - std::bind (&I2PTunnelConnection::HandleWrite, shared_from_this (), std::placeholders::_1)); - } + Write (m_StreamBuffer, bytes_transferred); + } + + void I2PTunnelConnection::Write (const uint8_t * buf, size_t len) + { + m_Socket->async_send (boost::asio::buffer (buf, len), + std::bind (&I2PTunnelConnection::HandleWrite, shared_from_this (), std::placeholders::_1)); } void I2PTunnelConnection::HandleConnect (const boost::system::error_code& ecode) @@ -159,6 +162,13 @@ namespace client } } + I2PTunnelConnectionHTTP::I2PTunnelConnectionHTTP (I2PService * owner, std::shared_ptr stream, + std::shared_ptr socket, + const boost::asio::ip::tcp::endpoint& target, const std::string& host): + I2PTunnelConnection (owner, stream, socket, target) + { + } + /* This handler tries to stablish a connection with the desired server and dies if it fails to do so */ class I2PClientTunnelHandler: public I2PServiceHandler, public std::enable_shared_from_this { @@ -255,13 +265,15 @@ namespace client I2PServerTunnel::I2PServerTunnel (const std::string& address, int port, std::shared_ptr localDestination, int inport): - I2PService (localDestination), m_Endpoint (boost::asio::ip::address::from_string (address), port), m_IsAccessList (false) + I2PService (localDestination), m_Address (address), m_Port (port), m_IsAccessList (false) { m_PortDestination = localDestination->CreateStreamingDestination (inport > 0 ? inport : port); } void I2PServerTunnel::Start () { + m_Endpoint.address (boost::asio::ip::address::from_string (m_Address)); + m_Endpoint.port (m_Port); Accept (); } @@ -304,15 +316,27 @@ namespace client return; } } - auto conn = std::make_shared (this, stream, std::make_shared (GetService ()), m_Endpoint); - AddHandler (conn); - conn->Connect (); + CreateI2PConnection (stream); } } - I2PServerTunnelHTTP::I2PServerTunnelHTTP (const std::string& host, int port, std::shared_ptr localDestination, int inport): - I2PServerTunnel (host, port, localDestination, inport) + void I2PServerTunnel::CreateI2PConnection (std::shared_ptr stream) { + auto conn = std::make_shared (this, stream, std::make_shared (GetService ()), GetEndpoint ()); + AddHandler (conn); + conn->Connect (); + } + + I2PServerTunnelHTTP::I2PServerTunnelHTTP (const std::string& address, int port, std::shared_ptr localDestination, int inport): + I2PServerTunnel (address, port, localDestination, inport) + { + } + + void I2PServerTunnelHTTP::CreateI2PConnection (std::shared_ptr stream) + { + auto conn = std::make_shared (this, stream, std::make_shared (GetService ()), GetEndpoint (), GetAddress ()); + AddHandler (conn); + conn->Connect (); } } } diff --git a/I2PTunnel.h b/I2PTunnel.h index e89b9088..be73594f 100644 --- a/I2PTunnel.h +++ b/I2PTunnel.h @@ -27,19 +27,20 @@ namespace client I2PTunnelConnection (I2PService * owner, std::shared_ptr socket, std::shared_ptr leaseSet, int port = 0); // to I2P I2PTunnelConnection (I2PService * owner, std::shared_ptr socket, - std::shared_ptr stream); // to I2P using simplified API :) + std::shared_ptr stream); // to I2P using simplified API I2PTunnelConnection (I2PService * owner, std::shared_ptr stream, std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, bool quiet = true); // from I2P ~I2PTunnelConnection (); void I2PConnect (const uint8_t * msg = nullptr, size_t len = 0); void Connect (); - private: + protected: void Terminate (); void Receive (); void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); + virtual void Write (const uint8_t * buf, size_t len); // can be overloaded void HandleWrite (const boost::system::error_code& ecode); void StreamReceive (); @@ -55,6 +56,15 @@ namespace client bool m_IsQuiet; // don't send destination }; + class I2PTunnelConnectionHTTP: public I2PTunnelConnection + { + public: + + I2PTunnelConnectionHTTP (I2PService * owner, std::shared_ptr stream, + std::shared_ptr socket, + const boost::asio::ip::tcp::endpoint& target, const std::string& host); + }; + class I2PClientTunnel: public TCPIPAcceptor { protected: @@ -92,13 +102,20 @@ namespace client void SetAccessList (const std::set& accessList); + const std::string& GetAddress() const { return m_Address; } + int GetPort () const { return m_Port; }; + const boost::asio::ip::tcp::endpoint& GetEndpoint () const { return m_Endpoint; } + private: void Accept (); void HandleAccept (std::shared_ptr stream); + virtual void CreateI2PConnection (std::shared_ptr stream); private: + std::string m_Address; + int m_Port; boost::asio::ip::tcp::endpoint m_Endpoint; std::shared_ptr m_PortDestination; std::set m_AccessList; @@ -109,8 +126,12 @@ namespace client { public: - I2PServerTunnelHTTP (const std::string& host, int port, + I2PServerTunnelHTTP (const std::string& address, int port, std::shared_ptr localDestination, int inport = 0); + + private: + + void CreateI2PConnection (std::shared_ptr stream); }; } } From 68834df271e640371a851b8fa56687fa7aab5db5 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 2 Jun 2015 13:18:41 -0400 Subject: [PATCH 06/67] use addresses in server tunnel configuration --- I2PTunnel.cpp | 32 +++++++++++++++++++++++++++++--- I2PTunnel.h | 3 +++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/I2PTunnel.cpp b/I2PTunnel.cpp index 97507582..9bf5c658 100644 --- a/I2PTunnel.cpp +++ b/I2PTunnel.cpp @@ -272,9 +272,21 @@ namespace client void I2PServerTunnel::Start () { - m_Endpoint.address (boost::asio::ip::address::from_string (m_Address)); - m_Endpoint.port (m_Port); - Accept (); + m_Endpoint.port (m_Port); + boost::system::error_code ec; + auto addr = boost::asio::ip::address::from_string (m_Address, ec); + if (!ec) + { + m_Endpoint.address (addr); + Accept (); + } + else + { + auto resolver = std::make_shared(GetService ()); + resolver->async_resolve (boost::asio::ip::tcp::resolver::query (m_Address, ""), + std::bind (&I2PServerTunnel::HandleResolve, this, + std::placeholders::_1, std::placeholders::_2, resolver)); + } } void I2PServerTunnel::Stop () @@ -282,6 +294,20 @@ namespace client ClearHandlers (); } + void I2PServerTunnel::HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, + std::shared_ptr resolver) + { + if (!ecode) + { + auto addr = (*it).endpoint ().address (); + LogPrint (eLogInfo, "server tunnel ", (*it).host_name (), " has been resolved to ", addr); + m_Endpoint.address (addr); + Accept (); + } + else + LogPrint (eLogError, "Unable to resolve server tunnel address: ", ecode.message ()); + } + void I2PServerTunnel::SetAccessList (const std::set& accessList) { m_AccessList = accessList; diff --git a/I2PTunnel.h b/I2PTunnel.h index be73594f..f6f9d3ec 100644 --- a/I2PTunnel.h +++ b/I2PTunnel.h @@ -108,6 +108,9 @@ namespace client private: + void HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, + std::shared_ptr resolver); + void Accept (); void HandleAccept (std::shared_ptr stream); virtual void CreateI2PConnection (std::shared_ptr stream); From d7deb938c59d1ac150f26e95e58677e985c7f18c Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 2 Jun 2015 16:21:38 -0400 Subject: [PATCH 07/67] catch HTTP header of HTTP server tunnel connection --- I2PTunnel.cpp | 14 +++++++++++++- I2PTunnel.h | 10 ++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/I2PTunnel.cpp b/I2PTunnel.cpp index 9bf5c658..b6cabd30 100644 --- a/I2PTunnel.cpp +++ b/I2PTunnel.cpp @@ -165,10 +165,22 @@ namespace client I2PTunnelConnectionHTTP::I2PTunnelConnectionHTTP (I2PService * owner, std::shared_ptr stream, std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, const std::string& host): - I2PTunnelConnection (owner, stream, socket, target) + I2PTunnelConnection (owner, stream, socket, target), m_HeaderSent (false) { } + void I2PTunnelConnectionHTTP::Write (const uint8_t * buf, size_t len) + { + if (m_HeaderSent) + I2PTunnelConnection::Write (buf, len); + else + { + m_Header.write ((const char *)buf, len); + I2PTunnelConnection::Write ((uint8_t *)m_Header.str ().c_str (), m_Header.str ().length ()); + m_HeaderSent = true; + } + } + /* This handler tries to stablish a connection with the desired server and dies if it fails to do so */ class I2PClientTunnelHandler: public I2PServiceHandler, public std::enable_shared_from_this { diff --git a/I2PTunnel.h b/I2PTunnel.h index f6f9d3ec..127f5c4f 100644 --- a/I2PTunnel.h +++ b/I2PTunnel.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "Identity.h" #include "Destination.h" @@ -63,6 +64,15 @@ namespace client I2PTunnelConnectionHTTP (I2PService * owner, std::shared_ptr stream, std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, const std::string& host); + + protected: + + void Write (const uint8_t * buf, size_t len); + + private: + + std::stringstream m_Header; + bool m_HeaderSent; }; class I2PClientTunnel: public TCPIPAcceptor From 09fd0baf7885acd02c5d107bca79f72f672438e2 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 3 Jun 2015 12:30:15 -0400 Subject: [PATCH 08/67] replace Host: for server http tunnels --- I2PTunnel.cpp | 32 +++++++++++++++++++++++++++----- I2PTunnel.h | 3 ++- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/I2PTunnel.cpp b/I2PTunnel.cpp index b6cabd30..a33a536d 100644 --- a/I2PTunnel.cpp +++ b/I2PTunnel.cpp @@ -165,7 +165,7 @@ namespace client I2PTunnelConnectionHTTP::I2PTunnelConnectionHTTP (I2PService * owner, std::shared_ptr stream, std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, const std::string& host): - I2PTunnelConnection (owner, stream, socket, target), m_HeaderSent (false) + I2PTunnelConnection (owner, stream, socket, target), m_Host (host), m_HeaderSent (false) { } @@ -174,10 +174,32 @@ namespace client if (m_HeaderSent) I2PTunnelConnection::Write (buf, len); else - { - m_Header.write ((const char *)buf, len); - I2PTunnelConnection::Write ((uint8_t *)m_Header.str ().c_str (), m_Header.str ().length ()); - m_HeaderSent = true; + { + m_InHeader.clear (); + m_InHeader.write ((const char *)buf, len); + std::string line; + bool endOfHeader = false; + while (!endOfHeader) + { + std::getline(m_InHeader, line); + if (!m_InHeader.fail ()) + { + if (line.find ("Host:") != std::string::npos) + m_OutHeader << "Host: " << m_Host << "\r\n"; + else + m_OutHeader << line << "\n"; + if (line == "\r") endOfHeader = true; + } + else + break; + } + + if (endOfHeader) + { + m_OutHeader << m_InHeader.str (); // data right after header + m_HeaderSent = true; + I2PTunnelConnection::Write ((uint8_t *)m_OutHeader.str ().c_str (), m_OutHeader.str ().length ()); + } } } diff --git a/I2PTunnel.h b/I2PTunnel.h index 127f5c4f..2071b89d 100644 --- a/I2PTunnel.h +++ b/I2PTunnel.h @@ -71,7 +71,8 @@ namespace client private: - std::stringstream m_Header; + std::string m_Host; + std::stringstream m_InHeader, m_OutHeader; bool m_HeaderSent; }; From abc05b448544b5088c2eb60e4a9d39baff0e0c43 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 4 Jun 2015 09:54:46 -0400 Subject: [PATCH 09/67] version 0.9.20 --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index 6ce0cfd7..d5406b0e 100644 --- a/version.h +++ b/version.h @@ -3,6 +3,6 @@ #define CODENAME "Purple" #define VERSION "0.9.0" -#define I2P_VERSION "0.9.19" +#define I2P_VERSION "0.9.20" #endif From da56397b392f7266f49803a8a4137415d4a2bc79 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 4 Jun 2015 11:31:22 -0400 Subject: [PATCH 10/67] fixed bug with zero-size clove --- Garlic.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Garlic.cpp b/Garlic.cpp index 34ed84b3..bbfaed91 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -225,9 +225,10 @@ namespace garlic if (newTags || m_LeaseSetUpdateStatus == eLeaseSetUpdated) // new tags created or leaseset updated { // clove is DeliveryStatus - size += CreateDeliveryStatusClove (payload + size, msgID); - if (size > 0) // successive? + auto cloveSize = CreateDeliveryStatusClove (payload + size, msgID); + if (cloveSize > 0) // successive? { + size += cloveSize; (*numCloves)++; if (newTags) // new tags created m_UnconfirmedTagsMsgs[msgID] = newTags; From 10e78785cd083ca51c6b61cc05f5026f4766157f Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 5 Jun 2015 15:55:21 -0400 Subject: [PATCH 11/67] additional statistics for profiling --- Profiling.cpp | 43 ++++++++++++++++++++++++++++--------------- Profiling.h | 12 +++++++++--- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/Profiling.cpp b/Profiling.cpp index 70df0e76..390a1536 100644 --- a/Profiling.cpp +++ b/Profiling.cpp @@ -11,8 +11,8 @@ namespace data { RouterProfile::RouterProfile (const IdentHash& identHash): m_IdentHash (identHash), m_LastUpdateTime (boost::posix_time::second_clock::local_time()), - m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), - m_NumTunnelsNonReplied (0) + m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0), + m_NumTimesTaken (0), m_NumTimesRejected (0) { } @@ -33,11 +33,15 @@ namespace data participation.put (PEER_PROFILE_PARTICIPATION_AGREED, m_NumTunnelsAgreed); participation.put (PEER_PROFILE_PARTICIPATION_DECLINED, m_NumTunnelsDeclined); participation.put (PEER_PROFILE_PARTICIPATION_NON_REPLIED, m_NumTunnelsNonReplied); + boost::property_tree::ptree usage; + usage.put (PEER_PROFILE_USAGE_TAKEN, m_NumTimesTaken); + usage.put (PEER_PROFILE_USAGE_REJECTED, m_NumTimesRejected); // fill property tree boost::property_tree::ptree pt; pt.put (PEER_PROFILE_LAST_UPDATE_TIME, boost::posix_time::to_simple_string (m_LastUpdateTime)); pt.put_child (PEER_PROFILE_SECTION_PARTICIPATION, participation); - + pt.put_child (PEER_PROFILE_SECTION_USAGE, usage); + // save to file auto path = i2p::util::filesystem::GetDefaultDataDir() / PEER_PROFILES_DIRECTORY; if (!boost::filesystem::exists (path)) @@ -102,6 +106,10 @@ namespace data m_NumTunnelsAgreed = participations.get (PEER_PROFILE_PARTICIPATION_AGREED, 0); m_NumTunnelsDeclined = participations.get (PEER_PROFILE_PARTICIPATION_DECLINED, 0); m_NumTunnelsNonReplied = participations.get (PEER_PROFILE_PARTICIPATION_NON_REPLIED, 0); + // read usage + auto usage = pt.get_child (PEER_PROFILE_SECTION_USAGE); + m_NumTimesTaken = usage.get (PEER_PROFILE_USAGE_TAKEN, 0); + m_NumTimesRejected = usage.get (PEER_PROFILE_USAGE_REJECTED, 0); } else *this = RouterProfile (m_IdentHash); @@ -128,27 +136,32 @@ namespace data UpdateTime (); } - bool RouterProfile::IsLowPartcipationRate (uint32_t elapsedTime) const + bool RouterProfile::IsLowPartcipationRate () const { - if (elapsedTime < 900) // if less than 15 minutes - return m_NumTunnelsAgreed < m_NumTunnelsDeclined; // 50% rate - else - return 3*m_NumTunnelsAgreed < m_NumTunnelsDeclined; // 25% rate + return 4*m_NumTunnelsAgreed < m_NumTunnelsDeclined; // < 20% rate } - bool RouterProfile::IsLowReplyRate (uint32_t elapsedTime) const + bool RouterProfile::IsLowReplyRate () const { auto total = m_NumTunnelsAgreed + m_NumTunnelsDeclined; - if (elapsedTime < 300) // if less than 5 minutes - return m_NumTunnelsNonReplied > 5*(total + 1); - else - return !total && m_NumTunnelsNonReplied*15 > elapsedTime; + return m_NumTunnelsNonReplied > 10*(total + 1); } - bool RouterProfile::IsBad () const + bool RouterProfile::IsBad () { auto elapsedTime = (GetTime () - m_LastUpdateTime).total_seconds (); - return IsAlwaysDeclining () || IsLowPartcipationRate (elapsedTime) || IsLowReplyRate (elapsedTime); + if (elapsedTime > 1800) + { + m_NumTunnelsNonReplied = 0; // drop non-replied after 30 minutes of inactivity + if (elapsedTime > 14400) // drop agreed and declined after 4 hours of inactivity + { + m_NumTunnelsAgreed = 0; + m_NumTunnelsDeclined = 0; + } + } + auto isBad = IsAlwaysDeclining () || IsLowPartcipationRate () || IsLowReplyRate (); + if (isBad) m_NumTimesRejected++; else m_NumTimesTaken++; + return isBad; } std::shared_ptr GetRouterProfile (const IdentHash& identHash) diff --git a/Profiling.h b/Profiling.h index 3a5a0844..0690d6cb 100644 --- a/Profiling.h +++ b/Profiling.h @@ -13,11 +13,14 @@ namespace data const char PEER_PROFILE_PREFIX[] = "profile-"; // sections const char PEER_PROFILE_SECTION_PARTICIPATION[] = "participation"; + const char PEER_PROFILE_SECTION_USAGE[] = "usage"; // params const char PEER_PROFILE_LAST_UPDATE_TIME[] = "lastupdatetime"; const char PEER_PROFILE_PARTICIPATION_AGREED[] = "agreed"; const char PEER_PROFILE_PARTICIPATION_DECLINED[] = "declined"; const char PEER_PROFILE_PARTICIPATION_NON_REPLIED[] = "nonreplied"; + const char PEER_PROFILE_USAGE_TAKEN[] = "taken"; + const char PEER_PROFILE_USAGE_REJECTED[] = "rejected"; const int PEER_PROFILE_EXPIRATION_TIMEOUT = 72; // in hours (3 days) @@ -31,7 +34,7 @@ namespace data void Save (); void Load (); - bool IsBad () const; + bool IsBad (); void TunnelBuildResponse (uint8_t ret); void TunnelNonReplied (); @@ -42,8 +45,8 @@ namespace data void UpdateTime (); bool IsAlwaysDeclining () const { return !m_NumTunnelsAgreed && m_NumTunnelsDeclined >= 5; }; - bool IsLowPartcipationRate (uint32_t elapsedTime) const; - bool IsLowReplyRate (uint32_t elapsedTime) const; + bool IsLowPartcipationRate () const; + bool IsLowReplyRate () const; private: @@ -53,6 +56,9 @@ namespace data uint32_t m_NumTunnelsAgreed; uint32_t m_NumTunnelsDeclined; uint32_t m_NumTunnelsNonReplied; + // usage + uint32_t m_NumTimesTaken; + uint32_t m_NumTimesRejected; }; std::shared_ptr GetRouterProfile (const IdentHash& identHash); From a96482b186ec55a56ba7214ef3791a64b6142153 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 5 Jun 2015 21:15:02 -0400 Subject: [PATCH 12/67] skip missing sections --- Profiling.cpp | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/Profiling.cpp b/Profiling.cpp index 390a1536..c5587f9a 100644 --- a/Profiling.cpp +++ b/Profiling.cpp @@ -101,15 +101,29 @@ namespace data m_LastUpdateTime = boost::posix_time::time_from_string (t); if ((GetTime () - m_LastUpdateTime).hours () < PEER_PROFILE_EXPIRATION_TIMEOUT) { - // read participations - auto participations = pt.get_child (PEER_PROFILE_SECTION_PARTICIPATION); - m_NumTunnelsAgreed = participations.get (PEER_PROFILE_PARTICIPATION_AGREED, 0); - m_NumTunnelsDeclined = participations.get (PEER_PROFILE_PARTICIPATION_DECLINED, 0); - m_NumTunnelsNonReplied = participations.get (PEER_PROFILE_PARTICIPATION_NON_REPLIED, 0); - // read usage - auto usage = pt.get_child (PEER_PROFILE_SECTION_USAGE); - m_NumTimesTaken = usage.get (PEER_PROFILE_USAGE_TAKEN, 0); - m_NumTimesRejected = usage.get (PEER_PROFILE_USAGE_REJECTED, 0); + try + { + // read participations + auto participations = pt.get_child (PEER_PROFILE_SECTION_PARTICIPATION); + m_NumTunnelsAgreed = participations.get (PEER_PROFILE_PARTICIPATION_AGREED, 0); + m_NumTunnelsDeclined = participations.get (PEER_PROFILE_PARTICIPATION_DECLINED, 0); + m_NumTunnelsNonReplied = participations.get (PEER_PROFILE_PARTICIPATION_NON_REPLIED, 0); + } + catch (boost::property_tree::ptree_bad_path& ex) + { + LogPrint (eLogWarning, "Missing section ", PEER_PROFILE_SECTION_PARTICIPATION); + } + try + { + // read usage + auto usage = pt.get_child (PEER_PROFILE_SECTION_USAGE); + m_NumTimesTaken = usage.get (PEER_PROFILE_USAGE_TAKEN, 0); + m_NumTimesRejected = usage.get (PEER_PROFILE_USAGE_REJECTED, 0); + } + catch (boost::property_tree::ptree_bad_path& ex) + { + LogPrint (eLogWarning, "Missing section ", PEER_PROFILE_SECTION_USAGE); + } } else *this = RouterProfile (m_IdentHash); From d9c0f52846331217823c82b04cc7931308c0d96b Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 5 Jun 2015 22:09:16 -0400 Subject: [PATCH 13/67] don't pick node for 5 minutes if declined --- Profiling.cpp | 12 +++++++++--- Profiling.h | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Profiling.cpp b/Profiling.cpp index c5587f9a..43dad505 100644 --- a/Profiling.cpp +++ b/Profiling.cpp @@ -11,6 +11,7 @@ namespace data { RouterProfile::RouterProfile (const IdentHash& identHash): m_IdentHash (identHash), m_LastUpdateTime (boost::posix_time::second_clock::local_time()), + m_LastDeclinedTime (boost::posix_time::min_date_time), m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0), m_NumTimesTaken (0), m_NumTimesRejected (0) { @@ -137,11 +138,14 @@ namespace data void RouterProfile::TunnelBuildResponse (uint8_t ret) { + UpdateTime (); if (ret > 0) + { + m_LastDeclinedTime = m_LastUpdateTime; m_NumTunnelsDeclined++; + } else m_NumTunnelsAgreed++; - UpdateTime (); } void RouterProfile::TunnelNonReplied () @@ -163,7 +167,8 @@ namespace data bool RouterProfile::IsBad () { - auto elapsedTime = (GetTime () - m_LastUpdateTime).total_seconds (); + auto t = GetTime (); + auto elapsedTime = (t - m_LastUpdateTime).total_seconds (); if (elapsedTime > 1800) { m_NumTunnelsNonReplied = 0; // drop non-replied after 30 minutes of inactivity @@ -173,7 +178,8 @@ namespace data m_NumTunnelsDeclined = 0; } } - auto isBad = IsAlwaysDeclining () || IsLowPartcipationRate () || IsLowReplyRate (); + auto isBad = IsAlwaysDeclining () || IsLowPartcipationRate () || IsLowReplyRate () || + ((t - m_LastDeclinedTime).total_seconds () < 300); // declined in last 5 minutes if (isBad) m_NumTimesRejected++; else m_NumTimesTaken++; return isBad; } diff --git a/Profiling.h b/Profiling.h index 0690d6cb..09dc35c4 100644 --- a/Profiling.h +++ b/Profiling.h @@ -51,7 +51,7 @@ namespace data private: IdentHash m_IdentHash; - boost::posix_time::ptime m_LastUpdateTime; + boost::posix_time::ptime m_LastUpdateTime, m_LastDeclinedTime; // participation uint32_t m_NumTunnelsAgreed; uint32_t m_NumTunnelsDeclined; From a3b08c0016fa4889c378e70d21308c70ed03b7f0 Mon Sep 17 00:00:00 2001 From: Mikhail Titov Date: Sat, 6 Jun 2015 03:33:15 -0500 Subject: [PATCH 14/67] Fix Win32 build with CMake and MSVC --- build/CMakeLists.txt | 27 +++++++++++++++++++++++--- build/cmake_modules/FindCryptoPP.cmake | 27 ++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index d753c58f..5d2e04bf 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -45,6 +45,10 @@ set (COMMON_SRC "${CMAKE_SOURCE_DIR}/Signature.cpp" ) +if (CMAKE_SYSTEM_NAME STREQUAL "Windows") + list (APPEND COMMON_SRC "${CMAKE_SOURCE_DIR}/I2PEndian.cpp") +endif () + add_library(common ${COMMON_SRC}) set (DAEMON_SRC @@ -80,7 +84,9 @@ else () endif () # compiler flags customization (by vendor) +if (NOT MSVC) add_definitions ( "-Wall -Wextra -fPIC" ) +endif () # check for c++11 support include(CheckCXXCompilerFlag) @@ -90,7 +96,7 @@ if (CXX11_SUPPORTED) add_definitions( "-std=c++11" ) elseif (CXX0X_SUPPORTED) # gcc 4.6 add_definitions( "-std=c++0x" ) -else () +elseif (NOT MSVC) message(SEND_ERROR "C++11 standart not seems to be supported by compiler. Too old version?") endif () @@ -117,6 +123,7 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin") list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/DaemonLinux.cpp") elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows") list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/DaemonWin32.cpp") + list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Win32Service.cpp") endif () if (WITH_AESNI) @@ -126,6 +133,10 @@ endif() # libraries find_package ( Threads REQUIRED ) +if (WITH_STATIC) + set(Boost_USE_STATIC_LIBS ON) +endif () + find_package ( Boost COMPONENTS system filesystem regex program_options date_time REQUIRED ) if(NOT DEFINED Boost_INCLUDE_DIRS) message(SEND_ERROR "Boost is not found, or your boost version was bellow 1.46. Please download Boost!") @@ -159,7 +170,9 @@ include(GNUInstallDirs) if (WITH_BINARY) add_executable ( "${PROJECT_NAME}-bin" ${DAEMON_SRC} ) + if(NOT MSVC) # FIXME: incremental linker file name (.ilk) collision for dll & exe set_target_properties("${PROJECT_NAME}-bin" PROPERTIES OUTPUT_NAME "${PROJECT_NAME}") + endif() if (WITH_HARDENING AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set_target_properties("${PROJECT_NAME}-bin" PROPERTIES LINK_FLAGS "-z relro -z now" ) @@ -168,15 +181,23 @@ if (WITH_BINARY) if (WITH_STATIC) set(BUILD_SHARED_LIBS OFF) set_target_properties("${PROJECT_NAME}-bin" PROPERTIES LINK_FLAGS "-static" ) + else() + add_definitions(-DBOOST_ALL_DYN_LINK) endif () target_link_libraries( "${PROJECT_NAME}-bin" common ${Boost_LIBRARIES} ${CRYPTO++_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) install(TARGETS "${PROJECT_NAME}-bin" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) + install(FILES $ DESTINATION "bin" CONFIGURATIONS DEBUG) endif () if (WITH_LIBRARY) + if (MSVC) + # FIXME: DLL would not have any symbols unless we use __declspec(dllexport) through out the code + add_library(${PROJECT_NAME} ${LIBRARY_SRC}) + else () add_library(${PROJECT_NAME} SHARED ${LIBRARY_SRC}) - target_link_libraries( ${PROJECT_NAME} common ) - install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ) + target_link_libraries( ${PROJECT_NAME} common ${Boost_LIBRARIES} ${CRYPTO++_LIBRARIES}) + endif () + install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif () diff --git a/build/cmake_modules/FindCryptoPP.cmake b/build/cmake_modules/FindCryptoPP.cmake index 7a8ac317..3435487d 100644 --- a/build/cmake_modules/FindCryptoPP.cmake +++ b/build/cmake_modules/FindCryptoPP.cmake @@ -12,6 +12,9 @@ else(CRYPTO++_INCLUDE_DIR AND CRYPTO++_LIBRARIES) /opt/local/include/crypto++ /opt/local/include/cryptopp $ENV{SystemDrive}/Crypto++/include + $ENV{CRYPTOPP} + $ENV{CRYPTOPP}/include + ${PROJECT_SOURCE_DIR}/../../cryptopp ) find_library(CRYPTO++_LIBRARIES NAMES cryptopp @@ -20,8 +23,32 @@ else(CRYPTO++_INCLUDE_DIR AND CRYPTO++_LIBRARIES) /usr/local/lib /opt/local/lib $ENV{SystemDrive}/Crypto++/lib + $ENV{CRYPTOPP}/lib ) + if(MSVC AND NOT CRYPTO++_LIBRARIES) # Give a chance for MSVC multiconfig + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(PLATFORM x64) + else() + set(PLATFORM Win32) + endif() + find_library(CRYPTO++_LIBRARIES_RELEASE NAMES cryptlib cryptopp + PATHS + $ENV{CRYPTOPP}/Win32/Output/Release + ${PROJECT_SOURCE_DIR}/../../cryptopp/${PLATFORM}/Output/Release + ) + find_library(CRYPTO++_LIBRARIES_DEBUG NAMES cryptlib cryptopp + PATHS + $ENV{CRYPTOPP}/Win32/Output/Debug + ${PROJECT_SOURCE_DIR}/../../cryptopp/${PLATFORM}/Output/Debug + ) + set(CRYPTO++_LIBRARIES + debug ${CRYPTO++_LIBRARIES_DEBUG} + optimized ${CRYPTO++_LIBRARIES_RELEASE} + CACHE PATH "Path to Crypto++ library" FORCE + ) + endif() + if(CRYPTO++_INCLUDE_DIR AND CRYPTO++_LIBRARIES) set(CRYPTO++_FOUND TRUE) message(STATUS "Found Crypto++: ${CRYPTO++_INCLUDE_DIR}, ${CRYPTO++_LIBRARIES}") From 2d3493a2257b82991efabfcd7c6a798f232575a9 Mon Sep 17 00:00:00 2001 From: Mikhail Titov Date: Sat, 6 Jun 2015 12:34:06 -0500 Subject: [PATCH 15/67] Perhaps bitness detection is an introspection http://www.cmake.org/cmake/help/v3.0/command/find_library.html --- build/cmake_modules/FindCryptoPP.cmake | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build/cmake_modules/FindCryptoPP.cmake b/build/cmake_modules/FindCryptoPP.cmake index 3435487d..09b72184 100644 --- a/build/cmake_modules/FindCryptoPP.cmake +++ b/build/cmake_modules/FindCryptoPP.cmake @@ -33,14 +33,16 @@ else(CRYPTO++_INCLUDE_DIR AND CRYPTO++_LIBRARIES) set(PLATFORM Win32) endif() find_library(CRYPTO++_LIBRARIES_RELEASE NAMES cryptlib cryptopp + HINTS + ${PROJECT_SOURCE_DIR}/../../cryptopp/${PLATFORM}/Output/Release PATHS $ENV{CRYPTOPP}/Win32/Output/Release - ${PROJECT_SOURCE_DIR}/../../cryptopp/${PLATFORM}/Output/Release ) find_library(CRYPTO++_LIBRARIES_DEBUG NAMES cryptlib cryptopp + HINTS + ${PROJECT_SOURCE_DIR}/../../cryptopp/${PLATFORM}/Output/Debug PATHS $ENV{CRYPTOPP}/Win32/Output/Debug - ${PROJECT_SOURCE_DIR}/../../cryptopp/${PLATFORM}/Output/Debug ) set(CRYPTO++_LIBRARIES debug ${CRYPTO++_LIBRARIES_DEBUG} From 046ffd8648c3f631ab14c820f1286226eff6e7bf Mon Sep 17 00:00:00 2001 From: Mikhail Titov Date: Sat, 6 Jun 2015 13:53:22 -0500 Subject: [PATCH 16/67] Fix UPnP for Win32 * find_package for headers * Swap includes order to pass compilation with MSVC 2013 * Enforce SO address resolution checks * Change SO/DLL name on Windows * Portable sleep from C++11 This closes #186 --- UPnP.cpp | 142 ++++++++++-------------- UPnP.h | 2 +- build/CMakeLists.txt | 15 ++- build/cmake_modules/FindMiniUPnPc.cmake | 25 +++++ 4 files changed, 100 insertions(+), 84 deletions(-) create mode 100644 build/cmake_modules/FindMiniUPnPc.cmake diff --git a/UPnP.cpp b/UPnP.cpp index 227bbbd7..21f7e76d 100644 --- a/UPnP.cpp +++ b/UPnP.cpp @@ -2,15 +2,19 @@ #include #include -#ifdef _WIN32 -#include -#endif - #include #include #include +#ifdef _WIN32 +#include +#define dlsym GetProcAddress +#else +#include +#endif + #include "Log.h" + #include "RouterContext.h" #include "UPnP.h" #include "NetDb.h" @@ -18,24 +22,36 @@ #include #include -#include +// These are per-process and are safe to reuse for all threads #ifndef UPNPDISCOVER_SUCCESS /* miniupnpc 1.5 */ -typedef UPNPDev* (*upnp_upnpDiscoverFunc) (int, const char *, const char *, int); -typedef int (*upnp_UPNP_AddPortMappingFunc) (const char *, const char *, const char *, const char *, +UPNPDev* (*upnpDiscoverFunc) (int, const char *, const char *, int); +int (*UPNP_AddPortMappingFunc) (const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *); #else /* miniupnpc 1.6 */ -typedef UPNPDev* (*upnp_upnpDiscoverFunc) (int, const char *, const char *, int, int, int *); -typedef int (*upnp_UPNP_AddPortMappingFunc) (const char *, const char *, const char *, const char *, +UPNPDev* (*upnpDiscoverFunc) (int, const char *, const char *, int, int, int *); +int (*UPNP_AddPortMappingFunc) (const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *); #endif -typedef int (*upnp_UPNP_GetValidIGDFunc) (struct UPNPDev *, struct UPNPUrls *, struct IGDdatas *, char *, int); -typedef int (*upnp_UPNP_GetExternalIPAddressFunc) (const char *, const char *, char *); -typedef int (*upnp_UPNP_DeletePortMappingFunc) (const char *, const char *, const char *, const char *, const char *); -typedef void (*upnp_freeUPNPDevlistFunc) (struct UPNPDev *); -typedef void (*upnp_FreeUPNPUrlsFunc) (struct UPNPUrls *); +int (*UPNP_GetValidIGDFunc) (struct UPNPDev *, struct UPNPUrls *, struct IGDdatas *, char *, int); +int (*UPNP_GetExternalIPAddressFunc) (const char *, const char *, char *); +int (*UPNP_DeletePortMappingFunc) (const char *, const char *, const char *, const char *, const char *); +void (*freeUPNPDevlistFunc) (struct UPNPDev *); +void (*FreeUPNPUrlsFunc) (struct UPNPUrls *); + +// Nice approach http://stackoverflow.com/a/21517513/673826 +template +F GetKnownProcAddressImpl(HMODULE hmod, const char *name, F) { + auto proc = reinterpret_cast(dlsym(hmod, name)); + if (!proc) { + LogPrint("Error resolving ", name, " from UPNP library. This often happens if there is version mismatch!"); + } + return proc; +} +#define GetKnownProcAddress(hmod, func) GetKnownProcAddressImpl(hmod, #func, func##Func); + namespace i2p { @@ -57,6 +73,33 @@ namespace transport void UPnP::Start() { + if (!m_IsModuleLoaded) { +#ifdef MAC_OSX + m_Module = dlopen ("libminiupnpc.dylib", RTLD_LAZY); +#elif _WIN32 + m_Module = LoadLibrary ("miniupnpc.dll"); // official prebuilt binary, e.g., in upnpc-exe-win32-20140422.zip +#else + m_Module = dlopen ("libminiupnpc.so", RTLD_LAZY); +#endif + if (m_Module == NULL) + { + LogPrint ("Error loading UPNP library. This often happens if there is version mismatch!"); + return; + } + else + { + upnpDiscoverFunc = GetKnownProcAddress (m_Module, upnpDiscover); + UPNP_GetValidIGDFunc = GetKnownProcAddress (m_Module, UPNP_GetValidIGD); + UPNP_GetExternalIPAddressFunc = GetKnownProcAddress (m_Module, UPNP_GetExternalIPAddress); + UPNP_AddPortMappingFunc = GetKnownProcAddress (m_Module, UPNP_AddPortMapping); + UPNP_DeletePortMappingFunc = GetKnownProcAddress (m_Module, UPNP_DeletePortMapping); + freeUPNPDevlistFunc = GetKnownProcAddress (m_Module, freeUPNPDevlist); + FreeUPNPUrlsFunc = GetKnownProcAddress (m_Module, FreeUPNPUrls); + if (upnpDiscoverFunc && UPNP_GetValidIGDFunc && UPNP_GetExternalIPAddressFunc && UPNP_AddPortMappingFunc && + UPNP_DeletePortMappingFunc && freeUPNPDevlistFunc && FreeUPNPUrlsFunc) + m_IsModuleLoaded = true; + } + } m_Thread = new std::thread (std::bind (&UPnP::Run, this)); } @@ -66,33 +109,6 @@ namespace transport void UPnP::Run () { -#ifdef MAC_OSX - m_Module = dlopen ("libminiupnpc.dylib", RTLD_LAZY); -#elif _WIN32 - m_Module = LoadLibrary ("libminiupnpc.dll"); - if (m_Module == NULL) - { - LogPrint ("Error loading UPNP library. This often happens if there is version mismatch!"); - return; - } - else - { - m_IsModuleLoaded = true; - } -#else - m_Module = dlopen ("libminiupnpc.so", RTLD_LAZY); -#endif -#ifndef _WIN32 - if (!m_Module) - { - LogPrint ("no UPnP module available (", dlerror (), ")"); - return; - } - else - { - m_IsModuleLoaded = true; - } -#endif for (auto& address : context.GetRouterInfo ().GetAddresses ()) { if (!address.host.is_v6 ()) @@ -112,18 +128,6 @@ namespace transport void UPnP::Discover () { - const char *error; -#ifdef _WIN32 - upnp_upnpDiscoverFunc upnpDiscoverFunc = (upnp_upnpDiscoverFunc) GetProcAddress (m_Module, "upnpDiscover"); -#else - upnp_upnpDiscoverFunc upnpDiscoverFunc = (upnp_upnpDiscoverFunc) dlsym (m_Module, "upnpDiscover"); - // reinterpret_cast (dlsym(...)); - if ( (error = dlerror ())) - { - LogPrint ("Error loading UPNP library. This often happens if there is version mismatch!"); - return; - } -#endif // _WIN32 #ifndef UPNPDISCOVER_SUCCESS /* miniupnpc 1.5 */ m_Devlist = upnpDiscoverFunc (2000, m_MulticastIf, m_Minissdpdpath, 0); @@ -134,15 +138,9 @@ namespace transport #endif int r; -#ifdef _WIN32 - upnp_UPNP_GetValidIGDFunc UPNP_GetValidIGDFunc = (upnp_UPNP_GetValidIGDFunc) GetProcAddress (m_Module, "UPNP_GetValidIGD"); -#else - upnp_UPNP_GetValidIGDFunc UPNP_GetValidIGDFunc = (upnp_UPNP_GetValidIGDFunc) dlsym (m_Module, "UPNP_GetValidIGD"); -#endif - r = (*UPNP_GetValidIGDFunc) (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr)); + r = UPNP_GetValidIGDFunc (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr)); if (r == 1) { - upnp_UPNP_GetExternalIPAddressFunc UPNP_GetExternalIPAddressFunc = (upnp_UPNP_GetExternalIPAddressFunc) dlsym (m_Module, "UPNP_GetExternalIPAddress"); r = UPNP_GetExternalIPAddressFunc (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); if(r != UPNPCOMMAND_SUCCESS) { @@ -182,11 +180,6 @@ namespace transport std::string strDesc = "I2Pd"; try { for (;;) { -#ifdef _WIN32 - upnp_UPNP_AddPortMappingFunc UPNP_AddPortMappingFunc = (upnp_UPNP_AddPortMappingFunc) GetProcAddress (m_Module, "UPNP_AddPortMapping"); -#else - upnp_UPNP_AddPortMappingFunc UPNP_AddPortMappingFunc = (upnp_UPNP_AddPortMappingFunc) dlsym (m_Module, "UPNP_AddPortMapping"); -#endif #ifndef UPNPDISCOVER_SUCCESS /* miniupnpc 1.5 */ r = UPNP_AddPortMappingFunc (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0); @@ -204,7 +197,9 @@ namespace transport LogPrint ("UPnP Port Mapping successful. (", m_NetworkAddr ,":", strPort.c_str(), " type ", strType.c_str () ," -> ", m_externalIPAddress ,":", strPort.c_str() ,")"); return; } - sleep(20*60); + std::this_thread::sleep_for(std::chrono::minutes(20)); // c++11 + //boost::this_thread::sleep_for(); // pre c++11 + //sleep(20*60); // non-portable } } catch (boost::thread_interrupted) @@ -228,29 +223,14 @@ namespace transport strType = "UDP"; } int r = 0; -#ifdef _WIN32 - upnp_UPNP_DeletePortMappingFunc UPNP_DeletePortMappingFunc = (upnp_UPNP_DeletePortMappingFunc) GetProcAddress (m_Module, "UPNP_DeletePortMapping"); -#else - upnp_UPNP_DeletePortMappingFunc UPNP_DeletePortMappingFunc = (upnp_UPNP_DeletePortMappingFunc) dlsym (m_Module, "UPNP_DeletePortMapping"); -#endif r = UPNP_DeletePortMappingFunc (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strType.c_str (), 0); LogPrint ("UPNP_DeletePortMapping() returned : ", r, "\n"); } void UPnP::Close () { -#ifdef _WIN32 - upnp_freeUPNPDevlistFunc freeUPNPDevlistFunc = (upnp_freeUPNPDevlistFunc) GetProcAddress (m_Module, "freeUPNPDevlist"); -#else - upnp_freeUPNPDevlistFunc freeUPNPDevlistFunc = (upnp_freeUPNPDevlistFunc) dlsym (m_Module, "freeUPNPDevlist"); -#endif freeUPNPDevlistFunc (m_Devlist); m_Devlist = 0; -#ifdef _WIN32 - upnp_FreeUPNPUrlsFunc FreeUPNPUrlsFunc = (upnp_FreeUPNPUrlsFunc) GetProcAddress (m_Module, "FreeUPNPUrlsFunc"); -#else - upnp_FreeUPNPUrlsFunc FreeUPNPUrlsFunc = (upnp_FreeUPNPUrlsFunc) dlsym (m_Module, "FreeUPNPUrlsFunc"); -#endif FreeUPNPUrlsFunc (&m_upnpUrls); #ifndef _WIN32 dlclose (m_Module); diff --git a/UPnP.h b/UPnP.h index 4884c423..1a7b55c5 100644 --- a/UPnP.h +++ b/UPnP.h @@ -52,7 +52,7 @@ namespace transport #ifndef _WIN32 void *m_Module; #else - HINSTANCE *m_Module; + HINSTANCE m_Module; #endif }; } diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 5d2e04bf..5c9e5a25 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -7,6 +7,7 @@ option(WITH_HARDENING "Use hardening compiler flags" OFF) option(WITH_LIBRARY "Build library" ON) option(WITH_BINARY "Build binary" ON) option(WITH_STATIC "Static build" OFF) +option(WITH_UPNP "Include support for UPnP client" OFF) # paths set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" ) @@ -43,6 +44,7 @@ set (COMMON_SRC "${CMAKE_SOURCE_DIR}/util.cpp" "${CMAKE_SOURCE_DIR}/Datagram.cpp" "${CMAKE_SOURCE_DIR}/Signature.cpp" + "${CMAKE_SOURCE_DIR}/UPnP.cpp" ) if (CMAKE_SYSTEM_NAME STREQUAL "Windows") @@ -62,10 +64,13 @@ set (DAEMON_SRC "${CMAKE_SOURCE_DIR}/I2PTunnel.cpp" "${CMAKE_SOURCE_DIR}/SAM.cpp" "${CMAKE_SOURCE_DIR}/SOCKS.cpp" - "${CMAKE_SOURCE_DIR}/UPnP.cpp" "${CMAKE_SOURCE_DIR}/i2p.cpp" ) +if (WITH_UPNP) + add_definitions(-DUSE_UPNP) +endif () + set (LIBRARY_SRC "${CMAKE_SOURCE_DIR}/api.cpp" ) @@ -137,7 +142,7 @@ if (WITH_STATIC) set(Boost_USE_STATIC_LIBS ON) endif () -find_package ( Boost COMPONENTS system filesystem regex program_options date_time REQUIRED ) +find_package ( Boost COMPONENTS system filesystem regex program_options date_time thread chrono REQUIRED ) if(NOT DEFINED Boost_INCLUDE_DIRS) message(SEND_ERROR "Boost is not found, or your boost version was bellow 1.46. Please download Boost!") endif() @@ -147,6 +152,11 @@ if(NOT DEFINED CRYPTO++_INCLUDE_DIR) message(SEND_ERROR "Could not find Crypto++. Please download and install it first!") endif() +find_package ( MiniUPnPc ) +if (NOT ${MINIUPNPC_FOUND}) + set(WITH_UPNP OFF) +endif() + # load includes include_directories( ${Boost_INCLUDE_DIRS} ${CRYPTO++_INCLUDE_DIR} "${CMAKE_SOURCE_DIR}/..") @@ -163,6 +173,7 @@ message(STATUS " HARDENING : ${WITH_HARDENING}") message(STATUS " LIBRARY : ${WITH_LIBRARY}") message(STATUS " BINARY : ${WITH_BINARY}") message(STATUS " STATIC BUILD : ${WITH_STATIC}") +message(STATUS " UPnP : ${WITH_UPNP}") message(STATUS "---------------------------------------") #Handle paths nicely diff --git a/build/cmake_modules/FindMiniUPnPc.cmake b/build/cmake_modules/FindMiniUPnPc.cmake new file mode 100644 index 00000000..7ecef75d --- /dev/null +++ b/build/cmake_modules/FindMiniUPnPc.cmake @@ -0,0 +1,25 @@ +# - Find MINIUPNPC + +if(MINIUPNPC_INCLUDE_DIR) + set(MINIUPNPC_FOUND TRUE) + +else() + find_path(MINIUPNPC_INCLUDE_DIR miniupnpc.h + /usr/include/miniupnpc + /usr/local/include/miniupnpc + /opt/local/include/miniupnpc + $ENV{SystemDrive}/miniupnpc + ${PROJECT_SOURCE_DIR}/../../miniupnpc + ) + + if(MINIUPNPC_INCLUDE_DIR) + set(MINIUPNPC_FOUND TRUE) + message(STATUS "Found MiniUPnP headers: ${MINIUPNPC_INCLUDE_DIR}") + else() + set(MINIUPNPC_FOUND FALSE) + message(STATUS "MiniUPnP not found.") + endif() + + mark_as_advanced(MINIUPNPC_INCLUDE_DIR) + +endif() From b5ee997da98a31cefa2d249ba39e3626b2268cab Mon Sep 17 00:00:00 2001 From: Mikhail Titov Date: Sat, 6 Jun 2015 14:16:29 -0500 Subject: [PATCH 17/67] MSVC specific debug symbols don't belong to other platforms --- build/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 5d2e04bf..c9dbcbd4 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -188,7 +188,9 @@ if (WITH_BINARY) target_link_libraries( "${PROJECT_NAME}-bin" common ${Boost_LIBRARIES} ${CRYPTO++_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) install(TARGETS "${PROJECT_NAME}-bin" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) - install(FILES $ DESTINATION "bin" CONFIGURATIONS DEBUG) + if (MSVC) + install(FILES $ DESTINATION "bin" CONFIGURATIONS DEBUG) + endif () endif () if (WITH_LIBRARY) From c896f6d0d7c6d26e49b6a0c1fd0b969b34791c57 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 7 Jun 2015 08:37:34 -0400 Subject: [PATCH 18/67] select first hop for inbound tunnel from connected peers --- TunnelPool.cpp | 97 +++++++++++++++++++++++--------------------------- TunnelPool.h | 1 + 2 files changed, 45 insertions(+), 53 deletions(-) diff --git a/TunnelPool.cpp b/TunnelPool.cpp index cc7b4eb0..0eaed3a3 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -70,7 +70,7 @@ namespace tunnel std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.insert (createdTunnel); } - CreatePairedInboundTunnel (createdTunnel); + //CreatePairedInboundTunnel (createdTunnel); } void TunnelPool::TunnelExpired (std::shared_ptr expiredTunnel) @@ -290,6 +290,35 @@ namespace tunnel hop = i2p::data::netdb.GetRandomRouter (); return hop; } + + bool TunnelPool::SelectPeers (std::vector >& hops) + { + auto prevHop = i2p::context.GetSharedRouterInfo (); + int numHops = m_NumInboundHops; + if (i2p::transport::transports.GetNumPeers () > 25) + { + auto r = i2p::transport::transports.GetRandomPeer (); + if (r && !r->GetProfile ()->IsBad ()) + { + prevHop = r; + hops.push_back (r); + numHops--; + } + } + + for (int i = 0; i < numHops; i++) + { + auto hop = SelectNextHop (prevHop); + if (!hop) + { + LogPrint (eLogError, "Can't select next hop"); + return false; + } + prevHop = hop; + hops.push_back (hop); + } + return true; + } void TunnelPool::CreateInboundTunnel () { @@ -297,34 +326,15 @@ namespace tunnel if (!outboundTunnel) outboundTunnel = tunnels.GetNextOutboundTunnel (); LogPrint ("Creating destination inbound tunnel..."); - auto prevHop = i2p::context.GetSharedRouterInfo (); std::vector > hops; - int numHops = m_NumInboundHops; - if (outboundTunnel) - { - // last hop - auto hop = outboundTunnel->GetTunnelConfig ()->GetFirstHop ()->router; - if (hop->GetIdentHash () != i2p::context.GetIdentHash ()) // outbound shouldn't be zero-hop tunnel - { - prevHop = hop; - hops.push_back (prevHop); - numHops--; - } - } - for (int i = 0; i < numHops; i++) + if (SelectPeers (hops)) { - auto hop = SelectNextHop (prevHop); - if (!hop) - { - LogPrint (eLogError, "Can't select next hop for inbound tunnel"); - return; - } - prevHop = hop; - hops.push_back (hop); - } - std::reverse (hops.begin (), hops.end ()); - auto tunnel = tunnels.CreateTunnel (std::make_shared (hops), outboundTunnel); - tunnel->SetTunnelPool (shared_from_this ()); + std::reverse (hops.begin (), hops.end ()); + auto tunnel = tunnels.CreateTunnel (std::make_shared (hops), outboundTunnel); + tunnel->SetTunnelPool (shared_from_this ()); + } + else + LogPrint (eLogError, "Can't create inbound tunnel. No peers available"); } void TunnelPool::RecreateInboundTunnel (std::shared_ptr tunnel) @@ -345,34 +355,15 @@ namespace tunnel if (inboundTunnel) { LogPrint ("Creating destination outbound tunnel..."); - int numHops = m_NumOutboundHops; - auto prevHop = i2p::context.GetSharedRouterInfo (); std::vector > hops; - if (i2p::transport::transports.GetNumPeers () > 25) - { - auto r = i2p::transport::transports.GetRandomPeer (); - if (r) - { - prevHop = r; - hops.push_back (r); - numHops--; - } - } - for (int i = 0; i < numHops; i++) - { - auto hop = SelectNextHop (prevHop); - if (!hop) - { - LogPrint (eLogError, "Can't select next hop for outbound tunnel"); - return; - } - prevHop = hop; - hops.push_back (hop); + if (SelectPeers (hops)) + { + auto tunnel = tunnels.CreateTunnel ( + std::make_shared (hops, inboundTunnel->GetTunnelConfig ())); + tunnel->SetTunnelPool (shared_from_this ()); } - - auto tunnel = tunnels.CreateTunnel ( - std::make_shared (hops, inboundTunnel->GetTunnelConfig ())); - tunnel->SetTunnelPool (shared_from_this ()); + else + LogPrint (eLogError, "Can't create outbound tunnel. No peers available"); } else LogPrint (eLogError, "Can't create outbound tunnel. No inbound tunnels found"); diff --git a/TunnelPool.h b/TunnelPool.h index 5f2dd5ce..b20cfaf2 100644 --- a/TunnelPool.h +++ b/TunnelPool.h @@ -61,6 +61,7 @@ namespace tunnel template typename TTunnels::value_type GetNextTunnel (TTunnels& tunnels, typename TTunnels::value_type excluded) const; std::shared_ptr SelectNextHop (std::shared_ptr prevHop) const; + bool SelectPeers (std::vector >& hops); private: From e461982a316ea8dcc9363c6654a85cdc585cebc5 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 9 Jun 2015 11:00:37 -0400 Subject: [PATCH 19/67] support multiple transport sessions to the same peer --- Transports.cpp | 40 ++++++++++++++++++---------------------- Transports.h | 8 +++++++- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/Transports.cpp b/Transports.cpp index f871607e..f288d113 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -239,7 +239,7 @@ namespace transport try { auto r = netdb.FindRouter (ident); - it = m_Peers.insert (std::pair(ident, { 0, r, nullptr, + it = m_Peers.insert (std::pair(ident, { 0, r, {}, i2p::util::GetSecondsSinceEpoch () })).first; connected = ConnectToPeer (ident, it->second); } @@ -254,8 +254,8 @@ namespace transport return; } } - if (it->second.session) - it->second.session->SendI2NPMessages (msgs); + if (!it->second.sessions.empty ()) + it->second.sessions.front ()->SendI2NPMessages (msgs); else { for (auto it1: msgs) @@ -309,7 +309,7 @@ namespace transport } } LogPrint (eLogError, "No NTCP and SSU addresses available"); - if (peer.session) peer.session->Done (); + peer.Done (); m_Peers.erase (ident); return false; } @@ -436,20 +436,12 @@ namespace transport auto it = m_Peers.find (ident); if (it != m_Peers.end ()) { - if (!it->second.session) - { - it->second.session = session; - session->SendI2NPMessages (it->second.delayedMessages); - it->second.delayedMessages.clear (); - } - else - { - LogPrint (eLogError, "Session for ", ident.ToBase64 ().substr (0, 4), " already exists"); - session->Done (); - } + it->second.sessions.push_back (session); + session->SendI2NPMessages (it->second.delayedMessages); + it->second.delayedMessages.clear (); } else // incoming connection - m_Peers.insert (std::make_pair (ident, Peer{ 0, nullptr, session, i2p::util::GetSecondsSinceEpoch () })); + m_Peers.insert (std::make_pair (ident, Peer{ 0, nullptr, { session }, i2p::util::GetSecondsSinceEpoch () })); }); } @@ -459,12 +451,16 @@ namespace transport { auto ident = session->GetRemoteIdentity ().GetIdentHash (); auto it = m_Peers.find (ident); - if (it != m_Peers.end () && (!it->second.session || it->second.session == session)) + if (it != m_Peers.end ()) { - if (it->second.delayedMessages.size () > 0) - ConnectToPeer (ident, it->second); - else - m_Peers.erase (it); + it->second.sessions.remove (session); + if (it->second.sessions.empty ()) // TODO: why? + { + if (it->second.delayedMessages.size () > 0) + ConnectToPeer (ident, it->second); + else + m_Peers.erase (it); + } } }); } @@ -482,7 +478,7 @@ namespace transport auto ts = i2p::util::GetSecondsSinceEpoch (); for (auto it = m_Peers.begin (); it != m_Peers.end (); ) { - if (!it->second.session && ts > it->second.creationTime + SESSION_CREATION_TIMEOUT) + if (it->second.sessions.empty () && ts > it->second.creationTime + SESSION_CREATION_TIMEOUT) { LogPrint (eLogError, "Session to peer ", it->first.ToBase64 (), " has not been created in ", SESSION_CREATION_TIMEOUT, " seconds"); it = m_Peers.erase (it); diff --git a/Transports.h b/Transports.h index 11f05190..ec04f6c7 100644 --- a/Transports.h +++ b/Transports.h @@ -60,10 +60,16 @@ namespace transport { int numAttempts; std::shared_ptr router; - std::shared_ptr session; + std::list > sessions; uint64_t creationTime; std::vector delayedMessages; + void Done () + { + for (auto it: sessions) + it->Done (); + } + ~Peer () { for (auto it :delayedMessages) From e8d80e16ba10b1df78fef7f35e323f7713444ad0 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 9 Jun 2015 13:02:37 -0400 Subject: [PATCH 20/67] very hash in one pass --- ElGamal.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ElGamal.h b/ElGamal.h index 3eed1ce6..359de358 100644 --- a/ElGamal.h +++ b/ElGamal.h @@ -60,15 +60,13 @@ namespace crypto { CryptoPP::Integer x(key, 256), a(zeroPadding? encrypted +1 : encrypted, 256), b(zeroPadding? encrypted + 258 :encrypted + 256, 256); - uint8_t m[255], hash[32]; + uint8_t m[255]; a_times_b_mod_c (b, a_exp_b_mod_c (a, elgp - x - 1, elgp), elgp).Encode (m, 255); - CryptoPP::SHA256().CalculateDigest(hash, m+33, 222); - for (int i = 0; i < 32; i++) - if (hash[i] != m[i+1]) - { - LogPrint ("ElGamal decrypt hash doesn't match"); - return false; - } + if (!CryptoPP::SHA256().VerifyDigest (m + 1, m + 33, 222)) + { + LogPrint ("ElGamal decrypt hash doesn't match"); + return false; + } memcpy (data, m + 33, 222); return true; } From 09298d7457bd547959b3f82bee0ac1a3b5ad6706 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 9 Jun 2015 14:04:25 -0400 Subject: [PATCH 21/67] changed profiling algorithm --- Profiling.cpp | 24 ++++++++---------------- Profiling.h | 2 +- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/Profiling.cpp b/Profiling.cpp index 43dad505..d0b8e85d 100644 --- a/Profiling.cpp +++ b/Profiling.cpp @@ -11,7 +11,6 @@ namespace data { RouterProfile::RouterProfile (const IdentHash& identHash): m_IdentHash (identHash), m_LastUpdateTime (boost::posix_time::second_clock::local_time()), - m_LastDeclinedTime (boost::posix_time::min_date_time), m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0), m_NumTimesTaken (0), m_NumTimesRejected (0) { @@ -140,10 +139,7 @@ namespace data { UpdateTime (); if (ret > 0) - { - m_LastDeclinedTime = m_LastUpdateTime; m_NumTunnelsDeclined++; - } else m_NumTunnelsAgreed++; } @@ -167,19 +163,15 @@ namespace data bool RouterProfile::IsBad () { - auto t = GetTime (); - auto elapsedTime = (t - m_LastUpdateTime).total_seconds (); - if (elapsedTime > 1800) + auto isBad = IsAlwaysDeclining () || IsLowPartcipationRate () /*|| IsLowReplyRate ()*/; + if (isBad && m_NumTimesRejected > 10*(m_NumTimesTaken + 1)) { - m_NumTunnelsNonReplied = 0; // drop non-replied after 30 minutes of inactivity - if (elapsedTime > 14400) // drop agreed and declined after 4 hours of inactivity - { - m_NumTunnelsAgreed = 0; - m_NumTunnelsDeclined = 0; - } - } - auto isBad = IsAlwaysDeclining () || IsLowPartcipationRate () || IsLowReplyRate () || - ((t - m_LastDeclinedTime).total_seconds () < 300); // declined in last 5 minutes + // reset profile + m_NumTunnelsAgreed = 0; + m_NumTunnelsDeclined = 0; + m_NumTunnelsNonReplied = 0; + isBad = false; + } if (isBad) m_NumTimesRejected++; else m_NumTimesTaken++; return isBad; } diff --git a/Profiling.h b/Profiling.h index 09dc35c4..0690d6cb 100644 --- a/Profiling.h +++ b/Profiling.h @@ -51,7 +51,7 @@ namespace data private: IdentHash m_IdentHash; - boost::posix_time::ptime m_LastUpdateTime, m_LastDeclinedTime; + boost::posix_time::ptime m_LastUpdateTime; // participation uint32_t m_NumTunnelsAgreed; uint32_t m_NumTunnelsDeclined; From 0e8bdf8299d9dcf1e050df59f9734a8f1cbb104e Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 9 Jun 2015 22:14:31 -0400 Subject: [PATCH 22/67] fixed race condition --- RouterContext.cpp | 12 ++++++++++++ RouterContext.h | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/RouterContext.cpp b/RouterContext.cpp index d2659016..495f1181 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -299,6 +299,18 @@ namespace i2p i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from)); } + void RouterContext::ProcessGarlicMessage (I2NPMessage * msg) + { + std::unique_lock l(m_GarlicMutex); + i2p::garlic::GarlicDestination::ProcessGarlicMessage (msg); + } + + void RouterContext::ProcessDeliveryStatusMessage (I2NPMessage * msg) + { + std::unique_lock l(m_GarlicMutex); + i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg); + } + uint32_t RouterContext::GetUptime () const { return i2p::util::GetSecondsSinceEpoch () - m_StartupTime; diff --git a/RouterContext.h b/RouterContext.h index 9f6cd00b..840d75ad 100644 --- a/RouterContext.h +++ b/RouterContext.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,10 @@ namespace i2p std::shared_ptr GetLeaseSet () { return nullptr; }; std::shared_ptr GetTunnelPool () const; void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from); + + // override GarlicDestination + void ProcessGarlicMessage (I2NPMessage * msg); + void ProcessDeliveryStatusMessage (I2NPMessage * msg); private: @@ -93,6 +98,7 @@ namespace i2p bool m_AcceptsTunnels, m_IsFloodfill; uint64_t m_StartupTime; // in seconds since epoch RouterStatus m_Status; + std::mutex m_GarlicMutex; }; extern RouterContext context; From 44768e92ad5757ce36b852d21336a70d3c0118a9 Mon Sep 17 00:00:00 2001 From: Mikhail Titov Date: Wed, 10 Jun 2015 01:07:39 -0500 Subject: [PATCH 23/67] CMake: fix static builds, add LTO for MinSizeRel --- build/CMakeLists.txt | 64 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index b31607f0..19509a74 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -82,15 +82,18 @@ source_group ("Header Files" FILES ${HEADERS}) source_group ("Source Files" FILES ${COMMON_SRC} ${DAEMON_SRC} ${LIBRARY_SRC}) # Default build is Debug -if (CMAKE_BUILD_TYPE STREQUAL "Release") - add_definitions( "-pedantic" ) -else () +if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Debug) endif () # compiler flags customization (by vendor) if (NOT MSVC) -add_definitions ( "-Wall -Wextra -fPIC" ) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra" ) + set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic" ) + # TODO: The following is incompatible with static build and enabled hardening for OpenWRT. + # Multiple definitions of __stack_chk_fail (libssp & libc) + set( CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s -ffunction-sections -fdata-sections" ) + set( CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections" ) # -flto is added from above endif () # check for c++11 support @@ -136,10 +139,44 @@ if (WITH_AESNI) endif() # libraries +# TODO: once CMake 3.1+ becomes mainstream, see e.g. http://stackoverflow.com/a/29871891/673826 +# use imported Threads::Threads instead +set(THREADS_PREFER_PTHREAD_FLAG ON) find_package ( Threads REQUIRED ) +if(THREADS_HAVE_PTHREAD_ARG) # compile time flag + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") +endif() if (WITH_STATIC) set(Boost_USE_STATIC_LIBS ON) + set(Boost_USE_STATIC_RUNTIME ON) + if (WIN32) + # http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace + # Note that you might need to rebuild Crypto++ + foreach(flag_var + CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) + if(${flag_var} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + endif(${flag_var} MATCHES "/MD") + endforeach(flag_var) + else () + set(CMAKE_FIND_LIBRARY_SUFFIXES .a) + endif () + set(BUILD_SHARED_LIBS OFF) + if (${CMAKE_CXX_COMPILER} MATCHES ".*-openwrt-.*") + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread" ) + # set( CMAKE_THREAD_LIBS_INIT "gcc_eh -Wl,--whole-archive -lpthread -Wl,--no-whole-archive" ) + set( CMAKE_THREAD_LIBS_INIT "gcc_eh -Wl,-u,pthread_create,-u,pthread_once,-u,pthread_mutex_lock,-u,pthread_mutex_unlock,-u,pthread_join,-u,pthread_equal,-u,pthread_detach,-u,pthread_cond_wait,-u,pthread_cond_signal,-u,pthread_cond_destroy,-u,pthread_cond_broadcast,-u,pthread_cancel" ) + endif () +else() + if (NOT WIN32) + # TODO: Consider separate compilation for COMMON_SRC for library. + # No need in -fPIC overhead for binary if not interested in library + # HINT: revert c266cff CMakeLists.txt: compilation speed up + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" ) + endif () + add_definitions(-DBOOST_ALL_DYN_LINK) endif () find_package ( Boost COMPONENTS system filesystem regex program_options date_time thread chrono REQUIRED ) @@ -183,19 +220,20 @@ if (WITH_BINARY) add_executable ( "${PROJECT_NAME}-bin" ${DAEMON_SRC} ) if(NOT MSVC) # FIXME: incremental linker file name (.ilk) collision for dll & exe set_target_properties("${PROJECT_NAME}-bin" PROPERTIES OUTPUT_NAME "${PROJECT_NAME}") + if (WITH_STATIC) + set_target_properties("${PROJECT_NAME}-bin" PROPERTIES LINK_FLAGS "-static" ) + endif () endif() if (WITH_HARDENING AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set_target_properties("${PROJECT_NAME}-bin" PROPERTIES LINK_FLAGS "-z relro -z now" ) endif () - if (WITH_STATIC) - set(BUILD_SHARED_LIBS OFF) - set_target_properties("${PROJECT_NAME}-bin" PROPERTIES LINK_FLAGS "-static" ) - else() - add_definitions(-DBOOST_ALL_DYN_LINK) - endif () - + # FindBoost pulls pthread for thread which is broken for static linking at least on Ubuntu 15.04 + list(GET Boost_LIBRARIES -1 LAST_Boost_LIBRARIES) + if(${LAST_Boost_LIBRARIES} MATCHES ".*pthread.*") + list(REMOVE_AT Boost_LIBRARIES -1) + endif() target_link_libraries( "${PROJECT_NAME}-bin" common ${Boost_LIBRARIES} ${CRYPTO++_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) install(TARGETS "${PROJECT_NAME}-bin" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) @@ -207,9 +245,9 @@ endif () if (WITH_LIBRARY) if (MSVC) # FIXME: DLL would not have any symbols unless we use __declspec(dllexport) through out the code - add_library(${PROJECT_NAME} ${LIBRARY_SRC}) + add_library(${PROJECT_NAME} STATIC ${LIBRARY_SRC}) else () - add_library(${PROJECT_NAME} SHARED ${LIBRARY_SRC}) + add_library(${PROJECT_NAME} ${LIBRARY_SRC}) target_link_libraries( ${PROJECT_NAME} common ${Boost_LIBRARIES} ${CRYPTO++_LIBRARIES}) endif () install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) From ba2b792916013b0833c064f6b0fccf769f539018 Mon Sep 17 00:00:00 2001 From: Mikhail Titov Date: Wed, 10 Jun 2015 01:12:43 -0500 Subject: [PATCH 24/67] Cleanup cryptopp headers path search --- build/CMakeLists.txt | 2 +- build/cmake_modules/FindCryptoPP.cmake | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 19509a74..4e125d58 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -195,7 +195,7 @@ if (NOT ${MINIUPNPC_FOUND}) endif() # load includes -include_directories( ${Boost_INCLUDE_DIRS} ${CRYPTO++_INCLUDE_DIR} "${CMAKE_SOURCE_DIR}/..") +include_directories( ${Boost_INCLUDE_DIRS} ${CRYPTO++_INCLUDE_DIR} ) # show summary message(STATUS "---------------------------------------") diff --git a/build/cmake_modules/FindCryptoPP.cmake b/build/cmake_modules/FindCryptoPP.cmake index 09b72184..396be144 100644 --- a/build/cmake_modules/FindCryptoPP.cmake +++ b/build/cmake_modules/FindCryptoPP.cmake @@ -4,17 +4,14 @@ if(CRYPTO++_INCLUDE_DIR AND CRYPTO++_LIBRARIES) set(CRYPTO++_FOUND TRUE) else(CRYPTO++_INCLUDE_DIR AND CRYPTO++_LIBRARIES) - find_path(CRYPTO++_INCLUDE_DIR cryptlib.h - /usr/include/crypto++ - /usr/include/cryptopp - /usr/local/include/crypto++ - /usr/local/include/cryptopp - /opt/local/include/crypto++ - /opt/local/include/cryptopp + find_path(CRYPTO++_INCLUDE_DIR cryptopp/cryptlib.h + /usr/include + /usr/local/include $ENV{SystemDrive}/Crypto++/include $ENV{CRYPTOPP} + $ENV{CRYPTOPP}/.. $ENV{CRYPTOPP}/include - ${PROJECT_SOURCE_DIR}/../../cryptopp + ${PROJECT_SOURCE_DIR}/../.. ) find_library(CRYPTO++_LIBRARIES NAMES cryptopp From 0354685e35c921ee457741b195b57ca57a788771 Mon Sep 17 00:00:00 2001 From: Mikhail Titov Date: Wed, 10 Jun 2015 01:04:33 -0500 Subject: [PATCH 25/67] Precompiled headers Sample times: MSVC 2013, debug x64: 5min 15sec -> 2min 15sec Ubuntu 15.04, with hardening, static, release: 5min 21sec -> 3min 24sec --- build/CMakeLists.txt | 46 ++++++++++++++++++++++++++++-- stdafx.cpp | 1 + stdafx.h | 67 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 stdafx.cpp create mode 100644 stdafx.h diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 4e125d58..254574fe 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required ( VERSION 2.8.5 ) +cmake_minimum_required ( VERSION 2.8.12 ) project ( "i2pd" ) # configurale options @@ -8,6 +8,7 @@ option(WITH_LIBRARY "Build library" ON) option(WITH_BINARY "Build binary" ON) option(WITH_STATIC "Static build" OFF) option(WITH_UPNP "Include support for UPnP client" OFF) +option(WITH_PCH "Use precompiled header" OFF) # paths set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" ) @@ -88,7 +89,7 @@ endif () # compiler flags customization (by vendor) if (NOT MSVC) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra" ) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch" ) set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic" ) # TODO: The following is incompatible with static build and enabled hardening for OpenWRT. # Multiple definitions of __stack_chk_fail (libssp & libc) @@ -179,6 +180,30 @@ else() add_definitions(-DBOOST_ALL_DYN_LINK) endif () +if (WITH_PCH) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) + add_library(stdafx STATIC "${CMAKE_SOURCE_DIR}/stdafx.cpp") + if(MSVC) + target_compile_options(stdafx PRIVATE /Ycstdafx.h /Zm135) + add_custom_command(TARGET stdafx POST_BUILD + COMMAND xcopy /y stdafx.dir\\$\\*.pdb common.dir\\$\\ + COMMAND xcopy /y stdafx.dir\\$\\*.pdb i2pd-bin.dir\\$\\ + COMMAND xcopy /y stdafx.dir\\$\\*.pdb i2pd.dir\\$\\ + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) + target_compile_options(common PRIVATE /FIstdafx.h /Yustdafx.h /Zm135 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$/stdafx.pch") + else() + string(TOUPPER ${CMAKE_BUILD_TYPE} BTU) + get_directory_property(DEFS DEFINITIONS) + string(REPLACE " " ";" FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BTU}} ${DEFS}") + add_custom_command(TARGET stdafx PRE_BUILD + COMMAND ${CMAKE_CXX_COMPILER} ${FLAGS} -c ${CMAKE_CURRENT_SOURCE_DIR}/../stdafx.h + ) + target_compile_options(common PRIVATE -include stdafx.h) + endif() + target_link_libraries(common stdafx) +endif() + find_package ( Boost COMPONENTS system filesystem regex program_options date_time thread chrono REQUIRED ) if(NOT DEFINED Boost_INCLUDE_DIRS) message(SEND_ERROR "Boost is not found, or your boost version was bellow 1.46. Please download Boost!") @@ -211,6 +236,7 @@ message(STATUS " LIBRARY : ${WITH_LIBRARY}") message(STATUS " BINARY : ${WITH_BINARY}") message(STATUS " STATIC BUILD : ${WITH_STATIC}") message(STATUS " UPnP : ${WITH_UPNP}") +message(STATUS " PCH : ${WITH_PCH}") message(STATUS "---------------------------------------") #Handle paths nicely @@ -225,6 +251,14 @@ if (WITH_BINARY) endif () endif() + if (WITH_PCH) + if (MSVC) + target_compile_options("${PROJECT_NAME}-bin" PRIVATE /FIstdafx.h /Yustdafx.h /Zm135 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$/stdafx.pch") + else() + target_compile_options("${PROJECT_NAME}-bin" PRIVATE -include stdafx.h) + endif() + endif() + if (WITH_HARDENING AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set_target_properties("${PROJECT_NAME}-bin" PROPERTIES LINK_FLAGS "-z relro -z now" ) endif () @@ -250,5 +284,13 @@ if (WITH_LIBRARY) add_library(${PROJECT_NAME} ${LIBRARY_SRC}) target_link_libraries( ${PROJECT_NAME} common ${Boost_LIBRARIES} ${CRYPTO++_LIBRARIES}) endif () + if (WITH_PCH) + if (MSVC) + add_dependencies(${PROJECT_NAME} stdafx) + target_compile_options(${PROJECT_NAME} PRIVATE /FIstdafx.h /Yustdafx.h /Zm135 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$/stdafx.pch") + else() + target_compile_options(${PROJECT_NAME} PRIVATE -include stdafx.h) + endif() + endif() install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif () diff --git a/stdafx.cpp b/stdafx.cpp new file mode 100644 index 00000000..fd4f341c --- /dev/null +++ b/stdafx.cpp @@ -0,0 +1 @@ +#include "stdafx.h" diff --git a/stdafx.h b/stdafx.h new file mode 100644 index 00000000..edfac630 --- /dev/null +++ b/stdafx.h @@ -0,0 +1,67 @@ +#ifndef STDAFX_H__ +#define STDAFX_H__ + +#include +#include +#include +#include +#include + +#include // TODO: replace with cstring and std:: through out +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif From ef6a0384513bb90627625db0242e08629cbf8786 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 10 Jun 2015 15:32:55 -0400 Subject: [PATCH 26/67] handle explicitPeers I2CP parameter --- Destination.cpp | 17 +++++++++++++++ Destination.h | 1 + Identity.h | 5 +++++ TunnelPool.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++----- TunnelPool.h | 7 ++++-- 5 files changed, 80 insertions(+), 7 deletions(-) diff --git a/Destination.cpp b/Destination.cpp index 606bd619..63c89fff 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -24,6 +24,7 @@ namespace client int outboundTunnelLen = DEFAULT_OUTBOUND_TUNNEL_LENGTH; int inboundTunnelsQuantity = DEFAULT_INBOUND_TUNNELS_QUANTITY; int outboundTunnelsQuantity = DEFAULT_OUTBOUND_TUNNELS_QUANTITY; + std::shared_ptr > explicitPeers; if (params) { auto it = params->find (I2CP_PARAM_INBOUND_TUNNEL_LENGTH); @@ -66,8 +67,24 @@ namespace client LogPrint (eLogInfo, "Outbound tunnels quantity set to ", quantity); } } + it = params->find (I2CP_PARAM_EXPLICIT_PEERS); + if (it != params->end ()) + { + explicitPeers = std::make_shared >(); + std::stringstream ss(it->second); + std::string b64; + while (std::getline (ss, b64, ',')) + { + i2p::data::IdentHash ident; + ident.FromBase64 (b64); + explicitPeers->push_back (ident); + } + LogPrint (eLogInfo, "Explicit peers set to ", it->second); + } } m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (this, inboundTunnelLen, outboundTunnelLen, inboundTunnelsQuantity, outboundTunnelsQuantity); + if (explicitPeers) + m_Pool->SetExplicitPeers (explicitPeers); if (m_IsPublic) LogPrint (eLogInfo, "Local address ", i2p::client::GetB32Address(GetIdentHash()), " created"); m_StreamingDestination = std::make_shared (*this); // TODO: diff --git a/Destination.h b/Destination.h index bf2dfcca..1f48ded0 100644 --- a/Destination.h +++ b/Destination.h @@ -40,6 +40,7 @@ namespace client const int DEFAULT_INBOUND_TUNNELS_QUANTITY = 5; const char I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY[] = "outbound.quantity"; const int DEFAULT_OUTBOUND_TUNNELS_QUANTITY = 5; + const char I2CP_PARAM_EXPLICIT_PEERS[] = "explicitPeers"; const int STREAM_REQUEST_TIMEOUT = 60; //in seconds typedef std::function stream)> StreamRequestComplete; diff --git a/Identity.h b/Identity.h index 02752d99..632c414a 100644 --- a/Identity.h +++ b/Identity.h @@ -69,6 +69,11 @@ namespace data i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz); } + void FromBase64 (const std::string& s) + { + i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz); + } + private: union // 8 bytes alignment diff --git a/TunnelPool.cpp b/TunnelPool.cpp index 0eaed3a3..478d6f11 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -1,3 +1,4 @@ +#include #include "I2PEndian.h" #include "CryptoConst.h" #include "Tunnel.h" @@ -22,6 +23,27 @@ namespace tunnel DetachTunnels (); } + void TunnelPool::SetExplicitPeers (std::shared_ptr > explicitPeers) + { + m_ExplicitPeers = explicitPeers; + if (m_ExplicitPeers) + { + int size = m_ExplicitPeers->size (); + if (m_NumInboundHops > size) + { + m_NumInboundHops = size; + LogPrint (eLogInfo, "Inbound tunnel length has beed adjusted to ", size, " for explicit peers"); + } + if (m_NumOutboundHops > size) + { + m_NumOutboundHops = size; + LogPrint (eLogInfo, "Outbound tunnel length has beed adjusted to ", size, " for explicit peers"); + } + m_NumInboundTunnels = 1; + m_NumOutboundTunnels = 1; + } + } + void TunnelPool::DetachTunnels () { { @@ -291,10 +313,11 @@ namespace tunnel return hop; } - bool TunnelPool::SelectPeers (std::vector >& hops) + bool TunnelPool::SelectPeers (std::vector >& hops, bool isInbound) { + if (m_ExplicitPeers) return SelectExplicitPeers (hops, isInbound); auto prevHop = i2p::context.GetSharedRouterInfo (); - int numHops = m_NumInboundHops; + int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops; if (i2p::transport::transports.GetNumPeers () > 25) { auto r = i2p::transport::transports.GetRandomPeer (); @@ -319,7 +342,31 @@ namespace tunnel } return true; } - + + bool TunnelPool::SelectExplicitPeers (std::vector >& hops, bool isInbound) + { + int size = m_ExplicitPeers->size (); + std::vector peerIndicies; + for (int i = 0; i < size; i++) peerIndicies.push_back(i); + std::random_shuffle (peerIndicies.begin(), peerIndicies.end()); + + int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops; + for (int i = 0; i < numHops; i++) + { + auto& ident = (*m_ExplicitPeers)[peerIndicies[i]]; + auto r = i2p::data::netdb.FindRouter (ident); + if (r) + hops.push_back (r); + else + { + LogPrint (eLogInfo, "Can't find router for ", ident.ToBase64 ()); + i2p::data::netdb.RequestDestination (ident); + return false; + } + } + return true; + } + void TunnelPool::CreateInboundTunnel () { auto outboundTunnel = GetNextOutboundTunnel (); @@ -327,7 +374,7 @@ namespace tunnel outboundTunnel = tunnels.GetNextOutboundTunnel (); LogPrint ("Creating destination inbound tunnel..."); std::vector > hops; - if (SelectPeers (hops)) + if (SelectPeers (hops, true)) { std::reverse (hops.begin (), hops.end ()); auto tunnel = tunnels.CreateTunnel (std::make_shared (hops), outboundTunnel); @@ -356,7 +403,7 @@ namespace tunnel { LogPrint ("Creating destination outbound tunnel..."); std::vector > hops; - if (SelectPeers (hops)) + if (SelectPeers (hops, false)) { auto tunnel = tunnels.CreateTunnel ( std::make_shared (hops, inboundTunnel->GetTunnelConfig ())); diff --git a/TunnelPool.h b/TunnelPool.h index b20cfaf2..2232a787 100644 --- a/TunnelPool.h +++ b/TunnelPool.h @@ -32,6 +32,7 @@ namespace tunnel i2p::garlic::GarlicDestination * GetLocalDestination () const { return m_LocalDestination; }; void SetLocalDestination (i2p::garlic::GarlicDestination * destination) { m_LocalDestination = destination; }; + void SetExplicitPeers (std::shared_ptr > explicitPeers); void CreateTunnels (); void TunnelCreated (std::shared_ptr createdTunnel); @@ -61,12 +62,14 @@ namespace tunnel template typename TTunnels::value_type GetNextTunnel (TTunnels& tunnels, typename TTunnels::value_type excluded) const; std::shared_ptr SelectNextHop (std::shared_ptr prevHop) const; - bool SelectPeers (std::vector >& hops); - + bool SelectPeers (std::vector >& hops, bool isInbound); + bool SelectExplicitPeers (std::vector >& hops, bool isInbound); + private: i2p::garlic::GarlicDestination * m_LocalDestination; int m_NumInboundHops, m_NumOutboundHops, m_NumInboundTunnels, m_NumOutboundTunnels; + std::shared_ptr > m_ExplicitPeers; mutable std::mutex m_InboundTunnelsMutex; std::set, TunnelCreationTimeCmp> m_InboundTunnels; // recent tunnel appears first mutable std::mutex m_OutboundTunnelsMutex; From 23a3d4861146dfb6316c4f649e47134b7f59ff44 Mon Sep 17 00:00:00 2001 From: Mikhail Titov Date: Wed, 10 Jun 2015 16:08:22 -0500 Subject: [PATCH 27/67] This closes #201 --- SAM.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SAM.cpp b/SAM.cpp index 971ed45e..7de1a8a8 100644 --- a/SAM.cpp +++ b/SAM.cpp @@ -101,6 +101,9 @@ namespace client if (separator) { separator++; + char *eol = strchr (separator, '\n'); + if (eol) + *eol = 0; std::map params; ExtractParams (separator, params); auto it = params.find (SAM_PARAM_MAX); From 20e43951e5be07e083e6f7b8f2ff624288f8efd0 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 11 Jun 2015 11:43:35 -0400 Subject: [PATCH 28/67] reduce CPU usage --- NetDb.cpp | 40 +++++++++++++++------------------------- NetDb.h | 3 ++- 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/NetDb.cpp b/NetDb.cpp index 0ec8c41d..5ba3c17d 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -732,28 +732,13 @@ namespace data if (!replyMsg) { LogPrint ("Requested ", key, " not found. ", numExcluded, " excluded"); - std::vector routers; - if (numExcluded > 0) - { - std::set excludedRouters; - for (int i = 0; i < numExcluded; i++) - { - excludedRouters.insert (excluded); - excluded += 32; - } - for (int i = 0; i < 3; i++) - { - auto floodfill = GetClosestFloodfill (ident, excludedRouters); - if (floodfill) - { - routers.push_back (floodfill->GetIdentHash ()); - excludedRouters.insert (floodfill->GetIdentHash ()); - } - } - } - else - routers = GetClosestFloodfills (ident, 3); - replyMsg = CreateDatabaseSearchReply (ident, routers); + std::set excludedRouters; + for (int i = 0; i < numExcluded; i++) + { + excludedRouters.insert (excluded); + excluded += 32; + } + replyMsg = CreateDatabaseSearchReply (ident, GetClosestFloodfills (ident, 3, excludedRouters)); } } @@ -955,7 +940,8 @@ namespace data return r; } - std::vector NetDb::GetClosestFloodfills (const IdentHash& destination, size_t num) const + std::vector NetDb::GetClosestFloodfills (const IdentHash& destination, size_t num, + std::set& excluded) const { struct Sorted { @@ -990,8 +976,12 @@ namespace data { if (i < num) { - res.push_back (it.r->GetIdentHash ()); - i++; + auto& ident = it.r->GetIdentHash (); + if (!excluded.count (ident)) + { + res.push_back (ident); + i++; + } } else break; diff --git a/NetDb.h b/NetDb.h index 1a7ee0de..2c6e78be 100644 --- a/NetDb.h +++ b/NetDb.h @@ -51,7 +51,8 @@ namespace data std::shared_ptr GetRandomPeerTestRouter () const; std::shared_ptr GetRandomIntroducer () const; std::shared_ptr GetClosestFloodfill (const IdentHash& destination, const std::set& excluded) const; - std::vector GetClosestFloodfills (const IdentHash& destination, size_t num) const; + std::vector GetClosestFloodfills (const IdentHash& destination, size_t num, + std::set& excluded) const; std::shared_ptr GetClosestNonFloodfill (const IdentHash& destination, const std::set& excluded) const; void SetUnreachable (const IdentHash& ident, bool unreachable); From b48682012d8d23c479dbc1158270847238ae2e9b Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 14 Jun 2015 10:37:15 -0400 Subject: [PATCH 29/67] verify adler checksum --- NTCPSession.cpp | 11 +++++++++-- NTCPSession.h | 2 -- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/NTCPSession.cpp b/NTCPSession.cpp index 4d718450..c5dac0a2 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -2,6 +2,7 @@ #include #include "I2PEndian.h" #include +#include #include "base64.h" #include "Log.h" #include "Timestamp.h" @@ -587,7 +588,13 @@ namespace transport if (m_NextMessageOffset >= m_NextMessage->len + 4) // +checksum { // we have a complete I2NP message - m_Handler.PutNextMessage (m_NextMessage); + if (CryptoPP::Adler32().VerifyDigest (m_NextMessage->buf + m_NextMessageOffset - 4, m_NextMessage->buf, m_NextMessageOffset - 4)) + m_Handler.PutNextMessage (m_NextMessage); + else + { + LogPrint (eLogWarning, "Incorrect adler checksum of NTCP message. Dropped"); + DeleteI2NPMessage (m_NextMessage); + } m_NextMessage = nullptr; } return true; @@ -629,7 +636,7 @@ namespace transport int padding = 0; if (rem > 0) padding = 16 - rem; // TODO: fill padding - m_Adler.CalculateDigest (sendBuffer + len + 2 + padding, sendBuffer, len + 2+ padding); + CryptoPP::Adler32().CalculateDigest (sendBuffer + len + 2 + padding, sendBuffer, len + 2+ padding); int l = len + padding + 6; m_Encryption.Encrypt(sendBuffer, l, sendBuffer); diff --git a/NTCPSession.h b/NTCPSession.h index 85a0aeb7..8e3e9073 100644 --- a/NTCPSession.h +++ b/NTCPSession.h @@ -9,7 +9,6 @@ #include #include #include -#include #include "aes.h" #include "Identity.h" #include "RouterInfo.h" @@ -116,7 +115,6 @@ namespace transport i2p::crypto::CBCDecryption m_Decryption; i2p::crypto::CBCEncryption m_Encryption; - CryptoPP::Adler32 m_Adler; struct Establisher { From a0de60e179e60ced49c76b4da3e8ca8536111b4b Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 16 Jun 2015 10:14:14 -0400 Subject: [PATCH 30/67] use share_ptr for garlic messages --- Destination.cpp | 7 +++---- Destination.h | 6 +++--- Garlic.cpp | 11 ++++------- Garlic.h | 8 ++++---- I2NPProtocol.cpp | 21 ++++++++++++--------- RouterContext.cpp | 4 ++-- RouterContext.h | 4 ++-- TunnelPool.cpp | 11 ++--------- TunnelPool.h | 4 ++-- 9 files changed, 34 insertions(+), 42 deletions(-) diff --git a/Destination.cpp b/Destination.cpp index 63c89fff..27f2564c 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -215,12 +215,12 @@ namespace client return true; } - void ClientDestination::ProcessGarlicMessage (I2NPMessage * msg) + void ClientDestination::ProcessGarlicMessage (std::shared_ptr msg) { m_Service.post (std::bind (&ClientDestination::HandleGarlicMessage, this, msg)); } - void ClientDestination::ProcessDeliveryStatusMessage (I2NPMessage * msg) + void ClientDestination::ProcessDeliveryStatusMessage (std::shared_ptr msg) { m_Service.post (std::bind (&ClientDestination::HandleDeliveryStatusMessage, this, msg)); } @@ -343,7 +343,7 @@ namespace client LogPrint ("Request for ", key.ToBase64 (), " not found"); } - void ClientDestination::HandleDeliveryStatusMessage (I2NPMessage * msg) + void ClientDestination::HandleDeliveryStatusMessage (std::shared_ptr msg) { uint32_t msgID = bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET); if (msgID == m_PublishReplyToken) @@ -351,7 +351,6 @@ namespace client LogPrint (eLogDebug, "Publishing confirmed"); m_ExcludedFloodfills.clear (); m_PublishReplyToken = 0; - i2p::DeleteI2NPMessage (msg); } else i2p::garlic::GarlicDestination::HandleDeliveryStatusMessage (msg); diff --git a/Destination.h b/Destination.h index 1f48ded0..c41ee9ca 100644 --- a/Destination.h +++ b/Destination.h @@ -99,8 +99,8 @@ namespace client // override GarlicDestination bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); - void ProcessGarlicMessage (I2NPMessage * msg); - void ProcessDeliveryStatusMessage (I2NPMessage * msg); + void ProcessGarlicMessage (std::shared_ptr msg); + void ProcessDeliveryStatusMessage (std::shared_ptr msg); void SetLeaseSetUpdated (); // I2CP @@ -114,7 +114,7 @@ namespace client void HandlePublishConfirmationTimer (const boost::system::error_code& ecode); void HandleDatabaseStoreMessage (const uint8_t * buf, size_t len); void HandleDatabaseSearchReplyMessage (const uint8_t * buf, size_t len); - void HandleDeliveryStatusMessage (I2NPMessage * msg); + void HandleDeliveryStatusMessage (std::shared_ptr msg); void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete); bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr nextFloodfill, LeaseSetRequest * request); diff --git a/Garlic.cpp b/Garlic.cpp index bbfaed91..8bdfb10c 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -362,14 +362,13 @@ namespace garlic return true; } - void GarlicDestination::HandleGarlicMessage (I2NPMessage * msg) + void GarlicDestination::HandleGarlicMessage (std::shared_ptr msg) { uint8_t * buf = msg->GetPayload (); uint32_t length = bufbe32toh (buf); if (length > msg->GetLength ()) { LogPrint (eLogError, "Garlic message length ", length, " exceeds I2NP message length ", msg->GetLength ()); - DeleteI2NPMessage (msg); return; } buf += 4; // length @@ -406,7 +405,6 @@ namespace garlic else LogPrint (eLogError, "Failed to decrypt garlic"); } - DeleteI2NPMessage (msg); // cleanup expired tags uint32_t ts = i2p::util::GetSecondsSinceEpoch (); @@ -588,7 +586,7 @@ namespace garlic m_CreatedSessions[msgID] = session; } - void GarlicDestination::HandleDeliveryStatusMessage (I2NPMessage * msg) + void GarlicDestination::HandleDeliveryStatusMessage (std::shared_ptr msg) { uint32_t msgID = bufbe32toh (msg->GetPayload ()); { @@ -600,7 +598,6 @@ namespace garlic LogPrint (eLogInfo, "Garlic message ", msgID, " acknowledged"); } } - DeleteI2NPMessage (msg); } void GarlicDestination::SetLeaseSetUpdated () @@ -610,12 +607,12 @@ namespace garlic it.second->SetLeaseSetUpdated (); } - void GarlicDestination::ProcessGarlicMessage (I2NPMessage * msg) + void GarlicDestination::ProcessGarlicMessage (std::shared_ptr msg) { HandleGarlicMessage (msg); } - void GarlicDestination::ProcessDeliveryStatusMessage (I2NPMessage * msg) + void GarlicDestination::ProcessDeliveryStatusMessage (std::shared_ptr msg) { HandleDeliveryStatusMessage (msg); } diff --git a/Garlic.h b/Garlic.h index 489e532b..d5330735 100644 --- a/Garlic.h +++ b/Garlic.h @@ -133,8 +133,8 @@ namespace garlic virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread void DeliveryStatusSent (std::shared_ptr session, uint32_t msgID); - virtual void ProcessGarlicMessage (I2NPMessage * msg); - virtual void ProcessDeliveryStatusMessage (I2NPMessage * msg); + virtual void ProcessGarlicMessage (std::shared_ptr msg); + virtual void ProcessDeliveryStatusMessage (std::shared_ptr msg); virtual void SetLeaseSetUpdated (); virtual std::shared_ptr GetLeaseSet () = 0; // TODO @@ -143,8 +143,8 @@ namespace garlic protected: - void HandleGarlicMessage (I2NPMessage * msg); - void HandleDeliveryStatusMessage (I2NPMessage * msg); + void HandleGarlicMessage (std::shared_ptr msg); + void HandleDeliveryStatusMessage (std::shared_ptr msg); private: diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 104fdef1..3948afec 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -537,20 +537,20 @@ namespace i2p i2p::tunnel::tunnels.PostTunnelData (msg); break; case eI2NPGarlic: + { LogPrint ("Garlic"); + auto sharedMsg = ToSharedI2NPMessage (msg); if (msg->from) { if (msg->from->GetTunnelPool ()) - msg->from->GetTunnelPool ()->ProcessGarlicMessage (msg); + msg->from->GetTunnelPool ()->ProcessGarlicMessage (sharedMsg); else - { LogPrint (eLogInfo, "Local destination for garlic doesn't exist anymore"); - DeleteI2NPMessage (msg); - } } else - i2p::context.ProcessGarlicMessage (msg); - break; + i2p::context.ProcessGarlicMessage (sharedMsg); + break; + } case eI2NPDatabaseStore: case eI2NPDatabaseSearchReply: case eI2NPDatabaseLookup: @@ -558,12 +558,15 @@ namespace i2p i2p::data::netdb.PostI2NPMsg (msg); break; case eI2NPDeliveryStatus: + { LogPrint ("DeliveryStatus"); + auto sharedMsg = ToSharedI2NPMessage (msg); if (msg->from && msg->from->GetTunnelPool ()) - msg->from->GetTunnelPool ()->ProcessDeliveryStatus (msg); + msg->from->GetTunnelPool ()->ProcessDeliveryStatus (sharedMsg); else - i2p::context.ProcessDeliveryStatusMessage (msg); - break; + i2p::context.ProcessDeliveryStatusMessage (sharedMsg); + break; + } case eI2NPVariableTunnelBuild: case eI2NPVariableTunnelBuildReply: case eI2NPTunnelBuild: diff --git a/RouterContext.cpp b/RouterContext.cpp index 495f1181..c9328b5c 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -299,13 +299,13 @@ namespace i2p i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from)); } - void RouterContext::ProcessGarlicMessage (I2NPMessage * msg) + void RouterContext::ProcessGarlicMessage (std::shared_ptr msg) { std::unique_lock l(m_GarlicMutex); i2p::garlic::GarlicDestination::ProcessGarlicMessage (msg); } - void RouterContext::ProcessDeliveryStatusMessage (I2NPMessage * msg) + void RouterContext::ProcessDeliveryStatusMessage (std::shared_ptr msg) { std::unique_lock l(m_GarlicMutex); i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg); diff --git a/RouterContext.h b/RouterContext.h index 840d75ad..2689d025 100644 --- a/RouterContext.h +++ b/RouterContext.h @@ -78,8 +78,8 @@ namespace i2p void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from); // override GarlicDestination - void ProcessGarlicMessage (I2NPMessage * msg); - void ProcessDeliveryStatusMessage (I2NPMessage * msg); + void ProcessGarlicMessage (std::shared_ptr msg); + void ProcessDeliveryStatusMessage (std::shared_ptr msg); private: diff --git a/TunnelPool.cpp b/TunnelPool.cpp index 478d6f11..0f0eb709 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -260,18 +260,15 @@ namespace tunnel } } - void TunnelPool::ProcessGarlicMessage (I2NPMessage * msg) + void TunnelPool::ProcessGarlicMessage (std::shared_ptr msg) { if (m_LocalDestination) m_LocalDestination->ProcessGarlicMessage (msg); else - { LogPrint (eLogWarning, "Local destination doesn't exist. Dropped"); - DeleteI2NPMessage (msg); - } } - void TunnelPool::ProcessDeliveryStatus (I2NPMessage * msg) + void TunnelPool::ProcessDeliveryStatus (std::shared_ptr msg) { const uint8_t * buf = msg->GetPayload (); uint32_t msgID = bufbe32toh (buf); @@ -288,17 +285,13 @@ namespace tunnel it->second.second->SetState (eTunnelStateEstablished); LogPrint ("Tunnel test ", it->first, " successive. ", i2p::util::GetMillisecondsSinceEpoch () - timestamp, " milliseconds"); m_Tests.erase (it); - DeleteI2NPMessage (msg); } else { if (m_LocalDestination) m_LocalDestination->ProcessDeliveryStatusMessage (msg); else - { LogPrint (eLogWarning, "Local destination doesn't exist. Dropped"); - DeleteI2NPMessage (msg); - } } } diff --git a/TunnelPool.h b/TunnelPool.h index 2232a787..2d4203ef 100644 --- a/TunnelPool.h +++ b/TunnelPool.h @@ -47,8 +47,8 @@ namespace tunnel std::shared_ptr GetNewOutboundTunnel (std::shared_ptr old) const; void TestTunnels (); - void ProcessGarlicMessage (I2NPMessage * msg); - void ProcessDeliveryStatus (I2NPMessage * msg); + void ProcessGarlicMessage (std::shared_ptr msg); + void ProcessDeliveryStatus (std::shared_ptr msg); bool IsActive () const { return m_IsActive; }; void SetActive (bool isActive) { m_IsActive = isActive; }; From 465945f8a8e67ad6ec50b6a38220a831e05180c5 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 16 Jun 2015 13:14:33 -0400 Subject: [PATCH 31/67] more generic queue --- NetDb.h | 2 +- Queue.h | 30 +++++++++++++++--------------- Tunnel.h | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/NetDb.h b/NetDb.h index 2c6e78be..6b96f155 100644 --- a/NetDb.h +++ b/NetDb.h @@ -89,7 +89,7 @@ namespace data bool m_IsRunning; std::thread * m_Thread; - i2p::util::Queue m_Queue; // of I2NPDatabaseStoreMsg + i2p::util::Queue m_Queue; // of I2NPDatabaseStoreMsg Reseeder * m_Reseeder; diff --git a/Queue.h b/Queue.h index 086d6d81..6f50e189 100644 --- a/Queue.h +++ b/Queue.h @@ -17,14 +17,14 @@ namespace util { public: - void Put (Element * e) + void Put (Element e) { std::unique_lock l(m_QueueMutex); m_Queue.push (e); m_NonEmpty.notify_one (); } - void Put (const std::vector& vec) + void Put (const std::vector& vec) { if (!vec.empty ()) { @@ -35,10 +35,10 @@ namespace util } } - Element * GetNext () + Element GetNext () { std::unique_lock l(m_QueueMutex); - Element * el = GetNonThreadSafe (); + auto el = GetNonThreadSafe (); if (!el) { m_NonEmpty.wait (l); @@ -47,10 +47,10 @@ namespace util return el; } - Element * GetNextWithTimeout (int usec) + Element GetNextWithTimeout (int usec) { std::unique_lock l(m_QueueMutex); - Element * el = GetNonThreadSafe (); + auto el = GetNonThreadSafe (); if (!el) { m_NonEmpty.wait_for (l, std::chrono::milliseconds (usec)); @@ -85,13 +85,13 @@ namespace util void WakeUp () { m_NonEmpty.notify_all (); }; - Element * Get () + Element Get () { std::unique_lock l(m_QueueMutex); return GetNonThreadSafe (); } - Element * Peek () + Element Peek () { std::unique_lock l(m_QueueMutex); return GetNonThreadSafe (true); @@ -99,11 +99,11 @@ namespace util private: - Element * GetNonThreadSafe (bool peek = false) + Element GetNonThreadSafe (bool peek = false) { if (!m_Queue.empty ()) { - Element * el = m_Queue.front (); + auto el = m_Queue.front (); if (!peek) m_Queue.pop (); return el; @@ -113,13 +113,13 @@ namespace util private: - std::queue m_Queue; + std::queue m_Queue; std::mutex m_QueueMutex; std::condition_variable m_NonEmpty; }; template - class MsgQueue: public Queue + class MsgQueue: public Queue { public: @@ -132,7 +132,7 @@ namespace util if (m_IsRunning) { m_IsRunning = false; - Queue::WakeUp (); + Queue::WakeUp (); m_Thread.join(); } } @@ -145,7 +145,7 @@ namespace util { while (m_IsRunning) { - while (Msg * msg = Queue::Get ()) + while (auto msg = Queue::Get ()) { msg->Process (); delete msg; @@ -153,7 +153,7 @@ namespace util if (m_OnEmpty != nullptr) m_OnEmpty (); if (m_IsRunning) - Queue::Wait (); + Queue::Wait (); } } diff --git a/Tunnel.h b/Tunnel.h index be15aa91..b6362997 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -177,7 +177,7 @@ namespace tunnel std::mutex m_PoolsMutex; std::list> m_Pools; std::shared_ptr m_ExploratoryPool; - i2p::util::Queue m_Queue; + i2p::util::Queue m_Queue; // some stats int m_NumSuccesiveTunnelCreations, m_NumFailedTunnelCreations; From d65257c7b0a15c25c189b17f7327960a781260ad Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 16 Jun 2015 13:32:42 -0400 Subject: [PATCH 32/67] pass I2NP as shared_ptr to netDB --- I2NPProtocol.cpp | 2 +- NetDb.cpp | 12 ++++++------ NetDb.h | 4 ++-- Tunnel.cpp | 4 ++-- TunnelEndpoint.cpp | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 3948afec..5d7afdfd 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -555,7 +555,7 @@ namespace i2p case eI2NPDatabaseSearchReply: case eI2NPDatabaseLookup: // forward to netDb - i2p::data::netdb.PostI2NPMsg (msg); + i2p::data::netdb.PostI2NPMsg (ToSharedI2NPMessage (msg)); break; case eI2NPDeliveryStatus: { diff --git a/NetDb.cpp b/NetDb.cpp index 5ba3c17d..a72e919a 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -92,7 +92,7 @@ namespace data { try { - I2NPMessage * msg = m_Queue.GetNextWithTimeout (15000); // 15 sec + auto msg = m_Queue.GetNextWithTimeout (15000); // 15 sec if (msg) { int numMsgs = 0; @@ -102,19 +102,19 @@ namespace data { case eI2NPDatabaseStore: LogPrint ("DatabaseStore"); - HandleDatabaseStoreMsg (ToSharedI2NPMessage (msg)); + HandleDatabaseStoreMsg (msg); break; case eI2NPDatabaseSearchReply: LogPrint ("DatabaseSearchReply"); - HandleDatabaseSearchReplyMsg (ToSharedI2NPMessage (msg)); + HandleDatabaseSearchReplyMsg (msg); break; case eI2NPDatabaseLookup: LogPrint ("DatabaseLookup"); - HandleDatabaseLookupMsg (ToSharedI2NPMessage (msg)); + HandleDatabaseLookupMsg (msg); break; default: // WTF? LogPrint (eLogError, "NetDb: unexpected message type ", msg->GetTypeID ()); - i2p::HandleI2NPMessage (msg); + //i2p::HandleI2NPMessage (msg); } if (numMsgs > 100) break; msg = m_Queue.Get (); @@ -912,7 +912,7 @@ namespace data return nullptr; // seems we have too few routers } - void NetDb::PostI2NPMsg (I2NPMessage * msg) + void NetDb::PostI2NPMsg (std::shared_ptr msg) { if (msg) m_Queue.Put (msg); } diff --git a/NetDb.h b/NetDb.h index 6b96f155..5028819e 100644 --- a/NetDb.h +++ b/NetDb.h @@ -56,7 +56,7 @@ namespace data std::shared_ptr GetClosestNonFloodfill (const IdentHash& destination, const std::set& excluded) const; void SetUnreachable (const IdentHash& ident, bool unreachable); - void PostI2NPMsg (I2NPMessage * msg); + void PostI2NPMsg (std::shared_ptr msg); void Reseed (); @@ -89,7 +89,7 @@ namespace data bool m_IsRunning; std::thread * m_Thread; - i2p::util::Queue m_Queue; // of I2NPDatabaseStoreMsg + i2p::util::Queue > m_Queue; // of I2NPDatabaseStoreMsg Reseeder * m_Reseeder; diff --git a/Tunnel.cpp b/Tunnel.cpp index 59a9de2b..7c8714d9 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -453,8 +453,8 @@ namespace tunnel // transit DatabaseStore my contain new/updated RI // or DatabaseSearchReply with new routers auto ds = NewI2NPMessage (); - *ds = *msg; - i2p::data::netdb.PostI2NPMsg (ds); + *ds = *msg; // TODO: don't copy once msg is shared_ptr + i2p::data::netdb.PostI2NPMsg (ToSharedI2NPMessage (ds)); } tunnel->SendTunnelDataMsg (msg); } diff --git a/TunnelEndpoint.cpp b/TunnelEndpoint.cpp index 24d86e57..db7ed7a6 100644 --- a/TunnelEndpoint.cpp +++ b/TunnelEndpoint.cpp @@ -267,8 +267,8 @@ namespace tunnel { // catch RI or reply with new list of routers auto ds = NewI2NPShortMessage (); - *ds = *(msg.data); - i2p::data::netdb.PostI2NPMsg (ds); + *ds = *(msg.data); // TODO: don't copy once msg.data is shared_ptr + i2p::data::netdb.PostI2NPMsg (ToSharedI2NPMessage (ds)); } i2p::transport::transports.SendMessage (msg.hash, msg.data); } From 3a63f6775a1624c906d096d04eb147f5f7f9e912 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 17 Jun 2015 10:47:26 -0400 Subject: [PATCH 33/67] pass I2NP message to transport session as shared_ptr --- NTCPSession.cpp | 42 +++++++++++++----------------------------- NTCPSession.h | 18 +++++++++--------- SSUData.cpp | 4 +--- SSUData.h | 2 +- SSUSession.cpp | 26 ++++++++------------------ SSUSession.h | 8 ++++---- TransportSession.h | 4 ++-- Transports.cpp | 10 ++++++++-- Transports.h | 8 +------- 9 files changed, 47 insertions(+), 75 deletions(-) diff --git a/NTCPSession.cpp b/NTCPSession.cpp index c5dac0a2..b7596997 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -83,8 +83,6 @@ namespace transport m_Socket.close (); transports.PeerDisconnected (shared_from_this ()); m_Server.RemoveNTCPSession (shared_from_this ()); - for (auto it: m_SendQueue) - DeleteI2NPMessage (it); m_SendQueue.clear (); if (m_NextMessage) { @@ -107,7 +105,7 @@ namespace transport m_DHKeysPair = nullptr; SendTimeSyncMessage (); - PostI2NPMessage (CreateDatabaseStoreMsg ()); // we tell immediately who we are + PostI2NPMessage (ToSharedI2NPMessage(CreateDatabaseStoreMsg ())); // we tell immediately who we are transports.PeerConnected (shared_from_this ()); } @@ -600,14 +598,14 @@ namespace transport return true; } - void NTCPSession::Send (i2p::I2NPMessage * msg) + void NTCPSession::Send (std::shared_ptr msg) { m_IsSending = true; boost::asio::async_write (m_Socket, CreateMsgBuffer (msg), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, std::vector{ msg })); + std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, std::vector >{ msg })); } - boost::asio::const_buffers_1 NTCPSession::CreateMsgBuffer (I2NPMessage * msg) + boost::asio::const_buffers_1 NTCPSession::CreateMsgBuffer (std::shared_ptr msg) { uint8_t * sendBuffer; int len; @@ -616,10 +614,7 @@ namespace transport { // regular I2NP if (msg->offset < 2) - { - LogPrint (eLogError, "Malformed I2NP message"); - i2p::DeleteI2NPMessage (msg); - } + LogPrint (eLogError, "Malformed I2NP message"); // TODO: sendBuffer = msg->GetBuffer () - 2; len = msg->GetLength (); htobe16buf (sendBuffer, len); @@ -644,7 +639,7 @@ namespace transport } - void NTCPSession::Send (const std::vector& msgs) + void NTCPSession::Send (const std::vector >& msgs) { m_IsSending = true; std::vector bufs; @@ -654,11 +649,9 @@ namespace transport std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, msgs)); } - void NTCPSession::HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, std::vector msgs) + void NTCPSession::HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, std::vector > msgs) { m_IsSending = false; - for (auto it: msgs) - if (it) i2p::DeleteI2NPMessage (it); if (ecode) { LogPrint (eLogWarning, "Couldn't send msgs: ", ecode.message ()); @@ -686,20 +679,16 @@ namespace transport Send (nullptr); } - void NTCPSession::SendI2NPMessage (I2NPMessage * msg) + void NTCPSession::SendI2NPMessage (std::shared_ptr msg) { m_Server.GetService ().post (std::bind (&NTCPSession::PostI2NPMessage, shared_from_this (), msg)); } - void NTCPSession::PostI2NPMessage (I2NPMessage * msg) + void NTCPSession::PostI2NPMessage (std::shared_ptr msg) { if (msg) { - if (m_IsTerminated) - { - DeleteI2NPMessage (msg); - return; - } + if (m_IsTerminated) return; if (m_IsSending) m_SendQueue.push_back (msg); else @@ -707,19 +696,14 @@ namespace transport } } - void NTCPSession::SendI2NPMessages (const std::vector& msgs) + void NTCPSession::SendI2NPMessages (const std::vector >& msgs) { m_Server.GetService ().post (std::bind (&NTCPSession::PostI2NPMessages, shared_from_this (), msgs)); } - void NTCPSession::PostI2NPMessages (std::vector msgs) + void NTCPSession::PostI2NPMessages (std::vector > msgs) { - if (m_IsTerminated) - { - for (auto it: msgs) - DeleteI2NPMessage (it); - return; - } + if (m_IsTerminated) return; if (m_IsSending) { for (auto it: msgs) diff --git a/NTCPSession.h b/NTCPSession.h index 8e3e9073..b09713e4 100644 --- a/NTCPSession.h +++ b/NTCPSession.h @@ -61,13 +61,13 @@ namespace transport void ClientLogin (); void ServerLogin (); - void SendI2NPMessage (I2NPMessage * msg); - void SendI2NPMessages (const std::vector& msgs); + void SendI2NPMessage (std::shared_ptr msg); + void SendI2NPMessages (const std::vector >& msgs); private: - void PostI2NPMessage (I2NPMessage * msg); - void PostI2NPMessages (std::vector msgs); + void PostI2NPMessage (std::shared_ptr msg); + void PostI2NPMessages (std::vector > msgs); void Connected (); void SendTimeSyncMessage (); void SetIsEstablished (bool isEstablished) { m_IsEstablished = isEstablished; } @@ -96,10 +96,10 @@ namespace transport void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); bool DecryptNextBlock (const uint8_t * encrypted); - void Send (i2p::I2NPMessage * msg); - boost::asio::const_buffers_1 CreateMsgBuffer (I2NPMessage * msg); - void Send (const std::vector& msgs); - void HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, std::vector msgs); + void Send (std::shared_ptr msg); + boost::asio::const_buffers_1 CreateMsgBuffer (std::shared_ptr msg); + void Send (const std::vector >& msgs); + void HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, std::vector > msgs); // timer @@ -131,7 +131,7 @@ namespace transport i2p::I2NPMessagesHandler m_Handler; bool m_IsSending; - std::vector m_SendQueue; + std::vector > m_SendQueue; boost::asio::ip::address m_ConnectedFrom; // for ban }; diff --git a/SSUData.cpp b/SSUData.cpp index 4cacfd68..83b82aab 100644 --- a/SSUData.cpp +++ b/SSUData.cpp @@ -294,13 +294,12 @@ namespace transport ProcessFragments (buf); } - void SSUData::Send (i2p::I2NPMessage * msg) + void SSUData::Send (std::shared_ptr msg) { uint32_t msgID = msg->ToSSU (); if (m_SentMessages.count (msgID) > 0) { LogPrint (eLogWarning, "SSU message ", msgID, " already sent"); - DeleteI2NPMessage (msg); return; } if (m_SentMessages.empty ()) // schedule resend at first message only @@ -368,7 +367,6 @@ namespace transport len = 0; fragmentNum++; } - DeleteI2NPMessage (msg); } void SSUData::SendMsgAck (uint32_t msgID) diff --git a/SSUData.h b/SSUData.h index ff7bb96c..39d14cc4 100644 --- a/SSUData.h +++ b/SSUData.h @@ -89,7 +89,7 @@ namespace transport void ProcessMessage (uint8_t * buf, size_t len); void FlushReceivedMessage (); - void Send (i2p::I2NPMessage * msg); + void Send (std::shared_ptr msg); void UpdatePacketSize (const i2p::data::IdentHash& remoteIdent); diff --git a/SSUSession.cpp b/SSUSession.cpp index 1e4f0fe7..39ef9df0 100644 --- a/SSUSession.cpp +++ b/SSUSession.cpp @@ -262,7 +262,7 @@ namespace transport if (paddingSize > 0) paddingSize = 16 - paddingSize; payload += paddingSize; // TODO: verify signature (need data from session request), payload points to signature - m_Data.Send (CreateDeliveryStatusMsg (0)); + m_Data.Send (ToSharedI2NPMessage(CreateDeliveryStatusMsg (0))); Established (); } @@ -783,7 +783,7 @@ namespace transport m_DHKeysPair = nullptr; } m_Data.Start (); - m_Data.Send (CreateDatabaseStoreMsg ()); + m_Data.Send (ToSharedI2NPMessage(CreateDatabaseStoreMsg ())); transports.PeerConnected (shared_from_this ()); if (m_PeerTest && (m_RemoteRouter && m_RemoteRouter->IsPeerTesting ())) SendPeerTest (); @@ -832,39 +832,29 @@ namespace transport } } - void SSUSession::SendI2NPMessage (I2NPMessage * msg) + void SSUSession::SendI2NPMessage (std::shared_ptr msg) { GetService ().post (std::bind (&SSUSession::PostI2NPMessage, shared_from_this (), msg)); } - void SSUSession::PostI2NPMessage (I2NPMessage * msg) + void SSUSession::PostI2NPMessage (std::shared_ptr msg) { - if (msg) - { - if (m_State == eSessionStateEstablished) - m_Data.Send (msg); - else - DeleteI2NPMessage (msg); - } + if (msg &&m_State == eSessionStateEstablished) + m_Data.Send (msg); } - void SSUSession::SendI2NPMessages (const std::vector& msgs) + void SSUSession::SendI2NPMessages (const std::vector >& msgs) { GetService ().post (std::bind (&SSUSession::PostI2NPMessages, shared_from_this (), msgs)); } - void SSUSession::PostI2NPMessages (std::vector msgs) + void SSUSession::PostI2NPMessages (std::vector > msgs) { if (m_State == eSessionStateEstablished) { for (auto it: msgs) if (it) m_Data.Send (it); } - else - { - for (auto it: msgs) - DeleteI2NPMessage (it); - } } void SSUSession::ProcessData (uint8_t * buf, size_t len) diff --git a/SSUSession.h b/SSUSession.h index 5f980784..fd1ba39e 100644 --- a/SSUSession.h +++ b/SSUSession.h @@ -76,8 +76,8 @@ namespace transport void Done (); boost::asio::ip::udp::endpoint& GetRemoteEndpoint () { return m_RemoteEndpoint; }; bool IsV6 () const { return m_RemoteEndpoint.address ().is_v6 (); }; - void SendI2NPMessage (I2NPMessage * msg); - void SendI2NPMessages (const std::vector& msgs); + void SendI2NPMessage (std::shared_ptr msg); + void SendI2NPMessages (const std::vector >& msgs); void SendPeerTest (); // Alice SessionState GetState () const { return m_State; }; @@ -95,8 +95,8 @@ namespace transport boost::asio::io_service& GetService (); void CreateAESandMacKey (const uint8_t * pubKey); - void PostI2NPMessage (I2NPMessage * msg); - void PostI2NPMessages (std::vector msgs); + void PostI2NPMessage (std::shared_ptr msg); + void PostI2NPMessages (std::vector > msgs); void ProcessMessage (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); // call for established session void ProcessSessionRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); void SendSessionRequest (); diff --git a/TransportSession.h b/TransportSession.h index 95267452..dcd9f66c 100644 --- a/TransportSession.h +++ b/TransportSession.h @@ -71,8 +71,8 @@ namespace transport size_t GetNumSentBytes () const { return m_NumSentBytes; }; size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; }; - virtual void SendI2NPMessage (I2NPMessage * msg) = 0; - virtual void SendI2NPMessages (const std::vector& msgs) = 0; + virtual void SendI2NPMessage (std::shared_ptr msg) = 0; + virtual void SendI2NPMessages (const std::vector >& msgs) = 0; protected: diff --git a/Transports.cpp b/Transports.cpp index f288d113..c24bd508 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -255,11 +255,17 @@ namespace transport } } if (!it->second.sessions.empty ()) - it->second.sessions.front ()->SendI2NPMessages (msgs); + { + // TODO: remove this copy operation later + std::vector > msgs1; + for (auto it1: msgs) + msgs1.push_back (ToSharedI2NPMessage(it1)); + it->second.sessions.front ()->SendI2NPMessages (msgs1); + } else { for (auto it1: msgs) - it->second.delayedMessages.push_back (it1); + it->second.delayedMessages.push_back (ToSharedI2NPMessage(it1)); } } diff --git a/Transports.h b/Transports.h index ec04f6c7..d660a36c 100644 --- a/Transports.h +++ b/Transports.h @@ -62,19 +62,13 @@ namespace transport std::shared_ptr router; std::list > sessions; uint64_t creationTime; - std::vector delayedMessages; + std::vector > delayedMessages; void Done () { for (auto it: sessions) it->Done (); } - - ~Peer () - { - for (auto it :delayedMessages) - i2p::DeleteI2NPMessage (it); - } }; const size_t SESSION_CREATION_TIMEOUT = 10; // in seconds From 25a163cdeb39d3fd02c3dbeb16c640b3d76c0f60 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 17 Jun 2015 11:41:07 -0400 Subject: [PATCH 34/67] send I2NP messages as shared_ptr --- Transports.cpp | 41 ++++++++++++++++++++++++----------------- Transports.h | 8 +++++--- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/Transports.cpp b/Transports.cpp index c24bd508..a4c8d1a8 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -215,21 +215,39 @@ namespace transport void Transports::SendMessage (const i2p::data::IdentHash& ident, i2p::I2NPMessage * msg) { - m_Service.post (std::bind (&Transports::PostMessages, this, ident, std::vector {msg})); + SendMessage (ident, ToSharedI2NPMessage (msg)); } void Transports::SendMessages (const i2p::data::IdentHash& ident, const std::vector& msgs) + { + std::vector > msgs1; + for (auto it: msgs) + msgs1.push_back (ToSharedI2NPMessage (it)); + SendMessages (ident, msgs1); + } + + void Transports::SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg) + { + m_Service.post (std::bind (&Transports::PostMessages, this, ident, std::vector > {msg })); + } + + void Transports::SendMessages (const i2p::data::IdentHash& ident, const std::vector >& msgs) { m_Service.post (std::bind (&Transports::PostMessages, this, ident, msgs)); } - void Transports::PostMessages (i2p::data::IdentHash ident, std::vector msgs) + void Transports::PostMessages (i2p::data::IdentHash ident, std::vector > msgs) { if (ident == i2p::context.GetRouterInfo ().GetIdentHash ()) { // we send it to ourself for (auto it: msgs) - i2p::HandleI2NPMessage (it); + { + // TODO: + auto m = NewI2NPMessage (); + *m = *(it); + i2p::HandleI2NPMessage (m); + } return; } auto it = m_Peers.find (ident); @@ -247,25 +265,14 @@ namespace transport { LogPrint (eLogError, "Transports::PostMessages ", ex.what ()); } - if (!connected) - { - for (auto it1: msgs) - DeleteI2NPMessage (it1); - return; - } + if (!connected) return; } if (!it->second.sessions.empty ()) - { - // TODO: remove this copy operation later - std::vector > msgs1; - for (auto it1: msgs) - msgs1.push_back (ToSharedI2NPMessage(it1)); - it->second.sessions.front ()->SendI2NPMessages (msgs1); - } + it->second.sessions.front ()->SendI2NPMessages (msgs); else { for (auto it1: msgs) - it->second.delayedMessages.push_back (ToSharedI2NPMessage(it1)); + it->second.delayedMessages.push_back (it1); } } diff --git a/Transports.h b/Transports.h index d660a36c..b29d7f1a 100644 --- a/Transports.h +++ b/Transports.h @@ -87,8 +87,10 @@ namespace transport i2p::transport::DHKeysPair * GetNextDHKeysPair (); void ReuseDHKeysPair (DHKeysPair * pair); - void SendMessage (const i2p::data::IdentHash& ident, i2p::I2NPMessage * msg); - void SendMessages (const i2p::data::IdentHash& ident, const std::vector& msgs); + void SendMessage (const i2p::data::IdentHash& ident, i2p::I2NPMessage * msg); // deprecated + void SendMessages (const i2p::data::IdentHash& ident, const std::vector& msgs); // deprecated + void SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg); + void SendMessages (const i2p::data::IdentHash& ident, const std::vector >& msgs); void CloseSession (std::shared_ptr router); void PeerConnected (std::shared_ptr session); @@ -110,7 +112,7 @@ namespace transport void Run (); void RequestComplete (std::shared_ptr r, const i2p::data::IdentHash& ident); void HandleRequestComplete (std::shared_ptr r, const i2p::data::IdentHash& ident); - void PostMessages (i2p::data::IdentHash ident, std::vector msgs); + void PostMessages (i2p::data::IdentHash ident, std::vector > msgs); void PostCloseSession (std::shared_ptr router); bool ConnectToPeer (const i2p::data::IdentHash& ident, Peer& peer); void HandlePeerCleanupTimer (const boost::system::error_code& ecode); From 5ca86b87f5476737fbad14df9daa7ad84fff5986 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 17 Jun 2015 12:08:06 -0400 Subject: [PATCH 35/67] create shared I2NP tunnel message in OBGW --- TunnelGateway.cpp | 8 +++----- TunnelGateway.h | 7 ++++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/TunnelGateway.cpp b/TunnelGateway.cpp index fbef1208..33935259 100644 --- a/TunnelGateway.cpp +++ b/TunnelGateway.cpp @@ -12,8 +12,6 @@ namespace tunnel { TunnelGatewayBuffer::~TunnelGatewayBuffer () { - for (auto it: m_TunnelDataMsgs) - DeleteI2NPMessage (it); } void TunnelGatewayBuffer::PutI2NPMsg (const TunnelMessageBlock& block) @@ -138,7 +136,7 @@ namespace tunnel void TunnelGatewayBuffer::CreateCurrentTunnelDataMessage () { - m_CurrentTunnelDataMsg = NewI2NPShortMessage (); + m_CurrentTunnelDataMsg = ToSharedI2NPMessage (NewI2NPShortMessage ()); m_CurrentTunnelDataMsg->Align (12); // we reserve space for padding m_CurrentTunnelDataMsg->offset += TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE; @@ -192,8 +190,8 @@ namespace tunnel auto tunnelMsgs = m_Buffer.GetTunnelDataMsgs (); for (auto tunnelMsg : tunnelMsgs) { - m_Tunnel->EncryptTunnelMsg (tunnelMsg); - FillI2NPMessageHeader (tunnelMsg, eI2NPTunnelData); + m_Tunnel->EncryptTunnelMsg (tunnelMsg.get ()); // TODO: + FillI2NPMessageHeader (tunnelMsg.get (), eI2NPTunnelData); // TODO: m_NumSentBytes += TUNNEL_DATA_MSG_SIZE; } i2p::transport::transports.SendMessages (m_Tunnel->GetNextIdentHash (), tunnelMsgs); diff --git a/TunnelGateway.h b/TunnelGateway.h index b81c01d3..cfad17b5 100644 --- a/TunnelGateway.h +++ b/TunnelGateway.h @@ -3,6 +3,7 @@ #include #include +#include #include "I2NPProtocol.h" #include "TunnelBase.h" @@ -17,7 +18,7 @@ namespace tunnel m_CurrentTunnelDataMsg (nullptr), m_RemainingSize (0) {}; ~TunnelGatewayBuffer (); void PutI2NPMsg (const TunnelMessageBlock& block); - const std::vector& GetTunnelDataMsgs () const { return m_TunnelDataMsgs; }; + const std::vector >& GetTunnelDataMsgs () const { return m_TunnelDataMsgs; }; void ClearTunnelDataMsgs (); void CompleteCurrentTunnelDataMessage (); @@ -28,8 +29,8 @@ namespace tunnel private: uint32_t m_TunnelID; - std::vector m_TunnelDataMsgs; - I2NPMessage * m_CurrentTunnelDataMsg; + std::vector > m_TunnelDataMsgs; + std::shared_ptr m_CurrentTunnelDataMsg; size_t m_RemainingSize; }; From a7cd16c1590683995751d891360dbc3dbceb8fbe Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 17 Jun 2015 12:25:02 -0400 Subject: [PATCH 36/67] use shared_ptr for direct DatabaseLookup message --- NetDbRequests.cpp | 4 ++-- NetDbRequests.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NetDbRequests.cpp b/NetDbRequests.cpp index 5e71e3f7..3509bcc7 100644 --- a/NetDbRequests.cpp +++ b/NetDbRequests.cpp @@ -19,13 +19,13 @@ namespace data return msg; } - I2NPMessage * RequestedDestination::CreateRequestMessage (const IdentHash& floodfill) + std::shared_ptr RequestedDestination::CreateRequestMessage (const IdentHash& floodfill) { I2NPMessage * msg = i2p::CreateRouterInfoDatabaseLookupMsg (m_Destination, i2p::context.GetRouterInfo ().GetIdentHash () , 0, false, &m_ExcludedPeers); m_ExcludedPeers.insert (floodfill); m_CreationTime = i2p::util::GetSecondsSinceEpoch (); - return msg; + return ToSharedI2NPMessage (msg); } void RequestedDestination::ClearExcludedPeers () diff --git a/NetDbRequests.h b/NetDbRequests.h index 4f7555d4..9dc49b26 100644 --- a/NetDbRequests.h +++ b/NetDbRequests.h @@ -29,7 +29,7 @@ namespace data bool IsExcluded (const IdentHash& ident) const { return m_ExcludedPeers.count (ident); }; uint64_t GetCreationTime () const { return m_CreationTime; }; I2NPMessage * CreateRequestMessage (std::shared_ptr, std::shared_ptr replyTunnel); - I2NPMessage * CreateRequestMessage (const IdentHash& floodfill); + std::shared_ptr CreateRequestMessage (const IdentHash& floodfill); void SetRequestComplete (const RequestComplete& requestComplete) { m_RequestComplete = requestComplete; }; bool IsRequestComplete () const { return m_RequestComplete != nullptr; }; From 98c91a01e39e8e430123438cab237a9a7a512734 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 17 Jun 2015 12:26:07 -0400 Subject: [PATCH 37/67] use shared_ptr for outbound tunnel build messages --- Tunnel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tunnel.cpp b/Tunnel.cpp index 7c8714d9..6568c509 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -83,7 +83,7 @@ namespace tunnel if (outboundTunnel) outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, msg); else - i2p::transport::transports.SendMessage (GetNextIdentHash (), msg); + i2p::transport::transports.SendMessage (GetNextIdentHash (), ToSharedI2NPMessage (msg)); } bool Tunnel::HandleTunnelBuildResponse (uint8_t * msg, size_t len) From 122b8c2a84b7a03b2712327251d04a6eb8dfd5e0 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 17 Jun 2015 12:31:28 -0400 Subject: [PATCH 38/67] use shared_ptr for transit tunnel participant --- TransitTunnel.cpp | 4 +--- TransitTunnel.h | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/TransitTunnel.cpp b/TransitTunnel.cpp index a3135db1..e0828f13 100644 --- a/TransitTunnel.cpp +++ b/TransitTunnel.cpp @@ -27,8 +27,6 @@ namespace tunnel TransitTunnelParticipant::~TransitTunnelParticipant () { - for (auto it: m_TunnelDataMsgs) - i2p::DeleteI2NPMessage (it); } void TransitTunnelParticipant::HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg) @@ -38,7 +36,7 @@ namespace tunnel m_NumTransmittedBytes += tunnelMsg->GetLength (); htobe32buf (tunnelMsg->GetPayload (), GetNextTunnelID ()); FillI2NPMessageHeader (tunnelMsg, eI2NPTunnelData); - m_TunnelDataMsgs.push_back (tunnelMsg); + m_TunnelDataMsgs.push_back (ToSharedI2NPMessage (tunnelMsg)); } void TransitTunnelParticipant::FlushTunnelDataMsgs () diff --git a/TransitTunnel.h b/TransitTunnel.h index a2a0347f..3f7d8676 100644 --- a/TransitTunnel.h +++ b/TransitTunnel.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "aes.h" #include "I2NPProtocol.h" #include "TunnelEndpoint.h" @@ -59,7 +60,7 @@ namespace tunnel private: size_t m_NumTransmittedBytes; - std::vector m_TunnelDataMsgs; + std::vector > m_TunnelDataMsgs; }; class TransitTunnelGateway: public TransitTunnel From 4ed7e29896bf00f73282be3bdb61bc23482b8b54 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 19 Jun 2015 14:38:31 -0400 Subject: [PATCH 39/67] use shared_ptr for I2NP messages through tunnels --- Datagram.cpp | 2 +- Destination.cpp | 4 ++-- I2NPProtocol.cpp | 30 +++++++++++++----------------- I2NPProtocol.h | 6 +++--- NetDb.cpp | 10 +++++----- RouterContext.cpp | 2 +- Streaming.cpp | 2 +- TransitTunnel.cpp | 18 ++++++++---------- TransitTunnel.h | 12 ++++++------ Transports.cpp | 7 +------ Tunnel.cpp | 36 ++++++++++++------------------------ Tunnel.h | 16 ++++++++-------- TunnelBase.h | 8 ++++---- TunnelEndpoint.cpp | 37 +++++-------------------------------- TunnelEndpoint.h | 6 +++--- TunnelGateway.cpp | 6 ++---- 16 files changed, 75 insertions(+), 127 deletions(-) diff --git a/Datagram.cpp b/Datagram.cpp index adb76d58..9179fb80 100644 --- a/Datagram.cpp +++ b/Datagram.cpp @@ -65,7 +65,7 @@ namespace datagram { i2p::tunnel::eDeliveryTypeTunnel, leases[i].tunnelGateway, leases[i].tunnelID, - garlic + ToSharedI2NPMessage (garlic) }); outboundTunnel->SendTunnelDataMsg (msgs); } diff --git a/Destination.cpp b/Destination.cpp index 27f2564c..107bcf0a 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -240,7 +240,7 @@ namespace client HandleDatabaseSearchReplyMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET)); break; default: - i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from)); + i2p::HandleI2NPMessage (ToSharedI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from))); } } @@ -589,7 +589,7 @@ namespace client i2p::tunnel::TunnelMessageBlock { i2p::tunnel::eDeliveryTypeRouter, - nextFloodfill->GetIdentHash (), 0, msg + nextFloodfill->GetIdentHash (), 0, ToSharedI2NPMessage (msg) } }); request->requestTimeoutTimer.expires_from_now (boost::posix_time::seconds(LEASESET_REQUEST_TIMEOUT)); diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 5d7afdfd..e4685c7e 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -445,7 +445,7 @@ namespace i2p return msg; } - I2NPMessage * CreateTunnelGatewayMsg (uint32_t tunnelID, I2NPMessage * msg) + std::shared_ptr CreateTunnelGatewayMsg (uint32_t tunnelID, std::shared_ptr msg) { if (msg->offset >= I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE) { @@ -456,14 +456,13 @@ namespace i2p htobe16buf (payload + TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET, len); msg->offset -= (I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE); msg->len = msg->offset + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE +len; - FillI2NPMessageHeader (msg, eI2NPTunnelGateway); + FillI2NPMessageHeader (msg.get(), eI2NPTunnelGateway); // TODO return msg; } else { I2NPMessage * msg1 = CreateTunnelGatewayMsg (tunnelID, msg->GetBuffer (), msg->GetLength ()); - DeleteI2NPMessage (msg); - return msg1; + return ToSharedI2NPMessage (msg1); } } @@ -522,7 +521,7 @@ namespace i2p } } - void HandleI2NPMessage (I2NPMessage * msg) + void HandleI2NPMessage (std::shared_ptr msg) { if (msg) { @@ -539,32 +538,30 @@ namespace i2p case eI2NPGarlic: { LogPrint ("Garlic"); - auto sharedMsg = ToSharedI2NPMessage (msg); if (msg->from) { if (msg->from->GetTunnelPool ()) - msg->from->GetTunnelPool ()->ProcessGarlicMessage (sharedMsg); + msg->from->GetTunnelPool ()->ProcessGarlicMessage (msg); else LogPrint (eLogInfo, "Local destination for garlic doesn't exist anymore"); } else - i2p::context.ProcessGarlicMessage (sharedMsg); + i2p::context.ProcessGarlicMessage (msg); break; } case eI2NPDatabaseStore: case eI2NPDatabaseSearchReply: case eI2NPDatabaseLookup: // forward to netDb - i2p::data::netdb.PostI2NPMsg (ToSharedI2NPMessage (msg)); + i2p::data::netdb.PostI2NPMsg (msg); break; case eI2NPDeliveryStatus: { LogPrint ("DeliveryStatus"); - auto sharedMsg = ToSharedI2NPMessage (msg); if (msg->from && msg->from->GetTunnelPool ()) - msg->from->GetTunnelPool ()->ProcessDeliveryStatus (sharedMsg); + msg->from->GetTunnelPool ()->ProcessDeliveryStatus (msg); else - i2p::context.ProcessDeliveryStatusMessage (sharedMsg); + i2p::context.ProcessDeliveryStatusMessage (msg); break; } case eI2NPVariableTunnelBuild: @@ -576,7 +573,6 @@ namespace i2p break; default: HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ()); - DeleteI2NPMessage (msg); } } } @@ -586,20 +582,20 @@ namespace i2p Flush (); } - void I2NPMessagesHandler::PutNextMessage (I2NPMessage * msg) + void I2NPMessagesHandler::PutNextMessage (I2NPMessage * msg) { if (msg) { switch (msg->GetTypeID ()) { case eI2NPTunnelData: - m_TunnelMsgs.push_back (msg); + m_TunnelMsgs.push_back (ToSharedI2NPMessage (msg)); break; case eI2NPTunnelGateway: - m_TunnelGatewayMsgs.push_back (msg); + m_TunnelGatewayMsgs.push_back (ToSharedI2NPMessage (msg)); break; default: - HandleI2NPMessage (msg); + HandleI2NPMessage (ToSharedI2NPMessage (msg)); } } } diff --git a/I2NPProtocol.h b/I2NPProtocol.h index 093d66ed..cee97bec 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -225,11 +225,11 @@ namespace tunnel I2NPMessage * CreateTunnelGatewayMsg (uint32_t tunnelID, const uint8_t * buf, size_t len); I2NPMessage * CreateTunnelGatewayMsg (uint32_t tunnelID, I2NPMessageType msgType, const uint8_t * buf, size_t len, uint32_t replyMsgID = 0); - I2NPMessage * CreateTunnelGatewayMsg (uint32_t tunnelID, I2NPMessage * msg); + std::shared_ptr CreateTunnelGatewayMsg (uint32_t tunnelID, std::shared_ptr msg); size_t GetI2NPMessageLength (const uint8_t * msg); void HandleI2NPMessage (uint8_t * msg, size_t len); - void HandleI2NPMessage (I2NPMessage * msg); + void HandleI2NPMessage (std::shared_ptr msg); class I2NPMessagesHandler { @@ -241,7 +241,7 @@ namespace tunnel private: - std::vector m_TunnelMsgs, m_TunnelGatewayMsgs; + std::vector > m_TunnelMsgs, m_TunnelGatewayMsgs; }; } diff --git a/NetDb.cpp b/NetDb.cpp index a72e919a..e97f6985 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -597,7 +597,7 @@ namespace data { i2p::tunnel::eDeliveryTypeRouter, nextFloodfill->GetIdentHash (), 0, - CreateDatabaseStoreMsg () + ToSharedI2NPMessage (CreateDatabaseStoreMsg ()) }); // request destination @@ -606,7 +606,7 @@ namespace data msgs.push_back (i2p::tunnel::TunnelMessageBlock { i2p::tunnel::eDeliveryTypeRouter, - nextFloodfill->GetIdentHash (), 0, msg + nextFloodfill->GetIdentHash (), 0, ToSharedI2NPMessage (msg) }); deleteDest = false; } @@ -763,7 +763,7 @@ namespace data if (outbound) outbound->SendTunnelDataMsg (buf+32, replyTunnelID, replyMsg); else - transports.SendMessage (buf+32, i2p::CreateTunnelGatewayMsg (replyTunnelID, replyMsg)); + transports.SendMessage (buf+32, i2p::CreateTunnelGatewayMsg (replyTunnelID, ToSharedI2NPMessage(replyMsg))); } else transports.SendMessage (buf+32, replyMsg); @@ -804,13 +804,13 @@ namespace data { i2p::tunnel::eDeliveryTypeRouter, floodfill->GetIdentHash (), 0, - CreateDatabaseStoreMsg () // tell floodfill about us + ToSharedI2NPMessage (CreateDatabaseStoreMsg ()) // tell floodfill about us }); msgs.push_back (i2p::tunnel::TunnelMessageBlock { i2p::tunnel::eDeliveryTypeRouter, floodfill->GetIdentHash (), 0, - dest->CreateRequestMessage (floodfill, inbound) // explore + ToSharedI2NPMessage (dest->CreateRequestMessage (floodfill, inbound)) // explore }); } else diff --git a/RouterContext.cpp b/RouterContext.cpp index c9328b5c..29815b06 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -296,7 +296,7 @@ namespace i2p void RouterContext::HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) { - i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from)); + i2p::HandleI2NPMessage (ToSharedI2NPMessage(CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from))); } void RouterContext::ProcessGarlicMessage (std::shared_ptr msg) diff --git a/Streaming.cpp b/Streaming.cpp index 4d9342c1..e20efffb 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -617,7 +617,7 @@ namespace stream { i2p::tunnel::eDeliveryTypeTunnel, m_CurrentRemoteLease.tunnelGateway, m_CurrentRemoteLease.tunnelID, - msg + ToSharedI2NPMessage (msg) }); m_NumSentBytes += it->GetLength (); } diff --git a/TransitTunnel.cpp b/TransitTunnel.cpp index e0828f13..aa4636d6 100644 --- a/TransitTunnel.cpp +++ b/TransitTunnel.cpp @@ -20,7 +20,7 @@ namespace tunnel m_Encryption.SetKeys (layerKey, ivKey); } - void TransitTunnel::EncryptTunnelMsg (I2NPMessage * tunnelMsg) + void TransitTunnel::EncryptTunnelMsg (std::shared_ptr tunnelMsg) { m_Encryption.Encrypt (tunnelMsg->GetPayload () + 4); } @@ -29,14 +29,14 @@ namespace tunnel { } - void TransitTunnelParticipant::HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg) + void TransitTunnelParticipant::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) { EncryptTunnelMsg (tunnelMsg); m_NumTransmittedBytes += tunnelMsg->GetLength (); htobe32buf (tunnelMsg->GetPayload (), GetNextTunnelID ()); - FillI2NPMessageHeader (tunnelMsg, eI2NPTunnelData); - m_TunnelDataMsgs.push_back (ToSharedI2NPMessage (tunnelMsg)); + FillI2NPMessageHeader (tunnelMsg.get (), eI2NPTunnelData); // TODO + m_TunnelDataMsgs.push_back (tunnelMsg); } void TransitTunnelParticipant::FlushTunnelDataMsgs () @@ -51,19 +51,17 @@ namespace tunnel } } - void TransitTunnel::SendTunnelDataMsg (i2p::I2NPMessage * msg) + void TransitTunnel::SendTunnelDataMsg (std::shared_ptr msg) { LogPrint (eLogError, "We are not a gateway for transit tunnel ", m_TunnelID); - i2p::DeleteI2NPMessage (msg); } - void TransitTunnel::HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg) + void TransitTunnel::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) { LogPrint (eLogError, "Incoming tunnel message is not supported ", m_TunnelID); - DeleteI2NPMessage (tunnelMsg); } - void TransitTunnelGateway::SendTunnelDataMsg (i2p::I2NPMessage * msg) + void TransitTunnelGateway::SendTunnelDataMsg (std::shared_ptr msg) { TunnelMessageBlock block; block.deliveryType = eDeliveryTypeLocal; @@ -78,7 +76,7 @@ namespace tunnel m_Gateway.SendBuffer (); } - void TransitTunnelEndpoint::HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg) + void TransitTunnelEndpoint::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) { EncryptTunnelMsg (tunnelMsg); diff --git a/TransitTunnel.h b/TransitTunnel.h index 3f7d8676..e6e0601d 100644 --- a/TransitTunnel.h +++ b/TransitTunnel.h @@ -28,9 +28,9 @@ namespace tunnel uint32_t GetTunnelID () const { return m_TunnelID; }; // implements TunnelBase - void SendTunnelDataMsg (i2p::I2NPMessage * msg); - void HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg); - void EncryptTunnelMsg (I2NPMessage * tunnelMsg); + void SendTunnelDataMsg (std::shared_ptr msg); + void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); + void EncryptTunnelMsg (std::shared_ptr tunnelMsg); uint32_t GetNextTunnelID () const { return m_NextTunnelID; }; const i2p::data::IdentHash& GetNextIdentHash () const { return m_NextIdent; }; @@ -54,7 +54,7 @@ namespace tunnel ~TransitTunnelParticipant (); size_t GetNumTransmittedBytes () const { return m_NumTransmittedBytes; }; - void HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); void FlushTunnelDataMsgs (); private: @@ -73,7 +73,7 @@ namespace tunnel TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey), m_Gateway(this) {}; - void SendTunnelDataMsg (i2p::I2NPMessage * msg); + void SendTunnelDataMsg (std::shared_ptr msg); void FlushTunnelDataMsgs (); size_t GetNumTransmittedBytes () const { return m_Gateway.GetNumSentBytes (); }; @@ -93,7 +93,7 @@ namespace tunnel TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey), m_Endpoint (false) {}; // transit endpoint is always outbound - void HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); size_t GetNumTransmittedBytes () const { return m_Endpoint.GetNumReceivedBytes (); } private: diff --git a/Transports.cpp b/Transports.cpp index a4c8d1a8..381d31e8 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -242,12 +242,7 @@ namespace transport { // we send it to ourself for (auto it: msgs) - { - // TODO: - auto m = NewI2NPMessage (); - *m = *(it); - i2p::HandleI2NPMessage (m); - } + i2p::HandleI2NPMessage (it); return; } auto it = m_Peers.find (ident); diff --git a/Tunnel.cpp b/Tunnel.cpp index 6568c509..5341da32 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -31,7 +31,7 @@ namespace tunnel CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator (); auto numHops = m_Config->GetNumHops (); int numRecords = numHops <= STANDARD_NUM_RECORDS ? STANDARD_NUM_RECORDS : numHops; - I2NPMessage * msg = NewI2NPShortMessage (); + auto msg = NewI2NPShortMessage (); *msg->GetPayload () = numRecords; msg->len += numRecords*TUNNEL_BUILD_RECORD_SIZE + 1; @@ -140,7 +140,7 @@ namespace tunnel return established; } - void Tunnel::EncryptTunnelMsg (I2NPMessage * tunnelMsg) + void Tunnel::EncryptTunnelMsg (std::shared_ptr tunnelMsg) { uint8_t * payload = tunnelMsg->GetPayload () + 4; TunnelHopConfig * hop = m_Config->GetLastHop (); @@ -151,13 +151,12 @@ namespace tunnel } } - void Tunnel::SendTunnelDataMsg (i2p::I2NPMessage * msg) + void Tunnel::SendTunnelDataMsg (std::shared_ptr msg) { LogPrint (eLogInfo, "Can't send I2NP messages without delivery instructions"); - DeleteI2NPMessage (msg); } - void InboundTunnel::HandleTunnelDataMsg (I2NPMessage * msg) + void InboundTunnel::HandleTunnelDataMsg (std::shared_ptr msg) { if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive msg->from = shared_from_this (); @@ -181,7 +180,7 @@ namespace tunnel } else block.deliveryType = eDeliveryTypeLocal; - block.data = msg; + block.data = ToSharedI2NPMessage (msg); std::unique_lock l(m_SendMutex); m_Gateway.SendTunnelDataMsg (block); @@ -195,10 +194,9 @@ namespace tunnel m_Gateway.SendBuffer (); } - void OutboundTunnel::HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg) + void OutboundTunnel::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) { LogPrint (eLogError, "Incoming message for outbound tunnel ", GetTunnelID ()); - DeleteI2NPMessage (tunnelMsg); } Tunnels tunnels; @@ -352,7 +350,7 @@ namespace tunnel { try { - I2NPMessage * msg = m_Queue.GetNextWithTimeout (1000); // 1 sec + auto msg = m_Queue.GetNextWithTimeout (1000); // 1 sec if (msg) { uint32_t prevTunnelID = 0, tunnelID = 0; @@ -383,27 +381,18 @@ namespace tunnel else // tunnel gateway assumed HandleTunnelGatewayMsg (tunnel, msg); } - else - { + else LogPrint (eLogWarning, "Tunnel ", tunnelID, " not found"); - DeleteI2NPMessage (msg); - } break; } case eI2NPVariableTunnelBuild: case eI2NPVariableTunnelBuildReply: case eI2NPTunnelBuild: case eI2NPTunnelBuildReply: - { HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ()); - DeleteI2NPMessage (msg); - break; - } + break; default: - { LogPrint (eLogError, "Unexpected messsage type ", (int)typeID); - DeleteI2NPMessage (msg); - } } msg = m_Queue.Get (); @@ -432,12 +421,11 @@ namespace tunnel } } - void Tunnels::HandleTunnelGatewayMsg (TunnelBase * tunnel, I2NPMessage * msg) + void Tunnels::HandleTunnelGatewayMsg (TunnelBase * tunnel, std::shared_ptr msg) { if (!tunnel) { LogPrint (eLogError, "Missing tunnel for TunnelGateway"); - i2p::DeleteI2NPMessage (msg); return; } const uint8_t * payload = msg->GetPayload (); @@ -661,12 +649,12 @@ namespace tunnel } } - void Tunnels::PostTunnelData (I2NPMessage * msg) + void Tunnels::PostTunnelData (std::shared_ptr msg) { if (msg) m_Queue.Put (msg); } - void Tunnels::PostTunnelData (const std::vector& msgs) + void Tunnels::PostTunnelData (const std::vector >& msgs) { m_Queue.Put (msgs); } diff --git a/Tunnel.h b/Tunnel.h index b6362997..f8c5e9cc 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -64,8 +64,8 @@ namespace tunnel bool HandleTunnelBuildResponse (uint8_t * msg, size_t len); // implements TunnelBase - void SendTunnelDataMsg (i2p::I2NPMessage * msg); - void EncryptTunnelMsg (I2NPMessage * tunnelMsg); + void SendTunnelDataMsg (std::shared_ptr msg); + void EncryptTunnelMsg (std::shared_ptr tunnelMsg); uint32_t GetNextTunnelID () const { return m_Config->GetFirstHop ()->tunnelID; }; const i2p::data::IdentHash& GetNextIdentHash () const { return m_Config->GetFirstHop ()->router->GetIdentHash (); }; @@ -90,7 +90,7 @@ namespace tunnel size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); }; // implements TunnelBase - void HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); uint32_t GetTunnelID () const { return GetNextTunnelID (); }; private: @@ -104,7 +104,7 @@ namespace tunnel public: InboundTunnel (std::shared_ptr config): Tunnel (config), m_Endpoint (true) {}; - void HandleTunnelDataMsg (I2NPMessage * msg); + void HandleTunnelDataMsg (std::shared_ptr msg); size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); }; // implements TunnelBase @@ -135,8 +135,8 @@ namespace tunnel void AddTransitTunnel (TransitTunnel * tunnel); void AddOutboundTunnel (std::shared_ptr newTunnel); void AddInboundTunnel (std::shared_ptr newTunnel); - void PostTunnelData (I2NPMessage * msg); - void PostTunnelData (const std::vector& msgs); + void PostTunnelData (std::shared_ptr msg); + void PostTunnelData (const std::vector >& msgs); template std::shared_ptr CreateTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel = nullptr); void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel); @@ -150,7 +150,7 @@ namespace tunnel template std::shared_ptr GetPendingTunnel (uint32_t replyMsgID, const std::map >& pendingTunnels); - void HandleTunnelGatewayMsg (TunnelBase * tunnel, I2NPMessage * msg); + void HandleTunnelGatewayMsg (TunnelBase * tunnel, std::shared_ptr msg); void Run (); void ManageTunnels (); @@ -177,7 +177,7 @@ namespace tunnel std::mutex m_PoolsMutex; std::list> m_Pools; std::shared_ptr m_ExploratoryPool; - i2p::util::Queue m_Queue; + i2p::util::Queue > m_Queue; // some stats int m_NumSuccesiveTunnelCreations, m_NumFailedTunnelCreations; diff --git a/TunnelBase.h b/TunnelBase.h index d867bf9a..5470f139 100644 --- a/TunnelBase.h +++ b/TunnelBase.h @@ -26,7 +26,7 @@ namespace tunnel TunnelDeliveryType deliveryType; i2p::data::IdentHash hash; uint32_t tunnelID; - I2NPMessage * data; + std::shared_ptr data; }; class TunnelBase @@ -37,10 +37,10 @@ namespace tunnel TunnelBase (): m_CreationTime (i2p::util::GetSecondsSinceEpoch ()) {}; virtual ~TunnelBase () {}; - virtual void HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg) = 0; - virtual void SendTunnelDataMsg (i2p::I2NPMessage * msg) = 0; + virtual void HandleTunnelDataMsg (std::shared_ptr tunnelMsg) = 0; + virtual void SendTunnelDataMsg (std::shared_ptr msg) = 0; virtual void FlushTunnelDataMsgs () {}; - virtual void EncryptTunnelMsg (I2NPMessage * tunnelMsg) = 0; + virtual void EncryptTunnelMsg (std::shared_ptr tunnelMsg) = 0; virtual uint32_t GetNextTunnelID () const = 0; virtual const i2p::data::IdentHash& GetNextIdentHash () const = 0; virtual uint32_t GetTunnelID () const = 0; // as known at our side diff --git a/TunnelEndpoint.cpp b/TunnelEndpoint.cpp index db7ed7a6..e493e168 100644 --- a/TunnelEndpoint.cpp +++ b/TunnelEndpoint.cpp @@ -13,13 +13,9 @@ namespace tunnel { TunnelEndpoint::~TunnelEndpoint () { - for (auto it: m_IncompleteMessages) - i2p::DeleteI2NPMessage (it.second.data); - for (auto it: m_OutOfSequenceFragments) - i2p::DeleteI2NPMessage (it.second.data); } - void TunnelEndpoint::HandleDecryptedTunnelDataMsg (I2NPMessage * msg) + void TunnelEndpoint::HandleDecryptedTunnelDataMsg (std::shared_ptr msg) { m_NumReceivedBytes += TUNNEL_DATA_MSG_SIZE; @@ -35,7 +31,6 @@ namespace tunnel if (memcmp (hash, decrypted, 4)) { LogPrint (eLogError, "TunnelMessage: checksum verification failed"); - i2p::DeleteI2NPMessage (msg); return; } // process fragments @@ -97,7 +92,7 @@ namespace tunnel if (fragment + size < decrypted + TUNNEL_DATA_ENCRYPTED_SIZE) { // this is not last message. we have to copy it - m.data = NewI2NPShortMessage (); + m.data = ToSharedI2NPMessage (NewI2NPShortMessage ()); m.data->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header m.data->len += TUNNEL_GATEWAY_HEADER_SIZE; *(m.data) = *msg; @@ -118,10 +113,7 @@ namespace tunnel if (ret.second) HandleOutOfSequenceFragment (msgID, ret.first->second); else - { LogPrint (eLogError, "Incomplete message ", msgID, "already exists"); - DeleteI2NPMessage (m.data); - } } else { @@ -130,20 +122,14 @@ namespace tunnel } } else - { LogPrint (eLogError, "Message is fragmented, but msgID is not presented"); - DeleteI2NPMessage (m.data); - } } fragment += size; } } else - { LogPrint (eLogError, "TunnelMessage: zero not found"); - i2p::DeleteI2NPMessage (msg); - } } void TunnelEndpoint::HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, const TunnelMessageBlockEx& m) @@ -161,9 +147,8 @@ namespace tunnel if (msg.data->len + size > msg.data->maxLen) { LogPrint (eLogInfo, "Tunnel endpoint I2NP message size ", msg.data->maxLen, " is not enough"); - I2NPMessage * newMsg = NewI2NPMessage (); + auto newMsg = ToSharedI2NPMessage (NewI2NPMessage ()); *newMsg = *(msg.data); - DeleteI2NPMessage (msg.data); msg.data = newMsg; } memcpy (msg.data->buf + msg.data->len, fragment, size); // concatenate fragment @@ -183,10 +168,8 @@ namespace tunnel else { LogPrint (eLogError, "Fragment ", m.nextFragmentNum, " of message ", msgID, "exceeds max I2NP message size. Message dropped"); - i2p::DeleteI2NPMessage (msg.data); m_IncompleteMessages.erase (it); } - i2p::DeleteI2NPMessage (m.data); } else { @@ -201,13 +184,11 @@ namespace tunnel } } - void TunnelEndpoint::AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, I2NPMessage * data) + void TunnelEndpoint::AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr data) { auto it = m_OutOfSequenceFragments.find (msgID); if (it == m_OutOfSequenceFragments.end ()) m_OutOfSequenceFragments.insert (std::pair (msgID, {fragmentNum, isLastFragment, data})); - else - i2p::DeleteI2NPMessage (data); } void TunnelEndpoint::HandleOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg) @@ -222,9 +203,8 @@ namespace tunnel if (msg.data->len + size > msg.data->maxLen) { LogPrint (eLogInfo, "Tunnel endpoint I2NP message size ", msg.data->maxLen, " is not enough"); - I2NPMessage * newMsg = NewI2NPMessage (); + auto newMsg = ToSharedI2NPMessage (NewI2NPMessage ()); *newMsg = *(msg.data); - DeleteI2NPMessage (msg.data); msg.data = newMsg; } memcpy (msg.data->buf + msg.data->len, it->second.data->GetBuffer (), size); // concatenate out-of-sync fragment @@ -237,7 +217,6 @@ namespace tunnel } else msg.nextFragmentNum++; - i2p::DeleteI2NPMessage (it->second.data); m_OutOfSequenceFragments.erase (it); } } @@ -273,17 +252,11 @@ namespace tunnel i2p::transport::transports.SendMessage (msg.hash, msg.data); } else // we shouldn't send this message. possible leakage - { LogPrint (eLogError, "Message to another router arrived from an inbound tunnel. Dropped"); - i2p::DeleteI2NPMessage (msg.data); - } } break; default: - { LogPrint (eLogError, "TunnelMessage: Unknown delivery type ", (int)msg.deliveryType); - i2p::DeleteI2NPMessage (msg.data); - } }; } } diff --git a/TunnelEndpoint.h b/TunnelEndpoint.h index 61d0a9ab..20b9105f 100644 --- a/TunnelEndpoint.h +++ b/TunnelEndpoint.h @@ -22,7 +22,7 @@ namespace tunnel { uint8_t fragmentNum; bool isLastFragment; - I2NPMessage * data; + std::shared_ptr data; }; public: @@ -31,14 +31,14 @@ namespace tunnel ~TunnelEndpoint (); size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; }; - void HandleDecryptedTunnelDataMsg (I2NPMessage * msg); + void HandleDecryptedTunnelDataMsg (std::shared_ptr msg); private: void HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, const TunnelMessageBlockEx& m); void HandleNextMessage (const TunnelMessageBlock& msg); - void AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, I2NPMessage * data); + void AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr data); void HandleOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg); private: diff --git a/TunnelGateway.cpp b/TunnelGateway.cpp index 33935259..2763ae17 100644 --- a/TunnelGateway.cpp +++ b/TunnelGateway.cpp @@ -40,7 +40,7 @@ namespace tunnel di[0] = block.deliveryType << 5; // set delivery type // create fragments - I2NPMessage * msg = block.data; + std::shared_ptr msg = block.data; auto fullMsgLen = diLen + msg->GetLength () + 2; // delivery instructions + payload + 2 bytes length if (fullMsgLen <= m_RemainingSize) { @@ -53,7 +53,6 @@ namespace tunnel m_RemainingSize -= diLen + msg->GetLength (); if (!m_RemainingSize) CompleteCurrentTunnelDataMessage (); - DeleteI2NPMessage (msg); } else { @@ -117,7 +116,6 @@ namespace tunnel size += s; fragmentNumber++; } - DeleteI2NPMessage (msg); } else { @@ -190,7 +188,7 @@ namespace tunnel auto tunnelMsgs = m_Buffer.GetTunnelDataMsgs (); for (auto tunnelMsg : tunnelMsgs) { - m_Tunnel->EncryptTunnelMsg (tunnelMsg.get ()); // TODO: + m_Tunnel->EncryptTunnelMsg (tunnelMsg); FillI2NPMessageHeader (tunnelMsg.get (), eI2NPTunnelData); // TODO: m_NumSentBytes += TUNNEL_DATA_MSG_SIZE; } From 38ebe28923f77cd3d8a21669b14873756f0f0f4a Mon Sep 17 00:00:00 2001 From: Mikhail Titov Date: Mon, 15 Jun 2015 16:55:21 -0500 Subject: [PATCH 40/67] Rearrange eol removal for handshake --- SAM.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SAM.cpp b/SAM.cpp index 7de1a8a8..cb2cac3e 100644 --- a/SAM.cpp +++ b/SAM.cpp @@ -85,6 +85,9 @@ namespace client else { m_Buffer[bytes_transferred] = 0; + char * eol = (char *)memchr (m_Buffer, '\n', bytes_transferred); + if (eol) + *eol = 0; LogPrint ("SAM handshake ", m_Buffer); char * separator = strchr (m_Buffer, ' '); if (separator) @@ -101,9 +104,6 @@ namespace client if (separator) { separator++; - char *eol = strchr (separator, '\n'); - if (eol) - *eol = 0; std::map params; ExtractParams (separator, params); auto it = params.find (SAM_PARAM_MAX); From 490b65dfe233fe298df05b75294abeb1f7bc00a3 Mon Sep 17 00:00:00 2001 From: Mikhail Titov Date: Fri, 19 Jun 2015 14:44:50 -0500 Subject: [PATCH 41/67] Materialize temporary string obtained from boost path --- DaemonLinux.cpp | 3 ++- NetDb.cpp | 42 +++++++++++++----------------------------- NetDb.h | 4 ++-- RouterInfo.cpp | 9 ++++++--- 4 files changed, 23 insertions(+), 35 deletions(-) diff --git a/DaemonLinux.cpp b/DaemonLinux.cpp index 48a05031..5824430e 100644 --- a/DaemonLinux.cpp +++ b/DaemonLinux.cpp @@ -62,7 +62,8 @@ namespace i2p LogPrint("Error, could not create process group."); return false; } - chdir(i2p::util::filesystem::GetDataDir().string().c_str()); + std::string d(i2p::util::filesystem::GetDataDir()); // make a copy + chdir(d.c_str()); // close stdin/stdout/stderr descriptors ::close (0); diff --git a/NetDb.cpp b/NetDb.cpp index e97f6985..b802f3dd 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -21,11 +21,7 @@ namespace i2p { namespace data { -#ifndef _WIN32 - const char NetDb::m_NetDbPath[] = "/netDb"; -#else - const char NetDb::m_NetDbPath[] = "\\netDb"; -#endif + const char NetDb::m_NetDbPath[] = "netDb"; NetDb netdb; NetDb::NetDb (): m_IsRunning (false), m_Thread (nullptr), m_Reseeder (nullptr) @@ -40,7 +36,7 @@ namespace data void NetDb::Start () { - Load (m_NetDbPath); + Load (); if (m_RouterInfos.size () < 25) // reseed if # of router less than 50 { // try SU3 first @@ -55,7 +51,7 @@ namespace data { m_Reseeder->reseedNow(); reseedRetries++; - Load (m_NetDbPath); + Load (); } } } @@ -133,7 +129,7 @@ namespace data { if (lastSave) { - SaveUpdated (m_NetDbPath); + SaveUpdated (); ManageLeaseSets (); } lastSave = ts; @@ -295,10 +291,9 @@ namespace data LogPrint (eLogWarning, "Failed to reseed after 10 attempts"); } - void NetDb::Load (const char * directory) + void NetDb::Load () { - boost::filesystem::path p (i2p::util::filesystem::GetDataDir()); - p /= (directory); + boost::filesystem::path p(i2p::util::filesystem::GetDataDir() / m_NetDbPath); if (!boost::filesystem::exists (p)) { // seems netDb doesn't exist yet @@ -345,27 +340,15 @@ namespace data LogPrint (m_Floodfills.size (), " floodfills loaded"); } - void NetDb::SaveUpdated (const char * directory) + void NetDb::SaveUpdated () { - auto GetFilePath = [](const char * directory, const RouterInfo * routerInfo) + auto GetFilePath = [](const boost::filesystem::path& directory, const RouterInfo * routerInfo) { -#ifndef _WIN32 - return std::string (directory) + "/r" + - routerInfo->GetIdentHashBase64 ()[0] + "/routerInfo-" + -#else - return std::string (directory) + "\\r" + - routerInfo->GetIdentHashBase64 ()[0] + "\\routerInfo-" + -#endif - routerInfo->GetIdentHashBase64 () + ".dat"; + std::string s(routerInfo->GetIdentHashBase64()); + return directory / (std::string("r") + s[0]) / ("routerInfo-" + s + ".dat"); }; - boost::filesystem::path p (i2p::util::filesystem::GetDataDir()); - p /= (directory); -#if BOOST_VERSION > 10500 - const char * fullDirectory = p.string().c_str (); -#else - const char * fullDirectory = p.c_str (); -#endif + boost::filesystem::path fullDirectory (i2p::util::filesystem::GetDataDir() / m_NetDbPath); int count = 0, deletedCount = 0; auto total = m_RouterInfos.size (); uint64_t ts = i2p::util::GetMillisecondsSinceEpoch (); @@ -373,7 +356,8 @@ namespace data { if (it.second->IsUpdated ()) { - it.second->SaveToFile (GetFilePath(fullDirectory, it.second.get ())); + std::string f = GetFilePath(fullDirectory, it.second.get()).string(); + it.second->SaveToFile (f); it.second->SetUpdated (false); it.second->SetUnreachable (false); it.second->DeleteBuffer (); diff --git a/NetDb.h b/NetDb.h index 5028819e..adeee675 100644 --- a/NetDb.h +++ b/NetDb.h @@ -68,8 +68,8 @@ namespace data private: bool CreateNetDb(boost::filesystem::path directory); - void Load (const char * directory); - void SaveUpdated (const char * directory); + void Load (); + void SaveUpdated (); void Run (); // exploratory thread void Explore (int numDestinations); void Publish (); diff --git a/RouterInfo.cpp b/RouterInfo.cpp index 7bc0161e..403b711c 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -447,10 +447,13 @@ namespace data if (m_Buffer) { std::ofstream f (fullPath, std::ofstream::binary | std::ofstream::out); - f.write ((char *)m_Buffer, m_BufferLen); - } + if (f.is_open ()) + f.write ((char *)m_Buffer, m_BufferLen); + else + LogPrint(eLogError, "Can't save RouterInfo to ", fullPath); + } else - LogPrint (eLogError, "Can't save to file"); + LogPrint (eLogError, "Can't save RouterInfo m_Buffer==NULL"); } size_t RouterInfo::ReadString (char * str, std::istream& s) From 2738169a9d5c644c9cc63449ffdd55da5ca1fb68 Mon Sep 17 00:00:00 2001 From: Mikhail Titov Date: Mon, 15 Jun 2015 16:57:02 -0500 Subject: [PATCH 42/67] Use static for now while returning HTTP 500 error --- HTTPProxy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index a575cc41..8e0ef9ad 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -90,7 +90,7 @@ namespace proxy //TODO: handle this apropriately void HTTPProxyHandler::HTTPRequestFailed(/*HTTPProxyHandler::errTypes error*/) { - std::string response = "HTTP/1.0 500 Internal Server Error\r\nContent-type: text/html\r\nContent-length: 0\r\n"; + static std::string response = "HTTP/1.0 500 Internal Server Error\r\nContent-type: text/html\r\nContent-length: 0\r\n"; boost::asio::async_write(*m_sock, boost::asio::buffer(response,response.size()), std::bind(&HTTPProxyHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); } From 4fab07b4da3b06c6b5545f4561cc009659ec63fa Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 19 Jun 2015 16:06:14 -0400 Subject: [PATCH 43/67] fixed build error --- DaemonLinux.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DaemonLinux.cpp b/DaemonLinux.cpp index 5824430e..ac7a3402 100644 --- a/DaemonLinux.cpp +++ b/DaemonLinux.cpp @@ -62,7 +62,7 @@ namespace i2p LogPrint("Error, could not create process group."); return false; } - std::string d(i2p::util::filesystem::GetDataDir()); // make a copy + std::string d(i2p::util::filesystem::GetDataDir().string ()); // make a copy chdir(d.c_str()); // close stdin/stdout/stderr descriptors From 60e2722a21114182e04670c7c1227c3be88e4691 Mon Sep 17 00:00:00 2001 From: Mikhail Titov Date: Sat, 20 Jun 2015 00:49:24 -0500 Subject: [PATCH 44/67] fixup! Fix UPnP for Win32 --- UPnP.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UPnP.cpp b/UPnP.cpp index 21f7e76d..6773b514 100644 --- a/UPnP.cpp +++ b/UPnP.cpp @@ -42,8 +42,8 @@ void (*freeUPNPDevlistFunc) (struct UPNPDev *); void (*FreeUPNPUrlsFunc) (struct UPNPUrls *); // Nice approach http://stackoverflow.com/a/21517513/673826 -template -F GetKnownProcAddressImpl(HMODULE hmod, const char *name, F) { +template +F GetKnownProcAddressImpl(M hmod, const char *name, F) { auto proc = reinterpret_cast(dlsym(hmod, name)); if (!proc) { LogPrint("Error resolving ", name, " from UPNP library. This often happens if there is version mismatch!"); From efe7e469cef95e77d6d239373f78cf72bd2d5b35 Mon Sep 17 00:00:00 2001 From: Mikhail Titov Date: Sat, 20 Jun 2015 11:48:48 -0500 Subject: [PATCH 45/67] Missing libdl for UPnP --- build/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 254574fe..ed8a281f 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -70,6 +70,9 @@ set (DAEMON_SRC if (WITH_UPNP) add_definitions(-DUSE_UPNP) + if (NOT MSVC) + set(DL_LIB ${CMAKE_DL_LIBS}) + endif () endif () set (LIBRARY_SRC @@ -268,7 +271,7 @@ if (WITH_BINARY) if(${LAST_Boost_LIBRARIES} MATCHES ".*pthread.*") list(REMOVE_AT Boost_LIBRARIES -1) endif() - target_link_libraries( "${PROJECT_NAME}-bin" common ${Boost_LIBRARIES} ${CRYPTO++_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) + target_link_libraries( "${PROJECT_NAME}-bin" common ${DL_LIB} ${Boost_LIBRARIES} ${CRYPTO++_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) install(TARGETS "${PROJECT_NAME}-bin" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) if (MSVC) From 9c9401ce2f0e3bd8158c1879988805dc2a79b51a Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 21 Jun 2015 15:08:22 -0400 Subject: [PATCH 46/67] use shared_ptr for all incoming I2NP messages --- I2NPProtocol.cpp | 8 ++++---- I2NPProtocol.h | 2 +- NTCPSession.cpp | 12 +++--------- NTCPSession.h | 2 +- SSUData.cpp | 9 ++------- SSUData.h | 5 ++--- 6 files changed, 13 insertions(+), 25 deletions(-) diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index e4685c7e..c0806d53 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -582,20 +582,20 @@ namespace i2p Flush (); } - void I2NPMessagesHandler::PutNextMessage (I2NPMessage * msg) + void I2NPMessagesHandler::PutNextMessage (std::shared_ptr msg) { if (msg) { switch (msg->GetTypeID ()) { case eI2NPTunnelData: - m_TunnelMsgs.push_back (ToSharedI2NPMessage (msg)); + m_TunnelMsgs.push_back (msg); break; case eI2NPTunnelGateway: - m_TunnelGatewayMsgs.push_back (ToSharedI2NPMessage (msg)); + m_TunnelGatewayMsgs.push_back (msg); break; default: - HandleI2NPMessage (ToSharedI2NPMessage (msg)); + HandleI2NPMessage (msg); } } } diff --git a/I2NPProtocol.h b/I2NPProtocol.h index cee97bec..4e8a8f8d 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -236,7 +236,7 @@ namespace tunnel public: ~I2NPMessagesHandler (); - void PutNextMessage (I2NPMessage * msg); + void PutNextMessage (std::shared_ptr msg); void Flush (); private: diff --git a/NTCPSession.cpp b/NTCPSession.cpp index b7596997..4b622c73 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -84,11 +84,7 @@ namespace transport transports.PeerDisconnected (shared_from_this ()); m_Server.RemoveNTCPSession (shared_from_this ()); m_SendQueue.clear (); - if (m_NextMessage) - { - i2p::DeleteI2NPMessage (m_NextMessage); - m_NextMessage = nullptr; - } + m_NextMessage = nullptr; m_TerminationTimer.cancel (); LogPrint (eLogInfo, "NTCP session terminated"); } @@ -564,7 +560,8 @@ namespace transport LogPrint (eLogError, "NTCP data size ", dataSize, " exceeds max size"); return false; } - m_NextMessage = dataSize <= I2NP_MAX_SHORT_MESSAGE_SIZE - 2 ? NewI2NPShortMessage () : NewI2NPMessage (); + auto msg = dataSize <= I2NP_MAX_SHORT_MESSAGE_SIZE - 2 ? NewI2NPShortMessage () : NewI2NPMessage (); + m_NextMessage = ToSharedI2NPMessage (msg); memcpy (m_NextMessage->buf, buf, 16); m_NextMessageOffset = 16; m_NextMessage->offset = 2; // size field @@ -589,10 +586,7 @@ namespace transport if (CryptoPP::Adler32().VerifyDigest (m_NextMessage->buf + m_NextMessageOffset - 4, m_NextMessage->buf, m_NextMessageOffset - 4)) m_Handler.PutNextMessage (m_NextMessage); else - { LogPrint (eLogWarning, "Incorrect adler checksum of NTCP message. Dropped"); - DeleteI2NPMessage (m_NextMessage); - } m_NextMessage = nullptr; } return true; diff --git a/NTCPSession.h b/NTCPSession.h index b09713e4..96644eea 100644 --- a/NTCPSession.h +++ b/NTCPSession.h @@ -126,7 +126,7 @@ namespace transport i2p::crypto::AESAlignedBuffer<16> m_TimeSyncBuffer; int m_ReceiveBufferOffset; - i2p::I2NPMessage * m_NextMessage; + std::shared_ptr m_NextMessage; size_t m_NextMessageOffset; i2p::I2NPMessagesHandler m_Handler; diff --git a/SSUData.cpp b/SSUData.cpp index 83b82aab..5c0c03dd 100644 --- a/SSUData.cpp +++ b/SSUData.cpp @@ -15,9 +15,8 @@ namespace transport if (msg->len + fragmentSize > msg->maxLen) { LogPrint (eLogInfo, "SSU I2NP message size ", msg->maxLen, " is not enough"); - I2NPMessage * newMsg = NewI2NPMessage (); + auto newMsg = ToSharedI2NPMessage(NewI2NPMessage ()); *newMsg = *msg; - DeleteI2NPMessage (msg); msg = newMsg; } memcpy (msg->buf + msg->len, fragment, fragmentSize); @@ -174,7 +173,7 @@ namespace transport if (it == m_IncompleteMessages.end ()) { // create new message - auto msg = NewI2NPShortMessage (); + auto msg = ToSharedI2NPMessage (NewI2NPShortMessage ()); msg->len -= I2NP_SHORT_HEADER_SIZE; it = m_IncompleteMessages.insert (std::make_pair (msgID, std::unique_ptr(new IncompleteMessage (msg)))).first; @@ -244,10 +243,7 @@ namespace transport m_Handler.PutNextMessage (msg); } else - { LogPrint (eLogWarning, "SSU message ", msgID, " already received"); - i2p::DeleteI2NPMessage (msg); - } } else { @@ -259,7 +255,6 @@ namespace transport } else LogPrint (eLogError, "SSU unexpected message ", (int)msg->GetTypeID ()); - DeleteI2NPMessage (msg); } } else diff --git a/SSUData.h b/SSUData.h index 39d14cc4..60d5057e 100644 --- a/SSUData.h +++ b/SSUData.h @@ -59,13 +59,12 @@ namespace transport struct IncompleteMessage { - I2NPMessage * msg; + std::shared_ptr msg; int nextFragmentNum; uint32_t lastFragmentInsertTime; // in seconds std::set, FragmentCmp> savedFragments; - IncompleteMessage (I2NPMessage * m): msg (m), nextFragmentNum (0), lastFragmentInsertTime (0) {}; - ~IncompleteMessage () { if (msg) DeleteI2NPMessage (msg); }; + IncompleteMessage (std::shared_ptr m): msg (m), nextFragmentNum (0), lastFragmentInsertTime (0) {}; void AttachNextFragment (const uint8_t * fragment, size_t fragmentSize); }; From 1fc50a59f54f7cb649376eb97230fc990a257e48 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 21 Jun 2015 17:05:01 -0400 Subject: [PATCH 47/67] different in and out buffers for tunnel encryption --- TransitTunnel.cpp | 2 +- Tunnel.cpp | 2 +- aes.cpp | 46 ++++++++++++++++++++++++---------------------- aes.h | 4 ++-- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/TransitTunnel.cpp b/TransitTunnel.cpp index aa4636d6..6fc6c5c0 100644 --- a/TransitTunnel.cpp +++ b/TransitTunnel.cpp @@ -22,7 +22,7 @@ namespace tunnel void TransitTunnel::EncryptTunnelMsg (std::shared_ptr tunnelMsg) { - m_Encryption.Encrypt (tunnelMsg->GetPayload () + 4); + m_Encryption.Encrypt (tunnelMsg->GetPayload () + 4, tunnelMsg->GetPayload () + 4); } TransitTunnelParticipant::~TransitTunnelParticipant () diff --git a/Tunnel.cpp b/Tunnel.cpp index 5341da32..de95ad68 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -146,7 +146,7 @@ namespace tunnel TunnelHopConfig * hop = m_Config->GetLastHop (); while (hop) { - hop->decryption.Decrypt (payload); + hop->decryption.Decrypt (payload, payload); hop = hop->prev; } } diff --git a/aes.cpp b/aes.cpp index 8d270521..506e7ca8 100644 --- a/aes.cpp +++ b/aes.cpp @@ -280,74 +280,76 @@ namespace crypto #endif } - void TunnelEncryption::Encrypt (uint8_t * payload) + void TunnelEncryption::Encrypt (const uint8_t * in, uint8_t * out) { #ifdef AESNI __asm__ ( // encrypt IV - "movups (%[payload]), %%xmm0 \n" + "movups (%[in]), %%xmm0 \n" EncryptAES256(sched_iv) "movaps %%xmm0, %%xmm1 \n" // double IV encryption EncryptAES256(sched_iv) - "movups %%xmm0, (%[payload]) \n" + "movups %%xmm0, (%[out]) \n" // encrypt data, IV is xmm1 "1: \n" - "add $16, %[payload] \n" - "movups (%[payload]), %%xmm0 \n" + "add $16, %[in] \n" + "add $16, %[out] \n" + "movups (%[in]), %%xmm0 \n" "pxor %%xmm1, %%xmm0 \n" EncryptAES256(sched_l) "movaps %%xmm0, %%xmm1 \n" - "movups %%xmm0, (%[payload]) \n" + "movups %%xmm0, (%[out]) \n" "dec %[num] \n" "jnz 1b \n" : : [sched_iv]"r"(m_IVEncryption.GetKeySchedule ()), [sched_l]"r"(m_LayerEncryption.GetKeySchedule ()), - [payload]"r"(payload), [num]"r"(63) // 63 blocks = 1008 bytes + [in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes : "%xmm0", "%xmm1", "cc", "memory" ); #else - m_IVEncryption.Encrypt ((ChipherBlock *)payload, (ChipherBlock *)payload); // iv - m_LayerEncryption.SetIV (payload); - m_LayerEncryption.Encrypt (payload + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, payload + 16); // data - m_IVEncryption.Encrypt ((ChipherBlock *)payload, (ChipherBlock *)payload); // double iv + m_IVEncryption.Encrypt ((const ChipherBlock *)in, (ChipherBlock *)out); // iv + m_LayerEncryption.SetIV (out); + m_LayerEncryption.Encrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data + m_IVEncryption.Encrypt ((ChipherBlock *)out, (ChipherBlock *)out); // double iv #endif } - void TunnelDecryption::Decrypt (uint8_t * payload) + void TunnelDecryption::Decrypt (const uint8_t * in, uint8_t * out) { #ifdef AESNI __asm__ ( // decrypt IV - "movups (%[payload]), %%xmm0 \n" + "movups (%[in]), %%xmm0 \n" DecryptAES256(sched_iv) "movaps %%xmm0, %%xmm1 \n" // double IV encryption DecryptAES256(sched_iv) - "movups %%xmm0, (%[payload]) \n" + "movups %%xmm0, (%[out]) \n" // decrypt data, IV is xmm1 "1: \n" - "add $16, %[payload] \n" - "movups (%[payload]), %%xmm0 \n" + "add $16, %[in] \n" + "add $16, %[out] \n" + "movups (%[in]), %%xmm0 \n" "movaps %%xmm0, %%xmm2 \n" DecryptAES256(sched_l) "pxor %%xmm1, %%xmm0 \n" - "movups %%xmm0, (%[payload]) \n" + "movups %%xmm0, (%[out]) \n" "movaps %%xmm2, %%xmm1 \n" "dec %[num] \n" "jnz 1b \n" : : [sched_iv]"r"(m_IVDecryption.GetKeySchedule ()), [sched_l]"r"(m_LayerDecryption.GetKeySchedule ()), - [payload]"r"(payload), [num]"r"(63) // 63 blocks = 1008 bytes + [in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes : "%xmm0", "%xmm1", "%xmm2", "cc", "memory" ); #else - m_IVDecryption.Decrypt ((ChipherBlock *)payload, (ChipherBlock *)payload); // iv - m_LayerDecryption.SetIV (payload); - m_LayerDecryption.Decrypt (payload + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, payload + 16); // data - m_IVDecryption.Decrypt ((ChipherBlock *)payload, (ChipherBlock *)payload); // double iv + m_IVDecryption.Decrypt ((const ChipherBlock *)in, (ChipherBlock *)out); // iv + m_LayerDecryption.SetIV (out); + m_LayerDecryption.Decrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data + m_IVDecryption.Decrypt ((ChipherBlock *)out, (ChipherBlock *)out); // double iv #endif } } diff --git a/aes.h b/aes.h index 95180fd6..84ca1f17 100644 --- a/aes.h +++ b/aes.h @@ -185,7 +185,7 @@ namespace crypto m_IVEncryption.SetKey (ivKey); } - void Encrypt (uint8_t * payload); // 1024 bytes (16 IV + 1008 data) + void Encrypt (const uint8_t * in, uint8_t * out); // 1024 bytes (16 IV + 1008 data) private: @@ -207,7 +207,7 @@ namespace crypto m_IVDecryption.SetKey (ivKey); } - void Decrypt (uint8_t * payload); // 1024 bytes (16 IV + 1008 data) + void Decrypt (const uint8_t * in, uint8_t * out); // 1024 bytes (16 IV + 1008 data) private: From 2cbd6e85c664bc36532a921b009b5534acf7fc81 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 21 Jun 2015 22:29:50 -0400 Subject: [PATCH 48/67] use shared_ptr for garlic messages --- Datagram.cpp | 4 ++-- Destination.cpp | 10 +++++----- Garlic.cpp | 19 ++++++++----------- Garlic.h | 6 +++--- NetDb.cpp | 14 +++++++------- NetDbRequests.cpp | 2 +- Streaming.cpp | 8 ++++---- Streaming.h | 2 +- Tunnel.cpp | 6 +++--- Tunnel.h | 2 +- TunnelPool.cpp | 2 +- 11 files changed, 36 insertions(+), 39 deletions(-) diff --git a/Datagram.cpp b/Datagram.cpp index 9179fb80..32499232 100644 --- a/Datagram.cpp +++ b/Datagram.cpp @@ -60,12 +60,12 @@ namespace datagram { std::vector msgs; uint32_t i = i2p::context.GetRandomNumberGenerator ().GenerateWord32 (0, leases.size () - 1); - auto garlic = m_Owner.WrapMessage (remote, msg, true); + auto garlic = m_Owner.WrapMessage (remote, ToSharedI2NPMessage (msg), true); msgs.push_back (i2p::tunnel::TunnelMessageBlock { i2p::tunnel::eDeliveryTypeTunnel, leases[i].tunnelGateway, leases[i].tunnelID, - ToSharedI2NPMessage (garlic) + garlic }); outboundTunnel->SendTunnelDataMsg (msgs); } diff --git a/Destination.cpp b/Destination.cpp index 107bcf0a..d98de3f7 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -393,7 +393,7 @@ namespace client m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); LogPrint (eLogDebug, "Publish LeaseSet of ", GetIdentHash ().ToBase32 ()); m_PublishReplyToken = i2p::context.GetRandomNumberGenerator ().GenerateWord32 (); - auto msg = WrapMessage (floodfill, i2p::CreateDatabaseStoreMsg (m_LeaseSet, m_PublishReplyToken)); + auto msg = WrapMessage (floodfill, ToSharedI2NPMessage (i2p::CreateDatabaseStoreMsg (m_LeaseSet, m_PublishReplyToken))); m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT)); m_PublishConfirmationTimer.async_wait (std::bind (&ClientDestination::HandlePublishConfirmationTimer, this, std::placeholders::_1)); @@ -581,15 +581,15 @@ namespace client rnd.GenerateBlock (replyTag, 32); // random session tag AddSessionKey (replyKey, replyTag); - I2NPMessage * msg = WrapMessage (nextFloodfill, - CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, - replyTunnel.get (), replyKey, replyTag)); + auto msg = WrapMessage (nextFloodfill, + ToSharedI2NPMessage (CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, + replyTunnel.get (), replyKey, replyTag))); outboundTunnel->SendTunnelDataMsg ( { i2p::tunnel::TunnelMessageBlock { i2p::tunnel::eDeliveryTypeRouter, - nextFloodfill->GetIdentHash (), 0, ToSharedI2NPMessage (msg) + nextFloodfill->GetIdentHash (), 0, msg } }); request->requestTimeoutTimer.expires_from_now (boost::posix_time::seconds(LEASESET_REQUEST_TIMEOUT)); diff --git a/Garlic.cpp b/Garlic.cpp index 8bdfb10c..4b89b147 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -107,9 +107,9 @@ namespace garlic return !m_SessionTags.empty () || m_UnconfirmedTagsMsgs.empty (); } - I2NPMessage * GarlicRoutingSession::WrapSingleMessage (I2NPMessage * msg) + std::shared_ptr GarlicRoutingSession::WrapSingleMessage (std::shared_ptr msg) { - I2NPMessage * m = NewI2NPMessage (); + auto m = ToSharedI2NPMessage(NewI2NPMessage ()); m->Align (12); // in order to get buf aligned to 16 (12 + 4) size_t len = 0; uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length @@ -164,12 +164,10 @@ namespace garlic len += 32; } // AES block - len += CreateAESBlock (buf, msg); + len += CreateAESBlock (buf, msg.get ()); // TODO htobe32buf (m->GetPayload (), len); m->len += len + 4; - FillI2NPMessageHeader (m, eI2NPGarlic); - if (msg) - DeleteI2NPMessage (msg); + FillI2NPMessageHeader (m.get (), eI2NPGarlic); // TODO return m; } @@ -309,7 +307,7 @@ namespace garlic htobe32buf (buf + size, inboundTunnel->GetNextTunnelID ()); // tunnelID size += 4; // create msg - I2NPMessage * msg = CreateDeliveryStatusMsg (msgID); + auto msg = ToSharedI2NPMessage (CreateDeliveryStatusMsg (msgID)); if (m_Owner) { //encrypt @@ -322,7 +320,6 @@ namespace garlic } memcpy (buf + size, msg->GetBuffer (), msg->GetLength ()); size += msg->GetLength (); - DeleteI2NPMessage (msg); // fill clove uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec htobe32buf (buf + size, m_Rnd.GenerateWord32 ()); // CloveID @@ -512,7 +509,7 @@ namespace garlic if (tunnel) // we have send it through an outbound tunnel { I2NPMessage * msg = CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from); - tunnel->SendTunnelDataMsg (gwHash, gwTunnel, msg); + tunnel->SendTunnelDataMsg (gwHash, gwTunnel, ToSharedI2NPMessage (msg)); } else LogPrint ("No outbound tunnels available for garlic clove"); @@ -537,8 +534,8 @@ namespace garlic } } - I2NPMessage * GarlicDestination::WrapMessage (std::shared_ptr destination, - I2NPMessage * msg, bool attachLeaseSet) + std::shared_ptr GarlicDestination::WrapMessage (std::shared_ptr destination, + std::shared_ptr msg, bool attachLeaseSet) { auto session = GetRoutingSession (destination, attachLeaseSet); // 32 tags by default return session->WrapSingleMessage (msg); diff --git a/Garlic.h b/Garlic.h index d5330735..580cabec 100644 --- a/Garlic.h +++ b/Garlic.h @@ -80,7 +80,7 @@ namespace garlic int numTags, bool attachLeaseSet); GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag); // one time encryption ~GarlicRoutingSession (); - I2NPMessage * WrapSingleMessage (I2NPMessage * msg); + std::shared_ptr WrapSingleMessage (std::shared_ptr msg); void MessageConfirmed (uint32_t msgID); bool CleanupExpiredTags (); // returns true if something left @@ -126,8 +126,8 @@ namespace garlic std::shared_ptr GetRoutingSession (std::shared_ptr destination, bool attachLeaseSet); void CleanupRoutingSessions (); void RemoveCreatedSession (uint32_t msgID); - I2NPMessage * WrapMessage (std::shared_ptr destination, - I2NPMessage * msg, bool attachLeaseSet = false); + std::shared_ptr WrapMessage (std::shared_ptr destination, + std::shared_ptr msg, bool attachLeaseSet = false); void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread diff --git a/NetDb.cpp b/NetDb.cpp index b802f3dd..90dcfc96 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -477,7 +477,7 @@ namespace data auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); auto outbound = pool ? pool->GetNextOutboundTunnel () : nullptr; if (outbound) - outbound->SendTunnelDataMsg (buf + offset, tunnelID, deliveryStatus); + outbound->SendTunnelDataMsg (buf + offset, tunnelID, ToSharedI2NPMessage (deliveryStatus)); else { LogPrint (eLogError, "No outbound tunnels for DatabaseStore reply found"); @@ -665,7 +665,7 @@ namespace data numExcluded = 0; // TODO: } - I2NPMessage * replyMsg = nullptr; + std::shared_ptr replyMsg; if (lookupType == DATABASE_LOOKUP_TYPE_EXPLORATORY_LOOKUP) { LogPrint ("Exploratory close to ", key, " ", numExcluded, " excluded"); @@ -685,7 +685,7 @@ namespace data excludedRouters.insert (r->GetIdentHash ()); } } - replyMsg = CreateDatabaseSearchReply (ident, routers); + replyMsg = ToSharedI2NPMessage (CreateDatabaseSearchReply (ident, routers)); } else { @@ -698,7 +698,7 @@ namespace data LogPrint ("Requested RouterInfo ", key, " found"); router->LoadBuffer (); if (router->GetBuffer ()) - replyMsg = CreateDatabaseStoreMsg (router); + replyMsg = ToSharedI2NPMessage (CreateDatabaseStoreMsg (router)); } } @@ -709,7 +709,7 @@ namespace data if (leaseSet) // we don't send back our LeaseSets { LogPrint ("Requested LeaseSet ", key, " found"); - replyMsg = CreateDatabaseStoreMsg (leaseSet); + replyMsg = ToSharedI2NPMessage (CreateDatabaseStoreMsg (leaseSet)); } } @@ -722,7 +722,7 @@ namespace data excludedRouters.insert (excluded); excluded += 32; } - replyMsg = CreateDatabaseSearchReply (ident, GetClosestFloodfills (ident, 3, excludedRouters)); + replyMsg = ToSharedI2NPMessage (CreateDatabaseSearchReply (ident, GetClosestFloodfills (ident, 3, excludedRouters))); } } @@ -747,7 +747,7 @@ namespace data if (outbound) outbound->SendTunnelDataMsg (buf+32, replyTunnelID, replyMsg); else - transports.SendMessage (buf+32, i2p::CreateTunnelGatewayMsg (replyTunnelID, ToSharedI2NPMessage(replyMsg))); + transports.SendMessage (buf+32, i2p::CreateTunnelGatewayMsg (replyTunnelID, replyMsg)); } else transports.SendMessage (buf+32, replyMsg); diff --git a/NetDbRequests.cpp b/NetDbRequests.cpp index 3509bcc7..670070fd 100644 --- a/NetDbRequests.cpp +++ b/NetDbRequests.cpp @@ -118,7 +118,7 @@ namespace data auto nextFloodfill = netdb.GetClosestFloodfill (dest->GetDestination (), dest->GetExcludedPeers ()); if (nextFloodfill && outbound && inbound) outbound->SendTunnelDataMsg (nextFloodfill->GetIdentHash (), 0, - dest->CreateRequestMessage (nextFloodfill, inbound)); + ToSharedI2NPMessage (dest->CreateRequestMessage (nextFloodfill, inbound))); else { done = true; diff --git a/Streaming.cpp b/Streaming.cpp index e20efffb..bd6cb4bb 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -617,7 +617,7 @@ namespace stream { i2p::tunnel::eDeliveryTypeTunnel, m_CurrentRemoteLease.tunnelGateway, m_CurrentRemoteLease.tunnelID, - ToSharedI2NPMessage (msg) + msg }); m_NumSentBytes += it->GetLength (); } @@ -761,9 +761,9 @@ namespace stream m_CurrentRemoteLease.endDate = 0; } - I2NPMessage * Stream::CreateDataMessage (const uint8_t * payload, size_t len) + std::shared_ptr Stream::CreateDataMessage (const uint8_t * payload, size_t len) { - I2NPMessage * msg = NewI2NPShortMessage (); + auto msg = ToSharedI2NPMessage (NewI2NPShortMessage ()); CryptoPP::Gzip compressor; if (len <= i2p::stream::COMPRESSION_THRESHOLD_SIZE) compressor.SetDeflateLevel (CryptoPP::Gzip::MIN_DEFLATE_LEVEL); @@ -780,7 +780,7 @@ namespace stream htobe16buf (buf + 6, m_Port); // destination port buf[9] = i2p::client::PROTOCOL_TYPE_STREAMING; // streaming protocol msg->len += size + 4; - FillI2NPMessageHeader (msg, eI2NPData); + FillI2NPMessageHeader (msg.get (), eI2NPData); // TODO: return msg; } diff --git a/Streaming.h b/Streaming.h index b3cd4b30..7e2aaa71 100644 --- a/Streaming.h +++ b/Streaming.h @@ -156,7 +156,7 @@ namespace stream void HandleResendTimer (const boost::system::error_code& ecode); void HandleAckSendTimer (const boost::system::error_code& ecode); - I2NPMessage * CreateDataMessage (const uint8_t * payload, size_t len); + std::shared_ptr CreateDataMessage (const uint8_t * payload, size_t len); private: diff --git a/Tunnel.cpp b/Tunnel.cpp index de95ad68..8b0d6cfd 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -81,7 +81,7 @@ namespace tunnel // send message if (outboundTunnel) - outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, msg); + outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, ToSharedI2NPMessage (msg)); else i2p::transport::transports.SendMessage (GetNextIdentHash (), ToSharedI2NPMessage (msg)); } @@ -164,7 +164,7 @@ namespace tunnel m_Endpoint.HandleDecryptedTunnelDataMsg (msg); } - void OutboundTunnel::SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, i2p::I2NPMessage * msg) + void OutboundTunnel::SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr msg) { TunnelMessageBlock block; if (gwHash) @@ -180,7 +180,7 @@ namespace tunnel } else block.deliveryType = eDeliveryTypeLocal; - block.data = ToSharedI2NPMessage (msg); + block.data = msg; std::unique_lock l(m_SendMutex); m_Gateway.SendTunnelDataMsg (block); diff --git a/Tunnel.h b/Tunnel.h index f8c5e9cc..4ce44240 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -83,7 +83,7 @@ namespace tunnel OutboundTunnel (std::shared_ptr config): Tunnel (config), m_Gateway (this) {}; - void SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, i2p::I2NPMessage * msg); + void SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr msg); void SendTunnelDataMsg (const std::vector& msgs); // multiple messages std::shared_ptr GetEndpointRouter () const { return GetTunnelConfig ()->GetLastHop ()->router; }; diff --git a/TunnelPool.cpp b/TunnelPool.cpp index 0f0eb709..689d31e8 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -254,7 +254,7 @@ namespace tunnel uint32_t msgID = rnd.GenerateWord32 (); m_Tests[msgID] = std::make_pair (*it1, *it2); (*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (), - CreateDeliveryStatusMsg (msgID)); + ToSharedI2NPMessage (CreateDeliveryStatusMsg (msgID))); it1++; it2++; } } From ff12421d60a75c122fe76e2ef6a852246329549e Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 22 Jun 2015 15:47:45 -0400 Subject: [PATCH 49/67] shared_ptr for lookup messages --- NetDb.cpp | 4 ++-- NetDbRequests.cpp | 6 +++--- NetDbRequests.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/NetDb.cpp b/NetDb.cpp index 90dcfc96..8abb317e 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -590,7 +590,7 @@ namespace data msgs.push_back (i2p::tunnel::TunnelMessageBlock { i2p::tunnel::eDeliveryTypeRouter, - nextFloodfill->GetIdentHash (), 0, ToSharedI2NPMessage (msg) + nextFloodfill->GetIdentHash (), 0, msg }); deleteDest = false; } @@ -794,7 +794,7 @@ namespace data { i2p::tunnel::eDeliveryTypeRouter, floodfill->GetIdentHash (), 0, - ToSharedI2NPMessage (dest->CreateRequestMessage (floodfill, inbound)) // explore + dest->CreateRequestMessage (floodfill, inbound) // explore }); } else diff --git a/NetDbRequests.cpp b/NetDbRequests.cpp index 670070fd..5f4a3e75 100644 --- a/NetDbRequests.cpp +++ b/NetDbRequests.cpp @@ -8,7 +8,7 @@ namespace i2p { namespace data { - I2NPMessage * RequestedDestination::CreateRequestMessage (std::shared_ptr router, + std::shared_ptr RequestedDestination::CreateRequestMessage (std::shared_ptr router, std::shared_ptr replyTunnel) { I2NPMessage * msg = i2p::CreateRouterInfoDatabaseLookupMsg (m_Destination, @@ -16,7 +16,7 @@ namespace data &m_ExcludedPeers); m_ExcludedPeers.insert (router->GetIdentHash ()); m_CreationTime = i2p::util::GetSecondsSinceEpoch (); - return msg; + return ToSharedI2NPMessage (msg); } std::shared_ptr RequestedDestination::CreateRequestMessage (const IdentHash& floodfill) @@ -118,7 +118,7 @@ namespace data auto nextFloodfill = netdb.GetClosestFloodfill (dest->GetDestination (), dest->GetExcludedPeers ()); if (nextFloodfill && outbound && inbound) outbound->SendTunnelDataMsg (nextFloodfill->GetIdentHash (), 0, - ToSharedI2NPMessage (dest->CreateRequestMessage (nextFloodfill, inbound))); + dest->CreateRequestMessage (nextFloodfill, inbound)); else { done = true; diff --git a/NetDbRequests.h b/NetDbRequests.h index 9dc49b26..0bab7080 100644 --- a/NetDbRequests.h +++ b/NetDbRequests.h @@ -28,7 +28,7 @@ namespace data bool IsExploratory () const { return m_IsExploratory; }; bool IsExcluded (const IdentHash& ident) const { return m_ExcludedPeers.count (ident); }; uint64_t GetCreationTime () const { return m_CreationTime; }; - I2NPMessage * CreateRequestMessage (std::shared_ptr, std::shared_ptr replyTunnel); + std::shared_ptr CreateRequestMessage (std::shared_ptr, std::shared_ptr replyTunnel); std::shared_ptr CreateRequestMessage (const IdentHash& floodfill); void SetRequestComplete (const RequestComplete& requestComplete) { m_RequestComplete = requestComplete; }; From a05a20440eb95f077ca1eff3dde89299df712f6e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 24 Jun 2015 10:25:05 -0400 Subject: [PATCH 50/67] deleted deprecated SendMessage --- I2NPProtocol.cpp | 16 ++++++++-------- NetDb.cpp | 6 +++--- Transports.cpp | 13 ------------- Transports.h | 2 -- 4 files changed, 11 insertions(+), 26 deletions(-) diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index c0806d53..57646b17 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -358,14 +358,14 @@ namespace i2p { // so we send it to reply tunnel transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), + ToSharedI2NPMessage (CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), eI2NPVariableTunnelBuildReply, buf, len, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); + bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)))); } else transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); + ToSharedI2NPMessage (CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len, + bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)))); } } } @@ -379,14 +379,14 @@ namespace i2p { // so we send it to reply tunnel transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), + ToSharedI2NPMessage (CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), eI2NPTunnelBuildReply, buf, len, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); + bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)))); } else transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateI2NPMessage (eI2NPTunnelBuild, buf, len, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); + ToSharedI2NPMessage (CreateI2NPMessage (eI2NPTunnelBuild, buf, len, + bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)))); } } diff --git a/NetDb.cpp b/NetDb.cpp index 8abb317e..36e637f1 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -471,7 +471,7 @@ namespace data uint32_t tunnelID = bufbe32toh (buf + offset); offset += 4; if (!tunnelID) // send response directly - transports.SendMessage (buf + offset, deliveryStatus); + transports.SendMessage (buf + offset, ToSharedI2NPMessage (deliveryStatus)); else { auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); @@ -503,7 +503,7 @@ namespace data memcpy (payload + DATABASE_STORE_HEADER_SIZE, buf + offset, len - offset); floodMsg->len += DATABASE_STORE_HEADER_SIZE + len -offset; FillI2NPMessageHeader (floodMsg, eI2NPDatabaseStore); - transports.SendMessage (floodfill->GetIdentHash (), floodMsg); + transports.SendMessage (floodfill->GetIdentHash (), ToSharedI2NPMessage (floodMsg)); } } } @@ -817,7 +817,7 @@ namespace data { uint32_t replyToken = i2p::context.GetRandomNumberGenerator ().GenerateWord32 (); LogPrint ("Publishing our RouterInfo to ", floodfill->GetIdentHashAbbreviation (), ". reply token=", replyToken); - transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken)); + transports.SendMessage (floodfill->GetIdentHash (), ToSharedI2NPMessage (CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken))); excluded.insert (floodfill->GetIdentHash ()); } } diff --git a/Transports.cpp b/Transports.cpp index 381d31e8..738db896 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -213,19 +213,6 @@ namespace transport return std::max (m_InBandwidth, m_OutBandwidth) > LOW_BANDWIDTH_LIMIT; } - void Transports::SendMessage (const i2p::data::IdentHash& ident, i2p::I2NPMessage * msg) - { - SendMessage (ident, ToSharedI2NPMessage (msg)); - } - - void Transports::SendMessages (const i2p::data::IdentHash& ident, const std::vector& msgs) - { - std::vector > msgs1; - for (auto it: msgs) - msgs1.push_back (ToSharedI2NPMessage (it)); - SendMessages (ident, msgs1); - } - void Transports::SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg) { m_Service.post (std::bind (&Transports::PostMessages, this, ident, std::vector > {msg })); diff --git a/Transports.h b/Transports.h index b29d7f1a..15ad980e 100644 --- a/Transports.h +++ b/Transports.h @@ -87,8 +87,6 @@ namespace transport i2p::transport::DHKeysPair * GetNextDHKeysPair (); void ReuseDHKeysPair (DHKeysPair * pair); - void SendMessage (const i2p::data::IdentHash& ident, i2p::I2NPMessage * msg); // deprecated - void SendMessages (const i2p::data::IdentHash& ident, const std::vector& msgs); // deprecated void SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg); void SendMessages (const i2p::data::IdentHash& ident, const std::vector >& msgs); void CloseSession (std::shared_ptr router); From 206f094dd48e689adef7881518d78ee5a5b3d2bb Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 24 Jun 2015 10:45:58 -0400 Subject: [PATCH 51/67] use shared_ptr for DeliverStatus --- Garlic.cpp | 2 +- I2NPProtocol.cpp | 4 ++-- I2NPProtocol.h | 2 +- NetDb.cpp | 7 ++----- SSUSession.cpp | 2 +- TunnelPool.cpp | 2 +- 6 files changed, 8 insertions(+), 11 deletions(-) diff --git a/Garlic.cpp b/Garlic.cpp index 4b89b147..d6216461 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -307,7 +307,7 @@ namespace garlic htobe32buf (buf + size, inboundTunnel->GetNextTunnelID ()); // tunnelID size += 4; // create msg - auto msg = ToSharedI2NPMessage (CreateDeliveryStatusMsg (msgID)); + auto msg = CreateDeliveryStatusMsg (msgID); if (m_Owner) { //encrypt diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 57646b17..9057500b 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -90,7 +90,7 @@ namespace i2p return msg; } - I2NPMessage * CreateDeliveryStatusMsg (uint32_t msgID) + std::shared_ptr CreateDeliveryStatusMsg (uint32_t msgID) { I2NPMessage * m = NewI2NPShortMessage (); uint8_t * buf = m->GetPayload (); @@ -106,7 +106,7 @@ namespace i2p } m->len += DELIVERY_STATUS_SIZE; FillI2NPMessageHeader (m, eI2NPDeliveryStatus); - return m; + return ToSharedI2NPMessage (m); } I2NPMessage * CreateRouterInfoDatabaseLookupMsg (const uint8_t * key, const uint8_t * from, diff --git a/I2NPProtocol.h b/I2NPProtocol.h index 4e8a8f8d..4c299f5e 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -203,7 +203,7 @@ namespace tunnel I2NPMessage * CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID = 0); I2NPMessage * CreateI2NPMessage (const uint8_t * buf, int len, std::shared_ptr from = nullptr); - I2NPMessage * CreateDeliveryStatusMsg (uint32_t msgID); + std::shared_ptr CreateDeliveryStatusMsg (uint32_t msgID); I2NPMessage * CreateRouterInfoDatabaseLookupMsg (const uint8_t * key, const uint8_t * from, uint32_t replyTunnelID, bool exploratory = false, std::set * excludedPeers = nullptr); I2NPMessage * CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest, diff --git a/NetDb.cpp b/NetDb.cpp index 36e637f1..06fd3c37 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -471,18 +471,15 @@ namespace data uint32_t tunnelID = bufbe32toh (buf + offset); offset += 4; if (!tunnelID) // send response directly - transports.SendMessage (buf + offset, ToSharedI2NPMessage (deliveryStatus)); + transports.SendMessage (buf + offset, deliveryStatus); else { auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); auto outbound = pool ? pool->GetNextOutboundTunnel () : nullptr; if (outbound) - outbound->SendTunnelDataMsg (buf + offset, tunnelID, ToSharedI2NPMessage (deliveryStatus)); + outbound->SendTunnelDataMsg (buf + offset, tunnelID, deliveryStatus); else - { LogPrint (eLogError, "No outbound tunnels for DatabaseStore reply found"); - DeleteI2NPMessage (deliveryStatus); - } } offset += 32; diff --git a/SSUSession.cpp b/SSUSession.cpp index 39ef9df0..c8c9fb2e 100644 --- a/SSUSession.cpp +++ b/SSUSession.cpp @@ -262,7 +262,7 @@ namespace transport if (paddingSize > 0) paddingSize = 16 - paddingSize; payload += paddingSize; // TODO: verify signature (need data from session request), payload points to signature - m_Data.Send (ToSharedI2NPMessage(CreateDeliveryStatusMsg (0))); + m_Data.Send (CreateDeliveryStatusMsg (0)); Established (); } diff --git a/TunnelPool.cpp b/TunnelPool.cpp index 689d31e8..0f0eb709 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -254,7 +254,7 @@ namespace tunnel uint32_t msgID = rnd.GenerateWord32 (); m_Tests[msgID] = std::make_pair (*it1, *it2); (*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (), - ToSharedI2NPMessage (CreateDeliveryStatusMsg (msgID))); + CreateDeliveryStatusMsg (msgID)); it1++; it2++; } } From 95c4a87cccc46d96dde5f5f16071c6787e1f5c4d Mon Sep 17 00:00:00 2001 From: Mikhail Titov Date: Wed, 24 Jun 2015 14:19:10 -0500 Subject: [PATCH 52/67] Check for invalid SAM destination This closes #208 --- SAM.cpp | 25 +++++++++++++++---------- SAM.h | 1 + 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/SAM.cpp b/SAM.cpp index cb2cac3e..7db1e1bb 100644 --- a/SAM.cpp +++ b/SAM.cpp @@ -343,19 +343,24 @@ namespace client if (m_Session) { i2p::data::IdentityEx dest; - dest.FromBase64 (destination); - context.GetAddressBook ().InsertAddress (dest); - auto leaseSet = m_Session->localDestination->FindLeaseSet (dest.GetIdentHash ()); - if (leaseSet) - Connect (leaseSet); - else + size_t len = dest.FromBase64(destination); + if (len > 0) { - m_Session->localDestination->RequestDestination (dest.GetIdentHash (), - std::bind (&SAMSocket::HandleConnectLeaseSetRequestComplete, - shared_from_this (), std::placeholders::_1)); + context.GetAddressBook().InsertAddress(dest); + auto leaseSet = m_Session->localDestination->FindLeaseSet(dest.GetIdentHash()); + if (leaseSet) + Connect(leaseSet); + else + { + m_Session->localDestination->RequestDestination(dest.GetIdentHash(), + std::bind(&SAMSocket::HandleConnectLeaseSetRequestComplete, + shared_from_this(), std::placeholders::_1)); + } } + else + SendMessageReply(SAM_SESSION_STATUS_INVALID_KEY, strlen(SAM_SESSION_STATUS_INVALID_KEY), true); } - else + else SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); } diff --git a/SAM.h b/SAM.h index d51f5aa3..7684d461 100644 --- a/SAM.h +++ b/SAM.h @@ -28,6 +28,7 @@ namespace client const char SAM_SESSION_CREATE_REPLY_OK[] = "SESSION STATUS RESULT=OK DESTINATION=%s\n"; const char SAM_SESSION_CREATE_DUPLICATED_ID[] = "SESSION STATUS RESULT=DUPLICATED_ID\n"; const char SAM_SESSION_CREATE_DUPLICATED_DEST[] = "SESSION STATUS RESULT=DUPLICATED_DEST\n"; + const char SAM_SESSION_STATUS_INVALID_KEY[] = "SESSION STATUS RESULT=INVALID_KEY\n"; const char SAM_STREAM_CONNECT[] = "STREAM CONNECT"; const char SAM_STREAM_STATUS_OK[] = "STREAM STATUS RESULT=OK\n"; const char SAM_STREAM_STATUS_INVALID_ID[] = "STREAM STATUS RESULT=INVALID_ID\n"; From d8cd2afd12699c6605e4dffed37127ae2f75c7bd Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 24 Jun 2015 22:19:56 -0400 Subject: [PATCH 53/67] different input anf output I2NP message for tunnel encryption --- I2NPProtocol.h | 1 + TransitTunnel.cpp | 8 ++++---- TransitTunnel.h | 2 +- Tunnel.cpp | 10 ++++++---- Tunnel.h | 2 +- TunnelBase.h | 2 +- TunnelGateway.cpp | 2 +- 7 files changed, 15 insertions(+), 12 deletions(-) diff --git a/I2NPProtocol.h b/I2NPProtocol.h index 4c299f5e..be8e4fbf 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -138,6 +138,7 @@ namespace tunnel // payload uint8_t * GetPayload () { return GetBuffer () + I2NP_HEADER_SIZE; }; + const uint8_t * GetPayload () const { return GetBuffer () + I2NP_HEADER_SIZE; }; uint8_t * GetBuffer () { return buf + offset; }; const uint8_t * GetBuffer () const { return buf + offset; }; size_t GetLength () const { return len - offset; }; diff --git a/TransitTunnel.cpp b/TransitTunnel.cpp index 6fc6c5c0..6cc3491a 100644 --- a/TransitTunnel.cpp +++ b/TransitTunnel.cpp @@ -20,9 +20,9 @@ namespace tunnel m_Encryption.SetKeys (layerKey, ivKey); } - void TransitTunnel::EncryptTunnelMsg (std::shared_ptr tunnelMsg) + void TransitTunnel::EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out) { - m_Encryption.Encrypt (tunnelMsg->GetPayload () + 4, tunnelMsg->GetPayload () + 4); + m_Encryption.Encrypt (in->GetPayload () + 4, out->GetPayload () + 4); } TransitTunnelParticipant::~TransitTunnelParticipant () @@ -31,7 +31,7 @@ namespace tunnel void TransitTunnelParticipant::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) { - EncryptTunnelMsg (tunnelMsg); + EncryptTunnelMsg (tunnelMsg, tunnelMsg); m_NumTransmittedBytes += tunnelMsg->GetLength (); htobe32buf (tunnelMsg->GetPayload (), GetNextTunnelID ()); @@ -78,7 +78,7 @@ namespace tunnel void TransitTunnelEndpoint::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) { - EncryptTunnelMsg (tunnelMsg); + EncryptTunnelMsg (tunnelMsg, tunnelMsg); LogPrint (eLogDebug, "TransitTunnel endpoint for ", GetTunnelID ()); m_Endpoint.HandleDecryptedTunnelDataMsg (tunnelMsg); diff --git a/TransitTunnel.h b/TransitTunnel.h index e6e0601d..e63ce9dc 100644 --- a/TransitTunnel.h +++ b/TransitTunnel.h @@ -30,7 +30,7 @@ namespace tunnel // implements TunnelBase void SendTunnelDataMsg (std::shared_ptr msg); void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); - void EncryptTunnelMsg (std::shared_ptr tunnelMsg); + void EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out); uint32_t GetNextTunnelID () const { return m_NextTunnelID; }; const i2p::data::IdentHash& GetNextIdentHash () const { return m_NextIdent; }; diff --git a/Tunnel.cpp b/Tunnel.cpp index 8b0d6cfd..cd3f69b8 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -140,14 +140,16 @@ namespace tunnel return established; } - void Tunnel::EncryptTunnelMsg (std::shared_ptr tunnelMsg) + void Tunnel::EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out) { - uint8_t * payload = tunnelMsg->GetPayload () + 4; + const uint8_t * inPayload = in->GetPayload () + 4; + uint8_t * outPayload = out->GetPayload () + 4; TunnelHopConfig * hop = m_Config->GetLastHop (); while (hop) { - hop->decryption.Decrypt (payload, payload); + hop->decryption.Decrypt (inPayload, outPayload); hop = hop->prev; + inPayload = outPayload; } } @@ -160,7 +162,7 @@ namespace tunnel { if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive msg->from = shared_from_this (); - EncryptTunnelMsg (msg); + EncryptTunnelMsg (msg, msg); m_Endpoint.HandleDecryptedTunnelDataMsg (msg); } diff --git a/Tunnel.h b/Tunnel.h index 4ce44240..b5cde16a 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -65,7 +65,7 @@ namespace tunnel // implements TunnelBase void SendTunnelDataMsg (std::shared_ptr msg); - void EncryptTunnelMsg (std::shared_ptr tunnelMsg); + void EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out); uint32_t GetNextTunnelID () const { return m_Config->GetFirstHop ()->tunnelID; }; const i2p::data::IdentHash& GetNextIdentHash () const { return m_Config->GetFirstHop ()->router->GetIdentHash (); }; diff --git a/TunnelBase.h b/TunnelBase.h index 5470f139..876d6d93 100644 --- a/TunnelBase.h +++ b/TunnelBase.h @@ -40,7 +40,7 @@ namespace tunnel virtual void HandleTunnelDataMsg (std::shared_ptr tunnelMsg) = 0; virtual void SendTunnelDataMsg (std::shared_ptr msg) = 0; virtual void FlushTunnelDataMsgs () {}; - virtual void EncryptTunnelMsg (std::shared_ptr tunnelMsg) = 0; + virtual void EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out) = 0; virtual uint32_t GetNextTunnelID () const = 0; virtual const i2p::data::IdentHash& GetNextIdentHash () const = 0; virtual uint32_t GetTunnelID () const = 0; // as known at our side diff --git a/TunnelGateway.cpp b/TunnelGateway.cpp index 2763ae17..cedbff10 100644 --- a/TunnelGateway.cpp +++ b/TunnelGateway.cpp @@ -188,7 +188,7 @@ namespace tunnel auto tunnelMsgs = m_Buffer.GetTunnelDataMsgs (); for (auto tunnelMsg : tunnelMsgs) { - m_Tunnel->EncryptTunnelMsg (tunnelMsg); + m_Tunnel->EncryptTunnelMsg (tunnelMsg, tunnelMsg); FillI2NPMessageHeader (tunnelMsg.get (), eI2NPTunnelData); // TODO: m_NumSentBytes += TUNNEL_DATA_MSG_SIZE; } From be1a4548e619592f33234c15605bde14c91261c6 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 25 Jun 2015 21:49:16 -0400 Subject: [PATCH 54/67] pass const I2NP message to HandleTunnelDataMsg --- I2NPProtocol.cpp | 7 +++++++ I2NPProtocol.h | 1 + TransitTunnel.cpp | 20 +++++++++++--------- TransitTunnel.h | 6 +++--- Tunnel.cpp | 13 +++++++------ Tunnel.h | 4 ++-- TunnelBase.h | 2 +- 7 files changed, 32 insertions(+), 21 deletions(-) diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 9057500b..98c008d8 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -432,6 +432,13 @@ namespace i2p FillI2NPMessageHeader (msg, eI2NPTunnelData); return msg; } + + std::shared_ptr CreateEmptyTunnelDataMsg () + { + I2NPMessage * msg = NewI2NPShortMessage (); + msg->len += i2p::tunnel::TUNNEL_DATA_MSG_SIZE; + return ToSharedI2NPMessage (msg); + } I2NPMessage * CreateTunnelGatewayMsg (uint32_t tunnelID, const uint8_t * buf, size_t len) { diff --git a/I2NPProtocol.h b/I2NPProtocol.h index be8e4fbf..026801c5 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -222,6 +222,7 @@ namespace tunnel I2NPMessage * CreateTunnelDataMsg (const uint8_t * buf); I2NPMessage * CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload); + std::shared_ptr CreateEmptyTunnelDataMsg (); I2NPMessage * CreateTunnelGatewayMsg (uint32_t tunnelID, const uint8_t * buf, size_t len); I2NPMessage * CreateTunnelGatewayMsg (uint32_t tunnelID, I2NPMessageType msgType, diff --git a/TransitTunnel.cpp b/TransitTunnel.cpp index 6cc3491a..7c58dabb 100644 --- a/TransitTunnel.cpp +++ b/TransitTunnel.cpp @@ -29,14 +29,15 @@ namespace tunnel { } - void TransitTunnelParticipant::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) + void TransitTunnelParticipant::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) { - EncryptTunnelMsg (tunnelMsg, tunnelMsg); + auto newMsg = CreateEmptyTunnelDataMsg (); + EncryptTunnelMsg (tunnelMsg, newMsg); m_NumTransmittedBytes += tunnelMsg->GetLength (); - htobe32buf (tunnelMsg->GetPayload (), GetNextTunnelID ()); - FillI2NPMessageHeader (tunnelMsg.get (), eI2NPTunnelData); // TODO - m_TunnelDataMsgs.push_back (tunnelMsg); + htobe32buf (newMsg->GetPayload (), GetNextTunnelID ()); + FillI2NPMessageHeader (newMsg.get (), eI2NPTunnelData); // TODO + m_TunnelDataMsgs.push_back (newMsg); } void TransitTunnelParticipant::FlushTunnelDataMsgs () @@ -56,7 +57,7 @@ namespace tunnel LogPrint (eLogError, "We are not a gateway for transit tunnel ", m_TunnelID); } - void TransitTunnel::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) + void TransitTunnel::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) { LogPrint (eLogError, "Incoming tunnel message is not supported ", m_TunnelID); } @@ -76,12 +77,13 @@ namespace tunnel m_Gateway.SendBuffer (); } - void TransitTunnelEndpoint::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) + void TransitTunnelEndpoint::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) { - EncryptTunnelMsg (tunnelMsg, tunnelMsg); + auto newMsg = CreateEmptyTunnelDataMsg (); + EncryptTunnelMsg (tunnelMsg, newMsg); LogPrint (eLogDebug, "TransitTunnel endpoint for ", GetTunnelID ()); - m_Endpoint.HandleDecryptedTunnelDataMsg (tunnelMsg); + m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg); } TransitTunnel * CreateTransitTunnel (uint32_t receiveTunnelID, diff --git a/TransitTunnel.h b/TransitTunnel.h index e63ce9dc..79bb99bb 100644 --- a/TransitTunnel.h +++ b/TransitTunnel.h @@ -29,7 +29,7 @@ namespace tunnel // implements TunnelBase void SendTunnelDataMsg (std::shared_ptr msg); - void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); void EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out); uint32_t GetNextTunnelID () const { return m_NextTunnelID; }; const i2p::data::IdentHash& GetNextIdentHash () const { return m_NextIdent; }; @@ -54,7 +54,7 @@ namespace tunnel ~TransitTunnelParticipant (); size_t GetNumTransmittedBytes () const { return m_NumTransmittedBytes; }; - void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); void FlushTunnelDataMsgs (); private: @@ -93,7 +93,7 @@ namespace tunnel TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey), m_Endpoint (false) {}; // transit endpoint is always outbound - void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); size_t GetNumTransmittedBytes () const { return m_Endpoint.GetNumReceivedBytes (); } private: diff --git a/Tunnel.cpp b/Tunnel.cpp index cd3f69b8..74780b6c 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -158,12 +158,13 @@ namespace tunnel LogPrint (eLogInfo, "Can't send I2NP messages without delivery instructions"); } - void InboundTunnel::HandleTunnelDataMsg (std::shared_ptr msg) + void InboundTunnel::HandleTunnelDataMsg (std::shared_ptr msg) { - if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive - msg->from = shared_from_this (); - EncryptTunnelMsg (msg, msg); - m_Endpoint.HandleDecryptedTunnelDataMsg (msg); + if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive + auto newMsg = CreateEmptyTunnelDataMsg (); + EncryptTunnelMsg (msg, newMsg); + newMsg->from = shared_from_this (); + m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg); } void OutboundTunnel::SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr msg) @@ -196,7 +197,7 @@ namespace tunnel m_Gateway.SendBuffer (); } - void OutboundTunnel::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) + void OutboundTunnel::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) { LogPrint (eLogError, "Incoming message for outbound tunnel ", GetTunnelID ()); } diff --git a/Tunnel.h b/Tunnel.h index b5cde16a..e75de74b 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -90,7 +90,7 @@ namespace tunnel size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); }; // implements TunnelBase - void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); uint32_t GetTunnelID () const { return GetNextTunnelID (); }; private: @@ -104,7 +104,7 @@ namespace tunnel public: InboundTunnel (std::shared_ptr config): Tunnel (config), m_Endpoint (true) {}; - void HandleTunnelDataMsg (std::shared_ptr msg); + void HandleTunnelDataMsg (std::shared_ptr msg); size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); }; // implements TunnelBase diff --git a/TunnelBase.h b/TunnelBase.h index 876d6d93..76175d0a 100644 --- a/TunnelBase.h +++ b/TunnelBase.h @@ -37,7 +37,7 @@ namespace tunnel TunnelBase (): m_CreationTime (i2p::util::GetSecondsSinceEpoch ()) {}; virtual ~TunnelBase () {}; - virtual void HandleTunnelDataMsg (std::shared_ptr tunnelMsg) = 0; + virtual void HandleTunnelDataMsg (std::shared_ptr tunnelMsg) = 0; virtual void SendTunnelDataMsg (std::shared_ptr msg) = 0; virtual void FlushTunnelDataMsgs () {}; virtual void EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out) = 0; From bf4c33325cf7c447890c90a4c1361c8bd0a5bada Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 26 Jun 2015 16:06:59 -0400 Subject: [PATCH 55/67] random non-zero padding --- TunnelGateway.cpp | 16 ++++++++++++++-- TunnelGateway.h | 6 +++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/TunnelGateway.cpp b/TunnelGateway.cpp index cedbff10..ffbb8fe3 100644 --- a/TunnelGateway.cpp +++ b/TunnelGateway.cpp @@ -10,6 +10,14 @@ namespace i2p { namespace tunnel { + TunnelGatewayBuffer::TunnelGatewayBuffer (uint32_t tunnelID): m_TunnelID (tunnelID), + m_CurrentTunnelDataMsg (nullptr), m_RemainingSize (0) + { + context.GetRandomNumberGenerator ().GenerateBlock (m_NonZeroRandomBuffer, TUNNEL_DATA_MAX_PAYLOAD_SIZE); + for (size_t i = 0; i < TUNNEL_DATA_MAX_PAYLOAD_SIZE; i++) + if (!m_NonZeroRandomBuffer[i]) m_NonZeroRandomBuffer[i] = 1; + } + TunnelGatewayBuffer::~TunnelGatewayBuffer () { } @@ -160,13 +168,17 @@ namespace tunnel payload[-1] = 0; // zero ptrdiff_t paddingSize = payload - buf - 25; // 25 = 24 + 1 if (paddingSize > 0) - memset (buf + 24, 1, paddingSize); // padding TODO: fill with random data + { + // non-zero padding + auto randomOffset = rnd.GenerateWord32 (0, TUNNEL_DATA_MAX_PAYLOAD_SIZE - paddingSize); + memcpy (buf + 24, m_NonZeroRandomBuffer + randomOffset, paddingSize); + } // we can't fill message header yet because encryption is required m_TunnelDataMsgs.push_back (m_CurrentTunnelDataMsg); m_CurrentTunnelDataMsg = nullptr; } - + void TunnelGateway::SendTunnelDataMsg (const TunnelMessageBlock& block) { if (block.data) diff --git a/TunnelGateway.h b/TunnelGateway.h index cfad17b5..ea88317b 100644 --- a/TunnelGateway.h +++ b/TunnelGateway.h @@ -14,8 +14,7 @@ namespace tunnel class TunnelGatewayBuffer { public: - TunnelGatewayBuffer (uint32_t tunnelID): m_TunnelID (tunnelID), - m_CurrentTunnelDataMsg (nullptr), m_RemainingSize (0) {}; + TunnelGatewayBuffer (uint32_t tunnelID); ~TunnelGatewayBuffer (); void PutI2NPMsg (const TunnelMessageBlock& block); const std::vector >& GetTunnelDataMsgs () const { return m_TunnelDataMsgs; }; @@ -32,13 +31,14 @@ namespace tunnel std::vector > m_TunnelDataMsgs; std::shared_ptr m_CurrentTunnelDataMsg; size_t m_RemainingSize; + uint8_t m_NonZeroRandomBuffer[TUNNEL_DATA_MAX_PAYLOAD_SIZE]; }; class TunnelGateway { public: - TunnelGateway (TunnelBase * tunnel): + TunnelGateway (TunnelBase * tunnel): m_Tunnel (tunnel), m_Buffer (tunnel->GetNextTunnelID ()), m_NumSentBytes (0) {}; void SendTunnelDataMsg (const TunnelMessageBlock& block); void PutTunnelDataMsg (const TunnelMessageBlock& block); From 047c6a93a3d949af56bed8e499e4ebe626505b7f Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 27 Jun 2015 22:02:00 -0400 Subject: [PATCH 56/67] don't copy transit DatabaseStore --- Tunnel.cpp | 6 +----- TunnelEndpoint.cpp | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/Tunnel.cpp b/Tunnel.cpp index 74780b6c..b773cbfc 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -440,13 +440,9 @@ namespace tunnel LogPrint (eLogDebug, "TunnelGateway of ", (int)len, " bytes for tunnel ", tunnel->GetTunnelID (), ". Msg type ", (int)typeID); if (typeID == eI2NPDatabaseStore || typeID == eI2NPDatabaseSearchReply) - { // transit DatabaseStore my contain new/updated RI // or DatabaseSearchReply with new routers - auto ds = NewI2NPMessage (); - *ds = *msg; // TODO: don't copy once msg is shared_ptr - i2p::data::netdb.PostI2NPMsg (ToSharedI2NPMessage (ds)); - } + i2p::data::netdb.PostI2NPMsg (msg); tunnel->SendTunnelDataMsg (msg); } diff --git a/TunnelEndpoint.cpp b/TunnelEndpoint.cpp index e493e168..a8206d3f 100644 --- a/TunnelEndpoint.cpp +++ b/TunnelEndpoint.cpp @@ -243,12 +243,8 @@ namespace tunnel { auto typeID = msg.data->GetTypeID (); if (typeID == eI2NPDatabaseStore || typeID == eI2NPDatabaseSearchReply ) - { // catch RI or reply with new list of routers - auto ds = NewI2NPShortMessage (); - *ds = *(msg.data); // TODO: don't copy once msg.data is shared_ptr - i2p::data::netdb.PostI2NPMsg (ToSharedI2NPMessage (ds)); - } + i2p::data::netdb.PostI2NPMsg (msg.data); i2p::transport::transports.SendMessage (msg.hash, msg.data); } else // we shouldn't send this message. possible leakage From adf12b6084196c49f2ee8620003b6492a58ff3a3 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 29 Jun 2015 21:40:43 -0400 Subject: [PATCH 57/67] handle DeliveryStatus garlic clove directly --- Destination.cpp | 6 +++++- Garlic.cpp | 4 ++-- I2NPProtocol.cpp | 4 ++-- I2NPProtocol.h | 2 +- RouterContext.cpp | 2 +- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Destination.cpp b/Destination.cpp index d98de3f7..e1c639c2 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -233,6 +233,10 @@ namespace client case eI2NPData: HandleDataMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET)); break; + case eI2NPDeliveryStatus: + // we assume tunnel tests non-encrypted + HandleDeliveryStatusMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from)); + break; case eI2NPDatabaseStore: HandleDatabaseStoreMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET)); break; @@ -240,7 +244,7 @@ namespace client HandleDatabaseSearchReplyMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET)); break; default: - i2p::HandleI2NPMessage (ToSharedI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from))); + i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from)); } } diff --git a/Garlic.cpp b/Garlic.cpp index d6216461..00a943e2 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -508,8 +508,8 @@ namespace garlic tunnel = from->GetTunnelPool ()->GetNextOutboundTunnel (); if (tunnel) // we have send it through an outbound tunnel { - I2NPMessage * msg = CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from); - tunnel->SendTunnelDataMsg (gwHash, gwTunnel, ToSharedI2NPMessage (msg)); + auto msg = CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from); + tunnel->SendTunnelDataMsg (gwHash, gwTunnel, msg); } else LogPrint ("No outbound tunnels available for garlic clove"); diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 98c008d8..0c9d82da 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -76,7 +76,7 @@ namespace i2p return msg; } - I2NPMessage * CreateI2NPMessage (const uint8_t * buf, int len, std::shared_ptr from) + std::shared_ptr CreateI2NPMessage (const uint8_t * buf, int len, std::shared_ptr from) { I2NPMessage * msg = NewI2NPMessage (); if (msg->offset + len < msg->maxLen) @@ -87,7 +87,7 @@ namespace i2p } else LogPrint (eLogError, "I2NP message length ", len, " exceeds max length"); - return msg; + return ToSharedI2NPMessage(msg); } std::shared_ptr CreateDeliveryStatusMsg (uint32_t msgID) diff --git a/I2NPProtocol.h b/I2NPProtocol.h index 026801c5..98e5f1c5 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -202,7 +202,7 @@ namespace tunnel void FillI2NPMessageHeader (I2NPMessage * msg, I2NPMessageType msgType, uint32_t replyMsgID = 0); void RenewI2NPMessageHeader (I2NPMessage * msg); I2NPMessage * CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID = 0); - I2NPMessage * CreateI2NPMessage (const uint8_t * buf, int len, std::shared_ptr from = nullptr); + std::shared_ptr CreateI2NPMessage (const uint8_t * buf, int len, std::shared_ptr from = nullptr); std::shared_ptr CreateDeliveryStatusMsg (uint32_t msgID); I2NPMessage * CreateRouterInfoDatabaseLookupMsg (const uint8_t * key, const uint8_t * from, diff --git a/RouterContext.cpp b/RouterContext.cpp index 29815b06..c9328b5c 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -296,7 +296,7 @@ namespace i2p void RouterContext::HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) { - i2p::HandleI2NPMessage (ToSharedI2NPMessage(CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from))); + i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from)); } void RouterContext::ProcessGarlicMessage (std::shared_ptr msg) From 83e76c6b5326596b677a74e30dbf8bac6561d1c5 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 1 Jul 2015 14:13:42 -0400 Subject: [PATCH 58/67] use shared flood message --- NetDb.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/NetDb.cpp b/NetDb.cpp index 06fd3c37..db163002 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -486,22 +486,19 @@ namespace data if (context.IsFloodfill ()) { // flood it + auto floodMsg = ToSharedI2NPMessage (NewI2NPShortMessage ()); + uint8_t * payload = floodMsg->GetPayload (); + memcpy (payload, buf, 33); // key + type + htobe32buf (payload + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0); // zero reply token + memcpy (payload + DATABASE_STORE_HEADER_SIZE, buf + offset, len - offset); + floodMsg->len += DATABASE_STORE_HEADER_SIZE + len -offset; + FillI2NPMessageHeader (floodMsg.get (), eI2NPDatabaseStore); // TODO std::set excluded; for (int i = 0; i < 3; i++) { auto floodfill = GetClosestFloodfill (ident, excluded); if (floodfill) - { - excluded.insert (floodfill->GetIdentHash ()); - auto floodMsg = NewI2NPShortMessage (); - uint8_t * payload = floodMsg->GetPayload (); - memcpy (payload, buf, 33); // key + type - htobe32buf (payload + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0); // zero reply token - memcpy (payload + DATABASE_STORE_HEADER_SIZE, buf + offset, len - offset); - floodMsg->len += DATABASE_STORE_HEADER_SIZE + len -offset; - FillI2NPMessageHeader (floodMsg, eI2NPDatabaseStore); - transports.SendMessage (floodfill->GetIdentHash (), ToSharedI2NPMessage (floodMsg)); - } + transports.SendMessage (floodfill->GetIdentHash (), floodMsg); } } } From fbebdd3055f0b3395abf66c3c469af5defa1d92a Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 1 Jul 2015 17:20:41 -0400 Subject: [PATCH 59/67] fixed race condition --- Streaming.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Streaming.cpp b/Streaming.cpp index bd6cb4bb..41d39a63 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -22,7 +22,7 @@ namespace stream { m_RecvStreamID = i2p::context.GetRandomNumberGenerator ().GenerateWord32 (); m_RemoteIdentity = remote->GetIdentity (); - UpdateCurrentRemoteLease (); + m_CurrentRemoteLease.endDate = 0; } Stream::Stream (boost::asio::io_service& service, StreamingDestination& local): From 654357f5cee727408c2afb0768d28ac3267d3b2b Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 2 Jul 2015 13:43:03 -0400 Subject: [PATCH 60/67] copy shared_ptr --- Transports.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Transports.cpp b/Transports.cpp index 738db896..da07dc1d 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -215,7 +215,7 @@ namespace transport void Transports::SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg) { - m_Service.post (std::bind (&Transports::PostMessages, this, ident, std::vector > {msg })); + SendMessages (ident, std::vector > {msg }); } void Transports::SendMessages (const i2p::data::IdentHash& ident, const std::vector >& msgs) From 17acdcc4d547d772fa0b76f7aeb89f7b20d0eff7 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 2 Jul 2015 14:11:30 -0400 Subject: [PATCH 61/67] temporary fix of crash --- TunnelEndpoint.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TunnelEndpoint.cpp b/TunnelEndpoint.cpp index a8206d3f..9d1425e1 100644 --- a/TunnelEndpoint.cpp +++ b/TunnelEndpoint.cpp @@ -241,10 +241,10 @@ namespace tunnel // to somebody else if (!m_IsInbound) // outbound transit tunnel { - auto typeID = msg.data->GetTypeID (); + /* auto typeID = msg.data->GetTypeID (); if (typeID == eI2NPDatabaseStore || typeID == eI2NPDatabaseSearchReply ) // catch RI or reply with new list of routers - i2p::data::netdb.PostI2NPMsg (msg.data); + i2p::data::netdb.PostI2NPMsg (msg.data);*/ i2p::transport::transports.SendMessage (msg.hash, msg.data); } else // we shouldn't send this message. possible leakage From 0c8fb376db133e95b1207ae49c65dc6cb4bda3e2 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 3 Jul 2015 10:11:55 -0400 Subject: [PATCH 62/67] some cleanup --- NTCPSession.cpp | 18 +----------------- NTCPSession.h | 2 -- SSUSession.cpp | 11 ----------- SSUSession.h | 2 -- TransportSession.h | 1 - 5 files changed, 1 insertion(+), 33 deletions(-) diff --git a/NTCPSession.cpp b/NTCPSession.cpp index 4b622c73..dfd69be9 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -101,7 +101,7 @@ namespace transport m_DHKeysPair = nullptr; SendTimeSyncMessage (); - PostI2NPMessage (ToSharedI2NPMessage(CreateDatabaseStoreMsg ())); // we tell immediately who we are + Send (ToSharedI2NPMessage(CreateDatabaseStoreMsg ())); // we tell immediately who we are transports.PeerConnected (shared_from_this ()); } @@ -673,22 +673,6 @@ namespace transport Send (nullptr); } - void NTCPSession::SendI2NPMessage (std::shared_ptr msg) - { - m_Server.GetService ().post (std::bind (&NTCPSession::PostI2NPMessage, shared_from_this (), msg)); - } - - void NTCPSession::PostI2NPMessage (std::shared_ptr msg) - { - if (msg) - { - if (m_IsTerminated) return; - if (m_IsSending) - m_SendQueue.push_back (msg); - else - Send (msg); - } - } void NTCPSession::SendI2NPMessages (const std::vector >& msgs) { diff --git a/NTCPSession.h b/NTCPSession.h index 96644eea..2921e923 100644 --- a/NTCPSession.h +++ b/NTCPSession.h @@ -61,12 +61,10 @@ namespace transport void ClientLogin (); void ServerLogin (); - void SendI2NPMessage (std::shared_ptr msg); void SendI2NPMessages (const std::vector >& msgs); private: - void PostI2NPMessage (std::shared_ptr msg); void PostI2NPMessages (std::vector > msgs); void Connected (); void SendTimeSyncMessage (); diff --git a/SSUSession.cpp b/SSUSession.cpp index c8c9fb2e..3900e7de 100644 --- a/SSUSession.cpp +++ b/SSUSession.cpp @@ -832,17 +832,6 @@ namespace transport } } - void SSUSession::SendI2NPMessage (std::shared_ptr msg) - { - GetService ().post (std::bind (&SSUSession::PostI2NPMessage, shared_from_this (), msg)); - } - - void SSUSession::PostI2NPMessage (std::shared_ptr msg) - { - if (msg &&m_State == eSessionStateEstablished) - m_Data.Send (msg); - } - void SSUSession::SendI2NPMessages (const std::vector >& msgs) { GetService ().post (std::bind (&SSUSession::PostI2NPMessages, shared_from_this (), msgs)); diff --git a/SSUSession.h b/SSUSession.h index fd1ba39e..6c222185 100644 --- a/SSUSession.h +++ b/SSUSession.h @@ -76,7 +76,6 @@ namespace transport void Done (); boost::asio::ip::udp::endpoint& GetRemoteEndpoint () { return m_RemoteEndpoint; }; bool IsV6 () const { return m_RemoteEndpoint.address ().is_v6 (); }; - void SendI2NPMessage (std::shared_ptr msg); void SendI2NPMessages (const std::vector >& msgs); void SendPeerTest (); // Alice @@ -95,7 +94,6 @@ namespace transport boost::asio::io_service& GetService (); void CreateAESandMacKey (const uint8_t * pubKey); - void PostI2NPMessage (std::shared_ptr msg); void PostI2NPMessages (std::vector > msgs); void ProcessMessage (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); // call for established session void ProcessSessionRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); diff --git a/TransportSession.h b/TransportSession.h index dcd9f66c..f8da2b4d 100644 --- a/TransportSession.h +++ b/TransportSession.h @@ -71,7 +71,6 @@ namespace transport size_t GetNumSentBytes () const { return m_NumSentBytes; }; size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; }; - virtual void SendI2NPMessage (std::shared_ptr msg) = 0; virtual void SendI2NPMessages (const std::vector >& msgs) = 0; protected: From bf14b7da9a92e96622ffda33ce5973863fe907ce Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 3 Jul 2015 11:11:07 -0400 Subject: [PATCH 63/67] move FillI2NPMessageHeader into I2NPMessage --- Datagram.cpp | 2 +- Garlic.cpp | 2 +- I2NPProtocol.cpp | 49 ++++++++++++++++++++++------------------------- I2NPProtocol.h | 5 +++-- NetDb.cpp | 2 +- Streaming.cpp | 2 +- TransitTunnel.cpp | 2 +- Tunnel.cpp | 2 +- TunnelGateway.cpp | 2 +- 9 files changed, 33 insertions(+), 35 deletions(-) diff --git a/Datagram.cpp b/Datagram.cpp index 32499232..63b487ff 100644 --- a/Datagram.cpp +++ b/Datagram.cpp @@ -143,7 +143,7 @@ namespace datagram htobe16buf (buf + 6, toPort); // destination port buf[9] = i2p::client::PROTOCOL_TYPE_DATAGRAM; // datagram protocol msg->len += size + 4; - FillI2NPMessageHeader (msg, eI2NPData); + msg->FillI2NPMessageHeader (eI2NPData); return msg; } } diff --git a/Garlic.cpp b/Garlic.cpp index 00a943e2..fb67b0ae 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -167,7 +167,7 @@ namespace garlic len += CreateAESBlock (buf, msg.get ()); // TODO htobe32buf (m->GetPayload (), len); m->len += len + 4; - FillI2NPMessageHeader (m.get (), eI2NPGarlic); // TODO + m->FillI2NPMessageHeader (eI2NPGarlic); return m; } diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 0c9d82da..f98bdc1c 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -41,25 +41,22 @@ namespace i2p return std::shared_ptr(msg, DeleteI2NPMessage); } - void FillI2NPMessageHeader (I2NPMessage * msg, I2NPMessageType msgType, uint32_t replyMsgID) + void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID) { - msg->SetTypeID (msgType); + SetTypeID (msgType); if (replyMsgID) // for tunnel creation - msg->SetMsgID (replyMsgID); + SetMsgID (replyMsgID); else - msg->SetMsgID (i2p::context.GetRandomNumberGenerator ().GenerateWord32 ()); - msg->SetExpiration (i2p::util::GetMillisecondsSinceEpoch () + 5000); // TODO: 5 secs is a magic number - msg->UpdateSize (); - msg->UpdateChks (); + SetMsgID (i2p::context.GetRandomNumberGenerator ().GenerateWord32 ()); + SetExpiration (i2p::util::GetMillisecondsSinceEpoch () + 5000); // TODO: 5 secs is a magic number + UpdateSize (); + UpdateChks (); } - void RenewI2NPMessageHeader (I2NPMessage * msg) + void I2NPMessage::RenewI2NPMessageHeader () { - if (msg) - { - msg->SetMsgID (i2p::context.GetRandomNumberGenerator ().GenerateWord32 ()); - msg->SetExpiration (i2p::util::GetMillisecondsSinceEpoch () + 5000); - } + SetMsgID (i2p::context.GetRandomNumberGenerator ().GenerateWord32 ()); + SetExpiration (i2p::util::GetMillisecondsSinceEpoch () + 5000); } I2NPMessage * CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID) @@ -72,7 +69,7 @@ namespace i2p } else LogPrint (eLogError, "I2NP message length ", len, " exceeds max length"); - FillI2NPMessageHeader (msg, msgType, replyMsgID); + msg->FillI2NPMessageHeader (msgType, replyMsgID); return msg; } @@ -105,7 +102,7 @@ namespace i2p htobe64buf (buf + DELIVERY_STATUS_TIMESTAMP_OFFSET, 2); // netID = 2 } m->len += DELIVERY_STATUS_SIZE; - FillI2NPMessageHeader (m, eI2NPDeliveryStatus); + m->FillI2NPMessageHeader (eI2NPDeliveryStatus); return ToSharedI2NPMessage (m); } @@ -150,7 +147,7 @@ namespace i2p } m->len += (buf - m->GetPayload ()); - FillI2NPMessageHeader (m, eI2NPDatabaseLookup); + m->FillI2NPMessageHeader (eI2NPDatabaseLookup); return m; } @@ -187,7 +184,7 @@ namespace i2p buf += 65; m->len += (buf - m->GetPayload ()); - FillI2NPMessageHeader (m, eI2NPDatabaseLookup); + m->FillI2NPMessageHeader (eI2NPDatabaseLookup); return m; } @@ -211,7 +208,7 @@ namespace i2p memcpy (buf + len, i2p::context.GetRouterInfo ().GetIdentHash (), 32); len += 32; m->len += len; - FillI2NPMessageHeader (m, eI2NPDatabaseSearchReply); + m->FillI2NPMessageHeader (eI2NPDatabaseSearchReply); return m; } @@ -245,7 +242,7 @@ namespace i2p compressor.Get (buf, size); buf += size; m->len += (buf - payload); // payload size - FillI2NPMessageHeader (m, eI2NPDatabaseStore); + m->FillI2NPMessageHeader (eI2NPDatabaseStore); return m; } @@ -275,7 +272,7 @@ namespace i2p memcpy (payload + size, leaseSet->GetBuffer (), leaseSet->GetBufferLen ()); size += leaseSet->GetBufferLen (); m->len += size; - FillI2NPMessageHeader (m, eI2NPDatabaseStore); + m->FillI2NPMessageHeader (eI2NPDatabaseStore); return m; } @@ -419,7 +416,7 @@ namespace i2p I2NPMessage * msg = NewI2NPShortMessage (); memcpy (msg->GetPayload (), buf, i2p::tunnel::TUNNEL_DATA_MSG_SIZE); msg->len += i2p::tunnel::TUNNEL_DATA_MSG_SIZE; - FillI2NPMessageHeader (msg, eI2NPTunnelData); + msg->FillI2NPMessageHeader (eI2NPTunnelData); return msg; } @@ -429,7 +426,7 @@ namespace i2p memcpy (msg->GetPayload () + 4, payload, i2p::tunnel::TUNNEL_DATA_MSG_SIZE - 4); htobe32buf (msg->GetPayload (), tunnelID); msg->len += i2p::tunnel::TUNNEL_DATA_MSG_SIZE; - FillI2NPMessageHeader (msg, eI2NPTunnelData); + msg->FillI2NPMessageHeader (eI2NPTunnelData); return msg; } @@ -448,7 +445,7 @@ namespace i2p htobe16buf (payload + TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET, len); memcpy (payload + TUNNEL_GATEWAY_HEADER_SIZE, buf, len); msg->len += TUNNEL_GATEWAY_HEADER_SIZE + len; - FillI2NPMessageHeader (msg, eI2NPTunnelGateway); + msg->FillI2NPMessageHeader (eI2NPTunnelGateway); return msg; } @@ -463,7 +460,7 @@ namespace i2p htobe16buf (payload + TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET, len); msg->offset -= (I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE); msg->len = msg->offset + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE +len; - FillI2NPMessageHeader (msg.get(), eI2NPTunnelGateway); // TODO + msg->FillI2NPMessageHeader (eI2NPTunnelGateway); return msg; } else @@ -482,13 +479,13 @@ namespace i2p msg->len += gatewayMsgOffset; memcpy (msg->GetPayload (), buf, len); msg->len += len; - FillI2NPMessageHeader (msg, msgType, replyMsgID); // create content message + msg->FillI2NPMessageHeader (msgType, replyMsgID); // create content message len = msg->GetLength (); msg->offset -= gatewayMsgOffset; uint8_t * payload = msg->GetPayload (); htobe32buf (payload + TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET, tunnelID); htobe16buf (payload + TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET, len); - FillI2NPMessageHeader (msg, eI2NPTunnelGateway); // gateway message + msg->FillI2NPMessageHeader (eI2NPTunnelGateway); // gateway message return msg; } diff --git a/I2NPProtocol.h b/I2NPProtocol.h index 98e5f1c5..0e6f5621 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -184,6 +184,9 @@ namespace tunnel len = offset + I2NP_SHORT_HEADER_SIZE + bufbe16toh (header + I2NP_HEADER_SIZE_OFFSET); return bufbe32toh (header + I2NP_HEADER_MSGID_OFFSET); } + + void FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID = 0); + void RenewI2NPMessageHeader (); }; template @@ -199,8 +202,6 @@ namespace tunnel void DeleteI2NPMessage (I2NPMessage * msg); std::shared_ptr ToSharedI2NPMessage (I2NPMessage * msg); - void FillI2NPMessageHeader (I2NPMessage * msg, I2NPMessageType msgType, uint32_t replyMsgID = 0); - void RenewI2NPMessageHeader (I2NPMessage * msg); I2NPMessage * CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID = 0); std::shared_ptr CreateI2NPMessage (const uint8_t * buf, int len, std::shared_ptr from = nullptr); diff --git a/NetDb.cpp b/NetDb.cpp index db163002..dad122a2 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -492,7 +492,7 @@ namespace data htobe32buf (payload + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0); // zero reply token memcpy (payload + DATABASE_STORE_HEADER_SIZE, buf + offset, len - offset); floodMsg->len += DATABASE_STORE_HEADER_SIZE + len -offset; - FillI2NPMessageHeader (floodMsg.get (), eI2NPDatabaseStore); // TODO + floodMsg->FillI2NPMessageHeader (eI2NPDatabaseStore); std::set excluded; for (int i = 0; i < 3; i++) { diff --git a/Streaming.cpp b/Streaming.cpp index 41d39a63..785e2987 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -780,7 +780,7 @@ namespace stream htobe16buf (buf + 6, m_Port); // destination port buf[9] = i2p::client::PROTOCOL_TYPE_STREAMING; // streaming protocol msg->len += size + 4; - FillI2NPMessageHeader (msg.get (), eI2NPData); // TODO: + msg->FillI2NPMessageHeader (eI2NPData); return msg; } diff --git a/TransitTunnel.cpp b/TransitTunnel.cpp index 7c58dabb..ad6aa0b3 100644 --- a/TransitTunnel.cpp +++ b/TransitTunnel.cpp @@ -36,7 +36,7 @@ namespace tunnel m_NumTransmittedBytes += tunnelMsg->GetLength (); htobe32buf (newMsg->GetPayload (), GetNextTunnelID ()); - FillI2NPMessageHeader (newMsg.get (), eI2NPTunnelData); // TODO + newMsg->FillI2NPMessageHeader (eI2NPTunnelData); m_TunnelDataMsgs.push_back (newMsg); } diff --git a/Tunnel.cpp b/Tunnel.cpp index b773cbfc..0c5600e7 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -77,7 +77,7 @@ namespace tunnel } hop = hop->prev; } - FillI2NPMessageHeader (msg, eI2NPVariableTunnelBuild); + msg->FillI2NPMessageHeader (eI2NPVariableTunnelBuild); // send message if (outboundTunnel) diff --git a/TunnelGateway.cpp b/TunnelGateway.cpp index ffbb8fe3..b05a342c 100644 --- a/TunnelGateway.cpp +++ b/TunnelGateway.cpp @@ -201,7 +201,7 @@ namespace tunnel for (auto tunnelMsg : tunnelMsgs) { m_Tunnel->EncryptTunnelMsg (tunnelMsg, tunnelMsg); - FillI2NPMessageHeader (tunnelMsg.get (), eI2NPTunnelData); // TODO: + tunnelMsg->FillI2NPMessageHeader (eI2NPTunnelData); m_NumSentBytes += TUNNEL_DATA_MSG_SIZE; } i2p::transport::transports.SendMessages (m_Tunnel->GetNextIdentHash (), tunnelMsgs); From c5644e0e32d799d59c3de6df1ecbf18598c870ca Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 3 Jul 2015 21:27:40 -0400 Subject: [PATCH 64/67] const I2NP messages --- NetDb.cpp | 20 ++++++++++---------- NetDb.h | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/NetDb.cpp b/NetDb.cpp index dad122a2..39dd6430 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -453,7 +453,7 @@ namespace data } } - void NetDb::HandleDatabaseStoreMsg (std::shared_ptr m) + void NetDb::HandleDatabaseStoreMsg (std::shared_ptr m) { const uint8_t * buf = m->GetPayload (); size_t len = m->GetSize (); @@ -540,9 +540,9 @@ namespace data } } - void NetDb::HandleDatabaseSearchReplyMsg (std::shared_ptr msg) + void NetDb::HandleDatabaseSearchReplyMsg (std::shared_ptr msg) { - uint8_t * buf = msg->GetPayload (); + const uint8_t * buf = msg->GetPayload (); char key[48]; int l = i2p::data::ByteStreamToBase64 (buf, 32, key, 48); key[l] = 0; @@ -611,7 +611,7 @@ namespace data // try responses for (int i = 0; i < num; i++) { - uint8_t * router = buf + 33 + i*32; + const uint8_t * router = buf + 33 + i*32; char peerHash[48]; int l1 = i2p::data::ByteStreamToBase64 (router, 32, peerHash, 48); peerHash[l1] = 0; @@ -629,9 +629,9 @@ namespace data } } - void NetDb::HandleDatabaseLookupMsg (std::shared_ptr msg) + void NetDb::HandleDatabaseLookupMsg (std::shared_ptr msg) { - uint8_t * buf = msg->GetPayload (); + const uint8_t * buf = msg->GetPayload (); IdentHash ident (buf); if (ident.IsZero ()) { @@ -644,7 +644,7 @@ namespace data uint8_t flag = buf[64]; LogPrint ("DatabaseLookup for ", key, " recieved flags=", (int)flag); uint8_t lookupType = flag & DATABASE_LOOKUP_TYPE_FLAGS_MASK; - uint8_t * excluded = buf + 65; + const uint8_t * excluded = buf + 65; uint32_t replyTunnelID = 0; if (flag & DATABASE_LOOKUP_DELIVERY_FLAG) //reply to tunnel { @@ -727,11 +727,11 @@ namespace data // encryption might be used though tunnel only if (flag & DATABASE_LOOKUP_ENCYPTION_FLAG) // encrypted reply requested { - uint8_t * sessionKey = excluded; + const uint8_t * sessionKey = excluded; uint8_t numTags = sessionKey[32]; if (numTags > 0) { - uint8_t * sessionTag = sessionKey + 33; // take first tag + const uint8_t * sessionTag = sessionKey + 33; // take first tag i2p::garlic::GarlicRoutingSession garlic (sessionKey, sessionTag); replyMsg = garlic.WrapSingleMessage (replyMsg); } @@ -890,7 +890,7 @@ namespace data return nullptr; // seems we have too few routers } - void NetDb::PostI2NPMsg (std::shared_ptr msg) + void NetDb::PostI2NPMsg (std::shared_ptr msg) { if (msg) m_Queue.Put (msg); } diff --git a/NetDb.h b/NetDb.h index adeee675..71db2e52 100644 --- a/NetDb.h +++ b/NetDb.h @@ -41,9 +41,9 @@ namespace data void RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete = nullptr); - void HandleDatabaseStoreMsg (std::shared_ptr msg); - void HandleDatabaseSearchReplyMsg (std::shared_ptr msg); - void HandleDatabaseLookupMsg (std::shared_ptr msg); + void HandleDatabaseStoreMsg (std::shared_ptr msg); + void HandleDatabaseSearchReplyMsg (std::shared_ptr msg); + void HandleDatabaseLookupMsg (std::shared_ptr msg); std::shared_ptr GetRandomRouter () const; std::shared_ptr GetRandomRouter (std::shared_ptr compatibleWith) const; @@ -56,7 +56,7 @@ namespace data std::shared_ptr GetClosestNonFloodfill (const IdentHash& destination, const std::set& excluded) const; void SetUnreachable (const IdentHash& ident, bool unreachable); - void PostI2NPMsg (std::shared_ptr msg); + void PostI2NPMsg (std::shared_ptr msg); void Reseed (); @@ -89,7 +89,7 @@ namespace data bool m_IsRunning; std::thread * m_Thread; - i2p::util::Queue > m_Queue; // of I2NPDatabaseStoreMsg + i2p::util::Queue > m_Queue; // of I2NPDatabaseStoreMsg Reseeder * m_Reseeder; From e03f1597a00a89df6efd59103187f3d5cf4b35fe Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 3 Jul 2015 21:50:26 -0400 Subject: [PATCH 65/67] don't send DatabaseStore until time sync complete --- NTCPSession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NTCPSession.cpp b/NTCPSession.cpp index dfd69be9..86418749 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -101,7 +101,7 @@ namespace transport m_DHKeysPair = nullptr; SendTimeSyncMessage (); - Send (ToSharedI2NPMessage(CreateDatabaseStoreMsg ())); // we tell immediately who we are + m_SendQueue.push_back (ToSharedI2NPMessage(CreateDatabaseStoreMsg ())); // we tell immediately who we are transports.PeerConnected (shared_from_this ()); } From 3405ffd8d8fa6aa8cc42517ce6148d535a21d248 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 5 Jul 2015 07:59:38 -0400 Subject: [PATCH 66/67] check for buffer size --- I2NPProtocol.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index f98bdc1c..8fd493f1 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -109,7 +109,7 @@ namespace i2p I2NPMessage * CreateRouterInfoDatabaseLookupMsg (const uint8_t * key, const uint8_t * from, uint32_t replyTunnelID, bool exploratory, std::set * excludedPeers) { - I2NPMessage * m = NewI2NPShortMessage (); + I2NPMessage * m = excludedPeers ? NewI2NPMessage () : NewI2NPShortMessage (); uint8_t * buf = m->GetPayload (); memcpy (buf, key, 32); // key buf += 32; @@ -155,7 +155,8 @@ namespace i2p const std::set& excludedFloodfills, const i2p::tunnel::InboundTunnel * replyTunnel, const uint8_t * replyKey, const uint8_t * replyTag) { - I2NPMessage * m = NewI2NPShortMessage (); + int cnt = excludedFloodfills.size (); + I2NPMessage * m = cnt > 0 ? NewI2NPMessage () : NewI2NPShortMessage (); uint8_t * buf = m->GetPayload (); memcpy (buf, dest, 32); // key buf += 32; @@ -166,7 +167,6 @@ namespace i2p buf += 5; // excluded - int cnt = excludedFloodfills.size (); htobe16buf (buf, cnt); buf += 2; if (cnt > 0) @@ -186,9 +186,7 @@ namespace i2p m->len += (buf - m->GetPayload ()); m->FillI2NPMessageHeader (eI2NPDatabaseLookup); return m; - } - - + } I2NPMessage * CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, std::vector routers) @@ -238,10 +236,18 @@ namespace i2p auto size = compressor.MaxRetrievable (); htobe16buf (buf, size); // size buf += 2; - // TODO: check if size doesn't exceed buffer - compressor.Get (buf, size); - buf += size; m->len += (buf - payload); // payload size + if (m->len + size > m->maxLen) + { + LogPrint (eLogInfo, "DatabaseStore message size is not enough for ", m->len + size); + auto newMsg = NewI2NPMessage (); + *newMsg = *m; + DeleteI2NPMessage (m); + m = newMsg; + buf = m->buf + m->len; + } + compressor.Get (buf, size); + m->len += size; m->FillI2NPMessageHeader (eI2NPDatabaseStore); return m; From 73d402525636276ac78aa92ea88535911e21928c Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 6 Jul 2015 12:11:17 -0400 Subject: [PATCH 67/67] version 0.10.0 --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index d5406b0e..bdff9c2e 100644 --- a/version.h +++ b/version.h @@ -2,7 +2,7 @@ #define _VERSION_H_ #define CODENAME "Purple" -#define VERSION "0.9.0" +#define VERSION "0.10.0" #define I2P_VERSION "0.9.20" #endif