Browse Source

select first hop from high bandwidth peer for client tunnels

pull/1872/head
orignal 1 year ago
parent
commit
21542e8150
  1. 11
      libi2pd/Transports.cpp
  2. 15
      libi2pd/Transports.h
  3. 8
      libi2pd/TunnelPool.cpp
  4. 10
      libi2pd/TunnelPool.h
  5. 4
      libi2pd_client/MatchedDestination.cpp

11
libi2pd/Transports.cpp

@ -476,7 +476,7 @@ namespace transport @@ -476,7 +476,7 @@ namespace transport
bool Transports::ConnectToPeer (const i2p::data::IdentHash& ident, Peer& peer)
{
if (!peer.router) // reconnect
peer.router = netdb.FindRouter (ident); // try to get new one from netdb
peer.SetRouter (netdb.FindRouter (ident)); // try to get new one from netdb
if (peer.router) // we have RI already
{
if (peer.priority.empty ())
@ -598,7 +598,7 @@ namespace transport @@ -598,7 +598,7 @@ namespace transport
if (r)
{
LogPrint (eLogDebug, "Transports: RouterInfo for ", ident.ToBase64 (), " found, trying to connect");
it->second.router = r;
it->second.SetRouter (r);
ConnectToPeer (ident, it->second);
}
else
@ -900,14 +900,15 @@ namespace transport @@ -900,14 +900,15 @@ namespace transport
return found ? i2p::data::netdb.FindRouter (ident) : nullptr;
}
std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRandomPeer () const
std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRandomPeer (bool isHighBandwidth) const
{
return GetRandomPeer (
[](const Peer& peer)->bool
[isHighBandwidth](const Peer& peer)->bool
{
// connected and not overloaded
return !peer.router && !peer.sessions.empty () &&
peer.sessions.front ()->GetSendQueueSize () <= PEER_ROUTER_INFO_OVERLOAD_QUEUE_SIZE;
peer.sessions.front ()->GetSendQueueSize () <= PEER_ROUTER_INFO_OVERLOAD_QUEUE_SIZE &&
(!isHighBandwidth || peer.isHighBandwidth);
});
}

15
libi2pd/Transports.h

@ -72,11 +72,15 @@ namespace transport @@ -72,11 +72,15 @@ namespace transport
uint64_t creationTime, nextRouterInfoUpdateTime;
std::vector<std::shared_ptr<i2p::I2NPMessage> > delayedMessages;
std::vector<i2p::data::RouterInfo::SupportedTransports> priority;
bool isHighBandwidth;
Peer (std::shared_ptr<const i2p::data::RouterInfo> r, uint64_t ts):
numAttempts (0), router (r), creationTime (ts),
nextRouterInfoUpdateTime (ts + PEER_ROUTER_INFO_UPDATE_INTERVAL)
nextRouterInfoUpdateTime (ts + PEER_ROUTER_INFO_UPDATE_INTERVAL),
isHighBandwidth (false)
{
if (router)
isHighBandwidth = router->IsHighBandwidth ();
}
void Done ()
@ -84,6 +88,13 @@ namespace transport @@ -84,6 +88,13 @@ namespace transport
for (auto& it: sessions)
it->Done ();
}
void SetRouter (std::shared_ptr<const i2p::data::RouterInfo> r)
{
router = r;
if (router)
isHighBandwidth = router->IsHighBandwidth ();
}
};
const uint64_t SESSION_CREATION_TIMEOUT = 15; // in seconds
@ -131,7 +142,7 @@ namespace transport @@ -131,7 +142,7 @@ namespace transport
bool IsBandwidthExceeded () const;
bool IsTransitBandwidthExceeded () const;
size_t GetNumPeers () const { return m_Peers.size (); };
std::shared_ptr<const i2p::data::RouterInfo> GetRandomPeer () const;
std::shared_ptr<const i2p::data::RouterInfo> GetRandomPeer (bool isHighBandwidth) const;
/** get a trusted first hop for restricted routes */
std::shared_ptr<const i2p::data::RouterInfo> GetRestrictedPeer() const;

8
libi2pd/TunnelPool.cpp

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
* Copyright (c) 2013-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@ -480,7 +480,7 @@ namespace tunnel @@ -480,7 +480,7 @@ namespace tunnel
return hop;
}
bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop)
bool TunnelPool::StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop)
{
int start = 0;
std::shared_ptr<const i2p::data::RouterInfo> prevHop = i2p::context.GetSharedRouterInfo ();
@ -496,7 +496,7 @@ namespace tunnel @@ -496,7 +496,7 @@ namespace tunnel
else if (i2p::transport::transports.GetNumPeers () > 100 ||
(inbound && i2p::transport::transports.GetNumPeers () > 25))
{
auto r = i2p::transport::transports.GetRandomPeer ();
auto r = i2p::transport::transports.GetRandomPeer (IsExploratory ());
if (r && r->IsECIES () && !r->GetProfile ()->IsBad () &&
(numHops > 1 || (r->IsV4 () && (!inbound || r->IsReachable ())))) // first inbound must be reachable
{
@ -512,7 +512,7 @@ namespace tunnel @@ -512,7 +512,7 @@ namespace tunnel
if (!hop && !i) // if no suitable peer found for first hop, try already connected
{
LogPrint (eLogInfo, "Tunnels: Can't select first hop for a tunnel. Trying already connected");
hop = i2p::transport::transports.GetRandomPeer ();
hop = i2p::transport::transports.GetRandomPeer (false);
if (hop && !hop->IsECIES ()) hop = nullptr;
}
if (!hop)

10
libi2pd/TunnelPool.h

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
* Copyright (c) 2013-2023, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@ -54,12 +54,9 @@ namespace tunnel @@ -54,12 +54,9 @@ namespace tunnel
virtual bool SelectPeers(Path & peers, int hops, bool isInbound) = 0;
};
typedef std::function<std::shared_ptr<const i2p::data::RouterInfo>(std::shared_ptr<const i2p::data::RouterInfo>, bool)> SelectHopFunc;
bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop);
class TunnelPool: public std::enable_shared_from_this<TunnelPool> // per local destination
{
typedef std::function<std::shared_ptr<const i2p::data::RouterInfo>(std::shared_ptr<const i2p::data::RouterInfo>, bool)> SelectHopFunc;
public:
TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels,
@ -116,7 +113,8 @@ namespace tunnel @@ -116,7 +113,8 @@ namespace tunnel
// for overriding tunnel peer selection
std::shared_ptr<const i2p::data::RouterInfo> SelectNextHop (std::shared_ptr<const i2p::data::RouterInfo> prevHop, bool reverse) const;
bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop);
private:
void TestTunnels ();

4
libi2pd_client/MatchedDestination.cpp

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

Loading…
Cancel
Save