From 53cd9c24182921e12906229488034d815fc85767 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 5 Feb 2014 15:07:47 -0500 Subject: [PATCH] parse data message --- SSU.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SSU.h | 2 ++ 2 files changed, 63 insertions(+) diff --git a/SSU.cpp b/SSU.cpp index 4a9892ab..521117ba 100644 --- a/SSU.cpp +++ b/SSU.cpp @@ -47,6 +47,11 @@ namespace ssu { switch (m_State) { + case eSessionStateEstablised: + // most common case + ProcessMessage (buf, len); + break; + // establishing case eSessionStateUnknown: // session request ProcessSessionRequest (buf, len, senderEndpoint); @@ -64,6 +69,34 @@ namespace ssu } } + void SSUSession::ProcessMessage (uint8_t * buf, size_t len) + { + if (Validate (buf, len, m_MacKey)) + { + Decrypt (buf, len, m_SessionKey); + SSUHeader * header = (SSUHeader *)buf; + uint8_t payloadType = header->flag >> 4; + switch (payloadType) + { + case PAYLOAD_TYPE_DATA: + LogPrint ("SSU data received"); + ProcessData (buf + sizeof (SSUHeader), len - sizeof (SSUHeader)); + break; + case PAYLOAD_TYPE_TEST: + LogPrint ("SSU test received"); + break; + case PAYLOAD_TYPE_SESSION_DESTROY: + LogPrint ("SSU session destroy received"); + break; + default: + LogPrint ("Unexpected SSU payload type ", (int)payloadType); + } + } + // TODO: try intro key as well + else + LogPrint ("MAC verifcation failed"); + } + void SSUSession::ProcessSessionRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint) { LogPrint ("Process session request"); @@ -98,6 +131,7 @@ namespace ssu LogPrint ("Our external address is ", ourIP.to_string (), ":", ourPort); uint32_t relayTag = be32toh (*(uint32_t *)(buf + sizeof (SSUHeader) + 263)); SendSessionConfirmed (buf + sizeof (SSUHeader), ourAddress, relayTag); + m_State = eSessionStateEstablised; } } @@ -113,6 +147,7 @@ namespace ssu m_State = eSessionStateConfirmedReceived; LogPrint ("Session confirmed received"); // TODO: + m_State = eSessionStateEstablised; } else LogPrint ("Unexpected payload type ", (int)(header->flag >> 4)); @@ -327,6 +362,32 @@ namespace ssu // TODO: } + void SSUSession::ProcessData (uint8_t * buf, size_t len) + { + //uint8_t * start = buf; + uint8_t flag = *buf; + buf++; + LogPrint ("Process SSU data flags=", (int)flag); + if (flag) + { + //TODO: process options + return; + } + uint8_t numFragments = *buf; // number of fragments + buf++; + uint32_t msgID = be32toh (*(uint32_t *)buf); // message ID + buf += 4; + uint8_t frag[4]; + frag[0] = 0; + memcpy (frag + 1, buf, 3); + buf += 3; + uint32_t fragmentInfo = be32toh (*(uint32_t *)frag); // fragment info + uint16_t fragmentSize = be16toh (fragmentInfo & 0x1FFF); // bits 0 - 13 + bool isLast = fragmentInfo & 0x010000; // bit 16 + uint8_t fragmentNum = fragmentInfo >> 17; // bits 23 - 17 + LogPrint ("SSU data fragment ", (int)fragmentNum, " of ", (int)numFragments, " of message ", msgID, " size=", (int)fragmentSize, isLast ? " last" : " non-last"); + } + SSUServer::SSUServer (boost::asio::io_service& service, int port): m_Endpoint (boost::asio::ip::udp::v4 (), port), m_Socket (service, m_Endpoint) { diff --git a/SSU.h b/SSU.h index c33b3f83..aee160ae 100644 --- a/SSU.h +++ b/SSU.h @@ -65,12 +65,14 @@ namespace ssu void CreateAESandMacKey (uint8_t * pubKey, uint8_t * aesKey, uint8_t * macKey); + void ProcessMessage (uint8_t * buf, size_t len); // call for established session void ProcessSessionRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); void SendSessionRequest (); void ProcessSessionCreated (uint8_t * buf, size_t len); void SendSessionCreated (const uint8_t * x); void ProcessSessionConfirmed (uint8_t * buf, size_t len); void SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, uint32_t relayTag); + void ProcessData (uint8_t * buf, size_t len); bool ProcessIntroKeyEncryptedMessage (uint8_t expectedPayloadType, i2p::data::RouterInfo& r, uint8_t * buf, size_t len); void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len, uint8_t * aesKey, uint8_t * iv, uint8_t * macKey);