diff --git a/Identity.cpp b/Identity.cpp index b80d1cbf..f57ab97b 100644 --- a/Identity.cpp +++ b/Identity.cpp @@ -1,3 +1,5 @@ +#include +#include #include #include #include @@ -43,5 +45,30 @@ namespace data return keys; } + + RoutingKey CreateRoutingKey (const IdentHash& ident) + { + uint8_t buf[41]; // ident + yyyymmdd + memcpy (buf, (const uint8_t *)ident, 32); + time_t t = time (nullptr); + struct tm tm; + gmtime_r (&t, &tm); + sprintf ((char *)(buf + 32),"%4i%2i%2i", tm.tm_year, tm.tm_mon, tm.tm_mday); + + RoutingKey key; + CryptoPP::SHA256().CalculateDigest(key.hash, buf, 40); + return key; + } + + XORMetric operator^(const RoutingKey& key1, const RoutingKey& key2) + { + // TODO: implementation depends on CPU + XORMetric m; + ((uint64_t *)m.metric)[0] = ((uint64_t *)key1.hash)[0] ^ ((uint64_t *)key2.hash)[0]; + ((uint64_t *)m.metric)[1] = ((uint64_t *)key1.hash)[1] ^ ((uint64_t *)key2.hash)[1]; + ((uint64_t *)m.metric)[2] = ((uint64_t *)key1.hash)[2] ^ ((uint64_t *)key2.hash)[2]; + ((uint64_t *)m.metric)[3] = ((uint64_t *)key1.hash)[3] ^ ((uint64_t *)key2.hash)[3]; + return m; + } } } diff --git a/Identity.h b/Identity.h index 549e9cea..9e8b62ac 100644 --- a/Identity.h +++ b/Identity.h @@ -57,7 +57,26 @@ namespace data IdentHash CalculateIdentHash (const Identity& identity); Keys CreateRandomKeys (); + + // kademlia + struct RoutingKey + { + uint8_t hash[32]; + }; + + struct XORMetric + { + uint8_t metric[32]; + + 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; }; + }; + + RoutingKey CreateRoutingKey (const IdentHash& ident); + XORMetric operator^(const RoutingKey& key1, const RoutingKey& key2); + // destination for delivery instuctions class RoutingDestination { public: diff --git a/NetDb.cpp b/NetDb.cpp index 77e2ce72..89364c1b 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -388,5 +388,26 @@ namespace data { if (msg) m_Queue.Put (msg); } + + const RouterInfo * NetDb::GetClosestFloodfill (const IdentHash& destination) const + { + RouterInfo * r = nullptr; + XORMetric minMetric; + RoutingKey destKey = CreateRoutingKey (destination); + minMetric.SetMax (); + for (auto it: m_RouterInfos) + { + if (it.second->IsFloodfill () &&! it.second->IsUnreachable ()) + { + XORMetric m = destKey ^ it.second->GetRoutingKey (); + if (m < minMetric) + { + minMetric = m; + r = it.second; + } + } + } + return r; + } } } diff --git a/NetDb.h b/NetDb.h index ca63a239..761d3a09 100644 --- a/NetDb.h +++ b/NetDb.h @@ -48,6 +48,7 @@ namespace data void SaveUpdated (const char * directory); void Run (); // exploratory thread void Explore (); + const RouterInfo * GetClosestFloodfill (const IdentHash& destination) const; private: diff --git a/RouterInfo.cpp b/RouterInfo.cpp index 417466c6..45ab4c20 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -35,6 +35,7 @@ namespace data m_RouterIdentity = identity; m_IdentHash = CalculateIdentHash (m_RouterIdentity); UpdateIdentHashBase64 (); + UpdateRoutingKey (); m_Timestamp = i2p::util::GetMillisecondsSinceEpoch (); } @@ -126,6 +127,7 @@ namespace data CryptoPP::SHA256().CalculateDigest(m_IdentHash, (uint8_t *)&m_RouterIdentity, sizeof (m_RouterIdentity)); UpdateIdentHashBase64 (); + UpdateRoutingKey (); } void RouterInfo::UpdateIdentHashBase64 () @@ -135,6 +137,11 @@ namespace data memcpy (m_IdentHashAbbreviation, m_IdentHashBase64, 4); m_IdentHashAbbreviation[4] = 0; } + + void RouterInfo::UpdateRoutingKey () + { + m_RoutingKey = CreateRoutingKey (m_IdentHash); + } void RouterInfo::WriteToStream (std::ostream& s) { diff --git a/RouterInfo.h b/RouterInfo.h index 3111fbf3..ceda10cb 100644 --- a/RouterInfo.h +++ b/RouterInfo.h @@ -46,6 +46,7 @@ namespace data uint64_t GetTimestamp () const { return m_Timestamp; }; const std::vector
& GetAddresses () const { return m_Addresses; }; Address * GetNTCPAddress (); + const RoutingKey& GetRoutingKey () const { return m_RoutingKey; }; void AddNTCPAddress (const char * host, int port); void SetProperty (const char * key, const char * value); @@ -56,6 +57,7 @@ namespace data bool IsUnreachable () const { return m_IsUnreachable; }; void CreateBuffer (); + void UpdateRoutingKey (); const char * GetBuffer () const { return m_Buffer; }; int GetBufferLen () const { return m_BufferLen; }; @@ -81,6 +83,7 @@ namespace data Identity m_RouterIdentity; IdentHash m_IdentHash; + RoutingKey m_RoutingKey; char m_IdentHashBase64[48], m_IdentHashAbbreviation[5]; char m_Buffer[2048]; int m_BufferLen;