A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tcp-ledbat.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016 NITK Surathkal
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: Ankit Deepak <adadeepak8@gmail.com>
18 *
19 */
20
21#include "tcp-ledbat.h"
22
23#include "tcp-socket-state.h"
24
25#include "ns3/log.h"
26#include "ns3/simulator.h" // Now ()
27
28namespace ns3
29{
30
31NS_LOG_COMPONENT_DEFINE("TcpLedbat");
33
34TypeId
36{
37 static TypeId tid =
38 TypeId("ns3::TcpLedbat")
40 .AddConstructor<TcpLedbat>()
41 .SetGroupName("Internet")
42 .AddAttribute("TargetDelay",
43 "Targeted Queue Delay",
47 .AddAttribute("BaseHistoryLen",
48 "Number of Base delay samples",
49 UintegerValue(10),
51 MakeUintegerChecker<uint32_t>())
52 .AddAttribute("NoiseFilterLen",
53 "Number of Current delay samples",
56 MakeUintegerChecker<uint32_t>())
57 .AddAttribute("Gain",
58 "Offset Gain",
59 DoubleValue(1.0),
61 MakeDoubleChecker<double>())
62 .AddAttribute("SSParam",
63 "Possibility of Slow Start",
65 MakeEnumAccessor<SlowStartType>(&TcpLedbat::SetDoSs),
67 .AddAttribute("MinCwnd",
68 "Minimum cWnd for Ledbat",
71 MakeUintegerChecker<uint32_t>());
72 return tid;
73}
74
75void
77{
78 NS_LOG_FUNCTION(this << doSS);
79 m_doSs = doSS;
80 if (m_doSs)
81 {
83 }
84 else
85 {
86 m_flag &= ~LEDBAT_CAN_SS;
87 }
88}
89
91 : TcpNewReno()
92{
93 NS_LOG_FUNCTION(this);
95 m_gain = 1;
97 m_baseHistoLen = 10;
101 m_lastRollover = 0;
102 m_sndCwndCnt = 0;
104 m_minCwnd = 2;
105}
106
107void
109{
110 NS_LOG_FUNCTION(this);
111 buffer.buffer.clear();
112 buffer.min = 0;
113}
114
116 : TcpNewReno(sock)
117{
118 NS_LOG_FUNCTION(this);
119 m_target = sock.m_target;
120 m_gain = sock.m_gain;
121 m_doSs = sock.m_doSs;
128 m_flag = sock.m_flag;
129 m_minCwnd = sock.m_minCwnd;
130}
131
133{
134 NS_LOG_FUNCTION(this);
135}
136
139{
140 return CopyObject<TcpLedbat>(this);
141}
142
143std::string
145{
146 return "TcpLedbat";
147}
148
151{
153 if (b.buffer.empty())
154 {
155 return ~0U;
156 }
157 else
158 {
159 return b.buffer[b.min];
160 }
161}
162
164TcpLedbat::CurrentDelay(FilterFunction filter)
165{
166 NS_LOG_FUNCTION(this);
167 return filter(m_noiseFilter);
168}
169
172{
173 NS_LOG_FUNCTION(this);
175}
176
177void
179{
180 NS_LOG_FUNCTION(this << tcb << segmentsAcked);
181 if (tcb->m_cWnd.Get() <= tcb->m_segmentSize)
182 {
184 }
185 if (m_doSs == DO_SLOWSTART && tcb->m_cWnd <= tcb->m_ssThresh && (m_flag & LEDBAT_CAN_SS))
186 {
187 SlowStart(tcb, segmentsAcked);
188 }
189 else
190 {
191 m_flag &= ~LEDBAT_CAN_SS;
192 CongestionAvoidance(tcb, segmentsAcked);
193 }
194}
195
196void
198{
199 NS_LOG_FUNCTION(this << tcb << segmentsAcked);
200 if ((m_flag & LEDBAT_VALID_OWD) == 0)
201 {
203 tcb,
204 segmentsAcked); // letting it fall to TCP behaviour if no timestamps
205 return;
206 }
207 int64_t queue_delay;
208 double offset;
209 uint32_t cwnd = (tcb->m_cWnd.Get());
210 uint32_t max_cwnd;
211 uint64_t current_delay = CurrentDelay(&TcpLedbat::MinCircBuf);
212 uint64_t base_delay = BaseDelay();
213
214 if (current_delay > base_delay)
215 {
216 queue_delay = static_cast<int64_t>(current_delay - base_delay);
217 offset = m_target.GetMilliSeconds() - queue_delay;
218 }
219 else
220 {
221 queue_delay = static_cast<int64_t>(base_delay - current_delay);
222 offset = m_target.GetMilliSeconds() + queue_delay;
223 }
224 offset *= m_gain;
225 m_sndCwndCnt = static_cast<int32_t>(offset * segmentsAcked * tcb->m_segmentSize);
226 double inc = (m_sndCwndCnt * 1.0) / (m_target.GetMilliSeconds() * tcb->m_cWnd.Get());
227 cwnd += (inc * tcb->m_segmentSize);
228
229 max_cwnd = static_cast<uint32_t>(tcb->m_highTxMark.Get() - tcb->m_lastAckedSeq) +
230 segmentsAcked * tcb->m_segmentSize;
231 cwnd = std::min(cwnd, max_cwnd);
232 cwnd = std::max(cwnd, m_minCwnd * tcb->m_segmentSize);
233 tcb->m_cWnd = cwnd;
234
235 if (tcb->m_cWnd <= tcb->m_ssThresh)
236 {
237 tcb->m_ssThresh = tcb->m_cWnd - 1;
238 }
239}
240
241void
243{
244 NS_LOG_FUNCTION(this << owd << maxlen << cb.buffer.size());
245 if (cb.buffer.empty())
246 {
247 NS_LOG_LOGIC("First Value for queue");
248 cb.buffer.push_back(owd);
249 cb.min = 0;
250 return;
251 }
252 cb.buffer.push_back(owd);
253 if (cb.buffer[cb.min] > owd)
254 {
255 cb.min = static_cast<uint32_t>(cb.buffer.size() - 1);
256 }
257 if (cb.buffer.size() >= maxlen)
258 {
259 NS_LOG_LOGIC("Queue full" << maxlen);
260 cb.buffer.erase(cb.buffer.begin());
261 cb.min = 0;
262 NS_LOG_LOGIC("Current min element" << cb.buffer[cb.min]);
263 for (uint32_t i = 1; i < maxlen - 1; i++)
264 {
265 if (cb.buffer[i] < cb.buffer[cb.min])
266 {
267 cb.min = i;
268 }
269 }
270 }
271}
272
273void
275{
276 NS_LOG_FUNCTION(this << owd);
277 if (m_baseHistory.buffer.empty())
278 {
280 return;
281 }
282 uint64_t timestamp = static_cast<uint64_t>(Simulator::Now().GetSeconds());
283
284 if (timestamp - m_lastRollover > 60)
285 {
286 m_lastRollover = timestamp;
288 }
289 else
290 {
291 auto last = static_cast<uint32_t>(m_baseHistory.buffer.size() - 1);
292 if (owd < m_baseHistory.buffer[last])
293 {
294 m_baseHistory.buffer[last] = owd;
296 {
297 m_baseHistory.min = last;
298 }
299 }
300 }
301}
302
303void
305{
306 NS_LOG_FUNCTION(this << tcb << segmentsAcked << rtt);
307 if (tcb->m_rcvTimestampValue == 0 || tcb->m_rcvTimestampEchoReply == 0)
308 {
309 m_flag &= ~LEDBAT_VALID_OWD;
310 }
311 else
312 {
314 }
315 if (rtt.IsPositive())
316 {
318 tcb->m_rcvTimestampValue - tcb->m_rcvTimestampEchoReply,
320 UpdateBaseDelay(tcb->m_rcvTimestampValue - tcb->m_rcvTimestampEchoReply);
321 }
322}
323
324} // namespace ns3
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Hold variables of type enum.
Definition: enum.h:62
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
An implementation of LEDBAT.
Definition: tcp-ledbat.h:40
static TypeId GetTypeId()
Get the type ID.
Definition: tcp-ledbat.cc:35
SlowStartType m_doSs
Permissible Slow Start State.
Definition: tcp-ledbat.h:188
std::string GetName() const override
Get the name of the TCP flavour.
Definition: tcp-ledbat.cc:144
void UpdateBaseDelay(uint32_t owd)
Update the base delay buffer.
Definition: tcp-ledbat.cc:274
uint32_t m_minCwnd
Minimum cWnd value mentioned in RFC 6817.
Definition: tcp-ledbat.h:196
void IncreaseWindow(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked) override
Adjust cwnd following LEDBAT algorithm.
Definition: tcp-ledbat.cc:178
uint32_t m_flag
LEDBAT Flag.
Definition: tcp-ledbat.h:195
uint32_t BaseDelay()
Return the value of base delay.
Definition: tcp-ledbat.cc:171
void SetDoSs(SlowStartType doSS)
Change the Slow Start Capability.
Definition: tcp-ledbat.cc:76
double m_gain
GAIN value from RFC.
Definition: tcp-ledbat.h:187
@ LEDBAT_CAN_SS
If LEDBAT allows Slow Start.
Definition: tcp-ledbat.h:58
@ LEDBAT_VALID_OWD
If valid timestamps are present.
Definition: tcp-ledbat.h:57
Ptr< TcpCongestionOps > Fork() override
Copy the congestion control algorithm across sockets.
Definition: tcp-ledbat.cc:138
void AddDelay(OwdCircBuf &cb, uint32_t owd, uint32_t maxlen)
Add new delay to the buffers.
Definition: tcp-ledbat.cc:242
OwdCircBuf m_noiseFilter
Buffer to store the current delay.
Definition: tcp-ledbat.h:194
SlowStartType
The slowstart types.
Definition: tcp-ledbat.h:46
@ DO_NOT_SLOWSTART
Do not Slow Start.
Definition: tcp-ledbat.h:47
@ DO_SLOWSTART
Do NewReno Slow Start.
Definition: tcp-ledbat.h:48
void PktsAcked(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked, const Time &rtt) override
Get information from the acked packet.
Definition: tcp-ledbat.cc:304
TcpLedbat()
Create an unbound tcp socket.
Definition: tcp-ledbat.cc:90
~TcpLedbat() override
Destructor.
Definition: tcp-ledbat.cc:132
void CongestionAvoidance(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked) override
Reduce Congestion.
Definition: tcp-ledbat.cc:197
void InitCircBuf(OwdCircBuf &buffer)
Initialise a new buffer.
Definition: tcp-ledbat.cc:108
static uint32_t MinCircBuf(OwdCircBuf &b)
Return the minimum delay of the buffer.
Definition: tcp-ledbat.cc:150
Time m_target
Target Queue Delay.
Definition: tcp-ledbat.h:186
int32_t m_sndCwndCnt
The congestion window addition parameter.
Definition: tcp-ledbat.h:192
uint32_t m_baseHistoLen
Length of base delay history buffer.
Definition: tcp-ledbat.h:189
uint32_t m_noiseFilterLen
Length of current delay buffer.
Definition: tcp-ledbat.h:190
uint64_t m_lastRollover
Timestamp of last added delay.
Definition: tcp-ledbat.h:191
OwdCircBuf m_baseHistory
Buffer to store the base delay.
Definition: tcp-ledbat.h:193
uint32_t CurrentDelay(FilterFunction filter)
Return the value of current delay.
Definition: tcp-ledbat.cc:164
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.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
bool IsPositive() const
Exactly equivalent to t >= 0.
Definition: nstime.h:333
int64_t GetMilliSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:408
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
AttributeValue implementation for Time.
Definition: nstime.h:1406
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
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1427
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1407
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_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#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
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1331
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:189
Buffer structure to store delays.
Definition: tcp-ledbat.h:132
uint32_t min
The index of minimum value.
Definition: tcp-ledbat.h:134
std::vector< uint32_t > buffer
Vector to store the delay.
Definition: tcp-ledbat.h:133