From 72e689791c9610ed7f1d25a0ce4f8e75d3950e8b Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 26 Jul 2014 20:56:42 -0400 Subject: [PATCH] tunnel state --- Tunnel.cpp | 15 ++++++++------- Tunnel.h | 17 +++++++++++++---- TunnelPool.cpp | 25 +++++++++++++++++++------ 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/Tunnel.cpp b/Tunnel.cpp index 1ce7ac82..94fc9b81 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -14,8 +14,8 @@ namespace i2p namespace tunnel { - Tunnel::Tunnel (TunnelConfig * config): m_Config (config), m_Pool (nullptr), - m_IsEstablished (false), m_IsFailed (false) + Tunnel::Tunnel (TunnelConfig * config): + m_Config (config), m_Pool (nullptr), m_State (eTunnelStatePending) { } @@ -111,7 +111,7 @@ namespace tunnel hop = hop->prev; } - m_IsEstablished = true; + bool established = true; hop = m_Config->GetFirstHop (); while (hop) { @@ -119,10 +119,10 @@ namespace tunnel LogPrint ("Ret code=", (int)record->ret); if (record->ret) // if any of participants declined the tunnel is not established - m_IsEstablished = false; + established = false; hop = hop->next; } - if (m_IsEstablished) + if (established) { // change reply keys to layer keys hop = m_Config->GetFirstHop (); @@ -132,7 +132,8 @@ namespace tunnel hop = hop->next; } } - return m_IsEstablished; + if (established) m_State = eTunnelStateEstablished; + return established; } void Tunnel::EncryptTunnelMsg (I2NPMessage * tunnelMsg) @@ -148,7 +149,7 @@ namespace tunnel void InboundTunnel::HandleTunnelDataMsg (I2NPMessage * msg) { - if (IsFailed ()) SetFailed (false); // incoming messages means a tunnel is alive + if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive msg->from = this; EncryptTunnelMsg (msg); m_Endpoint.HandleDecryptedTunnelDataMsg (msg); diff --git a/Tunnel.h b/Tunnel.h index 63adadc5..8feb4926 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -22,6 +22,14 @@ namespace i2p namespace tunnel { const int TUNNEL_EXPIRATION_TIMEOUT = 660; // 11 minutes + + enum TunnelState + { + eTunnelStatePending, + eTunnelStateEstablished, + eTunnelStateTestFailed, + eTunnelStateFailed + }; class OutboundTunnel; class InboundTunnel; @@ -35,9 +43,10 @@ namespace tunnel void Build (uint32_t replyMsgID, OutboundTunnel * outboundTunnel = 0); TunnelConfig * GetTunnelConfig () const { return m_Config; } - bool IsEstablished () const { return m_IsEstablished; }; - bool IsFailed () const { return m_IsFailed; }; - void SetFailed (bool failed) { m_IsFailed = failed; } + TunnelState GetState () const { return m_State; }; + void SetState (TunnelState state) { m_State = state; }; + bool IsEstablished () const { return m_State == eTunnelStateEstablished; }; + bool IsFailed () const { return m_State == eTunnelStateFailed; }; TunnelPool * GetTunnelPool () const { return m_Pool; }; void SetTunnelPool (TunnelPool * pool) { m_Pool = pool; }; @@ -53,7 +62,7 @@ namespace tunnel TunnelConfig * m_Config; TunnelPool * m_Pool; // pool, tunnel belongs to, or null - bool m_IsEstablished, m_IsFailed; + TunnelState m_State; }; class OutboundTunnel: public Tunnel diff --git a/TunnelPool.cpp b/TunnelPool.cpp index 7f65c731..4cc3e960 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -109,16 +109,26 @@ namespace tunnel for (auto it: m_Tests) { LogPrint ("Tunnel test ", (int)it.first, " failed"); - // both outbound and inbound tunnels considered as invalid + // if test failed again with another tunnel we consider it failed if (it.second.first) { - it.second.first->SetFailed (true); - m_OutboundTunnels.erase (it.second.first); + if (it.second.first->GetState () == eTunnelStateTestFailed) + { + it.second.first->SetState (eTunnelStateFailed); + m_OutboundTunnels.erase (it.second.first); + } + else + it.second.first->SetState (eTunnelStateTestFailed); } if (it.second.second) { - it.second.second->SetFailed (true); - m_InboundTunnels.erase (it.second.second); + if (it.second.second->GetState () == eTunnelStateTestFailed) + { + it.second.second->SetState (eTunnelStateFailed); + m_InboundTunnels.erase (it.second.second); + } + else + it.second.second->SetState (eTunnelStateTestFailed); } } m_Tests.clear (); @@ -138,7 +148,7 @@ namespace tunnel it2++; } if (!failed) - { + { uint32_t msgID = rnd.GenerateWord32 (); m_Tests[msgID] = std::make_pair (*it1, *it2); (*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (), @@ -156,6 +166,9 @@ namespace tunnel { LogPrint ("Tunnel test ", it->first, " successive. ", i2p::util::GetMillisecondsSinceEpoch () - be64toh (deliveryStatus->timestamp), " milliseconds"); m_Tests.erase (it); + // restore from test failed state if any + it->second.first->SetState (eTunnelStateEstablished); + it->second.second->SetState (eTunnelStateEstablished); } else i2p::garlic::routing.HandleDeliveryStatusMessage (msg->GetPayload (), msg->GetLength ()); // TODO: