summaryrefslogtreecommitdiff
path: root/clientloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'clientloop.c')
-rw-r--r--clientloop.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/clientloop.c b/clientloop.c
index da396c72a..60b46d161 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.344 2020/04/24 02:19:40 dtucker Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.346 2020/09/16 03:07:31 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
@@ -162,6 +162,7 @@ static int connection_out; /* Connection to server (output). */
162static int need_rekeying; /* Set to non-zero if rekeying is requested. */ 162static int need_rekeying; /* Set to non-zero if rekeying is requested. */
163static int session_closed; /* In SSH2: login session closed. */ 163static int session_closed; /* In SSH2: login session closed. */
164static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ 164static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */
165static time_t server_alive_time; /* Time to do server_alive_check */
165 166
166static void client_init_dispatch(struct ssh *ssh); 167static void client_init_dispatch(struct ssh *ssh);
167int session_ident = -1; 168int session_ident = -1;
@@ -467,6 +468,13 @@ client_global_request_reply(int type, u_int32_t seq, struct ssh *ssh)
467} 468}
468 469
469static void 470static void
471schedule_server_alive_check(void)
472{
473 if (options.server_alive_interval > 0)
474 server_alive_time = monotime() + options.server_alive_interval;
475}
476
477static void
470server_alive_check(struct ssh *ssh) 478server_alive_check(struct ssh *ssh)
471{ 479{
472 int r; 480 int r;
@@ -482,6 +490,7 @@ server_alive_check(struct ssh *ssh)
482 fatal("%s: send packet: %s", __func__, ssh_err(r)); 490 fatal("%s: send packet: %s", __func__, ssh_err(r));
483 /* Insert an empty placeholder to maintain ordering */ 491 /* Insert an empty placeholder to maintain ordering */
484 client_register_global_confirm(NULL, NULL); 492 client_register_global_confirm(NULL, NULL);
493 schedule_server_alive_check();
485} 494}
486 495
487/* 496/*
@@ -495,7 +504,7 @@ client_wait_until_can_do_something(struct ssh *ssh,
495{ 504{
496 struct timeval tv, *tvp; 505 struct timeval tv, *tvp;
497 int timeout_secs; 506 int timeout_secs;
498 time_t minwait_secs = 0, server_alive_time = 0, now = monotime(); 507 time_t minwait_secs = 0, now = monotime();
499 int r, ret; 508 int r, ret;
500 509
501 /* Add any selections by the channel mechanism. */ 510 /* Add any selections by the channel mechanism. */
@@ -524,10 +533,8 @@ client_wait_until_can_do_something(struct ssh *ssh,
524 */ 533 */
525 534
526 timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */ 535 timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */
527 if (options.server_alive_interval > 0) { 536 if (options.server_alive_interval > 0)
528 timeout_secs = options.server_alive_interval; 537 timeout_secs = MAXIMUM(server_alive_time - now, 0);
529 server_alive_time = now + options.server_alive_interval;
530 }
531 if (options.rekey_interval > 0 && !rekeying) 538 if (options.rekey_interval > 0 && !rekeying)
532 timeout_secs = MINIMUM(timeout_secs, 539 timeout_secs = MINIMUM(timeout_secs,
533 ssh_packet_get_rekey_timeout(ssh)); 540 ssh_packet_get_rekey_timeout(ssh));
@@ -557,7 +564,6 @@ client_wait_until_can_do_something(struct ssh *ssh,
557 */ 564 */
558 memset(*readsetp, 0, *nallocp); 565 memset(*readsetp, 0, *nallocp);
559 memset(*writesetp, 0, *nallocp); 566 memset(*writesetp, 0, *nallocp);
560
561 if (errno == EINTR) 567 if (errno == EINTR)
562 return; 568 return;
563 /* Note: we might still have data in the buffers. */ 569 /* Note: we might still have data in the buffers. */
@@ -565,15 +571,14 @@ client_wait_until_can_do_something(struct ssh *ssh,
565 "select: %s\r\n", strerror(errno))) != 0) 571 "select: %s\r\n", strerror(errno))) != 0)
566 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 572 fatal("%s: buffer error: %s", __func__, ssh_err(r));
567 quit_pending = 1; 573 quit_pending = 1;
568 } else if (ret == 0) { 574 } else if (options.server_alive_interval > 0 && !FD_ISSET(connection_in,
575 *readsetp) && monotime() >= server_alive_time)
569 /* 576 /*
570 * Timeout. Could have been either keepalive or rekeying. 577 * ServerAlive check is needed. We can't rely on the select
571 * Keepalive we check here, rekeying is checked in clientloop. 578 * timing out since traffic on the client side such as port
579 * forwards can keep waking it up.
572 */ 580 */
573 if (server_alive_time != 0 && server_alive_time <= monotime()) 581 server_alive_check(ssh);
574 server_alive_check(ssh);
575 }
576
577} 582}
578 583
579static void 584static void
@@ -613,6 +618,7 @@ client_process_net_input(struct ssh *ssh, fd_set *readset)
613 * the packet subsystem. 618 * the packet subsystem.
614 */ 619 */
615 if (FD_ISSET(connection_in, readset)) { 620 if (FD_ISSET(connection_in, readset)) {
621 schedule_server_alive_check();
616 /* Read as much as possible. */ 622 /* Read as much as possible. */
617 len = read(connection_in, buf, sizeof(buf)); 623 len = read(connection_in, buf, sizeof(buf));
618 if (len == 0) { 624 if (len == 0) {
@@ -1232,7 +1238,6 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1232 int r, max_fd = 0, max_fd2 = 0, len; 1238 int r, max_fd = 0, max_fd2 = 0, len;
1233 u_int64_t ibytes, obytes; 1239 u_int64_t ibytes, obytes;
1234 u_int nalloc = 0; 1240 u_int nalloc = 0;
1235 char buf[100];
1236 1241
1237 debug("Entering interactive session."); 1242 debug("Entering interactive session.");
1238 1243
@@ -1314,6 +1319,8 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1314 client_channel_closed, 0); 1319 client_channel_closed, 0);
1315 } 1320 }
1316 1321
1322 schedule_server_alive_check();
1323
1317 /* Main loop of the client for the interactive session mode. */ 1324 /* Main loop of the client for the interactive session mode. */
1318 while (!quit_pending) { 1325 while (!quit_pending) {
1319 1326
@@ -1459,7 +1466,6 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1459 } 1466 }
1460 1467
1461 /* Clear and free any buffers. */ 1468 /* Clear and free any buffers. */
1462 explicit_bzero(buf, sizeof(buf));
1463 sshbuf_free(stderr_buffer); 1469 sshbuf_free(stderr_buffer);
1464 1470
1465 /* Report bytes transferred, and transfer rates. */ 1471 /* Report bytes transferred, and transfer rates. */