diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 0e6b1910..e92a3810 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -1056,30 +1056,32 @@ namespace transport return ret; } - std::list > SSU2Server::FindIntroducers (int maxNumIntroducers, - bool v4, const std::unordered_set& excluded) + std::vector > SSU2Server::FindIntroducers (int maxNumIntroducers, + bool v4, const std::unordered_set& excluded) const { - std::list > ret; + std::vector > ret; + if (maxNumIntroducers <= 0) return ret; + auto newer = [](const std::shared_ptr& s1, const std::shared_ptr& s2) -> bool + { + auto t1 = s1->GetCreationTime (), t2 = s2->GetCreationTime (); + return (t1 != t2) ? (t1 > t2) : (s1->GetConnID () > s2->GetConnID ()); + }; + std::set, decltype (newer)> introducers(newer); for (const auto& s : m_Sessions) { if (s.second->IsEstablished () && (s.second->GetRelayTag () && s.second->IsOutgoing ()) && !excluded.count (s.second->GetRemoteIdentity ()->GetIdentHash ()) && ((v4 && (s.second->GetRemoteTransports () & i2p::data::RouterInfo::eSSU2V4)) || (!v4 && (s.second->GetRemoteTransports () & i2p::data::RouterInfo::eSSU2V6)))) - ret.push_back (s.second); + introducers.insert (s.second); } - if ((int)ret.size () > maxNumIntroducers) + int i = 0; + for (auto it: introducers) { - // shink ret randomly - int sz = ret.size () - maxNumIntroducers; - for (int i = 0; i < sz; i++) - { - auto ind = m_Rng () % ret.size (); - auto it = ret.begin (); - std::advance (it, ind); - ret.erase (it); - } - } + ret.push_back (it); + i++; + if (i >= maxNumIntroducers) break; + } return ret; } diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h index aace654a..5a9eba44 100644 --- a/libi2pd/SSU2.h +++ b/libi2pd/SSU2.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include "util.h" @@ -129,8 +130,8 @@ namespace transport void HandleResendTimer (const boost::system::error_code& ecode); void ConnectThroughIntroducer (std::shared_ptr session); - std::list > FindIntroducers (int maxNumIntroducers, - bool v4, const std::unordered_set& excluded); + std::vector > FindIntroducers (int maxNumIntroducers, + bool v4, const std::unordered_set& excluded) const; void UpdateIntroducers (bool v4); void ScheduleIntroducersUpdateTimer (); void HandleIntroducersUpdateTimer (const boost::system::error_code& ecode, bool v4);