NetSim Source Code Help
Loading...
Searching...
No Matches
CUBIC.c
Go to the documentation of this file.
1/************************************************************************************
2* Copyright (C) 2020 *
3* TETCOS, Bangalore. India *
4* *
5* Tetcos owns the intellectual property rights in the Product and its content. *
6* The copying, redistribution, reselling or publication of any or all of the *
7* Product or its content without express prior written consent of Tetcos is *
8* prohibited. Ownership and / or any other right relating to the software and all *
9* intellectual property rights therein shall remain at all times with Tetcos. *
10* *
11* Author: Shashi Kant Suman *
12* *
13* ---------------------------------------------------------------------------------*/
14#include "main.h"
15#include "TCP.h"
16#include <intrin.h>
17
18//#define _TEST_CONGESTION_
19
20#ifdef _TEST_CONGESTION_
21static FILE* fp;
22#endif
23
24#define clamp(val, lo, hi) min(max(val, lo), hi)
25
26#define tcp_time_stamp ((UINT32)(pstruEventDetails->dEventTime/1000))
27#define CUBIC_HZ 1024
28
29#define BICTCP_BETA_SCALE 1024 /* Scale factor beta calculation
30* max_cwnd = snd_cwnd * beta
31*/
32#define BICTCP_HZ 10 /* BIC HZ 2^10 = 1024 */
34/* Two methods of hybrid slow start */
35#define HYSTART_ACK_TRAIN 0x1
36#define HYSTART_DELAY 0x2
38/* Number of delay samples for detecting the increase of delay */
39#define HYSTART_MIN_SAMPLES 8
40#define HYSTART_DELAY_MIN (4U<<3)
41#define HYSTART_DELAY_MAX (16U<<3)
42#define HYSTART_DELAY_THRESH(x) clamp(x, HYSTART_DELAY_MIN, HYSTART_DELAY_MAX)
44static int fast_convergence = 1;
45static int tcp_friendliness = 1;
47static int hystart = 1;
52static UINT32 beta_scale;
54
55typedef struct stru_cubic
60 int beta; /* = 717/1024 (BICTCP_BETA_SCALE) */
63 UINT32 cnt; /* increase cwnd by 1 after ACKs */
64 UINT32 last_max_cwnd; /* last maximum snd_cwnd */
65 UINT32 loss_cwnd; /* congestion window at last loss */
66 UINT32 last_cwnd; /* the last snd_cwnd */
67 UINT32 last_time; /* time when updated last_cwnd */
68 UINT32 bic_origin_point;/* origin point of bic function */
69 UINT32 bic_K; /* time to origin point
70 from the beginning of the current epoch */
71 UINT32 delay_min; /* min delay (msec << 3) */
72 UINT32 epoch_start; /* beginning of an epoch */
73 UINT32 ack_cnt; /* number of acks */
74 UINT32 tcp_cwnd; /* estimated tcp cwnd */
76 UINT8 sample_cnt; /* number of samples to decide curr_rtt */
77 UINT8 found; /* the exit point is found? */
78 UINT32 round_start; /* beginning of each round */
79 UINT32 end_seq; /* end_seq of the round */
80 UINT32 last_ack; /* last time when the ACK spacing is close */
81 UINT32 curr_rtt; /* the minimum rtt of current round */
83}CUBIC, *PCUBIC;
84
85typedef struct stru_congestion_var
86{
87 UINT16 SMSS; ///< To store the size of the largest segment that the sender can transmit.
88 UINT16 RMSS; ///< To store the size of the largest segment that the receiver is willing to accept.
89 UINT16 IW; ///< Size of the sender's congestion window after the three-way handshake is completed.
90 UINT16 LW;
91 UINT16 ssthresh; ///< To store slow start threshold value
92 UINT16 cwnd; ///< To store Congestion window size value.
93 UINT16 rwnd; ///< To store the most recently advertised receiver window size value.
94 double lastWinUpdateTime;
95
96 //Fast Retransmit
99
100 //Fast Recovery
101 bool isFastRecovery;
102
103 //SACK
106 //CUBIC
107 CUBIC cubic;
109
111{
114
115static inline void set_congestionvar(PNETSIM_SOCKET s, PCONGESTIONVAR data)
116{
117 s->tcb->congestionData = data;
119
120static void set_cwnd(PNETSIM_SOCKET s, UINT32 newcwnd)
121{
123 if (s->tcb->isWindowScaling)
124 {
125 UINT32 c = (UINT32)newcwnd;
126 var->cwnd = (UINT16)(c >> s->tcb->Snd.Wind_Shift);
127 assert(var->cwnd < 65535);
128 }
129 else
130 {
131 var->cwnd = (UINT16)newcwnd;
132 }
134
136{
138 UINT32 c = (UINT32)var->cwnd;
139 if (s->tcb->isWindowScaling)
140 {
141 return c << s->tcb->Snd.Wind_Shift;
142 }
143 else
144 {
145 return c;
146 }
148
149static void set_ssthres(PNETSIM_SOCKET s, UINT32 newssthres)
150{
152 if (s->tcb->isWindowScaling)
153 {
154 UINT32 c = (UINT32)newssthres;
155 var->ssthresh = (UINT16)(c >> s->tcb->Snd.Wind_Shift);
156 }
157 else
158 {
159 var->ssthresh = (UINT16)newssthres;
160 }
162
164{
166 UINT32 c = (UINT32)var->ssthresh;
167 if (s->tcb->isWindowScaling)
168 {
169 return c << s->tcb->Snd.Wind_Shift;
170 }
171 else
172 {
173 return c;
174 }
176
177static void increase_cwnd(PNETSIM_SOCKET s, UINT16 increase)
178{
180 if (s->tcb->isWindowScaling)
181 {
183 c += increase;
184 var->cwnd = (UINT16)(c >> s->tcb->Snd.Wind_Shift);
185 assert(var->cwnd < 65535);
186 }
187 else
188 {
189 UINT32 c = var->cwnd + increase;
190 if (c >= 65535)
191 var->cwnd = 65535; // Don't want to do this. But no option.
192 else
193 var->cwnd = var->cwnd + increase;
194 }
196
197static inline bool tcp_in_slow_start(PNETSIM_SOCKET s)
198{
199 return (get_cwnd(s) <= get_ssthres(s));
201
202static bool isDupAck(PNETSIM_SOCKET s, PCONGESTIONVAR var)
203{
204 return (s->tcb->SEG.ACK <= s->tcb->SND.UNA);
205}
206
207/**
208* div64_u64 - unsigned 64bit divide with 64bit divisor
209*/
210static inline UINT64 div64_u64(UINT64 dividend, UINT64 divisor)
211{
212 return dividend / divisor;
214
215#define do_div(x,y) (x=x/y)
216
217static inline bool before(UINT32 seq1, UINT32 seq2)
218{
219 return (int)(seq1 - seq2) < 0;
220}
221#define after(seq2, seq1) before(seq1, seq2)
222
223static UINT count_bit(UINT64 n)
224{
225 char a[100];
226 _i64toa(n, a, 2);
227 int i;
228 int len = (int)strlen(a);
229 for (i = 0; i < len; i++)
230 if (a[i] == '1')
231 return i;
232 return 0;
234
235static void slowStart(PNETSIM_SOCKET s, PCONGESTIONVAR var)
236{
237 //Slow start mode
238 UINT16 N; /* N is the number of previously unacknowledged
239 * bytes acknowledged in the incoming ACK.
240 */
241 N = (UINT16)(s->tcb->SEG.ACK - s->tcb->SND.UNA);
242 increase_cwnd(s, min(N, var->SMSS));
244
245static inline void cubictcp_reset(PCUBIC ca)
246{
247 ca->cnt = 0;
248 ca->last_max_cwnd = 0;
249 ca->last_cwnd = 0;
250 ca->last_time = 0;
251 ca->bic_origin_point = 0;
252 ca->bic_K = 0;
253 ca->delay_min = 0;
254 ca->epoch_start = 0;
255 ca->ack_cnt = 0;
256 ca->tcp_cwnd = 0;
257 ca->found = 0;
259
260static inline UINT32 cubictcp_clock(void)
261{
262 return (UINT32)(pstruEventDetails->dEventTime / 1000);
264
265static inline void cubictcp_hystart_reset(PNETSIM_SOCKET sk)
266{
267 PCUBIC ca = &get_congestionvar(sk)->cubic;
268
269 ca->round_start = ca->last_ack = cubictcp_clock();
270 ca->end_seq = sk->tcb->SND.NXT;
271 ca->curr_rtt = 0;
272 ca->sample_cnt = 0;
274
275static void cubictcp_init(PNETSIM_SOCKET sk, PTCP_DEV_VAR tcp)
276{
277 PCUBIC ca = &get_congestionvar(sk)->cubic;
278
279 cubictcp_reset(ca);
280 ca->loss_cwnd = 0;
281
284 ca->beta = (int)tcp->beta;
285 ca->bic_scale = tcp->bic_scale;
287
288 if (hystart)
291
293{
296 if (!var)
297 {
298 var = (PCONGESTIONVAR)calloc(1, sizeof* var);
299 set_congestionvar(s, var);
300 }
301 var->SMSS = tcp->MSS;
302 var->RMSS = tcp->MSS;
303 set_ssthres(s, tcp->initSSThresh);
304 var->cwnd = var->ssthresh;
305 var->rwnd = var->ssthresh;
306
307 var->isFastRetransmit = true;
308
309 cubictcp_init(s,tcp);
310 PCUBIC cubic = &var->cubic;
311
312 beta_scale = 8 * (BICTCP_BETA_SCALE + cubic->beta) / 3
313 / (BICTCP_BETA_SCALE - cubic->beta);
314
315 cube_rtt_scale = (cubic->bic_scale * 10); /* 1024*c/rtt */
316
317 /* calculate the "K" for (wmax-cwnd) = c/rtt * K^3
318 * so K = cubic_root( (wmax-cwnd)*rtt/c )
319 * the unit of K is bictcp_HZ=2^10, not HZ
320 *
321 * c = bic_scale >> 10
322 * rtt = 100ms
323 *
324 * the following code has been designed and tested for
325 * cwnd < 1 million packets
326 * RTT < 100 seconds
327 * HZ < 1,000,00 (corresponding to 10 nano-second)
328 */
329
330 /* 1/c * 2^2*bictcp_HZ * srtt */
331
332#pragma warning(disable:4310)
333 cube_factor = (UINT32)(1ull << (10 + 3 * BICTCP_HZ)); /* 2^40 */
334#pragma warning(default:4310)
335
336 /* divide by bic_scale and by constant Srtt (100ms) */
337 do_div(cube_factor, cubic->bic_scale * 10);
338
339
340#ifdef _TEST_CONGESTION_
341 fp = fopen("Congestion.csv", "w");
342 fprintf(fp, "Called For,Time,CWND,ssThres,Flight Size,Ackno,UNA,\n");
343 fflush(fp);
344#endif
345}
346
347/* calculate the cubic root of x using a table lookup followed by one
348* Newton-Raphson iteration.
349* Avg err ~= 0.195%
350*/
352{
353 UINT32 x, b, shift;
354 /*
355 * cbrt(x) MSB values for x MSB values in [0..63].
356 * Precomputed then refined by hand - Willy Tarreau
357 *
358 * For x in [0..63],
359 * v = cbrt(x << 18) - 1
360 * cbrt(x) = (v[x] + 10) >> 6
361 */
362 static const UINT8 v[] = {
363 /* 0x00 */ 0, 54, 54, 54, 118, 118, 118, 118,
364 /* 0x08 */ 123, 129, 134, 138, 143, 147, 151, 156,
365 /* 0x10 */ 157, 161, 164, 168, 170, 173, 176, 179,
366 /* 0x18 */ 181, 185, 187, 190, 192, 194, 197, 199,
367 /* 0x20 */ 200, 202, 204, 206, 209, 211, 213, 215,
368 /* 0x28 */ 217, 219, 221, 222, 224, 225, 227, 229,
369 /* 0x30 */ 231, 232, 234, 236, 237, 239, 240, 242,
370 /* 0x38 */ 244, 245, 246, 248, 250, 251, 252, 254,
371 };
372
373 b = count_bit(a);
374 if (b < 7) {
375 /* a in [0..63] */
376 return ((UINT32)v[(UINT32)a] + 35) >> 6;
377 }
378
379 b = ((b * 84) >> 8) - 1;
380 shift = (UINT32)(a >> (b * 3));
381
382 x = ((UINT32)(((UINT32)v[shift] + 10) << b)) >> 6;
383
384 /*
385 * Newton-Raphson iteration
386 * 2
387 * x = ( 2 * x + a / x ) / 3
388 * k+1 k k
389 */
390 x = (2 * x + (UINT32)div64_u64(a, (UINT64)x * (UINT64)(x - 1)));
391 x = ((x * 341) >> 10);
392 return x;
394
396{
397 PCUBIC ca = &get_congestionvar(sk)->cubic;
398
399 UINT32 segCwnd = (UINT32)get_cwnd(sk) / sk->tcb->get_MSS(sk);
400
401 ca->epoch_start = 0; /* end of epoch */
402
403 /* Wmax and fast convergence */
404 if (segCwnd < ca->last_max_cwnd && fast_convergence)
405 ca->last_max_cwnd = (segCwnd * (BICTCP_BETA_SCALE + ca->beta))
406 / (2 * BICTCP_BETA_SCALE);
407 else
408 ca->last_max_cwnd = segCwnd;
409
410 ca->loss_cwnd = segCwnd;
411
412 return max((segCwnd * ca->beta) / BICTCP_BETA_SCALE, 2U);
413}
414
415/*
416* Compute congestion window to use.
417*/
418static inline void cubictcp_update(PNETSIM_SOCKET sk, UINT32 acked)
419{
421 PCUBIC ca = &c->cubic;
422 UINT32 cwnd = (UINT32)get_cwnd(sk) / sk->tcb->get_MSS(sk);
423
424 UINT32 delta, bic_target, max_cnt;
425 UINT64 offs, t;
426
427 ca->ack_cnt += acked; /* count the number of ACKed packets */
428
429 if (ca->last_cwnd == cwnd &&
430 (int)(tcp_time_stamp - ca->last_time) <= CUBIC_HZ / 32)
431 return;
432
433 /* The CUBIC function can update ca->cnt at most once per jiffy.
434 * On all cwnd reduction events, ca->epoch_start is set to 0,
435 * which will force a recalculation of ca->cnt.
436 */
437 if (ca->epoch_start && tcp_time_stamp == ca->last_time)
438 goto tcp_friendliness;
439
440 ca->last_cwnd = cwnd;
442
443 if (ca->epoch_start == 0)
444 {
445 ca->epoch_start = tcp_time_stamp; /* record beginning */
446 ca->ack_cnt = acked; /* start counting */
447 ca->tcp_cwnd = cwnd; /* syn with cubic */
448
449 if (ca->last_max_cwnd <= cwnd)
450 {
451 ca->bic_K = 0;
452 ca->bic_origin_point = cwnd;
453 }
454 else
455 {
456 /* Compute new K based on
457 * (wmax-cwnd) * (srtt>>3 / HZ) / c * 2^(3*bictcp_HZ)
458 */
460 * (ca->last_max_cwnd - cwnd));
462 }
463 }
464
465 /* cubic function - calc*/
466 /* calculate c * time^3 / rtt,
467 * while considering overflow in calculation of time^3
468 * (so time^3 is done by using 64 bit)
469 * and without the support of division of 64bit numbers
470 * (so all divisions are done by using 32 bit)
471 * also NOTE the unit of those veriables
472 * time = (t - K) / 2^bictcp_HZ
473 * c = bic_scale >> 10
474 * rtt = (srtt >> 3) / HZ
475 * !!! The following code does not have overflow problems,
476 * if the cwnd < 1 million packets !!!
477 */
478
479 t = (int)(tcp_time_stamp - ca->epoch_start);
480 t += (ca->delay_min >> 3);
481 /* change the unit from HZ to bictcp_HZ */
482 t <<= BICTCP_HZ;
483 do_div(t, CUBIC_HZ);
484
485 if (t < ca->bic_K) /* t - K */
486 offs = ca->bic_K - t;
487 else
488 offs = t - ca->bic_K;
489
490 /* c/rtt * (t-K)^3 */
491 delta = (cube_rtt_scale * offs * offs * offs) >> (10 + 3 * BICTCP_HZ);
492 if (t < ca->bic_K) /* below origin*/
493 bic_target = ca->bic_origin_point - delta;
494 else /* above origin*/
495 bic_target = ca->bic_origin_point + delta;
496
497 /* cubic function - calc bictcp_cnt*/
498 if (bic_target > cwnd)
499 {
500 ca->cnt = cwnd / (bic_target - cwnd);
501 }
502 else
503 {
504 ca->cnt = 100 * cwnd; /* very small increment*/
505 }
506
507 /*
508 * The initial growth of cubic function may be too conservative
509 * when the available bandwidth is still unknown.
510 */
511 if (ca->last_max_cwnd == 0 && ca->cnt > 20)
512 ca->cnt = 20; /* increase cwnd 5% per RTT */
513
515 /* TCP Friendly */
517 {
518 UINT32 scale = beta_scale;
519
520 delta = (cwnd * scale) >> 3;
521 while (delta && ca->ack_cnt > delta)
522 { /* update tcp cwnd */
523 ca->ack_cnt -= delta;
524 ca->tcp_cwnd++;
525 }
526
527 if (ca->tcp_cwnd > cwnd)
528 { /* if bic is slower than tcp */
529 delta = ca->tcp_cwnd - cwnd;
530 max_cnt = cwnd / delta;
531 if (ca->cnt > max_cnt)
532 ca->cnt = max_cnt;
533 }
534 }
535
536 /* The maximum rate of cwnd increase CUBIC allows is 1 packet per
537 * 2 packets ACKed, meaning cwnd grows at 1.5x per RTT.
538 */
539 ca->cnt = max(ca->cnt, 2U);
540
542
543static void cubictcp_cong_avoid(PNETSIM_SOCKET sk, UINT32 segmentAcked)
544{
546 PCUBIC ca = &var->cubic;
547 UINT32 ack = sk->tcb->SEG.ACK;
548
549 if (tcp_in_slow_start(sk))
550 {
551 if (hystart && after(ack, ca->end_seq))
554 segmentAcked--;
555 }
556
557 if (!tcp_in_slow_start(sk) && segmentAcked > 0)
558 {
559
560 ca->cwndcnt += segmentAcked;
561 cubictcp_update(sk,segmentAcked);
562 UINT32 cnt = ca->cnt;
563 /* According to the BIC paper and RFC 6356 even once the new cwnd is
564 * calculated you must compare this to the number of ACKs received since
565 * the last cwnd update. If not enough ACKs have been received then cwnd
566 * cannot be updated.
567 */
568 if (ca->cwndcnt > cnt)
569 {
570 increase_cwnd(sk, var->SMSS);
571 ca->cwndcnt = 0;
572 }
573 else
574 {
575 //Not enough segments have been ACKed to increment cwnd
576 }
577 }
579
580static void hystart_update(PNETSIM_SOCKET sk, UINT32 delay)
581{
583 PCUBIC ca = &var->cubic;
584
585 if (ca->found & hystart_detect)
586 return;
587
589 UINT32 now = cubictcp_clock();
590
591 /* first detection parameter - ack-train detection */
592 if ((int)(now - ca->last_ack) <= ca->hystart_ack_delta)
593 {
594 ca->last_ack = now;
595 if ((int)(now - ca->round_start) > ca->delay_min >> 4)
596 {
598 if(get_ssthres(sk) != ca->initial_ssthresh)
599 set_cwnd(sk, get_ssthres(sk));
600 }
601 }
602 }
603
605 {
606 /* obtain the minimum delay of more than sampling packets */
608 {
609 if (ca->curr_rtt == 0 || ca->curr_rtt > delay)
610 ca->curr_rtt = delay;
611
612 ca->sample_cnt++;
613 }
614 else
615 {
616 if (ca->curr_rtt > ca->delay_min +
618 {
619 ca->found |= HYSTART_DELAY;
620 set_ssthres(sk, get_cwnd(sk));
621 }
622 }
623 }
624}
625
626/* Track delayed acknowledgment ratio using sliding window
627* ratio = (15*ratio + sample) / 16
628*/
629static void cubictcp_acked(PNETSIM_SOCKET sk)
630{
631 PCUBIC ca = &get_congestionvar(sk)->cubic;
632 UINT32 delay;
633 UINT32 cwnd = (UINT32)get_cwnd(sk) / sk->tcb->get_MSS(sk);
634 delay = (UINT32)((((UINT32)get_RTT(sk->tcb, sk->tcb->SEG.ACK)) << 3) / MILLISECOND);
635 if (!delay)
636 delay = 1;
637
638 /* hystart triggers when cwnd is larger than some threshold */
639 if (hystart && tcp_in_slow_start(sk) &&
640 cwnd >= ca->hystart_low_window)
641 hystart_update(sk, delay);
643
645{
647
648 if (var->dupAckCount == TCP_DupThresh)
649 {
650 UINT32 ssThresh = cubictcp_recalc_ssthresh(s);
651 set_ssthres(s, ssThresh*s->tcb->get_MSS(s));
652
653 /*
654 3. The lost segment starting at SND.UNA MUST be retransmitted and
655 cwnd set to ssthresh plus 3*SMSS. This artificially "inflates"
656 the congestion window by the number of segments (three) that have
657 left the network and which the receiver has buffered.
658 */
659 set_cwnd(s, get_ssthres(s) + TCP_DupThresh * var->SMSS);
661
662 var->isFastRecovery = true;
663
664 if (s->tcb->isSackOption)
665 {
667 var->isLossRecoveryPhase = true;
668 }
669 }
670 else
671 {
672 /*
673 4. For each additional duplicate ACK received(after the third),
674 cwnd MUST be incremented by SMSS.This artificially inflates the
675 congestion window in order to reflect the additional segment that
676 has left the network.
677 */
678 increase_cwnd(s, var->SMSS);
679
680 if (s->tcb->isSackOption &&
682 {
684 }
685 }
687
689{
690 var->isFastRecovery = false;
691 var->dupAckCount = 0;
692 set_cwnd(s, get_ssthres(s));
694
696 {
698 UINT32 segmentAcked = (s->tcb->SEG.ACK - s->tcb->SND.UNA) /
699 s->tcb->get_MSS(s);
700
701 bool isdup = isDupAck(s, var);
702 if (isdup)
703 {
704 var->dupAckCount++;
705 if (var->dupAckCount < TCP_DupThresh)
706 {
707 if (s->tcb->isSackOption &&
708 tcp_sack_isLost(s, get_highAck(s) + 1))
709 {
711 }
712 }
713 else
714 {
716 }
717 }
718 else if (var->isFastRecovery)
719 {
720 FastRecovery(s, var);
721 }
722 else
723 {
725 cubictcp_cong_avoid(s, segmentAcked);
726 }
727
728#ifdef _TEST_CONGESTION_
729 fprintf(fp, "Ack,%lf,%d,%d,%d,%d,%d\n",
732 get_ssthres(s),
733 s->tcb->SND.NXT - s->tcb->SND.UNA,
734 s->tcb->SEG.ACK, s->tcb->SND.UNA);
735 fflush(fp);
736#endif
737}
static void cubictcp_acked(PNETSIM_SOCKET sk)
Definition: CUBIC.c:627
static void cubictcp_update(PNETSIM_SOCKET sk, UINT32 acked)
Definition: CUBIC.c:416
struct stru_cubic CUBIC
#define do_div(x, y)
Definition: CUBIC.c:213
static bool before(UINT32 seq1, UINT32 seq2)
Definition: CUBIC.c:215
static void set_congestionvar(PNETSIM_SOCKET s, PCONGESTIONVAR data)
Definition: CUBIC.c:113
static void slowStart(PNETSIM_SOCKET s, PCONGESTIONVAR var)
Definition: CUBIC.c:233
static void hystart_update(PNETSIM_SOCKET sk, UINT32 delay)
Definition: CUBIC.c:578
static int hystart
Definition: CUBIC.c:45
static UINT32 get_ssthres(PNETSIM_SOCKET s)
Definition: CUBIC.c:161
#define HYSTART_DELAY_THRESH(x)
Definition: CUBIC.c:40
#define tcp_time_stamp
Definition: CUBIC.c:26
#define HYSTART_MIN_SAMPLES
Definition: CUBIC.c:37
static UINT32 cubictcp_recalc_ssthresh(PNETSIM_SOCKET sk)
Definition: CUBIC.c:393
static void cubictcp_hystart_reset(PNETSIM_SOCKET sk)
Definition: CUBIC.c:263
struct stru_cubic * PCUBIC
void cubic_ack_received(PNETSIM_SOCKET s)
Definition: CUBIC.c:693
static UINT64 div64_u64(UINT64 dividend, UINT64 divisor)
Definition: CUBIC.c:208
void init_cubic(PNETSIM_SOCKET s)
Definition: CUBIC.c:290
static void set_ssthres(PNETSIM_SOCKET s, UINT32 newssthres)
Definition: CUBIC.c:147
#define HYSTART_DELAY
Definition: CUBIC.c:34
static UINT count_bit(UINT64 n)
Definition: CUBIC.c:221
static bool isDupAck(PNETSIM_SOCKET s, PCONGESTIONVAR var)
Definition: CUBIC.c:200
static void cubictcp_cong_avoid(PNETSIM_SOCKET sk, UINT32 segmentAcked)
Definition: CUBIC.c:541
struct stru_congestion_var * PCONGESTIONVAR
static UINT32 cubic_root(UINT64 a)
Definition: CUBIC.c:349
#define BICTCP_BETA_SCALE
Definition: CUBIC.c:29
static PCONGESTIONVAR get_congestionvar(PNETSIM_SOCKET s)
Definition: CUBIC.c:108
static void increase_cwnd(PNETSIM_SOCKET s, UINT16 increase)
Definition: CUBIC.c:175
#define after(seq2, seq1)
Definition: CUBIC.c:219
static int tcp_friendliness
Definition: CUBIC.c:43
static void cubictcp_fastretransmit(PNETSIM_SOCKET s)
Definition: CUBIC.c:642
static UINT32 get_cwnd(PNETSIM_SOCKET s)
Definition: CUBIC.c:133
static UINT32 beta_scale
Definition: CUBIC.c:50
#define HYSTART_ACK_TRAIN
Definition: CUBIC.c:33
static int hystart_detect
Definition: CUBIC.c:46
static bool tcp_in_slow_start(PNETSIM_SOCKET s)
Definition: CUBIC.c:195
static void set_cwnd(PNETSIM_SOCKET s, UINT32 newcwnd)
Definition: CUBIC.c:118
static void cubictcp_init(PNETSIM_SOCKET sk, PTCP_DEV_VAR tcp)
Definition: CUBIC.c:273
#define BICTCP_HZ
Definition: CUBIC.c:30
struct stru_congestion_var CONGESTIONVAR
#define CUBIC_HZ
Definition: CUBIC.c:27
static UINT32 cubictcp_clock(void)
Definition: CUBIC.c:258
static UINT32 cube_factor
Definition: CUBIC.c:51
static void cubictcp_reset(PCUBIC ca)
Definition: CUBIC.c:243
static void FastRecovery(PNETSIM_SOCKET s, PCONGESTIONVAR var)
Definition: CUBIC.c:686
static int fast_convergence
Definition: CUBIC.c:42
static UINT32 cube_rtt_scale
Definition: CUBIC.c:49
UINT32 get_cwnd_print(PNETSIM_SOCKET s)
Definition: Congestion.c:200
#define c
#define UINT64
Definition: Linux.h:37
#define UINT
Definition: Linux.h:38
#define UINT32
Definition: Linux.h:35
#define UINT16
Definition: Linux.h:33
#define min(a, b)
Definition: Linux.h:106
#define UINT8
Definition: Linux.h:31
#define max(a, b)
Definition: Linux.h:107
#define calloc(c, s)
Definition: Memory.h:29
static struct stru_802_11_Phy_Parameters_HT a
bool tcp_sack_lossRecoveryPhase(PNETSIM_SOCKET s)
Definition: SACK.c:321
UINT32 get_highAck(PNETSIM_SOCKET s)
Definition: SACK.c:23
void tcp_sack_fastRetransmit(PNETSIM_SOCKET s)
Definition: SACK.c:312
bool tcp_sack_isLost(PNETSIM_SOCKET s, UINT seqNum)
Definition: SACK.c:170
#define MILLISECOND
Definition: Stack.h:59
EXPORTED struct stru_NetSim_EventDetails * pstruEventDetails
Definition: Stack.h:837
double get_RTT(PTCB tcb, UINT ackNo)
Definition: TCB.c:372
static PTCP_DEV_VAR GET_TCP_DEV_VAR(NETSIM_ID d)
Definition: TCP.h:167
UINT32 window_scale_get_cwnd(PNETSIM_SOCKET s)
Definition: WindowScale.c:50
void resend_segment_without_timeout(PNETSIM_SOCKET s, UINT seq)
Definition: TCP_Outgoing.c:79
#define TCP_DupThresh
Definition: TCP.h:51
PTCB tcb
Definition: TCP.h:132
NETSIM_ID localDeviceId
Definition: TCP.h:125
double beta
Definition: TCP.h:159
UINT32 hystart_ack_delta
Definition: TCP.h:165
UINT16 MSS
Definition: TCP.h:148
UINT16 initSSThresh
Definition: TCP.h:147
UINT32 hystart_low_window
Definition: TCP.h:164
UINT32 bic_scale
Definition: TCP.h:163
UINT16 IW
Size of the sender's congestion window after the three-way handshake is completed.
Definition: Congestion.c:53
UINT16 RMSS
To store the size of the largest segment that the receiver is willing to accept.
Definition: Congestion.c:52
UINT16 ssthresh
To store slow start threshold value.
Definition: Congestion.c:55
UINT16 rwnd
To store the most recently advertised receiver window size value.
Definition: Congestion.c:57
double lastWinUpdateTime
Definition: Congestion.c:58
UINT16 SMSS
To store the size of the largest segment that the sender can transmit.
Definition: Congestion.c:51
UINT16 cwnd
To store Congestion window size value.
Definition: Congestion.c:56
UINT32 cwndcnt
Definition: CUBIC.c:80
UINT32 delay_min
Definition: CUBIC.c:69
UINT32 last_ack
Definition: CUBIC.c:78
int bic_scale
Definition: CUBIC.c:57
UINT32 initial_ssthresh
Definition: CUBIC.c:59
int beta
Definition: CUBIC.c:58
UINT32 last_max_cwnd
Definition: CUBIC.c:62
UINT32 last_time
Definition: CUBIC.c:65
UINT32 bic_K
Definition: CUBIC.c:67
UINT32 curr_rtt
Definition: CUBIC.c:79
UINT8 sample_cnt
Definition: CUBIC.c:74
UINT32 hystart_low_window
Definition: CUBIC.c:55
UINT32 cnt
Definition: CUBIC.c:61
UINT32 ack_cnt
Definition: CUBIC.c:71
UINT32 end_seq
Definition: CUBIC.c:77
UINT32 tcp_cwnd
Definition: CUBIC.c:72
UINT32 round_start
Definition: CUBIC.c:76
UINT32 epoch_start
Definition: CUBIC.c:70
UINT8 found
Definition: CUBIC.c:75
int hystart_ack_delta
Definition: CUBIC.c:56
UINT32 loss_cwnd
Definition: CUBIC.c:63
UINT32 unused
Definition: CUBIC.c:73
UINT32 bic_origin_point
Definition: CUBIC.c:66
UINT32 last_cwnd
Definition: CUBIC.c:64
struct stru_tcp_Transmission_Control_Block::stru_tcb_send_seq_var SND
UINT16(* get_MSS)(PNETSIM_SOCKET)
Definition: TCB.h:134
struct stru_tcp_Transmission_Control_Block::stru_tcp_snd Snd
struct stru_tcp_Transmission_Control_Block::stru_tcb_curr_seg_var SEG