diff --git a/Tunnel.cpp b/Tunnel.cpp index f189f5c3..c44921c1 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -18,7 +18,7 @@ namespace tunnel { Tunnel::Tunnel (TunnelConfig * config): - m_Config (config), m_Pool (nullptr), m_State (eTunnelStatePending) + m_Config (config), m_Pool (nullptr), m_State (eTunnelStatePending), m_IsRecreated (false) { } @@ -542,12 +542,17 @@ namespace tunnel } else { - if (tunnel->IsEstablished () && ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) + if (tunnel->IsEstablished ()) { - tunnel->SetState (eTunnelStateExpiring); - auto pool = tunnel->GetTunnelPool (); - if (pool) - pool->RecreateOutboundTunnel (tunnel); + if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) + { + tunnel->SetIsRecreated (); + auto pool = tunnel->GetTunnelPool (); + if (pool) + pool->RecreateOutboundTunnel (tunnel); + } + if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) + tunnel->SetState (eTunnelStateExpiring); } it++; } @@ -585,12 +590,18 @@ namespace tunnel } else { - if (tunnel->IsEstablished () && ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) + if (tunnel->IsEstablished ()) { - tunnel->SetState (eTunnelStateExpiring); - auto pool = tunnel->GetTunnelPool (); - if (pool) - pool->RecreateInboundTunnel (tunnel); + if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) + { + tunnel->SetIsRecreated (); + auto pool = tunnel->GetTunnelPool (); + if (pool) + pool->RecreateInboundTunnel (tunnel); + } + + if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) + tunnel->SetState (eTunnelStateExpiring); } it++; } diff --git a/Tunnel.h b/Tunnel.h index b59e3d7f..cd8a1379 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -24,6 +24,7 @@ namespace tunnel { const int TUNNEL_EXPIRATION_TIMEOUT = 660; // 11 minutes const int TUNNEL_EXPIRATION_THRESHOLD = 60; // 1 minute + const int TUNNEL_RECREATION_THRESHOLD = 90; // 1.5 minutes const int TUNNEL_CREATION_TIMEOUT = 30; // 30 seconds const int STANDARD_NUM_RECORDS = 5; // in VariableTunnelBuild message @@ -54,6 +55,8 @@ namespace tunnel void SetState (TunnelState state) { m_State = state; }; bool IsEstablished () const { return m_State == eTunnelStateEstablished; }; bool IsFailed () const { return m_State == eTunnelStateFailed; }; + bool IsRecreated () const { return m_IsRecreated; }; + void SetIsRecreated () { m_IsRecreated = true; }; std::shared_ptr GetTunnelPool () const { return m_Pool; }; void SetTunnelPool (std::shared_ptr pool) { m_Pool = pool; }; @@ -71,6 +74,7 @@ namespace tunnel TunnelConfig * m_Config; std::shared_ptr m_Pool; // pool, tunnel belongs to, or null TunnelState m_State; + bool m_IsRecreated; }; class OutboundTunnel: public Tunnel diff --git a/TunnelPool.cpp b/TunnelPool.cpp index 6315e501..505b82f3 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -140,7 +140,10 @@ namespace tunnel std::unique_lock l(m_OutboundTunnelsMutex); for (auto it: m_OutboundTunnels) if (it->IsEstablished () && old->GetEndpointRouter ()->GetIdentHash () == it->GetEndpointRouter ()->GetIdentHash ()) + { tunnel = it; + break; + } } if (!tunnel)