diff options
Diffstat (limited to 'misc.c')
-rw-r--r-- | misc.c | 139 |
1 files changed, 132 insertions, 7 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.84 2010/11/21 01:01:13 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. |
@@ -35,9 +35,12 @@ | |||
35 | #include <stdio.h> | 35 | #include <stdio.h> |
36 | #include <stdlib.h> | 36 | #include <stdlib.h> |
37 | #include <string.h> | 37 | #include <string.h> |
38 | #include <time.h> | ||
38 | #include <unistd.h> | 39 | #include <unistd.h> |
39 | 40 | ||
40 | #include <netinet/in.h> | 41 | #include <netinet/in.h> |
42 | #include <netinet/in_systm.h> | ||
43 | #include <netinet/ip.h> | ||
41 | #include <netinet/tcp.h> | 44 | #include <netinet/tcp.h> |
42 | 45 | ||
43 | #include <errno.h> | 46 | #include <errno.h> |
@@ -900,16 +903,138 @@ ms_to_timeval(struct timeval *tv, int ms) | |||
900 | tv->tv_usec = (ms % 1000) * 1000; | 903 | tv->tv_usec = (ms % 1000) * 1000; |
901 | } | 904 | } |
902 | 905 | ||
906 | void | ||
907 | bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) | ||
908 | { | ||
909 | bw->buflen = buflen; | ||
910 | bw->rate = kbps; | ||
911 | bw->thresh = bw->rate; | ||
912 | bw->lamt = 0; | ||
913 | timerclear(&bw->bwstart); | ||
914 | timerclear(&bw->bwend); | ||
915 | } | ||
916 | |||
917 | /* Callback from read/write loop to insert bandwidth-limiting delays */ | ||
918 | void | ||
919 | bandwidth_limit(struct bwlimit *bw, size_t read_len) | ||
920 | { | ||
921 | u_int64_t waitlen; | ||
922 | struct timespec ts, rm; | ||
923 | |||
924 | if (!timerisset(&bw->bwstart)) { | ||
925 | gettimeofday(&bw->bwstart, NULL); | ||
926 | return; | ||
927 | } | ||
928 | |||
929 | bw->lamt += read_len; | ||
930 | if (bw->lamt < bw->thresh) | ||
931 | return; | ||
932 | |||
933 | gettimeofday(&bw->bwend, NULL); | ||
934 | timersub(&bw->bwend, &bw->bwstart, &bw->bwend); | ||
935 | if (!timerisset(&bw->bwend)) | ||
936 | return; | ||
937 | |||
938 | bw->lamt *= 8; | ||
939 | waitlen = (double)1000000L * bw->lamt / bw->rate; | ||
940 | |||
941 | bw->bwstart.tv_sec = waitlen / 1000000L; | ||
942 | bw->bwstart.tv_usec = waitlen % 1000000L; | ||
943 | |||
944 | if (timercmp(&bw->bwstart, &bw->bwend, >)) { | ||
945 | timersub(&bw->bwstart, &bw->bwend, &bw->bwend); | ||
946 | |||
947 | /* Adjust the wait time */ | ||
948 | if (bw->bwend.tv_sec) { | ||
949 | bw->thresh /= 2; | ||
950 | if (bw->thresh < bw->buflen / 4) | ||
951 | bw->thresh = bw->buflen / 4; | ||
952 | } else if (bw->bwend.tv_usec < 10000) { | ||
953 | bw->thresh *= 2; | ||
954 | if (bw->thresh > bw->buflen * 8) | ||
955 | bw->thresh = bw->buflen * 8; | ||
956 | } | ||
957 | |||
958 | TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts); | ||
959 | while (nanosleep(&ts, &rm) == -1) { | ||
960 | if (errno != EINTR) | ||
961 | break; | ||
962 | ts = rm; | ||
963 | } | ||
964 | } | ||
965 | |||
966 | bw->lamt = 0; | ||
967 | gettimeofday(&bw->bwstart, NULL); | ||
968 | } | ||
969 | |||
970 | /* Make a template filename for mk[sd]temp() */ | ||
971 | void | ||
972 | mktemp_proto(char *s, size_t len) | ||
973 | { | ||
974 | const char *tmpdir; | ||
975 | int r; | ||
976 | |||
977 | if ((tmpdir = getenv("TMPDIR")) != NULL) { | ||
978 | r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir); | ||
979 | if (r > 0 && (size_t)r < len) | ||
980 | return; | ||
981 | } | ||
982 | r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX"); | ||
983 | if (r < 0 || (size_t)r >= len) | ||
984 | fatal("%s: template string too short", __func__); | ||
985 | } | ||
986 | |||
987 | static const struct { | ||
988 | const char *name; | ||
989 | int value; | ||
990 | } ipqos[] = { | ||
991 | { "af11", IPTOS_DSCP_AF11 }, | ||
992 | { "af12", IPTOS_DSCP_AF12 }, | ||
993 | { "af13", IPTOS_DSCP_AF13 }, | ||
994 | { "af14", IPTOS_DSCP_AF21 }, | ||
995 | { "af22", IPTOS_DSCP_AF22 }, | ||
996 | { "af23", IPTOS_DSCP_AF23 }, | ||
997 | { "af31", IPTOS_DSCP_AF31 }, | ||
998 | { "af32", IPTOS_DSCP_AF32 }, | ||
999 | { "af33", IPTOS_DSCP_AF33 }, | ||
1000 | { "af41", IPTOS_DSCP_AF41 }, | ||
1001 | { "af42", IPTOS_DSCP_AF42 }, | ||
1002 | { "af43", IPTOS_DSCP_AF43 }, | ||
1003 | { "cs0", IPTOS_DSCP_CS0 }, | ||
1004 | { "cs1", IPTOS_DSCP_CS1 }, | ||
1005 | { "cs2", IPTOS_DSCP_CS2 }, | ||
1006 | { "cs3", IPTOS_DSCP_CS3 }, | ||
1007 | { "cs4", IPTOS_DSCP_CS4 }, | ||
1008 | { "cs5", IPTOS_DSCP_CS5 }, | ||
1009 | { "cs6", IPTOS_DSCP_CS6 }, | ||
1010 | { "cs7", IPTOS_DSCP_CS7 }, | ||
1011 | { "ef", IPTOS_DSCP_EF }, | ||
1012 | { "lowdelay", IPTOS_LOWDELAY }, | ||
1013 | { "throughput", IPTOS_THROUGHPUT }, | ||
1014 | { "reliability", IPTOS_RELIABILITY }, | ||
1015 | { NULL, -1 } | ||
1016 | }; | ||
1017 | |||
903 | int | 1018 | int |
904 | timingsafe_bcmp(const void *b1, const void *b2, size_t n) | 1019 | parse_ipqos(const char *cp) |
905 | { | 1020 | { |
906 | const unsigned char *p1 = b1, *p2 = b2; | 1021 | u_int i; |
907 | int ret = 0; | 1022 | char *ep; |
1023 | long val; | ||
908 | 1024 | ||
909 | for (; n > 0; n--) | 1025 | if (cp == NULL) |
910 | ret |= *p1++ ^ *p2++; | 1026 | return -1; |
911 | return (ret != 0); | 1027 | for (i = 0; ipqos[i].name != NULL; i++) { |
1028 | if (strcasecmp(cp, ipqos[i].name) == 0) | ||
1029 | return ipqos[i].value; | ||
1030 | } | ||
1031 | /* Try parsing as an integer */ | ||
1032 | val = strtol(cp, &ep, 0); | ||
1033 | if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255) | ||
1034 | return -1; | ||
1035 | return val; | ||
912 | } | 1036 | } |
1037 | |||
913 | void | 1038 | void |
914 | sock_set_v6only(int s) | 1039 | sock_set_v6only(int s) |
915 | { | 1040 | { |