From ee1c4f4fdc5f8c440580f50c6ae3439524707867 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 24 Mar 2022 15:50:20 -0400 Subject: [PATCH] internal numeric id for families --- libi2pd/Family.cpp | 16 ++++++++++++---- libi2pd/Family.h | 8 +++++--- libi2pd/NetDb.cpp | 3 ++- libi2pd/NetDb.hpp | 2 +- libi2pd/RouterInfo.cpp | 25 +++++++++++++------------ libi2pd/RouterInfo.h | 5 +++-- libi2pd/Transports.cpp | 17 +++++++++++------ libi2pd/Transports.h | 4 ++-- 8 files changed, 49 insertions(+), 31 deletions(-) diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index a6f0e2ee..09dc30dd 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2022, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -88,7 +88,7 @@ namespace data } EVP_PKEY_free (pkey); if (verifier && cn) - m_SigningKeys[cn] = verifier; + m_SigningKeys.emplace (cn, std::make_pair(verifier, m_SigningKeys.size () + 1)); } SSL_free (ssl); } @@ -121,7 +121,7 @@ namespace data } bool Families::VerifyFamily (const std::string& family, const IdentHash& ident, - const char * signature, const char * key) + const char * signature, const char * key) const { uint8_t buf[100], signatureBuf[64]; size_t len = family.length (), signatureLen = strlen (signature); @@ -137,11 +137,19 @@ namespace data Base64ToByteStream (signature, signatureLen, signatureBuf, 64); auto it = m_SigningKeys.find (family); if (it != m_SigningKeys.end ()) - return it->second->Verify (buf, len, signatureBuf); + return it->second.first->Verify (buf, len, signatureBuf); // TODO: process key return true; } + FamilyID Families::GetFamilyID (const std::string& family) const + { + auto it = m_SigningKeys.find (family); + if (it != m_SigningKeys.end ()) + return it->second.second; + return 0; + } + std::string CreateFamilySignature (const std::string& family, const IdentHash& ident) { auto filename = i2p::fs::DataDirPath("family", (family + ".key")); diff --git a/libi2pd/Family.h b/libi2pd/Family.h index 2a9149ba..b19ea142 100644 --- a/libi2pd/Family.h +++ b/libi2pd/Family.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2022, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -19,6 +19,7 @@ namespace i2p { namespace data { + typedef int FamilyID; class Families { public: @@ -27,7 +28,8 @@ namespace data ~Families (); void LoadCertificates (); bool VerifyFamily (const std::string& family, const IdentHash& ident, - const char * signature, const char * key = nullptr); + const char * signature, const char * key = nullptr) const; + FamilyID GetFamilyID (const std::string& family) const; private: @@ -35,7 +37,7 @@ namespace data private: - std::map > m_SigningKeys; + std::map, FamilyID> > m_SigningKeys; // family -> (verifier, id) }; std::string CreateFamilySignature (const std::string& family, const IdentHash& ident); diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 5f05b0eb..8e25db6d 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1364,7 +1364,8 @@ namespace data return res; } - std::shared_ptr NetDb::GetRandomRouterInFamily(const std::string & fam) const { + std::shared_ptr NetDb::GetRandomRouterInFamily (FamilyID fam) const + { return GetRandomRouter( [fam](std::shared_ptr router)->bool { diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 1d087e46..b244fa83 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -96,7 +96,7 @@ namespace data std::vector GetClosestFloodfills (const IdentHash& destination, size_t num, std::set& excluded, bool closeThanUsOnly = false) const; std::shared_ptr GetClosestNonFloodfill (const IdentHash& destination, const std::set& excluded) const; - std::shared_ptr GetRandomRouterInFamily(const std::string & fam) const; + std::shared_ptr GetRandomRouterInFamily (FamilyID fam) const; void SetUnreachable (const IdentHash& ident, bool unreachable); void PostI2NPMsg (std::shared_ptr msg); diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index d572f74d..5e1479f8 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -41,7 +41,7 @@ namespace data } RouterInfo::RouterInfo (const std::string& fullPath): - m_IsUpdated (false), m_IsUnreachable (false), + m_FamilyID (0), m_IsUpdated (false), m_IsUnreachable (false), m_SupportedTransports (0),m_ReachableTransports (0), m_Caps (0), m_Version (0) { @@ -51,8 +51,9 @@ namespace data } RouterInfo::RouterInfo (std::shared_ptr&& buf, size_t len): - m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), - m_ReachableTransports (0), m_Caps (0), m_Version (0) + m_FamilyID (0), m_IsUpdated (true), m_IsUnreachable (false), + m_SupportedTransports (0), m_ReachableTransports (0), + m_Caps (0), m_Version (0) { if (len <= MAX_RI_BUFFER_SIZE) { @@ -442,6 +443,7 @@ namespace data // read properties m_Version = 0; bool isNetId = false; + std::string family; uint16_t size, r = 0; s.read ((char *)&size, sizeof (size)); if (!s) return; size = be16toh (size); @@ -486,16 +488,15 @@ namespace data // family else if (!strcmp (key, ROUTER_INFO_PROPERTY_FAMILY)) { - m_Family = value; - boost::to_lower (m_Family); + family = value; + boost::to_lower (family); } else if (!strcmp (key, ROUTER_INFO_PROPERTY_FAMILY_SIG)) { - if (!netdb.GetFamilies ().VerifyFamily (m_Family, GetIdentHash (), value)) - { - LogPrint (eLogWarning, "RouterInfo: Family signature verification failed"); - m_Family.clear (); - } + if (netdb.GetFamilies ().VerifyFamily (family, GetIdentHash (), value)) + m_FamilyID = netdb.GetFamilies ().GetFamilyID (family); + else + LogPrint (eLogWarning, "RouterInfo: Family ", family, " signature verification failed"); } if (!s) return; @@ -505,9 +506,9 @@ namespace data SetUnreachable (true); } - bool RouterInfo::IsFamily(const std::string & fam) const + bool RouterInfo::IsFamily (FamilyID famid) const { - return m_Family == fam; + return m_FamilyID == famid; } void RouterInfo::ExtractCaps (const char * value) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 616f1a6c..a77abd17 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -19,6 +19,7 @@ #include #include "Identity.h" #include "Profiling.h" +#include "Family.h" namespace i2p { @@ -252,7 +253,7 @@ namespace data bool IsNewer (const uint8_t * buf, size_t len) const; /** return true if we are in a router family and the signature is valid */ - bool IsFamily(const std::string & fam) const; + bool IsFamily (FamilyID famid) const; // implements RoutingDestination std::shared_ptr GetIdentity () const { return m_RouterIdentity; }; @@ -284,7 +285,7 @@ namespace data private: - std::string m_Family; + FamilyID m_FamilyID; std::shared_ptr m_RouterIdentity; std::shared_ptr m_Buffer; size_t m_BufferLen; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 687ec0b0..5e7099eb 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -829,12 +829,18 @@ namespace transport } return i2p::data::netdb.FindRouter (ident); } - void Transports::RestrictRoutesToFamilies(std::set families) + + void Transports::RestrictRoutesToFamilies(const std::set& families) { std::lock_guard lock(m_FamilyMutex); m_TrustedFamilies.clear(); - for ( const auto& fam : families ) - m_TrustedFamilies.push_back(fam); + for (auto fam : families) + { + boost::to_lower (fam); + auto id = i2p::data::netdb.GetFamilies ().GetFamilyID (fam); + if (id) + m_TrustedFamilies.push_back (id); + } } void Transports::RestrictRoutesToRouters(std::set routers) @@ -856,20 +862,19 @@ namespace transport { { std::lock_guard l(m_FamilyMutex); - std::string fam; + i2p::data::FamilyID fam = 0; auto sz = m_TrustedFamilies.size(); if(sz > 1) { auto it = m_TrustedFamilies.begin (); std::advance(it, rand() % sz); fam = *it; - boost::to_lower(fam); } else if (sz == 1) { fam = m_TrustedFamilies[0]; } - if (fam.size()) + if (fam) return i2p::data::netdb.GetRandomRouterInFamily(fam); } { diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index eb9c5cc9..988b323d 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -126,7 +126,7 @@ namespace transport /** do we want to use restricted routes? */ bool RoutesRestricted() const; /** restrict routes to use only these router families for first hops */ - void RestrictRoutesToFamilies(std::set families); + void RestrictRoutesToFamilies(const std::set& families); /** restrict routes to use only these routers for first hops */ void RestrictRoutesToRouters(std::set routers); @@ -173,7 +173,7 @@ namespace transport uint64_t m_LastBandwidthUpdateTime; /** which router families to trust for first hops */ - std::vector m_TrustedFamilies; + std::vector m_TrustedFamilies; mutable std::mutex m_FamilyMutex; /** which routers for first hop to trust */