aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2006-12-03 11:52:26 -0500
committerArnaldo Carvalho de Melo <acme@mandriva.com>2006-12-03 11:52:26 -0500
commit8d0086adac0041de66b5f41b77eec0d8d239e16c (patch)
tree9830f9188a9ba57bf75c0fa7c2246866f8a8789a /net
parent90fb0e60dd9178dbca2e42c682c483cdb7ea9f2d (diff)
[DCCP] tfrc: Add protection against invalid parameters to TFRC routines
1) For the forward X_calc lookup, it * protects effectively against RTT=0 (this case is possible), by returning the maximal lookup value instead of just setting it to 1 * reformulates the array-bounds exceeded condition: this only happens if p is greater than 1E6 (due to the scaling) * the case of negative indices can now with certainty be excluded, since documentation shows that the formulas are within bounds * additional protection against p = 0 (would give divide-by-zero) 2) For the reverse lookup, it warns against * protects against exceeding array bounds * now returns 0 if f(p) = 0, due to function definition * warns about minimal resolution error and returns the smallest table value instead of p=0 [this would mask congestion conditions] Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz> Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Diffstat (limited to 'net')
-rw-r--r--net/dccp/ccids/lib/tfrc_equation.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/net/dccp/ccids/lib/tfrc_equation.c b/net/dccp/ccids/lib/tfrc_equation.c
index 78bdf3489162..ef3233d45a61 100644
--- a/net/dccp/ccids/lib/tfrc_equation.c
+++ b/net/dccp/ccids/lib/tfrc_equation.c
@@ -608,22 +608,19 @@ u32 tfrc_calc_x(u16 s, u32 R, u32 p)
608 u32 f; 608 u32 f;
609 u64 tmp1, tmp2; 609 u64 tmp1, tmp2;
610 610
611 /* check against invalid parameters and divide-by-zero */
612 BUG_ON(p > 1000000); /* p must not exceed 100% */
613 BUG_ON(p == 0); /* f(0) = 0, divide by zero */
614 if (R == 0) { /* possible divide by zero */
615 DCCP_CRIT("WARNING: RTT is 0, returning maximum X_calc.");
616 return ~0U;
617 }
618
611 if (p < TFRC_CALC_X_SPLIT) /* 0 <= p < 0.05 */ 619 if (p < TFRC_CALC_X_SPLIT) /* 0 <= p < 0.05 */
612 index = (p / (TFRC_CALC_X_SPLIT / TFRC_CALC_X_ARRSIZE)) - 1; 620 index = (p / (TFRC_CALC_X_SPLIT / TFRC_CALC_X_ARRSIZE)) - 1;
613 else /* 0.05 <= p <= 1.00 */ 621 else /* 0.05 <= p <= 1.00 */
614 index = (p / (1000000 / TFRC_CALC_X_ARRSIZE)) - 1; 622 index = (p / (1000000 / TFRC_CALC_X_ARRSIZE)) - 1;
615 623
616 if (index < 0)
617 /* p should be 0 unless there is a bug in my code */
618 index = 0;
619
620 if (R == 0) {
621 DCCP_WARN("RTT==0, setting to 1\n");
622 R = 1; /* RTT can't be zero or else divide by zero */
623 }
624
625 BUG_ON(index >= TFRC_CALC_X_ARRSIZE);
626
627 if (p >= TFRC_CALC_X_SPLIT) 624 if (p >= TFRC_CALC_X_SPLIT)
628 f = tfrc_calc_x_lookup[index][0]; 625 f = tfrc_calc_x_lookup[index][0];
629 else 626 else
@@ -653,13 +650,21 @@ u32 tfrc_calc_x_reverse_lookup(u32 fvalue)
653 int ctr = 0; 650 int ctr = 0;
654 int small; 651 int small;
655 652
656 if (fvalue < tfrc_calc_x_lookup[0][1]) 653 if (fvalue == 0) /* f(p) = 0 whenever p = 0 */
657 return 0; 654 return 0;
658 655
656 /* Error cases. */
657 if (fvalue < tfrc_calc_x_lookup[0][1]) {
658 DCCP_WARN("fvalue %d smaller than resolution\n", fvalue);
659 return tfrc_calc_x_lookup[0][1];
660 }
661 if (fvalue > tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE - 1][0]) {
662 DCCP_WARN("fvalue %d exceeds bounds!\n", fvalue);
663 return 1000000;
664 }
665
659 if (fvalue <= tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE - 1][1]) 666 if (fvalue <= tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE - 1][1])
660 small = 1; 667 small = 1;
661 else if (fvalue > tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE - 1][0])
662 return 1000000;
663 else 668 else
664 small = 0; 669 small = 0;
665 670