From b2fb466cde74c332b2d8ab140b89f6ffbc39faef Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Mar 2014 12:02:51 -0400 Subject: [PATCH 01/11] extract caps --- RouterInfo.cpp | 40 +++++++++++++++++++++++++++++++--------- RouterInfo.h | 16 ++++++++++++---- SSU.cpp | 21 +++++++++++++-------- 3 files changed, 56 insertions(+), 21 deletions(-) diff --git a/RouterInfo.cpp b/RouterInfo.cpp index adae686c..56c05591 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -18,13 +18,13 @@ namespace i2p namespace data { RouterInfo::RouterInfo (const char * filename): - m_IsUpdated (false), m_IsUnreachable (false), m_SupportedTransports (0) + m_IsUpdated (false), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0) { ReadFromFile (filename); } RouterInfo::RouterInfo (const uint8_t * buf, int len): - m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0) + m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0) { memcpy (m_Buffer, buf, len); m_BufferLen = len; @@ -175,6 +175,10 @@ namespace data r += ReadString (value, s); s.seekg (1, std::ios_base::cur); r++; // ; m_Properties[key] = value; + + // extract caps + if (strcmp (key, "caps")) + ExtractCaps (value); } CryptoPP::SHA256().CalculateDigest(m_IdentHash, (uint8_t *)&m_RouterIdentity, sizeof (m_RouterIdentity)); @@ -185,6 +189,29 @@ namespace data SetUnreachable (true); } + void RouterInfo::ExtractCaps (const char * value) + { + m_Caps = 0; + const char * cap = value; + while (*cap) + { + switch (*cap) + { + case 'f': + m_Caps |= Caps::eFloodfill; + break; + case 'O': + m_Caps |= Caps::eHighBanwidth; + break; + case 'R': + m_Caps |= Caps::eReachable; + break; + default: ; + } + cap++; + } + } + void RouterInfo::UpdateIdentHashBase64 () { size_t l = i2p::data::ByteStreamToBase64 (m_IdentHash, 32, m_IdentHashBase64, 48); @@ -337,10 +364,7 @@ namespace data bool RouterInfo::IsFloodfill () const { - const char * caps = GetProperty ("caps"); - if (caps) - return strchr (caps, 'f'); - return false; + return m_Caps & Caps::eFloodfill; } bool RouterInfo::IsNTCP (bool v4only) const @@ -361,9 +385,7 @@ namespace data bool RouterInfo::UsesIntroducer () const { - if (!IsSSU ()) return false; - auto address = GetSSUAddress (true); // no introducers for v6 - return address && !address->introducers.empty (); + return !(m_Caps & Caps::eReachable); // non-reachable } const RouterInfo::Address * RouterInfo::GetNTCPAddress (bool v4only) const diff --git a/RouterInfo.h b/RouterInfo.h index 52a8d9e9..afde30bc 100644 --- a/RouterInfo.h +++ b/RouterInfo.h @@ -20,11 +20,18 @@ namespace data enum SupportedTranports { eNTCPV4 = 0x01, - eNTCPV6 = 0x20, - eSSUV4 = 0x40, - eSSUV6 = 0x80 + eNTCPV6 = 0x02, + eSSUV4 = 0x04, + eSSUV6 = 0x08 }; + enum Caps + { + eFloodfill = 0x01, + eHighBanwidth = 0x02, + eReachable = 0x04 + }; + enum TransportStyle { eTransportUnknown = 0, @@ -102,6 +109,7 @@ namespace data void WriteToStream (std::ostream& s); size_t ReadString (char * str, std::istream& s); void WriteString (const std::string& str, std::ostream& s); + void ExtractCaps (const char * value); void UpdateIdentHashBase64 (); const Address * GetAddress (TransportStyle s, bool v4only) const; @@ -117,7 +125,7 @@ namespace data std::vector
m_Addresses; std::map m_Properties; bool m_IsUpdated, m_IsUnreachable; - uint8_t m_SupportedTransports; + uint8_t m_SupportedTransports, m_Caps; }; } } diff --git a/SSU.cpp b/SSU.cpp index 64886e90..b118c70a 100644 --- a/SSU.cpp +++ b/SSU.cpp @@ -822,14 +822,19 @@ namespace ssu } else { - // connect to introducer - auto& introducer = address->introducers[0]; // TODO: - boost::asio::ip::udp::endpoint introducerEndpoint (introducer.iHost, introducer.iPort); - session = new SSUSession (this, introducerEndpoint, router); - m_Sessions[introducerEndpoint] = session; - LogPrint ("New SSU session to [", router->GetIdentHashAbbreviation (), - "] created through introducer ", introducerEndpoint.address ().to_string (), ":", introducerEndpoint.port ()); - session->ConnectThroughIntroducer (introducer); + // connect through introducer + if (address->introducers.size () > 0) + { + auto& introducer = address->introducers[0]; // TODO: + boost::asio::ip::udp::endpoint introducerEndpoint (introducer.iHost, introducer.iPort); + session = new SSUSession (this, introducerEndpoint, router); + m_Sessions[introducerEndpoint] = session; + LogPrint ("New SSU session to [", router->GetIdentHashAbbreviation (), + "] through introducer ", introducerEndpoint.address ().to_string (), ":", introducerEndpoint.port ()); + session->ConnectThroughIntroducer (introducer); + } + else + LogPrint ("Router is unreachable, but not introducers presentd. Ignored"); } } } From d32f345aeedc213813f615bef23549322c048469 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Mar 2014 12:16:05 -0400 Subject: [PATCH 02/11] don't copy temporary data structure --- TunnelGateway.cpp | 2 +- TunnelGateway.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/TunnelGateway.cpp b/TunnelGateway.cpp index cc1189e0..c85e92e6 100644 --- a/TunnelGateway.cpp +++ b/TunnelGateway.cpp @@ -107,7 +107,7 @@ namespace tunnel } } - std::vector TunnelGatewayBuffer::GetTunnelDataMsgs () + const std::vector TunnelGatewayBuffer::GetTunnelDataMsgs () { CompleteCurrentTunnelDataMessage (); std::vector ret = m_TunnelDataMsgs; // TODO: implement it better diff --git a/TunnelGateway.h b/TunnelGateway.h index 8c390eef..aec0ca03 100644 --- a/TunnelGateway.h +++ b/TunnelGateway.h @@ -16,7 +16,7 @@ namespace tunnel TunnelGatewayBuffer (uint32_t tunnelID): m_TunnelID (tunnelID), m_CurrentTunnelDataMsg (nullptr), m_RemainingSize (0) {}; void PutI2NPMsg (const TunnelMessageBlock& block); - std::vector GetTunnelDataMsgs (); + const std::vector GetTunnelDataMsgs (); private: From fb9d3516007ce710f73810301c33b40580de58c5 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Mar 2014 14:08:09 -0400 Subject: [PATCH 03/11] store floodfills separately --- NetDb.cpp | 34 ++++++++++++---------------------- NetDb.h | 3 ++- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/NetDb.cpp b/NetDb.cpp index 2b3598fc..8b706589 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -55,7 +55,7 @@ namespace data NetDb::~NetDb () { - Stop (); + Stop (); for (auto l:m_LeaseSets) delete l.second; for (auto r:m_RouterInfos) @@ -160,6 +160,8 @@ namespace data { LogPrint ("New RouterInfo added"); m_RouterInfos[r->GetIdentHash ()] = r; + if (r->IsFloodfill ()) + m_Floodfills.push_back (r); } } @@ -237,6 +239,7 @@ namespace data for (auto r: m_RouterInfos) delete r.second; m_RouterInfos.clear (); + m_Floodfills.clear (); // load routers now int numRouters = 0; @@ -253,11 +256,14 @@ namespace data RouterInfo * r = new RouterInfo(it1->path().c_str()); #endif m_RouterInfos[r->GetIdentHash ()] = r; + if (r->IsFloodfill ()) + m_Floodfills.push_back (r); numRouters++; } } } LogPrint (numRouters, " routers loaded"); + LogPrint (m_Floodfills.size (), " floodfills loaded"); } void NetDb::SaveUpdated (const char * directory) @@ -594,22 +600,6 @@ namespace data delete dest; } } - - const RouterInfo * NetDb::GetRandomNTCPRouter (bool floodfillOnly) const - { - CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator (); - uint32_t ind = rnd.GenerateWord32 (0, m_RouterInfos.size () - 1), i = 0; - RouterInfo * last = nullptr; - for (auto it: m_RouterInfos) - { - if (it.second->IsNTCP () && !it.second->IsUnreachable () && - (!floodfillOnly || it.second->IsFloodfill ())) - last = it.second; - if (i >= ind) break; - else i++; - } - return last; - } const RouterInfo * NetDb::GetRandomRouter (const RouterInfo * compatibleWith, bool floodfillOnly) const { @@ -633,7 +623,7 @@ namespace data // we couldn't find anything, try second pass ind = 0; } - return nullptr; // seem we have too few routers + return nullptr; // seems we have too few routers } void NetDb::PostI2NPMsg (I2NPMessage * msg) @@ -648,15 +638,15 @@ namespace data XORMetric minMetric; RoutingKey destKey = CreateRoutingKey (destination); minMetric.SetMax (); - for (auto it: m_RouterInfos) + for (auto it: m_Floodfills) { - if (it.second->IsFloodfill () &&! it.second->IsUnreachable () && !excluded.count (it.first)) + if (!it->IsUnreachable () && !excluded.count (it->GetIdentHash ())) { - XORMetric m = destKey ^ it.second->GetRoutingKey (); + XORMetric m = destKey ^ it->GetRoutingKey (); if (m < minMetric) { minMetric = m; - r = it.second; + r = it; } } } diff --git a/NetDb.h b/NetDb.h index f9cf3900..4e1e1038 100644 --- a/NetDb.h +++ b/NetDb.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -73,7 +74,6 @@ namespace data void HandleDatabaseStoreMsg (uint8_t * buf, size_t len); void HandleDatabaseSearchReplyMsg (I2NPMessage * msg); - const RouterInfo * GetRandomNTCPRouter (bool floodfillOnly = false) const; const RouterInfo * GetRandomRouter (const RouterInfo * compatibleWith = nullptr, bool floodfillOnly = false) const; void PostI2NPMsg (I2NPMessage * msg); @@ -98,6 +98,7 @@ namespace data std::map m_LeaseSets; std::map m_RouterInfos; + std::vector m_Floodfills; std::map m_RequestedDestinations; std::set m_Subscriptions; From 59d195c6da41f312e68b91d691b619f804c5a555 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Mar 2014 15:58:57 -0400 Subject: [PATCH 04/11] find router with specified caps --- NetDb.cpp | 4 ++-- NetDb.h | 2 +- RouterInfo.cpp | 4 +++- RouterInfo.h | 5 +++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/NetDb.cpp b/NetDb.cpp index 8b706589..3d8a4212 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -601,7 +601,7 @@ namespace data } } - const RouterInfo * NetDb::GetRandomRouter (const RouterInfo * compatibleWith, bool floodfillOnly) const + const RouterInfo * NetDb::GetRandomRouter (const RouterInfo * compatibleWith, uint8_t caps) const { CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator (); uint32_t ind = rnd.GenerateWord32 (0, m_RouterInfos.size () - 1); @@ -614,7 +614,7 @@ namespace data { if (!it.second->IsUnreachable () && (!compatibleWith || it.second->IsCompatible (*compatibleWith)) && - (!floodfillOnly || it.second->IsFloodfill ())) + (!caps || (it.second->GetCaps () & caps) == caps)) return it.second; } else diff --git a/NetDb.h b/NetDb.h index 4e1e1038..a369459b 100644 --- a/NetDb.h +++ b/NetDb.h @@ -74,7 +74,7 @@ namespace data void HandleDatabaseStoreMsg (uint8_t * buf, size_t len); void HandleDatabaseSearchReplyMsg (I2NPMessage * msg); - const RouterInfo * GetRandomRouter (const RouterInfo * compatibleWith = nullptr, bool floodfillOnly = false) const; + const RouterInfo * GetRandomRouter (const RouterInfo * compatibleWith = nullptr, uint8_t caps = 0) const; void PostI2NPMsg (I2NPMessage * msg); diff --git a/RouterInfo.cpp b/RouterInfo.cpp index 56c05591..1fa1202c 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -200,8 +200,10 @@ namespace data case 'f': m_Caps |= Caps::eFloodfill; break; + case 'M': + case 'N': case 'O': - m_Caps |= Caps::eHighBanwidth; + m_Caps |= Caps::eHighBandwidth; break; case 'R': m_Caps |= Caps::eReachable; diff --git a/RouterInfo.h b/RouterInfo.h index afde30bc..19521a6d 100644 --- a/RouterInfo.h +++ b/RouterInfo.h @@ -28,7 +28,7 @@ namespace data enum Caps { eFloodfill = 0x01, - eHighBanwidth = 0x02, + eHighBandwidth = 0x02, eReachable = 0x04 }; @@ -84,7 +84,8 @@ namespace data bool IsSSU (bool v4only = true) const; bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; }; bool UsesIntroducer () const; - + uint8_t GetCaps () const { return m_Caps; }; + void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; }; bool IsUnreachable () const { return m_IsUnreachable; }; From c855d8b413bf9b59073cb4443d78bc219ab9ef67 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Mar 2014 16:38:55 -0400 Subject: [PATCH 05/11] load eepsite keys --- Identity.h | 7 +++++++ Streaming.cpp | 19 +++++++++++++++++-- Streaming.h | 2 ++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Identity.h b/Identity.h index 6552fa38..58d7849e 100644 --- a/Identity.h +++ b/Identity.h @@ -28,6 +28,13 @@ namespace data Identity& operator=(const Keys& keys); }; + struct PrivateKeys // for eepsites + { + Identity pub; + uint8_t privateKey[256]; + uint8_t signingPrivateKey[20]; + }; + #pragma pack() class IdentHash diff --git a/Streaming.cpp b/Streaming.cpp index a537def8..eedef81e 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include "Log.h" @@ -301,7 +301,6 @@ namespace stream StreamingDestination::StreamingDestination (): m_LeaseSet (nullptr) { - // TODO: read from file later m_Keys = i2p::data::CreateRandomKeys (); m_Identity = m_Keys; m_IdentHash = i2p::data::CalculateIdentHash (m_Identity); @@ -310,6 +309,22 @@ namespace stream m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (this); } + StreamingDestination::StreamingDestination (const std::string& fullPath): m_LeaseSet (nullptr) + { + std::ifstream s(fullPath.c_str (), std::ifstream::binary); + if (s.is_open ()) + { + i2p::data::PrivateKeys keys; + s.read ((char *)&keys, sizeof (keys)); + // TODO: use PrivateKeys + m_Identity = keys.pub; + memcpy (m_Keys.privateKey, keys.privateKey, 276); + } + else + LogPrint ("Can't open file ", fullPath); + m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (this); + } + StreamingDestination::~StreamingDestination () { if (m_LeaseSet) diff --git a/Streaming.h b/Streaming.h index 973c2a55..36140d0b 100644 --- a/Streaming.h +++ b/Streaming.h @@ -2,6 +2,7 @@ #define STREAMING_H__ #include +#include #include #include #include @@ -106,6 +107,7 @@ namespace stream public: StreamingDestination (); + StreamingDestination (const std::string& fullPath); ~StreamingDestination (); const i2p::data::Keys& GetKeys () const { return m_Keys; }; From 72cb35fcc0a370f3bbf9abd1109b61becbbdfde7 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Mar 2014 16:44:03 -0400 Subject: [PATCH 06/11] load eepsite keys --- Identity.cpp | 7 +++++++ Identity.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/Identity.cpp b/Identity.cpp index fd5c0b74..eb107ca3 100644 --- a/Identity.cpp +++ b/Identity.cpp @@ -19,6 +19,13 @@ namespace data return *this; } + PrivateKeys& PrivateKeys::operator=(const Keys& keys) + { + pub = keys; + memcpy (privateKey, keys.privateKey, 276); // 256 + 20 + return *this; + } + IdentHash CalculateIdentHash (const Identity& identity) { IdentHash hash; diff --git a/Identity.h b/Identity.h index 58d7849e..6b180999 100644 --- a/Identity.h +++ b/Identity.h @@ -33,6 +33,8 @@ namespace data Identity pub; uint8_t privateKey[256]; uint8_t signingPrivateKey[20]; + + PrivateKeys& operator=(const Keys& keys); }; #pragma pack() From 604a69802b499d9477da64487a49f706f980f7e8 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Mar 2014 17:27:37 -0400 Subject: [PATCH 07/11] fixed typo --- RouterInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RouterInfo.cpp b/RouterInfo.cpp index 1fa1202c..735453c8 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -177,7 +177,7 @@ namespace data m_Properties[key] = value; // extract caps - if (strcmp (key, "caps")) + if (!strcmp (key, "caps")) ExtractCaps (value); } From a34d1de10e1137f4831c1c6415ee36d83196378a Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Mar 2014 22:03:50 -0400 Subject: [PATCH 08/11] use PrivateKeys for local destination --- Streaming.cpp | 15 ++++----------- Streaming.h | 7 +++---- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/Streaming.cpp b/Streaming.cpp index eedef81e..305b8832 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -302,8 +302,7 @@ namespace stream StreamingDestination::StreamingDestination (): m_LeaseSet (nullptr) { m_Keys = i2p::data::CreateRandomKeys (); - m_Identity = m_Keys; - m_IdentHash = i2p::data::CalculateIdentHash (m_Identity); + m_IdentHash = i2p::data::CalculateIdentHash (m_Keys.pub); m_SigningPrivateKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, CryptoPP::Integer (m_Keys.signingPrivateKey, 20)); m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (this); @@ -313,13 +312,7 @@ namespace stream { std::ifstream s(fullPath.c_str (), std::ifstream::binary); if (s.is_open ()) - { - i2p::data::PrivateKeys keys; - s.read ((char *)&keys, sizeof (keys)); - // TODO: use PrivateKeys - m_Identity = keys.pub; - memcpy (m_Keys.privateKey, keys.privateKey, 276); - } + s.read ((char *)&m_Keys, sizeof (m_Keys)); else LogPrint ("Can't open file ", fullPath); m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (this); @@ -391,8 +384,8 @@ namespace stream uint8_t * buf = m->GetPayload () + sizeof (I2NPDatabaseStoreMsg); size_t size = 0; - memcpy (buf + size, &m_Identity, sizeof (m_Identity)); - size += sizeof (m_Identity); // destination + memcpy (buf + size, &m_Keys.pub, sizeof (m_Keys.pub)); + size += sizeof (m_Keys.pub); // destination memcpy (buf + size, m_Pool->GetEncryptionPublicKey (), 256); size += 256; // encryption key memset (buf + size, 0, 128); diff --git a/Streaming.h b/Streaming.h index 36140d0b..18ca01f9 100644 --- a/Streaming.h +++ b/Streaming.h @@ -110,8 +110,8 @@ namespace stream StreamingDestination (const std::string& fullPath); ~StreamingDestination (); - const i2p::data::Keys& GetKeys () const { return m_Keys; }; - const i2p::data::Identity& GetIdentity () const { return m_Identity; }; + const i2p::data::PrivateKeys& GetKeys () const { return m_Keys; }; + const i2p::data::Identity& GetIdentity () const { return m_Keys.pub; }; I2NPMessage * GetLeaseSet (); i2p::tunnel::TunnelPool * GetTunnelPool () const { return m_Pool; }; void Sign (uint8_t * buf, int len, uint8_t * signature) const; @@ -130,8 +130,7 @@ namespace stream private: std::map m_Streams; - i2p::data::Keys m_Keys; - i2p::data::Identity m_Identity; + i2p::data::PrivateKeys m_Keys; i2p::data::IdentHash m_IdentHash; i2p::tunnel::TunnelPool * m_Pool; From 25f2f932b0bd52908e77a1a1ade9c100e48f450a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 20 Mar 2014 09:47:02 -0400 Subject: [PATCH 09/11] pass local LeaseSet as const --- Garlic.cpp | 10 +++++----- Garlic.h | 10 +++++----- I2NPProtocol.h | 5 +++-- Streaming.cpp | 4 ++-- Streaming.h | 2 +- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Garlic.cpp b/Garlic.cpp index c003b9a7..94d09a89 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -43,7 +43,7 @@ namespace garlic } } - I2NPMessage * GarlicRoutingSession::WrapSingleMessage (I2NPMessage * msg, I2NPMessage * leaseSet) + I2NPMessage * GarlicRoutingSession::WrapSingleMessage (I2NPMessage * msg, const I2NPMessage * leaseSet) { I2NPMessage * m = NewI2NPMessage (); size_t len = 0; @@ -89,7 +89,7 @@ namespace garlic return m; } - size_t GarlicRoutingSession::CreateAESBlock (uint8_t * buf, I2NPMessage * msg, I2NPMessage * leaseSet) + size_t GarlicRoutingSession::CreateAESBlock (uint8_t * buf, const I2NPMessage * msg, const I2NPMessage * leaseSet) { size_t blockSize = 0; *(uint16_t *)buf = m_NextTag < 0 ? htobe16 (m_NumTags) : 0; // tag count @@ -116,7 +116,7 @@ namespace garlic return blockSize; } - size_t GarlicRoutingSession::CreateGarlicPayload (uint8_t * payload, I2NPMessage * msg, I2NPMessage * leaseSet) + size_t GarlicRoutingSession::CreateGarlicPayload (uint8_t * payload, const I2NPMessage * msg, const I2NPMessage * leaseSet) { uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec uint32_t msgID = m_Rnd.GenerateWord32 (); @@ -153,7 +153,7 @@ namespace garlic return size; } - size_t GarlicRoutingSession::CreateGarlicClove (uint8_t * buf, I2NPMessage * msg, bool isDestination) + size_t GarlicRoutingSession::CreateGarlicClove (uint8_t * buf, const I2NPMessage * msg, bool isDestination) { uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec size_t size = 0; @@ -245,7 +245,7 @@ namespace garlic } I2NPMessage * GarlicRouting::WrapMessage (const i2p::data::RoutingDestination& destination, - I2NPMessage * msg, I2NPMessage * leaseSet) + I2NPMessage * msg, const I2NPMessage * leaseSet) { auto it = m_Sessions.find (destination.GetIdentHash ()); GarlicRoutingSession * session = nullptr; diff --git a/Garlic.h b/Garlic.h index 3fb8ba50..f6c61a06 100644 --- a/Garlic.h +++ b/Garlic.h @@ -42,7 +42,7 @@ namespace garlic GarlicRoutingSession (const i2p::data::RoutingDestination& destination, int numTags); ~GarlicRoutingSession (); - I2NPMessage * WrapSingleMessage (I2NPMessage * msg, I2NPMessage * leaseSet); + I2NPMessage * WrapSingleMessage (I2NPMessage * msg, const I2NPMessage * leaseSet); int GetNextTag () const { return m_NextTag; }; uint32_t GetFirstMsgID () const { return m_FirstMsgID; }; @@ -51,9 +51,9 @@ namespace garlic private: - size_t CreateAESBlock (uint8_t * buf, I2NPMessage * msg, I2NPMessage * leaseSet); - size_t CreateGarlicPayload (uint8_t * payload, I2NPMessage * msg, I2NPMessage * leaseSet); - size_t CreateGarlicClove (uint8_t * buf, I2NPMessage * msg, bool isDestination); + size_t CreateAESBlock (uint8_t * buf, const I2NPMessage * msg, const I2NPMessage * leaseSet); + size_t CreateGarlicPayload (uint8_t * payload, const I2NPMessage * msg, const I2NPMessage * leaseSet); + size_t CreateGarlicClove (uint8_t * buf, const I2NPMessage * msg, bool isDestination); size_t CreateDeliveryStatusClove (uint8_t * buf, uint32_t msgID); void GenerateSessionTags (); @@ -86,7 +86,7 @@ namespace garlic I2NPMessage * WrapSingleMessage (const i2p::data::RoutingDestination& destination, I2NPMessage * msg); I2NPMessage * WrapMessage (const i2p::data::RoutingDestination& destination, - I2NPMessage * msg, I2NPMessage * leaseSet = nullptr); + I2NPMessage * msg, const I2NPMessage * leaseSet = nullptr); private: diff --git a/I2NPProtocol.h b/I2NPProtocol.h index 2030bdad..fe836630 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -103,9 +103,10 @@ namespace tunnel size_t len, offset; i2p::tunnel::InboundTunnel * from; - I2NPHeader * GetHeader () { return (I2NPHeader *)(buf + offset); }; - uint8_t * GetPayload () { return buf + offset + sizeof(I2NPHeader); }; + I2NPHeader * GetHeader () { return (I2NPHeader *)GetBuffer (); }; + uint8_t * GetPayload () { return GetBuffer () + sizeof(I2NPHeader); }; uint8_t * GetBuffer () { return buf + offset; }; + const uint8_t * GetBuffer () const { return buf + offset; }; size_t GetLength () const { return len - offset; }; I2NPMessage& operator=(const I2NPMessage& other) diff --git a/Streaming.cpp b/Streaming.cpp index 305b8832..c5f05297 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -264,7 +264,7 @@ namespace stream bool Stream::SendPacket (uint8_t * packet, size_t size) { - I2NPMessage * leaseSet = nullptr; + const I2NPMessage * leaseSet = nullptr; if (m_LeaseSetUpdated) { leaseSet = m_LocalDestination->GetLeaseSet (); @@ -367,7 +367,7 @@ namespace stream it.second->SetLeaseSetUpdated (); } - I2NPMessage * StreamingDestination::GetLeaseSet () + const I2NPMessage * StreamingDestination::GetLeaseSet () { if (!m_LeaseSet) m_LeaseSet = CreateLeaseSet (); diff --git a/Streaming.h b/Streaming.h index 18ca01f9..b9f52c1a 100644 --- a/Streaming.h +++ b/Streaming.h @@ -112,7 +112,7 @@ namespace stream const i2p::data::PrivateKeys& GetKeys () const { return m_Keys; }; const i2p::data::Identity& GetIdentity () const { return m_Keys.pub; }; - I2NPMessage * GetLeaseSet (); + const I2NPMessage * GetLeaseSet (); i2p::tunnel::TunnelPool * GetTunnelPool () const { return m_Pool; }; void Sign (uint8_t * buf, int len, uint8_t * signature) const; From eeacc3e0f39ab1ce4e9052c50ca74a32210fa514 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 20 Mar 2014 12:13:06 -0400 Subject: [PATCH 10/11] pass local LeaseSet as const --- Streaming.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Streaming.cpp b/Streaming.cpp index c5f05297..c505711a 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -369,8 +369,10 @@ namespace stream const I2NPMessage * StreamingDestination::GetLeaseSet () { - if (!m_LeaseSet) - m_LeaseSet = CreateLeaseSet (); + // TODO: LeaseSet is always re-created. ivestigate + if (m_LeaseSet) + DeleteI2NPMessage (m_LeaseSet); + m_LeaseSet = CreateLeaseSet (); return m_LeaseSet; } From ac48e3b35502cfa8986387e1d5edbcc95d841672 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 20 Mar 2014 12:48:03 -0400 Subject: [PATCH 11/11] renew LeaseSet's I2NP message ID and timestamp before sending --- I2NPProtocol.cpp | 17 ++++++++++++++--- I2NPProtocol.h | 1 + Streaming.cpp | 8 ++++---- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 5b2c66f1..0b34f9db 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -31,17 +31,17 @@ namespace i2p delete msg; } + static uint32_t I2NPmsgID = 0; // TODO: create class void FillI2NPMessageHeader (I2NPMessage * msg, I2NPMessageType msgType, uint32_t replyMsgID) { - static uint32_t msgID = 0; I2NPHeader * header = msg->GetHeader (); header->typeID = msgType; if (replyMsgID) // for tunnel creation header->msgID = htobe32 (replyMsgID); else { - header->msgID = htobe32 (msgID); - msgID++; + header->msgID = htobe32 (I2NPmsgID); + I2NPmsgID++; } header->expiration = htobe64 (i2p::util::GetMillisecondsSinceEpoch () + 5000); // TODO: 5 secs is a magic number int len = msg->GetLength () - sizeof (I2NPHeader); @@ -51,6 +51,17 @@ namespace i2p header->chks = hash[0]; } + void RenewI2NPMessageHeader (I2NPMessage * msg) + { + if (msg) + { + I2NPHeader * header = msg->GetHeader (); + header->msgID = htobe32 (I2NPmsgID); + I2NPmsgID++; + header->expiration = htobe64 (i2p::util::GetMillisecondsSinceEpoch () + 5000); + } + } + I2NPMessage * CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID) { I2NPMessage * msg = NewI2NPMessage (); diff --git a/I2NPProtocol.h b/I2NPProtocol.h index fe836630..5e7900aa 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -142,6 +142,7 @@ namespace tunnel I2NPMessage * NewI2NPMessage (); void DeleteI2NPMessage (I2NPMessage * msg); void FillI2NPMessageHeader (I2NPMessage * msg, I2NPMessageType msgType, uint32_t replyMsgID = 0); + void RenewI2NPMessageHeader (I2NPMessage * msg); I2NPMessage * CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID = 0); I2NPMessage * CreateI2NPMessage (const uint8_t * buf, int len); diff --git a/Streaming.cpp b/Streaming.cpp index c505711a..eb942bd5 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -369,10 +369,10 @@ namespace stream const I2NPMessage * StreamingDestination::GetLeaseSet () { - // TODO: LeaseSet is always re-created. ivestigate - if (m_LeaseSet) - DeleteI2NPMessage (m_LeaseSet); - m_LeaseSet = CreateLeaseSet (); + if (!m_LeaseSet) + m_LeaseSet = CreateLeaseSet (); + else + RenewI2NPMessageHeader (m_LeaseSet); return m_LeaseSet; }