void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) { int num = buf[0]; LogPrint (eLogDebug, "I2NP: VariableTunnelBuild ", num, " records"); if (len < num*BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 1) { LogPrint (eLogError, "VaribleTunnelBuild message of ", num, " records is too short ", len); return; } auto tunnel = i2p::tunnel::tunnels.GetPendingInboundTunnel (replyMsgID); if (tunnel) { // endpoint of inbound tunnel LogPrint (eLogDebug, "I2NP: VariableTunnelBuild reply for tunnel ", tunnel->GetTunnelID ()); if (tunnel->HandleTunnelBuildResponse (buf, len)) { LogPrint (eLogInfo, "I2NP: Inbound tunnel ", tunnel->GetTunnelID (), " has been created"); tunnel->SetState (i2p::tunnel::eTunnelStateEstablished); i2p::tunnel::tunnels.AddInboundTunnel (tunnel); } else { LogPrint (eLogInfo, "I2NP: Inbound tunnel ", tunnel->GetTunnelID (), " has been declined"); tunnel->SetState (i2p::tunnel::eTunnelStateBuildFailed); } } else { uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; if (HandleBuildRequestRecords (num, buf + 1, clearText)) { if (clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x40) // we are endpoint of outboud tunnel { // so we send it to reply tunnel transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), eI2NPVariableTunnelBuildReply, buf, len, bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); } else transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len, bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); } } }
std::shared_ptr<I2NPMessage> CreateTunnelGatewayMsg (uint32_t tunnelID, std::shared_ptr<I2NPMessage> msg) { if (msg->offset >= I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE) { // message is capable to be used without copying uint8_t * payload = msg->GetBuffer () - TUNNEL_GATEWAY_HEADER_SIZE; htobe32buf (payload + TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET, tunnelID); int len = msg->GetLength (); htobe16buf (payload + TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET, len); msg->offset -= (I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE); msg->len = msg->offset + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE +len; msg->FillI2NPMessageHeader (eI2NPTunnelGateway); return msg; } else return CreateTunnelGatewayMsg (tunnelID, msg->GetBuffer (), msg->GetLength ()); }
void HandleTunnelBuildMsg (uint8_t * buf, size_t len) { I2NPBuildRequestRecordClearText clearText; if (HandleBuildRequestRecords (NUM_TUNNEL_BUILD_RECORDS, (I2NPBuildRequestRecordElGamalEncrypted *)buf, clearText)) { if (clearText.flag & 0x40) // we are endpoint of outbound tunnel { // so we send it to reply tunnel transports.SendMessage (clearText.nextIdent, CreateTunnelGatewayMsg (be32toh (clearText.nextTunnel), eI2NPTunnelBuildReply, buf, len, be32toh (clearText.nextMessageID))); } else transports.SendMessage (clearText.nextIdent, CreateI2NPMessage (eI2NPTunnelBuild, buf, len, be32toh (clearText.nextMessageID))); } }
void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) { int num = buf[0]; LogPrint ("VariableTunnelBuild ", num, " records"); i2p::tunnel::Tunnel * tunnel = i2p::tunnel::tunnels.GetPendingTunnel (replyMsgID); if (tunnel) { // endpoint of inbound tunnel LogPrint ("VariableTunnelBuild reply for tunnel ", tunnel->GetTunnelID ()); if (tunnel->HandleTunnelBuildResponse (buf, len)) { LogPrint ("Inbound tunnel ", tunnel->GetTunnelID (), " has been created"); tunnel->SetState (i2p::tunnel::eTunnelStateEstablished); i2p::tunnel::tunnels.AddInboundTunnel (static_cast<i2p::tunnel::InboundTunnel *>(tunnel)); } else { LogPrint ("Inbound tunnel ", tunnel->GetTunnelID (), " has been declined"); tunnel->SetState (i2p::tunnel::eTunnelStateBuildFailed); } } else { I2NPBuildRequestRecordElGamalEncrypted * records = (I2NPBuildRequestRecordElGamalEncrypted *)(buf+1); I2NPBuildRequestRecordClearText clearText; if (HandleBuildRequestRecords (num, records, clearText)) { if (clearText.flag & 0x40) // we are endpoint of outboud tunnel { // so we send it to reply tunnel transports.SendMessage (clearText.nextIdent, CreateTunnelGatewayMsg (be32toh (clearText.nextTunnel), eI2NPVariableTunnelBuildReply, buf, len, be32toh (clearText.nextMessageID))); } else transports.SendMessage (clearText.nextIdent, CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len, be32toh (clearText.nextMessageID))); } } }
I2NPMessage * CreateTunnelGatewayMsg (uint32_t tunnelID, I2NPMessage * msg) { if (msg->offset >= sizeof (I2NPHeader) + sizeof (TunnelGatewayHeader)) { // message is capable to be used without copying TunnelGatewayHeader * header = (TunnelGatewayHeader *)(msg->GetBuffer () - sizeof (TunnelGatewayHeader)); header->tunnelID = htobe32 (tunnelID); int len = msg->GetLength (); header->length = htobe16 (len); msg->offset -= (sizeof (I2NPHeader) + sizeof (TunnelGatewayHeader)); msg->len = msg->offset + sizeof (I2NPHeader) + sizeof (TunnelGatewayHeader) +len; FillI2NPMessageHeader (msg, eI2NPTunnelGateway); return msg; } else { I2NPMessage * msg1 = CreateTunnelGatewayMsg (tunnelID, msg->GetBuffer (), msg->GetLength ()); DeleteI2NPMessage (msg); return msg1; } }
void HandleTunnelBuildMsg (uint8_t * buf, size_t len) { if (len < NUM_TUNNEL_BUILD_RECORDS*BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE) { LogPrint (eLogError, "TunnelBuild message is too short ", len); return; } uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; if (HandleBuildRequestRecords (NUM_TUNNEL_BUILD_RECORDS, buf, clearText)) { if (clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x40) // we are endpoint of outbound tunnel { // so we send it to reply tunnel transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), eI2NPTunnelBuildReply, buf, len, bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); } else transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, CreateI2NPMessage (eI2NPTunnelBuild, buf, len, bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); } }