A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tcp-highspeed.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
8#include "tcp-highspeed.h"
9
10#include "tcp-socket-state.h"
11
12#include "ns3/log.h"
13
14namespace ns3
15{
16
17NS_LOG_COMPONENT_DEFINE("TcpHighSpeed");
18NS_OBJECT_ENSURE_REGISTERED(TcpHighSpeed);
19
20TypeId
22{
23 static TypeId tid = TypeId("ns3::TcpHighSpeed")
25 .AddConstructor<TcpHighSpeed>()
26 .SetGroupName("Internet");
27 return tid;
28}
29
31 : TcpNewReno(),
32 m_ackCnt(0)
33{
34 NS_LOG_FUNCTION(this);
35}
36
38 : TcpNewReno(sock),
39 m_ackCnt(sock.m_ackCnt)
40{
41 NS_LOG_FUNCTION(this);
42}
43
48
54
55/**
56 * \brief Congestion avoidance of TcpHighSpeed
57 *
58 * As implementation choice, we increment cWnd only by MSS, when the right
59 * number of ACK has been received. At this point, the important question is:
60 * what is the "right number of ACK" ?
61 *
62 * As you can recall from RFC, Highspeed works this way:
63 *
64 * w = w + a(w)/w
65 *
66 * Let's start when a(w) is 1 (so it is classical NewReno). The formula then is
67 * the classical text-book version for NewReno:
68 *
69 * w = w + 1 / w
70 *
71 * So, for each segment acked, we increase the window by the quantity 1/w. Or,
72 * instead of adding the 1/w quantity for each segment acked, we can track the
73 * number of segments acked (m_ackCnt) and increment by 1 MSS when m_ackCnt
74 * reaches w.
75 *
76 * When a(w) > 1, it means that each segment acked has a different "weight".
77 * For instance, when it is equal to 2, we need to increase the window by the
78 * quantity 2/w. But, this means that one segment acked is equivalent (from
79 * the point of view of incrementing cWnd) to two segments acked in NewReno
80 * (1/w + 1/w). That a coefficient is, in other word, the weight of each segment
81 * acked. More weight, less ACK are necessary to increment cWnd, which is
82 * exactly the Highspeed principle.
83 *
84 * \param tcb internal congestion state
85 * \param segmentsAcked count of segments acked
86 */
87void
89{
90 NS_LOG_FUNCTION(this << tcb << segmentsAcked);
91
92 uint32_t segCwnd = tcb->GetCwndInSegments();
93 uint32_t oldCwnd = segCwnd;
94
95 if (segmentsAcked > 0)
96 {
97 uint32_t coeffA = TableLookupA(segCwnd);
98 m_ackCnt += segmentsAcked * coeffA;
99 }
100
101 while (m_ackCnt >= segCwnd)
102 {
103 m_ackCnt -= segCwnd;
104 segCwnd += 1;
105 }
106
107 if (segCwnd != oldCwnd)
108 {
109 tcb->m_cWnd = segCwnd * tcb->m_segmentSize;
110 NS_LOG_INFO("In CongAvoid, updated to cwnd " << tcb->m_cWnd << " ssthresh "
111 << tcb->m_ssThresh);
112 }
113}
114
115std::string
117{
118 return "TcpHighSpeed";
119}
120
121/**
122 * \brief Get slow start threshold following HighSpeed principles
123 *
124 * \param tcb internal congestion state
125 * \param bytesInFlight Bytes in flight
126 *
127 * \return the slow start threshold value
128 */
131{
132 NS_LOG_FUNCTION(this << tcb << bytesInFlight);
133
134 uint32_t segCwnd = bytesInFlight / tcb->m_segmentSize;
135
136 double b = 1.0 - TableLookupB(segCwnd);
137 uint32_t ssThresh = static_cast<uint32_t>(std::max(2.0, segCwnd * b));
138
139 NS_LOG_DEBUG("Calculated b(w) = " << b << " resulting (in segment) ssThresh=" << ssThresh);
140
141 return ssThresh * tcb->m_segmentSize;
142}
143
146{
147 if (w <= 38)
148 {
149 return 1;
150 }
151 else if (w <= 118)
152 {
153 return 2;
154 }
155 else if (w <= 221)
156 {
157 return 3;
158 }
159 else if (w <= 347)
160 {
161 return 4;
162 }
163 else if (w <= 495)
164 {
165 return 5;
166 }
167 else if (w <= 663)
168 {
169 return 6;
170 }
171 else if (w <= 851)
172 {
173 return 7;
174 }
175 else if (w <= 1058)
176 {
177 return 8;
178 }
179 else if (w <= 1284)
180 {
181 return 9;
182 }
183 else if (w <= 1529)
184 {
185 return 10;
186 }
187 else if (w <= 1793)
188 {
189 return 11;
190 }
191 else if (w <= 2076)
192 {
193 return 12;
194 }
195 else if (w <= 2378)
196 {
197 return 13;
198 }
199 else if (w <= 2699)
200 {
201 return 14;
202 }
203 else if (w <= 3039)
204 {
205 return 15;
206 }
207 else if (w <= 3399)
208 {
209 return 16;
210 }
211 else if (w <= 3778)
212 {
213 return 17;
214 }
215 else if (w <= 4177)
216 {
217 return 18;
218 }
219 else if (w <= 4596)
220 {
221 return 19;
222 }
223 else if (w <= 5036)
224 {
225 return 20;
226 }
227 else if (w <= 5497)
228 {
229 return 21;
230 }
231 else if (w <= 5979)
232 {
233 return 22;
234 }
235 else if (w <= 6483)
236 {
237 return 23;
238 }
239 else if (w <= 7009)
240 {
241 return 24;
242 }
243 else if (w <= 7558)
244 {
245 return 25;
246 }
247 else if (w <= 8130)
248 {
249 return 26;
250 }
251 else if (w <= 8726)
252 {
253 return 27;
254 }
255 else if (w <= 9346)
256 {
257 return 28;
258 }
259 else if (w <= 9991)
260 {
261 return 29;
262 }
263 else if (w <= 10661)
264 {
265 return 30;
266 }
267 else if (w <= 11358)
268 {
269 return 31;
270 }
271 else if (w <= 12082)
272 {
273 return 32;
274 }
275 else if (w <= 12834)
276 {
277 return 33;
278 }
279 else if (w <= 13614)
280 {
281 return 34;
282 }
283 else if (w <= 14424)
284 {
285 return 35;
286 }
287 else if (w <= 15265)
288 {
289 return 36;
290 }
291 else if (w <= 16137)
292 {
293 return 37;
294 }
295 else if (w <= 17042)
296 {
297 return 38;
298 }
299 else if (w <= 17981)
300 {
301 return 39;
302 }
303 else if (w <= 18955)
304 {
305 return 40;
306 }
307 else if (w <= 19965)
308 {
309 return 41;
310 }
311 else if (w <= 21013)
312 {
313 return 42;
314 }
315 else if (w <= 22101)
316 {
317 return 43;
318 }
319 else if (w <= 23230)
320 {
321 return 44;
322 }
323 else if (w <= 24402)
324 {
325 return 45;
326 }
327 else if (w <= 25618)
328 {
329 return 46;
330 }
331 else if (w <= 26881)
332 {
333 return 47;
334 }
335 else if (w <= 28193)
336 {
337 return 48;
338 }
339 else if (w <= 29557)
340 {
341 return 49;
342 }
343 else if (w <= 30975)
344 {
345 return 50;
346 }
347 else if (w <= 32450)
348 {
349 return 51;
350 }
351 else if (w <= 33986)
352 {
353 return 52;
354 }
355 else if (w <= 35586)
356 {
357 return 53;
358 }
359 else if (w <= 37253)
360 {
361 return 54;
362 }
363 else if (w <= 38992)
364 {
365 return 55;
366 }
367 else if (w <= 40808)
368 {
369 return 56;
370 }
371 else if (w <= 42707)
372 {
373 return 57;
374 }
375 else if (w <= 44694)
376 {
377 return 58;
378 }
379 else if (w <= 46776)
380 {
381 return 59;
382 }
383 else if (w <= 48961)
384 {
385 return 60;
386 }
387 else if (w <= 51258)
388 {
389 return 61;
390 }
391 else if (w <= 53667)
392 {
393 return 62;
394 }
395 else if (w <= 56230)
396 {
397 return 63;
398 }
399 else if (w <= 58932)
400 {
401 return 64;
402 }
403 else if (w <= 61799)
404 {
405 return 65;
406 }
407 else if (w <= 64851)
408 {
409 return 66;
410 }
411 else if (w <= 68113)
412 {
413 return 67;
414 }
415 else if (w <= 71617)
416 {
417 return 68;
418 }
419 else if (w <= 75401)
420 {
421 return 69;
422 }
423 else if (w <= 79517)
424 {
425 return 70;
426 }
427 else if (w <= 84035)
428 {
429 return 71;
430 }
431 else if (w <= 89053)
432 {
433 return 72;
434 }
435 else if (w <= 94717)
436 {
437 return 73;
438 }
439
440 return 73;
441}
442
443double
445{
446 // NOLINTBEGIN(bugprone-branch-clone)
447 if (w <= 38)
448 {
449 return 0.50;
450 }
451 else if (w <= 118)
452 {
453 return 0.44;
454 }
455 else if (w <= 221)
456 {
457 return 0.41;
458 }
459 else if (w <= 347)
460 {
461 return 0.38;
462 }
463 else if (w <= 495)
464 {
465 return 0.37;
466 }
467 else if (w <= 663)
468 {
469 return 0.35;
470 }
471 else if (w <= 851)
472 {
473 return 0.34;
474 }
475 else if (w <= 1058)
476 {
477 return 0.33;
478 }
479 else if (w <= 1284)
480 {
481 return 0.32;
482 }
483 else if (w <= 1529)
484 {
485 return 0.31;
486 }
487 else if (w <= 1793)
488 {
489 return 0.30;
490 }
491 else if (w <= 2076)
492 {
493 return 0.29;
494 }
495 else if (w <= 2378)
496 {
497 return 0.28;
498 }
499 else if (w <= 2699)
500 {
501 return 0.28;
502 }
503 else if (w <= 3039)
504 {
505 return 0.27;
506 }
507 else if (w <= 3399)
508 {
509 return 0.27;
510 }
511 else if (w <= 3778)
512 {
513 return 0.26;
514 }
515 else if (w <= 4177)
516 {
517 return 0.26;
518 }
519 else if (w <= 4596)
520 {
521 return 0.25;
522 }
523 else if (w <= 5036)
524 {
525 return 0.25;
526 }
527 else if (w <= 5497)
528 {
529 return 0.24;
530 }
531 else if (w <= 5979)
532 {
533 return 0.24;
534 }
535 else if (w <= 6483)
536 {
537 return 0.23;
538 }
539 else if (w <= 7009)
540 {
541 return 0.23;
542 }
543 else if (w <= 7558)
544 {
545 return 0.22;
546 }
547 else if (w <= 8130)
548 {
549 return 0.22;
550 }
551 else if (w <= 8726)
552 {
553 return 0.22;
554 }
555 else if (w <= 9346)
556 {
557 return 0.21;
558 }
559 else if (w <= 9991)
560 {
561 return 0.21;
562 }
563 else if (w <= 10661)
564 {
565 return 0.21;
566 }
567 else if (w <= 11358)
568 {
569 return 0.20;
570 }
571 else if (w <= 12082)
572 {
573 return 0.20;
574 }
575 else if (w <= 12834)
576 {
577 return 0.20;
578 }
579 else if (w <= 13614)
580 {
581 return 0.19;
582 }
583 else if (w <= 14424)
584 {
585 return 0.19;
586 }
587 else if (w <= 15265)
588 {
589 return 0.19;
590 }
591 else if (w <= 16137)
592 {
593 return 0.19;
594 }
595 else if (w <= 17042)
596 {
597 return 0.18;
598 }
599 else if (w <= 17981)
600 {
601 return 0.18;
602 }
603 else if (w <= 18955)
604 {
605 return 0.18;
606 }
607 else if (w <= 19965)
608 {
609 return 0.17;
610 }
611 else if (w <= 21013)
612 {
613 return 0.17;
614 }
615 else if (w <= 22101)
616 {
617 return 0.17;
618 }
619 else if (w <= 23230)
620 {
621 return 0.17;
622 }
623 else if (w <= 24402)
624 {
625 return 0.16;
626 }
627 else if (w <= 25618)
628 {
629 return 0.16;
630 }
631 else if (w <= 26881)
632 {
633 return 0.16;
634 }
635 else if (w <= 28193)
636 {
637 return 0.16;
638 }
639 else if (w <= 29557)
640 {
641 return 0.15;
642 }
643 else if (w <= 30975)
644 {
645 return 0.15;
646 }
647 else if (w <= 32450)
648 {
649 return 0.15;
650 }
651 else if (w <= 33986)
652 {
653 return 0.15;
654 }
655 else if (w <= 35586)
656 {
657 return 0.14;
658 }
659 else if (w <= 37253)
660 {
661 return 0.14;
662 }
663 else if (w <= 38992)
664 {
665 return 0.14;
666 }
667 else if (w <= 40808)
668 {
669 return 0.14;
670 }
671 else if (w <= 42707)
672 {
673 return 0.13;
674 }
675 else if (w <= 44694)
676 {
677 return 0.13;
678 }
679 else if (w <= 46776)
680 {
681 return 0.13;
682 }
683 else if (w <= 48961)
684 {
685 return 0.13;
686 }
687 else if (w <= 51258)
688 {
689 return 0.13;
690 }
691 else if (w <= 53667)
692 {
693 return 0.12;
694 }
695 else if (w <= 56230)
696 {
697 return 0.12;
698 }
699 else if (w <= 58932)
700 {
701 return 0.12;
702 }
703 else if (w <= 61799)
704 {
705 return 0.12;
706 }
707 else if (w <= 64851)
708 {
709 return 0.11;
710 }
711 else if (w <= 68113)
712 {
713 return 0.11;
714 }
715 else if (w <= 71617)
716 {
717 return 0.11;
718 }
719 else if (w <= 75401)
720 {
721 return 0.10;
722 }
723 else if (w <= 79517)
724 {
725 return 0.10;
726 }
727 else if (w <= 84035)
728 {
729 return 0.10;
730 }
731 else if (w <= 89053)
732 {
733 return 0.10;
734 }
735 else if (w <= 94717)
736 {
737 return 0.09;
738 }
739 else
740 {
741 return 0.09;
742 }
743 // NOLINTEND(bugprone-branch-clone)
744}
745
746} // namespace ns3
friend Ptr< T > CopyObject(Ptr< T > object)
Copy an Object.
Definition object.h:581
Smart pointer class similar to boost::intrusive_ptr.
An implementation of TCP HighSpeed.
~TcpHighSpeed() override
static double TableLookupB(uint32_t w)
Lookup table for the coefficient b (from RFC 3649)
static uint32_t TableLookupA(uint32_t w)
Lookup table for the coefficient a (from RFC 3649)
uint32_t GetSsThresh(Ptr< const TcpSocketState > tcb, uint32_t bytesInFlight) override
Get slow start threshold following HighSpeed principles.
void CongestionAvoidance(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked) override
Congestion avoidance of TcpHighSpeed.
std::string GetName() const override
Get the name of the congestion control algorithm.
static TypeId GetTypeId()
Get the type ID.
TcpHighSpeed()
Create an unbound tcp socket.
Ptr< TcpCongestionOps > Fork() override
Copy the congestion control algorithm across sockets.
uint32_t m_ackCnt
Number of received ACK, corrected with the coefficient a.
The NewReno implementation.
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
#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_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.