summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2010-09-24 22:15:11 +1000
committerDamien Miller <djm@mindrot.org>2010-09-24 22:15:11 +1000
commit65e42f87fe945a2bf30d7e02358554dbaefa8a4c (patch)
tree102c10a0b5328a40c79dca19d208f0ca0c1671b5 /misc.c
parent7fe2b1fec3b364faf952828f3875b8e7eed8feb4 (diff)
- djm@cvs.openbsd.org 2010/09/22 22:58:51
[atomicio.c atomicio.h misc.c misc.h scp.c sftp-client.c] [sftp-client.h sftp.1 sftp.c] add an option per-read/write callback to atomicio factor out bandwidth limiting code from scp(1) into a generic bandwidth limiter that can be attached using the atomicio callback mechanism add a bandwidth limit option to sftp(1) using the above "very nice" markus@
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/misc.c b/misc.c
index a82e7936e..41c92a82b 100644
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: misc.c,v 1.80 2010/07/21 02:10:58 djm Exp $ */ 1/* $OpenBSD: misc.c,v 1.81 2010/09/22 22:58:51 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved. 4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@@ -860,6 +860,70 @@ timingsafe_bcmp(const void *b1, const void *b2, size_t n)
860 ret |= *p1++ ^ *p2++; 860 ret |= *p1++ ^ *p2++;
861 return (ret != 0); 861 return (ret != 0);
862} 862}
863
864void
865bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen)
866{
867 bw->buflen = buflen;
868 bw->rate = kbps;
869 bw->thresh = bw->rate;
870 bw->lamt = 0;
871 timerclear(&bw->bwstart);
872 timerclear(&bw->bwend);
873}
874
875/* Callback from read/write loop to insert bandwidth-limiting delays */
876void
877bandwidth_limit(struct bwlimit *bw, size_t read_len)
878{
879 u_int64_t waitlen;
880 struct timespec ts, rm;
881
882 if (!timerisset(&bw->bwstart)) {
883 gettimeofday(&bw->bwstart, NULL);
884 return;
885 }
886
887 bw->lamt += read_len;
888 if (bw->lamt < bw->thresh)
889 return;
890
891 gettimeofday(&bw->bwend, NULL);
892 timersub(&bw->bwend, &bw->bwstart, &bw->bwend);
893 if (!timerisset(&bw->bwend))
894 return;
895
896 bw->lamt *= 8;
897 waitlen = (double)1000000L * bw->lamt / bw->rate;
898
899 bw->bwstart.tv_sec = waitlen / 1000000L;
900 bw->bwstart.tv_usec = waitlen % 1000000L;
901
902 if (timercmp(&bw->bwstart, &bw->bwend, >)) {
903 timersub(&bw->bwstart, &bw->bwend, &bw->bwend);
904
905 /* Adjust the wait time */
906 if (bw->bwend.tv_sec) {
907 bw->thresh /= 2;
908 if (bw->thresh < bw->buflen / 4)
909 bw->thresh = bw->buflen / 4;
910 } else if (bw->bwend.tv_usec < 10000) {
911 bw->thresh *= 2;
912 if (bw->thresh > bw->buflen * 8)
913 bw->thresh = bw->buflen * 8;
914 }
915
916 TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts);
917 while (nanosleep(&ts, &rm) == -1) {
918 if (errno != EINTR)
919 break;
920 ts = rm;
921 }
922 }
923
924 bw->lamt = 0;
925 gettimeofday(&bw->bwstart, NULL);
926}
863void 927void
864sock_set_v6only(int s) 928sock_set_v6only(int s)
865{ 929{