The unit of `read_len` is `Bytes` but the unit of `bw->thresh` is `bits`, so at the first 8 seconds, the actual bandwidth is 8 times of the expected bandwidth limit. The `bw->thresh` will reduce to 1/8 of its original value after 8 seconds and the actual bandwidth will also reduce to the expected bandwidth limit accordingly along the way. This patch will fix this problem. This bug has been reported by me: https://bugzilla.mindrot.org/show_bug.cgi?id=2928 Signed-off-by: Hao Lee <haolee.swjtu at gmail.com> --- misc.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/misc.c b/misc.c index bdc06fd..3d2372c 100644 --- a/misc.c +++ b/misc.c @@ -1343,7 +1343,7 @@ bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) /* Callback from read/write loop to insert bandwidth-limiting delays */ void -bandwidth_limit(struct bwlimit *bw, size_t read_len) +bandwidth_limit(struct bwlimit *bw, size_t read_len_bytes) { u_int64_t waitlen; struct timespec ts, rm; @@ -1353,7 +1353,7 @@ bandwidth_limit(struct bwlimit *bw, size_t read_len) return; } - bw->lamt += read_len; + bw->lamt += read_len_bytes * 8; if (bw->lamt < bw->thresh) return; @@ -1362,7 +1362,6 @@ bandwidth_limit(struct bwlimit *bw, size_t read_len) if (!timerisset(&bw->bwend)) return; - bw->lamt *= 8; waitlen = (double)1000000L * bw->lamt / bw->rate; bw->bwstart.tv_sec = waitlen / 1000000L; @@ -1370,18 +1369,6 @@ bandwidth_limit(struct bwlimit *bw, size_t read_len) if (timercmp(&bw->bwstart, &bw->bwend, >)) { timersub(&bw->bwstart, &bw->bwend, &bw->bwend); - - /* Adjust the wait time */ - if (bw->bwend.tv_sec) { - bw->thresh /= 2; - if (bw->thresh < bw->buflen / 4) - bw->thresh = bw->buflen / 4; - } else if (bw->bwend.tv_usec < 10000) { - bw->thresh *= 2; - if (bw->thresh > bw->buflen * 8) - bw->thresh = bw->buflen * 8; - } - TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts); while (nanosleep(&ts, &rm) == -1) { if (errno != EINTR) -- 2.14.5