Skip to content

Commit

Permalink
dccp ccid-3: X truncated due to type conversion
Browse files Browse the repository at this point in the history
This fixes a bug in computing the inter-packet-interval t_ipi = s/X: 

 scaled_div32(a, b) uses u32 for b, but in "scaled_div32(s, X)" the type of the
 sending rate `X' is u64. Since X is scaled by 2^6, this truncates rates greater
 than 2^26 Bps (~537 Mbps).

Using full 64-bit division now.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
  • Loading branch information
Gerrit Renker committed Jun 11, 2008
1 parent 1e8a287 commit 7deb0f8
Showing 1 changed file with 6 additions and 8 deletions.
14 changes: 6 additions & 8 deletions net/dccp/ccids/lib/tfrc.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* (at your option) any later version.
*/
#include <linux/types.h>
#include <asm/div64.h>
#include <linux/math64.h>
#include "../../dccp.h"
/* internal includes that this module exports: */
#include "loss_interval.h"
Expand All @@ -29,21 +29,19 @@ extern int tfrc_debug;
#endif

/* integer-arithmetic divisions of type (a * 1000000)/b */
static inline u64 scaled_div(u64 a, u32 b)
static inline u64 scaled_div(u64 a, u64 b)
{
BUG_ON(b==0);
a *= 1000000;
do_div(a, b);
return a;
return div64_u64(a * 1000000, b);
}

static inline u32 scaled_div32(u64 a, u32 b)
static inline u32 scaled_div32(u64 a, u64 b)
{
u64 result = scaled_div(a, b);

if (result > UINT_MAX) {
DCCP_CRIT("Overflow: a(%llu)/b(%u) > ~0U",
(unsigned long long)a, b);
DCCP_CRIT("Overflow: %llu/%llu > UINT_MAX",
(unsigned long long)a, (unsigned long long)b);
return UINT_MAX;
}
return result;
Expand Down

0 comments on commit 7deb0f8

Please sign in to comment.