mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 21:37:17 +01:00
use short tunnel build if possible
This commit is contained in:
parent
28369faa00
commit
c153471c49
|
@ -45,6 +45,7 @@ namespace data
|
|||
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_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 */
|
||||
typedef std::function<void(const IdentHash, std::shared_ptr<LeaseSet>)> LeaseSetVisitor;
|
||||
|
|
|
@ -24,6 +24,22 @@ namespace i2p
|
|||
{
|
||||
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):
|
||||
m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops),
|
||||
m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels),
|
||||
|
@ -420,7 +436,7 @@ namespace tunnel
|
|||
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;
|
||||
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 */
|
||||
auto hop = i2p::transport::transports.GetRestrictedPeer();
|
||||
if(!hop) return false;
|
||||
peers.push_back(hop->GetRouterIdentity());
|
||||
path.Add (hop);
|
||||
prevHop = hop;
|
||||
start++;
|
||||
}
|
||||
|
@ -441,7 +457,7 @@ namespace tunnel
|
|||
(numHops > 1 || (r->IsV4 () && (!inbound || r->IsReachable ())))) // first inbound must be reachable
|
||||
{
|
||||
prevHop = r;
|
||||
peers.push_back (r->GetRouterIdentity ());
|
||||
path.Add (r);
|
||||
start++;
|
||||
}
|
||||
}
|
||||
|
@ -466,12 +482,12 @@ namespace tunnel
|
|||
if (hop1) hop = hop1;
|
||||
}
|
||||
prevHop = hop;
|
||||
peers.push_back (hop->GetRouterIdentity ());
|
||||
path.Add (hop);
|
||||
}
|
||||
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;
|
||||
// peers is empty
|
||||
|
@ -480,14 +496,14 @@ namespace tunnel
|
|||
{
|
||||
std::lock_guard<std::mutex> lock(m_CustomPeerSelectorMutex);
|
||||
if (m_CustomPeerSelector)
|
||||
return m_CustomPeerSelector->SelectPeers(peers, numHops, isInbound);
|
||||
return m_CustomPeerSelector->SelectPeers(path, numHops, isInbound);
|
||||
}
|
||||
// explicit peers in use
|
||||
if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound);
|
||||
return StandardSelectPeers(peers, numHops, isInbound, std::bind(&TunnelPool::SelectNextHop, this, std::placeholders::_1, std::placeholders::_2));
|
||||
if (m_ExplicitPeers) return SelectExplicitPeers (path, isInbound);
|
||||
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 ();
|
||||
std::vector<int> peerIndicies;
|
||||
|
@ -500,7 +516,7 @@ namespace tunnel
|
|||
auto& ident = (*m_ExplicitPeers)[peerIndicies[i]];
|
||||
auto r = i2p::data::netdb.FindRouter (ident);
|
||||
if (r)
|
||||
peers.push_back (r->GetRouterIdentity ());
|
||||
path.Add (r);
|
||||
else
|
||||
{
|
||||
LogPrint (eLogInfo, "Tunnels: Can't find router for ", ident.ToBase64 ());
|
||||
|
@ -517,14 +533,14 @@ namespace tunnel
|
|||
if (!outboundTunnel)
|
||||
outboundTunnel = tunnels.GetNextOutboundTunnel ();
|
||||
LogPrint (eLogDebug, "Tunnels: Creating destination inbound tunnel...");
|
||||
std::vector<std::shared_ptr<const i2p::data::IdentityEx> > peers;
|
||||
if (SelectPeers (peers, true))
|
||||
Path path;
|
||||
if (SelectPeers (path, true))
|
||||
{
|
||||
std::shared_ptr<TunnelConfig> config;
|
||||
if (m_NumInboundHops > 0)
|
||||
{
|
||||
std::reverse (peers.begin (), peers.end ());
|
||||
config = std::make_shared<TunnelConfig> (peers);
|
||||
path.Reverse ();
|
||||
config = std::make_shared<TunnelConfig> (path.peers, path.isShort);
|
||||
}
|
||||
auto tunnel = tunnels.CreateInboundTunnel (config, shared_from_this (), outboundTunnel);
|
||||
if (tunnel->IsEstablished ()) // zero hops
|
||||
|
@ -566,14 +582,23 @@ namespace tunnel
|
|||
if (inboundTunnel)
|
||||
{
|
||||
LogPrint (eLogDebug, "Tunnels: Creating destination outbound tunnel...");
|
||||
std::vector<std::shared_ptr<const i2p::data::IdentityEx> > peers;
|
||||
if (SelectPeers (peers, false))
|
||||
Path path;
|
||||
if (SelectPeers (path, false))
|
||||
{
|
||||
std::shared_ptr<TunnelConfig> config;
|
||||
if (m_NumOutboundHops > 0)
|
||||
config = std::make_shared<TunnelConfig>(peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ());
|
||||
auto tunnel = tunnels.CreateOutboundTunnel (config, shared_from_this ());
|
||||
if (tunnel->IsEstablished ()) // zero hops
|
||||
config = std::make_shared<TunnelConfig>(path.peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash (), path.isShort);
|
||||
|
||||
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);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -36,7 +36,14 @@ namespace tunnel
|
|||
class OutboundTunnel;
|
||||
|
||||
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 */
|
||||
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;
|
||||
// standard peer selection algorithm
|
||||
bool StandardSelectPeers(Path & path, int hops, bool inbound, SelectHopFunc nextHop);
|
||||
|
||||
bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop);
|
||||
|
||||
class TunnelPool: public std::enable_shared_from_this<TunnelPool> // per local destination
|
||||
{
|
||||
public:
|
||||
|
@ -114,8 +120,8 @@ namespace tunnel
|
|||
void CreatePairedInboundTunnel (std::shared_ptr<OutboundTunnel> outboundTunnel);
|
||||
template<class TTunnels>
|
||||
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 SelectExplicitPeers (std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& hops, bool isInbound);
|
||||
bool SelectPeers (Path& path, bool isInbound);
|
||||
bool SelectExplicitPeers (Path& path, bool isInbound);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -79,23 +79,23 @@ namespace client
|
|||
if(!inbound && m_RemoteLeaseSet)
|
||||
{
|
||||
if(m_RemoteLeaseSet->IsExpired())
|
||||
{
|
||||
ResolveCurrentLeaseSet();
|
||||
}
|
||||
if(m_RemoteLeaseSet && !m_RemoteLeaseSet->IsExpired())
|
||||
{
|
||||
// remote lease set is good
|
||||
auto leases = m_RemoteLeaseSet->GetNonExpiredLeases();
|
||||
// pick lease
|
||||
std::shared_ptr<i2p::data::RouterInfo> obep;
|
||||
while(!obep && leases.size() > 0) {
|
||||
while(!obep && leases.size() > 0)
|
||||
{
|
||||
auto idx = rand() % leases.size();
|
||||
auto lease = leases[idx];
|
||||
obep = i2p::data::netdb.FindRouter(lease->tunnelGateway);
|
||||
leases.erase(leases.begin()+idx);
|
||||
}
|
||||
if(obep) {
|
||||
path.push_back(obep->GetRouterIdentity());
|
||||
if(obep)
|
||||
{
|
||||
path.Add (obep);
|
||||
LogPrint(eLogDebug, "Destination: found OBEP matching IBGW");
|
||||
} else
|
||||
LogPrint(eLogWarning, "Destination: could not find proper IBGW for matched outbound tunnel");
|
||||
|
|
Loading…
Reference in a new issue