mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 00:00:29 +03:00
Inroduced IdentHash
This commit is contained in:
parent
fbbcc69c72
commit
885e996a8a
34
LeaseSet.h
34
LeaseSet.h
@ -2,12 +2,14 @@
|
||||
#define LEASE_SET_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <list>
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace data
|
||||
{
|
||||
|
||||
#pragma pack(1)
|
||||
struct Lease
|
||||
{
|
||||
@ -17,10 +19,36 @@ namespace data
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
class IdentHash
|
||||
{
|
||||
public:
|
||||
|
||||
IdentHash (const uint8_t * hash) { memcpy (m_Hash, hash, 32); };
|
||||
IdentHash (const IdentHash& ) = default;
|
||||
IdentHash (IdentHash&& ) = default;
|
||||
IdentHash () = default;
|
||||
|
||||
IdentHash& operator= (const IdentHash& ) = default;
|
||||
IdentHash& operator= (IdentHash&& ) = default;
|
||||
|
||||
uint8_t * operator()() { return m_Hash; };
|
||||
const uint8_t * operator()() const { return m_Hash; };
|
||||
|
||||
operator uint8_t * () { return m_Hash; };
|
||||
operator const uint8_t * () const { return m_Hash; };
|
||||
|
||||
bool operator== (const IdentHash& other) const { return !memcmp (m_Hash, other.m_Hash, 32); };
|
||||
bool operator< (const IdentHash& other) const { return memcmp (m_Hash, other.m_Hash, 32) < 0; };
|
||||
|
||||
private:
|
||||
|
||||
uint8_t m_Hash[32];
|
||||
};
|
||||
|
||||
class RoutingDestination // TODO: move to separate file later
|
||||
{
|
||||
public:
|
||||
virtual const uint8_t * GetIdentHash () const = 0;
|
||||
virtual const IdentHash& GetIdentHash () const = 0;
|
||||
virtual const uint8_t * GetEncryptionPublicKey () const = 0;
|
||||
virtual bool IsDestination () const = 0; // for garlic
|
||||
};
|
||||
@ -32,14 +60,14 @@ namespace data
|
||||
LeaseSet (const uint8_t * buf, int len);
|
||||
|
||||
// implements RoutingDestination
|
||||
const uint8_t * GetIdentHash () const { return m_IdentHash; };
|
||||
const IdentHash& GetIdentHash () const { return m_IdentHash; };
|
||||
const uint8_t * GetEncryptionPublicKey () const { return m_EncryptionKey; };
|
||||
bool IsDestination () const { return true; };
|
||||
|
||||
private:
|
||||
|
||||
std::list<Lease> m_Leases;
|
||||
uint8_t m_IdentHash[32];
|
||||
IdentHash m_IdentHash;
|
||||
uint8_t m_EncryptionKey[256];
|
||||
};
|
||||
}
|
||||
|
@ -20,9 +20,9 @@ namespace i2p
|
||||
{
|
||||
namespace ntcp
|
||||
{
|
||||
NTCPSession::NTCPSession (boost::asio::ip::tcp::socket& s, const i2p::data::RouterInfo * in_RemoteRouterInfo):
|
||||
m_Socket (s), m_IsEstablished (false), m_ReceiveBufferOffset (0),
|
||||
m_NextMessage (nullptr), m_DelayedMessage (nullptr)
|
||||
NTCPSession::NTCPSession (boost::asio::io_service& service, const i2p::data::RouterInfo * in_RemoteRouterInfo):
|
||||
m_Socket (service), m_TerminationTimer (service), m_IsEstablished (false),
|
||||
m_ReceiveBufferOffset (0), m_NextMessage (nullptr)
|
||||
{
|
||||
if (in_RemoteRouterInfo)
|
||||
m_RemoteRouterInfo = *in_RemoteRouterInfo;
|
||||
@ -52,8 +52,9 @@ namespace ntcp
|
||||
{
|
||||
m_IsEstablished = false;
|
||||
m_Socket.close ();
|
||||
if (m_DelayedMessage)
|
||||
delete m_DelayedMessage;
|
||||
for (auto it :m_DelayedMessages)
|
||||
delete it;
|
||||
m_DelayedMessages.clear ();
|
||||
// TODO: notify tunnels
|
||||
i2p::transports.RemoveNTCPSession (this);
|
||||
delete this;
|
||||
@ -64,16 +65,15 @@ namespace ntcp
|
||||
{
|
||||
LogPrint ("NTCP session connected");
|
||||
m_IsEstablished = true;
|
||||
i2p::transports.AddNTCPSession (this);
|
||||
|
||||
SendTimeSyncMessage ();
|
||||
SendI2NPMessage (CreateDatabaseStoreMsg ()); // we tell immediately who we are
|
||||
|
||||
if (m_DelayedMessage)
|
||||
if (!m_DelayedMessages.empty ())
|
||||
{
|
||||
i2p::I2NPMessage * delayedMessage = m_DelayedMessage;
|
||||
m_DelayedMessage = 0;
|
||||
SendI2NPMessage (delayedMessage);
|
||||
for (auto it :m_DelayedMessages)
|
||||
SendI2NPMessage (it);
|
||||
m_DelayedMessages.clear ();
|
||||
}
|
||||
}
|
||||
|
||||
@ -468,6 +468,7 @@ namespace ntcp
|
||||
|
||||
boost::asio::async_write (m_Socket, boost::asio::buffer (sendBuffer, l), boost::asio::transfer_all (),
|
||||
boost::bind(&NTCPSession::HandleSent, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, msg));
|
||||
ScheduleTermination (); // reset termination timer
|
||||
}
|
||||
|
||||
void NTCPSession::HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, i2p::I2NPMessage * msg)
|
||||
@ -497,13 +498,31 @@ namespace ntcp
|
||||
if (m_IsEstablished)
|
||||
Send (msg);
|
||||
else
|
||||
m_DelayedMessage = msg;
|
||||
m_DelayedMessages.push_back (msg);
|
||||
}
|
||||
}
|
||||
|
||||
void NTCPSession::ScheduleTermination ()
|
||||
{
|
||||
m_TerminationTimer.cancel ();
|
||||
m_TerminationTimer.expires_from_now (boost::posix_time::seconds(TERMINATION_TIMEOUT));
|
||||
m_TerminationTimer.async_wait (boost::bind (&NTCPSession::HandleTerminationTimer,
|
||||
this, boost::asio::placeholders::error));
|
||||
}
|
||||
|
||||
void NTCPSession::HandleTerminationTimer (const boost::system::error_code& ecode)
|
||||
{
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
{
|
||||
LogPrint ("No activity fo ", TERMINATION_TIMEOUT, " seconds");
|
||||
m_Socket.close ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NTCPClient::NTCPClient (boost::asio::io_service& service, const char * address,
|
||||
int port, const i2p::data::RouterInfo& in_RouterInfo): NTCPSession (m_Socket, &in_RouterInfo),
|
||||
m_Socket (service), m_Endpoint (boost::asio::ip::address::from_string (address), port)
|
||||
int port, const i2p::data::RouterInfo& in_RouterInfo): NTCPSession (service, &in_RouterInfo),
|
||||
m_Endpoint (boost::asio::ip::address::from_string (address), port)
|
||||
{
|
||||
Connect ();
|
||||
}
|
||||
@ -511,7 +530,7 @@ namespace ntcp
|
||||
void NTCPClient::Connect ()
|
||||
{
|
||||
LogPrint ("Connecting to ", m_Endpoint.address ().to_string (),":", m_Endpoint.port ());
|
||||
m_Socket.async_connect (m_Endpoint, boost::bind (&NTCPClient::HandleConnect,
|
||||
GetSocket ().async_connect (m_Endpoint, boost::bind (&NTCPClient::HandleConnect,
|
||||
this, boost::asio::placeholders::error));
|
||||
}
|
||||
|
||||
@ -529,9 +548,14 @@ namespace ntcp
|
||||
}
|
||||
}
|
||||
|
||||
NTCPServerConnection::NTCPServerConnection (boost::asio::io_service& service):
|
||||
NTCPSession (m_Socket), m_Socket (service)
|
||||
void NTCPServerConnection::Connected ()
|
||||
{
|
||||
LogPrint ("NTCP server session connected");
|
||||
SetIsEstablished (true);
|
||||
i2p::transports.AddNTCPSession (this);
|
||||
|
||||
SendTimeSyncMessage ();
|
||||
SendI2NPMessage (CreateDatabaseStoreMsg ()); // we tell immediately who we are
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <mutex>
|
||||
#include <list>
|
||||
#include <boost/asio.hpp>
|
||||
#include <cryptopp/modes.h>
|
||||
#include <cryptopp/aes.h>
|
||||
@ -60,13 +61,15 @@ namespace ntcp
|
||||
|
||||
#pragma pack()
|
||||
|
||||
const int TERMINATION_TIMEOUT = 60; // 1 minute
|
||||
class NTCPSession
|
||||
{
|
||||
public:
|
||||
|
||||
NTCPSession (boost::asio::ip::tcp::socket& s, const i2p::data::RouterInfo * in_RemoteRouterInfo = 0);
|
||||
NTCPSession (boost::asio::io_service& service, const i2p::data::RouterInfo * in_RemoteRouterInfo = 0);
|
||||
virtual ~NTCPSession () {};
|
||||
|
||||
boost::asio::ip::tcp::socket& GetSocket () { return m_Socket; };
|
||||
bool IsEstablished () const { return m_IsEstablished; };
|
||||
const i2p::data::RouterInfo& GetRemoteRouterInfo () const { return m_RemoteRouterInfo; };
|
||||
|
||||
@ -77,7 +80,9 @@ namespace ntcp
|
||||
protected:
|
||||
|
||||
void Terminate ();
|
||||
void Connected ();
|
||||
virtual void Connected ();
|
||||
void SendTimeSyncMessage ();
|
||||
void SetIsEstablished (bool isEstablished) { m_IsEstablished = isEstablished; }
|
||||
|
||||
private:
|
||||
|
||||
@ -106,11 +111,15 @@ namespace ntcp
|
||||
void Send (i2p::I2NPMessage * msg);
|
||||
void HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, i2p::I2NPMessage * msg);
|
||||
|
||||
void SendTimeSyncMessage ();
|
||||
|
||||
// timer
|
||||
void ScheduleTermination ();
|
||||
void HandleTerminationTimer (const boost::system::error_code& ecode);
|
||||
|
||||
private:
|
||||
|
||||
boost::asio::ip::tcp::socket& m_Socket;
|
||||
boost::asio::ip::tcp::socket m_Socket;
|
||||
boost::asio::deadline_timer m_TerminationTimer;
|
||||
bool m_IsEstablished;
|
||||
|
||||
CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption m_Decryption;
|
||||
@ -127,7 +136,8 @@ namespace ntcp
|
||||
uint8_t m_ReceiveBuffer[i2p::NTCP_MAX_MESSAGE_SIZE*2], m_TimeSyncBuffer[16];
|
||||
int m_ReceiveBufferOffset;
|
||||
|
||||
i2p::I2NPMessage * m_NextMessage, * m_DelayedMessage;
|
||||
i2p::I2NPMessage * m_NextMessage;
|
||||
std::list<i2p::I2NPMessage *> m_DelayedMessages;
|
||||
size_t m_NextMessageOffset;
|
||||
|
||||
std::mutex m_EncryptionMutex;
|
||||
@ -146,7 +156,6 @@ namespace ntcp
|
||||
|
||||
private:
|
||||
|
||||
boost::asio::ip::tcp::socket m_Socket;
|
||||
boost::asio::ip::tcp::endpoint m_Endpoint;
|
||||
};
|
||||
|
||||
@ -154,12 +163,11 @@ namespace ntcp
|
||||
{
|
||||
public:
|
||||
|
||||
NTCPServerConnection (boost::asio::io_service& service);
|
||||
boost::asio::ip::tcp::socket& GetSocket () { return m_Socket; };
|
||||
NTCPServerConnection (boost::asio::io_service& service): NTCPSession (service) {};
|
||||
|
||||
private:
|
||||
protected:
|
||||
|
||||
boost::asio::ip::tcp::socket m_Socket;
|
||||
virtual void Connected ();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
17
NetDb.cpp
17
NetDb.cpp
@ -95,14 +95,13 @@ namespace data
|
||||
void NetDb::AddRouterInfo (uint8_t * buf, int len)
|
||||
{
|
||||
RouterInfo * r = new RouterInfo (buf, len);
|
||||
std::string hash((const char *)r->GetIdentHash (), 32);
|
||||
auto it = m_RouterInfos.find(hash);
|
||||
auto it = m_RouterInfos.find(r->GetIdentHash ());
|
||||
if (it != m_RouterInfos.end ())
|
||||
{
|
||||
if (r->GetTimestamp () > it->second->GetTimestamp ())
|
||||
{
|
||||
LogPrint ("RouterInfo updated");
|
||||
*m_RouterInfos[hash] = *r; // we can't replace point because it's used by tunnels
|
||||
*m_RouterInfos[r->GetIdentHash ()] = *r; // we can't replace point because it's used by tunnels
|
||||
}
|
||||
else
|
||||
delete r;
|
||||
@ -110,19 +109,19 @@ namespace data
|
||||
else
|
||||
{
|
||||
LogPrint ("New RouterInfo added");
|
||||
m_RouterInfos[hash] = r;
|
||||
m_RouterInfos[r->GetIdentHash ()] = r;
|
||||
}
|
||||
}
|
||||
|
||||
void NetDb::AddLeaseSet (uint8_t * buf, int len)
|
||||
{
|
||||
LeaseSet * l = new LeaseSet (buf, len);
|
||||
m_LeaseSets[std::string ((const char *)l->GetIdentHash (), 32)] = l;
|
||||
m_LeaseSets[l->GetIdentHash ()] = l;
|
||||
}
|
||||
|
||||
RouterInfo * NetDb::FindRouter (const uint8_t * ident) const
|
||||
RouterInfo * NetDb::FindRouter (const IdentHash& ident) const
|
||||
{
|
||||
auto it = m_RouterInfos.find (std::string ((const char *)ident, 32));
|
||||
auto it = m_RouterInfos.find (ident);
|
||||
if (it != m_RouterInfos.end ())
|
||||
return it->second;
|
||||
else
|
||||
@ -143,7 +142,7 @@ namespace data
|
||||
for (boost::filesystem::directory_iterator it1 (it->path ()); it1 != end; ++it1)
|
||||
{
|
||||
RouterInfo * r = new RouterInfo (it1->path ().c_str ());
|
||||
m_RouterInfos[std::string ((const char *)r->GetIdentHash (), 32)] = r;
|
||||
m_RouterInfos[r->GetIdentHash ()] = r;
|
||||
numRouters++;
|
||||
}
|
||||
}
|
||||
@ -252,7 +251,7 @@ namespace data
|
||||
|
||||
if (isExploratory)
|
||||
{
|
||||
if (m_RouterInfos.find (std::string ((const char *)router, 32)) == m_RouterInfos.end ())
|
||||
if (m_RouterInfos.find (IdentHash(router)) == m_RouterInfos.end ())
|
||||
{
|
||||
LogPrint ("Found new router. Requesting RouterInfo ...");
|
||||
if (outbound && inbound)
|
||||
|
6
NetDb.h
6
NetDb.h
@ -26,7 +26,7 @@ namespace data
|
||||
|
||||
void AddRouterInfo (uint8_t * buf, int len);
|
||||
void AddLeaseSet (uint8_t * buf, int len);
|
||||
RouterInfo * FindRouter (const uint8_t * ident) const;
|
||||
RouterInfo * FindRouter (const IdentHash& ident) const;
|
||||
|
||||
void RequestDestination (const char * b32, const uint8_t * router); // in base32
|
||||
void RequestDestination (const uint8_t * destination, const uint8_t * router);
|
||||
@ -47,8 +47,8 @@ namespace data
|
||||
|
||||
private:
|
||||
|
||||
std::map<std::string, LeaseSet *> m_LeaseSets;
|
||||
std::map<std::string, RouterInfo *> m_RouterInfos;
|
||||
std::map<IdentHash, LeaseSet *> m_LeaseSets;
|
||||
std::map<IdentHash, RouterInfo *> m_RouterInfos;
|
||||
|
||||
bool m_IsRunning;
|
||||
std::thread * m_Thread;
|
||||
|
@ -53,6 +53,7 @@ namespace data
|
||||
void SetRouterIdentity (const RouterIdentity& identity);
|
||||
const char * GetIdentHashBase64 () const { return m_IdentHashBase64; };
|
||||
const char * GetIdentHashAbbreviation () const { return m_IdentHashAbbreviation; };
|
||||
uint64_t GetTimestamp () const { return m_Timestamp; };
|
||||
const std::vector<Address>& GetAddresses () const { return m_Addresses; };
|
||||
Address * GetNTCPAddress ();
|
||||
|
||||
@ -70,7 +71,7 @@ namespace data
|
||||
void SetUpdated (bool updated) { m_IsUpdated = updated; };
|
||||
|
||||
// implements RoutingDestination
|
||||
const uint8_t * GetIdentHash () const { return m_IdentHash; };
|
||||
const IdentHash& GetIdentHash () const { return m_IdentHash; };
|
||||
const uint8_t * GetEncryptionPublicKey () const { return m_RouterIdentity.publicKey; };
|
||||
bool IsDestination () const { return false; };
|
||||
|
||||
@ -86,7 +87,7 @@ namespace data
|
||||
private:
|
||||
|
||||
RouterIdentity m_RouterIdentity;
|
||||
uint8_t m_IdentHash[32];
|
||||
IdentHash m_IdentHash;
|
||||
char m_IdentHashBase64[48], m_IdentHashAbbreviation[5];
|
||||
char m_Buffer[2048];
|
||||
int m_BufferLen;
|
||||
|
@ -12,31 +12,21 @@ namespace tunnel
|
||||
{
|
||||
TransitTunnel::TransitTunnel (uint32_t receiveTunnelID,
|
||||
const uint8_t * nextIdent, uint32_t nextTunnelID,
|
||||
const uint8_t * layerKey,const uint8_t * ivKey,
|
||||
bool isGateway, bool isEndpoint)
|
||||
const uint8_t * layerKey,const uint8_t * ivKey):
|
||||
m_TunnelID (receiveTunnelID), m_NextTunnelID (nextTunnelID), m_NextIdent (nextIdent)
|
||||
{
|
||||
memcpy (m_LayerKey, layerKey, 32);
|
||||
memcpy (m_IVKey, ivKey, 32);
|
||||
memcpy (m_NextIdent, nextIdent, 32);
|
||||
m_IsGateway = isGateway;
|
||||
m_IsEndpoint = isEndpoint;
|
||||
m_TunnelID = receiveTunnelID;
|
||||
m_NextTunnelID = nextTunnelID;
|
||||
if (m_IsEndpoint)
|
||||
LogPrint ("TransitTunnel endpoint: ", m_TunnelID, " created");
|
||||
else if (m_IsGateway)
|
||||
LogPrint ("TransitTunnel gateway: ", m_TunnelID, " created");
|
||||
else
|
||||
LogPrint ("TransitTunnel: ",m_TunnelID,"->", m_NextTunnelID, " created");
|
||||
}
|
||||
|
||||
void TransitTunnel::Encrypt (uint8_t * payload)
|
||||
void TransitTunnel::EncryptTunnelMsg (I2NPMessage * tunnelMsg)
|
||||
{
|
||||
uint8_t * payload = tunnelMsg->GetPayload () + 4;
|
||||
m_ECBEncryption.SetKey (m_IVKey, 32);
|
||||
m_ECBEncryption.ProcessData(payload, payload, 16); // iv
|
||||
|
||||
m_CBCEncryption.SetKeyWithIV (m_LayerKey, 32, payload);
|
||||
m_CBCEncryption.ProcessData(payload + 16, payload + 16, 1008); // payload
|
||||
m_CBCEncryption.ProcessData(payload + 16, payload + 16, TUNNEL_DATA_ENCRYPTED_SIZE); // payload
|
||||
|
||||
m_ECBEncryption.SetKey (m_IVKey, 32);
|
||||
m_ECBEncryption.ProcessData(payload, payload, 16); // double iv encryption
|
||||
@ -45,41 +35,54 @@ namespace tunnel
|
||||
|
||||
void TransitTunnel::HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg)
|
||||
{
|
||||
Encrypt (tunnelMsg->GetPayload () + 4);
|
||||
EncryptTunnelMsg (tunnelMsg);
|
||||
|
||||
if (m_IsEndpoint)
|
||||
{
|
||||
LogPrint ("TransitTunnel endpoint for ", m_TunnelID);
|
||||
m_Endpoint.HandleDecryptedTunnelDataMsg (tunnelMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint ("TransitTunnel: ",m_TunnelID,"->", m_NextTunnelID);
|
||||
*(uint32_t *)(tunnelMsg->GetPayload ()) = htobe32 (m_NextTunnelID);
|
||||
FillI2NPMessageHeader (tunnelMsg, eI2NPTunnelData);
|
||||
|
||||
i2p::transports.SendMessage (m_NextIdent, tunnelMsg);
|
||||
}
|
||||
}
|
||||
|
||||
void TransitTunnel::SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, i2p::I2NPMessage * msg)
|
||||
{
|
||||
if (m_IsGateway)
|
||||
{
|
||||
m_Gateway.PutI2NPMsg (gwHash, gwTunnel, msg);
|
||||
auto tunnelMsgs = m_Gateway.GetTunnelDataMsgs (m_NextTunnelID);
|
||||
for (auto tunnelMsg : tunnelMsgs)
|
||||
{
|
||||
Encrypt (tunnelMsg->GetPayload () + 4);
|
||||
FillI2NPMessageHeader (tunnelMsg, eI2NPTunnelData);
|
||||
i2p::transports.SendMessage (m_NextIdent, tunnelMsg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint ("We are not a gateway for transit tunnel ", m_TunnelID);
|
||||
i2p::DeleteI2NPMessage (msg);
|
||||
}
|
||||
|
||||
void TransitTunnelGateway::SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, i2p::I2NPMessage * msg)
|
||||
{
|
||||
m_Gateway.SendTunnelDataMsg (gwHash, gwTunnel, msg);
|
||||
}
|
||||
|
||||
void TransitTunnelEndpoint::HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg)
|
||||
{
|
||||
EncryptTunnelMsg (tunnelMsg);
|
||||
|
||||
LogPrint ("TransitTunnel endpoint for ", GetTunnelID ());
|
||||
m_Endpoint.HandleDecryptedTunnelDataMsg (tunnelMsg);
|
||||
}
|
||||
|
||||
TransitTunnel * CreateTransitTunnel (uint32_t receiveTunnelID,
|
||||
const uint8_t * nextIdent, uint32_t nextTunnelID,
|
||||
const uint8_t * layerKey,const uint8_t * ivKey,
|
||||
bool isGateway, bool isEndpoint)
|
||||
{
|
||||
if (isEndpoint)
|
||||
{
|
||||
LogPrint ("TransitTunnel endpoint: ", receiveTunnelID, " created");
|
||||
return new TransitTunnelEndpoint (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey);
|
||||
}
|
||||
else if (isGateway)
|
||||
{
|
||||
LogPrint ("TransitTunnel gateway: ", receiveTunnelID, " created");
|
||||
return new TransitTunnelGateway (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint ("TransitTunnel: ", receiveTunnelID, "->", nextTunnelID, " created");
|
||||
return new TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,46 +7,78 @@
|
||||
#include "I2NPProtocol.h"
|
||||
#include "TunnelEndpoint.h"
|
||||
#include "TunnelGateway.h"
|
||||
#include "TunnelBase.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace tunnel
|
||||
{
|
||||
class TransitTunnel
|
||||
class TransitTunnel: public TunnelBase // tunnel patricipant
|
||||
{
|
||||
public:
|
||||
|
||||
TransitTunnel (uint32_t receiveTunnelID,
|
||||
const uint8_t * nextIdent, uint32_t nextTunnelID,
|
||||
const uint8_t * layerKey,const uint8_t * ivKey,
|
||||
bool isGateway, bool isEndpoint);
|
||||
const uint8_t * layerKey,const uint8_t * ivKey);
|
||||
|
||||
void HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg);
|
||||
void SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, i2p::I2NPMessage * msg);
|
||||
virtual void HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg);
|
||||
virtual void SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, i2p::I2NPMessage * msg);
|
||||
|
||||
uint32_t GetTunnelID () const { return m_TunnelID; };
|
||||
bool IsGateway () const { return m_IsGateway; };
|
||||
bool IsEndpoint () const { return m_IsEndpoint; };
|
||||
bool IsParticipant () const { return !IsGateway () && !IsEndpoint (); };
|
||||
|
||||
private:
|
||||
|
||||
void Encrypt (uint8_t * payload);
|
||||
// implements TunnelBase
|
||||
void EncryptTunnelMsg (I2NPMessage * tunnelMsg);
|
||||
uint32_t GetNextTunnelID () const { return m_NextTunnelID; };
|
||||
const i2p::data::IdentHash& GetNextIdentHash () const { return m_NextIdent; };
|
||||
|
||||
private:
|
||||
|
||||
uint32_t m_TunnelID, m_NextTunnelID;
|
||||
uint8_t m_NextIdent[32];
|
||||
i2p::data::IdentHash m_NextIdent;
|
||||
uint8_t m_LayerKey[32];
|
||||
uint8_t m_IVKey[32];
|
||||
bool m_IsGateway, m_IsEndpoint;
|
||||
|
||||
TunnelEndpoint m_Endpoint;
|
||||
TunnelGatewayBuffer m_Gateway;
|
||||
|
||||
CryptoPP::ECB_Mode<CryptoPP::AES>::Encryption m_ECBEncryption;
|
||||
CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption m_CBCEncryption;
|
||||
};
|
||||
|
||||
class TransitTunnelGateway: public TransitTunnel
|
||||
{
|
||||
public:
|
||||
|
||||
TransitTunnelGateway (uint32_t receiveTunnelID,
|
||||
const uint8_t * nextIdent, uint32_t nextTunnelID,
|
||||
const uint8_t * layerKey,const uint8_t * ivKey):
|
||||
TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID,
|
||||
layerKey, ivKey), m_Gateway(this) {};
|
||||
|
||||
void SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, i2p::I2NPMessage * msg);
|
||||
|
||||
private:
|
||||
|
||||
TunnelGateway m_Gateway;
|
||||
};
|
||||
|
||||
class TransitTunnelEndpoint: public TransitTunnel
|
||||
{
|
||||
public:
|
||||
|
||||
TransitTunnelEndpoint (uint32_t receiveTunnelID,
|
||||
const uint8_t * nextIdent, uint32_t nextTunnelID,
|
||||
const uint8_t * layerKey,const uint8_t * ivKey):
|
||||
TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey) {};
|
||||
|
||||
void HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg);
|
||||
|
||||
private:
|
||||
|
||||
TunnelEndpoint m_Endpoint;
|
||||
};
|
||||
|
||||
TransitTunnel * CreateTransitTunnel (uint32_t receiveTunnelID,
|
||||
const uint8_t * nextIdent, uint32_t nextTunnelID,
|
||||
const uint8_t * layerKey,const uint8_t * ivKey,
|
||||
bool isGateway, bool isEndpoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,16 +57,28 @@ namespace i2p
|
||||
}
|
||||
}
|
||||
|
||||
void Transports::Run ()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_Service.run ();
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
LogPrint ("Transports: ", ex.what ());
|
||||
}
|
||||
}
|
||||
|
||||
void Transports::AddNTCPSession (i2p::ntcp::NTCPSession * session)
|
||||
{
|
||||
if (session)
|
||||
m_NTCPSessions[std::string ((const char *)session->GetRemoteRouterInfo ().GetIdentHash (), 32)] = session;
|
||||
m_NTCPSessions[session->GetRemoteRouterInfo ().GetIdentHash ()] = session;
|
||||
}
|
||||
|
||||
void Transports::RemoveNTCPSession (i2p::ntcp::NTCPSession * session)
|
||||
{
|
||||
if (session)
|
||||
m_NTCPSessions.erase (std::string ((const char *)session->GetRemoteRouterInfo ().GetIdentHash (), 32));
|
||||
m_NTCPSessions.erase (session->GetRemoteRouterInfo ().GetIdentHash ());
|
||||
}
|
||||
|
||||
void Transports::HandleAccept (i2p::ntcp::NTCPServerConnection * conn, const boost::system::error_code& error)
|
||||
@ -94,17 +106,17 @@ namespace i2p
|
||||
return 0;
|
||||
}
|
||||
|
||||
i2p::ntcp::NTCPSession * Transports::FindNTCPSession (const uint8_t * ident)
|
||||
i2p::ntcp::NTCPSession * Transports::FindNTCPSession (const i2p::data::IdentHash& ident)
|
||||
{
|
||||
auto it = m_NTCPSessions.find (std::string ((const char *)ident,32));
|
||||
auto it = m_NTCPSessions.find (ident);
|
||||
if (it != m_NTCPSessions.end ())
|
||||
return it->second;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Transports::SendMessage (const uint8_t * ident, i2p::I2NPMessage * msg)
|
||||
void Transports::SendMessage (const i2p::data::IdentHash& ident, i2p::I2NPMessage * msg)
|
||||
{
|
||||
if (!memcmp (ident, i2p::context.GetRouterInfo ().GetIdentHash (), 32))
|
||||
if (ident == i2p::context.GetRouterInfo ().GetIdentHash ())
|
||||
// we send it to ourself
|
||||
i2p::HandleI2NPMessage (msg);
|
||||
else
|
||||
@ -117,7 +129,10 @@ namespace i2p
|
||||
{
|
||||
auto address = r->GetNTCPAddress ();
|
||||
if (address)
|
||||
{
|
||||
session = new i2p::ntcp::NTCPClient (m_Service, address->host.c_str (), address->port, *r);
|
||||
AddNTCPSession (session);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (session)
|
||||
|
11
Transports.h
11
Transports.h
@ -28,15 +28,14 @@ namespace i2p
|
||||
void RemoveNTCPSession (i2p::ntcp::NTCPSession * session);
|
||||
|
||||
i2p::ntcp::NTCPSession * GetNextNTCPSession ();
|
||||
i2p::ntcp::NTCPSession * FindNTCPSession (const uint8_t * ident);
|
||||
i2p::ntcp::NTCPSession * FindNTCPSession (const i2p::data::IdentHash& ident);
|
||||
|
||||
void SendMessage (const uint8_t * ident, i2p::I2NPMessage * msg);
|
||||
void SendMessage (const i2p::data::IdentHash& ident, i2p::I2NPMessage * msg);
|
||||
|
||||
private:
|
||||
|
||||
void Run () { m_Service.run (); };
|
||||
void HandleAccept (i2p::ntcp::NTCPServerConnection * conn,
|
||||
const boost::system::error_code& error);
|
||||
void Run ();
|
||||
void HandleAccept (i2p::ntcp::NTCPServerConnection * conn, const boost::system::error_code& error);
|
||||
|
||||
private:
|
||||
|
||||
@ -45,7 +44,7 @@ namespace i2p
|
||||
boost::asio::io_service::work m_Work;
|
||||
boost::asio::ip::tcp::acceptor * m_NTCPAcceptor;
|
||||
|
||||
std::map<std::string, i2p::ntcp::NTCPSession *> m_NTCPSessions;
|
||||
std::map<i2p::data::IdentHash, i2p::ntcp::NTCPSession *> m_NTCPSessions;
|
||||
};
|
||||
|
||||
extern Transports transports;
|
||||
|
@ -60,7 +60,7 @@ namespace tunnel
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<I2NPMessage *> TunnelGatewayBuffer::GetTunnelDataMsgs (uint32_t tunnelID)
|
||||
std::vector<I2NPMessage *> TunnelGatewayBuffer::GetTunnelDataMsgs ()
|
||||
{
|
||||
m_Remaining = 0;
|
||||
m_NextOffset = 0;
|
||||
@ -71,7 +71,7 @@ namespace tunnel
|
||||
int ind = 0;
|
||||
while (ind < cnt)
|
||||
{
|
||||
auto tunnelMsg = CreateNextTunnelMessage (tunnelID, ind);
|
||||
auto tunnelMsg = CreateNextTunnelMessage (ind);
|
||||
if (!tunnelMsg) break;
|
||||
res.push_back (tunnelMsg);
|
||||
}
|
||||
@ -139,7 +139,7 @@ namespace tunnel
|
||||
return ret;
|
||||
}
|
||||
|
||||
I2NPMessage * TunnelGatewayBuffer::CreateNextTunnelMessage (uint32_t tunnelID, int& ind)
|
||||
I2NPMessage * TunnelGatewayBuffer::CreateNextTunnelMessage (int& ind)
|
||||
{
|
||||
int cnt = m_I2NPMsgs.size ();
|
||||
if (ind > cnt - 1) return nullptr; // no more messages
|
||||
@ -166,7 +166,7 @@ namespace tunnel
|
||||
|
||||
I2NPMessage * tunnelMsg = NewI2NPMessage ();
|
||||
uint8_t * buf = tunnelMsg->GetPayload ();
|
||||
*(uint32_t *)(buf) = htobe32 (tunnelID);
|
||||
*(uint32_t *)(buf) = htobe32 (m_TunnelID);
|
||||
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
|
||||
rnd.GenerateBlock (buf + 4, 16); // original IV
|
||||
memcpy (buf + TUNNEL_DATA_MSG_SIZE, buf + 4, 16); // copy IV for checksum
|
||||
@ -219,12 +219,13 @@ namespace tunnel
|
||||
|
||||
void TunnelGateway::SendBuffer ()
|
||||
{
|
||||
auto tunnelMsgs = m_Buffer.GetTunnelDataMsgs (m_Tunnel->GetNextTunnelID ());
|
||||
auto tunnelMsgs = m_Buffer.GetTunnelDataMsgs ();
|
||||
for (auto tunnelMsg : tunnelMsgs)
|
||||
{
|
||||
m_Tunnel->EncryptTunnelMsg (tunnelMsg);
|
||||
FillI2NPMessageHeader (tunnelMsg, eI2NPTunnelData);
|
||||
i2p::transports.SendMessage (m_Tunnel->GetNextIdentHash (), tunnelMsg);
|
||||
m_NumSentBytes += TUNNEL_DATA_MSG_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,19 +20,20 @@ namespace tunnel
|
||||
|
||||
public:
|
||||
|
||||
TunnelGatewayBuffer (): m_Remaining (0) {};
|
||||
TunnelGatewayBuffer (uint32_t tunnelID): m_TunnelID (tunnelID), m_Remaining (0) {};
|
||||
|
||||
void PutI2NPMsg (const uint8_t * gwHash, uint32_t gwTunnel, I2NPMessage * msg);
|
||||
std::vector<I2NPMessage *> GetTunnelDataMsgs (uint32_t tunnelID);
|
||||
std::vector<I2NPMessage *> GetTunnelDataMsgs ();
|
||||
|
||||
private:
|
||||
|
||||
size_t CreateFirstFragment (TunnelMessageBlockExt * block, uint8_t * buf, size_t len);
|
||||
size_t CreateFollowOnFragment (TunnelMessageBlockExt * block, uint8_t * buf, size_t len);
|
||||
I2NPMessage * CreateNextTunnelMessage (uint32_t tunnelID, int& ind);
|
||||
I2NPMessage * CreateNextTunnelMessage (int& ind);
|
||||
|
||||
private:
|
||||
|
||||
uint32_t m_TunnelID;
|
||||
std::vector<TunnelMessageBlockExt *> m_I2NPMsgs;
|
||||
// for fragmented messages
|
||||
size_t m_NextOffset, m_NextSeqn, m_Remaining;
|
||||
@ -43,15 +44,18 @@ namespace tunnel
|
||||
{
|
||||
public:
|
||||
|
||||
TunnelGateway (TunnelBase * tunnel): m_Tunnel (tunnel) {};
|
||||
TunnelGateway (TunnelBase * tunnel):
|
||||
m_Tunnel (tunnel), m_Buffer (tunnel->GetNextTunnelID ()), m_NumSentBytes (0) {};
|
||||
void SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, i2p::I2NPMessage * msg);
|
||||
void PutTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, i2p::I2NPMessage * msg);
|
||||
void SendBuffer ();
|
||||
size_t GetNumSentBytes () const { return m_NumSentBytes; };
|
||||
|
||||
private:
|
||||
|
||||
TunnelBase * m_Tunnel;
|
||||
TunnelGatewayBuffer m_Buffer;
|
||||
size_t m_NumSentBytes;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user