mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-04-28 03:37:49 +02:00
limit stream's inbound speed
This commit is contained in:
parent
41dd8b527d
commit
fb8e0e1b5b
5 changed files with 53 additions and 5 deletions
|
@ -70,6 +70,7 @@ namespace stream
|
|||
std::shared_ptr<const i2p::data::LeaseSet> remote, int port): m_Service (service),
|
||||
m_SendStreamID (0), m_SequenceNumber (0),
|
||||
m_TunnelsChangeSequenceNumber (0), m_LastReceivedSequenceNumber (-1), m_PreviousReceivedSequenceNumber (-1),
|
||||
m_LastConfirmedReceivedSequenceNumber (0), // for limit inbound speed
|
||||
m_Status (eStreamStatusNew), m_IsAckSendScheduled (false), m_IsNAcked (false), m_IsFirstACK (false),
|
||||
m_IsResendNeeded (false), m_IsFirstRttSample (false), m_IsSendTime (true), m_IsWinDropped (true),
|
||||
m_IsTimeOutResend (false), m_LocalDestination (local),
|
||||
|
@ -78,18 +79,25 @@ namespace stream
|
|||
m_RTT (INITIAL_RTT), m_SlowRTT (INITIAL_RTT), m_WindowSize (INITIAL_WINDOW_SIZE), m_LastWindowDropSize (0), m_WindowIncCounter (0), m_RTO (INITIAL_RTO),
|
||||
m_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()), m_PrevRTTSample (INITIAL_RTT),
|
||||
m_PrevRTT (INITIAL_RTT), m_Jitter (0), m_MinPacingTime (0),
|
||||
m_PacingTime (INITIAL_PACING_TIME), m_PacingTimeRem (0), m_DropWindowDelayTime (0), m_NumResendAttempts (0), m_MTU (STREAMING_MTU)
|
||||
m_PacingTime (INITIAL_PACING_TIME), m_PacingTimeRem (0), m_DropWindowDelayTime (0),
|
||||
m_LastACKSendTime (0), m_PacketACKInterval (1), m_PacketACKIntervalRem (0), // for limit inbound speed
|
||||
m_NumResendAttempts (0), m_MTU (STREAMING_MTU)
|
||||
{
|
||||
RAND_bytes ((uint8_t *)&m_RecvStreamID, 4);
|
||||
m_RemoteIdentity = remote->GetIdentity ();
|
||||
auto outboundSpeed = local.GetOwner ()->GetStreamingOutboundSpeed ();
|
||||
if (outboundSpeed)
|
||||
m_MinPacingTime = (1000000LL*STREAMING_MTU)/outboundSpeed;
|
||||
|
||||
auto inboundSpeed = local.GetOwner ()->GetStreamingInboundSpeed (); // for limit inbound speed
|
||||
if (inboundSpeed)
|
||||
m_PacketACKInterval = (1000000LL*STREAMING_MTU)/inboundSpeed;
|
||||
}
|
||||
|
||||
Stream::Stream (boost::asio::io_service& service, StreamingDestination& local):
|
||||
m_Service (service), m_SendStreamID (0), m_SequenceNumber (0),
|
||||
m_TunnelsChangeSequenceNumber (0), m_LastReceivedSequenceNumber (-1), m_PreviousReceivedSequenceNumber (-1),
|
||||
m_LastConfirmedReceivedSequenceNumber (0), // for limit inbound speed
|
||||
m_Status (eStreamStatusNew), m_IsAckSendScheduled (false), m_IsNAcked (false), m_IsFirstACK (false),
|
||||
m_IsResendNeeded (false), m_IsFirstRttSample (false), m_IsSendTime (true), m_IsWinDropped (true),
|
||||
m_IsTimeOutResend (false), m_LocalDestination (local),
|
||||
|
@ -98,12 +106,18 @@ namespace stream
|
|||
m_WindowSize (INITIAL_WINDOW_SIZE), m_LastWindowDropSize (0), m_WindowIncCounter (0),
|
||||
m_RTO (INITIAL_RTO), m_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()),
|
||||
m_PrevRTTSample (INITIAL_RTT), m_PrevRTT (INITIAL_RTT), m_Jitter (0), m_MinPacingTime (0),
|
||||
m_PacingTime (INITIAL_PACING_TIME), m_PacingTimeRem (0), m_DropWindowDelayTime (0), m_NumResendAttempts (0), m_MTU (STREAMING_MTU)
|
||||
m_PacingTime (INITIAL_PACING_TIME), m_PacingTimeRem (0), m_DropWindowDelayTime (0),
|
||||
m_LastACKSendTime (0), m_PacketACKInterval (1), m_PacketACKIntervalRem (0), // for limit inbound speed
|
||||
m_NumResendAttempts (0), m_MTU (STREAMING_MTU)
|
||||
{
|
||||
RAND_bytes ((uint8_t *)&m_RecvStreamID, 4);
|
||||
auto outboundSpeed = local.GetOwner ()->GetStreamingOutboundSpeed ();
|
||||
if (outboundSpeed)
|
||||
m_MinPacingTime = (1000000LL*STREAMING_MTU)/outboundSpeed;
|
||||
m_MinPacingTime = (1000000LL*STREAMING_MTU)/outboundSpeed;
|
||||
|
||||
auto inboundSpeed = local.GetOwner ()->GetStreamingInboundSpeed (); // for limit inbound speed
|
||||
if (inboundSpeed)
|
||||
m_PacketACKInterval = (1000000LL*STREAMING_MTU)/inboundSpeed;
|
||||
}
|
||||
|
||||
Stream::~Stream ()
|
||||
|
@ -754,10 +768,26 @@ namespace stream
|
|||
void Stream::SendQuickAck ()
|
||||
{
|
||||
int32_t lastReceivedSeqn = m_LastReceivedSequenceNumber;
|
||||
// for limit inbound speed
|
||||
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||
int numPackets = 0;
|
||||
int64_t passedTime = m_PacketACKInterval * INITIAL_WINDOW_SIZE; // in microseconds // while m_LastACKSendTime == 0
|
||||
if (m_LastACKSendTime)
|
||||
passedTime = (ts - m_LastACKSendTime)*1000; // in microseconds
|
||||
numPackets = (passedTime + m_PacketACKIntervalRem) / m_PacketACKInterval;
|
||||
m_PacketACKIntervalRem = (passedTime + m_PacketACKIntervalRem) - (numPackets * m_PacketACKInterval);
|
||||
if (m_LastConfirmedReceivedSequenceNumber + numPackets < m_LastReceivedSequenceNumber)
|
||||
lastReceivedSeqn = m_LastConfirmedReceivedSequenceNumber + numPackets;
|
||||
if (numPackets == 0) return;
|
||||
// for limit inbound speed
|
||||
if (!m_SavedPackets.empty ())
|
||||
{
|
||||
int32_t seqn = (*m_SavedPackets.rbegin ())->GetSeqn ();
|
||||
if (seqn > lastReceivedSeqn) lastReceivedSeqn = seqn;
|
||||
for (auto it: m_SavedPackets)
|
||||
{
|
||||
auto seqn = it->GetSeqn ();
|
||||
if (m_LastConfirmedReceivedSequenceNumber + numPackets < int(seqn)) break; // for limit inbound speed
|
||||
if (seqn > lastReceivedSeqn) lastReceivedSeqn = seqn;
|
||||
}
|
||||
}
|
||||
if (lastReceivedSeqn < 0)
|
||||
{
|
||||
|
@ -786,6 +816,11 @@ namespace stream
|
|||
for (auto it: m_SavedPackets)
|
||||
{
|
||||
auto seqn = it->GetSeqn ();
|
||||
if (m_LastConfirmedReceivedSequenceNumber + numPackets < int(seqn)) // for limit inbound speed
|
||||
{
|
||||
htobe32buf (packet + 12, nextSeqn - 1);
|
||||
break;
|
||||
}
|
||||
if (numNacks + (seqn - nextSeqn) >= 256)
|
||||
{
|
||||
LogPrint (eLogError, "Streaming: Number of NACKs exceeds 256. seqn=", seqn, " nextSeqn=", nextSeqn);
|
||||
|
@ -827,6 +862,8 @@ namespace stream
|
|||
p.len = size;
|
||||
|
||||
SendPackets (std::vector<Packet *> { &p });
|
||||
m_LastACKSendTime = ts; // for limit inbound speed
|
||||
m_LastConfirmedReceivedSequenceNumber = lastReceivedSeqn; // for limit inbound speed
|
||||
LogPrint (eLogDebug, "Streaming: Quick Ack sent. ", (int)numNacks, " NACKs");
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue