A Discrete-Event Network Simulator
API
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 
28 namespace ns3
29 {
30 
31 NS_LOG_COMPONENT_DEFINE("TcpLedbat");
33 
34 TypeId
36 {
37  static TypeId tid =
38  TypeId("ns3::TcpLedbat")
40  .AddConstructor<TcpLedbat>()
41  .SetGroupName("Internet")
42  .AddAttribute("TargetDelay",
43  "Targeted Queue Delay",
44  TimeValue(MilliSeconds(100)),
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",
54  UintegerValue(4),
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",
69  UintegerValue(2),
71  MakeUintegerChecker<uint32_t>());
72  return tid;
73 }
74 
75 void
77 {
78  NS_LOG_FUNCTION(this << doSS);
79  m_doSs = doSS;
80  if (m_doSs)
81  {
83  }
84  else
85  {
87  }
88 }
89 
91  : TcpNewReno()
92 {
93  NS_LOG_FUNCTION(this);
94  m_target = MilliSeconds(100);
95  m_gain = 1;
97  m_baseHistoLen = 10;
98  m_noiseFilterLen = 4;
101  m_lastRollover = 0;
102  m_sndCwndCnt = 0;
104  m_minCwnd = 2;
105 }
106 
107 void
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;
127  m_sndCwndCnt = sock.m_sndCwndCnt;
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 
143 std::string
145 {
146  return "TcpLedbat";
147 }
148 
149 uint32_t
151 {
153  if (b.buffer.empty())
154  {
155  return ~0U;
156  }
157  else
158  {
159  return b.buffer[b.min];
160  }
161 }
162 
163 uint32_t
164 TcpLedbat::CurrentDelay(FilterFunction filter)
165 {
166  NS_LOG_FUNCTION(this);
167  return filter(m_noiseFilter);
168 }
169 
170 uint32_t
172 {
173  NS_LOG_FUNCTION(this);
174  return MinCircBuf(m_baseHistory);
175 }
176 
177 void
178 TcpLedbat::IncreaseWindow(Ptr<TcpSocketState> tcb, uint32_t segmentsAcked)
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 
196 void
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 
241 void
242 TcpLedbat::AddDelay(OwdCircBuf& cb, uint32_t owd, uint32_t maxlen)
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 
273 void
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 
303 void
304 TcpLedbat::PktsAcked(Ptr<TcpSocketState> tcb, uint32_t segmentsAcked, const Time& rtt)
305 {
306  NS_LOG_FUNCTION(this << tcb << segmentsAcked << rtt);
307  if (tcb->m_rcvTimestampValue == 0 || tcb->m_rcvTimestampEchoReply == 0)
308  {
310  }
311  else
312  {
314  }
315  if (rtt.IsPositive())
316  {
321  }
322 }
323 
324 } // namespace ns3
#define min(a, b)
Definition: 80211b.c:41
#define max(a, b)
Definition: 80211b.c:42
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.
uint32_t m_segmentSize
Segment size.
TracedValue< SequenceNumber32 > m_highTxMark
Highest seqno ever sent, regardless of ReTx.
SequenceNumber32 m_lastAckedSeq
Last sequence ACKed.
TracedValue< uint32_t > m_cWnd
Congestion window.
uint32_t m_rcvTimestampEchoReply
Sender Timestamp echoed by the receiver.
TracedValue< uint32_t > m_ssThresh
Slow start threshold.
uint32_t m_rcvTimestampValue
Receiver Timestamp value.
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
T Get() const
Get the underlying value.
Definition: traced-value.h:249
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Hold an unsigned integer type.
Definition: uinteger.h:45
#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:1338
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
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:194
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
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