include DeliveryStatus to Garlic

pull/7/head
orignal 11 years ago
parent 3aab091e9f
commit 57c97208f9

@ -4,6 +4,8 @@
#include <string> #include <string>
#include "ElGamal.h" #include "ElGamal.h"
#include "RouterContext.h" #include "RouterContext.h"
#include "I2NPProtocol.h"
#include "Tunnel.h"
#include "Timestamp.h" #include "Timestamp.h"
#include "Streaming.h" #include "Streaming.h"
#include "Garlic.h" #include "Garlic.h"
@ -65,8 +67,6 @@ namespace garlic
FillI2NPMessageHeader (m, eI2NPGarlic); FillI2NPMessageHeader (m, eI2NPGarlic);
if (msg) if (msg)
DeleteI2NPMessage (msg); DeleteI2NPMessage (msg);
if (leaseSet)
DeleteI2NPMessage (leaseSet);
return m; return m;
} }
@ -97,17 +97,23 @@ namespace garlic
size_t GarlicRoutingSession::CreateGarlicPayload (uint8_t * payload, I2NPMessage * msg, I2NPMessage * leaseSet) size_t GarlicRoutingSession::CreateGarlicPayload (uint8_t * payload, I2NPMessage * msg, I2NPMessage * leaseSet)
{ {
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec
uint32_t msgID = m_Rnd.GenerateWord32 ();
size_t size = 0; size_t size = 0;
uint8_t * numCloves = payload + size; uint8_t * numCloves = payload + size;
*numCloves = 0; *numCloves = 0;
size++; size++;
if (leaseSet) // first clove is our leaseSet if presented if (leaseSet)
{ {
// clove is DeliveryStatus is LeaseSet is presented
size += CreateDeliveryStatusClove (payload + size, msgID);
(*numCloves)++;
// clove is our leaseSet if presented
size += CreateGarlicClove (payload + size, leaseSet, false); size += CreateGarlicClove (payload + size, leaseSet, false);
(*numCloves)++; (*numCloves)++;
} }
if (msg) // next clove message ifself if presented if (msg) // clove message ifself if presented
{ {
size += CreateGarlicClove (payload + size, msg, m_Destination->IsDestination ()); size += CreateGarlicClove (payload + size, msg, m_Destination->IsDestination ());
(*numCloves)++; (*numCloves)++;
@ -115,7 +121,7 @@ namespace garlic
memset (payload + size, 0, 3); // certificate of message memset (payload + size, 0, 3); // certificate of message
size += 3; size += 3;
*(uint32_t *)(payload + size) = htobe32 (m_Rnd.GenerateWord32 ()); // MessageID *(uint32_t *)(payload + size) = htobe32 (msgID); // MessageID
size += 4; size += 4;
*(uint64_t *)(payload + size) = htobe64 (ts); // Expiration of message *(uint64_t *)(payload + size) = htobe64 (ts); // Expiration of message
size += 8; size += 8;
@ -150,6 +156,42 @@ namespace garlic
return size; return size;
} }
size_t GarlicRoutingSession::CreateDeliveryStatusClove (uint8_t * buf, uint32_t msgID)
{
size_t size = 0;
auto tunnel = i2p::tunnel::tunnels.GetNextInboundTunnel ();
if (tunnel)
{
buf[size] = eGarlicDeliveryTypeTunnel << 5; // delivery instructions flag tunnel
size++;
*(uint32_t *)(buf + size) = htobe32 (tunnel->GetNextTunnelID ()); // tunnelID
size += 4;
memcpy (buf + size, tunnel->GetNextIdentHash (), 32); // To Hash
size += 32;
}
else
{
LogPrint ("No reply tunnels for garlic DeliveryStatus found");
buf[size] = 0;// delivery instructions flag local
size++;
}
I2NPMessage * msg = CreateDeliveryStatusMsg (msgID);
memcpy (buf + size, msg->GetBuffer (), msg->GetLength ());
size += msg->GetLength ();
DeleteI2NPMessage (msg);
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec
*(uint32_t *)(buf + size) = htobe32 (m_Rnd.GenerateWord32 ()); // CloveID
size += 4;
*(uint64_t *)(buf + size) = htobe64 (ts); // Expiration of clove
size += 8;
memset (buf + size, 0, 3); // certificate of clove
size += 3;
return size;
}
GarlicRouting routing; GarlicRouting routing;
GarlicRouting::GarlicRouting () GarlicRouting::GarlicRouting ()
{ {

@ -48,6 +48,7 @@ namespace garlic
size_t CreateAESBlock (uint8_t * buf, I2NPMessage * msg, I2NPMessage * leaseSet); size_t CreateAESBlock (uint8_t * buf, I2NPMessage * msg, I2NPMessage * leaseSet);
size_t CreateGarlicPayload (uint8_t * payload, 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 CreateGarlicClove (uint8_t * buf, I2NPMessage * msg, bool isDestination);
size_t CreateDeliveryStatusClove (uint8_t * buf, uint32_t msgID);
private: private:

@ -67,7 +67,7 @@ namespace i2p
return msg; return msg;
} }
I2NPMessage * CreateDeliveryStatusMsg () I2NPMessage * CreateDeliveryStatusMsg (uint32_t msgID)
{ {
#pragma pack(1) #pragma pack(1)
struct struct
@ -77,7 +77,7 @@ namespace i2p
} msg; } msg;
#pragma pack () #pragma pack ()
msg.msgID = 0; msg.msgID = htobe32 (msgID);
msg.timestamp = htobe64 (i2p::util::GetMillisecondsSinceEpoch ()); msg.timestamp = htobe64 (i2p::util::GetMillisecondsSinceEpoch ());
return CreateI2NPMessage (eI2NPDeliveryStatus, (uint8_t *)&msg, sizeof (msg)); return CreateI2NPMessage (eI2NPDeliveryStatus, (uint8_t *)&msg, sizeof (msg));
} }

@ -103,7 +103,7 @@ namespace i2p
I2NPMessage * CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID = 0); I2NPMessage * CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID = 0);
I2NPMessage * CreateI2NPMessage (const uint8_t * buf, int len); I2NPMessage * CreateI2NPMessage (const uint8_t * buf, int len);
I2NPMessage * CreateDeliveryStatusMsg (); I2NPMessage * CreateDeliveryStatusMsg (uint32_t msgID);
I2NPMessage * CreateDatabaseLookupMsg (const uint8_t * key, const uint8_t * from, I2NPMessage * CreateDatabaseLookupMsg (const uint8_t * key, const uint8_t * from,
uint32_t replyTunnelID, bool exploratory = false, uint32_t replyTunnelID, bool exploratory = false,
std::set<i2p::data::IdentHash> * excludedPeers = nullptr); std::set<i2p::data::IdentHash> * excludedPeers = nullptr);

@ -1,3 +1,5 @@
#include <cryptopp/dsa.h>
#include "CryptoConst.h"
#include "Log.h" #include "Log.h"
#include "LeaseSet.h" #include "LeaseSet.h"
@ -24,10 +26,22 @@ namespace data
memcpy (m_EncryptionKey, header->encryptionKey, 256); memcpy (m_EncryptionKey, header->encryptionKey, 256);
LogPrint ("LeaseSet num=", (int)header->num); LogPrint ("LeaseSet num=", (int)header->num);
const uint8_t * leases = buf + sizeof (H);
for (int i = 0; i < header->num; i++) for (int i = 0; i < header->num; i++)
{ {
m_Leases.push_back (*(Lease *)(buf + sizeof (H))); Lease lease = *(Lease *)leases;
lease.tunnelID = be32toh (lease.tunnelID);
m_Leases.push_back (lease);
leases += sizeof (Lease);
} }
// verify
CryptoPP::DSA::PublicKey pubKey;
pubKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag,
CryptoPP::Integer (m_Identity.signingKey, 128));
CryptoPP::DSA::Verifier verifier (pubKey);
if (!verifier.VerifyMessage (buf, leases - buf, leases, 40))
LogPrint ("LeaseSet verification failed");
} }
} }
} }

@ -91,7 +91,7 @@ namespace stream
size += len; // payload size += len; // payload
m_LocalDestination->Sign (packet, size, signature); m_LocalDestination->Sign (packet, size, signature);
I2NPMessage * msg = i2p::garlic::routing.WrapSingleMessage (m_RemoteLeaseSet, I2NPMessage * msg = i2p::garlic::routing.WrapSingleMessage (m_RemoteLeaseSet,
CreateDataMessage (this, packet, size), m_LocalDestination->CreateLeaseSet ()); CreateDataMessage (this, packet, size), m_LocalDestination->GetLeaseSet ());
auto outbound = i2p::tunnel::tunnels.GetNextOutboundTunnel (); auto outbound = i2p::tunnel::tunnels.GetNextOutboundTunnel ();
if (outbound) if (outbound)
@ -106,7 +106,7 @@ namespace stream
StreamingDestination * sharedLocalDestination = nullptr; StreamingDestination * sharedLocalDestination = nullptr;
StreamingDestination::StreamingDestination () StreamingDestination::StreamingDestination (): m_LeaseSet (nullptr)
{ {
// TODO: read from file later // TODO: read from file later
m_Keys = i2p::data::CreateRandomKeys (); m_Keys = i2p::data::CreateRandomKeys ();
@ -116,6 +116,12 @@ namespace stream
CryptoPP::Integer (m_Keys.signingPrivateKey, 20)); CryptoPP::Integer (m_Keys.signingPrivateKey, 20));
} }
StreamingDestination::~StreamingDestination ()
{
if (m_LeaseSet)
DeleteI2NPMessage (m_LeaseSet);
}
void StreamingDestination::HandleNextPacket (const uint8_t * buf, size_t len) void StreamingDestination::HandleNextPacket (const uint8_t * buf, size_t len)
{ {
uint32_t sendStreamID = *(uint32_t *)(buf); uint32_t sendStreamID = *(uint32_t *)(buf);
@ -142,6 +148,15 @@ namespace stream
} }
} }
I2NPMessage * StreamingDestination::GetLeaseSet ()
{
if (!m_LeaseSet)
m_LeaseSet = CreateLeaseSet ();
else
FillI2NPMessageHeader (m_LeaseSet, eI2NPDatabaseStore); // refresh msgID
return m_LeaseSet;
}
I2NPMessage * StreamingDestination::CreateLeaseSet () const I2NPMessage * StreamingDestination::CreateLeaseSet () const
{ {
I2NPMessage * m = NewI2NPMessage (); I2NPMessage * m = NewI2NPMessage ();

@ -52,16 +52,21 @@ namespace stream
public: public:
StreamingDestination (); StreamingDestination ();
~StreamingDestination ();
const i2p::data::Keys& GetKeys () const { return m_Keys; }; const i2p::data::Keys& GetKeys () const { return m_Keys; };
const i2p::data::Identity& GetIdentity () const { return m_Identity; }; const i2p::data::Identity& GetIdentity () const { return m_Identity; };
I2NPMessage * CreateLeaseSet () const; I2NPMessage * GetLeaseSet ();
void Sign (uint8_t * buf, int len, uint8_t * signature) const; void Sign (uint8_t * buf, int len, uint8_t * signature) const;
Stream * CreateNewStream (const i2p::data::LeaseSet * remote); Stream * CreateNewStream (const i2p::data::LeaseSet * remote);
void DeleteStream (Stream * stream); void DeleteStream (Stream * stream);
void HandleNextPacket (const uint8_t * buf, size_t len); void HandleNextPacket (const uint8_t * buf, size_t len);
private:
I2NPMessage * CreateLeaseSet () const;
private: private:
std::map<uint32_t, Stream *> m_Streams; std::map<uint32_t, Stream *> m_Streams;
@ -69,6 +74,8 @@ namespace stream
i2p::data::Identity m_Identity; i2p::data::Identity m_Identity;
i2p::data::IdentHash m_IdentHash; i2p::data::IdentHash m_IdentHash;
I2NPMessage * m_LeaseSet;
CryptoPP::DSA::PrivateKey m_SigningPrivateKey; CryptoPP::DSA::PrivateKey m_SigningPrivateKey;
}; };

Loading…
Cancel
Save