mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-02 19:14:01 +01:00
commit
bf3615fb32
|
@ -99,16 +99,22 @@ namespace client
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientContext::Stop ()
|
void ClientContext::Stop ()
|
||||||
|
{
|
||||||
|
if (m_HttpProxy)
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "Clients: stopping HTTP Proxy");
|
LogPrint(eLogInfo, "Clients: stopping HTTP Proxy");
|
||||||
m_HttpProxy->Stop();
|
m_HttpProxy->Stop();
|
||||||
delete m_HttpProxy;
|
delete m_HttpProxy;
|
||||||
m_HttpProxy = nullptr;
|
m_HttpProxy = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_SocksProxy)
|
||||||
|
{
|
||||||
LogPrint(eLogInfo, "Clients: stopping SOCKS Proxy");
|
LogPrint(eLogInfo, "Clients: stopping SOCKS Proxy");
|
||||||
m_SocksProxy->Stop();
|
m_SocksProxy->Stop();
|
||||||
delete m_SocksProxy;
|
delete m_SocksProxy;
|
||||||
m_SocksProxy = nullptr;
|
m_SocksProxy = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& it: m_ClientTunnels)
|
for (auto& it: m_ClientTunnels)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
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
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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
126
Tunnel.cpp
126
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,16 +689,13 @@ 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 ());
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> l(m_TransitTunnelsMutex);
|
|
||||||
it = m_TransitTunnels.erase (it);
|
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,7 +759,9 @@ 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)
|
||||||
|
{
|
||||||
|
m_InboundTunnels.push_back (newTunnel);
|
||||||
auto pool = newTunnel->GetTunnelPool ();
|
auto pool = newTunnel->GetTunnelPool ();
|
||||||
if (!pool)
|
if (!pool)
|
||||||
{
|
{
|
||||||
|
@ -771,29 +778,60 @@ namespace tunnel
|
||||||
newTunnel->SetTunnelPool (nullptr);
|
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
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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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…
Reference in a new issue