Howdy! I found a strange bug in the new version of Udpcast. When
sending packets at speeds over around 80m, the program locks up. I
traced the problem to the doRateLimit function in rate-limit.c (I've
added some printfs):
sleepTime = rateLimit->queueSize * 8 * MILLION /
rateLimit->bitrate;
printf("sleepTime1 %lu\n",sleepTime);
printf("rateLimit->queueSize %lu\n",rateLimit->queueSize);
if(sleepTime > 40000 || rateLimit->queueSize >= 100000) {
printf("sleepTime2 %lu\n",sleepTime);
sleepTime -= 10000;
printf("sleepTime3 %lu\n",sleepTime);
printf("sleepTime3 % 10000 %u\n",sleepTime % 10000);
sleepTime -= sleepTime % 10000;
printf("sleepTime4 %lu\n",sleepTime);
usleep((useconds_t)sleepTime);
}
What is happening is that sometimes rateLimit->queueSize >= 100000 but
sleepTime is small, so subtracting 10000 from it wraps around to near
maxint. The strange thing is that when the program then does sleepTime
-= sleepTime % 10000 the result is *different* from the 20200328 version
because of the change to long unsigned integers. In the old version
sleepTime would become zero, but now it stays huge, leading to an
extremely long usleep.
Here is the old behavior:
sleepTime1 1338
rateLimit->queueSize 100350
sleepTime2 1338
sleepTime3 4294958634
sleepTime3 % 10000 4294958634
sleepTime4 0
Here is the new behavior (which hangs):
sleepTime1 1344
rateLimit->queueSize 100800
sleepTime2 1344
sleepTime3 18446744073709542960
sleepTime3 % 10000 2960
sleepTime4 18446744073709540000
It looks to me like the older version actually had offsetting bugs:
sleepTime % 10000 *should* return a value less than 10000 but in the old
code for some reason it just returned sleepTime, which then subtracted
from itself gave zero. In the new version the wraparound error from the
sleepTime -= 10000 has been exposed, causing the hang.
Anyway, hopefully this isn't too hard to fix: your program is
super-useful for us, and the old version merrily blasts udp packets at
gigabit speeds!
Thanks,
Robert II