mirror of https://github.com/PurpleI2P/i2pd.git
orignal
11 years ago
2 changed files with 485 additions and 0 deletions
@ -0,0 +1,358 @@ |
|||||||
|
#include <string.h> |
||||||
|
#include <endian.h> |
||||||
|
#include <cryptopp/gzip.h> |
||||||
|
#include <cryptopp/sha.h> |
||||||
|
#include <cryptopp/modes.h> |
||||||
|
#include <cryptopp/aes.h> |
||||||
|
#include "ElGamal.h" |
||||||
|
#include "Timestamp.h" |
||||||
|
#include "RouterContext.h" |
||||||
|
#include "NetDb.h" |
||||||
|
#include "Tunnel.h" |
||||||
|
#include "base64.h" |
||||||
|
#include "Transports.h" |
||||||
|
#include "I2NPProtocol.h" |
||||||
|
|
||||||
|
namespace i2p |
||||||
|
{ |
||||||
|
|
||||||
|
I2NPMessage * NewI2NPMessage () |
||||||
|
{ |
||||||
|
I2NPMessage * msg = new I2NPMessage; |
||||||
|
msg->offset = 0; |
||||||
|
msg->len = sizeof (I2NPHeader); |
||||||
|
return msg; |
||||||
|
} |
||||||
|
|
||||||
|
void DeleteI2NPMessage (I2NPMessage * msg) |
||||||
|
{ |
||||||
|
delete msg; |
||||||
|
} |
||||||
|
|
||||||
|
void FillI2NPMessageHeader (I2NPMessage * msg, I2NPMessageType msgType, uint32_t replyMsgID) |
||||||
|
{ |
||||||
|
static uint32_t msgID = 0; |
||||||
|
I2NPHeader * header = msg->GetHeader (); |
||||||
|
header->typeID = msgType; |
||||||
|
if (replyMsgID) // for tunnel creation
|
||||||
|
header->msgID = htobe32 (replyMsgID); |
||||||
|
else |
||||||
|
{ |
||||||
|
header->msgID = htobe32 (msgID); |
||||||
|
msgID++; |
||||||
|
} |
||||||
|
header->expiration = htobe64 (i2p::util::GetMillisecondsSinceEpoch () + 5000); // TODO: 5 secs is a magic number
|
||||||
|
int len = msg->len - sizeof (I2NPHeader); |
||||||
|
header->size = htobe16 (len); |
||||||
|
uint8_t hash[32]; |
||||||
|
CryptoPP::SHA256().CalculateDigest(hash, msg->GetPayload (), len); |
||||||
|
header->chks = hash[0]; |
||||||
|
} |
||||||
|
|
||||||
|
I2NPMessage * CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID) |
||||||
|
{ |
||||||
|
I2NPMessage * msg = NewI2NPMessage (); |
||||||
|
memcpy (msg->GetPayload (), buf, len); |
||||||
|
msg->len += len; |
||||||
|
FillI2NPMessageHeader (msg, msgType, replyMsgID); |
||||||
|
return msg; |
||||||
|
} |
||||||
|
|
||||||
|
I2NPMessage * CreateDeliveryStatusMsg () |
||||||
|
{ |
||||||
|
#pragma pack(1) |
||||||
|
struct |
||||||
|
{ |
||||||
|
uint32_t msgID; |
||||||
|
uint64_t timestamp; |
||||||
|
} msg; |
||||||
|
#pragma pack () |
||||||
|
|
||||||
|
msg.msgID = 0; |
||||||
|
msg.timestamp = htobe64 (i2p::util::GetMillisecondsSinceEpoch ()); |
||||||
|
return CreateI2NPMessage (eI2NPDeliveryStatus, (uint8_t *)&msg, sizeof (msg)); |
||||||
|
} |
||||||
|
|
||||||
|
I2NPMessage * CreateDatabaseLookupMsg (const uint8_t * key, const uint8_t * from, uint32_t replyTunnelID) |
||||||
|
{ |
||||||
|
#pragma pack(1) |
||||||
|
struct |
||||||
|
{ |
||||||
|
uint8_t key[32]; |
||||||
|
uint8_t from[32]; |
||||||
|
uint8_t flags; |
||||||
|
uint32_t replyTunnelID; |
||||||
|
uint16_t size; |
||||||
|
} msg; |
||||||
|
#pragma pack () |
||||||
|
|
||||||
|
memcpy (msg.key, key, 32); |
||||||
|
memcpy (msg.from, from, 32); |
||||||
|
msg.flags = replyTunnelID ? 0x01 : 0; |
||||||
|
msg.replyTunnelID = htobe32 (replyTunnelID); |
||||||
|
msg.size = 0; |
||||||
|
return CreateI2NPMessage (eI2NPDatabaseLookup, (uint8_t *)&msg, sizeof (msg)); |
||||||
|
} |
||||||
|
|
||||||
|
I2NPMessage * CreateDatabaseStoreMsg () |
||||||
|
{ |
||||||
|
I2NPMessage * m = NewI2NPMessage (); |
||||||
|
I2NPDatabaseStoreMsg * msg = (I2NPDatabaseStoreMsg *)m->GetPayload (); |
||||||
|
|
||||||
|
memcpy (msg->key, context.GetRouterInfo ().GetIdentHash (), 32); |
||||||
|
msg->type = 0; |
||||||
|
msg->replyToken = 0; |
||||||
|
msg->size = 0; |
||||||
|
|
||||||
|
CryptoPP::Gzip compressor; |
||||||
|
compressor.Put ((uint8_t *)context.GetRouterInfo ().GetBuffer (), context.GetRouterInfo ().GetBufferLen ()); |
||||||
|
compressor.MessageEnd(); |
||||||
|
int size = compressor.MaxRetrievable (); |
||||||
|
msg->size = htobe16 (size); |
||||||
|
uint8_t * buf = m->GetPayload () + sizeof (I2NPDatabaseStoreMsg); |
||||||
|
compressor.Get (buf, size); |
||||||
|
m->len += sizeof (I2NPDatabaseStoreMsg) + size; // payload size
|
||||||
|
FillI2NPMessageHeader (m, eI2NPDatabaseStore); |
||||||
|
|
||||||
|
return m; |
||||||
|
} |
||||||
|
|
||||||
|
void HandleDatabaseStoreMsg (uint8_t * buf, size_t len) |
||||||
|
{ |
||||||
|
I2NPDatabaseStoreMsg * msg = (I2NPDatabaseStoreMsg *)buf; |
||||||
|
if (msg->type) |
||||||
|
{ |
||||||
|
LogPrint ("LeaseSet"); |
||||||
|
i2p::data::netdb.AddLeaseSet (buf + sizeof (I2NPDatabaseStoreMsg)-2, len - sizeof (I2NPDatabaseStoreMsg)+2); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
LogPrint ("RouterInfo"); |
||||||
|
CryptoPP::Gunzip decompressor; |
||||||
|
decompressor.Put (buf + sizeof (I2NPDatabaseStoreMsg), be16toh (msg->size)); |
||||||
|
decompressor.MessageEnd(); |
||||||
|
uint8_t uncompressed[1024]; |
||||||
|
int size = decompressor.MaxRetrievable (); |
||||||
|
decompressor.Get (uncompressed, size); |
||||||
|
i2p::data::netdb.AddRouterInfo (uncompressed, size); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void HandleDatabaseSearchReplyMsg (uint8_t * buf, size_t len) |
||||||
|
{ |
||||||
|
#pragma pack(1) |
||||||
|
struct |
||||||
|
{ |
||||||
|
uint8_t key[32]; |
||||||
|
uint8_t num; |
||||||
|
} * msg; |
||||||
|
#pragma pack() |
||||||
|
msg = (decltype(msg))buf; |
||||||
|
char key[48]; |
||||||
|
int l = i2p::data::ByteStreamToBase64 (msg->key, 32, key, 48); |
||||||
|
key[l] = 0; |
||||||
|
LogPrint ("DatabaseSearchReply for ", key, " num=", (int)msg->num); |
||||||
|
for (int i = 0; i < msg->num; i++) |
||||||
|
{ |
||||||
|
char peerHash[48]; |
||||||
|
int l1 = i2p::data::ByteStreamToBase64 (buf + sizeof (*msg) +i*32, 32, peerHash, 48); |
||||||
|
peerHash[l1] = 0; |
||||||
|
LogPrint (i,": ", peerHash); |
||||||
|
|
||||||
|
i2p::data::netdb.RequestDestination (msg->key, buf + sizeof (*msg) +i*32); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
I2NPBuildRequestRecordClearText CreateBuildRequestRecord ( |
||||||
|
const uint8_t * ourIdent, uint32_t receiveTunnelID, |
||||||
|
const uint8_t * nextIdent, uint32_t nextTunnelID, |
||||||
|
const uint8_t * layerKey,const uint8_t * ivKey, |
||||||
|
const uint8_t * replyKey, const uint8_t * replyIV, uint32_t nextMessageID, |
||||||
|
bool isGateway, bool isEndpoint) |
||||||
|
{ |
||||||
|
I2NPBuildRequestRecordClearText clearText; |
||||||
|
clearText.receiveTunnel = htobe32 (receiveTunnelID); |
||||||
|
clearText.nextTunnel = htobe32(nextTunnelID); |
||||||
|
memcpy (clearText.layerKey, layerKey, 32); |
||||||
|
memcpy (clearText.ivKey, ivKey, 32); |
||||||
|
memcpy (clearText.replyKey, replyKey, 32); |
||||||
|
memcpy (clearText.replyIV, replyIV, 16); |
||||||
|
clearText.flag = 0; |
||||||
|
if (isGateway) clearText.flag |= 0x80; |
||||||
|
if (isEndpoint) clearText.flag |= 0x40; |
||||||
|
memcpy (clearText.ourIdent, ourIdent, 32); |
||||||
|
memcpy (clearText.nextIdent, nextIdent, 32); |
||||||
|
clearText.requestTime = i2p::util::GetHoursSinceEpoch (); |
||||||
|
clearText.nextMessageID = htobe32(nextMessageID); |
||||||
|
return clearText; |
||||||
|
} |
||||||
|
|
||||||
|
void EncryptBuildRequestRecord (const i2p::data::RouterInfo& router, |
||||||
|
const I2NPBuildRequestRecordClearText& clearText, |
||||||
|
I2NPBuildRequestRecordElGamalEncrypted& record) |
||||||
|
{ |
||||||
|
i2p::crypto::ElGamalEncrypt (router.GetRouterIdentity ().publicKey, (uint8_t *)&clearText, sizeof(clearText), record.encrypted); |
||||||
|
memcpy (record.toPeer, router.GetIdentHash (), 16); |
||||||
|
} |
||||||
|
|
||||||
|
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) |
||||||
|
{ |
||||||
|
LogPrint ("VariableTunnelBuild reply for tunnel ", tunnel->GetTunnelID ()); |
||||||
|
tunnel->HandleVariableTunnelBuildReplyMsg (buf, len); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
I2NPBuildRequestRecordElGamalEncrypted * records = (I2NPBuildRequestRecordElGamalEncrypted *)(buf+1); |
||||||
|
for (int i = 0; i < num; i++) |
||||||
|
{ |
||||||
|
if (!memcmp (records[i].toPeer, 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 = |
||||||
|
new i2p::tunnel::TransitTunnel ( |
||||||
|
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])); |
||||||
|
} |
||||||
|
|
||||||
|
i2p::transports.SendMessage (clearText.nextIdent, |
||||||
|
CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len, be32toh (clearText.nextMessageID))); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void HandleVariableTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) |
||||||
|
{ |
||||||
|
LogPrint ("VariableTunnelBuildReplyMsg replyMsgID=", replyMsgID); |
||||||
|
i2p::tunnel::Tunnel * tunnel = i2p::tunnel::tunnels.GetPendingTunnel (replyMsgID); |
||||||
|
if (tunnel) |
||||||
|
{ |
||||||
|
tunnel->HandleVariableTunnelBuildReplyMsg (buf, len); |
||||||
|
LogPrint ("Tunnel ", tunnel->GetTunnelID (), " has been created"); |
||||||
|
} |
||||||
|
else |
||||||
|
LogPrint ("Pending tunnel for message ", replyMsgID, " not found"); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
I2NPMessage * CreateTunnelDataMsg (const uint8_t * buf) |
||||||
|
{ |
||||||
|
I2NPMessage * msg = NewI2NPMessage (); |
||||||
|
memcpy (msg->GetPayload (), buf, 1028); |
||||||
|
msg->len += 1028; |
||||||
|
FillI2NPMessageHeader (msg, eI2NPTunnelData); |
||||||
|
return msg; |
||||||
|
} |
||||||
|
|
||||||
|
I2NPMessage * CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload) |
||||||
|
{ |
||||||
|
I2NPMessage * msg = NewI2NPMessage (); |
||||||
|
memcpy (msg->GetPayload () + 4, payload, 1024); |
||||||
|
*(uint32_t *)(msg->GetPayload ()) = htobe32 (tunnelID); |
||||||
|
msg->len += 1028; |
||||||
|
FillI2NPMessageHeader (msg, eI2NPTunnelData); |
||||||
|
return msg; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
void HandleTunnelGatewayMsg (uint8_t * buf, size_t len) |
||||||
|
{ |
||||||
|
TunnelGatewayHeader * header = (TunnelGatewayHeader *)buf; |
||||||
|
uint32_t tunnelID = be32toh(header->tunnelID); |
||||||
|
LogPrint ("TunnelGateway of ", (int)be16toh(header->length), |
||||||
|
" bytes for tunnel ", (unsigned int)tunnelID); |
||||||
|
i2p::tunnel::Tunnel * tunnel = i2p::tunnel::tunnels.GetTunnel (tunnelID); |
||||||
|
if (tunnel) |
||||||
|
{ |
||||||
|
// TODO: we must submit message to tunnel
|
||||||
|
} |
||||||
|
else |
||||||
|
LogPrint ("Tunnel ", (unsigned int)tunnelID, " not found"); |
||||||
|
} |
||||||
|
|
||||||
|
void HandleI2NPMessage (uint8_t * msg, size_t len) |
||||||
|
{ |
||||||
|
I2NPHeader * header = (I2NPHeader *)msg; |
||||||
|
uint32_t msgID = be32toh (header->msgID); |
||||||
|
LogPrint ("I2NP msg received len=", len,", type=", (int)header->typeID, ", msgID=", (unsigned int)msgID); |
||||||
|
|
||||||
|
uint8_t * buf = msg + sizeof (I2NPHeader); |
||||||
|
int size = be16toh (header->size); |
||||||
|
switch (header->typeID) |
||||||
|
{ |
||||||
|
case eI2NPTunnelData: // main message
|
||||||
|
LogPrint ("Unexpected TunnelData"); |
||||||
|
break; |
||||||
|
case eI2NPGarlic: |
||||||
|
LogPrint ("Garlic"); |
||||||
|
break; |
||||||
|
case eI2NPDatabaseStore: |
||||||
|
LogPrint ("DatabaseStore"); |
||||||
|
HandleDatabaseStoreMsg (buf, size); |
||||||
|
break; |
||||||
|
case eI2NPDatabaseSearchReply: |
||||||
|
LogPrint ("DatabaseSearchReply"); |
||||||
|
HandleDatabaseSearchReplyMsg (buf, size); |
||||||
|
break; |
||||||
|
case eI2NPDeliveryStatus: |
||||||
|
LogPrint ("DeliveryStatus"); |
||||||
|
break; |
||||||
|
case eI2NPVariableTunnelBuild: |
||||||
|
LogPrint ("VariableTunnelBuild"); |
||||||
|
HandleVariableTunnelBuildMsg (msgID, buf, size); |
||||||
|
break; |
||||||
|
case eI2NPTunnelGateway: |
||||||
|
LogPrint ("TunnelGateway"); |
||||||
|
HandleTunnelGatewayMsg (buf, size); |
||||||
|
break; |
||||||
|
case eI2NPVariableTunnelBuildReply: |
||||||
|
LogPrint ("VariableTunnelBuildReply"); |
||||||
|
HandleVariableTunnelBuildReplyMsg (msgID, buf, size); |
||||||
|
break; |
||||||
|
default: |
||||||
|
; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void HandleI2NPMessage (I2NPMessage * msg) |
||||||
|
{ |
||||||
|
if (msg) |
||||||
|
{ |
||||||
|
if (msg->GetHeader ()->typeID == eI2NPTunnelData) |
||||||
|
{ |
||||||
|
LogPrint ("TunnelData"); |
||||||
|
i2p::tunnel::tunnels.PostTunnelData (msg); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ()); |
||||||
|
DeleteI2NPMessage (msg); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,127 @@ |
|||||||
|
#ifndef I2NP_PROTOCOL_H__ |
||||||
|
#define I2NP_PROTOCOL_H__ |
||||||
|
|
||||||
|
#include <inttypes.h> |
||||||
|
#include <vector> |
||||||
|
#include "RouterInfo.h" |
||||||
|
|
||||||
|
namespace i2p |
||||||
|
{ |
||||||
|
#pragma pack (1) |
||||||
|
|
||||||
|
struct I2NPHeader |
||||||
|
{ |
||||||
|
uint8_t typeID; |
||||||
|
uint32_t msgID; |
||||||
|
uint64_t expiration; |
||||||
|
uint16_t size; |
||||||
|
uint8_t chks; |
||||||
|
}; |
||||||
|
|
||||||
|
struct I2NPDatabaseStoreMsg |
||||||
|
{ |
||||||
|
uint8_t key[32]; |
||||||
|
uint8_t type; |
||||||
|
uint32_t replyToken; |
||||||
|
uint16_t size; |
||||||
|
}; |
||||||
|
|
||||||
|
struct I2NPBuildRequestRecordClearText |
||||||
|
{ |
||||||
|
uint32_t receiveTunnel; |
||||||
|
uint8_t ourIdent[32]; |
||||||
|
uint32_t nextTunnel; |
||||||
|
uint8_t nextIdent[32]; |
||||||
|
uint8_t layerKey[32]; |
||||||
|
uint8_t ivKey[32]; |
||||||
|
uint8_t replyKey[32]; |
||||||
|
uint8_t replyIV[16]; |
||||||
|
uint8_t flag; |
||||||
|
uint32_t requestTime; |
||||||
|
uint32_t nextMessageID; |
||||||
|
uint8_t filler[29]; |
||||||
|
}; |
||||||
|
|
||||||
|
struct I2NPBuildResponseRecord |
||||||
|
{ |
||||||
|
uint8_t hash[32]; |
||||||
|
uint8_t padding[495]; |
||||||
|
uint8_t ret; |
||||||
|
}; |
||||||
|
|
||||||
|
struct I2NPBuildRequestRecordElGamalEncrypted |
||||||
|
{ |
||||||
|
uint8_t toPeer[16]; |
||||||
|
uint8_t encrypted[512]; |
||||||
|
}; |
||||||
|
|
||||||
|
struct TunnelGatewayHeader |
||||||
|
{ |
||||||
|
uint32_t tunnelID; |
||||||
|
uint16_t length; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
#pragma pack () |
||||||
|
|
||||||
|
enum I2NPMessageType |
||||||
|
{ |
||||||
|
eI2NPDatabaseStore = 1, |
||||||
|
eI2NPDatabaseLookup = 2, |
||||||
|
eI2NPDatabaseSearchReply = 3, |
||||||
|
eI2NPDeliveryStatus = 10, |
||||||
|
eI2NPGarlic = 11, |
||||||
|
eI2NPTunnelData = 18, |
||||||
|
eI2NPTunnelGateway = 19, |
||||||
|
eI2NPData = 20, |
||||||
|
eI2NPVariableTunnelBuild = 23, |
||||||
|
eI2NPVariableTunnelBuildReply = 24 |
||||||
|
}; |
||||||
|
|
||||||
|
const int NTCP_MAX_MESSAGE_SIZE = 16384; |
||||||
|
struct I2NPMessage |
||||||
|
{ |
||||||
|
uint8_t buf[NTCP_MAX_MESSAGE_SIZE]; |
||||||
|
size_t len, offset; |
||||||
|
|
||||||
|
I2NPHeader * GetHeader () { return (I2NPHeader *)(buf + offset); }; |
||||||
|
uint8_t * GetPayload () { return buf + offset + sizeof(I2NPHeader); }; |
||||||
|
uint8_t * GetBuffer () { return buf + offset; }; |
||||||
|
size_t GetLength () const { return len - offset; }; |
||||||
|
}; |
||||||
|
I2NPMessage * NewI2NPMessage (); |
||||||
|
void DeleteI2NPMessage (I2NPMessage * msg); |
||||||
|
void FillI2NPMessageHeader (I2NPMessage * msg, I2NPMessageType msgType, uint32_t replyMsgID = 0); |
||||||
|
I2NPMessage * CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID = 0); |
||||||
|
|
||||||
|
I2NPMessage * CreateDeliveryStatusMsg (); |
||||||
|
I2NPMessage * CreateDatabaseLookupMsg (const uint8_t * key, const uint8_t * from, uint32_t replyTunnelID); |
||||||
|
I2NPMessage * CreateDatabaseStoreMsg (); |
||||||
|
|
||||||
|
void HandleDatabaseStoreMsg (uint8_t * buf, size_t len); |
||||||
|
void HandleDatabaseSearchReplyMsg (uint8_t * buf, size_t len); |
||||||
|
|
||||||
|
|
||||||
|
I2NPBuildRequestRecordClearText CreateBuildRequestRecord ( |
||||||
|
const uint8_t * ourIdent, uint32_t receiveTunnelID, |
||||||
|
const uint8_t * nextIdent, uint32_t nextTunnelID, |
||||||
|
const uint8_t * layerKey,const uint8_t * ivKey, |
||||||
|
const uint8_t * replyKey, const uint8_t * replyIV, uint32_t nextMessageID, |
||||||
|
bool isGateway, bool isEndpoint); |
||||||
|
void EncryptBuildRequestRecord (const i2p::data::RouterInfo& router, |
||||||
|
const I2NPBuildRequestRecordClearText& clearText, |
||||||
|
I2NPBuildRequestRecordElGamalEncrypted& record); |
||||||
|
|
||||||
|
void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len); |
||||||
|
void HandleVariableTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len); |
||||||
|
|
||||||
|
I2NPMessage * CreateTunnelDataMsg (const uint8_t * buf); |
||||||
|
I2NPMessage * CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload); |
||||||
|
|
||||||
|
void HandleTunnelGatewayMsg (uint8_t * buf, size_t len); |
||||||
|
|
||||||
|
void HandleI2NPMessage (uint8_t * msg, size_t len); |
||||||
|
void HandleI2NPMessage (I2NPMessage * msg); |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
Loading…
Reference in new issue