Quoting Eddie Kohler:
| I'm surprised that this case occurs:
|
| Gerrit Renker wrote:
| > [CCID 3]: Fix bug in the calculation of very low sending rates
| >
| > This fixes an error in the calculation of t_ipi when X converges towards
| > very low sending rates (between 1 and 64 bytes per second).
| >
| > Although this case may not sound likely, it can be reproduced by
connecting,
| > hitting enter (1 byte sent) and waiting for some time, during which the
| > nofeedback timer halves the sending rate until finally it reaches the
region
| > 1..64 bytes/sec. Computing X is handled correctly (tested separately); but
by
| > dividing X _before_ entering the calculation of t_ipi, X becomes zero as
| > a result. This in turn triggers a BUG condition caught in scaled_div().
|
| According to RFC 4342, the allowed sending rate should never be reduced
| below the TCP initial sending rate of two or four packets per RTT,
| depending on the packet size, as the result of an idle or slow period.
|
| Hitting enter and then waiting is an idle period.
|
| Since X is the allowed transmit rate, it seems Linux implementation is
| not following this at the moment; but perhaps there is code elsewhere
| handling this case?
|
Respecting the TCP initial sending rate is handled by rfc3390_initial_rate(),
but this
patch is in a different section of the code; the nofeedback timer reducing X.
This patch is not affected by and does not affect the TCP initial rate.
It is a bona-fide bug fix and only concerned with rounding errors. The present
code is
wrong and will cause a BUG condition under the described conditions.
| > static inline void ccid3_update_send_interval(struct ccid3_hc_tx_sock
*hctx)
| > {
| > /* Calculate new t_ipi = s / X_inst (X_inst is in 64 * bytes/second) */
| > - hctx->ccid3hctx_t_ipi = scaled_div(hctx->ccid3hctx_s,
| > - hctx->ccid3hctx_x >> 6);
| > + hctx->ccid3hctx_t_ipi = scaled_div32(((u64)hctx->ccid3hctx_s) << 6,
| > + hctx->ccid3hctx_x);
The bug here is in scaled_div(hctx->ccid3hctx_s, hctx->ccid3hctx_x >> 6): the
right-shift
is done before the division operation is evaluated. Thus sending rates in the
range
1/64 bytes/sec ... 1 byte/sec will appear as 0, and consequently trigger
"divide-by-zero"
BUG condition in scaled_div. And this case is perfectly possible, due to the
definition
of s/t_mbi and s/(2*t_mbi) in RFC 3448, 4.3 - both values would with the above
show as 0
when s is very small.
It may be that due to the TCP initial rate this case is rare, but it still
represents a
bug condition and must not be allowed to occur.
-
To unsubscribe from this list: send the line "unsubscribe dccp" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html