summaryrefslogtreecommitdiff
path: root/clientloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'clientloop.c')
-rw-r--r--clientloop.c45
1 files changed, 40 insertions, 5 deletions
diff --git a/clientloop.c b/clientloop.c
index d8def78bd..d445230e5 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -317,10 +317,14 @@ client_check_window_change(void)
317 * one of the file descriptors). 317 * one of the file descriptors).
318 */ 318 */
319 319
320static void 320static int
321client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, 321client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
322 int *maxfdp, int *nallocp, int rekeying) 322 int *maxfdp, int *nallocp, int rekeying)
323{ 323{
324 struct timeval tv, *tvp;
325 int n;
326 extern Options options;
327
324 /* Add any selections by the channel mechanism. */ 328 /* Add any selections by the channel mechanism. */
325 channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying); 329 channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying);
326 330
@@ -349,7 +353,7 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
349 /* clear mask since we did not call select() */ 353 /* clear mask since we did not call select() */
350 memset(*readsetp, 0, *nallocp); 354 memset(*readsetp, 0, *nallocp);
351 memset(*writesetp, 0, *nallocp); 355 memset(*writesetp, 0, *nallocp);
352 return; 356 return 0;
353 } else { 357 } else {
354 FD_SET(connection_in, *readsetp); 358 FD_SET(connection_in, *readsetp);
355 } 359 }
@@ -368,7 +372,21 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
368 * SSH_MSG_IGNORE packet when the timeout expires. 372 * SSH_MSG_IGNORE packet when the timeout expires.
369 */ 373 */
370 374
371 if (select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL) < 0) { 375 /*
376 * We don't do the 'random' bit, but we want periodic ignored
377 * message anyway, so as to notice when the other ends TCP
378 * has given up during an outage.
379 */
380
381 if (options.protocolkeepalives > 0) {
382 tvp = &tv;
383 tv.tv_sec = options.protocolkeepalives;
384 tv.tv_usec = 0;
385 } else
386 tvp = 0;
387
388 n = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
389 if (n < 0) {
372 char buf[100]; 390 char buf[100];
373 391
374 /* 392 /*
@@ -380,12 +398,13 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
380 memset(*writesetp, 0, *nallocp); 398 memset(*writesetp, 0, *nallocp);
381 399
382 if (errno == EINTR) 400 if (errno == EINTR)
383 return; 401 return 0;
384 /* Note: we might still have data in the buffers. */ 402 /* Note: we might still have data in the buffers. */
385 snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); 403 snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno));
386 buffer_append(&stderr_buffer, buf, strlen(buf)); 404 buffer_append(&stderr_buffer, buf, strlen(buf));
387 quit_pending = 1; 405 quit_pending = 1;
388 } 406 }
407 return n == 0;
389} 408}
390 409
391static void 410static void
@@ -860,6 +879,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
860{ 879{
861 fd_set *readset = NULL, *writeset = NULL; 880 fd_set *readset = NULL, *writeset = NULL;
862 double start_time, total_time; 881 double start_time, total_time;
882 int timed_out;
863 int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0; 883 int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0;
864 char buf[100]; 884 char buf[100];
865 885
@@ -973,7 +993,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
973 * available on one of the descriptors). 993 * available on one of the descriptors).
974 */ 994 */
975 max_fd2 = max_fd; 995 max_fd2 = max_fd;
976 client_wait_until_can_do_something(&readset, &writeset, 996 timed_out = client_wait_until_can_do_something(&readset, &writeset,
977 &max_fd2, &nalloc, rekeying); 997 &max_fd2, &nalloc, rekeying);
978 998
979 if (quit_pending) 999 if (quit_pending)
@@ -996,6 +1016,21 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
996 if (quit_pending) 1016 if (quit_pending)
997 break; 1017 break;
998 1018
1019 if(timed_out) {
1020 /*
1021 * Nothing is happening, so synthesize some
1022 * bogus activity
1023 */
1024 packet_start(compat20
1025 ? SSH2_MSG_IGNORE
1026 : SSH_MSG_IGNORE);
1027 packet_put_cstring("");
1028 packet_send();
1029 if (FD_ISSET(connection_out, writeset))
1030 packet_write_poll();
1031 continue;
1032 }
1033
999 if (!compat20) { 1034 if (!compat20) {
1000 /* Buffer data from stdin */ 1035 /* Buffer data from stdin */
1001 client_process_input(readset); 1036 client_process_input(readset);