|
Lines 155-160
static int connection_out; /* Connection
Link Here
|
| 155 |
static int need_rekeying; /* Set to non-zero if rekeying is requested. */ |
155 |
static int need_rekeying; /* Set to non-zero if rekeying is requested. */ |
| 156 |
static int session_closed; /* In SSH2: login session closed. */ |
156 |
static int session_closed; /* In SSH2: login session closed. */ |
| 157 |
static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ |
157 |
static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ |
|
|
158 |
static time_t server_alive_time; /* Time to do server_alive_check */ |
| 158 |
|
159 |
|
| 159 |
static void client_init_dispatch(struct ssh *ssh); |
160 |
static void client_init_dispatch(struct ssh *ssh); |
| 160 |
int session_ident = -1; |
161 |
int session_ident = -1; |
|
Lines 460-465
client_global_request_reply(int type, u_
Link Here
|
| 460 |
} |
461 |
} |
| 461 |
|
462 |
|
| 462 |
static void |
463 |
static void |
|
|
464 |
schedule_server_alive_check() |
| 465 |
{ |
| 466 |
if (options.server_alive_interval > 0) |
| 467 |
server_alive_time = monotime() + options.server_alive_interval; |
| 468 |
} |
| 469 |
|
| 470 |
static void |
| 463 |
server_alive_check(struct ssh *ssh) |
471 |
server_alive_check(struct ssh *ssh) |
| 464 |
{ |
472 |
{ |
| 465 |
int r; |
473 |
int r; |
|
Lines 475-480
server_alive_check(struct ssh *ssh)
Link Here
|
| 475 |
fatal("%s: send packet: %s", __func__, ssh_err(r)); |
483 |
fatal("%s: send packet: %s", __func__, ssh_err(r)); |
| 476 |
/* Insert an empty placeholder to maintain ordering */ |
484 |
/* Insert an empty placeholder to maintain ordering */ |
| 477 |
client_register_global_confirm(NULL, NULL); |
485 |
client_register_global_confirm(NULL, NULL); |
|
|
486 |
schedule_server_alive_check(); |
| 478 |
} |
487 |
} |
| 479 |
|
488 |
|
| 480 |
/* |
489 |
/* |
|
Lines 488-494
client_wait_until_can_do_something(struc
Link Here
|
| 488 |
{ |
497 |
{ |
| 489 |
struct timeval tv, *tvp; |
498 |
struct timeval tv, *tvp; |
| 490 |
int timeout_secs; |
499 |
int timeout_secs; |
| 491 |
time_t minwait_secs = 0, server_alive_time = 0, now = monotime(); |
500 |
time_t minwait_secs = 0, now = monotime(); |
| 492 |
int r, ret; |
501 |
int r, ret; |
| 493 |
|
502 |
|
| 494 |
/* Add any selections by the channel mechanism. */ |
503 |
/* Add any selections by the channel mechanism. */ |
|
Lines 517-526
client_wait_until_can_do_something(struc
Link Here
|
| 517 |
*/ |
526 |
*/ |
| 518 |
|
527 |
|
| 519 |
timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */ |
528 |
timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */ |
| 520 |
if (options.server_alive_interval > 0) { |
529 |
if (options.server_alive_interval > 0) |
| 521 |
timeout_secs = options.server_alive_interval; |
530 |
timeout_secs = MAXIMUM(server_alive_time - now, 0); |
| 522 |
server_alive_time = now + options.server_alive_interval; |
|
|
| 523 |
} |
| 524 |
if (options.rekey_interval > 0 && !rekeying) |
531 |
if (options.rekey_interval > 0 && !rekeying) |
| 525 |
timeout_secs = MINIMUM(timeout_secs, |
532 |
timeout_secs = MINIMUM(timeout_secs, |
| 526 |
ssh_packet_get_rekey_timeout(ssh)); |
533 |
ssh_packet_get_rekey_timeout(ssh)); |
|
Lines 550-570
client_wait_until_can_do_something(struc
Link Here
|
| 550 |
*/ |
557 |
*/ |
| 551 |
memset(*readsetp, 0, *nallocp); |
558 |
memset(*readsetp, 0, *nallocp); |
| 552 |
memset(*writesetp, 0, *nallocp); |
559 |
memset(*writesetp, 0, *nallocp); |
| 553 |
|
560 |
if (errno == EINTR) |
| 554 |
if (errno == EINTR) |
|
|
| 555 |
return; |
561 |
return; |
| 556 |
/* Note: we might still have data in the buffers. */ |
562 |
/* Note: we might still have data in the buffers. */ |
| 557 |
if ((r = sshbuf_putf(stderr_buffer, |
563 |
if ((r = sshbuf_putf(stderr_buffer, |
| 558 |
"select: %s\r\n", strerror(errno))) != 0) |
564 |
"select: %s\r\n", strerror(errno))) != 0) |
| 559 |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
565 |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
| 560 |
quit_pending = 1; |
566 |
quit_pending = 1; |
| 561 |
} else if (ret == 0) { |
567 |
} else if (options.server_alive_interval > 0 && !FD_ISSET(connection_in, |
|
|
568 |
*readsetp) && monotime() >= server_alive_time) |
| 562 |
/* |
569 |
/* |
| 563 |
* Timeout. Could have been either keepalive or rekeying. |
570 |
* ServerAlive check is needed. We can't rely on the select |
| 564 |
* Keepalive we check here, rekeying is checked in clientloop. |
571 |
* timing out since traffic on the client side such as port |
|
|
572 |
* forwards can keep waking it up. |
| 565 |
*/ |
573 |
*/ |
| 566 |
if (server_alive_time != 0 && server_alive_time <= monotime()) |
574 |
server_alive_check(ssh); |
| 567 |
server_alive_check(ssh); |
|
|
| 568 |
} |
575 |
} |
| 569 |
|
576 |
|
| 570 |
} |
577 |
} |
|
Lines 606-611
client_process_net_input(struct ssh *ssh
Link Here
|
| 606 |
* the packet subsystem. |
613 |
* the packet subsystem. |
| 607 |
*/ |
614 |
*/ |
| 608 |
if (FD_ISSET(connection_in, readset)) { |
615 |
if (FD_ISSET(connection_in, readset)) { |
|
|
616 |
schedule_server_alive_check(); |
| 609 |
/* Read as much as possible. */ |
617 |
/* Read as much as possible. */ |
| 610 |
len = read(connection_in, buf, sizeof(buf)); |
618 |
len = read(connection_in, buf, sizeof(buf)); |
| 611 |
if (len == 0) { |
619 |
if (len == 0) { |
|
Lines 1305-1310
client_loop(struct ssh *ssh, int have_pt
Link Here
|
| 1305 |
channel_register_cleanup(ssh, session_ident, |
1313 |
channel_register_cleanup(ssh, session_ident, |
| 1306 |
client_channel_closed, 0); |
1314 |
client_channel_closed, 0); |
| 1307 |
} |
1315 |
} |
|
|
1316 |
|
| 1317 |
schedule_server_alive_check(); |
| 1308 |
|
1318 |
|
| 1309 |
/* Main loop of the client for the interactive session mode. */ |
1319 |
/* Main loop of the client for the interactive session mode. */ |
| 1310 |
while (!quit_pending) { |
1320 |
while (!quit_pending) { |