1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-08-08 19:02:07 +03:00

- Vlad Grachov brought the new function called

libssh2_session_block_directions() which returns a bitmask for what
  directions the connection blocks. It is to be used applications that use
  non-blocking sockets and when a libssh2 function returns
  LIBSSH2_ERROR_EAGAIN this function can be used to figure out in which
  direction the socket would block and thus it can wait for the socket to
  again be ready for communication in that direction before it calls libssh2
  again.
This commit is contained in:
Daniel Stenberg
2008-11-24 13:31:00 +00:00
parent 881b01e522
commit 160f89f42e
8 changed files with 52 additions and 9 deletions

16
NEWS
View File

@@ -1,7 +1,17 @@
Version 0.19 ( ) Version 0.19 ( )
------------------------------- -------------------------------
- Vincent Jaulin brought the new libssh2_channel_request_pty_size_ex() function. - Vlad Grachov brought the new function called
libssh2_session_block_directions() which returns a bitmask for what
directions the connection blocks. It is to be used applications that use
non-blocking sockets and when a libssh2 function returns
LIBSSH2_ERROR_EAGAIN this function can be used to figure out in which
direction the socket would block and thus it can wait for the socket to
again be ready for communication in that direction before it calls libssh2
again.
- Vincent Jaulin brought the new libssh2_channel_request_pty_size_ex()
function.
- Carlo Bramini fixed the build for msys+mingw. Bug #1943976. - Carlo Bramini fixed the build for msys+mingw. Bug #1943976.
@@ -16,8 +26,8 @@ Version 0.19 ( )
- Based on a patch in bug #1878059 by Steven Ayre libssh2 now parses >2GB file - Based on a patch in bug #1878059 by Steven Ayre libssh2 now parses >2GB file
sizes when downloading SCP files. sizes when downloading SCP files.
- Bug #2064371 pointed out that the SSH2 banner may not use dash ('-'). Reported - Bug #2064371 pointed out that the SSH2 banner may not use dash
by Bjorn Stenborg. ('-'). Reported by Bjorn Stenborg.
- Sean Peterson fixed a key re-exchange bug: - Sean Peterson fixed a key re-exchange bug:
http://daniel.haxx.se/projects/libssh2/mail/libssh2-devel-archive-2008-06/0002.shtml http://daniel.haxx.se/projects/libssh2/mail/libssh2-devel-archive-2008-06/0002.shtml

View File

@@ -1,4 +1,4 @@
# $Id: Makefile.am,v 1.28 2008/03/08 18:26:32 dottedmag Exp $ # $Id: Makefile.am,v 1.29 2008/11/24 13:31:00 bagder Exp $
EXTRA_DIST = template.3 EXTRA_DIST = template.3
@@ -29,6 +29,7 @@ dist_man_MANS = \
libssh2_scp_recv.3 \ libssh2_scp_recv.3 \
libssh2_scp_send_ex.3 \ libssh2_scp_send_ex.3 \
libssh2_session_abstract.3 \ libssh2_session_abstract.3 \
libssh2_session_block_directions.3 \
libssh2_session_callback_set.3 \ libssh2_session_callback_set.3 \
libssh2_session_free.3 \ libssh2_session_free.3 \
libssh2_session_disconnect_ex.3 \ libssh2_session_disconnect_ex.3 \

View File

@@ -244,6 +244,11 @@ typedef struct _LIBSSH2_POLLFD {
#define LIBSSH2_POLLFD_CHANNEL_CLOSED 0x0080 /* Channel Disconnect */ #define LIBSSH2_POLLFD_CHANNEL_CLOSED 0x0080 /* Channel Disconnect */
#define LIBSSH2_POLLFD_LISTENER_CLOSED 0x0080 /* Listener Disconnect */ #define LIBSSH2_POLLFD_LISTENER_CLOSED 0x0080 /* Listener Disconnect */
#define HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
/* Block Direction Types */
#define LIBSSH2_SESSION_BLOCK_INBOUND 0x0001
#define LIBSSH2_SESSION_BLOCK_OUTBOUND 0x0002
/* Hash Types */ /* Hash Types */
#define LIBSSH2_HOSTKEY_HASH_MD5 1 #define LIBSSH2_HOSTKEY_HASH_MD5 1
#define LIBSSH2_HOSTKEY_HASH_SHA1 2 #define LIBSSH2_HOSTKEY_HASH_SHA1 2
@@ -324,6 +329,7 @@ LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, int method
LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int method_type); LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int method_type);
LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf); LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf);
LIBSSH2_API int libssh2_session_last_errno(LIBSSH2_SESSION *session); LIBSSH2_API int libssh2_session_last_errno(LIBSSH2_SESSION *session);
LIBSSH2_API int libssh2_session_block_directions(LIBSSH2_SESSION *session);
LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int value); LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int value);

View File

@@ -1674,7 +1674,7 @@ libssh2_kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
* Returns 0 on success, non-zero on failure * Returns 0 on success, non-zero on failure
*/ */
int int
libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, /* session->flags |= SERVER */ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
key_exchange_state_t * key_state) key_exchange_state_t * key_state)
{ {
int rc = 0; int rc = 0;

View File

@@ -705,6 +705,7 @@ struct _LIBSSH2_SESSION
int socket_fd; int socket_fd;
int socket_block; int socket_block;
int socket_state; int socket_state;
int socket_block_directions;
/* Error tracking */ /* Error tracking */
char *err_msg; char *err_msg;

View File

@@ -665,6 +665,8 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
datalen - 13, datalen - 13,
0); 0);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_OUTBOUND;
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
session->packAdd_state = libssh2_NB_state_idle; session->packAdd_state = libssh2_NB_state_idle;
@@ -817,6 +819,8 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
&session-> &session->
packAdd_Qlstn_state); packAdd_Qlstn_state);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_OUTBOUND;
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
@@ -833,6 +837,8 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
rc = libssh2_packet_x11_open(session, data, datalen, rc = libssh2_packet_x11_open(session, data, datalen,
&session->packAdd_x11open_state); &session->packAdd_x11open_state);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_OUTBOUND;
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }

View File

@@ -133,6 +133,8 @@ libssh2_banner_receive(LIBSSH2_SESSION * session)
} }
#endif /* WIN32 */ #endif /* WIN32 */
if (errno == EAGAIN) { if (errno == EAGAIN) {
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_INBOUND;
session->banner_TxRx_total_send = banner_len; session->banner_TxRx_total_send = banner_len;
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
@@ -235,6 +237,8 @@ libssh2_banner_send(LIBSSH2_SESSION * session)
if (ret != (banner_len - session->banner_TxRx_total_send)) { if (ret != (banner_len - session->banner_TxRx_total_send)) {
if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) { if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
/* the whole packet could not be sent, save the what was */ /* the whole packet could not be sent, save the what was */
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_OUTBOUND;
session->banner_TxRx_total_send += ret; session->banner_TxRx_total_send += ret;
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
@@ -1536,4 +1540,15 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
return active_fds; return active_fds;
} }
/* {{{ libssh2_session_block_direction
* Get blocked direction when a function returns LIBSSH2_ERROR_EAGAIN
* Returns LIBSSH2_SOCKET_BLOCK_INBOUND if recv() blocked
* or LIBSSH2_SOCKET_BLOCK_OUTBOUND if send() blocked
*/
LIBSSH2_API int
libssh2_session_block_directions(LIBSSH2_SESSION *session)
{
return session->socket_block_directions;
}
/* }}} */ /* }}} */

View File

@@ -385,6 +385,8 @@ libssh2_packet_read(LIBSSH2_SESSION * session)
} }
#endif /* WIN32 */ #endif /* WIN32 */
if ((nread < 0) && (errno == EAGAIN)) { if ((nread < 0) && (errno == EAGAIN)) {
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_INBOUND;
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
return PACKET_FAIL; return PACKET_FAIL;
@@ -564,14 +566,14 @@ libssh2_packet_read(LIBSSH2_SESSION * session)
if (session->packAdd_state != libssh2_NB_state_idle) if (session->packAdd_state != libssh2_NB_state_idle)
{ {
/* fullpacket only returns PACKET_EAGAIN if /* fullpacket only returns PACKET_EAGAIN if
* libssh2_packet_add returns PACKET_EAGAIN. If that * libssh2_packet_add returns PACKET_EAGAIN. If that
* returns PACKET_EAGAIN but the packAdd_state is idle, * returns PACKET_EAGAIN but the packAdd_state is idle,
* then the packet has been added to the brigade, but some * then the packet has been added to the brigade, but some
* immediate action that was taken based on the packet * immediate action that was taken based on the packet
* type (such as key re-exchange) is not yet complete. * type (such as key re-exchange) is not yet complete.
* Clear the way for a new packet to be read in. * Clear the way for a new packet to be read in.
*/ */
session->readPack_encrypted = encrypted; session->readPack_encrypted = encrypted;
session->readPack_state = libssh2_NB_state_jump1; session->readPack_state = libssh2_NB_state_jump1;
} }
@@ -634,6 +636,7 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
/* send failure! */ /* send failure! */
return PACKET_FAIL; return PACKET_FAIL;
} }
session->socket_block_directions = LIBSSH2_SESSION_BLOCK_OUTBOUND;
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
@@ -786,6 +789,7 @@ libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
if (ret != total_length) { if (ret != total_length) {
if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) { if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
/* the whole packet could not be sent, save the rest */ /* the whole packet could not be sent, save the rest */
session->socket_block_directions = LIBSSH2_SESSION_BLOCK_OUTBOUND;
p->odata = orgdata; p->odata = orgdata;
p->olen = orgdata_len; p->olen = orgdata_len;
p->osent = (ret == -1) ? 0 : ret; p->osent = (ret == -1) ? 0 : ret;