From 014e1c54eb962e3df5f8ce681c5c54935b29f757 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 17 Mar 2014 16:50:03 -0400 Subject: [PATCH] tunnel test --- I2NPProtocol.cpp | 23 ++++++++++++++--------- Tunnel.cpp | 3 +++ TunnelPool.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ TunnelPool.h | 6 ++++++ 4 files changed, 64 insertions(+), 9 deletions(-) diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 8990da3b..5b2c66f1 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -425,11 +425,6 @@ namespace i2p int size = be16toh (header->size); switch (header->typeID) { - case eI2NPDeliveryStatus: - LogPrint ("DeliveryStatus"); - // we assume DeliveryStatusMessage is sent with garlic only - i2p::garlic::routing.HandleDeliveryStatusMessage (buf, size); - break; case eI2NPVariableTunnelBuild: LogPrint ("VariableTunnelBuild"); HandleVariableTunnelBuildMsg (msgID, buf, size); @@ -461,6 +456,10 @@ namespace i2p LogPrint ("TunnelGateway"); HandleTunnelGatewayMsg (msg); break; + case eI2NPGarlic: + LogPrint ("Garlic"); + i2p::garlic::routing.HandleGarlicMessage (msg); + break; case eI2NPDatabaseStore: LogPrint ("DatabaseStore"); i2p::data::netdb.PostI2NPMsg (msg); @@ -468,11 +467,17 @@ namespace i2p case eI2NPDatabaseSearchReply: LogPrint ("DatabaseSearchReply"); i2p::data::netdb.PostI2NPMsg (msg); + break; + case eI2NPDeliveryStatus: + LogPrint ("DeliveryStatus"); + if (msg->from && msg->from->GetTunnelPool ()) + msg->from->GetTunnelPool ()->ProcessDeliveryStatus (msg); + else + { + i2p::garlic::routing.HandleDeliveryStatusMessage (msg->GetPayload (), msg->GetLength ()); + DeleteI2NPMessage (msg); + } break; - case eI2NPGarlic: - LogPrint ("Garlic"); - i2p::garlic::routing.HandleGarlicMessage (msg); - break; default: HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ()); DeleteI2NPMessage (msg); diff --git a/Tunnel.cpp b/Tunnel.cpp index 5d93c50a..0ebd6345 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -502,7 +502,10 @@ namespace tunnel void Tunnels::ManageTunnelPools () { for (auto& it: m_Pools) + { it->CreateTunnels (); + it->TestTunnels (); + } } void Tunnels::PostTunnelData (I2NPMessage * msg) diff --git a/TunnelPool.cpp b/TunnelPool.cpp index 6d6516ec..f16b389d 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -1,9 +1,11 @@ #include +#include "I2PEndian.h" #include "CryptoConst.h" #include "Tunnel.h" #include "NetDb.h" #include "Timestamp.h" #include "RouterContext.h" +#include "Garlic.h" #include "TunnelPool.h" namespace i2p @@ -48,6 +50,8 @@ namespace tunnel void TunnelPool::TunnelExpired (OutboundTunnel * expiredTunnel) { m_OutboundTunnels.erase (expiredTunnel); + if (expiredTunnel == m_LastOutboundTunnel) + m_LastOutboundTunnel = nullptr; } std::vector TunnelPool::GetInboundTunnels (int num) const @@ -90,6 +94,43 @@ namespace tunnel CreateOutboundTunnel (); } + void TunnelPool::TestTunnels () + { + auto& rnd = i2p::context.GetRandomNumberGenerator (); + for (auto it: m_Tests) + { + LogPrint ("Tunnel test ", (int)it.first, " failed"); + // both outbound and inbound tunnels considered as invalid + TunnelExpired (it.second.first); + TunnelExpired (it.second.second); + } + m_Tests.clear (); + auto it1 = m_OutboundTunnels.begin (); + auto it2 = m_InboundTunnels.begin (); + while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ()) + { + uint32_t msgID = rnd.GenerateWord32 (); + m_Tests[msgID] = std::make_pair (*it1, *it2); + (*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (), + CreateDeliveryStatusMsg (msgID)); + it1++; it2++; + } + } + + void TunnelPool::ProcessDeliveryStatus (I2NPMessage * msg) + { + I2NPDeliveryStatusMsg * deliveryStatus = (I2NPDeliveryStatusMsg *)msg->GetPayload (); + auto it = m_Tests.find (be32toh (deliveryStatus->msgID)); + if (it != m_Tests.end ()) + { + LogPrint ("Tunnel test ", it->first, " successive. ", i2p::util::GetMillisecondsSinceEpoch () - be64toh (deliveryStatus->timestamp), " milliseconds"); + m_Tests.erase (it); + } + else + i2p::garlic::routing.HandleDeliveryStatusMessage (msg->GetPayload (), msg->GetLength ()); // TODO: + DeleteI2NPMessage (msg); + } + void TunnelPool::CreateInboundTunnel () { OutboundTunnel * outboundTunnel = m_OutboundTunnels.size () > 0 ? diff --git a/TunnelPool.h b/TunnelPool.h index f8b6aab5..8cef8375 100644 --- a/TunnelPool.h +++ b/TunnelPool.h @@ -1,8 +1,10 @@ #ifndef TUNNEL_POOL__ #define TUNNEL_POOL__ +#include #include #include +#include #include "Identity.h" #include "LeaseSet.h" #include "I2NPProtocol.h" @@ -34,6 +36,9 @@ namespace tunnel std::vector GetInboundTunnels (int num) const; OutboundTunnel * GetNextOutboundTunnel (); + void TestTunnels (); + void ProcessDeliveryStatus (I2NPMessage * msg); + private: void CreateInboundTunnel (); @@ -46,6 +51,7 @@ namespace tunnel int m_NumTunnels; std::set m_InboundTunnels; // recent tunnel appears first std::set m_OutboundTunnels; + std::map > m_Tests; OutboundTunnel * m_LastOutboundTunnel; }; }