diff options
Diffstat (limited to 'misc.c')
-rw-r--r-- | misc.c | 66 |
1 files changed, 65 insertions, 1 deletions
@@ -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 | |||
864 | void | ||
865 | bandwidth_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 */ | ||
876 | void | ||
877 | bandwidth_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 | } | ||
863 | void | 927 | void |
864 | sock_set_v6only(int s) | 928 | sock_set_v6only(int s) |
865 | { | 929 | { |