Browse Source

check connectivity between peers for tunnel

pull/1640/head
orignal 4 years ago
parent
commit
f70ee480ba
  1. 18
      libi2pd/NetDb.cpp
  2. 6
      libi2pd/NetDb.hpp
  3. 25
      libi2pd/RouterInfo.cpp
  4. 8
      libi2pd/RouterInfo.h
  5. 4
      libi2pd/Transports.cpp
  6. 16
      libi2pd/TunnelPool.cpp
  7. 6
      libi2pd/TunnelPool.h
  8. 5
      libi2pd_client/MatchedDestination.cpp

18
libi2pd/NetDb.cpp

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2020, The PurpleI2P Project * Copyright (c) 2013-2021, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -57,7 +57,7 @@ namespace data
uint16_t threshold; i2p::config::GetOption("reseed.threshold", threshold); uint16_t threshold; i2p::config::GetOption("reseed.threshold", threshold);
if (m_RouterInfos.size () < threshold) // reseed if # of router less than threshold if (m_RouterInfos.size () < threshold) // reseed if # of router less than threshold
Reseed (); Reseed ();
else if (!GetRandomRouter (i2p::context.GetSharedRouterInfo ())) else if (!GetRandomRouter (i2p::context.GetSharedRouterInfo (), false))
Reseed (); // we don't have a router we can connect to. Trying to reseed Reseed (); // we don't have a router we can connect to. Trying to reseed
i2p::config::GetOption("persist.profiles", m_PersistProfiles); i2p::config::GetOption("persist.profiles", m_PersistProfiles);
@ -1135,13 +1135,14 @@ namespace data
}); });
} }
std::shared_ptr<const RouterInfo> NetDb::GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith) const std::shared_ptr<const RouterInfo> NetDb::GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const
{ {
return GetRandomRouter ( return GetRandomRouter (
[compatibleWith](std::shared_ptr<const RouterInfo> router)->bool [compatibleWith, reverse](std::shared_ptr<const RouterInfo> router)->bool
{ {
return !router->IsHidden () && router != compatibleWith && return !router->IsHidden () && router != compatibleWith &&
router->IsCompatible (*compatibleWith); (reverse ? compatibleWith->IsReachableFrom (*router) :
router->IsReachableFrom (*compatibleWith));
}); });
} }
@ -1172,13 +1173,14 @@ namespace data
}); });
} }
std::shared_ptr<const RouterInfo> NetDb::GetHighBandwidthRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith) const std::shared_ptr<const RouterInfo> NetDb::GetHighBandwidthRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const
{ {
return GetRandomRouter ( return GetRandomRouter (
[compatibleWith](std::shared_ptr<const RouterInfo> router)->bool [compatibleWith, reverse](std::shared_ptr<const RouterInfo> router)->bool
{ {
return !router->IsHidden () && router != compatibleWith && return !router->IsHidden () && router != compatibleWith &&
router->IsCompatible (*compatibleWith) && (reverse ? compatibleWith->IsReachableFrom (*router) :
router->IsReachableFrom (*compatibleWith)) &&
(router->GetCaps () & RouterInfo::eHighBandwidth) && (router->GetCaps () & RouterInfo::eHighBandwidth) &&
router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION; router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION;
}); });

6
libi2pd/NetDb.hpp

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2020, The PurpleI2P Project * Copyright (c) 2013-2021, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -83,8 +83,8 @@ namespace data
void HandleDeliveryStatusMsg (std::shared_ptr<const I2NPMessage> msg); void HandleDeliveryStatusMsg (std::shared_ptr<const I2NPMessage> msg);
std::shared_ptr<const RouterInfo> GetRandomRouter () const; std::shared_ptr<const RouterInfo> GetRandomRouter () const;
std::shared_ptr<const RouterInfo> GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith) const; std::shared_ptr<const RouterInfo> GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const;
std::shared_ptr<const RouterInfo> GetHighBandwidthRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith) const; std::shared_ptr<const RouterInfo> GetHighBandwidthRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith, bool reverse) const;
std::shared_ptr<const RouterInfo> GetRandomPeerTestRouter (bool v4only = true) const; std::shared_ptr<const RouterInfo> GetRandomPeerTestRouter (bool v4only = true) const;
std::shared_ptr<const RouterInfo> GetRandomSSUV6Router () const; // TODO: change to v6 peer test later std::shared_ptr<const RouterInfo> GetRandomSSUV6Router () const; // TODO: change to v6 peer test later
std::shared_ptr<const RouterInfo> GetRandomIntroducer () const; std::shared_ptr<const RouterInfo> GetRandomIntroducer () const;

25
libi2pd/RouterInfo.cpp

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2020, The PurpleI2P Project * Copyright (c) 2013-2021, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -1079,22 +1079,37 @@ namespace data
auto supportedTransports = m_SupportedTransports & (eSSUV4 | eSSUV6); auto supportedTransports = m_SupportedTransports & (eSSUV4 | eSSUV6);
if (!supportedTransports) return false; // no SSU if (!supportedTransports) return false; // no SSU
if (v4only && !(supportedTransports & eSSUV4)) return false; // no SSU v4 if (v4only && !(supportedTransports & eSSUV4)) return false; // no SSU v4
return GetAddress ( return (bool)GetAddress (
[](std::shared_ptr<const RouterInfo::Address> address)->bool [](std::shared_ptr<const RouterInfo::Address> address)->bool
{ {
return (address->transportStyle == eTransportSSU) && address->IsPeerTesting (); return (address->transportStyle == eTransportSSU) && address->IsPeerTesting ();
}) != nullptr; });
} }
bool RouterInfo::IsIntroducer () const bool RouterInfo::IsIntroducer () const
{ {
// TODO: support ipv6 // TODO: support ipv6
if (!(m_SupportedTransports & eSSUV4)) return false; if (!(m_SupportedTransports & eSSUV4)) return false;
return GetAddress ( return (bool)GetAddress (
[](std::shared_ptr<const RouterInfo::Address> address)->bool [](std::shared_ptr<const RouterInfo::Address> address)->bool
{ {
return (address->transportStyle == eTransportSSU) && address->IsIntroducer (); return (address->transportStyle == eTransportSSU) && address->IsIntroducer ();
}) != nullptr; });
}
bool RouterInfo::IsReachableFrom (const RouterInfo& other) const
{
auto commonTransports = m_SupportedTransports & other.m_SupportedTransports;
if (!commonTransports) return false;
if (commonTransports & eNTCP2V6Mesh) return true;
return (bool)GetAddress (
[commonTransports](std::shared_ptr<const RouterInfo::Address> address)->bool
{
// TODO:check v4 and v6 separately based on caps
if ((commonTransports & (eNTCP2V4 | eNTCP2V6)) && address->IsPublishedNTCP2 ()) return true;
if ((commonTransports & (eSSUV4 | eSSUV6)) && address->IsReachableSSU ()) return true;
return false;
});
} }
} }
} }

8
libi2pd/RouterInfo.h

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2020, The PurpleI2P Project * Copyright (c) 2013-2021, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -147,7 +147,8 @@ namespace data
bool IsNTCP2 () const { return (bool)ntcp2; }; bool IsNTCP2 () const { return (bool)ntcp2; };
bool IsPublishedNTCP2 () const { return IsNTCP2 () && ntcp2->isPublished; }; bool IsPublishedNTCP2 () const { return IsNTCP2 () && ntcp2->isPublished; };
bool IsReachableSSU () const { return (bool)ssu && (!host.is_unspecified () || !ssu->introducers.empty ()); };
bool IsIntroducer () const { return caps & eSSUIntroducer; }; bool IsIntroducer () const { return caps & eSSUIntroducer; };
bool IsPeerTesting () const { return caps & eSSUTesting; }; bool IsPeerTesting () const { return caps & eSSUTesting; };
}; };
@ -196,7 +197,8 @@ namespace data
void DisableV4 (); void DisableV4 ();
void EnableMesh (); void EnableMesh ();
void DisableMesh (); void DisableMesh ();
bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; }; bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; };
bool IsReachableFrom (const RouterInfo& other) const;
bool HasValidAddresses () const { return m_SupportedTransports; }; bool HasValidAddresses () const { return m_SupportedTransports; };
bool UsesIntroducer () const; bool UsesIntroducer () const;
bool IsHidden () const { return m_Caps & eHidden; }; bool IsHidden () const { return m_Caps & eHidden; };

4
libi2pd/Transports.cpp

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2020, The PurpleI2P Project * Copyright (c) 2013-2021, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -503,7 +503,7 @@ namespace transport
} }
peer.numAttempts++; peer.numAttempts++;
} }
if (address) if (address && address->IsReachableSSU ())
{ {
m_SSUServer->CreateSession (peer.router, address); m_SSUServer->CreateSession (peer.router, address);
return true; return true;

16
libi2pd/TunnelPool.cpp

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2020, The PurpleI2P Project * Copyright (c) 2013-2021, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -393,14 +393,14 @@ namespace tunnel
} }
} }
std::shared_ptr<const i2p::data::RouterInfo> TunnelPool::SelectNextHop (std::shared_ptr<const i2p::data::RouterInfo> prevHop) const std::shared_ptr<const i2p::data::RouterInfo> TunnelPool::SelectNextHop (std::shared_ptr<const i2p::data::RouterInfo> prevHop, bool reverse) const
{ {
bool isExploratory = (i2p::tunnel::tunnels.GetExploratoryPool () == shared_from_this ()); bool isExploratory = (i2p::tunnel::tunnels.GetExploratoryPool () == shared_from_this ());
auto hop = isExploratory ? i2p::data::netdb.GetRandomRouter (prevHop): auto hop = isExploratory ? i2p::data::netdb.GetRandomRouter (prevHop, reverse):
i2p::data::netdb.GetHighBandwidthRandomRouter (prevHop); i2p::data::netdb.GetHighBandwidthRandomRouter (prevHop, reverse);
if (!hop || hop->GetProfile ()->IsBad ()) if (!hop || hop->GetProfile ()->IsBad ())
hop = i2p::data::netdb.GetRandomRouter (prevHop); hop = i2p::data::netdb.GetRandomRouter (prevHop, reverse);
return hop; return hop;
} }
@ -429,7 +429,7 @@ namespace tunnel
for(int i = 0; i < numHops; i++ ) for(int i = 0; i < numHops; i++ )
{ {
auto hop = nextHop (prevHop); auto hop = nextHop (prevHop, inbound);
if (!hop) if (!hop)
{ {
LogPrint (eLogError, "Tunnels: Can't select next hop for ", prevHop->GetIdentHashBase64 ()); LogPrint (eLogError, "Tunnels: Can't select next hop for ", prevHop->GetIdentHashBase64 ());
@ -438,7 +438,7 @@ namespace tunnel
if (inbound && (i == numHops - 1) && !hop->IsReachable ()) if (inbound && (i == numHops - 1) && !hop->IsReachable ())
{ {
// if first is not reachable try again // if first is not reachable try again
auto hop1 = nextHop (prevHop); auto hop1 = nextHop (prevHop, true);
if (hop1) hop = hop1; if (hop1) hop = hop1;
} }
prevHop = hop; prevHop = hop;
@ -460,7 +460,7 @@ namespace tunnel
} }
// explicit peers in use // explicit peers in use
if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound); if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound);
return StandardSelectPeers(peers, numHops, isInbound, std::bind(&TunnelPool::SelectNextHop, this, std::placeholders::_1)); return StandardSelectPeers(peers, 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 (std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& peers, bool isInbound)

6
libi2pd/TunnelPool.h

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2020, The PurpleI2P Project * Copyright (c) 2013-2021, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -46,7 +46,7 @@ namespace tunnel
}; };
typedef std::function<std::shared_ptr<const i2p::data::RouterInfo>(std::shared_ptr<const i2p::data::RouterInfo>)> SelectHopFunc; typedef std::function<std::shared_ptr<const i2p::data::RouterInfo>(std::shared_ptr<const i2p::data::RouterInfo>, bool)> SelectHopFunc;
// standard peer selection algorithm // standard peer selection algorithm
bool StandardSelectPeers(Path & path, int hops, bool inbound, SelectHopFunc nextHop); bool StandardSelectPeers(Path & path, int hops, bool inbound, SelectHopFunc nextHop);
@ -104,7 +104,7 @@ namespace tunnel
std::shared_ptr<OutboundTunnel> GetLowestLatencyOutboundTunnel(std::shared_ptr<OutboundTunnel> exclude = nullptr) const; std::shared_ptr<OutboundTunnel> GetLowestLatencyOutboundTunnel(std::shared_ptr<OutboundTunnel> exclude = nullptr) const;
// for overriding tunnel peer selection // for overriding tunnel peer selection
std::shared_ptr<const i2p::data::RouterInfo> SelectNextHop (std::shared_ptr<const i2p::data::RouterInfo> prevHop) const; std::shared_ptr<const i2p::data::RouterInfo> SelectNextHop (std::shared_ptr<const i2p::data::RouterInfo> prevHop, bool reverse) const;
private: private:

5
libi2pd_client/MatchedDestination.cpp

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2020, The PurpleI2P Project * Copyright (c) 2013-2021, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -72,7 +72,8 @@ namespace client
bool MatchedTunnelDestination::SelectPeers(i2p::tunnel::Path & path, int hops, bool inbound) bool MatchedTunnelDestination::SelectPeers(i2p::tunnel::Path & path, int hops, bool inbound)
{ {
auto pool = GetTunnelPool(); auto pool = GetTunnelPool();
if(!i2p::tunnel::StandardSelectPeers(path, hops, inbound, std::bind(&i2p::tunnel::TunnelPool::SelectNextHop, pool, std::placeholders::_1))) if(!i2p::tunnel::StandardSelectPeers(path, hops, inbound,
std::bind(&i2p::tunnel::TunnelPool::SelectNextHop, pool, std::placeholders::_1, std::placeholders::_2)))
return false; return false;
// more here for outbound tunnels // more here for outbound tunnels
if(!inbound && m_RemoteLeaseSet) if(!inbound && m_RemoteLeaseSet)

Loading…
Cancel
Save