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