[PATCH] scp: Fix bug in bandwidth limit

Hao Lee haolee.swjtu at gmail.com
Sun Nov 11 01:04:14 AEDT 2018


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



More information about the openssh-unix-dev mailing list