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