diff --git a/LeaseSet.h b/LeaseSet.h index 0d5afff0..d03aa61f 100644 --- a/LeaseSet.h +++ b/LeaseSet.h @@ -2,12 +2,14 @@ #define LEASE_SET_H__ #include +#include #include 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 m_Leases; - uint8_t m_IdentHash[32]; + IdentHash m_IdentHash; uint8_t m_EncryptionKey[256]; }; } diff --git a/NTCPSession.cpp b/NTCPSession.cpp index fa5a36b0..24d5ac0e 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -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 } } } diff --git a/NTCPSession.h b/NTCPSession.h index 226ec14e..c8b4aea5 100644 --- a/NTCPSession.h +++ b/NTCPSession.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -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::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 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 (); }; } } diff --git a/NetDb.cpp b/NetDb.cpp index 10644137..ae987d4b 100644 --- a/NetDb.cpp +++ b/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) diff --git a/NetDb.h b/NetDb.h index 5bbd179b..c76bd9f7 100644 --- a/NetDb.h +++ b/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 m_LeaseSets; - std::map m_RouterInfos; + std::map m_LeaseSets; + std::map m_RouterInfos; bool m_IsRunning; std::thread * m_Thread; diff --git a/RouterInfo.h b/RouterInfo.h index 4507ce17..ed947ab9 100644 --- a/RouterInfo.h +++ b/RouterInfo.h @@ -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
& 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; diff --git a/TransitTunnel.cpp b/TransitTunnel.cpp index bd50ae92..2ead9e77 100644 --- a/TransitTunnel.cpp +++ b/TransitTunnel.cpp @@ -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); } } } diff --git a/TransitTunnel.h b/TransitTunnel.h index 8253b47f..2109ee31 100644 --- a/TransitTunnel.h +++ b/TransitTunnel.h @@ -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::Encryption m_ECBEncryption; CryptoPP::CBC_Mode::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); } } diff --git a/Transports.cpp b/Transports.cpp index e5210184..e938c85b 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -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) diff --git a/Transports.h b/Transports.h index ea5a8057..90b1704a 100644 --- a/Transports.h +++ b/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 m_NTCPSessions; + std::map m_NTCPSessions; }; extern Transports transports; diff --git a/TunnelGateway.cpp b/TunnelGateway.cpp index 507beae4..d70763e6 100644 --- a/TunnelGateway.cpp +++ b/TunnelGateway.cpp @@ -60,7 +60,7 @@ namespace tunnel } } - std::vector TunnelGatewayBuffer::GetTunnelDataMsgs (uint32_t tunnelID) + std::vector 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; } } } diff --git a/TunnelGateway.h b/TunnelGateway.h index b8db1e80..9c679888 100644 --- a/TunnelGateway.h +++ b/TunnelGateway.h @@ -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 GetTunnelDataMsgs (uint32_t tunnelID); + std::vector 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 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; }; } }