Browse Source

Merge pull request #401 from PurpleI2P/openssl

recent changes
pull/405/merge
orignal 9 years ago
parent
commit
bf3615fb32
  1. 22
      ClientContext.cpp
  2. 25
      HTTPServer.cpp
  3. 3
      I2NPProtocol.cpp
  4. 11
      NetDb.cpp
  5. 2
      NetDb.h
  6. 8
      TransitTunnel.cpp
  7. 2
      TransitTunnel.h
  8. 152
      Tunnel.cpp
  9. 36
      Tunnel.h
  10. 34
      TunnelConfig.h

22
ClientContext.cpp

@ -100,15 +100,21 @@ namespace client
void ClientContext::Stop () void ClientContext::Stop ()
{ {
LogPrint(eLogInfo, "Clients: stopping HTTP Proxy"); if (m_HttpProxy)
m_HttpProxy->Stop(); {
delete m_HttpProxy; LogPrint(eLogInfo, "Clients: stopping HTTP Proxy");
m_HttpProxy = nullptr; m_HttpProxy->Stop();
delete m_HttpProxy;
m_HttpProxy = nullptr;
}
LogPrint(eLogInfo, "Clients: stopping SOCKS Proxy"); if (m_SocksProxy)
m_SocksProxy->Stop(); {
delete m_SocksProxy; LogPrint(eLogInfo, "Clients: stopping SOCKS Proxy");
m_SocksProxy = nullptr; m_SocksProxy->Stop();
delete m_SocksProxy;
m_SocksProxy = nullptr;
}
for (auto& it: m_ClientTunnels) for (auto& it: m_ClientTunnels)
{ {

25
HTTPServer.cpp

@ -447,6 +447,13 @@ namespace util
s << "<br>\r\n<b>Routers:</b> " << i2p::data::netdb.GetNumRouters () << " "; s << "<br>\r\n<b>Routers:</b> " << i2p::data::netdb.GetNumRouters () << " ";
s << "<b>Floodfills:</b> " << i2p::data::netdb.GetNumFloodfills () << " "; s << "<b>Floodfills:</b> " << i2p::data::netdb.GetNumFloodfills () << " ";
s << "<b>LeaseSets:</b> " << i2p::data::netdb.GetNumLeaseSets () << "<br>\r\n"; s << "<b>LeaseSets:</b> " << i2p::data::netdb.GetNumLeaseSets () << "<br>\r\n";
size_t clientTunnelCount = i2p::tunnel::tunnels.CountOutboundTunnels();
clientTunnelCount += i2p::tunnel::tunnels.CountInboundTunnels();
size_t transitTunnelCount = i2p::tunnel::tunnels.CountTransitTunnels();
s << "<b>Client Tunnels:</b> " << std::to_string(clientTunnelCount) << " ";
s << "<b>Transit Tunnels:</b> " << std::to_string(transitTunnelCount) << "<br>\r\n";
} }
void HTTPConnection::HandleCommand (const std::string& command, std::stringstream& s) void HTTPConnection::HandleCommand (const std::string& command, std::stringstream& s)
@ -603,13 +610,13 @@ namespace util
for (auto it: i2p::tunnel::tunnels.GetInboundTunnels ()) for (auto it: i2p::tunnel::tunnels.GetInboundTunnels ())
{ {
it.second->Print (s); it->Print (s);
auto state = it.second->GetState (); auto state = it->GetState ();
if (state == i2p::tunnel::eTunnelStateFailed) if (state == i2p::tunnel::eTunnelStateFailed)
s << "<span class=failed_tunnel> " << "Failed</span>"; s << "<span class=failed_tunnel> " << "Failed</span>";
else if (state == i2p::tunnel::eTunnelStateExpiring) else if (state == i2p::tunnel::eTunnelStateExpiring)
s << "<span class=expiring_tunnel> " << "Exp</span>"; s << "<span class=expiring_tunnel> " << "Exp</span>";
s << " " << (int)it.second->GetNumReceivedBytes () << "<br>\r\n"; s << " " << (int)it->GetNumReceivedBytes () << "<br>\r\n";
s << std::endl; s << std::endl;
} }
} }
@ -619,13 +626,13 @@ namespace util
s << "<b>Transit tunnels:</b><br>\r\n<br>\r\n"; s << "<b>Transit tunnels:</b><br>\r\n<br>\r\n";
for (auto it: i2p::tunnel::tunnels.GetTransitTunnels ()) for (auto it: i2p::tunnel::tunnels.GetTransitTunnels ())
{ {
if (dynamic_cast<i2p::tunnel::TransitTunnelGateway *>(it.second)) if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelGateway>(it))
s << it.second->GetTunnelID () << ""; s << it->GetTunnelID () << "";
else if (dynamic_cast<i2p::tunnel::TransitTunnelEndpoint *>(it.second)) else if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelEndpoint>(it))
s << "" << it.second->GetTunnelID (); s << "" << it->GetTunnelID ();
else else
s << "" << it.second->GetTunnelID () << ""; s << "" << it->GetTunnelID () << "";
s << " " << it.second->GetNumTransmittedBytes () << "<br>\r\n"; s << " " << it->GetNumTransmittedBytes () << "<br>\r\n";
} }
} }

3
I2NPProtocol.cpp

@ -301,8 +301,7 @@ namespace i2p
i2p::tunnel::tunnels.GetTransitTunnels ().size () <= MAX_NUM_TRANSIT_TUNNELS && i2p::tunnel::tunnels.GetTransitTunnels ().size () <= MAX_NUM_TRANSIT_TUNNELS &&
!i2p::transport::transports.IsBandwidthExceeded ()) !i2p::transport::transports.IsBandwidthExceeded ())
{ {
i2p::tunnel::TransitTunnel * transitTunnel = auto transitTunnel = i2p::tunnel::CreateTransitTunnel (
i2p::tunnel::CreateTransitTunnel (
bufbe32toh (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), bufbe32toh (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),

11
NetDb.cpp

@ -677,7 +677,7 @@ namespace data
excludedRouters.insert (excluded); excludedRouters.insert (excluded);
excluded += 32; 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<IdentHash> NetDb::GetClosestFloodfills (const IdentHash& destination, size_t num, std::vector<IdentHash> NetDb::GetClosestFloodfills (const IdentHash& destination, size_t num,
std::set<IdentHash>& excluded) const std::set<IdentHash>& excluded, bool closeThanUsOnly) const
{ {
struct Sorted struct Sorted
{ {
@ -895,6 +895,8 @@ namespace data
std::set<Sorted> sorted; std::set<Sorted> sorted;
IdentHash destKey = CreateRoutingKey (destination); IdentHash destKey = CreateRoutingKey (destination);
XORMetric ourMetric;
if (closeThanUsOnly) ourMetric = destKey ^ i2p::context.GetIdentHash ();
{ {
std::unique_lock<std::mutex> l(m_FloodfillsMutex); std::unique_lock<std::mutex> l(m_FloodfillsMutex);
for (auto it: m_Floodfills) for (auto it: m_Floodfills)
@ -902,6 +904,7 @@ namespace data
if (!it->IsUnreachable ()) if (!it->IsUnreachable ())
{ {
XORMetric m = destKey ^ it->GetIdentHash (); XORMetric m = destKey ^ it->GetIdentHash ();
if (closeThanUsOnly && ourMetric < m) continue;
if (sorted.size () < num) if (sorted.size () < num)
sorted.insert ({it, m}); sorted.insert ({it, m});
else if (m < sorted.rbegin ()->metric) else if (m < sorted.rbegin ()->metric)
@ -960,9 +963,9 @@ namespace data
auto ts = i2p::util::GetMillisecondsSinceEpoch (); auto ts = i2p::util::GetMillisecondsSinceEpoch ();
for (auto it = m_LeaseSets.begin (); it != m_LeaseSets.end ();) 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); it = m_LeaseSets.erase (it);
} }
else else

2
NetDb.h

@ -60,7 +60,7 @@ namespace data
std::shared_ptr<const RouterInfo> GetRandomIntroducer () const; std::shared_ptr<const RouterInfo> GetRandomIntroducer () const;
std::shared_ptr<const RouterInfo> GetClosestFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const; std::shared_ptr<const RouterInfo> GetClosestFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const;
std::vector<IdentHash> GetClosestFloodfills (const IdentHash& destination, size_t num, std::vector<IdentHash> GetClosestFloodfills (const IdentHash& destination, size_t num,
std::set<IdentHash>& excluded) const; std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const;
std::shared_ptr<const RouterInfo> GetClosestNonFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const; std::shared_ptr<const RouterInfo> GetClosestNonFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const;
void SetUnreachable (const IdentHash& ident, bool unreachable); void SetUnreachable (const IdentHash& ident, bool unreachable);

8
TransitTunnel.cpp

@ -85,7 +85,7 @@ namespace tunnel
m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg); m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg);
} }
TransitTunnel * CreateTransitTunnel (uint32_t receiveTunnelID, std::shared_ptr<TransitTunnel> CreateTransitTunnel (uint32_t receiveTunnelID,
const uint8_t * nextIdent, uint32_t nextTunnelID, const uint8_t * nextIdent, uint32_t nextTunnelID,
const uint8_t * layerKey,const uint8_t * ivKey, const uint8_t * layerKey,const uint8_t * ivKey,
bool isGateway, bool isEndpoint) bool isGateway, bool isEndpoint)
@ -93,17 +93,17 @@ namespace tunnel
if (isEndpoint) if (isEndpoint)
{ {
LogPrint (eLogInfo, "TransitTunnel: endpoint ", receiveTunnelID, " created"); LogPrint (eLogInfo, "TransitTunnel: endpoint ", receiveTunnelID, " created");
return new TransitTunnelEndpoint (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey); return std::make_shared<TransitTunnelEndpoint> (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey);
} }
else if (isGateway) else if (isGateway)
{ {
LogPrint (eLogInfo, "TransitTunnel: gateway ", receiveTunnelID, " created"); LogPrint (eLogInfo, "TransitTunnel: gateway ", receiveTunnelID, " created");
return new TransitTunnelGateway (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey); return std::make_shared<TransitTunnelGateway> (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey);
} }
else else
{ {
LogPrint (eLogInfo, "TransitTunnel: ", receiveTunnelID, "->", nextTunnelID, " created"); LogPrint (eLogInfo, "TransitTunnel: ", receiveTunnelID, "->", nextTunnelID, " created");
return new TransitTunnelParticipant (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey); return std::make_shared<TransitTunnelParticipant> (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey);
} }
} }
} }

2
TransitTunnel.h

@ -93,7 +93,7 @@ namespace tunnel
TunnelEndpoint m_Endpoint; TunnelEndpoint m_Endpoint;
}; };
TransitTunnel * CreateTransitTunnel (uint32_t receiveTunnelID, std::shared_ptr<TransitTunnel> CreateTransitTunnel (uint32_t receiveTunnelID,
const uint8_t * nextIdent, uint32_t nextTunnelID, const uint8_t * nextIdent, uint32_t nextTunnelID,
const uint8_t * layerKey,const uint8_t * ivKey, const uint8_t * layerKey,const uint8_t * ivKey,
bool isGateway, bool isEndpoint); bool isGateway, bool isEndpoint);

152
Tunnel.cpp

@ -206,6 +206,26 @@ namespace tunnel
s << "" << GetTunnelID () << ":me"; s << "" << GetTunnelID () << ":me";
} }
ZeroHopsInboundTunnel::ZeroHopsInboundTunnel ():
InboundTunnel (std::make_shared<ZeroHopsTunnelConfig> ()),
m_NumReceivedBytes (0)
{
}
void ZeroHopsInboundTunnel::SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg)
{
if (msg)
{
m_NumReceivedBytes += msg->GetLength ();
HandleI2NPMessage (msg);
}
}
void ZeroHopsInboundTunnel::Print (std::stringstream& s) const
{
s << "" << GetTunnelID () << ":me";
}
void OutboundTunnel::SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr<i2p::I2NPMessage> msg) void OutboundTunnel::SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr<i2p::I2NPMessage> msg)
{ {
TunnelMessageBlock block; TunnelMessageBlock block;
@ -257,23 +277,12 @@ namespace tunnel
Tunnels::~Tunnels () Tunnels::~Tunnels ()
{ {
for (auto& it : m_TransitTunnels)
delete it.second;
m_TransitTunnels.clear ();
} }
std::shared_ptr<InboundTunnel> Tunnels::GetInboundTunnel (uint32_t tunnelID) std::shared_ptr<TunnelBase> Tunnels::GetTunnel (uint32_t tunnelID)
{ {
auto it = m_InboundTunnels.find(tunnelID); auto it = m_Tunnels.find(tunnelID);
if (it != m_InboundTunnels.end ()) if (it != m_Tunnels.end ())
return it->second;
return nullptr;
}
TransitTunnel * Tunnels::GetTransitTunnel (uint32_t tunnelID)
{
auto it = m_TransitTunnels.find(tunnelID);
if (it != m_TransitTunnels.end ())
return it->second; return it->second;
return nullptr; return nullptr;
} }
@ -306,11 +315,11 @@ namespace tunnel
size_t minReceived = 0; size_t minReceived = 0;
for (auto it : m_InboundTunnels) for (auto it : m_InboundTunnels)
{ {
if (!it.second->IsEstablished ()) continue; if (!it->IsEstablished ()) continue;
if (!tunnel || it.second->GetNumReceivedBytes () < minReceived) if (!tunnel || it->GetNumReceivedBytes () < minReceived)
{ {
tunnel = it.second; tunnel = it;
minReceived = it.second->GetNumReceivedBytes (); minReceived = it->GetNumReceivedBytes ();
} }
} }
return tunnel; return tunnel;
@ -363,14 +372,12 @@ namespace tunnel
} }
} }
void Tunnels::AddTransitTunnel (TransitTunnel * tunnel) void Tunnels::AddTransitTunnel (std::shared_ptr<TransitTunnel> tunnel)
{ {
std::unique_lock<std::mutex> l(m_TransitTunnelsMutex); if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second)
if (!m_TransitTunnels.insert (std::make_pair (tunnel->GetTunnelID (), tunnel)).second) m_TransitTunnels.push_back (tunnel);
{ else
LogPrint (eLogError, "Tunnel: transit tunnel with id ", tunnel->GetTunnelID (), " already exists"); LogPrint (eLogError, "Tunnel: tunnel with id ", tunnel->GetTunnelID (), " already exists");
delete tunnel;
}
} }
void Tunnels::Start () void Tunnels::Start ()
@ -404,10 +411,10 @@ namespace tunnel
if (msg) if (msg)
{ {
uint32_t prevTunnelID = 0, tunnelID = 0; uint32_t prevTunnelID = 0, tunnelID = 0;
TunnelBase * prevTunnel = nullptr; std::shared_ptr<TunnelBase> prevTunnel;
do do
{ {
TunnelBase * tunnel = nullptr; std::shared_ptr<TunnelBase> tunnel;
uint8_t typeID = msg->GetTypeID (); uint8_t typeID = msg->GetTypeID ();
switch (typeID) switch (typeID)
{ {
@ -420,10 +427,8 @@ namespace tunnel
else if (prevTunnel) else if (prevTunnel)
prevTunnel->FlushTunnelDataMsgs (); prevTunnel->FlushTunnelDataMsgs ();
if (!tunnel && typeID == eI2NPTunnelData)
tunnel = GetInboundTunnel (tunnelID).get ();
if (!tunnel) if (!tunnel)
tunnel = GetTransitTunnel (tunnelID); tunnel = GetTunnel (tunnelID);
if (tunnel) if (tunnel)
{ {
if (typeID == eI2NPTunnelData) if (typeID == eI2NPTunnelData)
@ -471,7 +476,7 @@ namespace tunnel
} }
} }
void Tunnels::HandleTunnelGatewayMsg (TunnelBase * tunnel, std::shared_ptr<I2NPMessage> msg) void Tunnels::HandleTunnelGatewayMsg (std::shared_ptr<TunnelBase> tunnel, std::shared_ptr<I2NPMessage> msg)
{ {
if (!tunnel) if (!tunnel)
{ {
@ -580,6 +585,7 @@ namespace tunnel
auto pool = tunnel->GetTunnelPool (); auto pool = tunnel->GetTunnelPool ();
if (pool) if (pool)
pool->TunnelExpired (tunnel); pool->TunnelExpired (tunnel);
// we don't have outbound tunnels in m_Tunnels
it = m_OutboundTunnels.erase (it); it = m_OutboundTunnels.erase (it);
} }
else else
@ -621,13 +627,14 @@ namespace tunnel
{ {
for (auto it = m_InboundTunnels.begin (); it != m_InboundTunnels.end ();) for (auto it = m_InboundTunnels.begin (); it != m_InboundTunnels.end ();)
{ {
auto tunnel = it->second; auto tunnel = *it;
if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
{ {
LogPrint (eLogDebug, "Tunnel: tunnel with id ", tunnel->GetTunnelID (), " expired"); LogPrint (eLogDebug, "Tunnel: tunnel with id ", tunnel->GetTunnelID (), " expired");
auto pool = tunnel->GetTunnelPool (); auto pool = tunnel->GetTunnelPool ();
if (pool) if (pool)
pool->TunnelExpired (tunnel); pool->TunnelExpired (tunnel);
m_Tunnels.erase (tunnel->GetTunnelID ());
it = m_InboundTunnels.erase (it); it = m_InboundTunnels.erase (it);
} }
else else
@ -682,15 +689,12 @@ namespace tunnel
uint32_t ts = i2p::util::GetSecondsSinceEpoch (); uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
for (auto it = m_TransitTunnels.begin (); it != m_TransitTunnels.end ();) 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 ", tunnel->GetTunnelID (), " expired");
LogPrint (eLogDebug, "Tunnel: Transit tunnel with id ", tmp->GetTunnelID (), " expired"); m_Tunnels.erase (tunnel->GetTunnelID ());
{ it = m_TransitTunnels.erase (it);
std::unique_lock<std::mutex> l(m_TransitTunnelsMutex);
it = m_TransitTunnels.erase (it);
}
delete tmp;
} }
else else
it++; it++;
@ -744,6 +748,7 @@ namespace tunnel
void Tunnels::AddOutboundTunnel (std::shared_ptr<OutboundTunnel> newTunnel) void Tunnels::AddOutboundTunnel (std::shared_ptr<OutboundTunnel> newTunnel)
{ {
// we don't need to insert it to m_Tunnels
m_OutboundTunnels.push_back (newTunnel); m_OutboundTunnels.push_back (newTunnel);
auto pool = newTunnel->GetTunnelPool (); auto pool = newTunnel->GetTunnelPool ();
if (pool && pool->IsActive ()) if (pool && pool->IsActive ())
@ -754,46 +759,79 @@ namespace tunnel
void Tunnels::AddInboundTunnel (std::shared_ptr<InboundTunnel> newTunnel) void Tunnels::AddInboundTunnel (std::shared_ptr<InboundTunnel> newTunnel)
{ {
m_InboundTunnels[newTunnel->GetTunnelID ()] = newTunnel; if (m_Tunnels.emplace (newTunnel->GetTunnelID (), newTunnel).second)
auto pool = newTunnel->GetTunnelPool ();
if (!pool)
{
// build symmetric outbound tunnel
CreateTunnel<OutboundTunnel> (std::make_shared<TunnelConfig>(newTunnel->GetInvertedPeers (),
newTunnel->GetNextTunnelID (), newTunnel->GetNextIdentHash ()),
GetNextOutboundTunnel ());
}
else
{ {
if (pool->IsActive ()) m_InboundTunnels.push_back (newTunnel);
pool->TunnelCreated (newTunnel); auto pool = newTunnel->GetTunnelPool ();
if (!pool)
{
// build symmetric outbound tunnel
CreateTunnel<OutboundTunnel> (std::make_shared<TunnelConfig>(newTunnel->GetInvertedPeers (),
newTunnel->GetNextTunnelID (), newTunnel->GetNextIdentHash ()),
GetNextOutboundTunnel ());
}
else else
newTunnel->SetTunnelPool (nullptr); {
if (pool->IsActive ())
pool->TunnelCreated (newTunnel);
else
newTunnel->SetTunnelPool (nullptr);
}
} }
else
LogPrint (eLogError, "Tunnel: tunnel with id ", newTunnel->GetTunnelID (), " already exists");
} }
void Tunnels::CreateZeroHopsInboundTunnel () void Tunnels::CreateZeroHopsInboundTunnel ()
{ {
CreateTunnel<InboundTunnel> ( /*CreateTunnel<InboundTunnel> (
std::make_shared<TunnelConfig> (std::vector<std::shared_ptr<const i2p::data::IdentityEx> > std::make_shared<TunnelConfig> (std::vector<std::shared_ptr<const i2p::data::IdentityEx> >
{ {
i2p::context.GetIdentity () i2p::context.GetIdentity ()
})); }));*/
auto inboundTunnel = std::make_shared<ZeroHopsInboundTunnel> ();
m_InboundTunnels.push_back (inboundTunnel);
m_Tunnels[inboundTunnel->GetTunnelID ()] = inboundTunnel;
// create paired outbound tunnel, TODO: move to separate function
CreateTunnel<OutboundTunnel> (
std::make_shared<TunnelConfig> (std::vector<std::shared_ptr<const i2p::data::IdentityEx> >
{
i2p::context.GetIdentity ()
}, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()));
} }
int Tunnels::GetTransitTunnelsExpirationTimeout () int Tunnels::GetTransitTunnelsExpirationTimeout ()
{ {
int timeout = 0; int timeout = 0;
uint32_t ts = i2p::util::GetSecondsSinceEpoch (); uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
std::unique_lock<std::mutex> l(m_TransitTunnelsMutex); // TODO: possible race condition with I2PControl
for (auto it: m_TransitTunnels) 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; if (t > timeout) timeout = t;
} }
return timeout; return timeout;
} }
size_t Tunnels::CountTransitTunnels() const
{
// TODO: locking
return m_TransitTunnels.size();
}
size_t Tunnels::CountInboundTunnels() const
{
// TODO: locking
return m_InboundTunnels.size();
}
size_t Tunnels::CountOutboundTunnels() const
{
// TODO: locking
return m_OutboundTunnels.size();
}
} }
} }

36
Tunnel.h

@ -3,6 +3,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <map> #include <map>
#include <unordered_map>
#include <list> #include <list>
#include <vector> #include <vector>
#include <string> #include <string>
@ -72,6 +73,8 @@ namespace tunnel
bool HandleTunnelBuildResponse (uint8_t * msg, size_t len); bool HandleTunnelBuildResponse (uint8_t * msg, size_t len);
virtual void Print (std::stringstream& s) const {};
// implements TunnelBase // implements TunnelBase
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg); void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out); void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out);
@ -118,7 +121,7 @@ namespace tunnel
InboundTunnel (std::shared_ptr<const TunnelConfig> config): Tunnel (config), m_Endpoint (true) {}; InboundTunnel (std::shared_ptr<const TunnelConfig> config): Tunnel (config), m_Endpoint (true) {};
void HandleTunnelDataMsg (std::shared_ptr<const I2NPMessage> msg); void HandleTunnelDataMsg (std::shared_ptr<const I2NPMessage> msg);
size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); }; virtual size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); };
void Print (std::stringstream& s) const; void Print (std::stringstream& s) const;
private: private:
@ -126,6 +129,19 @@ namespace tunnel
TunnelEndpoint m_Endpoint; TunnelEndpoint m_Endpoint;
}; };
class ZeroHopsInboundTunnel: public InboundTunnel
{
public:
ZeroHopsInboundTunnel ();
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
void Print (std::stringstream& s) const;
size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
private:
size_t m_NumReceivedBytes;
};
class Tunnels class Tunnels
{ {
@ -136,15 +152,14 @@ namespace tunnel
void Start (); void Start ();
void Stop (); void Stop ();
std::shared_ptr<InboundTunnel> GetInboundTunnel (uint32_t tunnelID);
std::shared_ptr<InboundTunnel> GetPendingInboundTunnel (uint32_t replyMsgID); std::shared_ptr<InboundTunnel> GetPendingInboundTunnel (uint32_t replyMsgID);
std::shared_ptr<OutboundTunnel> GetPendingOutboundTunnel (uint32_t replyMsgID); std::shared_ptr<OutboundTunnel> GetPendingOutboundTunnel (uint32_t replyMsgID);
std::shared_ptr<InboundTunnel> GetNextInboundTunnel (); std::shared_ptr<InboundTunnel> GetNextInboundTunnel ();
std::shared_ptr<OutboundTunnel> GetNextOutboundTunnel (); std::shared_ptr<OutboundTunnel> GetNextOutboundTunnel ();
std::shared_ptr<TunnelPool> GetExploratoryPool () const { return m_ExploratoryPool; }; std::shared_ptr<TunnelPool> GetExploratoryPool () const { return m_ExploratoryPool; };
TransitTunnel * GetTransitTunnel (uint32_t tunnelID); std::shared_ptr<TunnelBase> GetTunnel (uint32_t tunnelID);
int GetTransitTunnelsExpirationTimeout (); int GetTransitTunnelsExpirationTimeout ();
void AddTransitTunnel (TransitTunnel * tunnel); void AddTransitTunnel (std::shared_ptr<TransitTunnel> tunnel);
void AddOutboundTunnel (std::shared_ptr<OutboundTunnel> newTunnel); void AddOutboundTunnel (std::shared_ptr<OutboundTunnel> newTunnel);
void AddInboundTunnel (std::shared_ptr<InboundTunnel> newTunnel); void AddInboundTunnel (std::shared_ptr<InboundTunnel> newTunnel);
void PostTunnelData (std::shared_ptr<I2NPMessage> msg); void PostTunnelData (std::shared_ptr<I2NPMessage> msg);
@ -163,7 +178,7 @@ namespace tunnel
template<class TTunnel> template<class TTunnel>
std::shared_ptr<TTunnel> GetPendingTunnel (uint32_t replyMsgID, const std::map<uint32_t, std::shared_ptr<TTunnel> >& pendingTunnels); std::shared_ptr<TTunnel> GetPendingTunnel (uint32_t replyMsgID, const std::map<uint32_t, std::shared_ptr<TTunnel> >& pendingTunnels);
void HandleTunnelGatewayMsg (TunnelBase * tunnel, std::shared_ptr<I2NPMessage> msg); void HandleTunnelGatewayMsg (std::shared_ptr<TunnelBase> tunnel, std::shared_ptr<I2NPMessage> msg);
void Run (); void Run ();
void ManageTunnels (); void ManageTunnels ();
@ -183,10 +198,10 @@ namespace tunnel
std::thread * m_Thread; std::thread * m_Thread;
std::map<uint32_t, std::shared_ptr<InboundTunnel> > m_PendingInboundTunnels; // by replyMsgID std::map<uint32_t, std::shared_ptr<InboundTunnel> > m_PendingInboundTunnels; // by replyMsgID
std::map<uint32_t, std::shared_ptr<OutboundTunnel> > m_PendingOutboundTunnels; // by replyMsgID std::map<uint32_t, std::shared_ptr<OutboundTunnel> > m_PendingOutboundTunnels; // by replyMsgID
std::map<uint32_t, std::shared_ptr<InboundTunnel> > m_InboundTunnels; std::list<std::shared_ptr<InboundTunnel> > m_InboundTunnels;
std::list<std::shared_ptr<OutboundTunnel> > m_OutboundTunnels; std::list<std::shared_ptr<OutboundTunnel> > m_OutboundTunnels;
std::mutex m_TransitTunnelsMutex; std::list<std::shared_ptr<TransitTunnel> > m_TransitTunnels;
std::map<uint32_t, TransitTunnel *> m_TransitTunnels; std::unordered_map<uint32_t, std::shared_ptr<TunnelBase> > m_Tunnels; // tunnelID->tunnel known by this id
std::mutex m_PoolsMutex; std::mutex m_PoolsMutex;
std::list<std::shared_ptr<TunnelPool>> m_Pools; std::list<std::shared_ptr<TunnelPool>> m_Pools;
std::shared_ptr<TunnelPool> m_ExploratoryPool; std::shared_ptr<TunnelPool> m_ExploratoryPool;
@ -201,6 +216,11 @@ namespace tunnel
const decltype(m_OutboundTunnels)& GetOutboundTunnels () const { return m_OutboundTunnels; }; const decltype(m_OutboundTunnels)& GetOutboundTunnels () const { return m_OutboundTunnels; };
const decltype(m_InboundTunnels)& GetInboundTunnels () const { return m_InboundTunnels; }; const decltype(m_InboundTunnels)& GetInboundTunnels () const { return m_InboundTunnels; };
const decltype(m_TransitTunnels)& GetTransitTunnels () const { return m_TransitTunnels; }; const decltype(m_TransitTunnels)& GetTransitTunnels () const { return m_TransitTunnels; };
size_t CountTransitTunnels() const;
size_t CountInboundTunnels() const;
size_t CountOutboundTunnels() const;
int GetQueueSize () { return m_Queue.GetSize (); }; int GetQueueSize () { return m_Queue.GetSize (); };
int GetTunnelCreationSuccessRate () const // in percents int GetTunnelCreationSuccessRate () const // in percents
{ {

34
TunnelConfig.h

@ -108,7 +108,7 @@ namespace tunnel
} }
}; };
class TunnelConfig: public std::enable_shared_from_this<TunnelConfig> class TunnelConfig
{ {
public: public:
@ -160,26 +160,26 @@ namespace tunnel
return num; 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; if (!m_FirstHop) return 0;
return IsInbound () ? m_LastHop->nextTunnelID : m_FirstHop->tunnelID; return IsInbound () ? m_LastHop->nextTunnelID : m_FirstHop->tunnelID;
} }
uint32_t GetNextTunnelID () const virtual uint32_t GetNextTunnelID () const
{ {
if (!m_FirstHop) return 0; if (!m_FirstHop) return 0;
return m_FirstHop->tunnelID; return m_FirstHop->tunnelID;
} }
const i2p::data::IdentHash& GetNextIdentHash () const virtual const i2p::data::IdentHash& GetNextIdentHash () const
{ {
return m_FirstHop->ident->GetIdentHash (); return m_FirstHop->ident->GetIdentHash ();
} }
const i2p::data::IdentHash& GetLastIdentHash () const virtual const i2p::data::IdentHash& GetLastIdentHash () const
{ {
return m_LastHop->ident->GetIdentHash (); return m_LastHop->ident->GetIdentHash ();
} }
@ -196,13 +196,15 @@ namespace tunnel
return peers; return peers;
} }
private: protected:
// this constructor can't be called from outside // this constructor can't be called from outside
TunnelConfig (): m_FirstHop (nullptr), m_LastHop (nullptr) TunnelConfig (): m_FirstHop (nullptr), m_LastHop (nullptr)
{ {
} }
private:
template<class Peers> template<class Peers>
void CreatePeers (const Peers& peers) void CreatePeers (const Peers& peers)
{ {
@ -223,6 +225,24 @@ namespace tunnel
TunnelHopConfig * m_FirstHop, * m_LastHop; TunnelHopConfig * m_FirstHop, * m_LastHop;
}; };
class ZeroHopsTunnelConfig: public TunnelConfig
{
public:
ZeroHopsTunnelConfig () { RAND_bytes ((uint8_t *)&m_TunnelID, 4);};
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 (); };
const i2p::data::IdentHash& GetLastIdentHash () const { return i2p::context.GetIdentHash (); };
private:
uint32_t m_TunnelID;
};
} }
} }

Loading…
Cancel
Save