mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-02 15:14:14 +00: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_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;
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
|
||||||
|
@ -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…
x
Reference in New Issue
Block a user