mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 12:24:19 +00:00
Transports priority for peer
This commit is contained in:
parent
e338ce7da9
commit
cef2263a7f
@ -417,8 +417,7 @@ namespace transport
|
|||||||
{
|
{
|
||||||
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
std::unique_lock<std::mutex> l(m_PeersMutex);
|
std::unique_lock<std::mutex> l(m_PeersMutex);
|
||||||
it = m_Peers.insert (std::pair<i2p::data::IdentHash, Peer>(ident, { 0, r, {},
|
it = m_Peers.insert (std::pair<i2p::data::IdentHash, Peer>(ident, {r, ts})).first;
|
||||||
ts, ts + PEER_ROUTER_INFO_UPDATE_INTERVAL, {} })).first;
|
|
||||||
}
|
}
|
||||||
connected = ConnectToPeer (ident, it->second);
|
connected = ConnectToPeer (ident, it->second);
|
||||||
}
|
}
|
||||||
@ -453,127 +452,81 @@ namespace transport
|
|||||||
peer.router = netdb.FindRouter (ident); // try to get new one from netdb
|
peer.router = 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.numAttempts < 2) // NTCP2, 0 - ipv6, 1 - ipv4
|
if (peer.priority.empty ())
|
||||||
{
|
SetPriority (peer);
|
||||||
if (m_NTCP2Server) // we support NTCP2
|
while (peer.numAttempts < (int)peer.priority.size ())
|
||||||
{
|
|
||||||
std::shared_ptr<const RouterInfo::Address> address;
|
|
||||||
if (!peer.numAttempts) // NTCP2 ipv6
|
|
||||||
{
|
|
||||||
if (context.GetRouterInfo ().IsNTCP2V6 () && peer.router->IsReachableBy (RouterInfo::eNTCP2V6))
|
|
||||||
{
|
|
||||||
address = peer.router->GetPublishedNTCP2V6Address ();
|
|
||||||
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
|
||||||
address = nullptr;
|
|
||||||
}
|
|
||||||
peer.numAttempts++;
|
|
||||||
}
|
|
||||||
if (!address && peer.numAttempts == 1) // NTCP2 ipv4
|
|
||||||
{
|
|
||||||
if (context.GetRouterInfo ().IsNTCP2 (true) && peer.router->IsReachableBy (RouterInfo::eNTCP2V4))
|
|
||||||
{
|
|
||||||
address = peer.router->GetPublishedNTCP2V4Address ();
|
|
||||||
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
|
||||||
address = nullptr;
|
|
||||||
}
|
|
||||||
peer.numAttempts++;
|
|
||||||
}
|
|
||||||
if (address)
|
|
||||||
{
|
|
||||||
auto s = std::make_shared<NTCP2Session> (*m_NTCP2Server, peer.router, address);
|
|
||||||
if( m_NTCP2Server->UsingProxy())
|
|
||||||
m_NTCP2Server->ConnectWithProxy(s);
|
|
||||||
else
|
|
||||||
m_NTCP2Server->Connect (s);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
peer.numAttempts = 2; // switch to SSU
|
|
||||||
}
|
|
||||||
if (peer.numAttempts == 2 || peer.numAttempts == 3) // SSU2, 2 - ipv6, 3 - ipv4
|
|
||||||
{
|
|
||||||
if (m_SSU2Server)
|
|
||||||
{
|
|
||||||
std::shared_ptr<const RouterInfo::Address> address;
|
|
||||||
if (peer.numAttempts == 2) // SSU2 ipv6
|
|
||||||
{
|
|
||||||
if (context.GetRouterInfo ().IsSSU2V6 () && peer.router->IsReachableBy (RouterInfo::eSSU2V6))
|
|
||||||
{
|
|
||||||
address = peer.router->GetSSU2V6Address ();
|
|
||||||
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
|
||||||
address = nullptr;
|
|
||||||
}
|
|
||||||
peer.numAttempts++;
|
|
||||||
}
|
|
||||||
if (!address && peer.numAttempts == 3) // SSU2 ipv4
|
|
||||||
{
|
|
||||||
if (context.GetRouterInfo ().IsSSU2V4 () && peer.router->IsReachableBy (RouterInfo::eSSU2V4))
|
|
||||||
{
|
|
||||||
address = peer.router->GetSSU2V4Address ();
|
|
||||||
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
|
||||||
address = nullptr;
|
|
||||||
}
|
|
||||||
peer.numAttempts++;
|
|
||||||
}
|
|
||||||
if (address && address->IsReachableSSU ())
|
|
||||||
{
|
|
||||||
if (m_SSU2Server->CreateSession (peer.router, address))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
peer.numAttempts += 2; // switch to mesh
|
|
||||||
}
|
|
||||||
if (peer.numAttempts == 4) // Mesh
|
|
||||||
{
|
{
|
||||||
|
auto tr = peer.priority[peer.numAttempts];
|
||||||
peer.numAttempts++;
|
peer.numAttempts++;
|
||||||
if (m_NTCP2Server && context.GetRouterInfo ().IsMesh () && peer.router->IsMesh ())
|
switch (tr)
|
||||||
{
|
{
|
||||||
auto address = peer.router->GetYggdrasilAddress ();
|
case i2p::data::RouterInfo::eNTCP2V4:
|
||||||
if (address)
|
case i2p::data::RouterInfo::eNTCP2V6:
|
||||||
{
|
{
|
||||||
auto s = std::make_shared<NTCP2Session> (*m_NTCP2Server, peer.router, address);
|
if (!m_NTCP2Server) continue;
|
||||||
m_NTCP2Server->Connect (s);
|
std::shared_ptr<const RouterInfo::Address> address = (tr == i2p::data::RouterInfo::eNTCP2V6) ?
|
||||||
return true;
|
peer.router->GetPublishedNTCP2V6Address () : peer.router->GetPublishedNTCP2V4Address ();
|
||||||
}
|
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
||||||
}
|
address = nullptr;
|
||||||
}
|
if (address)
|
||||||
if (peer.numAttempts == 5 || peer.numAttempts == 6) // SSU, 5 - ipv6, 6 - ipv4
|
|
||||||
{
|
|
||||||
if (m_SSUServer)
|
|
||||||
{
|
|
||||||
std::shared_ptr<const RouterInfo::Address> address;
|
|
||||||
if (peer.numAttempts == 5) // SSU ipv6
|
|
||||||
{
|
|
||||||
if (context.GetRouterInfo ().IsSSUV6 () && peer.router->IsReachableBy (RouterInfo::eSSUV6))
|
|
||||||
{
|
{
|
||||||
address = peer.router->GetSSUV6Address ();
|
auto s = std::make_shared<NTCP2Session> (*m_NTCP2Server, peer.router, address);
|
||||||
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
if( m_NTCP2Server->UsingProxy())
|
||||||
address = nullptr;
|
m_NTCP2Server->ConnectWithProxy(s);
|
||||||
}
|
else
|
||||||
peer.numAttempts++;
|
m_NTCP2Server->Connect (s);
|
||||||
}
|
|
||||||
if (!address && peer.numAttempts == 6) // SSU ipv4
|
|
||||||
{
|
|
||||||
if (context.GetRouterInfo ().IsSSU (true) && peer.router->IsReachableBy (RouterInfo::eSSUV4))
|
|
||||||
{
|
|
||||||
address = peer.router->GetSSUAddress (true);
|
|
||||||
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
|
||||||
address = nullptr;
|
|
||||||
}
|
|
||||||
peer.numAttempts++;
|
|
||||||
}
|
|
||||||
if (address && address->IsReachableSSU ())
|
|
||||||
{
|
|
||||||
if (m_SSUServer->CreateSession (peer.router, address))
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
case i2p::data::RouterInfo::eSSU2V4:
|
||||||
else
|
case i2p::data::RouterInfo::eSSU2V6:
|
||||||
peer.numAttempts += 2;
|
{
|
||||||
}
|
if (!m_SSU2Server) continue;
|
||||||
LogPrint (eLogInfo, "Transports: No compatble NTCP2 or SSU addresses available");
|
std::shared_ptr<const RouterInfo::Address> address = (tr == i2p::data::RouterInfo::eSSU2V6) ?
|
||||||
|
peer.router->GetSSU2V6Address () : peer.router->GetSSU2V4Address ();
|
||||||
|
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
||||||
|
address = nullptr;
|
||||||
|
if (address && address->IsReachableSSU ())
|
||||||
|
{
|
||||||
|
if (m_SSU2Server->CreateSession (peer.router, address))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case i2p::data::RouterInfo::eSSUV4:
|
||||||
|
case i2p::data::RouterInfo::eSSUV6:
|
||||||
|
{
|
||||||
|
if (!m_SSUServer) continue;
|
||||||
|
std::shared_ptr<const RouterInfo::Address> address = (tr == i2p::data::RouterInfo::eSSUV6) ?
|
||||||
|
peer.router->GetSSUV6Address () : peer.router->GetSSUAddress (true);
|
||||||
|
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
||||||
|
address = nullptr;
|
||||||
|
if (address && address->IsReachableSSU ())
|
||||||
|
{
|
||||||
|
if (m_SSUServer->CreateSession (peer.router, address))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case i2p::data::RouterInfo::eNTCP2V6Mesh:
|
||||||
|
{
|
||||||
|
if (!m_NTCP2Server) continue;
|
||||||
|
auto address = peer.router->GetYggdrasilAddress ();
|
||||||
|
if (address)
|
||||||
|
{
|
||||||
|
auto s = std::make_shared<NTCP2Session> (*m_NTCP2Server, peer.router, address);
|
||||||
|
m_NTCP2Server->Connect (s);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
LogPrint (eLogError, "Transports: Unknown transport ", (int)tr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogPrint (eLogInfo, "Transports: No compatible addresses available");
|
||||||
i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed
|
i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed
|
||||||
peer.Done ();
|
peer.Done ();
|
||||||
std::unique_lock<std::mutex> l(m_PeersMutex);
|
std::unique_lock<std::mutex> l(m_PeersMutex);
|
||||||
@ -585,10 +538,32 @@ namespace transport
|
|||||||
LogPrint (eLogInfo, "Transports: RouterInfo for ", ident.ToBase64 (), " not found, requested");
|
LogPrint (eLogInfo, "Transports: RouterInfo for ", ident.ToBase64 (), " not found, requested");
|
||||||
i2p::data::netdb.RequestDestination (ident, std::bind (
|
i2p::data::netdb.RequestDestination (ident, std::bind (
|
||||||
&Transports::RequestComplete, this, std::placeholders::_1, ident));
|
&Transports::RequestComplete, this, std::placeholders::_1, ident));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Transports::SetPriority (Peer& peer) const
|
||||||
|
{
|
||||||
|
static const std::vector<i2p::data::RouterInfo::SupportedTransports> ntcp2Priority =
|
||||||
|
{
|
||||||
|
i2p::data::RouterInfo::eNTCP2V6,
|
||||||
|
i2p::data::RouterInfo::eNTCP2V4,
|
||||||
|
i2p::data::RouterInfo::eSSU2V6,
|
||||||
|
i2p::data::RouterInfo::eSSU2V4,
|
||||||
|
i2p::data::RouterInfo::eNTCP2V6Mesh,
|
||||||
|
i2p::data::RouterInfo::eSSUV6,
|
||||||
|
i2p::data::RouterInfo::eSSUV4
|
||||||
|
};
|
||||||
|
if (!peer.router) return;
|
||||||
|
auto compatibleTransports = context.GetRouterInfo ().GetCompatibleTransports (false) &
|
||||||
|
peer.router->GetCompatibleTransports (true);
|
||||||
|
peer.numAttempts = 0;
|
||||||
|
peer.priority.clear ();
|
||||||
|
for (auto transport: ntcp2Priority)
|
||||||
|
if (transport & compatibleTransports)
|
||||||
|
peer.priority.push_back (transport);
|
||||||
|
}
|
||||||
|
|
||||||
void Transports::RequestComplete (std::shared_ptr<const i2p::data::RouterInfo> r, const i2p::data::IdentHash& ident)
|
void Transports::RequestComplete (std::shared_ptr<const i2p::data::RouterInfo> r, const i2p::data::IdentHash& ident)
|
||||||
{
|
{
|
||||||
m_Service->post (std::bind (&Transports::HandleRequestComplete, this, r, ident));
|
m_Service->post (std::bind (&Transports::HandleRequestComplete, this, r, ident));
|
||||||
@ -779,8 +754,7 @@ namespace transport
|
|||||||
session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); // send DatabaseStore
|
session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); // send DatabaseStore
|
||||||
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
std::unique_lock<std::mutex> l(m_PeersMutex);
|
std::unique_lock<std::mutex> l(m_PeersMutex);
|
||||||
m_Peers.insert (std::make_pair (ident, Peer{ 0, nullptr, { session },
|
m_Peers.insert (std::make_pair (ident, Peer{ nullptr, ts }));
|
||||||
ts, ts + PEER_ROUTER_INFO_UPDATE_INTERVAL, {} }));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,14 @@ namespace transport
|
|||||||
std::list<std::shared_ptr<TransportSession> > sessions;
|
std::list<std::shared_ptr<TransportSession> > sessions;
|
||||||
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;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void Done ()
|
void Done ()
|
||||||
{
|
{
|
||||||
for (auto& it: sessions)
|
for (auto& it: sessions)
|
||||||
@ -147,6 +154,7 @@ namespace transport
|
|||||||
void HandleRequestComplete (std::shared_ptr<const i2p::data::RouterInfo> r, i2p::data::IdentHash ident);
|
void HandleRequestComplete (std::shared_ptr<const i2p::data::RouterInfo> r, i2p::data::IdentHash ident);
|
||||||
void PostMessages (i2p::data::IdentHash ident, std::vector<std::shared_ptr<i2p::I2NPMessage> > msgs);
|
void PostMessages (i2p::data::IdentHash ident, std::vector<std::shared_ptr<i2p::I2NPMessage> > msgs);
|
||||||
bool ConnectToPeer (const i2p::data::IdentHash& ident, Peer& peer);
|
bool ConnectToPeer (const i2p::data::IdentHash& ident, Peer& peer);
|
||||||
|
void SetPriority (Peer& peer) const;
|
||||||
void HandlePeerCleanupTimer (const boost::system::error_code& ecode);
|
void HandlePeerCleanupTimer (const boost::system::error_code& ecode);
|
||||||
void HandlePeerTestTimer (const boost::system::error_code& ecode);
|
void HandlePeerTestTimer (const boost::system::error_code& ecode);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user