mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 00:00:29 +03:00
fixed tunnel build race condition
This commit is contained in:
parent
79d2f69837
commit
9cd62d8873
@ -330,7 +330,10 @@ namespace i2p
|
|||||||
i2p::tunnel::tunnels.AddInboundTunnel (static_cast<i2p::tunnel::InboundTunnel *>(tunnel));
|
i2p::tunnel::tunnels.AddInboundTunnel (static_cast<i2p::tunnel::InboundTunnel *>(tunnel));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
LogPrint ("Inbound tunnel ", tunnel->GetTunnelID (), " has been declined");
|
LogPrint ("Inbound tunnel ", tunnel->GetTunnelID (), " has been declined");
|
||||||
|
tunnel->SetState (i2p::tunnel::eTunnelStateBuildFailed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -386,7 +389,10 @@ namespace i2p
|
|||||||
i2p::tunnel::tunnels.AddOutboundTunnel (static_cast<i2p::tunnel::OutboundTunnel *>(tunnel));
|
i2p::tunnel::tunnels.AddOutboundTunnel (static_cast<i2p::tunnel::OutboundTunnel *>(tunnel));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
LogPrint ("Outbound tunnel ", tunnel->GetTunnelID (), " has been declined");
|
LogPrint ("Outbound tunnel ", tunnel->GetTunnelID (), " has been declined");
|
||||||
|
tunnel->SetState (i2p::tunnel::eTunnelStateBuildFailed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint ("Pending tunnel for message ", replyMsgID, " not found");
|
LogPrint ("Pending tunnel for message ", replyMsgID, " not found");
|
||||||
|
39
Tunnel.cpp
39
Tunnel.cpp
@ -246,7 +246,10 @@ namespace tunnel
|
|||||||
{
|
{
|
||||||
auto it = m_PendingTunnels.find(replyMsgID);
|
auto it = m_PendingTunnels.find(replyMsgID);
|
||||||
if (it != m_PendingTunnels.end ())
|
if (it != m_PendingTunnels.end ())
|
||||||
|
{
|
||||||
|
it->second->SetState (eTunnelStateBuildReplyReceived);
|
||||||
return it->second;
|
return it->second;
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,23 +372,35 @@ namespace tunnel
|
|||||||
|
|
||||||
void Tunnels::ManageTunnels ()
|
void Tunnels::ManageTunnels ()
|
||||||
{
|
{
|
||||||
// check pending tunnel. delete non-successive
|
// check pending tunnel. delete failed or timeout
|
||||||
uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
|
uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
for (auto it = m_PendingTunnels.begin (); it != m_PendingTunnels.end ();)
|
for (auto it = m_PendingTunnels.begin (); it != m_PendingTunnels.end ();)
|
||||||
{
|
{
|
||||||
if (it->second->GetState () == eTunnelStatePending)
|
auto tunnel = it->second;
|
||||||
|
switch (tunnel->GetState ())
|
||||||
{
|
{
|
||||||
if (ts > it->second->GetCreationTime () + TUNNEL_CREATION_TIMEOUT)
|
case eTunnelStatePending:
|
||||||
{
|
if (ts > tunnel->GetCreationTime () + TUNNEL_CREATION_TIMEOUT)
|
||||||
LogPrint ("Pending tunnel build request ", it->first, " was not successive. Deleted");
|
{
|
||||||
delete it->second;
|
LogPrint ("Pending tunnel build request ", it->first, " timeout. Deleted");
|
||||||
|
delete tunnel;
|
||||||
|
it = m_PendingTunnels.erase (it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
it++;
|
||||||
|
break;
|
||||||
|
case eTunnelStateBuildFailed:
|
||||||
|
LogPrint ("Pending tunnel build request ", it->first, " failed. Deleted");
|
||||||
|
delete tunnel;
|
||||||
it = m_PendingTunnels.erase (it);
|
it = m_PendingTunnels.erase (it);
|
||||||
}
|
break;
|
||||||
else
|
case eTunnelStateBuildReplyReceived:
|
||||||
|
// intermidiate state, will be either established of build failed
|
||||||
it++;
|
it++;
|
||||||
}
|
break;
|
||||||
else
|
default:
|
||||||
it = m_PendingTunnels.erase (it);
|
it = m_PendingTunnels.erase (it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ManageInboundTunnels ();
|
ManageInboundTunnels ();
|
||||||
@ -405,7 +420,7 @@ namespace tunnel
|
|||||||
if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
||||||
{
|
{
|
||||||
LogPrint ("Tunnel ", tunnel->GetTunnelID (), " expired");
|
LogPrint ("Tunnel ", tunnel->GetTunnelID (), " expired");
|
||||||
auto pool = (*it)->GetTunnelPool ();
|
auto pool = tunnel->GetTunnelPool ();
|
||||||
if (pool)
|
if (pool)
|
||||||
pool->TunnelExpired (tunnel);
|
pool->TunnelExpired (tunnel);
|
||||||
it = m_OutboundTunnels.erase (it);
|
it = m_OutboundTunnels.erase (it);
|
||||||
|
4
Tunnel.h
4
Tunnel.h
@ -23,12 +23,14 @@ namespace tunnel
|
|||||||
{
|
{
|
||||||
const int TUNNEL_EXPIRATION_TIMEOUT = 660; // 11 minutes
|
const int TUNNEL_EXPIRATION_TIMEOUT = 660; // 11 minutes
|
||||||
const int TUNNEL_EXPIRATION_THRESHOLD = 60; // 1 minute
|
const int TUNNEL_EXPIRATION_THRESHOLD = 60; // 1 minute
|
||||||
const int TUNNEL_CREATION_TIMEOUT = 20; // 20 seconds
|
const int TUNNEL_CREATION_TIMEOUT = 30; // 30 seconds
|
||||||
const int STANDARD_NUM_RECORDS = 5; // in VariableTunnelBuild message
|
const int STANDARD_NUM_RECORDS = 5; // in VariableTunnelBuild message
|
||||||
|
|
||||||
enum TunnelState
|
enum TunnelState
|
||||||
{
|
{
|
||||||
eTunnelStatePending,
|
eTunnelStatePending,
|
||||||
|
eTunnelStateBuildReplyReceived,
|
||||||
|
eTunnelStateBuildFailed,
|
||||||
eTunnelStateEstablished,
|
eTunnelStateEstablished,
|
||||||
eTunnelStateTestFailed,
|
eTunnelStateTestFailed,
|
||||||
eTunnelStateFailed,
|
eTunnelStateFailed,
|
||||||
|
Loading…
Reference in New Issue
Block a user