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

agent.c: Recv and send all bytes via network in agent_transact_unix() (#510)

Files: agent.c

Notes:
Handle sending/receiving partial packet replies in agent.c API.

Credit: Klevanets Igor <cerevra@yandex-team.ru>
This commit is contained in:
Igor Klevanets
2020-09-23 23:15:01 +03:00
committed by GitHub
parent ecd6a74e44
commit 9ae9ff30cb

View File

@@ -175,6 +175,40 @@ agent_connect_unix(LIBSSH2_AGENT *agent)
return LIBSSH2_ERROR_NONE;
}
#define RECV_SEND_ALL(func, socket, buffer, length, flags, abstract) \
int rc; \
size_t finished; \
\
finished = 0; \
\
while(finished < length) { \
rc = func(socket, \
(char *)buffer + finished, length - finished, \
flags, abstract); \
if(rc < 0) \
return rc; \
\
finished += rc; \
} \
\
return finished;
static ssize_t _send_all(LIBSSH2_SEND_FUNC(func), libssh2_socket_t socket,
const void *buffer, size_t length,
int flags, void **abstract)
{
RECV_SEND_ALL(func, socket, buffer, length, flags, abstract);
}
static ssize_t _recv_all(LIBSSH2_RECV_FUNC(func), libssh2_socket_t socket,
void *buffer, size_t length,
int flags, void **abstract)
{
RECV_SEND_ALL(func, socket, buffer, length, flags, abstract);
}
#undef RECV_SEND_ALL
static int
agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
{
@@ -184,7 +218,8 @@ 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_FD(agent->session, agent->fd, buf, sizeof buf, 0);
rc = _send_all(agent->session->send, agent->fd,
buf, sizeof buf, 0, &agent->session->abstract);
if(rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
else if(rc < 0)
@@ -195,8 +230,8 @@ 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_FD(agent->session, agent->fd, transctx->request,
transctx->request_len, 0);
rc = _send_all(agent->session->send, agent->fd, transctx->request,
transctx->request_len, 0, &agent->session->abstract);
if(rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
else if(rc < 0)
@@ -207,7 +242,8 @@ 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_FD(agent->session, agent->fd, buf, sizeof buf, 0);
rc = _recv_all(agent->session->recv, agent->fd,
buf, sizeof buf, 0, &agent->session->abstract);
if(rc < 0) {
if(rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
@@ -225,8 +261,8 @@ 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_FD(agent->session, agent->fd, transctx->response,
transctx->response_len, 0);
rc = _recv_all(agent->session->recv, agent->fd, transctx->response,
transctx->response_len, 0, &agent->session->abstract);
if(rc < 0) {
if(rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN;