diff --git a/docs/libssh2_session_get_read_timeout.3 b/docs/libssh2_session_get_read_timeout.3 new file mode 100644 index 00000000..4f47af39 --- /dev/null +++ b/docs/libssh2_session_get_read_timeout.3 @@ -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 +.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) diff --git a/docs/libssh2_session_set_read_timeout.3 b/docs/libssh2_session_set_read_timeout.3 new file mode 100644 index 00000000..63acd000 --- /dev/null +++ b/docs/libssh2_session_set_read_timeout.3 @@ -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 +.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) diff --git a/include/libssh2.h b/include/libssh2.h index c932d763..0c82911a 100644 --- a/include/libssh2.h +++ b/include/libssh2.h @@ -916,6 +916,10 @@ LIBSSH2_API void libssh2_session_set_timeout(LIBSSH2_SESSION* session, long timeout); 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_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode); diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h index 0307ec09..67c4da54 100644 --- a/src/libssh2_priv.h +++ b/src/libssh2_priv.h @@ -883,6 +883,9 @@ struct _LIBSSH2_SESSION int keepalive_interval; int keepalive_want_reply; time_t keepalive_last_sent; + + /* Configurable timeout for packets. Replaces LIBSSH2_READ_TIMEOUT */ + long packet_read_timeout; }; /* 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, size_t length, int flags, void **abstract); -#define LIBSSH2_READ_TIMEOUT 60 /* generic timeout in seconds used when - waiting for more data to arrive */ +#define LIBSSH2_DEFAULT_READ_TIMEOUT 60 /* generic timeout in seconds used when + waiting for more data to arrive */ int _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, diff --git a/src/packet.c b/src/packet.c index f507770a..fa221e83 100644 --- a/src/packet.c +++ b/src/packet.c @@ -1267,8 +1267,8 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type, } else if(ret == 0) { /* nothing available, wait until data arrives or we time out */ - long left = LIBSSH2_READ_TIMEOUT - (long)(time(NULL) - - state->start); + long left = session->packet_read_timeout - (long)(time(NULL) - + state->start); if(left <= 0) { state->start = 0; @@ -1380,7 +1380,7 @@ _libssh2_packet_requirev(LIBSSH2_SESSION *session, return ret; } if(ret <= 0) { - long left = LIBSSH2_READ_TIMEOUT - + long left = session->packet_read_timeout - (long)(time(NULL) - state->start); if(left <= 0) { diff --git a/src/session.c b/src/session.c index 65946e1e..96a2167b 100644 --- a/src/session.c +++ b/src/session.c @@ -518,6 +518,7 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)), session->abstract = abstract; session->api_timeout = 0; /* timeout-free 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, "New session resource allocated")); _libssh2_init_if_needed(); @@ -1469,6 +1470,30 @@ libssh2_session_get_timeout(LIBSSH2_SESSION * session) 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 * diff --git a/src/sftp.c b/src/sftp.c index 0065f1b9..1e890b79 100644 --- a/src/sftp.c +++ b/src/sftp.c @@ -611,7 +611,7 @@ sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses, else if(rc <= 0) { /* prevent busy-looping */ long left = - LIBSSH2_READ_TIMEOUT - + sftp->channel->session->packet_read_timeout - (long)(time(NULL) - sftp->requirev_start); if(left <= 0) {