Compare commits

...

2 Commits

Author SHA1 Message Date
orignal
29a5effabb use std::mt19937 for random numbers in netdb 2025-01-20 13:27:40 -05:00
orignal
39e07ac265 don't load router profile in NTCP2 or SSU2 thread when check for duplicates 2025-01-20 11:58:33 -05:00
4 changed files with 40 additions and 21 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2024, The PurpleI2P Project
* Copyright (c) 2013-2025, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -819,15 +819,20 @@ namespace transport
Terminate ();
return;
}
std::shared_ptr<i2p::data::RouterProfile> profile; // not null if older
bool isOlder = false;
if (ri.GetTimestamp () + i2p::data::NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < ri1->GetTimestamp ())
{
// received RouterInfo is older than one in netdb
profile = i2p::data::GetRouterProfile (ri1->GetIdentHash ()); // retrieve profile
if (profile && profile->IsDuplicated ())
isOlder = true;
if (ri1->HasProfile ())
{
SendTerminationAndTerminate (eNTCP2Banned);
return;
auto profile = i2p::data::GetRouterProfile (ri1->GetIdentHash ()); // retrieve profile
if (profile && profile->IsDuplicated ())
{
SendTerminationAndTerminate (eNTCP2Banned);
return;
}
}
}
@@ -844,8 +849,12 @@ namespace transport
memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data () + 1, addr->host.to_v6 ().to_bytes ().data () + 1, 7) : // from the same yggdrasil subnet
memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data (), addr->host.to_v6 ().to_bytes ().data (), 8)))) // temporary address
{
if (profile) // older router?
profile->Duplicated (); // mark router as duplicated in profile
if (isOlder) // older router?
i2p::data::UpdateRouterProfile (ri1->GetIdentHash (),
[](std::shared_ptr<i2p::data::RouterProfile> profile)
{
if (profile) profile->Duplicated (); // mark router as duplicated in profile
});
else
LogPrint (eLogInfo, "NTCP2: Host mismatch between published address ", addr->host, " and actual endpoint ", m_RemoteEndpoint.address ());
SendTerminationAndTerminate (eNTCP2Banned);

View File

@@ -10,7 +10,6 @@
#include <fstream>
#include <vector>
#include <map>
#include <random>
#include <boost/asio.hpp>
#include <stdexcept>
@@ -40,7 +39,7 @@ namespace data
NetDb::NetDb (): m_IsRunning (false), m_Thread (nullptr), m_Reseeder (nullptr),
m_Storage("netDb", "r", "routerInfo-", "dat"), m_PersistProfiles (true),
m_LastExploratorySelectionUpdateTime (0)
m_LastExploratorySelectionUpdateTime (0), m_Rng(i2p::util::GetMonotonicMicroseconds () % 1000000LL)
{
}
@@ -182,7 +181,7 @@ namespace data
LogPrint (eLogWarning, "NetDb: Can't persist profiles. Profiles are being saved to disk");
}
lastProfilesCleanup = mts;
profilesCleanupVariance = rand () % i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE;
profilesCleanupVariance = m_Rng () % i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE;
}
if (mts >= lastObsoleteProfilesCleanup + (uint64_t)(i2p::data::PEER_PROFILE_OBSOLETE_PROFILES_CLEAN_TIMEOUT + obsoleteProfilesCleanVariance)*1000)
@@ -198,7 +197,7 @@ namespace data
else
LogPrint (eLogWarning, "NetDb: Can't delete profiles. Profiles are being deleted from disk");
lastObsoleteProfilesCleanup = mts;
obsoleteProfilesCleanVariance = rand () % i2p::data::PEER_PROFILE_OBSOLETE_PROFILES_CLEAN_VARIANCE;
obsoleteProfilesCleanVariance = m_Rng () % i2p::data::PEER_PROFILE_OBSOLETE_PROFILES_CLEAN_VARIANCE;
}
if (mts >= lastApplyingProfileUpdates + i2p::data::PEER_PROFILE_APPLY_POSTPONED_TIMEOUT + applyingProfileUpdatesVariance)
{
@@ -211,7 +210,7 @@ namespace data
if (!isApplying)
m_ApplyingProfileUpdates = i2p::data::FlushPostponedRouterProfileUpdates ();
lastApplyingProfileUpdates = mts;
applyingProfileUpdatesVariance = rand () % i2p::data::PEER_PROFILE_APPLY_POSTPONED_TIMEOUT_VARIANCE;
applyingProfileUpdatesVariance = m_Rng () % i2p::data::PEER_PROFILE_APPLY_POSTPONED_TIMEOUT_VARIANCE;
}
}
catch (std::exception& ex)
@@ -571,7 +570,7 @@ namespace data
while(n > 0)
{
std::lock_guard<std::mutex> lock(m_RouterInfosMutex);
uint32_t idx = rand () % m_RouterInfos.size ();
uint32_t idx = m_Rng () % m_RouterInfos.size ();
uint32_t i = 0;
for (const auto & it : m_RouterInfos) {
if(i >= idx) // are we at the random start point?
@@ -1346,7 +1345,7 @@ namespace data
if (eligible.size () > NETDB_MAX_EXPLORATORY_SELECTION_SIZE)
{
std::sample (eligible.begin(), eligible.end(), std::back_inserter(m_ExploratorySelection),
NETDB_MAX_EXPLORATORY_SELECTION_SIZE, std::mt19937(ts));
NETDB_MAX_EXPLORATORY_SELECTION_SIZE, m_Rng);
}
else
std::swap (m_ExploratorySelection, eligible);

View File

@@ -16,6 +16,7 @@
#include <thread>
#include <mutex>
#include <future>
#include <random>
#include "Base.h"
#include "Gzip.h"
@@ -189,6 +190,7 @@ namespace data
std::vector<std::shared_ptr<const RouterInfo> > m_ExploratorySelection;
uint64_t m_LastExploratorySelectionUpdateTime; // in monotonic seconds
std::mt19937 m_Rng;
i2p::util::MemoryPoolMt<RouterInfo::Buffer> m_RouterInfoBuffersPool;
i2p::util::MemoryPoolMt<RouterInfo::Address> m_RouterInfoAddressesPool;

View File

@@ -1178,13 +1178,18 @@ namespace transport
LogPrint (eLogError, "SSU2: Couldn't update RouterInfo from SessionConfirmed in netdb");
return false;
}
std::shared_ptr<i2p::data::RouterProfile> profile; // not null if older
bool isOlder = false;
if (ri->GetTimestamp () + i2p::data::NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < ri1->GetTimestamp ())
{
// received RouterInfo is older than one in netdb
profile = i2p::data::GetRouterProfile (ri->GetIdentHash ()); // retrieve profile
if (profile && profile->IsDuplicated ())
return false;
isOlder = true;
if (ri->HasProfile ())
{
auto profile = i2p::data::GetRouterProfile (ri->GetIdentHash ()); // retrieve profile
if (profile && profile->IsDuplicated ())
return false;
}
}
ri = ri1;
@@ -1198,8 +1203,12 @@ namespace transport
(!m_RemoteEndpoint.address ().is_v6 () ||
memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data (), m_Address->host.to_v6 ().to_bytes ().data (), 8))) // temporary address
{
if (profile) // older router?
profile->Duplicated (); // mark router as duplicated in profile
if (isOlder) // older router?
i2p::data::UpdateRouterProfile (ri->GetIdentHash (),
[](std::shared_ptr<i2p::data::RouterProfile> profile)
{
if (profile) profile->Duplicated (); // mark router as duplicated in profile
});
else
LogPrint (eLogInfo, "SSU2: Host mismatch between published address ", m_Address->host,
" and actual endpoint ", m_RemoteEndpoint.address (), " from ", i2p::data::GetIdentHashAbbreviation (ri->GetIdentHash ()));