diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 1c874e3d..8c5406cb 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -298,7 +298,7 @@ namespace data if (m_Floodfills.GetSize () < NETDB_NUM_FLOODFILLS_THRESHOLD || r->GetProfile ()->IsReal ()) m_Floodfills.Insert (r); else - r->ResetFloodFill (); + r->ResetFloodfill (); } } } @@ -333,7 +333,7 @@ namespace data m_Floodfills.Insert (r); } else - r->ResetFloodFill (); + r->ResetFloodfill (); } } else @@ -458,7 +458,16 @@ namespace data r->SetUnreachable (unreachable); auto profile = r->GetProfile (); if (profile) + { profile->Unreachable (unreachable); + if (!unreachable && r->IsDeclaredFloodfill () && !r->IsFloodfill () && + r->IsEligibleFloodfill () && profile->IsReal ()) + { + // enable previously disabled floodfill + std::lock_guard l(m_FloodfillsMutex); + m_Floodfills.Insert (r); + } + } } } diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 3eb6ffbf..1bc7a203 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -560,10 +560,10 @@ namespace i2p { m_IsFloodfill = floodfill; if (floodfill) - m_RouterInfo.UpdateCaps (m_RouterInfo.GetCaps () | i2p::data::RouterInfo::eFloodfill); + m_RouterInfo.UpdateFloodfillProperty (true); else { - m_RouterInfo.UpdateCaps (m_RouterInfo.GetCaps () & ~i2p::data::RouterInfo::eFloodfill); + m_RouterInfo.UpdateFloodfillProperty (false); // we don't publish number of routers and leaseset for non-floodfill m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_LEASESETS); m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_ROUTERS); diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 8f12fb57..74417133 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -42,7 +42,7 @@ namespace data } RouterInfo::RouterInfo (const std::string& fullPath): - m_FamilyID (0), m_IsUpdated (false), m_IsUnreachable (false), + m_FamilyID (0), m_IsUpdated (false), m_IsUnreachable (false), m_IsFloodfill (false), m_SupportedTransports (0),m_ReachableTransports (0), m_PublishedTransports (0), m_Caps (0), m_Version (0), m_Congestion (eLowCongestion) { @@ -52,7 +52,7 @@ namespace data } RouterInfo::RouterInfo (std::shared_ptr&& buf, size_t len): - m_FamilyID (0), m_IsUpdated (true), m_IsUnreachable (false), + m_FamilyID (0), m_IsUpdated (true), m_IsUnreachable (false), m_IsFloodfill (false), m_SupportedTransports (0), m_ReachableTransports (0), m_PublishedTransports (0), m_Caps (0), m_Version (0), m_Congestion (eLowCongestion) { @@ -97,7 +97,7 @@ namespace data m_SupportedTransports = 0; m_ReachableTransports = 0; m_PublishedTransports = 0; - m_Caps = 0; + m_Caps = 0; m_IsFloodfill = false; // don't clean up m_Addresses, it will be replaced in ReadFromStream ClearProperties (); // skip identity @@ -451,7 +451,10 @@ namespace data // extract caps if (!strcmp (key, "caps")) + { ExtractCaps (value); + m_IsFloodfill = IsDeclaredFloodfill (); + } // extract version else if (!strcmp (key, ROUTER_INFO_PROPERTY_VERSION)) { @@ -1427,6 +1430,20 @@ namespace data return ""; } + void LocalRouterInfo::UpdateFloodfillProperty (bool floodfill) + { + if (floodfill) + { + UpdateCaps (GetCaps () | i2p::data::RouterInfo::eFloodfill); + SetFloodfill (); + } + else + { + UpdateCaps (GetCaps () & ~i2p::data::RouterInfo::eFloodfill); + ResetFloodfill (); + } + } + void LocalRouterInfo::WriteString (const std::string& str, std::ostream& s) const { uint8_t len = str.size (); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 423f1e9e..40534320 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -227,8 +227,9 @@ namespace data void SetUnreachableAddressesTransportCaps (uint8_t transports); // bitmask of AddressCaps void UpdateSupportedTransports (); void UpdateIntroducers (uint64_t ts); // ts in seconds - bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; }; - void ResetFloodFill () { m_Caps &= ~Caps::eFloodfill; }; + bool IsFloodfill () const { return m_IsFloodfill; }; + void SetFloodfill () { m_IsFloodfill = true; }; + void ResetFloodfill () { m_IsFloodfill = false; }; bool IsECIES () const { return m_RouterIdentity->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; }; bool IsNTCP2 (bool v4only = true) const; bool IsNTCP2V6 () const { return m_SupportedTransports & eNTCP2V6; }; @@ -253,6 +254,7 @@ namespace data bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; }; bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; }; bool IsEligibleFloodfill () const; + bool IsDeclaredFloodfill () const { return m_Caps & RouterInfo::eFloodfill; }; bool IsPublished (bool v4) const; bool IsNAT2NATOnly (const RouterInfo& other) const; // only NAT-to-NAT connection is possible bool IsSSU2PeerTesting (bool v4) const; @@ -328,7 +330,7 @@ namespace data size_t m_BufferLen; uint64_t m_Timestamp; // in milliseconds boost::shared_ptr m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9 - bool m_IsUpdated, m_IsUnreachable; + bool m_IsUpdated, m_IsUnreachable, m_IsFloodfill; CompatibleTransports m_SupportedTransports, m_ReachableTransports, m_PublishedTransports; uint8_t m_Caps; int m_Version; @@ -349,7 +351,8 @@ namespace data void DeleteProperty (const std::string& key); std::string GetProperty (const std::string& key) const; void ClearProperties () override { m_Properties.clear (); }; - + void UpdateFloodfillProperty (bool floodfill); + bool AddSSU2Introducer (const Introducer& introducer, bool v4); bool RemoveSSU2Introducer (const IdentHash& h, bool v4);