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 42ace7789..2cebea29f 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 |
@@ -166,6 +166,7 @@ static int connection_out; /* Connection to server (output). */ | |||
166 | static int need_rekeying; /* Set to non-zero if rekeying is requested. */ | 166 | static int need_rekeying; /* Set to non-zero if rekeying is requested. */ |
167 | static int session_closed; /* In SSH2: login session closed. */ | 167 | static int session_closed; /* In SSH2: login session closed. */ |
168 | static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ | 168 | static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ |
169 | static time_t server_alive_time; /* Time to do server_alive_check */ | ||
169 | 170 | ||
170 | static void client_init_dispatch(struct ssh *ssh); | 171 | static void client_init_dispatch(struct ssh *ssh); |
171 | int session_ident = -1; | 172 | int session_ident = -1; |
@@ -471,6 +472,13 @@ client_global_request_reply(int type, u_int32_t seq, struct ssh *ssh) | |||
471 | } | 472 | } |
472 | 473 | ||
473 | static void | 474 | static void |
475 | schedule_server_alive_check(void) | ||
476 | { | ||
477 | if (options.server_alive_interval > 0) | ||
478 | server_alive_time = monotime() + options.server_alive_interval; | ||
479 | } | ||
480 | |||
481 | static void | ||
474 | server_alive_check(struct ssh *ssh) | 482 | server_alive_check(struct ssh *ssh) |
475 | { | 483 | { |
476 | int r; | 484 | int r; |
@@ -486,6 +494,7 @@ server_alive_check(struct ssh *ssh) | |||
486 | fatal("%s: send packet: %s", __func__, ssh_err(r)); | 494 | fatal("%s: send packet: %s", __func__, ssh_err(r)); |
487 | /* Insert an empty placeholder to maintain ordering */ | 495 | /* Insert an empty placeholder to maintain ordering */ |
488 | client_register_global_confirm(NULL, NULL); | 496 | client_register_global_confirm(NULL, NULL); |
497 | schedule_server_alive_check(); | ||
489 | } | 498 | } |
490 | 499 | ||
491 | /* | 500 | /* |
@@ -499,7 +508,7 @@ client_wait_until_can_do_something(struct ssh *ssh, | |||
499 | { | 508 | { |
500 | struct timeval tv, *tvp; | 509 | struct timeval tv, *tvp; |
501 | int timeout_secs; | 510 | int timeout_secs; |
502 | time_t minwait_secs = 0, server_alive_time = 0, now = monotime(); | 511 | time_t minwait_secs = 0, now = monotime(); |
503 | int r, ret; | 512 | int r, ret; |
504 | 513 | ||
505 | /* Add any selections by the channel mechanism. */ | 514 | /* Add any selections by the channel mechanism. */ |
@@ -528,10 +537,8 @@ client_wait_until_can_do_something(struct ssh *ssh, | |||
528 | */ | 537 | */ |
529 | 538 | ||
530 | timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */ | 539 | timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */ |
531 | if (options.server_alive_interval > 0) { | 540 | if (options.server_alive_interval > 0) |
532 | timeout_secs = options.server_alive_interval; | 541 | timeout_secs = MAXIMUM(server_alive_time - now, 0); |
533 | server_alive_time = now + options.server_alive_interval; | ||
534 | } | ||
535 | if (options.rekey_interval > 0 && !rekeying) | 542 | if (options.rekey_interval > 0 && !rekeying) |
536 | timeout_secs = MINIMUM(timeout_secs, | 543 | timeout_secs = MINIMUM(timeout_secs, |
537 | ssh_packet_get_rekey_timeout(ssh)); | 544 | ssh_packet_get_rekey_timeout(ssh)); |
@@ -561,7 +568,6 @@ client_wait_until_can_do_something(struct ssh *ssh, | |||
561 | */ | 568 | */ |
562 | memset(*readsetp, 0, *nallocp); | 569 | memset(*readsetp, 0, *nallocp); |
563 | memset(*writesetp, 0, *nallocp); | 570 | memset(*writesetp, 0, *nallocp); |
564 | |||
565 | if (errno == EINTR) | 571 | if (errno == EINTR) |
566 | return; | 572 | return; |
567 | /* Note: we might still have data in the buffers. */ | 573 | /* Note: we might still have data in the buffers. */ |
@@ -569,15 +575,14 @@ client_wait_until_can_do_something(struct ssh *ssh, | |||
569 | "select: %s\r\n", strerror(errno))) != 0) | 575 | "select: %s\r\n", strerror(errno))) != 0) |
570 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 576 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
571 | quit_pending = 1; | 577 | quit_pending = 1; |
572 | } else if (ret == 0) { | 578 | } else if (options.server_alive_interval > 0 && !FD_ISSET(connection_in, |
579 | *readsetp) && monotime() >= server_alive_time) | ||
573 | /* | 580 | /* |
574 | * Timeout. Could have been either keepalive or rekeying. | 581 | * ServerAlive check is needed. We can't rely on the select |
575 | * Keepalive we check here, rekeying is checked in clientloop. | 582 | * timing out since traffic on the client side such as port |
583 | * forwards can keep waking it up. | ||
576 | */ | 584 | */ |
577 | if (server_alive_time != 0 && server_alive_time <= monotime()) | 585 | server_alive_check(ssh); |
578 | server_alive_check(ssh); | ||
579 | } | ||
580 | |||
581 | } | 586 | } |
582 | 587 | ||
583 | static void | 588 | static void |
@@ -617,6 +622,7 @@ client_process_net_input(struct ssh *ssh, fd_set *readset) | |||
617 | * the packet subsystem. | 622 | * the packet subsystem. |
618 | */ | 623 | */ |
619 | if (FD_ISSET(connection_in, readset)) { | 624 | if (FD_ISSET(connection_in, readset)) { |
625 | schedule_server_alive_check(); | ||
620 | /* Read as much as possible. */ | 626 | /* Read as much as possible. */ |
621 | len = read(connection_in, buf, sizeof(buf)); | 627 | len = read(connection_in, buf, sizeof(buf)); |
622 | if (len == 0) { | 628 | if (len == 0) { |
@@ -1236,7 +1242,6 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, | |||
1236 | int r, max_fd = 0, max_fd2 = 0, len; | 1242 | int r, max_fd = 0, max_fd2 = 0, len; |
1237 | u_int64_t ibytes, obytes; | 1243 | u_int64_t ibytes, obytes; |
1238 | u_int nalloc = 0; | 1244 | u_int nalloc = 0; |
1239 | char buf[100]; | ||
1240 | 1245 | ||
1241 | debug("Entering interactive session."); | 1246 | debug("Entering interactive session."); |
1242 | 1247 | ||
@@ -1318,6 +1323,8 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, | |||
1318 | client_channel_closed, 0); | 1323 | client_channel_closed, 0); |
1319 | } | 1324 | } |
1320 | 1325 | ||
1326 | schedule_server_alive_check(); | ||
1327 | |||
1321 | /* Main loop of the client for the interactive session mode. */ | 1328 | /* Main loop of the client for the interactive session mode. */ |
1322 | while (!quit_pending) { | 1329 | while (!quit_pending) { |
1323 | 1330 | ||
@@ -1472,7 +1479,6 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, | |||
1472 | } | 1479 | } |
1473 | 1480 | ||
1474 | /* Clear and free any buffers. */ | 1481 | /* Clear and free any buffers. */ |
1475 | explicit_bzero(buf, sizeof(buf)); | ||
1476 | sshbuf_free(stderr_buffer); | 1482 | sshbuf_free(stderr_buffer); |
1477 | 1483 | ||
1478 | /* Report bytes transferred, and transfer rates. */ | 1484 | /* Report bytes transferred, and transfer rates. */ |