A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tcp-veno.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016 ResiliNets, ITTC, University of Kansas
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
7 *
8 * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
9 * ResiliNets Research Group https://resilinets.org/
10 * Information and Telecommunication Technology Center (ITTC)
11 * and Department of Electrical Engineering and Computer Science
12 * The University of Kansas Lawrence, KS USA.
13 */
14
15#include "tcp-veno.h"
16
17#include "tcp-socket-state.h"
18
19#include "ns3/log.h"
20
21namespace ns3
22{
23
26
27TypeId
29{
30 static TypeId tid = TypeId("ns3::TcpVeno")
32 .AddConstructor<TcpVeno>()
33 .SetGroupName("Internet")
34 .AddAttribute("Beta",
35 "Threshold for congestion detection",
39 return tid;
40}
41
43 : TcpNewReno(),
44 m_baseRtt(Time::Max()),
45 m_minRtt(Time::Max()),
46 m_cntRtt(0),
47 m_doingVenoNow(true),
48 m_diff(0),
49 m_inc(true),
50 m_ackCnt(0),
51 m_beta(6)
52{
53 NS_LOG_FUNCTION(this);
54}
55
57 : TcpNewReno(sock),
58 m_baseRtt(sock.m_baseRtt),
59 m_minRtt(sock.m_minRtt),
60 m_cntRtt(sock.m_cntRtt),
61 m_doingVenoNow(true),
62 m_diff(0),
63 m_inc(true),
64 m_ackCnt(sock.m_ackCnt),
65 m_beta(sock.m_beta)
66{
67 NS_LOG_FUNCTION(this);
68}
69
74
77{
78 return CopyObject<TcpVeno>(this);
79}
80
81void
82TcpVeno::PktsAcked(Ptr<TcpSocketState> tcb, uint32_t segmentsAcked, const Time& rtt)
83{
84 NS_LOG_FUNCTION(this << tcb << segmentsAcked << rtt);
85
86 if (rtt.IsZero())
87 {
88 return;
89 }
90
91 m_minRtt = std::min(m_minRtt, rtt);
92 NS_LOG_DEBUG("Updated m_minRtt= " << m_minRtt);
93
94 m_baseRtt = std::min(m_baseRtt, rtt);
95 NS_LOG_DEBUG("Updated m_baseRtt= " << m_baseRtt);
96
97 // Update RTT counter
98 m_cntRtt++;
99 NS_LOG_DEBUG("Updated m_cntRtt= " << m_cntRtt);
100}
101
102void
104{
105 NS_LOG_FUNCTION(this);
106
107 m_doingVenoNow = true;
109}
110
111void
113{
114 NS_LOG_FUNCTION(this);
115
116 m_doingVenoNow = false;
117}
118
119void
121{
122 NS_LOG_FUNCTION(this << tcb << newState);
123 if (newState == TcpSocketState::CA_OPEN)
124 {
125 EnableVeno();
126 NS_LOG_LOGIC("Veno is now on.");
127 }
128 else
129 {
130 DisableVeno();
131 NS_LOG_LOGIC("Veno is turned off.");
132 }
133}
134
135void
137{
138 NS_LOG_FUNCTION(this << tcb << segmentsAcked);
139
140 // Always calculate m_diff, even if we are not doing Veno now
141 uint32_t targetCwnd;
142 uint32_t segCwnd = tcb->GetCwndInSegments();
143
144 /*
145 * Calculate the cwnd we should have. baseRtt is the minimum RTT
146 * per-connection, minRtt is the minimum RTT in this window
147 *
148 * little trick:
149 * desidered throughput is currentCwnd * baseRtt
150 * target cwnd is throughput / minRtt
151 */
152 double tmp = m_baseRtt.GetSeconds() / m_minRtt.GetSeconds();
153 targetCwnd = static_cast<uint32_t>(segCwnd * tmp);
154 NS_LOG_DEBUG("Calculated targetCwnd = " << targetCwnd);
155 NS_ASSERT(segCwnd >= targetCwnd); // implies baseRtt <= minRtt
156
157 // Calculate the difference between actual and target cwnd
158 m_diff = segCwnd - targetCwnd;
159 NS_LOG_DEBUG("Calculated m_diff = " << m_diff);
160
161 if (!m_doingVenoNow)
162 {
163 // If Veno is not on, we follow NewReno algorithm
164 NS_LOG_LOGIC("Veno is not turned on, we follow NewReno algorithm.");
165 TcpNewReno::IncreaseWindow(tcb, segmentsAcked);
166 return;
167 }
168
169 // We do the Veno calculations only if we got enough RTT samples
170 if (m_cntRtt <= 2)
171 { // We do not have enough RTT samples, so we should behave like NewReno
172 NS_LOG_LOGIC("We do not have enough RTT samples to perform Veno "
173 "calculations, we behave like NewReno.");
174 TcpNewReno::IncreaseWindow(tcb, segmentsAcked);
175 }
176 else
177 {
178 NS_LOG_LOGIC("We have enough RTT samples to perform Veno calculations.");
179
180 if (tcb->m_cWnd < tcb->m_ssThresh)
181 { // Slow start mode. Veno employs same slow start algorithm as NewReno's.
182 NS_LOG_LOGIC("We are in slow start, behave like NewReno.");
183 TcpNewReno::SlowStart(tcb, segmentsAcked);
184 }
185 else
186 { // Congestion avoidance mode
187 NS_LOG_LOGIC("We are in congestion avoidance, execute Veno additive "
188 "increase algo.");
189
190 if (m_diff < m_beta)
191 {
192 // Available bandwidth is not fully utilized,
193 // increase cwnd by 1 every RTT
194 NS_LOG_LOGIC("Available bandwidth not fully utilized, increase "
195 "cwnd by 1 every RTT");
196 TcpNewReno::CongestionAvoidance(tcb, segmentsAcked);
197 }
198 else
199 {
200 // Available bandwidth is fully utilized,
201 // increase cwnd by 1 every other RTT
202 NS_LOG_LOGIC("Available bandwidth fully utilized, increase cwnd "
203 "by 1 every other RTT");
204 if (m_inc)
205 {
206 TcpNewReno::CongestionAvoidance(tcb, segmentsAcked);
207 m_inc = false;
208 }
209 else
210 {
211 m_inc = true;
212 }
213 }
214 }
215 }
216
217 // Reset cntRtt & minRtt every RTT
218 m_cntRtt = 0;
220}
221
222std::string
224{
225 return "TcpVeno";
226}
227
230{
231 NS_LOG_FUNCTION(this << tcb << bytesInFlight);
232
233 if (m_diff < m_beta)
234 {
235 // random loss due to bit errors is most likely to have occurred,
236 // we cut cwnd by 1/5
237 NS_LOG_LOGIC("Random loss is most likely to have occurred, "
238 "cwnd is reduced by 1/5");
239 static double tmp = 4.0 / 5.0;
240 return std::max(static_cast<uint32_t>(bytesInFlight * tmp), 2 * tcb->m_segmentSize);
241 }
242 else
243 {
244 // congestion-based loss is most likely to have occurred,
245 // we reduce cwnd by 1/2 as in NewReno
246 NS_LOG_LOGIC("Congestive loss is most likely to have occurred, "
247 "cwnd is halved");
248 return TcpNewReno::GetSsThresh(tcb, bytesInFlight);
249 }
250}
251
252} // namespace ns3
#define Max(a, b)
friend Ptr< T > CopyObject(Ptr< T > object)
Copy an Object.
Definition object.h:581
Smart pointer class similar to boost::intrusive_ptr.
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.
void IncreaseWindow(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked) override
Try to increase the cWnd following the NewReno specification.
TcpCongState_t
Definition of the Congestion state machine.
@ CA_OPEN
Normal state, no dubious events.
An implementation of TCP Veno.
Definition tcp-veno.h:61
std::string GetName() const override
Get the name of the congestion control algorithm.
Definition tcp-veno.cc:223
bool m_inc
If true, cwnd needs to be incremented.
Definition tcp-veno.h:156
void PktsAcked(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked, const Time &rtt) override
Perform RTT sampling needed to execute Veno algorithm.
Definition tcp-veno.cc:82
uint32_t GetSsThresh(Ptr< const TcpSocketState > tcb, uint32_t bytesInFlight) override
Get slow start threshold during Veno multiplicative-decrease phase.
Definition tcp-veno.cc:229
uint32_t m_cntRtt
Number of RTT measurements during last RTT.
Definition tcp-veno.h:153
static TypeId GetTypeId()
Get the type ID.
Definition tcp-veno.cc:28
void EnableVeno()
Enable Veno algorithm to start Veno sampling.
Definition tcp-veno.cc:103
void IncreaseWindow(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked) override
Adjust cwnd following Veno additive increase algorithm.
Definition tcp-veno.cc:136
Time m_minRtt
Minimum of RTTs measured within last RTT.
Definition tcp-veno.h:152
bool m_doingVenoNow
If true, do Veno for this RTT.
Definition tcp-veno.h:154
uint32_t m_beta
Threshold for congestion detection.
Definition tcp-veno.h:158
void DisableVeno()
Turn off Veno.
Definition tcp-veno.cc:112
void CongestionStateSet(Ptr< TcpSocketState > tcb, const TcpSocketState::TcpCongState_t newState) override
Enable/disable Veno depending on the congestion state.
Definition tcp-veno.cc:120
~TcpVeno() override
Definition tcp-veno.cc:70
TcpVeno()
Create an unbound tcp socket.
Definition tcp-veno.cc:42
uint32_t m_diff
Difference between expected and actual throughput.
Definition tcp-veno.h:155
Ptr< TcpCongestionOps > Fork() override
Copy the congestion control algorithm across sockets.
Definition tcp-veno.cc:76
Time m_baseRtt
Minimum of all RTT measurements seen during connection.
Definition tcp-veno.h:151
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:392
static Time Max()
Maximum representable Time Not to be confused with Max(Time,Time).
Definition nstime.h:286
bool IsZero() const
Exactly equivalent to t == 0.
Definition nstime.h:304
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_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition uinteger.h:35
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#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.