diff options
author | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2006-12-03 11:52:26 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@mandriva.com> | 2006-12-03 11:52:26 -0500 |
commit | 8d0086adac0041de66b5f41b77eec0d8d239e16c (patch) | |
tree | 9830f9188a9ba57bf75c0fa7c2246866f8a8789a /net/dccp | |
parent | 90fb0e60dd9178dbca2e42c682c483cdb7ea9f2d (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/dccp')
-rw-r--r-- | net/dccp/ccids/lib/tfrc_equation.c | 33 |
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 | ||