diff --git a/Tunnel.cpp b/Tunnel.cpp index e1f5c035..e271052e 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -612,6 +612,7 @@ namespace tunnel for (auto it = pendingTunnels.begin (); it != pendingTunnels.end ();) { auto tunnel = it->second; + auto pool = tunnel->GetTunnelPool(); switch (tunnel->GetState ()) { case eTunnelStatePending: @@ -637,6 +638,8 @@ namespace tunnel #ifdef WITH_EVENTS EmitTunnelEvent("tunnel.state", tunnel.get(), eTunnelStateBuildFailed); #endif + // for i2lua + if(pool) pool->OnTunnelBuildResult(tunnel, eBuildResultTimeout); // delete it = pendingTunnels.erase (it); m_NumFailedTunnelCreations++; @@ -649,6 +652,9 @@ namespace tunnel #ifdef WITH_EVENTS EmitTunnelEvent("tunnel.state", tunnel.get(), eTunnelStateBuildFailed); #endif + // for i2lua + if(pool) pool->OnTunnelBuildResult(tunnel, eBuildResultRejected); + it = pendingTunnels.erase (it); m_NumFailedTunnelCreations++; break; diff --git a/TunnelPool.cpp b/TunnelPool.cpp index ccd4c12c..f8e34e7c 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -81,6 +81,8 @@ namespace tunnel } if (m_LocalDestination) m_LocalDestination->SetLeaseSetUpdated (); + + OnTunnelBuildResult(createdTunnel, eBuildResultOkay); } void TunnelPool::TunnelExpired (std::shared_ptr expiredTunnel) @@ -109,6 +111,8 @@ namespace tunnel std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.insert (createdTunnel); } + OnTunnelBuildResult(createdTunnel, eBuildResultOkay); + //CreatePairedInboundTunnel (createdTunnel); } @@ -576,5 +580,11 @@ namespace tunnel } return tun; } + + void TunnelPool::OnTunnelBuildResult(std::shared_ptr tunnel, TunnelBuildResult result) + { + auto peers = tunnel->GetPeers(); + if(m_CustomPeerSelector) m_CustomPeerSelector->OnBuildResult(peers, tunnel->IsInbound(), result); + } } } diff --git a/TunnelPool.h b/TunnelPool.h index 6a73bd67..9e2a3e24 100644 --- a/TunnelPool.h +++ b/TunnelPool.h @@ -23,12 +23,21 @@ namespace tunnel class InboundTunnel; class OutboundTunnel; + + enum TunnelBuildResult { + eBuildResultOkay, // tunnel was built okay + eBuildResultRejected, // tunnel build was explicitly rejected + eBuildResultTimeout // tunnel build timed out + }; + /** interface for custom tunnel peer selection algorithm */ struct ITunnelPeerSelector { typedef std::shared_ptr Peer; typedef std::vector TunnelPath; + virtual bool SelectPeers(TunnelPath & peers, int hops, bool isInbound) = 0; + virtual bool OnBuildResult(TunnelPath & peers, bool isInbound, TunnelBuildResult result) = 0; }; typedef std::shared_ptr TunnelPeerSelector; @@ -79,6 +88,8 @@ namespace tunnel /** @brief get the lowest latency tunnel in this tunnel pool regardless of latency requirements */ std::shared_ptr GetLowestLatencyInboundTunnel(std::shared_ptr exclude=nullptr) const; std::shared_ptr GetLowestLatencyOutboundTunnel(std::shared_ptr exclude=nullptr) const; + + void OnTunnelBuildResult(std::shared_ptr tunnel, TunnelBuildResult result); private: