A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tcp-bic.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014 Natale Patriciello <natale.patriciello@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7#include "tcp-bic.h"
8
9#include "ns3/log.h"
10#include "ns3/simulator.h"
11
12namespace ns3
13{
14
17
18TypeId
20{
21 static TypeId tid =
22 TypeId("ns3::TcpBic")
24 .AddConstructor<TcpBic>()
25 .SetGroupName("Internet")
26 .AddAttribute("FastConvergence",
27 "Turn on/off fast convergence.",
28 BooleanValue(true),
31 .AddAttribute("Beta",
32 "Beta for multiplicative decrease",
33 DoubleValue(0.8),
36 .AddAttribute("MaxIncr",
37 "Limit on increment allowed during binary search",
38 UintegerValue(16),
41 .AddAttribute("LowWnd",
42 "Threshold window size (in segments) for engaging BIC response",
43 UintegerValue(14),
46 .AddAttribute("SmoothPart",
47 "Number of RTT needed to approach cWnd_max from "
48 "cWnd_max-BinarySearchCoefficient. It can be viewed as the gradient "
49 "of the slow start AIM phase: less this value is, "
50 "more steep the increment will be.",
54 .AddAttribute("BinarySearchCoefficient",
55 "Inverse of the coefficient for the "
56 "binary search. Default 4, as in Linux",
60 return tid;
61}
62
65 m_cWndCnt(0),
66 m_lastMaxCwnd(0),
67 m_lastCwnd(0),
68 m_epochStart(Time::Min())
69{
70 NS_LOG_FUNCTION(this);
71}
72
74 : TcpCongestionOps(sock),
75 m_fastConvergence(sock.m_fastConvergence),
76 m_beta(sock.m_beta),
77 m_maxIncr(sock.m_maxIncr),
78 m_lowWnd(sock.m_lowWnd),
79 m_smoothPart(sock.m_smoothPart),
80 m_cWndCnt(sock.m_cWndCnt),
81 m_lastMaxCwnd(sock.m_lastMaxCwnd),
82 m_lastCwnd(sock.m_lastCwnd),
83 m_epochStart(sock.m_epochStart),
84 m_b(sock.m_b)
85{
86 NS_LOG_FUNCTION(this);
87}
88
89void
91{
92 NS_LOG_FUNCTION(this << tcb << segmentsAcked);
93
94 if (tcb->m_cWnd < tcb->m_ssThresh)
95 {
96 tcb->m_cWnd += tcb->m_segmentSize;
97 segmentsAcked -= 1;
98
99 NS_LOG_INFO("In SlowStart, updated to cwnd " << tcb->m_cWnd << " ssthresh "
100 << tcb->m_ssThresh);
101 }
102
103 if (tcb->m_cWnd >= tcb->m_ssThresh && segmentsAcked > 0)
104 {
105 m_cWndCnt += segmentsAcked;
106 uint32_t cnt = Update(tcb);
107
108 /* According to the BIC paper and RFC 6356 even once the new cwnd is
109 * calculated you must compare this to the number of ACKs received since
110 * the last cwnd update. If not enough ACKs have been received then cwnd
111 * cannot be updated.
112 */
113 if (m_cWndCnt > cnt)
114 {
115 tcb->m_cWnd += tcb->m_segmentSize;
116 m_cWndCnt = 0;
117 NS_LOG_INFO("In CongAvoid, updated to cwnd " << tcb->m_cWnd);
118 }
119 else
120 {
121 NS_LOG_INFO("Not enough segments have been ACKed to increment cwnd."
122 "Until now "
123 << m_cWndCnt);
124 }
125 }
126}
127
130{
131 NS_LOG_FUNCTION(this << tcb);
132
133 uint32_t segCwnd = tcb->GetCwndInSegments();
134 uint32_t cnt;
135
136 m_lastCwnd = segCwnd;
137
138 if (m_epochStart == Time::Min())
139 {
140 m_epochStart = Simulator::Now(); /* record the beginning of an epoch */
141 }
142
143 if (segCwnd < m_lowWnd)
144 {
145 NS_LOG_INFO("Under lowWnd, compatibility mode. Behaving as NewReno");
146 cnt = segCwnd;
147 return cnt;
148 }
149
150 if (segCwnd < m_lastMaxCwnd)
151 {
152 double dist = (m_lastMaxCwnd - segCwnd) / m_b;
153
154 NS_LOG_INFO("cWnd = " << segCwnd << " under lastMax, " << m_lastMaxCwnd
155 << " and dist=" << dist);
156 if (dist > m_maxIncr)
157 {
158 /* Linear increase */
159 cnt = segCwnd / m_maxIncr;
160 NS_LOG_INFO("Linear increase (maxIncr=" << m_maxIncr << "), cnt=" << cnt);
161 }
162 else if (dist <= 1)
163 {
164 /* smoothed binary search increase: when our window is really
165 * close to the last maximum, we parameterize in m_smoothPart the number
166 * of RTT needed to reach that window.
167 */
168 cnt = (segCwnd * m_smoothPart) / m_b;
169
170 NS_LOG_INFO("Binary search increase (smoothPart=" << m_smoothPart << "), cnt=" << cnt);
171 }
172 else
173 {
174 /* binary search increase */
175 cnt = static_cast<uint32_t>(segCwnd / dist);
176
177 NS_LOG_INFO("Binary search increase, cnt=" << cnt);
178 }
179 }
180 else
181 {
182 NS_LOG_INFO("cWnd = " << segCwnd << " above last max, " << m_lastMaxCwnd);
183 if (segCwnd < m_lastMaxCwnd + m_b)
184 {
185 /* slow start AMD linear increase */
186 cnt = (segCwnd * m_smoothPart) / m_b;
187 NS_LOG_INFO("Slow start AMD, cnt=" << cnt);
188 }
189 else if (segCwnd < m_lastMaxCwnd + m_maxIncr * (m_b - 1))
190 {
191 /* slow start */
192 cnt = (segCwnd * (m_b - 1)) / (segCwnd - m_lastMaxCwnd);
193
194 NS_LOG_INFO("Slow start, cnt=" << cnt);
195 }
196 else
197 {
198 /* linear increase */
199 cnt = segCwnd / m_maxIncr;
200
201 NS_LOG_INFO("Linear, cnt=" << cnt);
202 }
203 }
204
205 /* if in slow start or link utilization is very low. Code taken from Linux
206 * kernel, not sure of the source they take it. Usually, it is not reached,
207 * since if m_lastMaxCwnd is 0, we are (hopefully) in slow start.
208 */
209 if (m_lastMaxCwnd == 0)
210 {
211 if (cnt > 20) /* increase cwnd 5% per RTT */
212 {
213 cnt = 20;
214 }
215 }
216
217 if (cnt == 0)
218 {
219 cnt = 1;
220 }
221
222 return cnt;
223}
224
225std::string
227{
228 return "TcpBic";
229}
230
233{
234 NS_LOG_FUNCTION(this);
235
236 uint32_t segCwnd = tcb->GetCwndInSegments();
237 uint32_t ssThresh = 0;
238
240
241 /* Wmax and fast convergence */
242 if (segCwnd < m_lastMaxCwnd && m_fastConvergence)
243 {
244 NS_LOG_INFO("Fast Convergence. Last max cwnd: " << m_lastMaxCwnd << " updated to "
245 << static_cast<uint32_t>(m_beta * segCwnd));
246 m_lastMaxCwnd = static_cast<uint32_t>(m_beta * segCwnd);
247 }
248 else
249 {
250 NS_LOG_INFO("Last max cwnd: " << m_lastMaxCwnd << " updated to " << segCwnd);
251 m_lastMaxCwnd = segCwnd;
252 }
253
254 if (segCwnd < m_lowWnd)
255 {
256 ssThresh = std::max(2 * tcb->m_segmentSize, bytesInFlight / 2);
257 NS_LOG_INFO("Less than lowWindow, ssTh= " << ssThresh);
258 }
259 else
260 {
261 ssThresh = static_cast<uint32_t>(std::max(segCwnd * m_beta, 2.0) * tcb->m_segmentSize);
262 NS_LOG_INFO("More than lowWindow, ssTh= " << ssThresh);
263 }
264
265 return ssThresh;
266}
267
270{
271 return CopyObject<TcpBic>(this);
272}
273
274} // namespace ns3
#define Min(a, b)
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
friend Ptr< T > CopyObject(Ptr< T > object)
Copy an Object.
Definition object.h:581
Smart pointer class similar to boost::intrusive_ptr.
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
BIC congestion control algorithm.
Definition tcp-bic.h:71
bool m_fastConvergence
Enable or disable fast convergence algorithm.
Definition tcp-bic.h:117
uint32_t m_lastMaxCwnd
Last maximum cWnd.
Definition tcp-bic.h:125
uint32_t m_lowWnd
Lower bound on congestion window.
Definition tcp-bic.h:120
static TypeId GetTypeId()
Get the type ID.
Definition tcp-bic.cc:19
uint32_t GetSsThresh(Ptr< const TcpSocketState > tcb, uint32_t bytesInFlight) override
Get the slow start threshold after a loss event.
Definition tcp-bic.cc:232
uint8_t m_b
Binary search coefficient.
Definition tcp-bic.h:128
uint32_t m_lastCwnd
Last cWnd.
Definition tcp-bic.h:126
uint32_t m_maxIncr
Maximum window increment.
Definition tcp-bic.h:119
double m_beta
Beta for cubic multiplicative increase.
Definition tcp-bic.h:118
virtual uint32_t Update(Ptr< TcpSocketState > tcb)
Bic window update after a new ack received.
Definition tcp-bic.cc:129
TcpBic()
Constructor.
Definition tcp-bic.cc:63
uint32_t m_smoothPart
Number of RTT needed to reach Wmax from Wmax-B.
Definition tcp-bic.h:121
void IncreaseWindow(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked) override
Congestion avoidance algorithm implementation.
Definition tcp-bic.cc:90
Time m_epochStart
Beginning of an epoch.
Definition tcp-bic.h:127
uint32_t m_cWndCnt
cWnd integer-to-float counter
Definition tcp-bic.h:124
Ptr< TcpCongestionOps > Fork() override
Copy the congestion control algorithm across sockets.
Definition tcp-bic.cc:269
std::string GetName() const override
Get the name of the congestion control algorithm.
Definition tcp-bic.cc:226
Congestion control abstract class.
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
static Time Min()
Minimum representable Time Not to be confused with Min(Time,Time).
Definition nstime.h:276
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
#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.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition boolean.h:70
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition double.h:32