Package: iputils-ping Version: 3:20180629-2 Severity: normal Tags: patch Dear Maintainer,
As documented, ping fails to properly compute deviation where ping times are small. A patch follows. A simple example, using variables used there: Suppose we do 10 pings, and 5 take 10us, 5 take 11us. tsum2 is 1105, tsum is 105. We divide them, getting 110 and 10 respectively. tmdev is then llsqrt(110 - 10 * 10) = llsqrt(10) = 3us. But max-min is only 1us! The exact solution is sqrt(110.5-110.25) which is sqrt(0.25)=0.5. The new code will (more) correctly compute llsqrt(0) = 0 as the answer. It takes care not to do any horrendous integer overflows if there's a lot of long pings (a few thousand >1s pings would overflow without this). Patch is against 3:20101006-1. -- David Buckley
--- old/ping_common.c 2018-08-26 15:43:03.891105137 +0100 +++ new/ping_common.c 2018-08-26 16:01:39.046836333 +0100 @@ -855,13 +855,21 @@ if (nreceived && timing) { + long total = nreceived + nrepeats; + long tmavg = tsum / total; + long long tmvar; long tmdev; - tsum /= nreceived + nrepeats; - tsum2 /= nreceived + nrepeats; - tmdev = llsqrt(tsum2 - tsum * tsum); + if (nrepeats < INT_MAX) { + // This slightly clumsy computation order is important to avoid + // integer rounding errors for small ping times. + tmvar = (tsum2 - tsum * tsum / total) / total; + } else { + tmvar = tsum2 / total - tmavg * tmavg; + } + tmdev = llsqrt(tmvar); printf("rtt min/avg/max/mdev = %ld.%03ld/%lu.%03ld/%ld.%03ld/%ld.%03ld ms", (long)tmin/1000, (long)tmin%1000, - (unsigned long)(tsum/1000), (long)(tsum%1000), + (unsigned long)(tmavg/1000), (long)(tmavg%1000), (long)tmax/1000, (long)tmax%1000, (long)tmdev/1000, (long)tmdev%1000