summaryrefslogtreecommitdiff
path: root/packet.c
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2008-06-13 06:42:45 +1000
committerDarren Tucker <dtucker@zip.com.au>2008-06-13 06:42:45 +1000
commit3fc464efdc5111334f42213891521fcd42c0e7a1 (patch)
treee48491c53689ac119109005b3f5bbf84b57bbdcd /packet.c
parentf09e825329d13c5fc31a97fc7ea2312dd4fb5405 (diff)
- dtucker@cvs.openbsd.org 2008/06/12 20:38:28
[sshd.c sshconnect.c packet.h misc.c misc.h packet.c] Make keepalive timeouts apply while waiting for a packet, particularly during key renegotiation (bz #1363). With djm and Matt Day, ok djm@
Diffstat (limited to 'packet.c')
-rw-r--r--packet.c85
1 files changed, 76 insertions, 9 deletions
diff --git a/packet.c b/packet.c
index c0e91b2d6..9fd43ec68 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.c,v 1.153 2008/05/19 06:14:02 djm Exp $ */ 1/* $OpenBSD: packet.c,v 1.154 2008/06/12 20:38:28 dtucker Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -138,6 +138,9 @@ static int after_authentication = 0;
138 138
139int keep_alive_timeouts = 0; 139int keep_alive_timeouts = 0;
140 140
141/* Set to the maximum time that we will wait to send or receive a packet */
142static int packet_timeout_ms = -1;
143
141/* Session key information for Encryption and MAC */ 144/* Session key information for Encryption and MAC */
142Newkeys *newkeys[MODE_MAX]; 145Newkeys *newkeys[MODE_MAX];
143static struct packet_state { 146static struct packet_state {
@@ -191,6 +194,19 @@ packet_set_connection(int fd_in, int fd_out)
191 } 194 }
192} 195}
193 196
197void
198packet_set_timeout(int timeout, int count)
199{
200 if (timeout == 0 || count == 0) {
201 packet_timeout_ms = -1;
202 return;
203 }
204 if ((INT_MAX / 1000) / count < timeout)
205 packet_timeout_ms = INT_MAX;
206 else
207 packet_timeout_ms = timeout * count * 1000;
208}
209
194/* Returns 1 if remote host is connected via socket, 0 if not. */ 210/* Returns 1 if remote host is connected via socket, 0 if not. */
195 211
196int 212int
@@ -891,10 +907,11 @@ packet_send(void)
891int 907int
892packet_read_seqnr(u_int32_t *seqnr_p) 908packet_read_seqnr(u_int32_t *seqnr_p)
893{ 909{
894 int type, len; 910 int type, len, ret, ms_remain;
895 fd_set *setp; 911 fd_set *setp;
896 char buf[8192]; 912 char buf[8192];
897 DBG(debug("packet_read()")); 913 DBG(debug("packet_read()"));
914 struct timeval timeout, start, *timeoutp = NULL;
898 915
899 setp = (fd_set *)xcalloc(howmany(connection_in+1, NFDBITS), 916 setp = (fd_set *)xcalloc(howmany(connection_in+1, NFDBITS),
900 sizeof(fd_mask)); 917 sizeof(fd_mask));
@@ -925,11 +942,34 @@ packet_read_seqnr(u_int32_t *seqnr_p)
925 sizeof(fd_mask)); 942 sizeof(fd_mask));
926 FD_SET(connection_in, setp); 943 FD_SET(connection_in, setp);
927 944
945 if (packet_timeout_ms > 0) {
946 ms_remain = packet_timeout_ms;
947 timeoutp = &timeout;
948 }
928 /* Wait for some data to arrive. */ 949 /* Wait for some data to arrive. */
929 while (select(connection_in + 1, setp, NULL, NULL, NULL) == -1 && 950 for (;;) {
930 (errno == EAGAIN || errno == EINTR)) 951 if (packet_timeout_ms != -1) {
931 ; 952 ms_to_timeval(&timeout, ms_remain);
932 953 gettimeofday(&start, NULL);
954 }
955 if ((ret = select(connection_in + 1, setp, NULL,
956 NULL, timeoutp)) >= 0)
957 break;
958 if (errno != EAGAIN && errno != EINTR)
959 break;
960 if (packet_timeout_ms == -1)
961 continue;
962 ms_subtract_diff(&start, &ms_remain);
963 if (ms_remain <= 0) {
964 ret = 0;
965 break;
966 }
967 }
968 if (ret == 0) {
969 logit("Connection to %.200s timed out while "
970 "waiting to read", get_remote_ipaddr());
971 cleanup_exit(255);
972 }
933 /* Read data from the socket. */ 973 /* Read data from the socket. */
934 len = read(connection_in, buf, sizeof(buf)); 974 len = read(connection_in, buf, sizeof(buf));
935 if (len == 0) { 975 if (len == 0) {
@@ -1452,6 +1492,8 @@ void
1452packet_write_wait(void) 1492packet_write_wait(void)
1453{ 1493{
1454 fd_set *setp; 1494 fd_set *setp;
1495 int ret, ms_remain;
1496 struct timeval start, timeout, *timeoutp = NULL;
1455 1497
1456 setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS), 1498 setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS),
1457 sizeof(fd_mask)); 1499 sizeof(fd_mask));
@@ -1460,9 +1502,34 @@ packet_write_wait(void)
1460 memset(setp, 0, howmany(connection_out + 1, NFDBITS) * 1502 memset(setp, 0, howmany(connection_out + 1, NFDBITS) *
1461 sizeof(fd_mask)); 1503 sizeof(fd_mask));
1462 FD_SET(connection_out, setp); 1504 FD_SET(connection_out, setp);
1463 while (select(connection_out + 1, NULL, setp, NULL, NULL) == -1 && 1505
1464 (errno == EAGAIN || errno == EINTR)) 1506 if (packet_timeout_ms > 0) {
1465 ; 1507 ms_remain = packet_timeout_ms;
1508 timeoutp = &timeout;
1509 }
1510 for (;;) {
1511 if (packet_timeout_ms != -1) {
1512 ms_to_timeval(&timeout, ms_remain);
1513 gettimeofday(&start, NULL);
1514 }
1515 if ((ret = select(connection_out + 1, NULL, setp,
1516 NULL, timeoutp)) >= 0)
1517 break;
1518 if (errno != EAGAIN && errno != EINTR)
1519 break;
1520 if (packet_timeout_ms == -1)
1521 continue;
1522 ms_subtract_diff(&start, &ms_remain);
1523 if (ms_remain <= 0) {
1524 ret = 0;
1525 break;
1526 }
1527 }
1528 if (ret == 0) {
1529 logit("Connection to %.200s timed out while "
1530 "waiting to write", get_remote_ipaddr());
1531 cleanup_exit(255);
1532 }
1466 packet_write_poll(); 1533 packet_write_poll();
1467 } 1534 }
1468 xfree(setp); 1535 xfree(setp);