diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 24b99833..6dcdabec 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -36,7 +36,8 @@ namespace data m_LastUpdateTime (GetTime ()), m_IsUpdated (false), m_LastDeclineTime (0), m_LastUnreachableTime (0), m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0), - m_NumTimesTaken (0), m_NumTimesRejected (0), m_HasConnected (false) + m_NumTimesTaken (0), m_NumTimesRejected (0), m_HasConnected (false), + m_IsDuplicated (false) { } @@ -57,6 +58,8 @@ namespace data usage.put (PEER_PROFILE_USAGE_TAKEN, m_NumTimesTaken); usage.put (PEER_PROFILE_USAGE_REJECTED, m_NumTimesRejected); usage.put (PEER_PROFILE_USAGE_CONNECTED, m_HasConnected); + if (m_IsDuplicated) + usage.put (PEER_PROFILE_USAGE_DUPLICATED, true); // fill property tree boost::property_tree::ptree pt; pt.put (PEER_PROFILE_LAST_UPDATE_TIME, boost::posix_time::to_simple_string (m_LastUpdateTime)); @@ -126,6 +129,7 @@ namespace data m_NumTimesTaken = usage.get (PEER_PROFILE_USAGE_TAKEN, 0); m_NumTimesRejected = usage.get (PEER_PROFILE_USAGE_REJECTED, 0); m_HasConnected = usage.get (PEER_PROFILE_USAGE_CONNECTED, false); + m_IsDuplicated = usage.get (PEER_PROFILE_USAGE_DUPLICATED, false); } catch (boost::property_tree::ptree_bad_path& ex) { @@ -178,6 +182,11 @@ namespace data UpdateTime (); } + void RouterProfile::Duplicated () + { + m_IsDuplicated = true; + } + bool RouterProfile::IsLowPartcipationRate () const { return 4*m_NumTunnelsAgreed < m_NumTunnelsDeclined; // < 20% rate @@ -201,7 +210,7 @@ namespace data bool RouterProfile::IsBad () { - if (IsDeclinedRecently () || IsUnreachable ()) return true; + if (IsDeclinedRecently () || IsUnreachable () || m_IsDuplicated) return true; auto isBad = IsAlwaysDeclining () || IsLowPartcipationRate () /*|| IsLowReplyRate ()*/; if (isBad && m_NumTimesRejected > 10*(m_NumTimesTaken + 1)) { diff --git a/libi2pd/Profiling.h b/libi2pd/Profiling.h index f4c4a4da..2bae61d4 100644 --- a/libi2pd/Profiling.h +++ b/libi2pd/Profiling.h @@ -30,6 +30,7 @@ namespace data const char PEER_PROFILE_USAGE_TAKEN[] = "taken"; const char PEER_PROFILE_USAGE_REJECTED[] = "rejected"; const char PEER_PROFILE_USAGE_CONNECTED[] = "connected"; + const char PEER_PROFILE_USAGE_DUPLICATED[] = "duplicated"; const int PEER_PROFILE_EXPIRATION_TIMEOUT = 36; // in hours (1.5 days) const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 1500; // in seconds (25 minutes) @@ -59,6 +60,7 @@ namespace data void Unreachable (bool unreachable); void Connected (); + void Duplicated (); boost::posix_time::ptime GetLastUpdateTime () const { return m_LastUpdateTime; }; bool IsUpdated () const { return m_IsUpdated; }; @@ -87,6 +89,7 @@ namespace data uint32_t m_NumTimesTaken; uint32_t m_NumTimesRejected; bool m_HasConnected; // successful trusted(incoming or NTCP2) connection + bool m_IsDuplicated; }; std::shared_ptr GetRouterProfile (const IdentHash& identHash); diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index bb82135f..b0338666 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -1132,7 +1132,14 @@ namespace transport LogPrint (eLogError, "SSU2: Couldn't update RouterInfo from SessionConfirmed in netdb"); return false; } - if (ri->GetTimestamp () >= ri1->GetTimestamp ()) ri = ri1; // received RouterInfo is not older than one in netdb + if (ri->GetTimestamp () + i2p::data::NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL >= ri1->GetTimestamp ()) + ri = ri1; // received RouterInfo is not older than one in netdb + else + { + // othewise we assume duplicate + auto profile = i2p::data::GetRouterProfile (ri->GetIdentHash ()); + if (profile) profile->Duplicated (); // mark router as duplicated in profile + } m_Address = m_RemoteEndpoint.address ().is_v6 () ? ri->GetSSU2V6Address () : ri->GetSSU2V4Address (); if (!m_Address || memcmp (S, m_Address->s, 32))