mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 04:04:16 +00:00
cumulative ACK bitfields
This commit is contained in:
parent
04645aacc4
commit
fc2dc9a019
@ -185,7 +185,12 @@ namespace transport
|
||||
std::unique_ptr<IncompleteMessage>(new IncompleteMessage (msg)))).first;
|
||||
}
|
||||
std::unique_ptr<IncompleteMessage>& incompleteMessage = it->second;
|
||||
|
||||
// mark fragment as received
|
||||
if (fragmentNum < 64)
|
||||
incompleteMessage->receivedFragmentsBits |= (0x01 << fragmentNum);
|
||||
else
|
||||
LogPrint (eLogWarning, "SSU: Fragment number ", fragmentNum, " exceeds 64");
|
||||
|
||||
// handle current fragment
|
||||
if (fragmentNum == incompleteMessage->nextFragmentNum)
|
||||
{
|
||||
@ -220,7 +225,7 @@ namespace transport
|
||||
// missing fragment
|
||||
LogPrint (eLogWarning, "SSU: Missing fragments from ", (int)incompleteMessage->nextFragmentNum, " to ", fragmentNum - 1, " of message ", msgID);
|
||||
auto savedFragment = new Fragment (fragmentNum, buf, fragmentSize, isLast);
|
||||
if (incompleteMessage->savedFragments.insert (std::unique_ptr<Fragment>(savedFragment)).second)
|
||||
if (incompleteMessage->savedFragments.insert (std::unique_ptr<Fragment>(savedFragment)).second)
|
||||
incompleteMessage->lastFragmentInsertTime = i2p::util::GetSecondsSinceEpoch ();
|
||||
else
|
||||
LogPrint (eLogWarning, "SSU: Fragment ", (int)fragmentNum, " of message ", msgID, " already saved");
|
||||
@ -266,7 +271,7 @@ namespace transport
|
||||
}
|
||||
}
|
||||
else
|
||||
SendFragmentAck (msgID, fragmentNum);
|
||||
SendFragmentAck (msgID, incompleteMessage->receivedFragmentsBits);
|
||||
buf += fragmentSize;
|
||||
}
|
||||
}
|
||||
@ -394,13 +399,9 @@ namespace transport
|
||||
m_Session.Send (buf, 48);
|
||||
}
|
||||
|
||||
void SSUData::SendFragmentAck (uint32_t msgID, int fragmentNum)
|
||||
void SSUData::SendFragmentAck (uint32_t msgID, uint64_t bits)
|
||||
{
|
||||
if (fragmentNum > 64)
|
||||
{
|
||||
LogPrint (eLogWarning, "SSU: Fragment number ", fragmentNum, " exceeds 64");
|
||||
return;
|
||||
}
|
||||
if (!bits) return;
|
||||
uint8_t buf[64 + 18] = {0};
|
||||
uint8_t * payload = buf + sizeof (SSUHeader);
|
||||
*payload = DATA_FLAG_ACK_BITFIELDS_INCLUDED; // flag
|
||||
@ -410,14 +411,16 @@ namespace transport
|
||||
// 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 = 0x01 << d.rem; // set corresponding bit
|
||||
payload++;
|
||||
size_t len = 0;
|
||||
while (bits)
|
||||
{
|
||||
*payload = (bits & 0x7F); // next 7 bits
|
||||
bits >>= 7;
|
||||
if (bits) *payload &= 0x80; // 0x80 means non-last
|
||||
payload++; len++;
|
||||
}
|
||||
*payload = 0; // number of fragments
|
||||
|
||||
size_t len = d.quot < 4 ? 48 : 64; // 48 = 37 + 7 + 4 (3+1)
|
||||
len = (len <= 4) ? 48 : 64; // 48 = 37 + 7 + 4
|
||||
// encrypt message with session key
|
||||
m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, len);
|
||||
m_Session.Send (buf, len);
|
||||
|
@ -75,9 +75,11 @@ namespace transport
|
||||
std::shared_ptr<I2NPMessage> msg;
|
||||
int nextFragmentNum;
|
||||
uint32_t lastFragmentInsertTime; // in seconds
|
||||
uint64_t receivedFragmentsBits;
|
||||
std::set<std::unique_ptr<Fragment>, FragmentCmp> savedFragments;
|
||||
|
||||
IncompleteMessage (std::shared_ptr<I2NPMessage> m): msg (m), nextFragmentNum (0), lastFragmentInsertTime (0) {};
|
||||
IncompleteMessage (std::shared_ptr<I2NPMessage> m): msg (m), nextFragmentNum (0),
|
||||
lastFragmentInsertTime (0), receivedFragmentsBits (0) {};
|
||||
void AttachNextFragment (const uint8_t * fragment, size_t fragmentSize);
|
||||
};
|
||||
|
||||
@ -109,7 +111,7 @@ namespace transport
|
||||
private:
|
||||
|
||||
void SendMsgAck (uint32_t msgID);
|
||||
void SendFragmentAck (uint32_t msgID, int fragmentNum);
|
||||
void SendFragmentAck (uint32_t msgID, uint64_t bits);
|
||||
void ProcessAcks (uint8_t *& buf, uint8_t flag);
|
||||
void ProcessFragments (uint8_t * buf);
|
||||
void ProcessSentMessageAck (uint32_t msgID);
|
||||
|
Loading…
x
Reference in New Issue
Block a user