Browse Source

handle TunnelBuild (8 records) message

pull/72/head
orignal 11 years ago
parent
commit
c8a2ce4740
  1. 116
      I2NPProtocol.cpp
  2. 10
      I2NPProtocol.h

116
I2NPProtocol.cpp

@ -236,6 +236,41 @@ namespace i2p
memcpy (record.toPeer, (const uint8_t *)router.GetIdentHash (), 16); 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<CryptoPP::AES>::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) void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len)
{ {
int num = buf[0]; int num = buf[0];
@ -260,52 +295,43 @@ namespace i2p
else else
{ {
I2NPBuildRequestRecordElGamalEncrypted * records = (I2NPBuildRequestRecordElGamalEncrypted *)(buf+1); I2NPBuildRequestRecordElGamalEncrypted * records = (I2NPBuildRequestRecordElGamalEncrypted *)(buf+1);
for (int i = 0; i < num; i++) I2NPBuildRequestRecordClearText clearText;
{ if (HandleBuildRequestRecords (num, records, clearText))
if (!memcmp (records[i].toPeer, (const uint8_t *)i2p::context.GetRouterInfo ().GetIdentHash (), 16)) {
{ if (clearText.flag & 0x40) // we are endpoint of outboud tunnel
LogPrint ("Record ",i," is ours"); {
// so we send it to reply tunnel
I2NPBuildRequestRecordClearText clearText; i2p::transports.SendMessage (clearText.nextIdent,
i2p::crypto::ElGamalDecrypt (i2p::context.GetPrivateKey (), records[i].encrypted, (uint8_t *)&clearText); CreateTunnelGatewayMsg (be32toh (clearText.nextTunnel),
eI2NPVariableTunnelBuildReply, buf, len,
i2p::tunnel::TransitTunnel * transitTunnel = be32toh (clearText.nextMessageID)));
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<CryptoPP::AES>::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;
} }
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) void HandleVariableTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len)
{ {
LogPrint ("VariableTunnelBuildReplyMsg replyMsgID=", replyMsgID); LogPrint ("VariableTunnelBuildReplyMsg replyMsgID=", replyMsgID);
@ -444,6 +470,14 @@ namespace i2p
LogPrint ("VariableTunnelBuildReply"); LogPrint ("VariableTunnelBuildReply");
HandleVariableTunnelBuildReplyMsg (msgID, buf, size); HandleVariableTunnelBuildReplyMsg (msgID, buf, size);
break; break;
case eI2NPTunnelBuild:
LogPrint ("TunnelBuild");
HandleTunnelBuildMsg (buf, size);
break;
case eI2NPTunnelBuildReply:
LogPrint ("TunnelBuildReply");
// TODO:
break;
case eI2NPDatabaseLookup: case eI2NPDatabaseLookup:
LogPrint ("DatabaseLookup"); LogPrint ("DatabaseLookup");
HandleDatabaseLookupMsg (buf, size); HandleDatabaseLookupMsg (buf, size);

10
I2NPProtocol.h

@ -87,10 +87,14 @@ namespace i2p
eI2NPTunnelData = 18, eI2NPTunnelData = 18,
eI2NPTunnelGateway = 19, eI2NPTunnelGateway = 19,
eI2NPData = 20, eI2NPData = 20,
eI2NPTunnelBuild = 21,
eI2NPTunnelBuildReply = 22,
eI2NPVariableTunnelBuild = 23, eI2NPVariableTunnelBuild = 23,
eI2NPVariableTunnelBuildReply = 24 eI2NPVariableTunnelBuildReply = 24
}; };
const int NUM_TUNNEL_BUILD_RECORDS = 8;
namespace tunnel namespace tunnel
{ {
class InboundTunnel; class InboundTunnel;
@ -164,10 +168,12 @@ namespace tunnel
void EncryptBuildRequestRecord (const i2p::data::RouterInfo& router, void EncryptBuildRequestRecord (const i2p::data::RouterInfo& router,
const I2NPBuildRequestRecordClearText& clearText, const I2NPBuildRequestRecordClearText& clearText,
I2NPBuildRequestRecordElGamalEncrypted& record); I2NPBuildRequestRecordElGamalEncrypted& record);
bool HandleBuildRequestRecords (int num, I2NPBuildRequestRecordElGamalEncrypted * records, I2NPBuildRequestRecordClearText& clearText);
void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len); void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len);
void HandleVariableTunnelBuildReplyMsg (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 (const uint8_t * buf);
I2NPMessage * CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload); I2NPMessage * CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload);

Loading…
Cancel
Save