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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
18 *
19 * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
20 * ResiliNets Research Group https://resilinets.org/
21 * Information and Telecommunication Technology Center (ITTC)
22 * and Department of Electrical Engineering and Computer Science
23 * The University of Kansas Lawrence, KS USA.
24 */
25
26#include "tcp-veno.h"
27
28#include "tcp-socket-state.h"
29
30#include "ns3/log.h"
31
32namespace ns3
33{
34
37
38TypeId
40{
41 static TypeId tid = TypeId("ns3::TcpVeno")
43 .AddConstructor<TcpVeno>()
44 .SetGroupName("Internet")
45 .AddAttribute("Beta",
46 "Threshold for congestion detection",
49 MakeUintegerChecker<uint32_t>());
50 return tid;
51}
52
54 : TcpNewReno(),
55 m_baseRtt(Time::Max()),
56 m_minRtt(Time::Max()),
57 m_cntRtt(0),
58 m_doingVenoNow(true),
59 m_diff(0),
60 m_inc(true),
61 m_ackCnt(0),
62 m_beta(6)
63{
64 NS_LOG_FUNCTION(this);
65}
66
68 : TcpNewReno(sock),
69 m_baseRtt(sock.m_baseRtt),
70 m_minRtt(sock.m_minRtt),
71 m_cntRtt(sock.m_cntRtt),
72 m_doingVenoNow(true),
73 m_diff(0),
74 m_inc(true),
75 m_ackCnt(sock.m_ackCnt),
76 m_beta(sock.m_beta)
77{
78 NS_LOG_FUNCTION(this);
79}
80
82{
83 NS_LOG_FUNCTION(this);
84}
85
88{
89 return CopyObject<TcpVeno>(this);
90}
91
92void
93TcpVeno::PktsAcked(Ptr<TcpSocketState> tcb, uint32_t segmentsAcked, const Time& rtt)
94{
95 NS_LOG_FUNCTION(this << tcb << segmentsAcked << rtt);
96
97 if (rtt.IsZero())
98 {
99 return;
100 }
101
102 m_minRtt = std::min(m_minRtt, rtt);
103 NS_LOG_DEBUG("Updated m_minRtt= " << m_minRtt);
104
105 m_baseRtt = std::min(m_baseRtt, rtt);
106 NS_LOG_DEBUG("Updated m_baseRtt= " << m_baseRtt);
107
108 // Update RTT counter
109 m_cntRtt++;
110 NS_LOG_DEBUG("Updated m_cntRtt= " << m_cntRtt);
111}
112
113void
115{
116 NS_LOG_FUNCTION(this);
117
118 m_doingVenoNow = true;
120}
121
122void
124{
125 NS_LOG_FUNCTION(this);
126
127 m_doingVenoNow = false;
128}
129
130void
132{
133 NS_LOG_FUNCTION(this << tcb << newState);
134 if (newState == TcpSocketState::CA_OPEN)
135 {
136 EnableVeno();
137 NS_LOG_LOGIC("Veno is now on.");
138 }
139 else
140 {
141 DisableVeno();
142 NS_LOG_LOGIC("Veno is turned off.");
143 }
144}
145
146void
148{
149 NS_LOG_FUNCTION(this << tcb << segmentsAcked);
150
151 // Always calculate m_diff, even if we are not doing Veno now
152 uint32_t targetCwnd;
153 uint32_t segCwnd = tcb->GetCwndInSegments();
154
155 /*
156 * Calculate the cwnd we should have. baseRtt is the minimum RTT
157 * per-connection, minRtt is the minimum RTT in this window
158 *
159 * little trick:
160 * desidered throughput is currentCwnd * baseRtt
161 * target cwnd is throughput / minRtt
162 */
163 double tmp = m_baseRtt.GetSeconds() / m_minRtt.GetSeconds();
164 targetCwnd = static_cast<uint32_t>(segCwnd * tmp);
165 NS_LOG_DEBUG("Calculated targetCwnd = " << targetCwnd);
166 NS_ASSERT(segCwnd >= targetCwnd); // implies baseRtt <= minRtt
167
168 // Calculate the difference between actual and target cwnd
169 m_diff = segCwnd - targetCwnd;
170 NS_LOG_DEBUG("Calculated m_diff = " << m_diff);
171
172 if (!m_doingVenoNow)
173 {
174 // If Veno is not on, we follow NewReno algorithm
175 NS_LOG_LOGIC("Veno is not turned on, we follow NewReno algorithm.");
176 TcpNewReno::IncreaseWindow(tcb, segmentsAcked);
177 return;
178 }
179
180 // We do the Veno calculations only if we got enough RTT samples
181 if (m_cntRtt <= 2)
182 { // We do not have enough RTT samples, so we should behave like NewReno
183 NS_LOG_LOGIC("We do not have enough RTT samples to perform Veno "
184 "calculations, we behave like NewReno.");
185 TcpNewReno::IncreaseWindow(tcb, segmentsAcked);
186 }
187 else
188 {
189 NS_LOG_LOGIC("We have enough RTT samples to perform Veno calculations.");
190
191 if (tcb->m_cWnd < tcb->m_ssThresh)
192 { // Slow start mode. Veno employs same slow start algorithm as NewReno's.
193 NS_LOG_LOGIC("We are in slow start, behave like NewReno.");
194 TcpNewReno::SlowStart(tcb, segmentsAcked);
195 }
196 else
197 { // Congestion avoidance mode
198 NS_LOG_LOGIC("We are in congestion avoidance, execute Veno additive "
199 "increase algo.");
200
201 if (m_diff < m_beta)
202 {
203 // Available bandwidth is not fully utilized,
204 // increase cwnd by 1 every RTT
205 NS_LOG_LOGIC("Available bandwidth not fully utilized, increase "
206 "cwnd by 1 every RTT");
207 TcpNewReno::CongestionAvoidance(tcb, segmentsAcked);
208 }
209 else
210 {
211 // Available bandwidth is fully utilized,
212 // increase cwnd by 1 every other RTT
213 NS_LOG_LOGIC("Available bandwidth fully utilized, increase cwnd "
214 "by 1 every other RTT");
215 if (m_inc)
216 {
217 TcpNewReno::CongestionAvoidance(tcb, segmentsAcked);
218 m_inc = false;
219 }
220 else
221 {
222 m_inc = true;
223 }
224 }
225 }
226 }
227
228 // Reset cntRtt & minRtt every RTT
229 m_cntRtt = 0;
231}
232
233std::string
235{
236 return "TcpVeno";
237}
238
241{
242 NS_LOG_FUNCTION(this << tcb << bytesInFlight);
243
244 if (m_diff < m_beta)
245 {
246 // random loss due to bit errors is most likely to have occurred,
247 // we cut cwnd by 1/5
248 NS_LOG_LOGIC("Random loss is most likely to have occurred, "
249 "cwnd is reduced by 1/5");
250 static double tmp = 4.0 / 5.0;
251 return std::max(static_cast<uint32_t>(bytesInFlight * tmp), 2 * tcb->m_segmentSize);
252 }
253 else
254 {
255 // congestion-based loss is most likely to have occurred,
256 // we reduce cwnd by 1/2 as in NewReno
257 NS_LOG_LOGIC("Congestive loss is most likely to have occurred, "
258 "cwnd is halved");
259 return TcpNewReno::GetSsThresh(tcb, bytesInFlight);
260 }
261}
262
263} // namespace ns3
#define Max(a, b)
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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:72
std::string GetName() const override
Get the name of the congestion control algorithm.
Definition: tcp-veno.cc:234
bool m_inc
If true, cwnd needs to be incremented.
Definition: tcp-veno.h:167
void PktsAcked(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked, const Time &rtt) override
Perform RTT sampling needed to execute Veno algorithm.
Definition: tcp-veno.cc:93
uint32_t GetSsThresh(Ptr< const TcpSocketState > tcb, uint32_t bytesInFlight) override
Get slow start threshold during Veno multiplicative-decrease phase.
Definition: tcp-veno.cc:240
uint32_t m_cntRtt
Number of RTT measurements during last RTT.
Definition: tcp-veno.h:164
static TypeId GetTypeId()
Get the type ID.
Definition: tcp-veno.cc:39
void EnableVeno()
Enable Veno algorithm to start Veno sampling.
Definition: tcp-veno.cc:114
void IncreaseWindow(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked) override
Adjust cwnd following Veno additive increase algorithm.
Definition: tcp-veno.cc:147
Time m_minRtt
Minimum of RTTs measured within last RTT.
Definition: tcp-veno.h:163
bool m_doingVenoNow
If true, do Veno for this RTT.
Definition: tcp-veno.h:165
uint32_t m_beta
Threshold for congestion detection.
Definition: tcp-veno.h:169
void DisableVeno()
Turn off Veno.
Definition: tcp-veno.cc:123
void CongestionStateSet(Ptr< TcpSocketState > tcb, const TcpSocketState::TcpCongState_t newState) override
Enable/disable Veno depending on the congestion state.
Definition: tcp-veno.cc:131
~TcpVeno() override
Definition: tcp-veno.cc:81
TcpVeno()
Create an unbound tcp socket.
Definition: tcp-veno.cc:53
uint32_t m_diff
Difference between expected and actual throughput.
Definition: tcp-veno.h:166
Ptr< TcpCongestionOps > Fork() override
Copy the congestion control algorithm across sockets.
Definition: tcp-veno.cc:87
Time m_baseRtt
Minimum of all RTT measurements seen during connection.
Definition: tcp-veno.h:162
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
static Time Max()
Maximum representable Time Not to be confused with Max(Time,Time).
Definition: nstime.h:297
bool IsZero() const
Exactly equivalent to t == 0.
Definition: nstime.h:315
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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:46
Every class exported by the ns3 library is enclosed in the ns3 namespace.