From c8a2ce47408b514e88842ccc56cc4943c07760d4 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 30 Apr 2014 14:08:57 -0400 Subject: [PATCH] handle TunnelBuild (8 records) message --- I2NPProtocol.cpp | 116 ++++++++++++++++++++++++++++++----------------- I2NPProtocol.h | 10 +++- 2 files changed, 83 insertions(+), 43 deletions(-) diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 0b34f9db..76f6e7d4 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -236,6 +236,41 @@ namespace i2p memcpy (record.toPeer, (const uint8_t *)router.GetIdentHash (), 16); } + bool HandleBuildRequestRecords (int num, I2NPBuildRequestRecordElGamalEncrypted * records, I2NPBuildRequestRecordClearText& clearText) + { + for (int i = 0; i < num; i++) + { + if (!memcmp (records[i].toPeer, (const uint8_t *)i2p::context.GetRouterInfo ().GetIdentHash (), 16)) + { + LogPrint ("Record ",i," is ours"); + + i2p::crypto::ElGamalDecrypt (i2p::context.GetPrivateKey (), records[i].encrypted, (uint8_t *)&clearText); + + i2p::tunnel::TransitTunnel * transitTunnel = + i2p::tunnel::CreateTransitTunnel ( + be32toh (clearText.receiveTunnel), + clearText.nextIdent, be32toh (clearText.nextTunnel), + clearText.layerKey, clearText.ivKey, + clearText.flag & 0x80, clearText.flag & 0x40); + i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); + // replace record to reply + I2NPBuildResponseRecord * reply = (I2NPBuildResponseRecord *)(records + i); + reply->ret = 0; + //TODO: fill filler + CryptoPP::SHA256().CalculateDigest(reply->hash, reply->padding, sizeof (reply->padding) + 1); // + 1 byte of ret + // encrypt reply + CryptoPP::CBC_Mode::Encryption encryption; + for (int j = 0; j < num; j++) + { + encryption.SetKeyWithIV (clearText.replyKey, 32, clearText.replyIV); + encryption.ProcessData((uint8_t *)(records + j), (uint8_t *)(records + j), sizeof (records[j])); + } + return true; + } + } + return false; + } + void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) { int num = buf[0]; @@ -260,52 +295,43 @@ namespace i2p else { I2NPBuildRequestRecordElGamalEncrypted * records = (I2NPBuildRequestRecordElGamalEncrypted *)(buf+1); - for (int i = 0; i < num; i++) - { - if (!memcmp (records[i].toPeer, (const uint8_t *)i2p::context.GetRouterInfo ().GetIdentHash (), 16)) - { - LogPrint ("Record ",i," is ours"); - - I2NPBuildRequestRecordClearText clearText; - i2p::crypto::ElGamalDecrypt (i2p::context.GetPrivateKey (), records[i].encrypted, (uint8_t *)&clearText); - - i2p::tunnel::TransitTunnel * transitTunnel = - i2p::tunnel::CreateTransitTunnel ( - be32toh (clearText.receiveTunnel), - clearText.nextIdent, be32toh (clearText.nextTunnel), - clearText.layerKey, clearText.ivKey, - clearText.flag & 0x80, clearText.flag & 0x40); - i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); - // replace record to reply - I2NPBuildResponseRecord * reply = (I2NPBuildResponseRecord *)(records + i); - reply->ret = 0; - //TODO: fill filler - CryptoPP::SHA256().CalculateDigest(reply->hash, reply->padding, sizeof (reply->padding) + 1); // + 1 byte of ret - // encrypt reply - CryptoPP::CBC_Mode::Encryption encryption; - for (int j = 0; j < num; j++) - { - encryption.SetKeyWithIV (clearText.replyKey, 32, clearText.replyIV); - encryption.ProcessData((uint8_t *)(records + j), (uint8_t *)(records + j), sizeof (records[j])); - } - - if (clearText.flag & 0x40) // we are endpoint of outboud tunnel - { - // so we send it to reply tunnel - i2p::transports.SendMessage (clearText.nextIdent, - CreateTunnelGatewayMsg (be32toh (clearText.nextTunnel), - eI2NPVariableTunnelBuildReply, buf, len, - be32toh (clearText.nextMessageID))); - } - else - i2p::transports.SendMessage (clearText.nextIdent, - CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len, be32toh (clearText.nextMessageID))); - return; + I2NPBuildRequestRecordClearText clearText; + if (HandleBuildRequestRecords (num, records, clearText)) + { + if (clearText.flag & 0x40) // we are endpoint of outboud tunnel + { + // so we send it to reply tunnel + i2p::transports.SendMessage (clearText.nextIdent, + CreateTunnelGatewayMsg (be32toh (clearText.nextTunnel), + eI2NPVariableTunnelBuildReply, buf, len, + be32toh (clearText.nextMessageID))); } + else + i2p::transports.SendMessage (clearText.nextIdent, + CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len, be32toh (clearText.nextMessageID))); } } } + 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 + i2p::transports.SendMessage (clearText.nextIdent, + CreateTunnelGatewayMsg (be32toh (clearText.nextTunnel), + eI2NPTunnelBuildReply, buf, len, + be32toh (clearText.nextMessageID))); + } + else + i2p::transports.SendMessage (clearText.nextIdent, + CreateI2NPMessage (eI2NPTunnelBuild, buf, len, be32toh (clearText.nextMessageID))); + } + } + void HandleVariableTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) { LogPrint ("VariableTunnelBuildReplyMsg replyMsgID=", replyMsgID); @@ -444,6 +470,14 @@ namespace i2p LogPrint ("VariableTunnelBuildReply"); HandleVariableTunnelBuildReplyMsg (msgID, buf, size); break; + case eI2NPTunnelBuild: + LogPrint ("TunnelBuild"); + HandleTunnelBuildMsg (buf, size); + break; + case eI2NPTunnelBuildReply: + LogPrint ("TunnelBuildReply"); + // TODO: + break; case eI2NPDatabaseLookup: LogPrint ("DatabaseLookup"); HandleDatabaseLookupMsg (buf, size); diff --git a/I2NPProtocol.h b/I2NPProtocol.h index 5e7900aa..0b6e45d4 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -87,10 +87,14 @@ namespace i2p eI2NPTunnelData = 18, eI2NPTunnelGateway = 19, eI2NPData = 20, + eI2NPTunnelBuild = 21, + eI2NPTunnelBuildReply = 22, eI2NPVariableTunnelBuild = 23, eI2NPVariableTunnelBuildReply = 24 }; + const int NUM_TUNNEL_BUILD_RECORDS = 8; + namespace tunnel { class InboundTunnel; @@ -164,10 +168,12 @@ namespace tunnel void EncryptBuildRequestRecord (const i2p::data::RouterInfo& router, const I2NPBuildRequestRecordClearText& clearText, I2NPBuildRequestRecordElGamalEncrypted& record); - + + bool HandleBuildRequestRecords (int num, I2NPBuildRequestRecordElGamalEncrypted * records, I2NPBuildRequestRecordClearText& clearText); void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len); void HandleVariableTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len); - + void HandleTunnelBuildMsg (uint8_t * buf, size_t len); + I2NPMessage * CreateTunnelDataMsg (const uint8_t * buf); I2NPMessage * CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload);