void HandleI2NPMessage (uint8_t * msg, size_t len) { uint8_t typeID = msg[I2NP_HEADER_TYPEID_OFFSET]; uint32_t msgID = bufbe32toh (msg + I2NP_HEADER_MSGID_OFFSET); LogPrint (eLogDebug, "I2NP: msg received len=", len,", type=", (int)typeID, ", msgID=", (unsigned int)msgID); uint8_t * buf = msg + I2NP_HEADER_SIZE; int size = bufbe16toh (msg + I2NP_HEADER_SIZE_OFFSET); switch (typeID) { case eI2NPVariableTunnelBuild: HandleVariableTunnelBuildMsg (msgID, buf, size); break; case eI2NPVariableTunnelBuildReply: HandleVariableTunnelBuildReplyMsg (msgID, buf, size); break; case eI2NPTunnelBuild: HandleTunnelBuildMsg (buf, size); break; case eI2NPTunnelBuildReply: // TODO: break; default: LogPrint (eLogWarning, "I2NP: Unexpected message ", (int)typeID); } }
void GarlicDestination::HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr<AESDecryption> decryption, std::shared_ptr<i2p::tunnel::InboundTunnel> from) { uint16_t tagCount = bufbe16toh (buf); buf += 2; len -= 2; if (tagCount > 0) { if (tagCount*32 > len) { LogPrint (eLogError, "Garlic: Tag count ", tagCount, " exceeds length ", len); return ; } uint32_t ts = i2p::util::GetSecondsSinceEpoch (); for (int i = 0; i < tagCount; i++) m_Tags[SessionTag(buf + i*32, ts)] = decryption; } buf += tagCount*32; len -= tagCount*32; uint32_t payloadSize = bufbe32toh (buf); if (payloadSize > len) { LogPrint (eLogError, "Garlic: Unexpected payload size ", payloadSize); return; } buf += 4; uint8_t * payloadHash = buf; buf += 32;// payload hash. if (*buf) // session key? buf += 32; // new session key buf++; // flag // payload uint8_t digest[32]; SHA256 (buf, payloadSize, digest); if (memcmp (payloadHash, digest, 32)) // payload hash doesn't match { LogPrint (eLogError, "Garlic: wrong payload hash"); return; } HandleGarlicPayload (buf, payloadSize, from); }
size_t GetI2NPMessageLength (const uint8_t * msg) { return bufbe16toh (msg + I2NP_HEADER_SIZE_OFFSET) + I2NP_HEADER_SIZE; }