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
bool Transports::ConnectToPeer (const i2p::data::IdentHash& ident, Peer& peer) bool Transports::ConnectToPeer (const i2p::data::IdentHash& ident, Peer& peer)
{ {
if (!peer.router) // reconnect 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.router) // we have RI already
{ {
if (peer.priority.empty ()) if (peer.priority.empty ())
@ -598,7 +598,7 @@ namespace transport
if (r) if (r)
{ {
LogPrint (eLogDebug, "Transports: RouterInfo for ", ident.ToBase64 (), " found, trying to connect"); LogPrint (eLogDebug, "Transports: RouterInfo for ", ident.ToBase64 (), " found, trying to connect");
it->second.router = r; it->second.SetRouter (r);
ConnectToPeer (ident, it->second); ConnectToPeer (ident, it->second);
} }
else else
@ -900,14 +900,15 @@ namespace transport
return found ? i2p::data::netdb.FindRouter (ident) : nullptr; 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 ( return GetRandomPeer (
[](const Peer& peer)->bool [isHighBandwidth](const Peer& peer)->bool
{ {
// connected and not overloaded // connected and not overloaded
return !peer.router && !peer.sessions.empty () && 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
uint64_t creationTime, nextRouterInfoUpdateTime; uint64_t creationTime, nextRouterInfoUpdateTime;
std::vector<std::shared_ptr<i2p::I2NPMessage> > delayedMessages; std::vector<std::shared_ptr<i2p::I2NPMessage> > delayedMessages;
std::vector<i2p::data::RouterInfo::SupportedTransports> priority; std::vector<i2p::data::RouterInfo::SupportedTransports> priority;
bool isHighBandwidth;
Peer (std::shared_ptr<const i2p::data::RouterInfo> r, uint64_t ts): Peer (std::shared_ptr<const i2p::data::RouterInfo> r, uint64_t ts):
numAttempts (0), router (r), creationTime (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 () void Done ()
@ -84,6 +88,13 @@ namespace transport
for (auto& it: sessions) for (auto& it: sessions)
it->Done (); 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 const uint64_t SESSION_CREATION_TIMEOUT = 15; // in seconds
@ -131,7 +142,7 @@ namespace transport
bool IsBandwidthExceeded () const; bool IsBandwidthExceeded () const;
bool IsTransitBandwidthExceeded () const; bool IsTransitBandwidthExceeded () const;
size_t GetNumPeers () const { return m_Peers.size (); }; 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 */ /** get a trusted first hop for restricted routes */
std::shared_ptr<const i2p::data::RouterInfo> GetRestrictedPeer() const; std::shared_ptr<const i2p::data::RouterInfo> GetRestrictedPeer() const;

8
libi2pd/TunnelPool.cpp

@ -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 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -480,7 +480,7 @@ namespace tunnel
return hop; 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; 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 ();
@ -496,7 +496,7 @@ namespace tunnel
else if (i2p::transport::transports.GetNumPeers () > 100 || else if (i2p::transport::transports.GetNumPeers () > 100 ||
(inbound && i2p::transport::transports.GetNumPeers () > 25)) (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 () && if (r && r->IsECIES () && !r->GetProfile ()->IsBad () &&
(numHops > 1 || (r->IsV4 () && (!inbound || r->IsReachable ())))) // first inbound must be reachable (numHops > 1 || (r->IsV4 () && (!inbound || r->IsReachable ())))) // first inbound must be reachable
{ {
@ -512,7 +512,7 @@ namespace tunnel
if (!hop && !i) // if no suitable peer found for first hop, try already connected 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"); 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 && !hop->IsECIES ()) hop = nullptr;
} }
if (!hop) if (!hop)

10
libi2pd/TunnelPool.h

@ -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 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -54,12 +54,9 @@ namespace tunnel
virtual bool SelectPeers(Path & peers, int hops, bool isInbound) = 0; 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 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: public:
TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels,
@ -116,7 +113,8 @@ namespace tunnel
// 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, bool reverse) const; 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: private:
void TestTunnels (); void TestTunnels ();

4
libi2pd_client/MatchedDestination.cpp

@ -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 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -72,7 +72,7 @@ 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, if(!pool || !pool->StandardSelectPeers(path, hops, inbound,
std::bind(&i2p::tunnel::TunnelPool::SelectNextHop, pool, std::placeholders::_1, std::placeholders::_2))) 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

Loading…
Cancel
Save