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 20d4300d9..ea614ce22 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>
@@ -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
906void
907bandwidth_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 */
918void
919bandwidth_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() */
971void
972mktemp_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
987static 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
903int 1018int
904timingsafe_bcmp(const void *b1, const void *b2, size_t n) 1019parse_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
913void 1038void
914sock_set_v6only(int s) 1039sock_set_v6only(int s)
915{ 1040{