Commit 7deb0f85 authored by Gerrit Renker's avatar Gerrit Renker

dccp ccid-3: X truncated due to type conversion

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: default avatarGerrit Renker <gerrit@erg.abdn.ac.uk>
parent 1e8a287c
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* (at your option) any later version. * (at your option) any later version.
*/ */
#include <linux/types.h> #include <linux/types.h>
#include <asm/div64.h> #include <linux/math64.h>
#include "../../dccp.h" #include "../../dccp.h"
/* internal includes that this module exports: */ /* internal includes that this module exports: */
#include "loss_interval.h" #include "loss_interval.h"
...@@ -29,21 +29,19 @@ extern int tfrc_debug; ...@@ -29,21 +29,19 @@ extern int tfrc_debug;
#endif #endif
/* integer-arithmetic divisions of type (a * 1000000)/b */ /* 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); BUG_ON(b==0);
a *= 1000000; return div64_u64(a * 1000000, b);
do_div(a, b);
return a;
} }
static inline u32 scaled_div32(u64 a, u32 b) static inline u32 scaled_div32(u64 a, u64 b)
{ {
u64 result = scaled_div(a, b); u64 result = scaled_div(a, b);
if (result > UINT_MAX) { if (result > UINT_MAX) {
DCCP_CRIT("Overflow: a(%llu)/b(%u) > ~0U", DCCP_CRIT("Overflow: %llu/%llu > UINT_MAX",
(unsigned long long)a, b); (unsigned long long)a, (unsigned long long)b);
return UINT_MAX; return UINT_MAX;
} }
return result; return result;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment