Skip to content

Commit

Permalink
tcp (fixes #966): Suppress cwnd growth when rate-limited
Browse files Browse the repository at this point in the history
  • Loading branch information
tomhenderson committed May 26, 2024
1 parent 2bbcec0 commit f75345f
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Applications have a new Attribute to set the IPv4 ToS field.
### Changed behavior

* Fixed the corner rebound direction in `RandomWalk2d[Outdoor]MobilityModel` and the initial direction in case of node starting from a border or corner.
* (tcp) TcpCubic and TcpLinuxReno will no longer grow their congestion window when application-limited, now matching Linux behavior

Changes from ns-3.40 to ns-3.41
-------------------------------
Expand Down
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ topocentric coordinate systems
- (bindings, core) - Introduced a helper class to manage static initialization of Time as a workaround for Cppyy3 static initialization problems.
- (bindings, lte, wifi) - Relocated statically initialized variables from header files to source files for Cppyy3 compatibility.
- (tests) - Enhanced error handling in test.py to avoid attempts to open non-existent XML files following early test termination by sanitizers.
- (tcp) #966 - Tcp Cubic (and LinuxReno) cwnd should not grow during application-limited phase
- (tcp) #1085 - Do not reset Cubic W_max upon timeout
- (wifi) #1072 - Support configuration of custom EDCA parameters via Txop attributes before device installation
- (wifi) - Fix operation in 6 GHz band (added support for FILS Discovery frames and HE 6GHz Band Capabilities information element, fixed HE Operation information element, fixed NSS selection, fixed HT and VHT not supported on 6GHz links).
Expand Down
7 changes: 7 additions & 0 deletions src/internet/model/tcp-cubic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,13 @@ TcpCubic::IncreaseWindow(Ptr<TcpSocketState> tcb, uint32_t segmentsAcked)
{
NS_LOG_FUNCTION(this << tcb << segmentsAcked);

if (!tcb->m_isCwndLimited)
{
NS_LOG_DEBUG("No increase because current cwnd " << tcb->m_cWnd
<< " is not limiting the flow");
return;
}

if (tcb->m_cWnd < tcb->m_ssThresh)
{
if (m_hystart && tcb->m_lastAckedSeq > m_endSeq)
Expand Down
1 change: 1 addition & 0 deletions src/internet/model/tcp-dctcp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ TcpDctcp::Init(Ptr<TcpSocketState> tcb)
tcb->m_useEcn = TcpSocketState::On;
tcb->m_ecnMode = TcpSocketState::DctcpEcn;
tcb->m_ectCodePoint = m_useEct0 ? TcpSocketState::Ect0 : TcpSocketState::Ect1;
SetSuppressIncreaseIfCwndLimited(false);
m_initialized = true;
}

Expand Down
14 changes: 14 additions & 0 deletions src/internet/model/tcp-linux-reno.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ TcpLinuxReno::CongestionAvoidance(Ptr<TcpSocketState> tcb, uint32_t segmentsAcke
{
NS_LOG_FUNCTION(this << tcb << segmentsAcked);

if (m_suppressIncreaseIfCwndLimited && !tcb->m_isCwndLimited)
{
NS_LOG_DEBUG("No increase because current cwnd " << tcb->m_cWnd
<< " is not limiting the flow");
return;
}

uint32_t w = tcb->m_cWnd / tcb->m_segmentSize;

// Floor w to 1 if w == 0
Expand Down Expand Up @@ -150,4 +157,11 @@ TcpLinuxReno::Fork()
return CopyObject<TcpLinuxReno>(this);
}

void
TcpLinuxReno::SetSuppressIncreaseIfCwndLimited(bool value)
{
NS_LOG_FUNCTION(this << value);
m_suppressIncreaseIfCwndLimited = value;
}

} // namespace ns3
17 changes: 17 additions & 0 deletions src/internet/model/tcp-linux-reno.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,25 @@ class TcpLinuxReno : public TcpCongestionOps
*/
virtual void CongestionAvoidance(Ptr<TcpSocketState> tcb, uint32_t segmentsAcked);

/**
* TcpSocketBase follows the Linux way of setting a flag 'isCwndLimited'
* when BytesInFlight() >= cwnd. This flag, if true, will suppress
* additive increase window updates for this class. However, some
* derived classes using the IncreaseWindow() method may not want this
* behavior, so this method exists to allow subclasses to set it to false.
*
* \param value Value to set whether the isCwndLimited condition
* suppresses window updates
*/
void SetSuppressIncreaseIfCwndLimited(bool value);

private:
uint32_t m_cWndCnt{0}; //!< Linear increase counter
// The below flag exists for classes derived from TcpLinuxReno (such as
// TcpDctcp) that may not want to suppress cwnd increase, unlike Linux's
// tcp_reno_cong_avoid()
bool m_suppressIncreaseIfCwndLimited{
true}; //!< Suppress window increase if TCP is not cwnd limited
};

} // namespace ns3
Expand Down
6 changes: 6 additions & 0 deletions src/internet/model/tcp-socket-base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3238,6 +3238,12 @@ TcpSocketBase::SendDataPacket(SequenceNumber32 seq, uint32_t maxSize, bool withA
<< m_endPoint6->GetPeerAddress() << ". Header " << header);
}
// Signal to congestion control whether the cwnd is fully used
// This is a simple version of Linux tcp_cwnd_validate() but following
// the principle implemented in Linux that limits the updating of cwnd
// (in the congestion controls) when flight size is >= cwnd
m_tcb->m_isCwndLimited = (BytesInFlight() >= m_tcb->m_cWnd);
UpdateRttHistory(seq, sz, isRetransmission);
// Update bytes sent during recovery phase
Expand Down
1 change: 1 addition & 0 deletions src/internet/model/tcp-socket-state.cc
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ TcpSocketState::TcpSocketState(const TcpSocketState& other)
m_paceInitialWindow(other.m_paceInitialWindow),
m_minRtt(other.m_minRtt),
m_bytesInFlight(other.m_bytesInFlight),
m_isCwndLimited(other.m_isCwndLimited),
m_lastRtt(other.m_lastRtt),
m_ecnMode(other.m_ecnMode),
m_useEcn(other.m_useEcn),
Expand Down
1 change: 1 addition & 0 deletions src/internet/model/tcp-socket-state.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ class TcpSocketState : public Object
Time m_minRtt{Time::Max()}; //!< Minimum RTT observed throughout the connection

TracedValue<uint32_t> m_bytesInFlight{0}; //!< Bytes in flight
bool m_isCwndLimited{false}; //!< Whether throughput is limited by cwnd
TracedValue<Time> m_lastRtt{Seconds(0.0)}; //!< Last RTT sample collected

Ptr<TcpRxBuffer> m_rxBuffer; //!< Rx buffer (reordering buffer)
Expand Down
12 changes: 6 additions & 6 deletions src/test/ns3tcp/ns3tcp-cubic-test-suite.cc
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ Ns3TcpCubicTestCase::DoRun()
true,
"cwnd outside range");
// Time just before a reduction does not have much variation
NS_TEST_ASSERT_MSG_EQ(CheckValues(Seconds(9), Seconds(9.7), 84, 89),
NS_TEST_ASSERT_MSG_EQ(CheckValues(Seconds(9), Seconds(9.6), 84, 89),
true,
"cwnd outside range");
}
Expand All @@ -380,20 +380,20 @@ Ns3TcpCubicTestCase::DoRun()
}
else if (m_prefix == "ns3-tcp-cubic-no-friendly")
{
// Between time 12 and 16, cwnd should be fairly constant
// Between time 11 and 15, cwnd should be fairly constant
// because without TCP friendliness, Cubic does not respond quickly
NS_TEST_ASSERT_MSG_EQ(CheckValues(Seconds(12), Seconds(16), 107, 123),
NS_TEST_ASSERT_MSG_EQ(CheckValues(Seconds(11), Seconds(15), 107, 123),
true,
"cwnd outside range");
// After time 19.5, cwnd should have grown much higher
NS_TEST_ASSERT_MSG_EQ(CheckValues(Seconds(19.5), Seconds(20), 180, 210),
// After time 17.5, cwnd should have grown much higher
NS_TEST_ASSERT_MSG_EQ(CheckValues(Seconds(17.5), Seconds(18.5), 170, 215),
true,
"cwnd outside range");
}
else if (m_prefix == "ns3-tcp-cubic-friendly")
{
// In contrast to previous case, cwnd should grow above 150 much sooner
NS_TEST_ASSERT_MSG_EQ(CheckValues(Seconds(12), Seconds(14), 150, 210),
NS_TEST_ASSERT_MSG_EQ(CheckValues(Seconds(13), Seconds(15), 150, 210),
true,
"cwnd outside range");
}
Expand Down

0 comments on commit f75345f

Please sign in to comment.