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 fcd75d2d7..abfde2f3a 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
@@ -846,6 +865,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
846{ 865{
847 fd_set *readset = NULL, *writeset = NULL; 866 fd_set *readset = NULL, *writeset = NULL;
848 double start_time, total_time; 867 double start_time, total_time;
868 int timed_out;
849 int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0; 869 int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0;
850 char buf[100]; 870 char buf[100];
851 871
@@ -959,7 +979,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
959 * available on one of the descriptors). 979 * available on one of the descriptors).
960 */ 980 */
961 max_fd2 = max_fd; 981 max_fd2 = max_fd;
962 client_wait_until_can_do_something(&readset, &writeset, 982 timed_out = client_wait_until_can_do_something(&readset, &writeset,
963 &max_fd2, &nalloc, rekeying); 983 &max_fd2, &nalloc, rekeying);
964 984
965 if (quit_pending) 985 if (quit_pending)
@@ -983,6 +1003,21 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
983 if (quit_pending) 1003 if (quit_pending)
984 break; 1004 break;
985 1005
1006 if(timed_out) {
1007 /*
1008 * Nothing is happening, so synthesize some
1009 * bogus activity
1010 */
1011 packet_start(compat20
1012 ? SSH2_MSG_IGNORE
1013 : SSH_MSG_IGNORE);
1014 packet_put_cstring("");
1015 packet_send();
1016 if (FD_ISSET(connection_out, writeset))
1017 packet_write_poll();
1018 continue;
1019 }
1020
986 if (!compat20) { 1021 if (!compat20) {
987 /* Buffer data from stdin */ 1022 /* Buffer data from stdin */
988 client_process_input(readset); 1023 client_process_input(readset);