1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-07-29 13:01:14 +03:00

Configurable session read timeout (#892)

This set of changes provides a mechanism to runtime-configure the
previously #define'd timeout for reading packets from a session. The
intention here is to also extend libcurl to be able to use this
interface so that when fetching from sftp servers which are very slow
to return directory listings, connections do not time-out so much.

* Add new field to session to hold configurable read timeout

* Updated `_libssh2_packet_require()`, `_libssh2_packet_requirev()`,
  and `sftp_packet_requirev()` to use new field in session structure

* Updated docs for API functions to set/get read timeout field in
  session structure

* Updated `libssh2.h` to declare the get/set read timeout functions

Co-authored-by: Jon Axtell <jon.axtell@codethink.co.uk>
Credit: Daniel Silverstone
This commit is contained in:
Daniel Silverstone
2023-04-05 14:53:53 +01:00
committed by GitHub
parent a7d60c62ab
commit c20c81ab10
7 changed files with 77 additions and 6 deletions

View File

@ -0,0 +1,19 @@
.TH libssh2_session_get_read_timeout 3 "13 Jan 2023" "libssh2 1.10.1" "libssh2 manual"
.SH NAME
libssh2_session_get_read_timeout - get the timeout for packet read functions
.SH SYNOPSIS
#include <libssh2.h>
.nf
long libssh2_session_get_read_timeout(LIBSSH2_SESSION *session);
.SH DESCRIPTION
Returns the \fBtimeout\fP (in seconds) for how long the ssh2 packet receive
function calls may wait until they consider the situation an error and
return LIBSSH2_ERROR_TIMEOUT.
By default the timeout is 60 seconds.
.SH RETURN VALUE
The value of the timeout setting.
.SH AVAILABILITY
Added in 1.10.1
.SH SEE ALSO
.BR libssh2_session_set_read_timeout(3)

View File

@ -0,0 +1,20 @@
.TH libssh2_session_set_read_timeout 3 "13 Jan 2023" "libssh2 1.10.1" "libssh2 manual"
.SH NAME
libssh2_session_set_read_timeout - set timeout for packet read functions
.SH SYNOPSIS
#include <libssh2.h>
.nf
void libssh2_session_set_read_timeout(LIBSSH2_SESSION *session, long timeout);
.SH DESCRIPTION
Set the \fBtimeout\fP in seconds for how long libssh2 packet read
function calls may wait until they consider the situation an error and return
LIBSSH2_ERROR_TIMEOUT.
By default or if you set the timeout to zero, the timeout will be set to
60 seconds.
.SH RETURN VALUE
Nothing
.SH AVAILABILITY
Added in 1.10.1
.SH SEE ALSO
.BR libssh2_session_get_read_timeout(3)

View File

@ -916,6 +916,10 @@ LIBSSH2_API void libssh2_session_set_timeout(LIBSSH2_SESSION* session,
long timeout); long timeout);
LIBSSH2_API long libssh2_session_get_timeout(LIBSSH2_SESSION* session); LIBSSH2_API long libssh2_session_get_timeout(LIBSSH2_SESSION* session);
LIBSSH2_API void libssh2_session_set_read_timeout(LIBSSH2_SESSION* session,
long timeout);
LIBSSH2_API long libssh2_session_get_read_timeout(LIBSSH2_SESSION* session);
/* libssh2_channel_handle_extended_data is DEPRECATED, do not use! */ /* libssh2_channel_handle_extended_data is DEPRECATED, do not use! */
LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel,
int ignore_mode); int ignore_mode);

View File

@ -883,6 +883,9 @@ struct _LIBSSH2_SESSION
int keepalive_interval; int keepalive_interval;
int keepalive_want_reply; int keepalive_want_reply;
time_t keepalive_last_sent; time_t keepalive_last_sent;
/* Configurable timeout for packets. Replaces LIBSSH2_READ_TIMEOUT */
long packet_read_timeout;
}; };
/* session.state bits */ /* session.state bits */
@ -1089,8 +1092,8 @@ ssize_t _libssh2_recv(libssh2_socket_t socket, void *buffer,
ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer, ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer,
size_t length, int flags, void **abstract); size_t length, int flags, void **abstract);
#define LIBSSH2_READ_TIMEOUT 60 /* generic timeout in seconds used when #define LIBSSH2_DEFAULT_READ_TIMEOUT 60 /* generic timeout in seconds used when
waiting for more data to arrive */ waiting for more data to arrive */
int _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, int _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,

View File

@ -1267,8 +1267,8 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
} }
else if(ret == 0) { else if(ret == 0) {
/* nothing available, wait until data arrives or we time out */ /* nothing available, wait until data arrives or we time out */
long left = LIBSSH2_READ_TIMEOUT - (long)(time(NULL) - long left = session->packet_read_timeout - (long)(time(NULL) -
state->start); state->start);
if(left <= 0) { if(left <= 0) {
state->start = 0; state->start = 0;
@ -1380,7 +1380,7 @@ _libssh2_packet_requirev(LIBSSH2_SESSION *session,
return ret; return ret;
} }
if(ret <= 0) { if(ret <= 0) {
long left = LIBSSH2_READ_TIMEOUT - long left = session->packet_read_timeout -
(long)(time(NULL) - state->start); (long)(time(NULL) - state->start);
if(left <= 0) { if(left <= 0) {

View File

@ -518,6 +518,7 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
session->abstract = abstract; session->abstract = abstract;
session->api_timeout = 0; /* timeout-free API by default */ session->api_timeout = 0; /* timeout-free API by default */
session->api_block_mode = 1; /* blocking API by default */ session->api_block_mode = 1; /* blocking API by default */
session->packet_read_timeout = LIBSSH2_DEFAULT_READ_TIMEOUT;
_libssh2_debug((session, LIBSSH2_TRACE_TRANS, _libssh2_debug((session, LIBSSH2_TRACE_TRANS,
"New session resource allocated")); "New session resource allocated"));
_libssh2_init_if_needed(); _libssh2_init_if_needed();
@ -1469,6 +1470,30 @@ libssh2_session_get_timeout(LIBSSH2_SESSION * session)
return session->api_timeout; return session->api_timeout;
} }
/* libssh2_session_set_read_timeout
*
* Set a session's timeout (in sec) when reading packets,
* or 0 to use default of 60 seconds.
*/
LIBSSH2_API void
libssh2_session_set_read_timeout(LIBSSH2_SESSION * session, long timeout)
{
if(timeout <= 0) {
timeout = LIBSSH2_DEFAULT_READ_TIMEOUT;
}
session->packet_read_timeout = timeout;
}
/* libssh2_session_get_read_timeout
*
* Returns a session's timeout. Default is 60 seconds.
*/
LIBSSH2_API long
libssh2_session_get_read_timeout(LIBSSH2_SESSION * session)
{
return session->packet_read_timeout;
}
/* /*
* libssh2_poll_channel_read * libssh2_poll_channel_read
* *

View File

@ -611,7 +611,7 @@ sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses,
else if(rc <= 0) { else if(rc <= 0) {
/* prevent busy-looping */ /* prevent busy-looping */
long left = long left =
LIBSSH2_READ_TIMEOUT - sftp->channel->session->packet_read_timeout -
(long)(time(NULL) - sftp->requirev_start); (long)(time(NULL) - sftp->requirev_start);
if(left <= 0) { if(left <= 0) {