summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2011-01-24 12:43:25 +0000
committerColin Watson <cjwatson@debian.org>2011-01-24 12:43:25 +0000
commit626f1d986ff72aa514da63e34744e1de9cf21b9a (patch)
treed215a5280bc2e57251e4a9e08bfd3674ad824a94 /misc.c
parent6ed622cb6fe8f71bbe0d998cdd12280410bfb420 (diff)
parent0970072c89b079b022538e3c366fbfa2c53fc821 (diff)
* New upstream release (http://www.openssh.org/txt/release-5.7):
- Implement Elliptic Curve Cryptography modes for key exchange (ECDH) and host/user keys (ECDSA) as specified by RFC5656. ECDH and ECDSA offer better performance than plain DH and DSA at the same equivalent symmetric key length, as well as much shorter keys. - sftp(1)/sftp-server(8): add a protocol extension to support a hard link operation. It is available through the "ln" command in the client. The old "ln" behaviour of creating a symlink is available using its "-s" option or through the preexisting "symlink" command. - scp(1): Add a new -3 option to scp: Copies between two remote hosts are transferred through the local host (closes: #508613). - ssh(1): "atomically" create the listening mux socket by binding it on a temporary name and then linking it into position after listen() has succeeded. This allows the mux clients to determine that the server socket is either ready or stale without races (closes: #454784). Stale server sockets are now automatically removed (closes: #523250). - ssh(1): install a SIGCHLD handler to reap expired child process (closes: #594687). - ssh(1)/ssh-agent(1): honour $TMPDIR for client xauth and ssh-agent temporary directories (closes: #357469, although only if you arrange for ssh-agent to actually see $TMPDIR since the setgid bit will cause it to be stripped off).
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{