Browse Source

use short tunnel build if possible

pull/1677/head
orignal 3 years ago
parent
commit
c153471c49
  1. 1
      libi2pd/NetDb.hpp
  2. 63
      libi2pd/TunnelPool.cpp
  3. 18
      libi2pd/TunnelPool.h
  4. 10
      libi2pd_client/MatchedDestination.cpp

1
libi2pd/NetDb.hpp

@ -45,6 +45,7 @@ namespace data
const int NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15; const int NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15;
const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 36); // 0.9.36 const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 36); // 0.9.36
const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 38); // 0.9.38 const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 38); // 0.9.38
const int NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51
/** function for visiting a leaseset stored in a floodfill */ /** function for visiting a leaseset stored in a floodfill */
typedef std::function<void(const IdentHash, std::shared_ptr<LeaseSet>)> LeaseSetVisitor; typedef std::function<void(const IdentHash, std::shared_ptr<LeaseSet>)> LeaseSetVisitor;

63
libi2pd/TunnelPool.cpp

@ -24,6 +24,22 @@ namespace i2p
{ {
namespace tunnel namespace tunnel
{ {
void Path::Add (std::shared_ptr<const i2p::data::RouterInfo> r)
{
if (r)
{
peers.push_back (r->GetRouterIdentity ());
if (r->GetVersion () < i2p::data::NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION ||
r->GetRouterIdentity ()->GetCryptoKeyType () != i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)
isShort = false;
}
}
void Path::Reverse ()
{
std::reverse (peers.begin (), peers.end ());
}
TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels): TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels):
m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops), m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops),
m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels), m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels),
@ -420,7 +436,7 @@ namespace tunnel
return hop; return hop;
} }
bool StandardSelectPeers(Path & peers, int numHops, bool inbound, SelectHopFunc nextHop) bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop)
{ {
int start = 0; int start = 0;
std::shared_ptr<const i2p::data::RouterInfo> prevHop = i2p::context.GetSharedRouterInfo (); std::shared_ptr<const i2p::data::RouterInfo> prevHop = i2p::context.GetSharedRouterInfo ();
@ -429,7 +445,7 @@ namespace tunnel
/** if routes are restricted prepend trusted first hop */ /** if routes are restricted prepend trusted first hop */
auto hop = i2p::transport::transports.GetRestrictedPeer(); auto hop = i2p::transport::transports.GetRestrictedPeer();
if(!hop) return false; if(!hop) return false;
peers.push_back(hop->GetRouterIdentity()); path.Add (hop);
prevHop = hop; prevHop = hop;
start++; start++;
} }
@ -441,7 +457,7 @@ namespace tunnel
(numHops > 1 || (r->IsV4 () && (!inbound || r->IsReachable ())))) // first inbound must be reachable (numHops > 1 || (r->IsV4 () && (!inbound || r->IsReachable ())))) // first inbound must be reachable
{ {
prevHop = r; prevHop = r;
peers.push_back (r->GetRouterIdentity ()); path.Add (r);
start++; start++;
} }
} }
@ -466,12 +482,12 @@ namespace tunnel
if (hop1) hop = hop1; if (hop1) hop = hop1;
} }
prevHop = hop; prevHop = hop;
peers.push_back (hop->GetRouterIdentity ()); path.Add (hop);
} }
return true; return true;
} }
bool TunnelPool::SelectPeers (std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& peers, bool isInbound) bool TunnelPool::SelectPeers (Path& path, bool isInbound)
{ {
int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops; int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops;
// peers is empty // peers is empty
@ -480,14 +496,14 @@ namespace tunnel
{ {
std::lock_guard<std::mutex> lock(m_CustomPeerSelectorMutex); std::lock_guard<std::mutex> lock(m_CustomPeerSelectorMutex);
if (m_CustomPeerSelector) if (m_CustomPeerSelector)
return m_CustomPeerSelector->SelectPeers(peers, numHops, isInbound); return m_CustomPeerSelector->SelectPeers(path, numHops, isInbound);
} }
// explicit peers in use // explicit peers in use
if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound); if (m_ExplicitPeers) return SelectExplicitPeers (path, isInbound);
return StandardSelectPeers(peers, numHops, isInbound, std::bind(&TunnelPool::SelectNextHop, this, std::placeholders::_1, std::placeholders::_2)); return StandardSelectPeers(path, numHops, isInbound, std::bind(&TunnelPool::SelectNextHop, this, std::placeholders::_1, std::placeholders::_2));
} }
bool TunnelPool::SelectExplicitPeers (std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& peers, bool isInbound) bool TunnelPool::SelectExplicitPeers (Path& path, bool isInbound)
{ {
int size = m_ExplicitPeers->size (); int size = m_ExplicitPeers->size ();
std::vector<int> peerIndicies; std::vector<int> peerIndicies;
@ -500,7 +516,7 @@ namespace tunnel
auto& ident = (*m_ExplicitPeers)[peerIndicies[i]]; auto& ident = (*m_ExplicitPeers)[peerIndicies[i]];
auto r = i2p::data::netdb.FindRouter (ident); auto r = i2p::data::netdb.FindRouter (ident);
if (r) if (r)
peers.push_back (r->GetRouterIdentity ()); path.Add (r);
else else
{ {
LogPrint (eLogInfo, "Tunnels: Can't find router for ", ident.ToBase64 ()); LogPrint (eLogInfo, "Tunnels: Can't find router for ", ident.ToBase64 ());
@ -517,14 +533,14 @@ namespace tunnel
if (!outboundTunnel) if (!outboundTunnel)
outboundTunnel = tunnels.GetNextOutboundTunnel (); outboundTunnel = tunnels.GetNextOutboundTunnel ();
LogPrint (eLogDebug, "Tunnels: Creating destination inbound tunnel..."); LogPrint (eLogDebug, "Tunnels: Creating destination inbound tunnel...");
std::vector<std::shared_ptr<const i2p::data::IdentityEx> > peers; Path path;
if (SelectPeers (peers, true)) if (SelectPeers (path, true))
{ {
std::shared_ptr<TunnelConfig> config; std::shared_ptr<TunnelConfig> config;
if (m_NumInboundHops > 0) if (m_NumInboundHops > 0)
{ {
std::reverse (peers.begin (), peers.end ()); path.Reverse ();
config = std::make_shared<TunnelConfig> (peers); config = std::make_shared<TunnelConfig> (path.peers, path.isShort);
} }
auto tunnel = tunnels.CreateInboundTunnel (config, shared_from_this (), outboundTunnel); auto tunnel = tunnels.CreateInboundTunnel (config, shared_from_this (), outboundTunnel);
if (tunnel->IsEstablished ()) // zero hops if (tunnel->IsEstablished ()) // zero hops
@ -566,14 +582,23 @@ namespace tunnel
if (inboundTunnel) if (inboundTunnel)
{ {
LogPrint (eLogDebug, "Tunnels: Creating destination outbound tunnel..."); LogPrint (eLogDebug, "Tunnels: Creating destination outbound tunnel...");
std::vector<std::shared_ptr<const i2p::data::IdentityEx> > peers; Path path;
if (SelectPeers (peers, false)) if (SelectPeers (path, false))
{ {
std::shared_ptr<TunnelConfig> config; std::shared_ptr<TunnelConfig> config;
if (m_NumOutboundHops > 0) if (m_NumOutboundHops > 0)
config = std::make_shared<TunnelConfig>(peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()); config = std::make_shared<TunnelConfig>(path.peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash (), path.isShort);
auto tunnel = tunnels.CreateOutboundTunnel (config, shared_from_this ());
if (tunnel->IsEstablished ()) // zero hops std::shared_ptr<OutboundTunnel> tunnel;
if (path.isShort)
{
// TODO: implement it better
tunnel = tunnels.CreateOutboundTunnel (config, inboundTunnel->GetTunnelPool ());
tunnel->SetTunnelPool (shared_from_this ());
}
else
tunnel = tunnels.CreateOutboundTunnel (config, shared_from_this ());
if (tunnel && tunnel->IsEstablished ()) // zero hops
TunnelCreated (tunnel); TunnelCreated (tunnel);
} }
else else

18
libi2pd/TunnelPool.h

@ -36,7 +36,14 @@ namespace tunnel
class OutboundTunnel; class OutboundTunnel;
typedef std::shared_ptr<const i2p::data::IdentityEx> Peer; typedef std::shared_ptr<const i2p::data::IdentityEx> Peer;
typedef std::vector<Peer> Path; struct Path
{
std::vector<Peer> peers;
bool isShort = true;
void Add (std::shared_ptr<const i2p::data::RouterInfo> r);
void Reverse ();
};
/** interface for custom tunnel peer selection algorithm */ /** interface for custom tunnel peer selection algorithm */
struct ITunnelPeerSelector struct ITunnelPeerSelector
@ -47,9 +54,8 @@ namespace tunnel
typedef std::function<std::shared_ptr<const i2p::data::RouterInfo>(std::shared_ptr<const i2p::data::RouterInfo>, bool)> SelectHopFunc; typedef std::function<std::shared_ptr<const i2p::data::RouterInfo>(std::shared_ptr<const i2p::data::RouterInfo>, bool)> SelectHopFunc;
// standard peer selection algorithm bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop);
bool StandardSelectPeers(Path & path, int hops, bool inbound, SelectHopFunc nextHop);
class TunnelPool: public std::enable_shared_from_this<TunnelPool> // per local destination class TunnelPool: public std::enable_shared_from_this<TunnelPool> // per local destination
{ {
public: public:
@ -114,8 +120,8 @@ namespace tunnel
void CreatePairedInboundTunnel (std::shared_ptr<OutboundTunnel> outboundTunnel); void CreatePairedInboundTunnel (std::shared_ptr<OutboundTunnel> outboundTunnel);
template<class TTunnels> template<class TTunnels>
typename TTunnels::value_type GetNextTunnel (TTunnels& tunnels, typename TTunnels::value_type excluded) const; typename TTunnels::value_type GetNextTunnel (TTunnels& tunnels, typename TTunnels::value_type excluded) const;
bool SelectPeers (std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& hops, bool isInbound); bool SelectPeers (Path& path, bool isInbound);
bool SelectExplicitPeers (std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& hops, bool isInbound); bool SelectExplicitPeers (Path& path, bool isInbound);
private: private:

10
libi2pd_client/MatchedDestination.cpp

@ -79,23 +79,23 @@ namespace client
if(!inbound && m_RemoteLeaseSet) if(!inbound && m_RemoteLeaseSet)
{ {
if(m_RemoteLeaseSet->IsExpired()) if(m_RemoteLeaseSet->IsExpired())
{
ResolveCurrentLeaseSet(); ResolveCurrentLeaseSet();
}
if(m_RemoteLeaseSet && !m_RemoteLeaseSet->IsExpired()) if(m_RemoteLeaseSet && !m_RemoteLeaseSet->IsExpired())
{ {
// remote lease set is good // remote lease set is good
auto leases = m_RemoteLeaseSet->GetNonExpiredLeases(); auto leases = m_RemoteLeaseSet->GetNonExpiredLeases();
// pick lease // pick lease
std::shared_ptr<i2p::data::RouterInfo> obep; std::shared_ptr<i2p::data::RouterInfo> obep;
while(!obep && leases.size() > 0) { while(!obep && leases.size() > 0)
{
auto idx = rand() % leases.size(); auto idx = rand() % leases.size();
auto lease = leases[idx]; auto lease = leases[idx];
obep = i2p::data::netdb.FindRouter(lease->tunnelGateway); obep = i2p::data::netdb.FindRouter(lease->tunnelGateway);
leases.erase(leases.begin()+idx); leases.erase(leases.begin()+idx);
} }
if(obep) { if(obep)
path.push_back(obep->GetRouterIdentity()); {
path.Add (obep);
LogPrint(eLogDebug, "Destination: found OBEP matching IBGW"); LogPrint(eLogDebug, "Destination: found OBEP matching IBGW");
} else } else
LogPrint(eLogWarning, "Destination: could not find proper IBGW for matched outbound tunnel"); LogPrint(eLogWarning, "Destination: could not find proper IBGW for matched outbound tunnel");

Loading…
Cancel
Save