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 * This file is part of Purple i2pd project and licensed under BSD3
* *
@@ -819,15 +819,20 @@ namespace transport
Terminate (); Terminate ();
return; 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 ()) if (ri.GetTimestamp () + i2p::data::NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < ri1->GetTimestamp ())
{ {
// received RouterInfo is older than one in netdb // received RouterInfo is older than one in netdb
profile = i2p::data::GetRouterProfile (ri1->GetIdentHash ()); // retrieve profile isOlder = true;
if (profile && profile->IsDuplicated ()) if (ri1->HasProfile ())
{ {
SendTerminationAndTerminate (eNTCP2Banned); auto profile = i2p::data::GetRouterProfile (ri1->GetIdentHash ()); // retrieve profile
return; 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 () + 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 memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data (), addr->host.to_v6 ().to_bytes ().data (), 8)))) // temporary address
{ {
if (profile) // older router? if (isOlder) // older router?
profile->Duplicated (); // mark router as duplicated in profile i2p::data::UpdateRouterProfile (ri1->GetIdentHash (),
[](std::shared_ptr<i2p::data::RouterProfile> profile)
{
if (profile) profile->Duplicated (); // mark router as duplicated in profile
});
else else
LogPrint (eLogInfo, "NTCP2: Host mismatch between published address ", addr->host, " and actual endpoint ", m_RemoteEndpoint.address ()); LogPrint (eLogInfo, "NTCP2: Host mismatch between published address ", addr->host, " and actual endpoint ", m_RemoteEndpoint.address ());
SendTerminationAndTerminate (eNTCP2Banned); SendTerminationAndTerminate (eNTCP2Banned);

View File

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

View File

@@ -16,6 +16,7 @@
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#include <future> #include <future>
#include <random>
#include "Base.h" #include "Base.h"
#include "Gzip.h" #include "Gzip.h"
@@ -189,6 +190,7 @@ namespace data
std::vector<std::shared_ptr<const RouterInfo> > m_ExploratorySelection; std::vector<std::shared_ptr<const RouterInfo> > m_ExploratorySelection;
uint64_t m_LastExploratorySelectionUpdateTime; // in monotonic seconds uint64_t m_LastExploratorySelectionUpdateTime; // in monotonic seconds
std::mt19937 m_Rng;
i2p::util::MemoryPoolMt<RouterInfo::Buffer> m_RouterInfoBuffersPool; i2p::util::MemoryPoolMt<RouterInfo::Buffer> m_RouterInfoBuffersPool;
i2p::util::MemoryPoolMt<RouterInfo::Address> m_RouterInfoAddressesPool; 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"); LogPrint (eLogError, "SSU2: Couldn't update RouterInfo from SessionConfirmed in netdb");
return false; 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 ()) if (ri->GetTimestamp () + i2p::data::NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < ri1->GetTimestamp ())
{ {
// received RouterInfo is older than one in netdb // received RouterInfo is older than one in netdb
profile = i2p::data::GetRouterProfile (ri->GetIdentHash ()); // retrieve profile isOlder = true;
if (profile && profile->IsDuplicated ()) if (ri->HasProfile ())
return false; {
auto profile = i2p::data::GetRouterProfile (ri->GetIdentHash ()); // retrieve profile
if (profile && profile->IsDuplicated ())
return false;
}
} }
ri = ri1; ri = ri1;
@@ -1198,8 +1203,12 @@ namespace transport
(!m_RemoteEndpoint.address ().is_v6 () || (!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 memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data (), m_Address->host.to_v6 ().to_bytes ().data (), 8))) // temporary address
{ {
if (profile) // older router? if (isOlder) // older router?
profile->Duplicated (); // mark router as duplicated in profile i2p::data::UpdateRouterProfile (ri->GetIdentHash (),
[](std::shared_ptr<i2p::data::RouterProfile> profile)
{
if (profile) profile->Duplicated (); // mark router as duplicated in profile
});
else else
LogPrint (eLogInfo, "SSU2: Host mismatch between published address ", m_Address->host, LogPrint (eLogInfo, "SSU2: Host mismatch between published address ", m_Address->host,
" and actual endpoint ", m_RemoteEndpoint.address (), " from ", i2p::data::GetIdentHashAbbreviation (ri->GetIdentHash ())); " and actual endpoint ", m_RemoteEndpoint.address (), " from ", i2p::data::GetIdentHashAbbreviation (ri->GetIdentHash ()));