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 else
451 {
452 return 73;
453 }
454}
455
456double
458{
459 if (w <= 38)
460 {
461 return 0.50;
462 }
463 else if (w <= 118)
464 {
465 return 0.44;
466 }
467 else if (w <= 221)
468 {
469 return 0.41;
470 }
471 else if (w <= 347)
472 {
473 return 0.38;
474 }
475 else if (w <= 495)
476 {
477 return 0.37;
478 }
479 else if (w <= 663)
480 {
481 return 0.35;
482 }
483 else if (w <= 851)
484 {
485 return 0.34;
486 }
487 else if (w <= 1058)
488 {
489 return 0.33;
490 }
491 else if (w <= 1284)
492 {
493 return 0.32;
494 }
495 else if (w <= 1529)
496 {
497 return 0.31;
498 }
499 else if (w <= 1793)
500 {
501 return 0.30;
502 }
503 else if (w <= 2076)
504 {
505 return 0.29;
506 }
507 else if (w <= 2378)
508 {
509 return 0.28;
510 }
511 else if (w <= 2699)
512 {
513 return 0.28;
514 }
515 else if (w <= 3039)
516 {
517 return 0.27;
518 }
519 else if (w <= 3399)
520 {
521 return 0.27;
522 }
523 else if (w <= 3778)
524 {
525 return 0.26;
526 }
527 else if (w <= 4177)
528 {
529 return 0.26;
530 }
531 else if (w <= 4596)
532 {
533 return 0.25;
534 }
535 else if (w <= 5036)
536 {
537 return 0.25;
538 }
539 else if (w <= 5497)
540 {
541 return 0.24;
542 }
543 else if (w <= 5979)
544 {
545 return 0.24;
546 }
547 else if (w <= 6483)
548 {
549 return 0.23;
550 }
551 else if (w <= 7009)
552 {
553 return 0.23;
554 }
555 else if (w <= 7558)
556 {
557 return 0.22;
558 }
559 else if (w <= 8130)
560 {
561 return 0.22;
562 }
563 else if (w <= 8726)
564 {
565 return 0.22;
566 }
567 else if (w <= 9346)
568 {
569 return 0.21;
570 }
571 else if (w <= 9991)
572 {
573 return 0.21;
574 }
575 else if (w <= 10661)
576 {
577 return 0.21;
578 }
579 else if (w <= 11358)
580 {
581 return 0.20;
582 }
583 else if (w <= 12082)
584 {
585 return 0.20;
586 }
587 else if (w <= 12834)
588 {
589 return 0.20;
590 }
591 else if (w <= 13614)
592 {
593 return 0.19;
594 }
595 else if (w <= 14424)
596 {
597 return 0.19;
598 }
599 else if (w <= 15265)
600 {
601 return 0.19;
602 }
603 else if (w <= 16137)
604 {
605 return 0.19;
606 }
607 else if (w <= 17042)
608 {
609 return 0.18;
610 }
611 else if (w <= 17981)
612 {
613 return 0.18;
614 }
615 else if (w <= 18955)
616 {
617 return 0.18;
618 }
619 else if (w <= 19965)
620 {
621 return 0.17;
622 }
623 else if (w <= 21013)
624 {
625 return 0.17;
626 }
627 else if (w <= 22101)
628 {
629 return 0.17;
630 }
631 else if (w <= 23230)
632 {
633 return 0.17;
634 }
635 else if (w <= 24402)
636 {
637 return 0.16;
638 }
639 else if (w <= 25618)
640 {
641 return 0.16;
642 }
643 else if (w <= 26881)
644 {
645 return 0.16;
646 }
647 else if (w <= 28193)
648 {
649 return 0.16;
650 }
651 else if (w <= 29557)
652 {
653 return 0.15;
654 }
655 else if (w <= 30975)
656 {
657 return 0.15;
658 }
659 else if (w <= 32450)
660 {
661 return 0.15;
662 }
663 else if (w <= 33986)
664 {
665 return 0.15;
666 }
667 else if (w <= 35586)
668 {
669 return 0.14;
670 }
671 else if (w <= 37253)
672 {
673 return 0.14;
674 }
675 else if (w <= 38992)
676 {
677 return 0.14;
678 }
679 else if (w <= 40808)
680 {
681 return 0.14;
682 }
683 else if (w <= 42707)
684 {
685 return 0.13;
686 }
687 else if (w <= 44694)
688 {
689 return 0.13;
690 }
691 else if (w <= 46776)
692 {
693 return 0.13;
694 }
695 else if (w <= 48961)
696 {
697 return 0.13;
698 }
699 else if (w <= 51258)
700 {
701 return 0.13;
702 }
703 else if (w <= 53667)
704 {
705 return 0.12;
706 }
707 else if (w <= 56230)
708 {
709 return 0.12;
710 }
711 else if (w <= 58932)
712 {
713 return 0.12;
714 }
715 else if (w <= 61799)
716 {
717 return 0.12;
718 }
719 else if (w <= 64851)
720 {
721 return 0.11;
722 }
723 else if (w <= 68113)
724 {
725 return 0.11;
726 }
727 else if (w <= 71617)
728 {
729 return 0.11;
730 }
731 else if (w <= 75401)
732 {
733 return 0.10;
734 }
735 else if (w <= 79517)
736 {
737 return 0.10;
738 }
739 else if (w <= 84035)
740 {
741 return 0.10;
742 }
743 else if (w <= 89053)
744 {
745 return 0.10;
746 }
747 else if (w <= 94717)
748 {
749 return 0.09;
750 }
751 else
752 {
753 return 0.09;
754 }
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.