Inroduced IdentHash

pull/6/head
orignal 11 years ago
parent fbbcc69c72
commit 885e996a8a

@ -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 ();
}
}
@ -467,7 +467,8 @@ 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));
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 ();
};
}
}

@ -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)

@ -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,40 +35,53 @@ namespace tunnel
void TransitTunnel::HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg)
{
Encrypt (tunnelMsg->GetPayload () + 4);
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);
EncryptTunnelMsg (tunnelMsg);
i2p::transports.SendMessage (m_NextIdent, tunnelMsg);
}
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)
{
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 (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
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 ("We are not a gateway for transit tunnel ", m_TunnelID);
i2p::DeleteI2NPMessage (msg);
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)

@ -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…
Cancel
Save