diff --git a/Destination.cpp b/Destination.cpp index 8c8f5072..5a338a60 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -457,9 +457,15 @@ namespace client request->requestTime = i2p::util::GetSecondsSinceEpoch (); request->requestTimeoutTimer.cancel (); + CryptoPP::AutoSeededRandomPool rnd; + uint8_t replyKey[32], replyTag[32]; + rnd.GenerateBlock (replyKey, 32); // random session key + rnd.GenerateBlock (replyTag, 32); // random session tag + AddSessionKey (replyKey, replyTag); + I2NPMessage * msg = WrapMessage (*nextFloodfill, - CreateDatabaseLookupMsg (dest, replyTunnel->GetNextIdentHash (), - replyTunnel->GetNextTunnelID (), false, &request->excluded, true, m_Pool)); + CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, + replyTunnel, replyKey, replyTag)); outboundTunnel->SendTunnelDataMsg ( { i2p::tunnel::TunnelMessageBlock diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index eba49fa8..c2ae6d3b 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -171,6 +171,45 @@ namespace i2p return m; } + I2NPMessage * CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest, + const std::set& excludedFloodfills, + const i2p::tunnel::InboundTunnel * replyTunnel, const uint8_t * replyKey, const uint8_t * replyTag) + { + I2NPMessage * m = NewI2NPMessage (); + uint8_t * buf = m->GetPayload (); + memcpy (buf, dest, 32); // key + buf += 32; + memcpy (buf, replyTunnel->GetNextIdentHash (), 32); // reply tunnel GW + buf += 32; + *buf = 7; // flags (01 - tunnel, 10 - encrypted, 0100 - LS lookup + htobe32buf (buf + 1, replyTunnel->GetNextTunnelID ()); // reply tunnel ID + buf += 5; + + // excluded + int cnt = excludedFloodfills.size (); + htobe16buf (buf, cnt); + buf += 2; + if (cnt > 0) + { + for (auto& it: excludedFloodfills) + { + memcpy (buf, it, 32); + buf += 32; + } + } + // encryption + memcpy (buf, replyKey, 32); + buf[32] = 1; // 1 tag + memcpy (buf + 33, replyTag, 32); + buf += 65; + + m->len += (buf - m->GetPayload ()); + FillI2NPMessageHeader (m, eI2NPDatabaseLookup); + return m; + } + + + I2NPMessage * CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, const i2p::data::RouterInfo * floodfill) { diff --git a/I2NPProtocol.h b/I2NPProtocol.h index 39e719c8..9d3fa79b 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -5,6 +5,7 @@ #include #include #include "I2PEndian.h" +#include "Identity.h" #include "RouterInfo.h" #include "LeaseSet.h" @@ -180,6 +181,9 @@ namespace tunnel uint32_t replyTunnelID, bool exploratory = false, std::set * excludedPeers = nullptr, bool encryption = false, i2p::tunnel::TunnelPool * pool = nullptr); + I2NPMessage * CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest, + const std::set& excludedFloodfills, + const i2p::tunnel::InboundTunnel * replyTunnel, const uint8_t * replyKey, const uint8_t * replyTag); I2NPMessage * CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, const i2p::data::RouterInfo * floodfill); I2NPMessage * CreateDatabaseStoreMsg (const i2p::data::RouterInfo * router = nullptr);