From 79190f313d6014e512ddb665fee1519192b4630f Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 1 Mar 2016 15:22:36 -0500 Subject: [PATCH 01/11] use shared_ptr for transit tunnels --- HTTPServer.cpp | 4 ++-- I2NPProtocol.cpp | 3 +-- TransitTunnel.cpp | 8 ++++---- TransitTunnel.h | 2 +- Tunnel.cpp | 19 ++++++------------- Tunnel.h | 8 ++++---- 6 files changed, 18 insertions(+), 26 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 85dbec42..af9498c3 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -619,9 +619,9 @@ namespace util s << "Transit tunnels:
\r\n
\r\n"; for (auto it: i2p::tunnel::tunnels.GetTransitTunnels ()) { - if (dynamic_cast(it.second)) + if (std::dynamic_pointer_cast(it.second)) s << it.second->GetTunnelID () << " ⇒ "; - else if (dynamic_cast(it.second)) + else if (std::dynamic_pointer_cast(it.second)) s << " ⇒ " << it.second->GetTunnelID (); else s << " ⇒ " << it.second->GetTunnelID () << " ⇒ "; diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index dff66951..7cebf96a 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -301,8 +301,7 @@ namespace i2p i2p::tunnel::tunnels.GetTransitTunnels ().size () <= MAX_NUM_TRANSIT_TUNNELS && !i2p::transport::transports.IsBandwidthExceeded ()) { - i2p::tunnel::TransitTunnel * transitTunnel = - i2p::tunnel::CreateTransitTunnel ( + auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), diff --git a/TransitTunnel.cpp b/TransitTunnel.cpp index 81773bb5..0d54fc11 100644 --- a/TransitTunnel.cpp +++ b/TransitTunnel.cpp @@ -85,7 +85,7 @@ namespace tunnel m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg); } - TransitTunnel * CreateTransitTunnel (uint32_t receiveTunnelID, + std::shared_ptr CreateTransitTunnel (uint32_t receiveTunnelID, const uint8_t * nextIdent, uint32_t nextTunnelID, const uint8_t * layerKey,const uint8_t * ivKey, bool isGateway, bool isEndpoint) @@ -93,17 +93,17 @@ namespace tunnel if (isEndpoint) { LogPrint (eLogInfo, "TransitTunnel: endpoint ", receiveTunnelID, " created"); - return new TransitTunnelEndpoint (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey); + return std::make_shared (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey); } else if (isGateway) { LogPrint (eLogInfo, "TransitTunnel: gateway ", receiveTunnelID, " created"); - return new TransitTunnelGateway (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey); + return std::make_shared (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey); } else { LogPrint (eLogInfo, "TransitTunnel: ", receiveTunnelID, "->", nextTunnelID, " created"); - return new TransitTunnelParticipant (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey); + return std::make_shared (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey); } } } diff --git a/TransitTunnel.h b/TransitTunnel.h index e611d685..2a1908df 100644 --- a/TransitTunnel.h +++ b/TransitTunnel.h @@ -93,7 +93,7 @@ namespace tunnel TunnelEndpoint m_Endpoint; }; - TransitTunnel * CreateTransitTunnel (uint32_t receiveTunnelID, + std::shared_ptr CreateTransitTunnel (uint32_t receiveTunnelID, const uint8_t * nextIdent, uint32_t nextTunnelID, const uint8_t * layerKey,const uint8_t * ivKey, bool isGateway, bool isEndpoint); diff --git a/Tunnel.cpp b/Tunnel.cpp index f7102327..715a10f9 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -257,9 +257,6 @@ namespace tunnel Tunnels::~Tunnels () { - for (auto& it : m_TransitTunnels) - delete it.second; - m_TransitTunnels.clear (); } std::shared_ptr Tunnels::GetInboundTunnel (uint32_t tunnelID) @@ -270,7 +267,7 @@ namespace tunnel return nullptr; } - TransitTunnel * Tunnels::GetTransitTunnel (uint32_t tunnelID) + std::shared_ptr Tunnels::GetTransitTunnel (uint32_t tunnelID) { auto it = m_TransitTunnels.find(tunnelID); if (it != m_TransitTunnels.end ()) @@ -363,14 +360,11 @@ namespace tunnel } } - void Tunnels::AddTransitTunnel (TransitTunnel * tunnel) + void Tunnels::AddTransitTunnel (std::shared_ptr tunnel) { std::unique_lock l(m_TransitTunnelsMutex); if (!m_TransitTunnels.insert (std::make_pair (tunnel->GetTunnelID (), tunnel)).second) - { LogPrint (eLogError, "Tunnel: transit tunnel with id ", tunnel->GetTunnelID (), " already exists"); - delete tunnel; - } } void Tunnels::Start () @@ -404,10 +398,10 @@ namespace tunnel if (msg) { uint32_t prevTunnelID = 0, tunnelID = 0; - TunnelBase * prevTunnel = nullptr; + std::shared_ptr prevTunnel; do { - TunnelBase * tunnel = nullptr; + std::shared_ptr tunnel; uint8_t typeID = msg->GetTypeID (); switch (typeID) { @@ -421,7 +415,7 @@ namespace tunnel prevTunnel->FlushTunnelDataMsgs (); if (!tunnel && typeID == eI2NPTunnelData) - tunnel = GetInboundTunnel (tunnelID).get (); + tunnel = GetInboundTunnel (tunnelID); if (!tunnel) tunnel = GetTransitTunnel (tunnelID); if (tunnel) @@ -471,7 +465,7 @@ namespace tunnel } } - void Tunnels::HandleTunnelGatewayMsg (TunnelBase * tunnel, std::shared_ptr msg) + void Tunnels::HandleTunnelGatewayMsg (std::shared_ptr tunnel, std::shared_ptr msg) { if (!tunnel) { @@ -690,7 +684,6 @@ namespace tunnel std::unique_lock l(m_TransitTunnelsMutex); it = m_TransitTunnels.erase (it); } - delete tmp; } else it++; diff --git a/Tunnel.h b/Tunnel.h index 138a48fc..d37646d1 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -142,9 +142,9 @@ namespace tunnel std::shared_ptr GetNextInboundTunnel (); std::shared_ptr GetNextOutboundTunnel (); std::shared_ptr GetExploratoryPool () const { return m_ExploratoryPool; }; - TransitTunnel * GetTransitTunnel (uint32_t tunnelID); + std::shared_ptr GetTransitTunnel (uint32_t tunnelID); int GetTransitTunnelsExpirationTimeout (); - void AddTransitTunnel (TransitTunnel * tunnel); + void AddTransitTunnel (std::shared_ptr tunnel); void AddOutboundTunnel (std::shared_ptr newTunnel); void AddInboundTunnel (std::shared_ptr newTunnel); void PostTunnelData (std::shared_ptr msg); @@ -163,7 +163,7 @@ namespace tunnel template std::shared_ptr GetPendingTunnel (uint32_t replyMsgID, const std::map >& pendingTunnels); - void HandleTunnelGatewayMsg (TunnelBase * tunnel, std::shared_ptr msg); + void HandleTunnelGatewayMsg (std::shared_ptr tunnel, std::shared_ptr msg); void Run (); void ManageTunnels (); @@ -186,7 +186,7 @@ namespace tunnel std::map > m_InboundTunnels; std::list > m_OutboundTunnels; std::mutex m_TransitTunnelsMutex; - std::map m_TransitTunnels; + std::map > m_TransitTunnels; std::mutex m_PoolsMutex; std::list> m_Pools; std::shared_ptr m_ExploratoryPool; From 9403fbaf818dffb14768a512e7c29cdfd9e2e351 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 1 Mar 2016 20:48:56 -0500 Subject: [PATCH 02/11] common tunnels' hash table --- HTTPServer.cpp | 12 ++++----- Tunnel.cpp | 73 +++++++++++++++++++++++++++----------------------- Tunnel.h | 7 ++--- 3 files changed, 49 insertions(+), 43 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index af9498c3..87982044 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -619,13 +619,13 @@ namespace util s << "Transit tunnels:
\r\n
\r\n"; for (auto it: i2p::tunnel::tunnels.GetTransitTunnels ()) { - if (std::dynamic_pointer_cast(it.second)) - s << it.second->GetTunnelID () << " ⇒ "; - else if (std::dynamic_pointer_cast(it.second)) - s << " ⇒ " << it.second->GetTunnelID (); + if (std::dynamic_pointer_cast(it)) + s << it->GetTunnelID () << " ⇒ "; + else if (std::dynamic_pointer_cast(it)) + s << " ⇒ " << it->GetTunnelID (); else - s << " ⇒ " << it.second->GetTunnelID () << " ⇒ "; - s << " " << it.second->GetNumTransmittedBytes () << "
\r\n"; + s << " ⇒ " << it->GetTunnelID () << " ⇒ "; + s << " " << it->GetNumTransmittedBytes () << "
\r\n"; } } diff --git a/Tunnel.cpp b/Tunnel.cpp index 715a10f9..95d2f698 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -266,15 +266,15 @@ namespace tunnel return it->second; return nullptr; } - - std::shared_ptr Tunnels::GetTransitTunnel (uint32_t tunnelID) + + std::shared_ptr Tunnels::GetTunnel (uint32_t tunnelID) { - auto it = m_TransitTunnels.find(tunnelID); - if (it != m_TransitTunnels.end ()) + auto it = m_Tunnels.find(tunnelID); + if (it != m_Tunnels.end ()) return it->second; return nullptr; } - + std::shared_ptr Tunnels::GetPendingInboundTunnel (uint32_t replyMsgID) { return GetPendingTunnel (replyMsgID, m_PendingInboundTunnels); @@ -362,9 +362,10 @@ namespace tunnel void Tunnels::AddTransitTunnel (std::shared_ptr tunnel) { - std::unique_lock l(m_TransitTunnelsMutex); - if (!m_TransitTunnels.insert (std::make_pair (tunnel->GetTunnelID (), tunnel)).second) - LogPrint (eLogError, "Tunnel: transit tunnel with id ", tunnel->GetTunnelID (), " already exists"); + if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second) + m_TransitTunnels.push_back (tunnel); + else + LogPrint (eLogError, "Tunnel: tunnel with id ", tunnel->GetTunnelID (), " already exists"); } void Tunnels::Start () @@ -414,10 +415,8 @@ namespace tunnel else if (prevTunnel) prevTunnel->FlushTunnelDataMsgs (); - if (!tunnel && typeID == eI2NPTunnelData) - tunnel = GetInboundTunnel (tunnelID); if (!tunnel) - tunnel = GetTransitTunnel (tunnelID); + tunnel = GetTunnel (tunnelID); if (tunnel) { if (typeID == eI2NPTunnelData) @@ -574,6 +573,7 @@ namespace tunnel auto pool = tunnel->GetTunnelPool (); if (pool) pool->TunnelExpired (tunnel); + // we don't have outbound tunnels in m_Tunnels it = m_OutboundTunnels.erase (it); } else @@ -622,6 +622,7 @@ namespace tunnel auto pool = tunnel->GetTunnelPool (); if (pool) pool->TunnelExpired (tunnel); + m_Tunnels.erase (tunnel->GetTunnelID ()); it = m_InboundTunnels.erase (it); } else @@ -676,14 +677,12 @@ namespace tunnel uint32_t ts = i2p::util::GetSecondsSinceEpoch (); for (auto it = m_TransitTunnels.begin (); it != m_TransitTunnels.end ();) { - if (ts > it->second->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) + auto tunnel = *it; + if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) { - auto tmp = it->second; - LogPrint (eLogDebug, "Tunnel: Transit tunnel with id ", tmp->GetTunnelID (), " expired"); - { - std::unique_lock l(m_TransitTunnelsMutex); - it = m_TransitTunnels.erase (it); - } + LogPrint (eLogDebug, "Tunnel: Transit tunnel with id ", tunnel->GetTunnelID (), " expired"); + m_Tunnels.erase (tunnel->GetTunnelID ()); + it = m_TransitTunnels.erase (it); } else it++; @@ -737,6 +736,7 @@ namespace tunnel void Tunnels::AddOutboundTunnel (std::shared_ptr newTunnel) { + // we don't need to insert it to m_Tunnels m_OutboundTunnels.push_back (newTunnel); auto pool = newTunnel->GetTunnelPool (); if (pool && pool->IsActive ()) @@ -747,22 +747,27 @@ namespace tunnel void Tunnels::AddInboundTunnel (std::shared_ptr newTunnel) { - m_InboundTunnels[newTunnel->GetTunnelID ()] = newTunnel; - auto pool = newTunnel->GetTunnelPool (); - if (!pool) - { - // build symmetric outbound tunnel - CreateTunnel (std::make_shared(newTunnel->GetInvertedPeers (), - newTunnel->GetNextTunnelID (), newTunnel->GetNextIdentHash ()), - GetNextOutboundTunnel ()); + if (m_Tunnels.emplace (newTunnel->GetTunnelID (), newTunnel).second) + { + m_InboundTunnels[newTunnel->GetTunnelID ()] = newTunnel; + auto pool = newTunnel->GetTunnelPool (); + if (!pool) + { + // build symmetric outbound tunnel + CreateTunnel (std::make_shared(newTunnel->GetInvertedPeers (), + newTunnel->GetNextTunnelID (), newTunnel->GetNextIdentHash ()), + GetNextOutboundTunnel ()); + } + else + { + if (pool->IsActive ()) + pool->TunnelCreated (newTunnel); + else + newTunnel->SetTunnelPool (nullptr); + } } else - { - if (pool->IsActive ()) - pool->TunnelCreated (newTunnel); - else - newTunnel->SetTunnelPool (nullptr); - } + LogPrint (eLogError, "Tunnel: tunnel with id ", newTunnel->GetTunnelID (), " already exists"); } @@ -779,10 +784,10 @@ namespace tunnel { int timeout = 0; uint32_t ts = i2p::util::GetSecondsSinceEpoch (); - std::unique_lock l(m_TransitTunnelsMutex); + // TODO: possible race condition with I2PControl for (auto it: m_TransitTunnels) { - int t = it.second->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT - ts; + int t = it->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT - ts; if (t > timeout) timeout = t; } return timeout; diff --git a/Tunnel.h b/Tunnel.h index d37646d1..ca74c707 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -142,7 +143,7 @@ namespace tunnel std::shared_ptr GetNextInboundTunnel (); std::shared_ptr GetNextOutboundTunnel (); std::shared_ptr GetExploratoryPool () const { return m_ExploratoryPool; }; - std::shared_ptr GetTransitTunnel (uint32_t tunnelID); + std::shared_ptr GetTunnel (uint32_t tunnelID); int GetTransitTunnelsExpirationTimeout (); void AddTransitTunnel (std::shared_ptr tunnel); void AddOutboundTunnel (std::shared_ptr newTunnel); @@ -185,8 +186,8 @@ namespace tunnel std::map > m_PendingOutboundTunnels; // by replyMsgID std::map > m_InboundTunnels; std::list > m_OutboundTunnels; - std::mutex m_TransitTunnelsMutex; - std::map > m_TransitTunnels; + std::list > m_TransitTunnels; + std::unordered_map > m_Tunnels; // tunnelID->tunnel known by this id std::mutex m_PoolsMutex; std::list> m_Pools; std::shared_ptr m_ExploratoryPool; From eb96ead80e871320885dd916847b0ca97f9399da Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 2 Mar 2016 09:41:37 -0500 Subject: [PATCH 03/11] add tunnel counts to front page of web ui --- HTTPServer.cpp | 7 +++++++ Tunnel.cpp | 17 ++++++++++++++++- Tunnel.h | 5 +++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 85dbec42..e218117a 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -447,6 +447,13 @@ namespace util s << "
\r\nRouters: " << i2p::data::netdb.GetNumRouters () << " "; s << "Floodfills: " << i2p::data::netdb.GetNumFloodfills () << " "; s << "LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "
\r\n"; + + size_t clientTunnelCount = i2p::tunnel::tunnels.CountOutboundTunnels(); + clientTunnelCount += i2p::tunnel::tunnels.CountInboundTunnels(); + size_t transitTunnelCount = i2p::tunnel::tunnels.CountTransitTunnels(); + + s << "Client Tunnels " << std::to_string(clientTunnelCount) << " "; + s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n"; } void HTTPConnection::HandleCommand (const std::string& command, std::stringstream& s) diff --git a/Tunnel.cpp b/Tunnel.cpp index f7102327..ee3b7119 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -793,7 +793,22 @@ namespace tunnel if (t > timeout) timeout = t; } return timeout; - } + } + + size_t Tunnels::CountTransitTunnels() { + // TODO: locking + return m_TransitTunnels.size(); + } + + size_t Tunnels::CountInboundTunnels() { + // TODO: locking + return m_InboundTunnels.size(); + } + + size_t Tunnels::CountOutboundTunnels() { + // TODO: locking + return m_OutboundTunnels.size(); + } } } diff --git a/Tunnel.h b/Tunnel.h index 138a48fc..f3bcc127 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -201,6 +201,11 @@ namespace tunnel const decltype(m_OutboundTunnels)& GetOutboundTunnels () const { return m_OutboundTunnels; }; const decltype(m_InboundTunnels)& GetInboundTunnels () const { return m_InboundTunnels; }; const decltype(m_TransitTunnels)& GetTransitTunnels () const { return m_TransitTunnels; }; + + size_t CountTransitTunnels(); + size_t CountInboundTunnels(); + size_t CountOutboundTunnels(); + int GetQueueSize () { return m_Queue.GetSize (); }; int GetTunnelCreationSuccessRate () const // in percents { From 9378668e52d1e02e304a02db29b96cb49428d912 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 2 Mar 2016 09:58:17 -0500 Subject: [PATCH 04/11] add colin --- HTTPServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index e218117a..39109dba 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -452,7 +452,7 @@ namespace util clientTunnelCount += i2p::tunnel::tunnels.CountInboundTunnels(); size_t transitTunnelCount = i2p::tunnel::tunnels.CountTransitTunnels(); - s << "Client Tunnels " << std::to_string(clientTunnelCount) << " "; + s << "Client Tunnels: " << std::to_string(clientTunnelCount) << " "; s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n"; } From 1dc6cec1aa72ac85eeeaaee8189ff68126d17193 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 2 Mar 2016 10:05:26 -0500 Subject: [PATCH 05/11] add client/transit tunnel count in webui --- HTTPServer.cpp | 12 ++++++------ Tunnel.cpp | 28 ++++++++++++++-------------- Tunnel.h | 8 ++++---- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 39109dba..128b3ad6 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -448,12 +448,12 @@ namespace util s << "Floodfills: " << i2p::data::netdb.GetNumFloodfills () << " "; s << "LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "
\r\n"; - size_t clientTunnelCount = i2p::tunnel::tunnels.CountOutboundTunnels(); - clientTunnelCount += i2p::tunnel::tunnels.CountInboundTunnels(); - size_t transitTunnelCount = i2p::tunnel::tunnels.CountTransitTunnels(); - - s << "Client Tunnels: " << std::to_string(clientTunnelCount) << " "; - s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n"; + size_t clientTunnelCount = i2p::tunnel::tunnels.CountOutboundTunnels(); + clientTunnelCount += i2p::tunnel::tunnels.CountInboundTunnels(); + size_t transitTunnelCount = i2p::tunnel::tunnels.CountTransitTunnels(); + + s << "Client Tunnels: " << std::to_string(clientTunnelCount) << " "; + s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n"; } void HTTPConnection::HandleCommand (const std::string& command, std::stringstream& s) diff --git a/Tunnel.cpp b/Tunnel.cpp index ee3b7119..f235d321 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -795,20 +795,20 @@ namespace tunnel return timeout; } - size_t Tunnels::CountTransitTunnels() { - // TODO: locking - return m_TransitTunnels.size(); - } - - size_t Tunnels::CountInboundTunnels() { - // TODO: locking - return m_InboundTunnels.size(); - } - - size_t Tunnels::CountOutboundTunnels() { - // TODO: locking - return m_OutboundTunnels.size(); - } + size_t Tunnels::CountTransitTunnels() { + // TODO: locking + return m_TransitTunnels.size(); + } + + size_t Tunnels::CountInboundTunnels() { + // TODO: locking + return m_InboundTunnels.size(); + } + + size_t Tunnels::CountOutboundTunnels() { + // TODO: locking + return m_OutboundTunnels.size(); + } } } diff --git a/Tunnel.h b/Tunnel.h index f3bcc127..ea68f1c3 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -202,10 +202,10 @@ namespace tunnel const decltype(m_InboundTunnels)& GetInboundTunnels () const { return m_InboundTunnels; }; const decltype(m_TransitTunnels)& GetTransitTunnels () const { return m_TransitTunnels; }; - size_t CountTransitTunnels(); - size_t CountInboundTunnels(); - size_t CountOutboundTunnels(); - + size_t CountTransitTunnels(); + size_t CountInboundTunnels(); + size_t CountOutboundTunnels(); + int GetQueueSize () { return m_Queue.GetSize (); }; int GetTunnelCreationSuccessRate () const // in percents { From ef6028e933df2ec2ca32f9dec91a0ac6b69b251c Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 2 Mar 2016 11:58:52 -0500 Subject: [PATCH 06/11] replace std::map to std::list for inbound tunnels --- HTTPServer.cpp | 6 +++--- Tunnel.cpp | 29 ++++++++++++----------------- Tunnel.h | 9 ++++----- 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 2124ea87..3b92d4bc 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -610,13 +610,13 @@ namespace util for (auto it: i2p::tunnel::tunnels.GetInboundTunnels ()) { - it.second->Print (s); - auto state = it.second->GetState (); + it->Print (s); + auto state = it->GetState (); if (state == i2p::tunnel::eTunnelStateFailed) s << " " << "Failed"; else if (state == i2p::tunnel::eTunnelStateExpiring) s << " " << "Exp"; - s << " " << (int)it.second->GetNumReceivedBytes () << "
\r\n"; + s << " " << (int)it->GetNumReceivedBytes () << "
\r\n"; s << std::endl; } } diff --git a/Tunnel.cpp b/Tunnel.cpp index 91b8d077..f2521217 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -258,14 +258,6 @@ namespace tunnel Tunnels::~Tunnels () { } - - std::shared_ptr Tunnels::GetInboundTunnel (uint32_t tunnelID) - { - auto it = m_InboundTunnels.find(tunnelID); - if (it != m_InboundTunnels.end ()) - return it->second; - return nullptr; - } std::shared_ptr Tunnels::GetTunnel (uint32_t tunnelID) { @@ -303,11 +295,11 @@ namespace tunnel size_t minReceived = 0; for (auto it : m_InboundTunnels) { - if (!it.second->IsEstablished ()) continue; - if (!tunnel || it.second->GetNumReceivedBytes () < minReceived) + if (!it->IsEstablished ()) continue; + if (!tunnel || it->GetNumReceivedBytes () < minReceived) { - tunnel = it.second; - minReceived = it.second->GetNumReceivedBytes (); + tunnel = it; + minReceived = it->GetNumReceivedBytes (); } } return tunnel; @@ -615,7 +607,7 @@ namespace tunnel { for (auto it = m_InboundTunnels.begin (); it != m_InboundTunnels.end ();) { - auto tunnel = it->second; + auto tunnel = *it; if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) { LogPrint (eLogDebug, "Tunnel: tunnel with id ", tunnel->GetTunnelID (), " expired"); @@ -749,7 +741,7 @@ namespace tunnel { if (m_Tunnels.emplace (newTunnel->GetTunnelID (), newTunnel).second) { - m_InboundTunnels[newTunnel->GetTunnelID ()] = newTunnel; + m_InboundTunnels.push_back (newTunnel); auto pool = newTunnel->GetTunnelPool (); if (!pool) { @@ -793,17 +785,20 @@ namespace tunnel return timeout; } - size_t Tunnels::CountTransitTunnels() { + size_t Tunnels::CountTransitTunnels() const + { // TODO: locking return m_TransitTunnels.size(); } - size_t Tunnels::CountInboundTunnels() { + size_t Tunnels::CountInboundTunnels() const + { // TODO: locking return m_InboundTunnels.size(); } - size_t Tunnels::CountOutboundTunnels() { + size_t Tunnels::CountOutboundTunnels() const + { // TODO: locking return m_OutboundTunnels.size(); } diff --git a/Tunnel.h b/Tunnel.h index 11b50eab..c02eb966 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -137,7 +137,6 @@ namespace tunnel void Start (); void Stop (); - std::shared_ptr GetInboundTunnel (uint32_t tunnelID); std::shared_ptr GetPendingInboundTunnel (uint32_t replyMsgID); std::shared_ptr GetPendingOutboundTunnel (uint32_t replyMsgID); std::shared_ptr GetNextInboundTunnel (); @@ -184,7 +183,7 @@ namespace tunnel std::thread * m_Thread; std::map > m_PendingInboundTunnels; // by replyMsgID std::map > m_PendingOutboundTunnels; // by replyMsgID - std::map > m_InboundTunnels; + std::list > m_InboundTunnels; std::list > m_OutboundTunnels; std::list > m_TransitTunnels; std::unordered_map > m_Tunnels; // tunnelID->tunnel known by this id @@ -203,9 +202,9 @@ namespace tunnel const decltype(m_InboundTunnels)& GetInboundTunnels () const { return m_InboundTunnels; }; const decltype(m_TransitTunnels)& GetTransitTunnels () const { return m_TransitTunnels; }; - size_t CountTransitTunnels(); - size_t CountInboundTunnels(); - size_t CountOutboundTunnels(); + size_t CountTransitTunnels() const; + size_t CountInboundTunnels() const; + size_t CountOutboundTunnels() const; int GetQueueSize () { return m_Queue.GetSize (); }; int GetTunnelCreationSuccessRate () const // in percents From 81b72d54818814e47446889f0a4fb34adfa6df4b Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 2 Mar 2016 12:04:02 -0500 Subject: [PATCH 07/11] fixed crash on termination if proxies were excluded --- ClientContext.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/ClientContext.cpp b/ClientContext.cpp index ea459a13..2cdd3ae9 100644 --- a/ClientContext.cpp +++ b/ClientContext.cpp @@ -100,15 +100,21 @@ namespace client void ClientContext::Stop () { - LogPrint(eLogInfo, "Clients: stopping HTTP Proxy"); - m_HttpProxy->Stop(); - delete m_HttpProxy; - m_HttpProxy = nullptr; + if (m_HttpProxy) + { + LogPrint(eLogInfo, "Clients: stopping HTTP Proxy"); + m_HttpProxy->Stop(); + delete m_HttpProxy; + m_HttpProxy = nullptr; + } - LogPrint(eLogInfo, "Clients: stopping SOCKS Proxy"); - m_SocksProxy->Stop(); - delete m_SocksProxy; - m_SocksProxy = nullptr; + if (m_SocksProxy) + { + LogPrint(eLogInfo, "Clients: stopping SOCKS Proxy"); + m_SocksProxy->Stop(); + delete m_SocksProxy; + m_SocksProxy = nullptr; + } for (auto& it: m_ClientTunnels) { From fa67e907673c12b23a97290bb9db8432e6770f68 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 2 Mar 2016 16:12:02 -0500 Subject: [PATCH 08/11] inbound zero-hops tunnel --- Tunnel.cpp | 6 ++++++ Tunnel.h | 1 + TunnelConfig.h | 35 ++++++++++++++++++++++++++++------- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/Tunnel.cpp b/Tunnel.cpp index f2521217..92b20cdd 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -200,6 +200,12 @@ namespace tunnel m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg); } + void InboundTunnel::SendTunnelDataMsg (std::shared_ptr msg) + { + // assume zero-hops tunnel + m_Endpoint.HandleDecryptedTunnelDataMsg (msg); + } + void InboundTunnel::Print (std::stringstream& s) const { PrintHops (s); diff --git a/Tunnel.h b/Tunnel.h index c02eb966..c41d53b2 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -119,6 +119,7 @@ namespace tunnel InboundTunnel (std::shared_ptr config): Tunnel (config), m_Endpoint (true) {}; void HandleTunnelDataMsg (std::shared_ptr msg); + void SendTunnelDataMsg (std::shared_ptr msg); // for zero-hops only size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); }; void Print (std::stringstream& s) const; diff --git a/TunnelConfig.h b/TunnelConfig.h index 826979c8..ac493f24 100644 --- a/TunnelConfig.h +++ b/TunnelConfig.h @@ -108,7 +108,7 @@ namespace tunnel } }; - class TunnelConfig: public std::enable_shared_from_this + class TunnelConfig { public: @@ -160,26 +160,26 @@ namespace tunnel return num; } - bool IsInbound () const { return m_FirstHop->isGateway; } + virtual bool IsInbound () const { return m_FirstHop->isGateway; } - uint32_t GetTunnelID () const + virtual uint32_t GetTunnelID () const { if (!m_FirstHop) return 0; return IsInbound () ? m_LastHop->nextTunnelID : m_FirstHop->tunnelID; } - uint32_t GetNextTunnelID () const + virtual uint32_t GetNextTunnelID () const { if (!m_FirstHop) return 0; return m_FirstHop->tunnelID; } - const i2p::data::IdentHash& GetNextIdentHash () const + virtual const i2p::data::IdentHash& GetNextIdentHash () const { return m_FirstHop->ident->GetIdentHash (); } - const i2p::data::IdentHash& GetLastIdentHash () const + virtual const i2p::data::IdentHash& GetLastIdentHash () const { return m_LastHop->ident->GetIdentHash (); } @@ -196,12 +196,14 @@ namespace tunnel return peers; } - private: + protected: // this constructor can't be called from outside TunnelConfig (): m_FirstHop (nullptr), m_LastHop (nullptr) { } + + private: template void CreatePeers (const Peers& peers) @@ -222,6 +224,25 @@ namespace tunnel private: TunnelHopConfig * m_FirstHop, * m_LastHop; + }; + + class ZeroHopTunnelConfig: public TunnelConfig + { + public: + + ZeroHopTunnelConfig (uint32_t tunnelID = 0): // 0 means outbound + m_TunnelID (tunnelID) {}; + + bool IsInbound () const { return m_TunnelID; }; + uint32_t GetTunnelID () const { return m_TunnelID; }; + uint32_t GetNextTunnelID () const { return m_TunnelID; }; + const i2p::data::IdentHash& GetNextIdentHash () const { return i2p::context.GetIdentHash (); }; + const i2p::data::IdentHash& GetLastIdentHash () const { return i2p::context.GetIdentHash (); }; + + + private: + + uint32_t m_TunnelID; }; } } From ecfdc377ec8b1ad2ff5bf7f5a3c6989ad3af2c09 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 2 Mar 2016 19:46:32 -0500 Subject: [PATCH 09/11] send close floodfills only in DatabaseSearchReply --- NetDb.cpp | 11 +++++++---- NetDb.h | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/NetDb.cpp b/NetDb.cpp index 501852bb..eb1380de 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -677,7 +677,7 @@ namespace data excludedRouters.insert (excluded); excluded += 32; } - replyMsg = CreateDatabaseSearchReply (ident, GetClosestFloodfills (ident, 3, excludedRouters)); + replyMsg = CreateDatabaseSearchReply (ident, GetClosestFloodfills (ident, 3, excludedRouters, true)); } } @@ -884,7 +884,7 @@ namespace data } std::vector NetDb::GetClosestFloodfills (const IdentHash& destination, size_t num, - std::set& excluded) const + std::set& excluded, bool closeThanUsOnly) const { struct Sorted { @@ -895,6 +895,8 @@ namespace data std::set sorted; IdentHash destKey = CreateRoutingKey (destination); + XORMetric ourMetric; + if (closeThanUsOnly) ourMetric = destKey ^ i2p::context.GetIdentHash (); { std::unique_lock l(m_FloodfillsMutex); for (auto it: m_Floodfills) @@ -902,6 +904,7 @@ namespace data if (!it->IsUnreachable ()) { XORMetric m = destKey ^ it->GetIdentHash (); + if (closeThanUsOnly && ourMetric < m) continue; if (sorted.size () < num) sorted.insert ({it, m}); else if (m < sorted.rbegin ()->metric) @@ -960,9 +963,9 @@ namespace data auto ts = i2p::util::GetMillisecondsSinceEpoch (); for (auto it = m_LeaseSets.begin (); it != m_LeaseSets.end ();) { - if (ts > it->second->GetExpirationTime ()) + if (ts > it->second->GetExpirationTime () - LEASE_ENDDATE_THRESHOLD) { - LogPrint (eLogWarning, "NetDb: LeaseSet ", it->second->GetIdentHash ().ToBase64 (), " expired"); + LogPrint (eLogInfo, "NetDb: LeaseSet ", it->second->GetIdentHash ().ToBase64 (), " expired"); it = m_LeaseSets.erase (it); } else diff --git a/NetDb.h b/NetDb.h index 7b196330..536ff644 100644 --- a/NetDb.h +++ b/NetDb.h @@ -60,7 +60,7 @@ namespace data std::shared_ptr GetRandomIntroducer () const; std::shared_ptr GetClosestFloodfill (const IdentHash& destination, const std::set& excluded, bool closeThanUsOnly = false) const; std::vector GetClosestFloodfills (const IdentHash& destination, size_t num, - std::set& excluded) const; + std::set& excluded, bool closeThanUsOnly = false) const; std::shared_ptr GetClosestNonFloodfill (const IdentHash& destination, const std::set& excluded) const; void SetUnreachable (const IdentHash& ident, bool unreachable); From d541572882664b5be416bb3e1d37be16619d69b8 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 2 Mar 2016 22:41:53 -0500 Subject: [PATCH 10/11] enable zero-hops inbound tunnel --- Tunnel.cpp | 34 +++++++++++++++++++++++++++------- Tunnel.h | 15 ++++++++++++--- TunnelConfig.h | 7 +++---- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/Tunnel.cpp b/Tunnel.cpp index 92b20cdd..feaaddc4 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -200,15 +200,25 @@ namespace tunnel m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg); } - void InboundTunnel::SendTunnelDataMsg (std::shared_ptr msg) + void InboundTunnel::Print (std::stringstream& s) const + { + PrintHops (s); + s << " ⇒ " << GetTunnelID () << ":me"; + } + + ZeroHopsInboundTunnel::ZeroHopsInboundTunnel (): + InboundTunnel (std::make_shared ()) + { + } + + void ZeroHopsInboundTunnel::SendTunnelDataMsg (std::shared_ptr msg) { - // assume zero-hops tunnel + msg->from = shared_from_this (); m_Endpoint.HandleDecryptedTunnelDataMsg (msg); - } + } - void InboundTunnel::Print (std::stringstream& s) const + void ZeroHopsInboundTunnel::Print (std::stringstream& s) const { - PrintHops (s); s << " ⇒ " << GetTunnelID () << ":me"; } @@ -771,11 +781,21 @@ namespace tunnel void Tunnels::CreateZeroHopsInboundTunnel () { - CreateTunnel ( + /*CreateTunnel ( + std::make_shared (std::vector > + { + i2p::context.GetIdentity () + }));*/ + auto inboundTunnel = std::make_shared (); + m_InboundTunnels.push_back (inboundTunnel); + m_Tunnels[inboundTunnel->GetTunnelID ()] = inboundTunnel; + + // create paired outbound tunnel, TODO: move to separate function + CreateTunnel ( std::make_shared (std::vector > { i2p::context.GetIdentity () - })); + }, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ())); } int Tunnels::GetTransitTunnelsExpirationTimeout () diff --git a/Tunnel.h b/Tunnel.h index c41d53b2..7fa22a63 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -72,6 +72,8 @@ namespace tunnel void SetTunnelPool (std::shared_ptr pool) { m_Pool = pool; }; bool HandleTunnelBuildResponse (uint8_t * msg, size_t len); + + virtual void Print (std::stringstream& s) const {}; // implements TunnelBase void SendTunnelDataMsg (std::shared_ptr msg); @@ -112,22 +114,29 @@ namespace tunnel TunnelGateway m_Gateway; i2p::data::IdentHash m_EndpointIdentHash; }; - + class InboundTunnel: public Tunnel, public std::enable_shared_from_this { public: InboundTunnel (std::shared_ptr config): Tunnel (config), m_Endpoint (true) {}; void HandleTunnelDataMsg (std::shared_ptr msg); - void SendTunnelDataMsg (std::shared_ptr msg); // for zero-hops only size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); }; void Print (std::stringstream& s) const; - private: + protected: TunnelEndpoint m_Endpoint; }; + + class ZeroHopsInboundTunnel: public InboundTunnel + { + public: + ZeroHopsInboundTunnel (); + void SendTunnelDataMsg (std::shared_ptr msg); + void Print (std::stringstream& s) const; + }; class Tunnels { diff --git a/TunnelConfig.h b/TunnelConfig.h index ac493f24..c089b13c 100644 --- a/TunnelConfig.h +++ b/TunnelConfig.h @@ -226,14 +226,13 @@ namespace tunnel TunnelHopConfig * m_FirstHop, * m_LastHop; }; - class ZeroHopTunnelConfig: public TunnelConfig + class ZeroHopsTunnelConfig: public TunnelConfig { public: - ZeroHopTunnelConfig (uint32_t tunnelID = 0): // 0 means outbound - m_TunnelID (tunnelID) {}; + ZeroHopsTunnelConfig () { RAND_bytes ((uint8_t *)&m_TunnelID, 4);}; - bool IsInbound () const { return m_TunnelID; }; + bool IsInbound () const { return true; }; // TODO: uint32_t GetTunnelID () const { return m_TunnelID; }; uint32_t GetNextTunnelID () const { return m_TunnelID; }; const i2p::data::IdentHash& GetNextIdentHash () const { return i2p::context.GetIdentHash (); }; From 0f56b1c9438175c73959388e1dbe366c00fec30d Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 3 Mar 2016 07:30:38 -0500 Subject: [PATCH 11/11] show number of received bytes for zero-hops inbound tunnel --- Tunnel.cpp | 10 +++++++--- Tunnel.h | 9 +++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Tunnel.cpp b/Tunnel.cpp index feaaddc4..37dd6d67 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -207,14 +207,18 @@ namespace tunnel } ZeroHopsInboundTunnel::ZeroHopsInboundTunnel (): - InboundTunnel (std::make_shared ()) + InboundTunnel (std::make_shared ()), + m_NumReceivedBytes (0) { } void ZeroHopsInboundTunnel::SendTunnelDataMsg (std::shared_ptr msg) { - msg->from = shared_from_this (); - m_Endpoint.HandleDecryptedTunnelDataMsg (msg); + if (msg) + { + m_NumReceivedBytes += msg->GetLength (); + HandleI2NPMessage (msg); + } } void ZeroHopsInboundTunnel::Print (std::stringstream& s) const diff --git a/Tunnel.h b/Tunnel.h index 7fa22a63..34d0a0ab 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -121,10 +121,10 @@ namespace tunnel InboundTunnel (std::shared_ptr config): Tunnel (config), m_Endpoint (true) {}; void HandleTunnelDataMsg (std::shared_ptr msg); - size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); }; + virtual size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); }; void Print (std::stringstream& s) const; - protected: + private: TunnelEndpoint m_Endpoint; }; @@ -136,6 +136,11 @@ namespace tunnel ZeroHopsInboundTunnel (); void SendTunnelDataMsg (std::shared_ptr msg); void Print (std::stringstream& s) const; + size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; }; + + private: + + size_t m_NumReceivedBytes; }; class Tunnels