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<InboundTunnel> expiredTunnel)
@@ -109,6 +111,8 @@ namespace tunnel
 			std::unique_lock<std::mutex> 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> 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<const i2p::data::IdentityEx> Peer;
 		typedef std::vector<Peer> 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<ITunnelPeerSelector> TunnelPeerSelector;
@@ -79,6 +88,8 @@ namespace tunnel
 		/** @brief get the lowest latency tunnel in this tunnel pool regardless of latency requirements */
 		std::shared_ptr<InboundTunnel> GetLowestLatencyInboundTunnel(std::shared_ptr<InboundTunnel> exclude=nullptr) const;
 		std::shared_ptr<OutboundTunnel> GetLowestLatencyOutboundTunnel(std::shared_ptr<OutboundTunnel> exclude=nullptr) const;
+
+		void OnTunnelBuildResult(std::shared_ptr<Tunnel> tunnel, TunnelBuildResult result);
 		
 		private: