diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index c15ff95a..d0466e75 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -465,35 +465,6 @@ namespace i2p FillI2NPMessageHeader (msg, eI2NPTunnelGateway); // gateway message return msg; } - - void HandleTunnelGatewayMsg (I2NPMessage * msg) - { - const uint8_t * payload = msg->GetPayload (); - uint32_t tunnelID = bufbe32toh(payload + TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET); - uint16_t len = bufbe16toh(payload + TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET); - // we make payload as new I2NP message to send - msg->offset += I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE; - msg->len = msg->offset + len; - auto typeID = msg->GetTypeID (); - LogPrint ("TunnelGateway of ", (int)len, " bytes for tunnel ", (unsigned int)tunnelID, ". Msg type ", (int)typeID); - - if (typeID == eI2NPDatabaseStore || typeID == eI2NPDatabaseSearchReply) - { - // transit DatabaseStore my contain new/updated RI - // or DatabaseSearchReply with new routers - auto ds = NewI2NPMessage (); - *ds = *msg; - i2p::data::netdb.PostI2NPMsg (ds); - } - i2p::tunnel::TransitTunnel * tunnel = i2p::tunnel::tunnels.GetTransitTunnel (tunnelID); - if (tunnel) - tunnel->SendTunnelDataMsg (msg); - else - { - LogPrint ("Tunnel ", (unsigned int)tunnelID, " not found"); - i2p::DeleteI2NPMessage (msg); - } - } size_t GetI2NPMessageLength (const uint8_t * msg) { @@ -543,7 +514,7 @@ namespace i2p break; case eI2NPTunnelGateway: LogPrint ("TunnelGateway"); - HandleTunnelGatewayMsg (msg); + i2p::tunnel::tunnels.PostTunnelData (msg); break; case eI2NPGarlic: LogPrint ("Garlic"); diff --git a/I2NPProtocol.h b/I2NPProtocol.h index f5509cbd..137f649f 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -207,7 +207,6 @@ namespace tunnel I2NPMessage * CreateTunnelDataMsg (const uint8_t * buf); I2NPMessage * CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload); - void HandleTunnelGatewayMsg (I2NPMessage * msg); I2NPMessage * CreateTunnelGatewayMsg (uint32_t tunnelID, const uint8_t * buf, size_t len); I2NPMessage * CreateTunnelGatewayMsg (uint32_t tunnelID, I2NPMessageType msgType, const uint8_t * buf, size_t len, uint32_t replyMsgID = 0); diff --git a/TransitTunnel.h b/TransitTunnel.h index 93b72034..1ac3be93 100644 --- a/TransitTunnel.h +++ b/TransitTunnel.h @@ -22,12 +22,12 @@ namespace tunnel const uint8_t * nextIdent, uint32_t nextTunnelID, const uint8_t * layerKey,const uint8_t * ivKey); - virtual void SendTunnelDataMsg (i2p::I2NPMessage * msg); virtual size_t GetNumTransmittedBytes () const { return 0; }; uint32_t GetTunnelID () const { return m_TunnelID; }; // implements TunnelBase + void SendTunnelDataMsg (i2p::I2NPMessage * msg); void HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg); void EncryptTunnelMsg (I2NPMessage * tunnelMsg); uint32_t GetNextTunnelID () const { return m_NextTunnelID; }; diff --git a/Tunnel.cpp b/Tunnel.cpp index 8ce376a4..efa0e8db 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -150,7 +150,13 @@ namespace tunnel hop = hop->prev; } } - + + void Tunnel::SendTunnelDataMsg (i2p::I2NPMessage * msg) + { + LogPrint (eLogInfo, "Can't send I2NP messages without delivery instructions"); + DeleteI2NPMessage (msg); + } + void InboundTunnel::HandleTunnelDataMsg (I2NPMessage * msg) { if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive @@ -349,6 +355,7 @@ namespace tunnel I2NPMessage * msg = m_Queue.GetNextWithTimeout (1000); // 1 sec if (msg) { + uint8_t typeID = msg->GetTypeID (); uint32_t prevTunnelID = 0; TunnelBase * prevTunnel = nullptr; do @@ -360,12 +367,17 @@ namespace tunnel else if (prevTunnel) prevTunnel->FlushTunnelDataMsgs (); - if (!tunnel) + if (!tunnel && typeID == eI2NPTunnelData) tunnel = GetInboundTunnel (tunnelID); if (!tunnel) tunnel = GetTransitTunnel (tunnelID); if (tunnel) - tunnel->HandleTunnelDataMsg (msg); + { + if (typeID == eI2NPTunnelData) + tunnel->HandleTunnelDataMsg (msg); + else // tunnel gateway assumed + HandleTunnelGatewayMsg (tunnel, msg); + } else { LogPrint ("Tunnel ", tunnelID, " not found"); @@ -398,6 +410,33 @@ namespace tunnel } } + void Tunnels::HandleTunnelGatewayMsg (TunnelBase * tunnel, I2NPMessage * msg) + { + if (!tunnel) + { + LogPrint (eLogError, "Missing tunnel for TunnelGateway"); + i2p::DeleteI2NPMessage (msg); + return; + } + const uint8_t * payload = msg->GetPayload (); + uint16_t len = bufbe16toh(payload + TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET); + // we make payload as new I2NP message to send + msg->offset += I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE; + msg->len = msg->offset + len; + auto typeID = msg->GetTypeID (); + LogPrint (eLogDebug, "TunnelGateway of ", (int)len, " bytes for tunnel ", tunnel->GetTunnelID (), ". Msg type ", (int)typeID); + + if (typeID == eI2NPDatabaseStore || typeID == eI2NPDatabaseSearchReply) + { + // transit DatabaseStore my contain new/updated RI + // or DatabaseSearchReply with new routers + auto ds = NewI2NPMessage (); + *ds = *msg; + i2p::data::netdb.PostI2NPMsg (ds); + } + tunnel->SendTunnelDataMsg (msg); + } + void Tunnels::ManageTunnels () { ManagePendingTunnels (); diff --git a/Tunnel.h b/Tunnel.h index 4925df18..6f7cf709 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -61,6 +61,7 @@ namespace tunnel bool HandleTunnelBuildResponse (uint8_t * msg, size_t len); // implements TunnelBase + void SendTunnelDataMsg (i2p::I2NPMessage * msg); void EncryptTunnelMsg (I2NPMessage * tunnelMsg); uint32_t GetNextTunnelID () const { return m_Config->GetFirstHop ()->tunnelID; }; const i2p::data::IdentHash& GetNextIdentHash () const { return m_Config->GetFirstHop ()->router->GetIdentHash (); }; @@ -139,6 +140,8 @@ namespace tunnel private: + void HandleTunnelGatewayMsg (TunnelBase * tunnel, I2NPMessage * msg); + void Run (); void ManageTunnels (); void ManageOutboundTunnels (); diff --git a/TunnelBase.h b/TunnelBase.h index 8be6302c..dbb9c361 100644 --- a/TunnelBase.h +++ b/TunnelBase.h @@ -37,6 +37,7 @@ namespace tunnel virtual ~TunnelBase () {}; virtual void HandleTunnelDataMsg (i2p::I2NPMessage * tunnelMsg) = 0; + virtual void SendTunnelDataMsg (i2p::I2NPMessage * msg) = 0; virtual void FlushTunnelDataMsgs () {}; virtual void EncryptTunnelMsg (I2NPMessage * tunnelMsg) = 0; virtual uint32_t GetNextTunnelID () const = 0;