diff --git a/Tunnel.cpp b/Tunnel.cpp index 0c1b278a..12420b13 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -29,12 +29,14 @@ namespace tunnel void Tunnel::Build (uint32_t replyMsgID, std::shared_ptr outboundTunnel) { +#ifdef WITH_EVENTS + std::string peers = i2p::context.GetIdentity()->GetIdentHash().ToBase64(); +#endif auto numHops = m_Config->GetNumHops (); int numRecords = numHops <= STANDARD_NUM_RECORDS ? STANDARD_NUM_RECORDS : numHops; auto msg = NewI2NPShortMessage (); *msg->GetPayload () = numRecords; msg->len += numRecords*TUNNEL_BUILD_RECORD_SIZE + 1; - // shuffle records std::vector recordIndicies; for (int i = 0; i < numRecords; i++) recordIndicies.push_back(i); @@ -55,8 +57,15 @@ namespace tunnel hop->CreateBuildRequestRecord (records + idx*TUNNEL_BUILD_RECORD_SIZE, msgID); hop->recordIndex = idx; i++; +#ifdef WITH_EVENTS + peers += ":" + hop->ident->GetIdentHash().ToBase64(); +#endif hop = hop->next; } +#ifdef WITH_EVENTS + EmitTunnelEvent("tunnel.build", this, peers); +#endif + // fill up fake records with random data for (int i = numHops; i < numRecords; i++) { @@ -182,6 +191,13 @@ namespace tunnel return ret; } + void Tunnel::SetState(TunnelState state) + { + m_State = state; + EmitTunnelEvent("tunnel.state", this, state); + } + + void Tunnel::PrintHops (std::stringstream& s) const { // hops are in inverted order, we must print in direct order @@ -776,9 +792,9 @@ namespace tunnel std::shared_ptr Tunnels::CreateInboundTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel) { - if (config) + if (config) return CreateTunnel(config, outboundTunnel); - else + else return CreateZeroHopsInboundTunnel (); } diff --git a/Tunnel.h b/Tunnel.h index 5bc8b195..5b596886 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -19,11 +19,38 @@ #include "TunnelGateway.h" #include "TunnelBase.h" #include "I2NPProtocol.h" +#include "Event.h" namespace i2p { namespace tunnel -{ +{ + + template + static void EmitTunnelEvent(const std::string & ev, const TunnelT & t) + { +#ifdef WITH_EVENTS + EmitEvent({{"type", ev}, {"tid", std::to_string(t->GetTunnelID())}}); +#endif + } + + template + static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const T & val) + { +#ifdef WITH_EVENTS + EmitEvent({{"type", ev}, {"tid", std::to_string(t->GetTunnelID())}, {"value", std::to_string(val)}, {"inbound", std::to_string(t->IsInbound())}}); +#endif + } + + template + static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const std::string & val) + { +#ifdef WITH_EVENTS + EmitEvent({{"type", ev}, {"tid", std::to_string(t->GetTunnelID())}, {"value", val}, {"inbound", std::to_string(t->IsInbound())}}); +#endif + } + + 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 @@ -40,7 +67,7 @@ namespace tunnel eTunnelStateFailed, eTunnelStateExpiring }; - + class OutboundTunnel; class InboundTunnel; class Tunnel: public TunnelBase @@ -62,7 +89,7 @@ namespace tunnel std::vector > GetPeers () const; std::vector > GetInvertedPeers () const; TunnelState GetState () const { return m_State; }; - void SetState (TunnelState state) { m_State = state; }; + void SetState (TunnelState state); bool IsEstablished () const { return m_State == eTunnelStateEstablished; }; bool IsFailed () const { return m_State == eTunnelStateFailed; }; bool IsRecreated () const { return m_IsRecreated; }; diff --git a/TunnelPool.cpp b/TunnelPool.cpp index 35272f2c..da38c1cf 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -8,11 +8,14 @@ #include "Transports.h" #include "Log.h" #include "TunnelPool.h" +#include "Destination.h" +#include "Event.h" namespace i2p { namespace tunnel { + TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels): m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops), m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels), m_IsActive (true), @@ -67,6 +70,7 @@ namespace tunnel { if (!m_IsActive) return; { + EmitTunnelEvent("tunnels.created", createdTunnel); std::unique_lock l(m_InboundTunnelsMutex); m_InboundTunnels.insert (createdTunnel); } @@ -77,7 +81,9 @@ namespace tunnel void TunnelPool::TunnelExpired (std::shared_ptr expiredTunnel) { if (expiredTunnel) - { + { + EmitTunnelEvent("tunnels.expired", expiredTunnel); + expiredTunnel->SetTunnelPool (nullptr); for (auto& it: m_Tests) if (it.second.second == expiredTunnel) it.second.second = nullptr; @@ -91,6 +97,7 @@ namespace tunnel { if (!m_IsActive) return; { + EmitTunnelEvent("tunnels.created", createdTunnel); std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.insert (createdTunnel); } @@ -101,6 +108,8 @@ namespace tunnel { if (expiredTunnel) { + EmitTunnelEvent("tunnels.expired", expiredTunnel); + expiredTunnel->SetTunnelPool (nullptr); for (auto& it: m_Tests) if (it.second.first == expiredTunnel) it.second.first = nullptr;