diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 578c09eb..7a7400f9 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -662,24 +662,29 @@ namespace transport ); } - std::set SSUServer::FindIntroducers (int maxNumIntroducers, bool v4) + std::list > SSUServer::FindIntroducers (int maxNumIntroducers, bool v4) { uint32_t ts = i2p::util::GetSecondsSinceEpoch (); - std::set ret; - auto filter = [&ret, ts](std::shared_ptr session)->bool - { - return session->GetRelayTag () && !ret.count (session.get ()) && - session->GetState () == eSessionStateEstablished && - ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION; - }; - for (int i = 0; i < maxNumIntroducers; i++) + std::list > ret; + const auto& sessions = v4 ? m_Sessions : m_SessionsV6; + for (const auto& s : sessions) + { + if (s.second->GetRelayTag () && s.second->GetState () == eSessionStateEstablished && + ts < s.second->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION) + ret.push_back (s.second); + } + if ((int)ret.size () > maxNumIntroducers) { - auto session = v4 ? GetRandomV4Session (filter) : GetRandomV6Session (filter); - if (session) - ret.insert (session.get ()); - else - break; - } + // shink ret randomly + int sz = ret.size () - maxNumIntroducers; + for (int i = 0; i < sz; i++) + { + auto ind = rand () % ret.size (); + auto it = ret.begin (); + std::advance (it, ind); + ret.erase (it); + } + } return ret; } @@ -770,7 +775,7 @@ namespace transport if (numIntroducers < SSU_MAX_NUM_INTRODUCERS) { // create new - auto sessions = FindIntroducers (SSU_MAX_NUM_INTRODUCERS - numIntroducers, v4); + auto sessions = FindIntroducers (SSU_MAX_NUM_INTRODUCERS, v4); // try to find if duplicates for (const auto& it1: sessions) { const auto& ep = it1->GetRemoteEndpoint (); diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index cfeaf85f..e1751e0d 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -100,7 +100,7 @@ namespace transport template std::shared_ptr GetRandomV6Session (Filter filter); - std::set FindIntroducers (int maxNumIntroducers, bool v4); + std::list > FindIntroducers (int maxNumIntroducers, bool v4); void ScheduleIntroducersUpdateTimer (); void ScheduleIntroducersUpdateTimerV6 (); void HandleIntroducersUpdateTimer (const boost::system::error_code& ecode, bool v4);