diff options
Diffstat (limited to 'clientloop.c')
-rw-r--r-- | clientloop.c | 38 |
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). */ | |||
162 | static int need_rekeying; /* Set to non-zero if rekeying is requested. */ | 162 | static int need_rekeying; /* Set to non-zero if rekeying is requested. */ |
163 | static int session_closed; /* In SSH2: login session closed. */ | 163 | static int session_closed; /* In SSH2: login session closed. */ |
164 | static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ | 164 | static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ |
165 | static time_t server_alive_time; /* Time to do server_alive_check */ | ||
165 | 166 | ||
166 | static void client_init_dispatch(struct ssh *ssh); | 167 | static void client_init_dispatch(struct ssh *ssh); |
167 | int session_ident = -1; | 168 | int session_ident = -1; |
@@ -467,6 +468,13 @@ client_global_request_reply(int type, u_int32_t seq, struct ssh *ssh) | |||
467 | } | 468 | } |
468 | 469 | ||
469 | static void | 470 | static void |
471 | schedule_server_alive_check(void) | ||
472 | { | ||
473 | if (options.server_alive_interval > 0) | ||
474 | server_alive_time = monotime() + options.server_alive_interval; | ||
475 | } | ||
476 | |||
477 | static void | ||
470 | server_alive_check(struct ssh *ssh) | 478 | server_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 | ||
579 | static void | 584 | static 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. */ |