diff --git a/NEWS b/NEWS index b39fe02..366ed4b 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,17 @@ 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. @@ -16,8 +26,8 @@ Version 0.19 ( ) - Based on a patch in bug #1878059 by Steven Ayre libssh2 now parses >2GB file sizes when downloading SCP files. -- Bug #2064371 pointed out that the SSH2 banner may not use dash ('-'). Reported - by Bjorn Stenborg. +- Bug #2064371 pointed out that the SSH2 banner may not use dash + ('-'). Reported by Bjorn Stenborg. - Sean Peterson fixed a key re-exchange bug: http://daniel.haxx.se/projects/libssh2/mail/libssh2-devel-archive-2008-06/0002.shtml diff --git a/docs/Makefile.am b/docs/Makefile.am index e663726..32cedfa 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -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 @@ -29,6 +29,7 @@ dist_man_MANS = \ libssh2_scp_recv.3 \ libssh2_scp_send_ex.3 \ libssh2_session_abstract.3 \ + libssh2_session_block_directions.3 \ libssh2_session_callback_set.3 \ libssh2_session_free.3 \ libssh2_session_disconnect_ex.3 \ diff --git a/include/libssh2.h b/include/libssh2.h index 5c553d4..3bb7c44 100644 --- a/include/libssh2.h +++ b/include/libssh2.h @@ -244,6 +244,11 @@ typedef struct _LIBSSH2_POLLFD { #define LIBSSH2_POLLFD_CHANNEL_CLOSED 0x0080 /* Channel 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 */ #define LIBSSH2_HOSTKEY_HASH_MD5 1 #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 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_block_directions(LIBSSH2_SESSION *session); LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int value); diff --git a/src/kex.c b/src/kex.c index 9054858..3843278 100644 --- a/src/kex.c +++ b/src/kex.c @@ -1674,7 +1674,7 @@ libssh2_kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data, * Returns 0 on success, non-zero on failure */ 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) { int rc = 0; diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h index d2d26b2..8846670 100644 --- a/src/libssh2_priv.h +++ b/src/libssh2_priv.h @@ -705,6 +705,7 @@ struct _LIBSSH2_SESSION int socket_fd; int socket_block; int socket_state; + int socket_block_directions; /* Error tracking */ char *err_msg; diff --git a/src/packet.c b/src/packet.c index a30f603..1b0fc76 100644 --- a/src/packet.c +++ b/src/packet.c @@ -665,6 +665,8 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, datalen - 13, 0); if (rc == PACKET_EAGAIN) { + session->socket_block_directions = + LIBSSH2_SESSION_BLOCK_OUTBOUND; return PACKET_EAGAIN; } session->packAdd_state = libssh2_NB_state_idle; @@ -817,6 +819,8 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, &session-> packAdd_Qlstn_state); if (rc == PACKET_EAGAIN) { + session->socket_block_directions = + LIBSSH2_SESSION_BLOCK_OUTBOUND; return PACKET_EAGAIN; } @@ -833,6 +837,8 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, rc = libssh2_packet_x11_open(session, data, datalen, &session->packAdd_x11open_state); if (rc == PACKET_EAGAIN) { + session->socket_block_directions = + LIBSSH2_SESSION_BLOCK_OUTBOUND; return PACKET_EAGAIN; } diff --git a/src/session.c b/src/session.c index 1584af0..eb9b24e 100644 --- a/src/session.c +++ b/src/session.c @@ -133,6 +133,8 @@ libssh2_banner_receive(LIBSSH2_SESSION * session) } #endif /* WIN32 */ if (errno == EAGAIN) { + session->socket_block_directions = + LIBSSH2_SESSION_BLOCK_INBOUND; session->banner_TxRx_total_send = banner_len; return PACKET_EAGAIN; } @@ -235,6 +237,8 @@ libssh2_banner_send(LIBSSH2_SESSION * session) if (ret != (banner_len - session->banner_TxRx_total_send)) { if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) { /* 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; return PACKET_EAGAIN; } @@ -1536,4 +1540,15 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout) 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; +} + /* }}} */ diff --git a/src/transport.c b/src/transport.c index 2f3f605..e735514 100644 --- a/src/transport.c +++ b/src/transport.c @@ -385,6 +385,8 @@ libssh2_packet_read(LIBSSH2_SESSION * session) } #endif /* WIN32 */ if ((nread < 0) && (errno == EAGAIN)) { + session->socket_block_directions = + LIBSSH2_SESSION_BLOCK_INBOUND; return PACKET_EAGAIN; } return PACKET_FAIL; @@ -564,14 +566,14 @@ libssh2_packet_read(LIBSSH2_SESSION * session) 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 * returns PACKET_EAGAIN but the packAdd_state is idle, * then the packet has been added to the brigade, but some - * immediate action that was taken based on the packet - * type (such as key re-exchange) is not yet complete. + * immediate action that was taken based on the packet + * type (such as key re-exchange) is not yet complete. * Clear the way for a new packet to be read in. - */ + */ session->readPack_encrypted = encrypted; session->readPack_state = libssh2_NB_state_jump1; } @@ -634,6 +636,7 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data, /* send failure! */ return PACKET_FAIL; } + session->socket_block_directions = LIBSSH2_SESSION_BLOCK_OUTBOUND; return PACKET_EAGAIN; } @@ -786,6 +789,7 @@ libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data, if (ret != total_length) { if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) { /* the whole packet could not be sent, save the rest */ + session->socket_block_directions = LIBSSH2_SESSION_BLOCK_OUTBOUND; p->odata = orgdata; p->olen = orgdata_len; p->osent = (ret == -1) ? 0 : ret;