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;