From 3ca560b895476f9d72fef7406f051ce1d24cf5a0 Mon Sep 17 00:00:00 2001
From: orignal <i2porignal@yandex.ru>
Date: Sat, 29 Nov 2014 22:00:52 -0500
Subject: [PATCH] different tunnel length for IB and OB

---
 Destination.cpp |  2 +-
 Tunnel.cpp      |  6 +++---
 Tunnel.h        |  2 +-
 TunnelPool.cpp  | 16 +++++++++-------
 TunnelPool.h    |  4 ++--
 5 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/Destination.cpp b/Destination.cpp
index f1ad8cac..ed71d8f0 100644
--- a/Destination.cpp
+++ b/Destination.cpp
@@ -16,7 +16,7 @@ namespace client
 	{
 		CryptoPP::DH dh (i2p::crypto::elgp, i2p::crypto::elgg);
 		dh.GenerateKeyPair(i2p::context.GetRandomNumberGenerator (), m_EncryptionPrivateKey, m_EncryptionPublicKey);
-		m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (*this, 3); // 3-hops tunnel 
+		m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (*this, 3, 3); // 3-hops tunnel 
 		if (m_IsPublic)
 			LogPrint ("Local address ", GetIdentHash ().ToBase32 (), ".b32.i2p created");
 		m_StreamingDestination = new i2p::stream::StreamingDestination (*this); // TODO:
diff --git a/Tunnel.cpp b/Tunnel.cpp
index e4270335..eff9965c 100644
--- a/Tunnel.cpp
+++ b/Tunnel.cpp
@@ -287,9 +287,9 @@ namespace tunnel
 		return tunnel;
 	}	
 
-	TunnelPool * Tunnels::CreateTunnelPool (i2p::garlic::GarlicDestination& localDestination, int numHops)
+	TunnelPool * Tunnels::CreateTunnelPool (i2p::garlic::GarlicDestination& localDestination, int numInboundHops, int numOutboundHops)
 	{
-		auto pool = new TunnelPool (localDestination, numHops);
+		auto pool = new TunnelPool (localDestination, numInboundHops, numOutboundHops);
 		std::unique_lock<std::mutex> l(m_PoolsMutex);
 		m_Pools[pool->GetIdentHash ()] = pool;
 		return pool;
@@ -510,7 +510,7 @@ namespace tunnel
 			LogPrint ("Creating zero hops inbound tunnel...");
 			CreateZeroHopsInboundTunnel ();
 			if (!m_ExploratoryPool)
-				m_ExploratoryPool = CreateTunnelPool (i2p::context, 2); // 2-hop exploratory
+				m_ExploratoryPool = CreateTunnelPool (i2p::context, 2, 2); // 2-hop exploratory
 			return;
 		}
 		
diff --git a/Tunnel.h b/Tunnel.h
index cf78e9c7..520ef61b 100644
--- a/Tunnel.h
+++ b/Tunnel.h
@@ -129,7 +129,7 @@ namespace tunnel
 			void PostTunnelData (I2NPMessage * msg);
 			template<class TTunnel>
 			TTunnel * CreateTunnel (TunnelConfig * config, OutboundTunnel * outboundTunnel = 0);
-			TunnelPool * CreateTunnelPool (i2p::garlic::GarlicDestination& localDestination, int numHops);
+			TunnelPool * CreateTunnelPool (i2p::garlic::GarlicDestination& localDestination, int numInboundHops, int numOuboundHops);
 			void DeleteTunnelPool (TunnelPool * pool);
 			void StopTunnelPool (TunnelPool * pool);
 			
diff --git a/TunnelPool.cpp b/TunnelPool.cpp
index 3e6b9ccc..d20e4c14 100644
--- a/TunnelPool.cpp
+++ b/TunnelPool.cpp
@@ -10,9 +10,9 @@ namespace i2p
 {
 namespace tunnel
 {
-	TunnelPool::TunnelPool (i2p::garlic::GarlicDestination& localDestination, int numHops, int numTunnels):
-		m_LocalDestination (localDestination), m_NumHops (numHops), m_NumTunnels (numTunnels),
-		m_IsActive (true)
+	TunnelPool::TunnelPool (i2p::garlic::GarlicDestination& localDestination, int numInboundHops, int numOutboundHops, int numTunnels):
+		m_LocalDestination (localDestination), m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops),
+		m_NumTunnels (numTunnels), m_IsActive (true)
 	{
 	}
 
@@ -244,8 +244,10 @@ namespace tunnel
 
 	std::shared_ptr<const i2p::data::RouterInfo> TunnelPool::SelectNextHop (std::shared_ptr<const i2p::data::RouterInfo> prevHop) const
 	{
-		auto hop = m_NumHops >= 3 ? i2p::data::netdb.GetHighBandwidthRandomRouter (prevHop) :
-			i2p::data::netdb.GetRandomRouter (prevHop);
+		bool isExploratory = (&m_LocalDestination == &i2p::context); // TODO: implement it better
+		auto hop =  isExploratory ? i2p::data::netdb.GetRandomRouter (prevHop): 
+			i2p::data::netdb.GetHighBandwidthRandomRouter (prevHop);
+			
 		if (!hop)
 			hop = i2p::data::netdb.GetRandomRouter ();
 		return hop;	
@@ -259,7 +261,7 @@ namespace tunnel
 		LogPrint ("Creating destination inbound tunnel...");
 		auto prevHop = i2p::context.GetSharedRouterInfo ();	
 		std::vector<std::shared_ptr<const i2p::data::RouterInfo> > hops;
-		int numHops = m_NumHops;
+		int numHops = m_NumInboundHops;
 		if (outboundTunnel)
 		{	
 			// last hop
@@ -303,7 +305,7 @@ namespace tunnel
 
 			auto prevHop = i2p::context.GetSharedRouterInfo ();
 			std::vector<std::shared_ptr<const i2p::data::RouterInfo> > hops;
-			for (int i = 0; i < m_NumHops; i++)
+			for (int i = 0; i < m_NumOutboundHops; i++)
 			{
 				auto hop = SelectNextHop (prevHop);
 				prevHop = hop;
diff --git a/TunnelPool.h b/TunnelPool.h
index 2423e3af..d12629a1 100644
--- a/TunnelPool.h
+++ b/TunnelPool.h
@@ -26,7 +26,7 @@ namespace tunnel
 	{
 		public:
 
-			TunnelPool (i2p::garlic::GarlicDestination& localDestination, int numHops, int numTunnels = 5);
+			TunnelPool (i2p::garlic::GarlicDestination& localDestination, int numInboundHops, int numOutboundHops, int numTunnels = 5);
 			~TunnelPool ();
 
 			const uint8_t * GetEncryptionPrivateKey () const { return m_LocalDestination.GetEncryptionPrivateKey (); };
@@ -66,7 +66,7 @@ namespace tunnel
 		private:
 
 			i2p::garlic::GarlicDestination& m_LocalDestination;
-			int m_NumHops, m_NumTunnels;
+			int m_NumInboundHops, m_NumOutboundHops, m_NumTunnels;
 			mutable std::mutex m_InboundTunnelsMutex;
 			std::set<InboundTunnel *, TunnelCreationTimeCmp> m_InboundTunnels; // recent tunnel appears first
 			mutable std::mutex m_OutboundTunnelsMutex;