summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c139
1 files changed, 132 insertions, 7 deletions
diff --git a/misc.c b/misc.c
index a82e7936e..919b04e6b 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.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>
@@ -850,16 +853,138 @@ ms_to_timeval(struct timeval *tv, int ms)
850 tv->tv_usec = (ms % 1000) * 1000; 853 tv->tv_usec = (ms % 1000) * 1000;
851} 854}
852 855
856void
857bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen)
858{
859 bw->buflen = buflen;
860 bw->rate = kbps;
861 bw->thresh = bw->rate;
862 bw->lamt = 0;
863 timerclear(&bw->bwstart);
864 timerclear(&bw->bwend);
865}
866
867/* Callback from read/write loop to insert bandwidth-limiting delays */
868void
869bandwidth_limit(struct bwlimit *bw, size_t read_len)
870{
871 u_int64_t waitlen;
872 struct timespec ts, rm;
873
874 if (!timerisset(&bw->bwstart)) {
875 gettimeofday(&bw->bwstart, NULL);
876 return;
877 }
878
879 bw->lamt += read_len;
880 if (bw->lamt < bw->thresh)
881 return;
882
883 gettimeofday(&bw->bwend, NULL);
884 timersub(&bw->bwend, &bw->bwstart, &bw->bwend);
885 if (!timerisset(&bw->bwend))
886 return;
887
888 bw->lamt *= 8;
889 waitlen = (double)1000000L * bw->lamt / bw->rate;
890
891 bw->bwstart.tv_sec = waitlen / 1000000L;
892 bw->bwstart.tv_usec = waitlen % 1000000L;
893
894 if (timercmp(&bw->bwstart, &bw->bwend, >)) {
895 timersub(&bw->bwstart, &bw->bwend, &bw->bwend);
896
897 /* Adjust the wait time */
898 if (bw->bwend.tv_sec) {
899 bw->thresh /= 2;
900 if (bw->thresh < bw->buflen / 4)
901 bw->thresh = bw->buflen / 4;
902 } else if (bw->bwend.tv_usec < 10000) {
903 bw->thresh *= 2;
904 if (bw->thresh > bw->buflen * 8)
905 bw->thresh = bw->buflen * 8;
906 }
907
908 TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts);
909 while (nanosleep(&ts, &rm) == -1) {
910 if (errno != EINTR)
911 break;
912 ts = rm;
913 }
914 }
915
916 bw->lamt = 0;
917 gettimeofday(&bw->bwstart, NULL);
918}
919
920/* Make a template filename for mk[sd]temp() */
921void
922mktemp_proto(char *s, size_t len)
923{
924 const char *tmpdir;
925 int r;
926
927 if ((tmpdir = getenv("TMPDIR")) != NULL) {
928 r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir);
929 if (r > 0 && (size_t)r < len)
930 return;
931 }
932 r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX");
933 if (r < 0 || (size_t)r >= len)
934 fatal("%s: template string too short", __func__);
935}
936
937static const struct {
938 const char *name;
939 int value;
940} ipqos[] = {
941 { "af11", IPTOS_DSCP_AF11 },
942 { "af12", IPTOS_DSCP_AF12 },
943 { "af13", IPTOS_DSCP_AF13 },
944 { "af14", IPTOS_DSCP_AF21 },
945 { "af22", IPTOS_DSCP_AF22 },
946 { "af23", IPTOS_DSCP_AF23 },
947 { "af31", IPTOS_DSCP_AF31 },
948 { "af32", IPTOS_DSCP_AF32 },
949 { "af33", IPTOS_DSCP_AF33 },
950 { "af41", IPTOS_DSCP_AF41 },
951 { "af42", IPTOS_DSCP_AF42 },
952 { "af43", IPTOS_DSCP_AF43 },
953 { "cs0", IPTOS_DSCP_CS0 },
954 { "cs1", IPTOS_DSCP_CS1 },
955 { "cs2", IPTOS_DSCP_CS2 },
956 { "cs3", IPTOS_DSCP_CS3 },
957 { "cs4", IPTOS_DSCP_CS4 },
958 { "cs5", IPTOS_DSCP_CS5 },
959 { "cs6", IPTOS_DSCP_CS6 },
960 { "cs7", IPTOS_DSCP_CS7 },
961 { "ef", IPTOS_DSCP_EF },
962 { "lowdelay", IPTOS_LOWDELAY },
963 { "throughput", IPTOS_THROUGHPUT },
964 { "reliability", IPTOS_RELIABILITY },
965 { NULL, -1 }
966};
967
853int 968int
854timingsafe_bcmp(const void *b1, const void *b2, size_t n) 969parse_ipqos(const char *cp)
855{ 970{
856 const unsigned char *p1 = b1, *p2 = b2; 971 u_int i;
857 int ret = 0; 972 char *ep;
973 long val;
858 974
859 for (; n > 0; n--) 975 if (cp == NULL)
860 ret |= *p1++ ^ *p2++; 976 return -1;
861 return (ret != 0); 977 for (i = 0; ipqos[i].name != NULL; i++) {
978 if (strcasecmp(cp, ipqos[i].name) == 0)
979 return ipqos[i].value;
980 }
981 /* Try parsing as an integer */
982 val = strtol(cp, &ep, 0);
983 if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255)
984 return -1;
985 return val;
862} 986}
987
863void 988void
864sock_set_v6only(int s) 989sock_set_v6only(int s)
865{ 990{