From 96c4c3bc5810e8bed980504e4fefcb49ef437a77 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 28 Sep 2020 06:17:49 -0500 Subject: [PATCH] SSH2: add setKeepAlive() method --- phpseclib/Net/SSH2.php | 45 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index d3cbc1f4a..17125801a 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -692,6 +692,14 @@ class Net_SSH2 */ var $curTimeout; + /** + * Keep Alive Interval + * + * @see self::setKeepAlive() + * @access private + */ + var $keepAlive; + /** * Real-time log file pointer * @@ -2691,6 +2699,19 @@ function setTimeout($timeout) $this->timeout = $this->curTimeout = $timeout; } + /** + * Set Keep Alive + * + * Sends an SSH2_MSG_IGNORE message every x seconds, if x is a positive non-zero number. + * + * @param mixed $timeout + * @access public + */ + function setKeepAlive($interval) + { + $this->keepAlive = $interval; + } + /** * Get the output from stdError * @@ -3684,8 +3705,15 @@ function _get_channel_packet($client_channel, $skip_extended = false) $read = array($this->fsock); $write = $except = null; - if (!$this->curTimeout) { - @stream_select($read, $write, $except, null); + if ($this->curTimeout <= 0) { + if ($this->keepAlive <= 0) { + @stream_select($read, $write, $except, null); + } else { + if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) { + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + continue; + } + } } else { if ($this->curTimeout < 0) { $this->is_timeout = true; @@ -3696,8 +3724,21 @@ function _get_channel_packet($client_channel, $skip_extended = false) $write = $except = null; $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 + + if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) { + if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) { + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + $elapsed = strtok(microtime(), ' ') + strtok('') - $start; + $this->curTimeout-= $elapsed; + continue; + } + $elapsed = strtok(microtime(), ' ') + strtok('') - $start; + $this->curTimeout-= $elapsed; + } + $sec = floor($this->curTimeout); $usec = 1000000 * ($this->curTimeout - $sec); + // on windows this returns a "Warning: Invalid CRT parameters detected" error if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) { $this->is_timeout = true;