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 cd2eab77a..6d19b4a25 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
@@ -844,6 +863,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
844{ 863{
845 fd_set *readset = NULL, *writeset = NULL; 864 fd_set *readset = NULL, *writeset = NULL;
846 double start_time, total_time; 865 double start_time, total_time;
866 int timed_out;
847 int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0; 867 int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0;
848 char buf[100]; 868 char buf[100];
849 869
@@ -951,7 +971,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
951 * available on one of the descriptors). 971 * available on one of the descriptors).
952 */ 972 */
953 max_fd2 = max_fd; 973 max_fd2 = max_fd;
954 client_wait_until_can_do_something(&readset, &writeset, 974 timed_out = client_wait_until_can_do_something(&readset, &writeset,
955 &max_fd2, &nalloc, rekeying); 975 &max_fd2, &nalloc, rekeying);
956 976
957 if (quit_pending) 977 if (quit_pending)
@@ -975,6 +995,21 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
975 if (quit_pending) 995 if (quit_pending)
976 break; 996 break;
977 997
998 if(timed_out) {
999 /*
1000 * Nothing is happening, so synthesize some
1001 * bogus activity
1002 */
1003 packet_start(compat20
1004 ? SSH2_MSG_IGNORE
1005 : SSH_MSG_IGNORE);
1006 packet_put_cstring("");
1007 packet_send();
1008 if (FD_ISSET(connection_out, writeset))
1009 packet_write_poll();
1010 continue;
1011 }
1012
978 if (!compat20) { 1013 if (!compat20) {
979 /* Buffer data from stdin */ 1014 /* Buffer data from stdin */
980 client_process_input(readset); 1015 client_process_input(readset);