diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index a460a435..700dd776 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2025, The PurpleI2P Project +* Copyright (c) 2013-2026, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -188,7 +188,7 @@ namespace util if (bandwidth.length () > 0) { const auto NumBandwithRegex = std::regex(R"(^\d+$)"); - const auto BandwithRegex = std::regex(R"((\d+)(b|kb|mb|gb))"); + const auto BandwithRegex = std::regex(R"((\d+)(b|kb|mb|gb))"); std::smatch bandWithMatch; if (bandwidth.length () == 1 && ((bandwidth[0] >= 'K' && bandwidth[0] <= 'P') || bandwidth[0] == 'X' )) @@ -204,7 +204,7 @@ namespace util if (unit == "b") { limit /= 1000; - } + } else if(unit == "mb") { limit *= 1000; @@ -216,7 +216,7 @@ namespace util if (limit < 0) { LogPrint(eLogInfo, "Daemon: Unexpected bandwidth ", bandwidth, ". Set to 'low'"); - i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2); + i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2); } else { i2p::context.SetBandwidth(limit); } @@ -234,7 +234,7 @@ namespace util LogPrint(eLogInfo, "Daemon: Unexpected bandwidth ", bandwidth, ". Set to 'low'"); i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2); } - } + } } else if (isFloodfill) { @@ -259,35 +259,26 @@ namespace util if (trust) { LogPrint(eLogInfo, "Daemon: Explicit trust enabled"); - std::string fam; i2p::config::GetOption("trust.family", fam); + std::string f; i2p::config::GetOption("trust.family", f); std::string_view fam(f); std::string routers; i2p::config::GetOption("trust.routers", routers); bool restricted = false; if (fam.length() > 0) { - std::set fams; + std::vector fams; size_t pos = 0, comma; do { comma = fam.find (',', pos); - fams.insert (fam.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos)); + fams.push_back (fam.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos)); pos = comma + 1; } while (comma != std::string::npos); i2p::transport::transports.RestrictRoutesToFamilies(fams); restricted = fams.size() > 0; } - if (routers.length() > 0) { - std::set idents; - size_t pos = 0, comma; - do - { - comma = routers.find (',', pos); - i2p::data::IdentHash ident; - ident.FromBase64 (routers.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos)); - idents.insert (ident); - pos = comma + 1; - } - while (comma != std::string::npos); + if (!routers.empty ()) + { + auto idents = i2p::data::ExtractIdentHashes (routers); LogPrint(eLogInfo, "Daemon: Setting restricted routes to use ", idents.size(), " trusted routers"); i2p::transport::transports.RestrictRoutesToRouters(idents); restricted = idents.size() > 0; @@ -526,9 +517,9 @@ namespace util s << "Uptime: "; ShowUptime(s, i2p::context.GetUptime ()); auto gracefulTimeLeft = Daemon.GetGracefulShutdownInterval (); if (gracefulTimeLeft > 0) - { + { s << "Graceful shutdown, time left: "; ShowUptime(s, gracefulTimeLeft); - } + } else s << "\n"; s << "Inbound: " << i2p::transport::transports.GetInBandwidth() / 1024 << " KiB/s; "; diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 37ad3dd1..0287ae6b 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -62,19 +62,8 @@ namespace client } auto explicitPeersStr = (*params)[I2CP_PARAM_EXPLICIT_PEERS]; if (!explicitPeersStr.empty ()) - { - explicitPeers = std::make_shared >(); - std::string str (explicitPeersStr); - std::stringstream ss(str); - std::string b64; - while (std::getline (ss, b64, ',')) - { - i2p::data::IdentHash ident; - ident.FromBase64 (b64); - explicitPeers->push_back (ident); - LogPrint (eLogInfo, "Destination: Added to explicit peers list: ", b64); - } - } + explicitPeers = std::make_shared > (i2p::data::ExtractIdentHashes (explicitPeersStr)); + m_Nickname = (*params)[I2CP_PARAM_INBOUND_NICKNAME]; if (m_Nickname.empty ()) // try outbound m_Nickname = (*params)[I2CP_PARAM_OUTBOUND_NICKNAME]; diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 240862ae..3bf47416 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2025, The PurpleI2P Project +* Copyright (c) 2013-2026, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -17,6 +17,25 @@ namespace i2p { namespace data { + std::vector ExtractIdentHashes (std::string_view hashes) + { + std::vector idents; + if (!hashes.empty ()) + { + size_t pos = 0, comma; + do + { + comma = hashes.find (',', pos); + i2p::data::IdentHash ident; + if (ident.FromBase64 (hashes.substr (pos, comma != std::string_view::npos ? comma - pos : std::string_view::npos))) + idents.push_back (ident); + pos = comma + 1; + } + while (comma != std::string_view::npos); + } + return idents; + } + Identity& Identity::operator=(const Keys& keys) { // copy public and signing keys together @@ -129,8 +148,8 @@ namespace data memcpy (excessBuf, signingKey + 384, excessLen); cryptoType = 0xFF; // crypto key is not used break; - } -#endif + } +#endif default: LogPrint (eLogError, "Identity: Signing key type ", (int)type, " is not supported"); } @@ -212,25 +231,25 @@ namespace data m_ExtendedLen = other.m_ExtendedLen; if (m_ExtendedLen > 0) { - if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) + if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) { - if (oldLen > MAX_EXTENDED_BUFFER_SIZE) + if (oldLen > MAX_EXTENDED_BUFFER_SIZE) { if (m_ExtendedLen > oldLen) - { + { delete[] m_ExtendedBufferPtr; m_ExtendedBufferPtr = new uint8_t[m_ExtendedLen]; - } + } } else m_ExtendedBufferPtr = new uint8_t[m_ExtendedLen]; - memcpy (m_ExtendedBufferPtr, other.m_ExtendedBufferPtr, m_ExtendedLen); - } + memcpy (m_ExtendedBufferPtr, other.m_ExtendedBufferPtr, m_ExtendedLen); + } else { if (oldLen > MAX_EXTENDED_BUFFER_SIZE) delete[] m_ExtendedBufferPtr; memcpy (m_ExtendedBuffer, other.m_ExtendedBuffer, m_ExtendedLen); - } + } } m_Verifier = nullptr; CreateVerifier (); @@ -267,19 +286,19 @@ namespace data { if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) { - if (oldLen > MAX_EXTENDED_BUFFER_SIZE) + if (oldLen > MAX_EXTENDED_BUFFER_SIZE) { if (m_ExtendedLen > oldLen) - { + { delete[] m_ExtendedBufferPtr; m_ExtendedBufferPtr = new uint8_t[m_ExtendedLen]; - } + } } else m_ExtendedBufferPtr = new uint8_t[m_ExtendedLen]; memcpy (m_ExtendedBufferPtr, buf + DEFAULT_IDENTITY_SIZE, m_ExtendedLen); - } - else + } + else memcpy (m_ExtendedBuffer, buf + DEFAULT_IDENTITY_SIZE, m_ExtendedLen); } else @@ -305,12 +324,12 @@ namespace data if (fullLen > len) return 0; // buffer is too small and may overflow somewhere else memcpy (buf, &m_StandardIdentity, DEFAULT_IDENTITY_SIZE); if (m_ExtendedLen > 0) - { + { if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) memcpy (buf + DEFAULT_IDENTITY_SIZE, m_ExtendedBufferPtr, m_ExtendedLen); - else + else memcpy (buf + DEFAULT_IDENTITY_SIZE, m_ExtendedBuffer, m_ExtendedLen); - } + } return fullLen; } @@ -406,7 +425,7 @@ namespace data #if OPENSSL_PQ case SIGNING_KEY_TYPE_MLDSA44: return new i2p::crypto::MLDSA44Verifier (); -#endif +#endif case SIGNING_KEY_TYPE_RSA_SHA256_2048: case SIGNING_KEY_TYPE_RSA_SHA384_3072: case SIGNING_KEY_TYPE_RSA_SHA512_4096: @@ -438,8 +457,8 @@ namespace data memcpy (signingKey + 384, m_ExtendedBufferPtr + 4, excessLen); // right after signing and crypto key types verifier->SetPublicKey (signingKey); delete[] signingKey; - } -#endif + } +#endif else { // for P521 @@ -465,7 +484,7 @@ namespace data case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: case CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: case CRYPTO_KEY_TYPE_ECIES_MLKEM768_X25519_AEAD: - case CRYPTO_KEY_TYPE_ECIES_MLKEM1024_X25519_AEAD: + case CRYPTO_KEY_TYPE_ECIES_MLKEM1024_X25519_AEAD: return std::make_shared(key); break; case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: @@ -489,8 +508,8 @@ namespace data size_t l = DEFAULT_IDENTITY_SIZE + bufbe16toh (buf + DEFAULT_IDENTITY_SIZE - 2); if (l > len) return 0; return l; - } - + } + PrivateKeys& PrivateKeys::operator=(const Keys& keys) { m_Public = std::make_shared(Identity (keys)); @@ -558,7 +577,7 @@ namespace data { LogPrint (eLogError, "Identity: Offline signature expired"); return 0; - } + } SigningKeyType keyType = bufbe16toh (buf + ret); ret += 2; // key type std::unique_ptr transientVerifier (IdentityEx::CreateVerifier (keyType)); if (!transientVerifier) return 0; @@ -695,8 +714,8 @@ namespace data #if OPENSSL_PQ case SIGNING_KEY_TYPE_MLDSA44: return new i2p::crypto::MLDSA44Signer (priv); - break; -#endif + break; +#endif default: LogPrint (eLogError, "Identity: Signing key type ", (int)keyType, " is not supported"); } @@ -738,7 +757,7 @@ namespace data case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: case CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: case CRYPTO_KEY_TYPE_ECIES_MLKEM768_X25519_AEAD: - case CRYPTO_KEY_TYPE_ECIES_MLKEM1024_X25519_AEAD: + case CRYPTO_KEY_TYPE_ECIES_MLKEM1024_X25519_AEAD: return std::make_shared(key); break; case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: @@ -757,7 +776,7 @@ namespace data PrivateKeys keys; // signature std::unique_ptr verifier (IdentityEx::CreateVerifier (type)); - std::vector signingPublicKey(verifier->GetPublicKeyLen ()); + std::vector signingPublicKey(verifier->GetPublicKeyLen ()); keys.m_SigningPrivateKey.resize (verifier->GetPrivateKeyLen ()); GenerateSigningKeyPair (type, keys.m_SigningPrivateKey.data (), signingPublicKey.data ()); // encryption @@ -806,11 +825,11 @@ namespace data case SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519: i2p::crypto::CreateRedDSA25519RandomKeys (priv, pub); break; -#if OPENSSL_PQ +#if OPENSSL_PQ case SIGNING_KEY_TYPE_MLDSA44: i2p::crypto::CreateMLDSA44RandomKeys (priv, pub); - break; -#endif + break; +#endif default: LogPrint (eLogWarning, "Identity: Signing key type ", (int)type, " is not supported. Create DSA-SHA1"); i2p::crypto::CreateDSARandomKeys (priv, pub); // DSA-SHA1 @@ -830,7 +849,7 @@ namespace data case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: case CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD: case CRYPTO_KEY_TYPE_ECIES_MLKEM768_X25519_AEAD: - case CRYPTO_KEY_TYPE_ECIES_MLKEM1024_X25519_AEAD: + case CRYPTO_KEY_TYPE_ECIES_MLKEM1024_X25519_AEAD: i2p::crypto::CreateECIESX25519AEADRatchetRandomKeys (priv, pub); break; default: @@ -876,7 +895,7 @@ namespace data memcpy (buf, (const uint8_t *)ident, 32); if (nextDay) i2p::util::GetNextDayDate ((char *)(buf + 32)); - else + else i2p::util::GetCurrentDate ((char *)(buf + 32)); IdentHash key; SHA256(buf, 40, key); diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index c95ce000..4564b633 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2025, The PurpleI2P Project +* Copyright (c) 2013-2026, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -24,7 +24,7 @@ namespace crypto { class CryptoKeyEncryptor; class CryptoKeyDecryptor; -} +} namespace data { typedef Tag<32> IdentHash; @@ -33,6 +33,8 @@ namespace data return ident.ToBase64 ().substr (0, 4); } + std::vector ExtractIdentHashes (std::string_view hashes); + struct Keys { uint8_t privateKey[256]; @@ -73,7 +75,7 @@ namespace data const uint16_t CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD = 5; const uint16_t CRYPTO_KEY_TYPE_ECIES_MLKEM768_X25519_AEAD = 6; const uint16_t CRYPTO_KEY_TYPE_ECIES_MLKEM1024_X25519_AEAD = 7; - + const uint16_t SIGNING_KEY_TYPE_DSA_SHA1 = 0; const uint16_t SIGNING_KEY_TYPE_ECDSA_SHA256_P256 = 1; const uint16_t SIGNING_KEY_TYPE_ECDSA_SHA384_P384 = 2; @@ -87,7 +89,7 @@ namespace data const uint16_t SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512 = 10; // approved by FSB const uint16_t SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519 = 11; // for LeaseSet2 only const uint16_t SIGNING_KEY_TYPE_MLDSA44 = 12; - + typedef uint16_t SigningKeyType; typedef uint16_t CryptoKeyType; @@ -135,7 +137,7 @@ namespace data private: void CreateVerifier (); - + private: Identity m_StandardIdentity; @@ -143,10 +145,10 @@ namespace data std::unique_ptr m_Verifier; size_t m_ExtendedLen; union - { - uint8_t m_ExtendedBuffer[MAX_EXTENDED_BUFFER_SIZE]; + { + uint8_t m_ExtendedBuffer[MAX_EXTENDED_BUFFER_SIZE]; uint8_t * m_ExtendedBufferPtr; - }; + }; }; size_t GetIdentityBufferLen (const uint8_t * buf, size_t len); // return actual identity length in buffer diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index e1f7caee..ebe715ac 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -1183,20 +1183,20 @@ namespace transport }); } - void Transports::RestrictRoutesToFamilies(const std::set& families) + void Transports::RestrictRoutesToFamilies(const std::vector& families) { std::lock_guard lock(m_FamilyMutex); m_TrustedFamilies.clear(); - for (auto fam : families) + for (auto f: families) { - boost::to_lower (fam); + std::string fam(f); boost::to_lower (fam); auto id = i2p::data::netdb.GetFamilies ().GetFamilyID (fam); if (id) m_TrustedFamilies.push_back (id); } } - void Transports::RestrictRoutesToRouters(const std::set& routers) + void Transports::RestrictRoutesToRouters(const std::vector& routers) { std::lock_guard lock(m_TrustedRoutersMutex); m_TrustedRouters.clear(); diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 04b916b2..bd002c78 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2025, The PurpleI2P Project +* Copyright (c) 2013-2026, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -83,11 +83,11 @@ namespace transport Peer (std::shared_ptr r, uint64_t ts): numAttempts (0), router (r), creationTime (ts), nextRouterInfoUpdateTime (ts + PEER_ROUTER_INFO_UPDATE_INTERVAL), - lastSelectionTime (0), isHighBandwidth (false), isEligible (false) + lastSelectionTime (0), isHighBandwidth (false), isEligible (false) { UpdateParams (router); } - + void Done () { for (auto& it: sessions) @@ -115,7 +115,7 @@ namespace transport const int MAX_NUM_DELAYED_MESSAGES = 150; const int CHECK_PROFILE_NUM_DELAYED_MESSAGES = 15; // check profile after const int NUM_X25519_PRE_GENERATED_KEYS = 25; // pre-generated x25519 keys pairs - + const int TRAFFIC_SAMPLE_COUNT = 301; // seconds struct TrafficSample @@ -142,9 +142,9 @@ namespace transport bool IsOnline() const { return m_IsOnline; }; void SetOnline (bool online); - + int GetLocalDelay () const; // in millseconds - + auto& GetService () { return *m_Service; }; std::shared_ptr GetNextX25519KeysPair (); void ReuseX25519KeysPair (std::shared_ptr pair); @@ -177,9 +177,9 @@ 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(const std::set& families); + void RestrictRoutesToFamilies(const std::vector& families); /** restrict routes to use only these routers for first hops */ - void RestrictRoutesToRouters(const std::set& routers); + void RestrictRoutesToRouters(const std::vector& routers); bool IsTrustedRouter (const i2p::data::IdentHash& ih) const; bool IsRestrictedPeer(const i2p::data::IdentHash& ih) const;