mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 08:00:38 +03:00
commit
bf3615fb32
@ -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)
|
||||
{
|
||||
|
@ -447,6 +447,13 @@ namespace util
|
||||
s << "<br>\r\n<b>Routers:</b> " << i2p::data::netdb.GetNumRouters () << " ";
|
||||
s << "<b>Floodfills:</b> " << i2p::data::netdb.GetNumFloodfills () << " ";
|
||||
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)
|
||||
@ -603,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 << "<span class=failed_tunnel> " << "Failed</span>";
|
||||
else if (state == i2p::tunnel::eTunnelStateExpiring)
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -619,13 +626,13 @@ namespace util
|
||||
s << "<b>Transit tunnels:</b><br>\r\n<br>\r\n";
|
||||
for (auto it: i2p::tunnel::tunnels.GetTransitTunnels ())
|
||||
{
|
||||
if (dynamic_cast<i2p::tunnel::TransitTunnelGateway *>(it.second))
|
||||
s << it.second->GetTunnelID () << " ⇒ ";
|
||||
else if (dynamic_cast<i2p::tunnel::TransitTunnelEndpoint *>(it.second))
|
||||
s << " ⇒ " << it.second->GetTunnelID ();
|
||||
if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelGateway>(it))
|
||||
s << it->GetTunnelID () << " ⇒ ";
|
||||
else if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelEndpoint>(it))
|
||||
s << " ⇒ " << it->GetTunnelID ();
|
||||
else
|
||||
s << " ⇒ " << it.second->GetTunnelID () << " ⇒ ";
|
||||
s << " " << it.second->GetNumTransmittedBytes () << "<br>\r\n";
|
||||
s << " ⇒ " << it->GetTunnelID () << " ⇒ ";
|
||||
s << " " << it->GetNumTransmittedBytes () << "<br>\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
11
NetDb.cpp
11
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<IdentHash> NetDb::GetClosestFloodfills (const IdentHash& destination, size_t num,
|
||||
std::set<IdentHash>& excluded) const
|
||||
std::set<IdentHash>& excluded, bool closeThanUsOnly) const
|
||||
{
|
||||
struct Sorted
|
||||
{
|
||||
@ -895,6 +895,8 @@ namespace data
|
||||
|
||||
std::set<Sorted> sorted;
|
||||
IdentHash destKey = CreateRoutingKey (destination);
|
||||
XORMetric ourMetric;
|
||||
if (closeThanUsOnly) ourMetric = destKey ^ i2p::context.GetIdentHash ();
|
||||
{
|
||||
std::unique_lock<std::mutex> 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
|
||||
|
2
NetDb.h
2
NetDb.h
@ -60,7 +60,7 @@ namespace data
|
||||
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::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;
|
||||
void SetUnreachable (const IdentHash& ident, bool unreachable);
|
||||
|
||||
|
@ -85,7 +85,7 @@ namespace tunnel
|
||||
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 * 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<TransitTunnelEndpoint> (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<TransitTunnelGateway> (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint (eLogInfo, "TransitTunnel: ", receiveTunnelID, "->", nextTunnelID, " created");
|
||||
return new TransitTunnelParticipant (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey);
|
||||
return std::make_shared<TransitTunnelParticipant> (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ namespace tunnel
|
||||
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 * layerKey,const uint8_t * ivKey,
|
||||
bool isGateway, bool isEndpoint);
|
||||
|
160
Tunnel.cpp
160
Tunnel.cpp
@ -205,6 +205,26 @@ namespace tunnel
|
||||
PrintHops (s);
|
||||
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)
|
||||
{
|
||||
@ -257,27 +277,16 @@ namespace tunnel
|
||||
|
||||
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);
|
||||
if (it != m_InboundTunnels.end ())
|
||||
auto it = m_Tunnels.find(tunnelID);
|
||||
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 nullptr;
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<InboundTunnel> Tunnels::GetPendingInboundTunnel (uint32_t replyMsgID)
|
||||
{
|
||||
return GetPendingTunnel (replyMsgID, m_PendingInboundTunnels);
|
||||
@ -306,11 +315,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;
|
||||
@ -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_TransitTunnels.insert (std::make_pair (tunnel->GetTunnelID (), tunnel)).second)
|
||||
{
|
||||
LogPrint (eLogError, "Tunnel: transit tunnel with id ", tunnel->GetTunnelID (), " already exists");
|
||||
delete 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");
|
||||
}
|
||||
|
||||
void Tunnels::Start ()
|
||||
@ -404,10 +411,10 @@ namespace tunnel
|
||||
if (msg)
|
||||
{
|
||||
uint32_t prevTunnelID = 0, tunnelID = 0;
|
||||
TunnelBase * prevTunnel = nullptr;
|
||||
std::shared_ptr<TunnelBase> prevTunnel;
|
||||
do
|
||||
{
|
||||
TunnelBase * tunnel = nullptr;
|
||||
std::shared_ptr<TunnelBase> tunnel;
|
||||
uint8_t typeID = msg->GetTypeID ();
|
||||
switch (typeID)
|
||||
{
|
||||
@ -420,10 +427,8 @@ namespace tunnel
|
||||
else if (prevTunnel)
|
||||
prevTunnel->FlushTunnelDataMsgs ();
|
||||
|
||||
if (!tunnel && typeID == eI2NPTunnelData)
|
||||
tunnel = GetInboundTunnel (tunnelID).get ();
|
||||
if (!tunnel)
|
||||
tunnel = GetTransitTunnel (tunnelID);
|
||||
tunnel = GetTunnel (tunnelID);
|
||||
if (tunnel)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -580,6 +585,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
|
||||
@ -621,13 +627,14 @@ 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");
|
||||
auto pool = tunnel->GetTunnelPool ();
|
||||
if (pool)
|
||||
pool->TunnelExpired (tunnel);
|
||||
m_Tunnels.erase (tunnel->GetTunnelID ());
|
||||
it = m_InboundTunnels.erase (it);
|
||||
}
|
||||
else
|
||||
@ -682,15 +689,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<std::mutex> l(m_TransitTunnelsMutex);
|
||||
it = m_TransitTunnels.erase (it);
|
||||
}
|
||||
delete tmp;
|
||||
LogPrint (eLogDebug, "Tunnel: Transit tunnel with id ", tunnel->GetTunnelID (), " expired");
|
||||
m_Tunnels.erase (tunnel->GetTunnelID ());
|
||||
it = m_TransitTunnels.erase (it);
|
||||
}
|
||||
else
|
||||
it++;
|
||||
@ -744,6 +748,7 @@ namespace tunnel
|
||||
|
||||
void Tunnels::AddOutboundTunnel (std::shared_ptr<OutboundTunnel> newTunnel)
|
||||
{
|
||||
// we don't need to insert it to m_Tunnels
|
||||
m_OutboundTunnels.push_back (newTunnel);
|
||||
auto pool = newTunnel->GetTunnelPool ();
|
||||
if (pool && pool->IsActive ())
|
||||
@ -754,46 +759,79 @@ namespace tunnel
|
||||
|
||||
void Tunnels::AddInboundTunnel (std::shared_ptr<InboundTunnel> newTunnel)
|
||||
{
|
||||
m_InboundTunnels[newTunnel->GetTunnelID ()] = newTunnel;
|
||||
auto pool = newTunnel->GetTunnelPool ();
|
||||
if (!pool)
|
||||
{
|
||||
// build symmetric outbound tunnel
|
||||
CreateTunnel<OutboundTunnel> (std::make_shared<TunnelConfig>(newTunnel->GetInvertedPeers (),
|
||||
newTunnel->GetNextTunnelID (), newTunnel->GetNextIdentHash ()),
|
||||
GetNextOutboundTunnel ());
|
||||
if (m_Tunnels.emplace (newTunnel->GetTunnelID (), newTunnel).second)
|
||||
{
|
||||
m_InboundTunnels.push_back (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
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
void Tunnels::CreateZeroHopsInboundTunnel ()
|
||||
{
|
||||
CreateTunnel<InboundTunnel> (
|
||||
/*CreateTunnel<InboundTunnel> (
|
||||
std::make_shared<TunnelConfig> (std::vector<std::shared_ptr<const i2p::data::IdentityEx> >
|
||||
{
|
||||
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 timeout = 0;
|
||||
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)
|
||||
{
|
||||
int t = it.second->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT - ts;
|
||||
int t = it->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT - ts;
|
||||
if (t > timeout) timeout = t;
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
38
Tunnel.h
38
Tunnel.h
@ -3,6 +3,7 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@ -71,6 +72,8 @@ namespace tunnel
|
||||
void SetTunnelPool (std::shared_ptr<TunnelPool> 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<i2p::I2NPMessage> msg);
|
||||
@ -111,21 +114,34 @@ namespace tunnel
|
||||
TunnelGateway m_Gateway;
|
||||
i2p::data::IdentHash m_EndpointIdentHash;
|
||||
};
|
||||
|
||||
|
||||
class InboundTunnel: public Tunnel, public std::enable_shared_from_this<InboundTunnel>
|
||||
{
|
||||
public:
|
||||
|
||||
InboundTunnel (std::shared_ptr<const TunnelConfig> config): Tunnel (config), m_Endpoint (true) {};
|
||||
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;
|
||||
|
||||
private:
|
||||
|
||||
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
|
||||
{
|
||||
@ -136,15 +152,14 @@ namespace tunnel
|
||||
void Start ();
|
||||
void Stop ();
|
||||
|
||||
std::shared_ptr<InboundTunnel> GetInboundTunnel (uint32_t tunnelID);
|
||||
std::shared_ptr<InboundTunnel> GetPendingInboundTunnel (uint32_t replyMsgID);
|
||||
std::shared_ptr<OutboundTunnel> GetPendingOutboundTunnel (uint32_t replyMsgID);
|
||||
std::shared_ptr<InboundTunnel> GetNextInboundTunnel ();
|
||||
std::shared_ptr<OutboundTunnel> GetNextOutboundTunnel ();
|
||||
std::shared_ptr<TunnelPool> GetExploratoryPool () const { return m_ExploratoryPool; };
|
||||
TransitTunnel * GetTransitTunnel (uint32_t tunnelID);
|
||||
std::shared_ptr<TunnelBase> GetTunnel (uint32_t tunnelID);
|
||||
int GetTransitTunnelsExpirationTimeout ();
|
||||
void AddTransitTunnel (TransitTunnel * tunnel);
|
||||
void AddTransitTunnel (std::shared_ptr<TransitTunnel> tunnel);
|
||||
void AddOutboundTunnel (std::shared_ptr<OutboundTunnel> newTunnel);
|
||||
void AddInboundTunnel (std::shared_ptr<InboundTunnel> newTunnel);
|
||||
void PostTunnelData (std::shared_ptr<I2NPMessage> msg);
|
||||
@ -163,7 +178,7 @@ namespace tunnel
|
||||
template<class TTunnel>
|
||||
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 ManageTunnels ();
|
||||
@ -183,10 +198,10 @@ namespace tunnel
|
||||
std::thread * m_Thread;
|
||||
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<InboundTunnel> > m_InboundTunnels;
|
||||
std::list<std::shared_ptr<InboundTunnel> > m_InboundTunnels;
|
||||
std::list<std::shared_ptr<OutboundTunnel> > m_OutboundTunnels;
|
||||
std::mutex m_TransitTunnelsMutex;
|
||||
std::map<uint32_t, TransitTunnel *> m_TransitTunnels;
|
||||
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::mutex m_PoolsMutex;
|
||||
std::list<std::shared_ptr<TunnelPool>> m_Pools;
|
||||
std::shared_ptr<TunnelPool> m_ExploratoryPool;
|
||||
@ -201,6 +216,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() const;
|
||||
size_t CountInboundTunnels() const;
|
||||
size_t CountOutboundTunnels() const;
|
||||
|
||||
int GetQueueSize () { return m_Queue.GetSize (); };
|
||||
int GetTunnelCreationSuccessRate () const // in percents
|
||||
{
|
||||
|
@ -108,7 +108,7 @@ namespace tunnel
|
||||
}
|
||||
};
|
||||
|
||||
class TunnelConfig: public std::enable_shared_from_this<TunnelConfig>
|
||||
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<class Peers>
|
||||
void CreatePeers (const Peers& peers)
|
||||
@ -222,6 +224,24 @@ namespace tunnel
|
||||
private:
|
||||
|
||||
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…
Reference in New Issue
Block a user