mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2026-10-23 10:42:35 +00:00
Identity/IdentMetrics split
This commit is contained in:
1 parent
e9f7477fcf
commit
d6273b277d
7 files changed
+158
-112
No files matched your search
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2026, The PurpleI2P Project
|
||||
*
|
||||
* This file is part of Purple i2pd project and licensed under BSD3
|
||||
*
|
||||
* See full license text in LICENSE file at top of project tree
|
||||
*/
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "Siphash.h"
|
||||
#include "util.h"
|
||||
#include "Timestamp.h"
|
||||
#include "IdentMetrics.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace data
|
||||
{
|
||||
IdentHash CreateRoutingKey (const IdentHash& ident, bool nextDay)
|
||||
{
|
||||
uint8_t buf[41]; // ident + yyyymmdd
|
||||
memcpy (buf, (const uint8_t *)ident, 32);
|
||||
if (nextDay)
|
||||
i2p::util::GetNextDayDate ((char *)(buf + 32));
|
||||
else
|
||||
i2p::util::GetCurrentDate ((char *)(buf + 32));
|
||||
IdentHash key;
|
||||
SHA256(buf, 40, key);
|
||||
return key;
|
||||
}
|
||||
|
||||
XORMetric operator^(const IdentHash& key1, const IdentHash& key2)
|
||||
{
|
||||
XORMetric m;
|
||||
|
||||
const uint64_t * hash1 = key1.GetLL (), * hash2 = key2.GetLL ();
|
||||
m.metric_ll[0] = hash1[0] ^ hash2[0];
|
||||
m.metric_ll[1] = hash1[1] ^ hash2[1];
|
||||
m.metric_ll[2] = hash1[2] ^ hash2[2];
|
||||
m.metric_ll[3] = hash1[3] ^ hash2[3];
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
PeerOrdering::PeerOrdering ()
|
||||
{
|
||||
RAND_bytes (m_PeerOrderingKey, 16);
|
||||
}
|
||||
|
||||
int PeerOrdering::CalculatePeerOrderingGroup (const IdentHash& routerIdent)
|
||||
{
|
||||
uint8_t hash[16];
|
||||
#if OPENSSL_SIPHASH
|
||||
EVP_PKEY * sipKey = EVP_PKEY_new_raw_private_key (EVP_PKEY_SIPHASH, nullptr, m_PeerOrderingKey, 16);
|
||||
EVP_MD_CTX * ctx = EVP_MD_CTX_create ();
|
||||
EVP_DigestSignInit (ctx, nullptr, nullptr, nullptr, sipKey);
|
||||
size_t l = 16;
|
||||
EVP_DigestSign (ctx, hash, &l, routerIdent, 32);
|
||||
EVP_MD_CTX_destroy (ctx);
|
||||
EVP_PKEY_free (sipKey);
|
||||
#else
|
||||
i2p::crypto::Siphash<16> (hash, routerIdent, 32, m_PeerOrderingKey);
|
||||
#endif
|
||||
return hash[0] & 0x03;
|
||||
}
|
||||
|
||||
int PeerOrdering::GetPeerOrderingGroup (const IdentHash& routerIdent)
|
||||
{
|
||||
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
||||
auto it = m_OrderingGroups.find (routerIdent);
|
||||
if (it != m_OrderingGroups.end ())
|
||||
{
|
||||
it->second.second = ts;
|
||||
return it->second.first;
|
||||
}
|
||||
int group = CalculatePeerOrderingGroup (routerIdent);
|
||||
m_OrderingGroups.emplace (routerIdent, std::pair{group, ts});
|
||||
return group;
|
||||
}
|
||||
|
||||
void PeerOrdering::CleanUp (uint64_t ts)
|
||||
{
|
||||
for (auto it = m_OrderingGroups.begin (); it != m_OrderingGroups.end ();)
|
||||
{
|
||||
if (ts > it->second.second + PEER_ORDERING_INACTIVITY_TIMEOUT)
|
||||
it = m_OrderingGroups.erase (it);
|
||||
else
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2026, The PurpleI2P Project
|
||||
*
|
||||
* This file is part of Purple i2pd project and licensed under BSD3
|
||||
*
|
||||
* See full license text in LICENSE file at top of project tree
|
||||
*/
|
||||
|
||||
#ifndef IDENT_METRICS_H__
|
||||
#define IDENT_METRICS_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <unordered_map>
|
||||
#include "Tag.h"
|
||||
#include "Identity.h"
|
||||
#include "Crypto.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace data
|
||||
{
|
||||
// kademlia
|
||||
struct XORMetric
|
||||
{
|
||||
union
|
||||
{
|
||||
uint8_t metric[32];
|
||||
uint64_t metric_ll[4];
|
||||
};
|
||||
|
||||
void SetMin () { memset (metric, 0, 32); };
|
||||
void SetMax () { memset (metric, 0xFF, 32); };
|
||||
bool operator< (const XORMetric& other) const { return memcmp (metric, other.metric, 32) < 0; };
|
||||
};
|
||||
|
||||
IdentHash CreateRoutingKey (const IdentHash& ident, bool nextDay = false);
|
||||
XORMetric operator^(const IdentHash& key1, const IdentHash& key2);
|
||||
|
||||
// peer ordering
|
||||
constexpr uint64_t PEER_ORDERING_INACTIVITY_TIMEOUT = 400; // in seconds
|
||||
class PeerOrdering
|
||||
{
|
||||
public:
|
||||
|
||||
PeerOrdering ();
|
||||
int GetPeerOrderingGroup (const IdentHash& routerIdent);
|
||||
void CleanUp (uint64_t ts);
|
||||
|
||||
private:
|
||||
|
||||
int CalculatePeerOrderingGroup (const IdentHash& routerIdent);
|
||||
|
||||
private:
|
||||
|
||||
Tag<16> m_PeerOrderingKey;
|
||||
std::unordered_map<IdentHash, std::pair<int, uint64_t> > m_OrderingGroups; // router ident hash -> (group, last request time)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
#include "Crypto.h"
|
||||
#include "Siphash.h"
|
||||
#include "I2PEndian.h"
|
||||
#include "Log.h"
|
||||
#include "Timestamp.h"
|
||||
@@ -864,78 +863,5 @@ namespace data
|
||||
i2p::crypto::CreateDSARandomKeys (keys.signingPrivateKey, keys.signingKey);
|
||||
return keys;
|
||||
}
|
||||
|
||||
IdentHash CreateRoutingKey (const IdentHash& ident, bool nextDay)
|
||||
{
|
||||
uint8_t buf[41]; // ident + yyyymmdd
|
||||
memcpy (buf, (const uint8_t *)ident, 32);
|
||||
if (nextDay)
|
||||
i2p::util::GetNextDayDate ((char *)(buf + 32));
|
||||
else
|
||||
i2p::util::GetCurrentDate ((char *)(buf + 32));
|
||||
IdentHash key;
|
||||
SHA256(buf, 40, key);
|
||||
return key;
|
||||
}
|
||||
|
||||
XORMetric operator^(const IdentHash& key1, const IdentHash& key2)
|
||||
{
|
||||
XORMetric m;
|
||||
|
||||
const uint64_t * hash1 = key1.GetLL (), * hash2 = key2.GetLL ();
|
||||
m.metric_ll[0] = hash1[0] ^ hash2[0];
|
||||
m.metric_ll[1] = hash1[1] ^ hash2[1];
|
||||
m.metric_ll[2] = hash1[2] ^ hash2[2];
|
||||
m.metric_ll[3] = hash1[3] ^ hash2[3];
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
PeerOrdering::PeerOrdering ()
|
||||
{
|
||||
RAND_bytes (m_PeerOrderingKey, 16);
|
||||
}
|
||||
|
||||
int PeerOrdering::CalculatePeerOrderingGroup (const IdentHash& routerIdent)
|
||||
{
|
||||
uint8_t hash[16];
|
||||
#if OPENSSL_SIPHASH
|
||||
EVP_PKEY * sipKey = EVP_PKEY_new_raw_private_key (EVP_PKEY_SIPHASH, nullptr, m_PeerOrderingKey, 16);
|
||||
EVP_MD_CTX * ctx = EVP_MD_CTX_create ();
|
||||
EVP_DigestSignInit (ctx, nullptr, nullptr, nullptr, sipKey);
|
||||
size_t l = 16;
|
||||
EVP_DigestSign (ctx, hash, &l, routerIdent, 32);
|
||||
EVP_MD_CTX_destroy (ctx);
|
||||
EVP_PKEY_free (sipKey);
|
||||
#else
|
||||
i2p::crypto::Siphash<16> (hash, routerIdent, 32, m_PeerOrderingKey);
|
||||
#endif
|
||||
return hash[0] & 0x03;
|
||||
}
|
||||
|
||||
int PeerOrdering::GetPeerOrderingGroup (const IdentHash& routerIdent)
|
||||
{
|
||||
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
||||
auto it = m_OrderingGroups.find (routerIdent);
|
||||
if (it != m_OrderingGroups.end ())
|
||||
{
|
||||
it->second.second = ts;
|
||||
return it->second.first;
|
||||
}
|
||||
int group = CalculatePeerOrderingGroup (routerIdent);
|
||||
m_OrderingGroups.emplace (routerIdent, std::pair{group, ts});
|
||||
return group;
|
||||
}
|
||||
|
||||
void PeerOrdering::CleanUp (uint64_t ts)
|
||||
{
|
||||
for (auto it = m_OrderingGroups.begin (); it != m_OrderingGroups.end ();)
|
||||
{
|
||||
if (ts > it->second.second + PEER_ORDERING_INACTIVITY_TIMEOUT)
|
||||
it = m_OrderingGroups.erase (it);
|
||||
else
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <string_view>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include "Base.h"
|
||||
#include "Signature.h"
|
||||
#include "Tag.h"
|
||||
@@ -210,43 +209,6 @@ namespace data
|
||||
size_t m_TransientSigningPrivateKeyLen = 0;
|
||||
};
|
||||
|
||||
// kademlia
|
||||
struct XORMetric
|
||||
{
|
||||
union
|
||||
{
|
||||
uint8_t metric[32];
|
||||
uint64_t metric_ll[4];
|
||||
};
|
||||
|
||||
void SetMin () { memset (metric, 0, 32); };
|
||||
void SetMax () { memset (metric, 0xFF, 32); };
|
||||
bool operator< (const XORMetric& other) const { return memcmp (metric, other.metric, 32) < 0; };
|
||||
};
|
||||
|
||||
IdentHash CreateRoutingKey (const IdentHash& ident, bool nextDay = false);
|
||||
XORMetric operator^(const IdentHash& key1, const IdentHash& key2);
|
||||
|
||||
// peer ordering
|
||||
constexpr uint64_t PEER_ORDERING_INACTIVITY_TIMEOUT = 400; // in seconds
|
||||
class PeerOrdering
|
||||
{
|
||||
public:
|
||||
|
||||
PeerOrdering ();
|
||||
int GetPeerOrderingGroup (const IdentHash& routerIdent);
|
||||
void CleanUp (uint64_t ts);
|
||||
|
||||
private:
|
||||
|
||||
int CalculatePeerOrderingGroup (const IdentHash& routerIdent);
|
||||
|
||||
private:
|
||||
|
||||
Tag<16> m_PeerOrderingKey;
|
||||
std::unordered_map<IdentHash, std::pair<int, uint64_t> > m_OrderingGroups; // router ident hash -> (group, last request time)
|
||||
};
|
||||
|
||||
// destination for delivery instructions
|
||||
class RoutingDestination
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "ECIESX25519AEADRatchetSession.h"
|
||||
#include "Config.h"
|
||||
#include "util.h"
|
||||
#include "IdentMetrics.h"
|
||||
#include "NetDb.hpp"
|
||||
|
||||
using namespace i2p::transport;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "RouterInfo.h"
|
||||
#include "I2NPProtocol.h"
|
||||
#include "Identity.h"
|
||||
#include "IdentMetrics.h"
|
||||
#include "util.h"
|
||||
|
||||
namespace i2p
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <memory>
|
||||
#include <random>
|
||||
#include "Identity.h"
|
||||
#include "IdentMetrics.h"
|
||||
#include "LeaseSet.h"
|
||||
#include "RouterInfo.h"
|
||||
#include "I2NPProtocol.h"
|
||||
|
||||
Reference in new issue
Block a user