A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tcp-congestion-ops.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015 Natale Patriciello <natale.patriciello@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
8
9#include "ns3/log.h"
10
11namespace ns3
12{
13
14NS_LOG_COMPONENT_DEFINE("TcpCongestionOps");
15
16NS_OBJECT_ENSURE_REGISTERED(TcpCongestionOps);
17
18TypeId
20{
21 static TypeId tid =
22 TypeId("ns3::TcpCongestionOps").SetParent<Object>().SetGroupName("Internet");
23 return tid;
24}
25
30
35
39
40void
42{
43 NS_LOG_FUNCTION(this << tcb << segmentsAcked);
44}
45
46void
48{
49 NS_LOG_FUNCTION(this << tcb << segmentsAcked << rtt);
50}
51
52void
58
59void
64
65bool
67{
68 return false;
69}
70
71void
78
79// RENO
80
82
85{
86 static TypeId tid = TypeId("ns3::TcpNewReno")
88 .SetGroupName("Internet")
89 .AddConstructor<TcpNewReno>();
90 return tid;
91}
92
98
100 : TcpCongestionOps(sock)
101{
102 NS_LOG_FUNCTION(this);
103}
104
108
109/**
110 * \brief Tcp NewReno slow start algorithm
111 *
112 * Defined in RFC 5681 as
113 *
114 * > During slow start, a TCP increments cwnd by at most SMSS bytes for
115 * > each ACK received that cumulatively acknowledges new data. Slow
116 * > start ends when cwnd exceeds ssthresh (or, optionally, when it
117 * > reaches it, as noted above) or when congestion is observed. While
118 * > traditionally TCP implementations have increased cwnd by precisely
119 * > SMSS bytes upon receipt of an ACK covering new data, we RECOMMEND
120 * > that TCP implementations increase cwnd, per:
121 * >
122 * > cwnd += min (N, SMSS) (2)
123 * >
124 * > where N is the number of previously unacknowledged bytes acknowledged
125 * > in the incoming ACK.
126 *
127 * The ns-3 implementation respect the RFC definition. Linux does something
128 * different:
129 * \code{.cpp}
130 u32 tcp_slow_start(struct tcp_sock *tp, u32 acked)
131 {
132 u32 cwnd = tp->snd_cwnd + acked;
133
134 if (cwnd > tp->snd_ssthresh)
135 cwnd = tp->snd_ssthresh + 1;
136 acked -= cwnd - tp->snd_cwnd;
137 tp->snd_cwnd = min(cwnd, tp->snd_cwnd_clamp);
138
139 return acked;
140 }
141 \endcode
142 *
143 * As stated, we want to avoid the case when a cumulative ACK increases cWnd more
144 * than a segment size, but we keep count of how many segments we have ignored,
145 * and return them.
146 *
147 * \param tcb internal congestion state
148 * \param segmentsAcked count of segments acked
149 * \return the number of segments not considered for increasing the cWnd
150 */
153{
154 NS_LOG_FUNCTION(this << tcb << segmentsAcked);
155
156 if (segmentsAcked >= 1)
157 {
158 tcb->m_cWnd += tcb->m_segmentSize;
159 NS_LOG_INFO("In SlowStart, updated to cwnd " << tcb->m_cWnd << " ssthresh "
160 << tcb->m_ssThresh);
161 return segmentsAcked - 1;
162 }
163
164 return 0;
165}
166
167/**
168 * \brief NewReno congestion avoidance
169 *
170 * During congestion avoidance, cwnd is incremented by roughly 1 full-sized
171 * segment per round-trip time (RTT).
172 *
173 * \param tcb internal congestion state
174 * \param segmentsAcked count of segments acked
175 */
176void
178{
179 NS_LOG_FUNCTION(this << tcb << segmentsAcked);
180
181 if (segmentsAcked > 0)
182 {
183 double adder =
184 static_cast<double>(tcb->m_segmentSize * tcb->m_segmentSize) / tcb->m_cWnd.Get();
185 adder = std::max(1.0, adder);
186 tcb->m_cWnd += static_cast<uint32_t>(adder);
187 NS_LOG_INFO("In CongAvoid, updated to cwnd " << tcb->m_cWnd << " ssthresh "
188 << tcb->m_ssThresh);
189 }
190}
191
192/**
193 * \brief Try to increase the cWnd following the NewReno specification
194 *
195 * \see SlowStart
196 * \see CongestionAvoidance
197 *
198 * \param tcb internal congestion state
199 * \param segmentsAcked count of segments acked
200 */
201void
203{
204 NS_LOG_FUNCTION(this << tcb << segmentsAcked);
205
206 if (tcb->m_cWnd < tcb->m_ssThresh)
207 {
208 segmentsAcked = SlowStart(tcb, segmentsAcked);
209 }
210
211 if (tcb->m_cWnd >= tcb->m_ssThresh)
212 {
213 CongestionAvoidance(tcb, segmentsAcked);
214 }
215
216 /* At this point, we could have segmentsAcked != 0. This because RFC says
217 * that in slow start, we should increase cWnd by min (N, SMSS); if in
218 * slow start we receive a cumulative ACK, it counts only for 1 SMSS of
219 * increase, wasting the others.
220 *
221 * // Incorrect assert, I am sorry
222 * NS_ASSERT (segmentsAcked == 0);
223 */
224}
225
226std::string
228{
229 return "TcpNewReno";
230}
231
234{
235 NS_LOG_FUNCTION(this << state << bytesInFlight);
236
237 return std::max(2 * state->m_segmentSize, bytesInFlight / 2);
238}
239
242{
243 return CopyObject<TcpNewReno>(this);
244}
245
246} // namespace ns3
A base class which provides memory management and object aggregation.
Definition object.h:78
friend Ptr< T > CopyObject(Ptr< T > object)
Copy an Object.
Definition object.h:581
Smart pointer class similar to boost::intrusive_ptr.
Congestion control abstract class.
virtual void CwndEvent(Ptr< TcpSocketState > tcb, const TcpSocketState::TcpCAEvent_t event)
Trigger events/calculations on occurrence of congestion window event.
virtual void IncreaseWindow(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked)
Congestion avoidance algorithm implementation.
virtual void CongControl(Ptr< TcpSocketState > tcb, const TcpRateOps::TcpRateConnection &rc, const TcpRateOps::TcpRateSample &rs)
Called when packets are delivered to update cwnd and pacing rate.
static TypeId GetTypeId()
Get the type ID.
virtual void PktsAcked(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked, const Time &rtt)
Timing information on received ACK.
virtual bool HasCongControl() const
Returns true when Congestion Control Algorithm implements CongControl.
virtual void CongestionStateSet(Ptr< TcpSocketState > tcb, const TcpSocketState::TcpCongState_t newState)
Trigger events/calculations specific to a congestion state.
The NewReno implementation.
virtual uint32_t SlowStart(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked)
Tcp NewReno slow start algorithm.
virtual void CongestionAvoidance(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked)
NewReno congestion avoidance.
uint32_t GetSsThresh(Ptr< const TcpSocketState > tcb, uint32_t bytesInFlight) override
Get the slow start threshold after a loss event.
std::string GetName() const override
Get the name of the congestion control algorithm.
void IncreaseWindow(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked) override
Try to increase the cWnd following the NewReno specification.
static TypeId GetTypeId()
Get the type ID.
Ptr< TcpCongestionOps > Fork() override
Copy the congestion control algorithm across sockets.
TcpCAEvent_t
Congestion avoidance events.
TcpCongState_t
Definition of the Congestion state machine.
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Information about the connection rate.
Rate Sample structure.