Browse Source

moved all transit tunnels code to TransitTunnels class

pull/2125/head
orignal 1 week ago
parent
commit
72a39609ed
  1. 64
      libi2pd/TransitTunnel.cpp
  2. 20
      libi2pd/TransitTunnel.h
  3. 72
      libi2pd/Tunnel.cpp
  4. 11
      libi2pd/Tunnel.h

64
libi2pd/TransitTunnel.cpp

@ -122,7 +122,16 @@ namespace tunnel
} }
} }
void TransitTunnelBuildMsgHandler::HandleShortTransitTunnelBuildMsg (std::shared_ptr<I2NPMessage>&& msg) void TransitTunnels::Start ()
{
}
void TransitTunnels::Stop ()
{
m_TransitTunnels.clear ();
}
void TransitTunnels::HandleShortTransitTunnelBuildMsg (std::shared_ptr<I2NPMessage>&& msg)
{ {
if (!msg) return; if (!msg) return;
uint8_t * buf = msg->GetPayload(); uint8_t * buf = msg->GetPayload();
@ -194,7 +203,7 @@ namespace tunnel
layerKey, ivKey, layerKey, ivKey,
clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG,
clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG);
if (!i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel)) if (!AddTransitTunnel (transitTunnel))
retCode = 30; retCode = 30;
} }
@ -275,7 +284,7 @@ namespace tunnel
} }
} }
bool TransitTunnelBuildMsgHandler::HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText) bool TransitTunnels::HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText)
{ {
for (int i = 0; i < num; i++) for (int i = 0; i < num; i++)
{ {
@ -324,7 +333,7 @@ namespace tunnel
clearText + ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET, clearText + ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET,
clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG,
clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG);
if (!i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel)) if (!AddTransitTunnel (transitTunnel))
retCode = 30; retCode = 30;
} }
else else
@ -362,7 +371,7 @@ namespace tunnel
return false; return false;
} }
void TransitTunnelBuildMsgHandler::HandleVariableTransitTunnelBuildMsg (std::shared_ptr<I2NPMessage>&& msg) void TransitTunnels::HandleVariableTransitTunnelBuildMsg (std::shared_ptr<I2NPMessage>&& msg)
{ {
if (!msg) return; if (!msg) return;
uint8_t * buf = msg->GetPayload(); uint8_t * buf = msg->GetPayload();
@ -396,5 +405,50 @@ namespace tunnel
bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
} }
} }
bool TransitTunnels::AddTransitTunnel (std::shared_ptr<TransitTunnel> tunnel)
{
if (tunnels.AddTunnel (tunnel))
m_TransitTunnels.push_back (tunnel);
else
{
LogPrint (eLogError, "TransitTunnel: Tunnel with id ", tunnel->GetTunnelID (), " already exists");
return false;
}
return true;
}
void TransitTunnels::ManageTransitTunnels (uint64_t ts)
{
for (auto it = m_TransitTunnels.begin (); it != m_TransitTunnels.end ();)
{
auto tunnel = *it;
if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT ||
ts + TUNNEL_EXPIRATION_TIMEOUT < tunnel->GetCreationTime ())
{
LogPrint (eLogDebug, "TransitTunnel: Transit tunnel with id ", tunnel->GetTunnelID (), " expired");
tunnels.RemoveTunnel (tunnel->GetTunnelID ());
it = m_TransitTunnels.erase (it);
}
else
{
tunnel->Cleanup ();
it++;
}
}
}
int TransitTunnels::GetTransitTunnelsExpirationTimeout ()
{
int timeout = 0;
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
// TODO: possible race condition with I2PControl
for (const auto& it : m_TransitTunnels)
{
int t = it->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT - ts;
if (t > timeout) timeout = t;
}
return timeout;
}
} }
} }

20
libi2pd/TransitTunnel.h

@ -109,19 +109,33 @@ namespace tunnel
const i2p::crypto::AESKey& layerKey, const i2p::crypto::AESKey& ivKey, const i2p::crypto::AESKey& layerKey, const i2p::crypto::AESKey& ivKey,
bool isGateway, bool isEndpoint); bool isGateway, bool isEndpoint);
class TransitTunnelBuildMsgHandler class TransitTunnels
{ {
public: public:
void Start () {}; void Start ();
void Stop () {}; void Stop ();
void ManageTransitTunnels (uint64_t ts);
size_t GetNumTransitTunnels () const { return m_TransitTunnels.size (); }
int GetTransitTunnelsExpirationTimeout ();
void HandleShortTransitTunnelBuildMsg (std::shared_ptr<I2NPMessage>&& msg); void HandleShortTransitTunnelBuildMsg (std::shared_ptr<I2NPMessage>&& msg);
void HandleVariableTransitTunnelBuildMsg (std::shared_ptr<I2NPMessage>&& msg); void HandleVariableTransitTunnelBuildMsg (std::shared_ptr<I2NPMessage>&& msg);
private: private:
bool AddTransitTunnel (std::shared_ptr<TransitTunnel> tunnel);
bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText); bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText);
private:
std::list<std::shared_ptr<TransitTunnel> > m_TransitTunnels;
public:
// for HTTP only
auto& GetTransitTunnels () const { return m_TransitTunnels; };
}; };
} }
} }

72
libi2pd/Tunnel.cpp

@ -379,6 +379,17 @@ namespace tunnel
return nullptr; return nullptr;
} }
bool Tunnels::AddTunnel (std::shared_ptr<TunnelBase> tunnel)
{
if (!tunnel) return false;
return m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second;
}
void Tunnels::RemoveTunnel (uint32_t tunnelID)
{
m_Tunnels.erase (tunnelID);
}
std::shared_ptr<InboundTunnel> Tunnels::GetPendingInboundTunnel (uint32_t replyMsgID) std::shared_ptr<InboundTunnel> Tunnels::GetPendingInboundTunnel (uint32_t replyMsgID)
{ {
return GetPendingTunnel (replyMsgID, m_PendingInboundTunnels); return GetPendingTunnel (replyMsgID, m_PendingInboundTunnels);
@ -466,28 +477,16 @@ namespace tunnel
} }
} }
bool Tunnels::AddTransitTunnel (std::shared_ptr<TransitTunnel> tunnel)
{
if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second)
m_TransitTunnels.push_back (tunnel);
else
{
LogPrint (eLogError, "Tunnel: Tunnel with id ", tunnel->GetTunnelID (), " already exists");
return false;
}
return true;
}
void Tunnels::Start () void Tunnels::Start ()
{ {
m_IsRunning = true; m_IsRunning = true;
m_Thread = new std::thread (std::bind (&Tunnels::Run, this)); m_Thread = new std::thread (std::bind (&Tunnels::Run, this));
m_TransitTunnelBuildMsgHandler.Start (); m_TransitTunnels.Start ();
} }
void Tunnels::Stop () void Tunnels::Stop ()
{ {
m_TransitTunnelBuildMsgHandler.Stop (); m_TransitTunnels.Stop ();
m_IsRunning = false; m_IsRunning = false;
m_Queue.WakeUp (); m_Queue.WakeUp ();
if (m_Thread) if (m_Thread)
@ -656,7 +655,7 @@ namespace tunnel
return; return;
} }
else else
m_TransitTunnelBuildMsgHandler.HandleShortTransitTunnelBuildMsg (std::move (msg)); m_TransitTunnels.HandleShortTransitTunnelBuildMsg (std::move (msg));
} }
void Tunnels::HandleVariableTunnelBuildMsg (std::shared_ptr<I2NPMessage> msg) void Tunnels::HandleVariableTunnelBuildMsg (std::shared_ptr<I2NPMessage> msg)
@ -679,7 +678,7 @@ namespace tunnel
} }
} }
else else
m_TransitTunnelBuildMsgHandler.HandleVariableTransitTunnelBuildMsg (std::move (msg)); m_TransitTunnels.HandleVariableTransitTunnelBuildMsg (std::move (msg));
} }
void Tunnels::HandleTunnelBuildReplyMsg (std::shared_ptr<I2NPMessage> msg, bool isShort) void Tunnels::HandleTunnelBuildReplyMsg (std::shared_ptr<I2NPMessage> msg, bool isShort)
@ -711,7 +710,7 @@ namespace tunnel
ManagePendingTunnels (ts); ManagePendingTunnels (ts);
ManageInboundTunnels (ts); ManageInboundTunnels (ts);
ManageOutboundTunnels (ts); ManageOutboundTunnels (ts);
ManageTransitTunnels (ts); m_TransitTunnels.ManageTransitTunnels (ts);
} }
void Tunnels::ManagePendingTunnels (uint64_t ts) void Tunnels::ManagePendingTunnels (uint64_t ts)
@ -838,7 +837,7 @@ namespace tunnel
auto pool = tunnel->GetTunnelPool (); auto pool = tunnel->GetTunnelPool ();
if (pool) if (pool)
pool->TunnelExpired (tunnel); pool->TunnelExpired (tunnel);
m_Tunnels.erase (tunnel->GetTunnelID ()); RemoveTunnel (tunnel->GetTunnelID ());
it = m_InboundTunnels.erase (it); it = m_InboundTunnels.erase (it);
} }
else else
@ -900,26 +899,6 @@ namespace tunnel
} }
} }
void Tunnels::ManageTransitTunnels (uint64_t ts)
{
for (auto it = m_TransitTunnels.begin (); it != m_TransitTunnels.end ();)
{
auto tunnel = *it;
if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT ||
ts + TUNNEL_EXPIRATION_TIMEOUT < tunnel->GetCreationTime ())
{
LogPrint (eLogDebug, "Tunnel: Transit tunnel with id ", tunnel->GetTunnelID (), " expired");
m_Tunnels.erase (tunnel->GetTunnelID ());
it = m_TransitTunnels.erase (it);
}
else
{
tunnel->Cleanup ();
it++;
}
}
}
void Tunnels::ManageTunnelPools (uint64_t ts) void Tunnels::ManageTunnelPools (uint64_t ts)
{ {
std::unique_lock<std::mutex> l(m_PoolsMutex); std::unique_lock<std::mutex> l(m_PoolsMutex);
@ -993,7 +972,7 @@ namespace tunnel
void Tunnels::AddInboundTunnel (std::shared_ptr<InboundTunnel> newTunnel) void Tunnels::AddInboundTunnel (std::shared_ptr<InboundTunnel> newTunnel)
{ {
if (m_Tunnels.emplace (newTunnel->GetTunnelID (), newTunnel).second) if (AddTunnel (newTunnel))
{ {
m_InboundTunnels.push_back (newTunnel); m_InboundTunnels.push_back (newTunnel);
auto pool = newTunnel->GetTunnelPool (); auto pool = newTunnel->GetTunnelPool ();
@ -1023,7 +1002,7 @@ namespace tunnel
inboundTunnel->SetTunnelPool (pool); inboundTunnel->SetTunnelPool (pool);
inboundTunnel->SetState (eTunnelStateEstablished); inboundTunnel->SetState (eTunnelStateEstablished);
m_InboundTunnels.push_back (inboundTunnel); m_InboundTunnels.push_back (inboundTunnel);
m_Tunnels[inboundTunnel->GetTunnelID ()] = inboundTunnel; AddTunnel (inboundTunnel);
return inboundTunnel; return inboundTunnel;
} }
@ -1057,21 +1036,12 @@ namespace tunnel
int Tunnels::GetTransitTunnelsExpirationTimeout () int Tunnels::GetTransitTunnelsExpirationTimeout ()
{ {
int timeout = 0; return m_TransitTunnels.GetTransitTunnelsExpirationTimeout ();
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
// TODO: possible race condition with I2PControl
for (const auto& it : m_TransitTunnels)
{
int t = it->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT - ts;
if (t > timeout) timeout = t;
}
return timeout;
} }
size_t Tunnels::CountTransitTunnels() const size_t Tunnels::CountTransitTunnels() const
{ {
// TODO: locking return m_TransitTunnels.GetNumTransitTunnels ();
return m_TransitTunnels.size();
} }
size_t Tunnels::CountInboundTunnels() const size_t Tunnels::CountInboundTunnels() const

11
libi2pd/Tunnel.h

@ -223,8 +223,9 @@ namespace tunnel
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; };
std::shared_ptr<TunnelBase> GetTunnel (uint32_t tunnelID); std::shared_ptr<TunnelBase> GetTunnel (uint32_t tunnelID);
bool AddTunnel (std::shared_ptr<TunnelBase> tunnel);
void RemoveTunnel (uint32_t tunnelID);
int GetTransitTunnelsExpirationTimeout (); int GetTransitTunnelsExpirationTimeout ();
bool 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);
std::shared_ptr<InboundTunnel> CreateInboundTunnel (std::shared_ptr<TunnelConfig> config, std::shared_ptr<TunnelPool> pool, std::shared_ptr<OutboundTunnel> outboundTunnel); std::shared_ptr<InboundTunnel> CreateInboundTunnel (std::shared_ptr<TunnelConfig> config, std::shared_ptr<TunnelPool> pool, std::shared_ptr<OutboundTunnel> outboundTunnel);
@ -243,7 +244,7 @@ namespace tunnel
void SetMaxNumTransitTunnels (uint32_t maxNumTransitTunnels); void SetMaxNumTransitTunnels (uint32_t maxNumTransitTunnels);
uint32_t GetMaxNumTransitTunnels () const { return m_MaxNumTransitTunnels; }; uint32_t GetMaxNumTransitTunnels () const { return m_MaxNumTransitTunnels; };
int GetCongestionLevel() const { return m_MaxNumTransitTunnels ? CONGESTION_LEVEL_FULL * m_TransitTunnels.size() / m_MaxNumTransitTunnels : CONGESTION_LEVEL_FULL; } int GetCongestionLevel() const { return m_MaxNumTransitTunnels ? CONGESTION_LEVEL_FULL * m_TransitTunnels.GetNumTransitTunnels () / m_MaxNumTransitTunnels : CONGESTION_LEVEL_FULL; }
std::mt19937& GetRng () { return m_Rng; }; std::mt19937& GetRng () { return m_Rng; };
@ -265,7 +266,6 @@ namespace tunnel
void ManageTunnels (uint64_t ts); void ManageTunnels (uint64_t ts);
void ManageOutboundTunnels (uint64_t ts); void ManageOutboundTunnels (uint64_t ts);
void ManageInboundTunnels (uint64_t ts); void ManageInboundTunnels (uint64_t ts);
void ManageTransitTunnels (uint64_t ts);
void ManagePendingTunnels (uint64_t ts); void ManagePendingTunnels (uint64_t ts);
template<class PendingTunnels> template<class PendingTunnels>
void ManagePendingTunnels (PendingTunnels& pendingTunnels, uint64_t ts); void ManagePendingTunnels (PendingTunnels& pendingTunnels, uint64_t ts);
@ -300,7 +300,6 @@ namespace tunnel
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::list<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::list<std::shared_ptr<TransitTunnel> > m_TransitTunnels;
std::unordered_map<uint32_t, std::shared_ptr<TunnelBase> > m_Tunnels; // tunnelID->tunnel known by this id 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;
@ -314,14 +313,14 @@ namespace tunnel
double m_TunnelCreationSuccessRate; double m_TunnelCreationSuccessRate;
int m_TunnelCreationAttemptsNum; int m_TunnelCreationAttemptsNum;
std::mt19937 m_Rng; std::mt19937 m_Rng;
TransitTunnelBuildMsgHandler m_TransitTunnelBuildMsgHandler; TransitTunnels m_TransitTunnels;
public: public:
// for HTTP only // for HTTP only
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; }; auto& GetTransitTunnels () const { return m_TransitTunnels.GetTransitTunnels (); };
size_t CountTransitTunnels() const; size_t CountTransitTunnels() const;
size_t CountInboundTunnels() const; size_t CountInboundTunnels() const;

Loading…
Cancel
Save