Custom callbacks for performing low level socket I/O
This commit is contained in:
parent
462996b064
commit
7aa4bfc671
@ -33,6 +33,12 @@ Called when a mismatched MAC has been detected in the transport layer. If the
|
||||
function returns 0, the packet will be accepted nonetheless.
|
||||
.IP LIBSSH2_CALLBACK_X11
|
||||
Called when an X11 connection has been accepted
|
||||
.IP LIBSSH2_CALLBACK_SEND
|
||||
Called when libssh2 wants to send some data on the connection.
|
||||
Can be set to a custom function to handle I/O your own way.
|
||||
.IP LIBSSH2_CALLBACK_RECV
|
||||
Called when libssh2 wants to receive some data from the connection.
|
||||
Can be set to a custom function to handle I/O your own way.
|
||||
.SH RETURN VALUE
|
||||
Pointer to previous callback handler. Returns NULL if no prior callback
|
||||
handler was set or the callback type was unknown.
|
||||
|
@ -237,12 +237,22 @@ typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE
|
||||
void name(LIBSSH2_SESSION *session, void **session_abstract, \
|
||||
LIBSSH2_CHANNEL *channel, void **channel_abstract)
|
||||
|
||||
/* I/O callbacks */
|
||||
#define LIBSSH2_RECV_FUNC(name) ssize_t name(int socket, \
|
||||
void *buffer, size_t length, \
|
||||
int flags, void **abstract)
|
||||
#define LIBSSH2_SEND_FUNC(name) ssize_t name(int socket, \
|
||||
const void *buffer, size_t length,\
|
||||
int flags, void **abstract)
|
||||
|
||||
/* libssh2_session_callback_set() constants */
|
||||
#define LIBSSH2_CALLBACK_IGNORE 0
|
||||
#define LIBSSH2_CALLBACK_DEBUG 1
|
||||
#define LIBSSH2_CALLBACK_DISCONNECT 2
|
||||
#define LIBSSH2_CALLBACK_MACERROR 3
|
||||
#define LIBSSH2_CALLBACK_X11 4
|
||||
#define LIBSSH2_CALLBACK_SEND 5
|
||||
#define LIBSSH2_CALLBACK_RECV 6
|
||||
|
||||
/* libssh2_session_method_pref() constants */
|
||||
#define LIBSSH2_METHOD_KEX 0
|
||||
|
@ -177,7 +177,7 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
/* Send the length of the request */
|
||||
if (transctx->state == agent_NB_state_request_created) {
|
||||
_libssh2_htonu32(buf, transctx->request_len);
|
||||
rc = _libssh2_send(agent->fd, buf, sizeof buf, 0);
|
||||
rc = LIBSSH2_SEND_FD(agent->session, agent->fd, buf, sizeof buf, 0);
|
||||
if (rc == -EAGAIN)
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
else if (rc < 0)
|
||||
@ -188,7 +188,7 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
|
||||
/* Send the request body */
|
||||
if (transctx->state == agent_NB_state_request_length_sent) {
|
||||
rc = _libssh2_send(agent->fd, transctx->request,
|
||||
rc = LIBSSH2_SEND_FD(agent->session, agent->fd, transctx->request,
|
||||
transctx->request_len, 0);
|
||||
if (rc == -EAGAIN)
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
@ -200,7 +200,7 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
|
||||
/* Receive the length of a response */
|
||||
if (transctx->state == agent_NB_state_request_sent) {
|
||||
rc = _libssh2_recv(agent->fd, buf, sizeof buf, 0);
|
||||
rc = LIBSSH2_RECV_FD(agent->session, agent->fd, buf, sizeof buf, 0);
|
||||
if (rc < 0) {
|
||||
if (rc == -EAGAIN)
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
@ -218,7 +218,7 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
|
||||
/* Receive the response body */
|
||||
if (transctx->state == agent_NB_state_response_length_received) {
|
||||
rc = _libssh2_recv(agent->fd, transctx->response,
|
||||
rc = LIBSSH2_RECV_FD(agent->session, agent->fd, transctx->response,
|
||||
transctx->response_len, 0);
|
||||
if (rc < 0) {
|
||||
if (rc == -EAGAIN)
|
||||
|
@ -171,6 +171,12 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
|
||||
|
||||
#define LIBSSH2_CHANNEL_CLOSE(session, channel) channel->close_cb((session), &(session)->abstract, (channel), &(channel)->abstract)
|
||||
|
||||
#define LIBSSH2_SEND_FD(session, fd, buffer, length, flags) session->send(fd, buffer, length, flags, &session->abstract)
|
||||
#define LIBSSH2_RECV_FD(session, fd, buffer, length, flags) session->recv(fd, buffer, length, flags, &session->abstract)
|
||||
|
||||
#define LIBSSH2_SEND(session, buffer, length, flags) LIBSSH2_SEND_FD(session, session->socket_fd, buffer, length, flags)
|
||||
#define LIBSSH2_RECV(session, buffer, length, flags) LIBSSH2_SEND_FD(session, session->socket_fd, buffer, length, flags)
|
||||
|
||||
typedef struct _LIBSSH2_KEX_METHOD LIBSSH2_KEX_METHOD;
|
||||
typedef struct _LIBSSH2_HOSTKEY_METHOD LIBSSH2_HOSTKEY_METHOD;
|
||||
typedef struct _LIBSSH2_CRYPT_METHOD LIBSSH2_CRYPT_METHOD;
|
||||
@ -539,6 +545,8 @@ struct _LIBSSH2_SESSION
|
||||
LIBSSH2_DISCONNECT_FUNC((*ssh_msg_disconnect));
|
||||
LIBSSH2_MACERROR_FUNC((*macerror));
|
||||
LIBSSH2_X11_OPEN_FUNC((*x11));
|
||||
LIBSSH2_SEND_FUNC((*send));
|
||||
LIBSSH2_RECV_FUNC((*recv));
|
||||
|
||||
/* Method preferences -- NULL yields "load order" */
|
||||
char *kex_prefs;
|
||||
@ -972,9 +980,9 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
|
||||
#define SSH_OPEN_RESOURCE_SHORTAGE 4
|
||||
|
||||
ssize_t _libssh2_recv(libssh2_socket_t socket, void *buffer,
|
||||
size_t length, int flags);
|
||||
size_t length, int flags, void **abstract);
|
||||
ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer,
|
||||
size_t length, int flags);
|
||||
size_t length, int flags, void **abstract);
|
||||
|
||||
#define LIBSSH2_READ_TIMEOUT 60 /* generic timeout in seconds used when
|
||||
waiting for more data to arrive */
|
||||
|
@ -94,7 +94,7 @@ static int wsa2errno(void)
|
||||
* Replacement for the standard recv, return -errno on failure.
|
||||
*/
|
||||
ssize_t
|
||||
_libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length, int flags)
|
||||
_libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length, int flags, void **abstract)
|
||||
{
|
||||
ssize_t rc = recv(sock, buffer, length, flags);
|
||||
#ifdef WIN32
|
||||
@ -126,7 +126,7 @@ _libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length, int flags)
|
||||
*/
|
||||
ssize_t
|
||||
_libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length,
|
||||
int flags)
|
||||
int flags, void **abstract)
|
||||
{
|
||||
ssize_t rc = send(sock, buffer, length, flags);
|
||||
#ifdef WIN32
|
||||
|
@ -115,7 +115,7 @@ banner_receive(LIBSSH2_SESSION * session)
|
||||
/* no incoming block yet! */
|
||||
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||
|
||||
ret = _libssh2_recv(session->socket_fd, &c, 1,
|
||||
ret = LIBSSH2_RECV(session, &c, 1,
|
||||
LIBSSH2_SOCKET_RECV_FLAGS(session));
|
||||
if (ret < 0) {
|
||||
if(session->api_block_mode || (ret != -EAGAIN))
|
||||
@ -227,7 +227,7 @@ banner_send(LIBSSH2_SESSION * session)
|
||||
/* no outgoing block yet! */
|
||||
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||
|
||||
ret = _libssh2_send(session->socket_fd,
|
||||
ret = LIBSSH2_SEND(session,
|
||||
banner + session->banner_TxRx_total_send,
|
||||
banner_len - session->banner_TxRx_total_send,
|
||||
LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||
@ -481,6 +481,8 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
|
||||
session->alloc = local_alloc;
|
||||
session->free = local_free;
|
||||
session->realloc = local_realloc;
|
||||
session->send = _libssh2_send;
|
||||
session->recv = _libssh2_recv;
|
||||
session->abstract = abstract;
|
||||
session->api_timeout = 0; /* timeout-free API by default */
|
||||
session->api_block_mode = 1; /* blocking API by default */
|
||||
@ -532,6 +534,15 @@ libssh2_session_callback_set(LIBSSH2_SESSION * session,
|
||||
session->x11 = callback;
|
||||
return oldcb;
|
||||
|
||||
case LIBSSH2_CALLBACK_SEND:
|
||||
oldcb = session->send;
|
||||
session->send = callback;
|
||||
return oldcb;
|
||||
|
||||
case LIBSSH2_CALLBACK_RECV:
|
||||
oldcb = session->recv;
|
||||
session->recv = callback;
|
||||
return oldcb;
|
||||
}
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting Callback %d", cbtype);
|
||||
|
||||
|
@ -357,7 +357,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
||||
|
||||
/* now read a big chunk from the network into the temp buffer */
|
||||
nread =
|
||||
_libssh2_recv(session->socket_fd, &p->buf[remainbuf],
|
||||
LIBSSH2_RECV(session, &p->buf[remainbuf],
|
||||
PACKETBUFSIZE - remainbuf,
|
||||
LIBSSH2_SOCKET_RECV_FLAGS(session));
|
||||
if (nread <= 0) {
|
||||
@ -610,7 +610,7 @@ send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
|
||||
/* number of bytes left to send */
|
||||
length = p->ototal_num - p->osent;
|
||||
|
||||
rc = _libssh2_send(session->socket_fd, &p->outbuf[p->osent], length,
|
||||
rc = LIBSSH2_SEND(session, &p->outbuf[p->osent], length,
|
||||
LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||
if (rc < 0)
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||
@ -823,7 +823,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
||||
|
||||
session->local.seqno++;
|
||||
|
||||
ret = _libssh2_send(session->socket_fd, p->outbuf, total_length,
|
||||
ret = LIBSSH2_SEND(session, p->outbuf, total_length,
|
||||
LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||
if (ret < 0)
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||
|
Loading…
Reference in New Issue
Block a user