From 2f601ce02f634432c117eb75b0005f9d93e1572b Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 15 Jul 2014 14:49:54 -0400 Subject: [PATCH] send ack per fragment. temporary disble check for duplicated through IV --- SSU.cpp | 4 ++-- SSUData.cpp | 35 ++++++++++++++++++++++++++++++++++- SSUData.h | 3 ++- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/SSU.cpp b/SSU.cpp index 8c2115f8..9660023d 100644 --- a/SSU.cpp +++ b/SSU.cpp @@ -84,10 +84,10 @@ namespace ssu else { ScheduleTermination (); - // check for duplicate + /* // check for duplicate const uint8_t * iv = ((SSUHeader *)buf)->iv; if (m_ReceivedIVs.count (iv)) return; // duplicate detected - m_ReceivedIVs.insert (iv); + m_ReceivedIVs.insert (iv);*/ if (m_IsSessionKey && Validate (buf, len, m_MacKey)) // try session key first DecryptSessionKey (buf, len); diff --git a/SSUData.cpp b/SSUData.cpp index 64887602..75a1df41 100644 --- a/SSUData.cpp +++ b/SSUData.cpp @@ -1,3 +1,4 @@ +#include #include "Log.h" #include "SSU.h" #include "SSUData.h" @@ -172,7 +173,9 @@ namespace ssu LogPrint ("SSU unexpected message ", (int)msg->GetHeader ()->typeID); DeleteI2NPMessage (msg); } - } + } + else + SendFragmentAck (msgID, fragmentNum); buf += fragmentSize; } } @@ -252,6 +255,36 @@ namespace ssu m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, 48); m_Session.Send (buf, 48); } + + void SSUData::SendFragmentAck (uint32_t msgID, int fragmentNum) + { + if (fragmentNum > 64) + { + LogPrint ("Fragment number ", fragmentNum, " exceeds 64"); + return; + } + uint8_t buf[64 + 18]; + uint8_t * payload = buf + sizeof (SSUHeader); + *payload = DATA_FLAG_ACK_BITFIELDS_INCLUDED; // flag + payload++; + *payload = 1; // number of ACK bitfields + payload++; + // one ack + *(uint32_t *)(payload) = htobe32 (msgID); // msgID + payload += 4; + div_t d = div (fragmentNum, 7); + memset (payload, 0x80, d.quot); // 0x80 means non-last + payload += d.quot; + *payload = 0x40 >> d.rem; // set corresponding bit + payload++; + *payload = 0; // number of fragments + + size_t len = d.quot < 4 ? 48 : 64; // 48 = 37 + 7 + 4 (3+1) + // encrypt message with session key + m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, len); + m_Session.Send (buf, len); + } + } } diff --git a/SSUData.h b/SSUData.h index fb04879d..603f50b8 100644 --- a/SSUData.h +++ b/SSUData.h @@ -64,7 +64,8 @@ namespace ssu private: void SendMsgAck (uint32_t msgID); - void ProcessSentMessageAck (uint32_t msgID); + void SendFragmentAck (uint32_t msgID, int fragmentNum); + void ProcessSentMessageAck (uint32_t msgID); private: