common code to extract routers hashes from param

This commit is contained in:
orignal
2026-01-15 19:51:51 -05:00
parent 68c6852029
commit 60cc526dda
6 changed files with 90 additions and 89 deletions
+13 -22
View File
@@ -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<std::string> fams;
std::vector<std::string_view> 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<i2p::data::IdentHash> 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; ";
+2 -13
View File
@@ -62,19 +62,8 @@ namespace client
}
auto explicitPeersStr = (*params)[I2CP_PARAM_EXPLICIT_PEERS];
if (!explicitPeersStr.empty ())
{
explicitPeers = std::make_shared<std::vector<i2p::data::IdentHash> >();
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<std::vector<i2p::data::IdentHash> > (i2p::data::ExtractIdentHashes (explicitPeersStr));
m_Nickname = (*params)[I2CP_PARAM_INBOUND_NICKNAME];
if (m_Nickname.empty ()) // try outbound
m_Nickname = (*params)[I2CP_PARAM_OUTBOUND_NICKNAME];
+53 -34
View File
@@ -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<IdentHash> ExtractIdentHashes (std::string_view hashes)
{
std::vector<IdentHash> 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<i2p::crypto::ECIESX25519AEADRatchetEncryptor>(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<IdentityEx>(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<i2p::crypto::Verifier> 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<i2p::crypto::ECIESX25519AEADRatchetDecryptor>(key);
break;
case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC:
@@ -757,7 +776,7 @@ namespace data
PrivateKeys keys;
// signature
std::unique_ptr<i2p::crypto::Verifier> verifier (IdentityEx::CreateVerifier (type));
std::vector<uint8_t> signingPublicKey(verifier->GetPublicKeyLen ());
std::vector<uint8_t> 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);
+10 -8
View File
@@ -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<IdentHash> 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<i2p::crypto::Verifier> 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
+4 -4
View File
@@ -1183,20 +1183,20 @@ namespace transport
});
}
void Transports::RestrictRoutesToFamilies(const std::set<std::string>& families)
void Transports::RestrictRoutesToFamilies(const std::vector<std::string_view>& families)
{
std::lock_guard<std::mutex> 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<i2p::data::IdentHash>& routers)
void Transports::RestrictRoutesToRouters(const std::vector<i2p::data::IdentHash>& routers)
{
std::lock_guard<std::mutex> lock(m_TrustedRoutersMutex);
m_TrustedRouters.clear();
+8 -8
View File
@@ -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<const i2p::data::RouterInfo> 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<i2p::crypto::X25519Keys> GetNextX25519KeysPair ();
void ReuseX25519KeysPair (std::shared_ptr<i2p::crypto::X25519Keys> 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<std::string>& families);
void RestrictRoutesToFamilies(const std::vector<std::string_view>& families);
/** restrict routes to use only these routers for first hops */
void RestrictRoutesToRouters(const std::set<i2p::data::IdentHash>& routers);
void RestrictRoutesToRouters(const std::vector<i2p::data::IdentHash>& routers);
bool IsTrustedRouter (const i2p::data::IdentHash& ih) const;
bool IsRestrictedPeer(const i2p::data::IdentHash& ih) const;