mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-11 18:50:28 +09:00
Compare commits
7 Commits
ef50a3c0f0
...
118a747acd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
118a747acd | ||
|
|
5691e0f609 | ||
|
|
5a6e2fd02a | ||
|
|
e8099375fe | ||
|
|
d00f267bc6 | ||
|
|
35d337834b | ||
|
|
ba1e8303f8 |
@@ -33,7 +33,7 @@ void ssh_socket_cleanup(void);
|
|||||||
ssh_socket ssh_socket_new(ssh_session session);
|
ssh_socket ssh_socket_new(ssh_session session);
|
||||||
void ssh_socket_reset(ssh_socket s);
|
void ssh_socket_reset(ssh_socket s);
|
||||||
void ssh_socket_free(ssh_socket s);
|
void ssh_socket_free(ssh_socket s);
|
||||||
void ssh_socket_set_fd(ssh_socket s, socket_t fd);
|
int ssh_socket_set_fd(ssh_socket s, socket_t fd);
|
||||||
socket_t ssh_socket_get_fd(ssh_socket s);
|
socket_t ssh_socket_get_fd(ssh_socket s);
|
||||||
void ssh_socket_set_connected(ssh_socket s, struct ssh_poll_handle_struct *p);
|
void ssh_socket_set_connected(ssh_socket s, struct ssh_poll_handle_struct *p);
|
||||||
int ssh_socket_unix(ssh_socket s, const char *path);
|
int ssh_socket_unix(ssh_socket s, const char *path);
|
||||||
|
|||||||
@@ -210,8 +210,7 @@ int ssh_set_agent_socket(ssh_session session, socket_t fd)
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_socket_set_fd(session->agent->sock, fd);
|
return ssh_socket_set_fd(session->agent->sock, fd);
|
||||||
return SSH_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -505,7 +505,10 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd)
|
|||||||
ssh_set_error_oom(sshbind);
|
ssh_set_error_oom(sshbind);
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
ssh_socket_set_fd(session->socket, fd);
|
rc = ssh_socket_set_fd(session->socket, fd);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
handle = ssh_socket_get_poll_handle(session->socket);
|
handle = ssh_socket_get_poll_handle(session->socket);
|
||||||
if (handle == NULL) {
|
if (handle == NULL) {
|
||||||
ssh_set_error_oom(sshbind);
|
ssh_set_error_oom(sshbind);
|
||||||
|
|||||||
@@ -602,8 +602,7 @@ int ssh_connect(ssh_session session)
|
|||||||
|
|
||||||
if (session->opts.fd != SSH_INVALID_SOCKET) {
|
if (session->opts.fd != SSH_INVALID_SOCKET) {
|
||||||
session->session_state = SSH_SESSION_STATE_SOCKET_CONNECTED;
|
session->session_state = SSH_SESSION_STATE_SOCKET_CONNECTED;
|
||||||
ssh_socket_set_fd(session->socket, session->opts.fd);
|
ret = ssh_socket_set_fd(session->socket, session->opts.fd);
|
||||||
ret = SSH_OK;
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#ifdef HAVE_PTHREAD
|
#ifdef HAVE_PTHREAD
|
||||||
} else if (ssh_libssh_proxy_jumps() &&
|
} else if (ssh_libssh_proxy_jumps() &&
|
||||||
|
|||||||
@@ -1985,10 +1985,10 @@ int ssh_options_apply(ssh_session session)
|
|||||||
* it with ssh expansion of ssh escape characters.
|
* it with ssh expansion of ssh escape characters.
|
||||||
*/
|
*/
|
||||||
tmp = ssh_path_expand_escape(session, id);
|
tmp = ssh_path_expand_escape(session, id);
|
||||||
|
free(id);
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
free(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* use append to keep the order at first call and use prepend
|
/* use append to keep the order at first call and use prepend
|
||||||
@@ -1999,6 +1999,7 @@ int ssh_options_apply(ssh_session session)
|
|||||||
rc = ssh_list_append(session->opts.identity, tmp);
|
rc = ssh_list_append(session->opts.identity, tmp);
|
||||||
}
|
}
|
||||||
if (rc != SSH_OK) {
|
if (rc != SSH_OK) {
|
||||||
|
free(tmp);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2010,13 +2011,14 @@ int ssh_options_apply(ssh_session session)
|
|||||||
char *id = tmp;
|
char *id = tmp;
|
||||||
|
|
||||||
tmp = ssh_path_expand_escape(session, id);
|
tmp = ssh_path_expand_escape(session, id);
|
||||||
|
free(id);
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
free(id);
|
|
||||||
|
|
||||||
rc = ssh_list_append(session->opts.certificate, tmp);
|
rc = ssh_list_append(session->opts.certificate, tmp);
|
||||||
if (rc != SSH_OK) {
|
if (rc != SSH_OK) {
|
||||||
|
free(tmp);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
243
src/poll.c
243
src/poll.c
@@ -61,24 +61,24 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct ssh_poll_handle_struct {
|
struct ssh_poll_handle_struct {
|
||||||
ssh_poll_ctx ctx;
|
ssh_poll_ctx ctx;
|
||||||
ssh_session session;
|
ssh_session session;
|
||||||
union {
|
union {
|
||||||
socket_t fd;
|
socket_t fd;
|
||||||
size_t idx;
|
size_t idx;
|
||||||
} x;
|
} x;
|
||||||
short events;
|
short events;
|
||||||
uint32_t lock_cnt;
|
uint32_t lock_cnt;
|
||||||
ssh_poll_callback cb;
|
ssh_poll_callback cb;
|
||||||
void *cb_data;
|
void *cb_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ssh_poll_ctx_struct {
|
struct ssh_poll_ctx_struct {
|
||||||
ssh_poll_handle *pollptrs;
|
ssh_poll_handle *pollptrs;
|
||||||
ssh_pollfd_t *pollfds;
|
ssh_pollfd_t *pollfds;
|
||||||
size_t polls_allocated;
|
size_t polls_allocated;
|
||||||
size_t polls_used;
|
size_t polls_used;
|
||||||
size_t chunk_size;
|
size_t chunk_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
@@ -96,7 +96,7 @@ void ssh_poll_cleanup(void)
|
|||||||
|
|
||||||
int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout)
|
int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout)
|
||||||
{
|
{
|
||||||
return poll((struct pollfd *) fds, nfds, timeout);
|
return poll((struct pollfd *)fds, nfds, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* HAVE_POLL */
|
#else /* HAVE_POLL */
|
||||||
@@ -249,14 +249,15 @@ static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// we use the readfds to get POLLHUP and POLLERR, which are provided even when not requested
|
// we use the readfds to get POLLHUP and POLLERR, which are provided
|
||||||
FD_SET (fds[i].fd, &readfds);
|
// even when not requested
|
||||||
|
FD_SET(fds[i].fd, &readfds);
|
||||||
|
|
||||||
if (fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND)) {
|
if (fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND)) {
|
||||||
FD_SET (fds[i].fd, &writefds);
|
FD_SET(fds[i].fd, &writefds);
|
||||||
}
|
}
|
||||||
if (fds[i].events & (POLLPRI | POLLRDBAND)) {
|
if (fds[i].events & (POLLPRI | POLLRDBAND)) {
|
||||||
FD_SET (fds[i].fd, &exceptfds);
|
FD_SET(fds[i].fd, &exceptfds);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fds[i].fd > max_fd) {
|
if (fds[i].fd > max_fd) {
|
||||||
@@ -297,11 +298,12 @@ static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout)
|
|||||||
fds[i].revents = 0;
|
fds[i].revents = 0;
|
||||||
|
|
||||||
if (FD_ISSET(fds[i].fd, &readfds)) {
|
if (FD_ISSET(fds[i].fd, &readfds)) {
|
||||||
fds[i].revents = bsd_socket_compute_revents(fds[i].fd,
|
fds[i].revents =
|
||||||
fds[i].events);
|
bsd_socket_compute_revents(fds[i].fd, fds[i].events);
|
||||||
}
|
}
|
||||||
if (FD_ISSET(fds[i].fd, &writefds)) {
|
if (FD_ISSET(fds[i].fd, &writefds)) {
|
||||||
fds[i].revents |= fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND);
|
fds[i].revents |=
|
||||||
|
fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(fds[i].fd, &exceptfds)) {
|
if (FD_ISSET(fds[i].fd, &exceptfds)) {
|
||||||
@@ -319,22 +321,26 @@ static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ssh_poll_init(void) {
|
void ssh_poll_init(void)
|
||||||
|
{
|
||||||
ssh_poll_emu = bsd_poll;
|
ssh_poll_emu = bsd_poll;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ssh_poll_cleanup(void) {
|
void ssh_poll_cleanup(void)
|
||||||
|
{
|
||||||
ssh_poll_emu = bsd_poll;
|
ssh_poll_emu = bsd_poll;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout)
|
||||||
|
{
|
||||||
return (ssh_poll_emu)(fds, nfds, timeout);
|
return (ssh_poll_emu)(fds, nfds, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_POLL */
|
#endif /* HAVE_POLL */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allocate a new poll object, which could be used within a poll context.
|
* @brief Allocate a new poll object, which could be used within a poll
|
||||||
|
* context.
|
||||||
*
|
*
|
||||||
* @param[in] fd Socket that will be polled.
|
* @param[in] fd Socket that will be polled.
|
||||||
* @param[in] events Poll events that will be monitored for the socket.
|
* @param[in] events Poll events that will be monitored for the socket.
|
||||||
@@ -354,7 +360,7 @@ int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
|||||||
ssh_poll_handle
|
ssh_poll_handle
|
||||||
ssh_poll_new(socket_t fd, short events, ssh_poll_callback cb, void *userdata)
|
ssh_poll_new(socket_t fd, short events, ssh_poll_callback cb, void *userdata)
|
||||||
{
|
{
|
||||||
ssh_poll_handle p;
|
ssh_poll_handle p = NULL;
|
||||||
|
|
||||||
p = malloc(sizeof(struct ssh_poll_handle_struct));
|
p = malloc(sizeof(struct ssh_poll_handle_struct));
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
@@ -370,7 +376,6 @@ ssh_poll_new(socket_t fd, short events, ssh_poll_callback cb, void *userdata)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Free a poll object.
|
* @brief Free a poll object.
|
||||||
*
|
*
|
||||||
@@ -433,8 +438,8 @@ void ssh_poll_set_events(ssh_poll_handle p, short events)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the file descriptor of a poll object. The FD will also be propagated
|
* @brief Set the file descriptor of a poll object. The FD will also be
|
||||||
* to an associated poll context.
|
* propagated to an associated poll context.
|
||||||
*
|
*
|
||||||
* @param p Pointer to an already allocated poll object.
|
* @param p Pointer to an already allocated poll object.
|
||||||
* @param fd New file descriptor.
|
* @param fd New file descriptor.
|
||||||
@@ -496,7 +501,9 @@ socket_t ssh_poll_get_fd(ssh_poll_handle p)
|
|||||||
* @param userdata Userdata to be passed to the callback function. NULL if
|
* @param userdata Userdata to be passed to the callback function. NULL if
|
||||||
* not needed.
|
* not needed.
|
||||||
*/
|
*/
|
||||||
void ssh_poll_set_callback(ssh_poll_handle p, ssh_poll_callback cb, void *userdata)
|
void ssh_poll_set_callback(ssh_poll_handle p,
|
||||||
|
ssh_poll_callback cb,
|
||||||
|
void *userdata)
|
||||||
{
|
{
|
||||||
if (cb != NULL) {
|
if (cb != NULL) {
|
||||||
p->cb = cb;
|
p->cb = cb;
|
||||||
@@ -542,7 +549,7 @@ ssh_poll_ctx ssh_poll_ctx_new(size_t chunk_size)
|
|||||||
void ssh_poll_ctx_free(ssh_poll_ctx ctx)
|
void ssh_poll_ctx_free(ssh_poll_ctx ctx)
|
||||||
{
|
{
|
||||||
if (ctx->polls_allocated > 0) {
|
if (ctx->polls_allocated > 0) {
|
||||||
while (ctx->polls_used > 0){
|
while (ctx->polls_used > 0) {
|
||||||
ssh_poll_handle p = ctx->pollptrs[0];
|
ssh_poll_handle p = ctx->pollptrs[0];
|
||||||
/*
|
/*
|
||||||
* The free function calls ssh_poll_ctx_remove() and decrements
|
* The free function calls ssh_poll_ctx_remove() and decrements
|
||||||
@@ -565,25 +572,33 @@ static int ssh_poll_ctx_resize(ssh_poll_ctx ctx, size_t new_size)
|
|||||||
|
|
||||||
pollptrs = realloc(ctx->pollptrs, sizeof(ssh_poll_handle) * new_size);
|
pollptrs = realloc(ctx->pollptrs, sizeof(ssh_poll_handle) * new_size);
|
||||||
if (pollptrs == NULL) {
|
if (pollptrs == NULL) {
|
||||||
return -1;
|
/* Fail, but keep the old value to be freed later */
|
||||||
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
ctx->pollptrs = pollptrs;
|
ctx->pollptrs = pollptrs;
|
||||||
|
|
||||||
pollfds = realloc(ctx->pollfds, sizeof(ssh_pollfd_t) * new_size);
|
pollfds = realloc(ctx->pollfds, sizeof(ssh_pollfd_t) * new_size);
|
||||||
if (pollfds == NULL) {
|
if (pollfds == NULL) {
|
||||||
|
if (ctx->polls_allocated == 0) {
|
||||||
|
/* This was initial allocation -- just free what we allocated above
|
||||||
|
* and fail */
|
||||||
|
SAFE_FREE(ctx->pollptrs);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
/* Try to realloc the pollptrs back to the original size */
|
||||||
pollptrs = realloc(ctx->pollptrs,
|
pollptrs = realloc(ctx->pollptrs,
|
||||||
sizeof(ssh_poll_handle) * ctx->polls_allocated);
|
sizeof(ssh_poll_handle) * ctx->polls_allocated);
|
||||||
if (pollptrs == NULL) {
|
if (pollptrs == NULL) {
|
||||||
return -1;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
ctx->pollptrs = pollptrs;
|
ctx->pollptrs = pollptrs;
|
||||||
return -1;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->pollfds = pollfds;
|
ctx->pollfds = pollfds;
|
||||||
ctx->polls_allocated = new_size;
|
ctx->polls_allocated = new_size;
|
||||||
|
|
||||||
return 0;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -596,27 +611,27 @@ static int ssh_poll_ctx_resize(ssh_poll_ctx ctx, size_t new_size)
|
|||||||
*/
|
*/
|
||||||
int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p)
|
int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p)
|
||||||
{
|
{
|
||||||
socket_t fd;
|
socket_t fd;
|
||||||
|
|
||||||
if (p->ctx != NULL) {
|
if (p->ctx != NULL) {
|
||||||
/* already attached to a context */
|
/* already attached to a context */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->polls_used == ctx->polls_allocated &&
|
if (ctx->polls_used == ctx->polls_allocated &&
|
||||||
ssh_poll_ctx_resize(ctx, ctx->polls_allocated + ctx->chunk_size) < 0) {
|
ssh_poll_ctx_resize(ctx, ctx->polls_allocated + ctx->chunk_size) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = p->x.fd;
|
fd = p->x.fd;
|
||||||
p->x.idx = ctx->polls_used++;
|
p->x.idx = ctx->polls_used++;
|
||||||
ctx->pollptrs[p->x.idx] = p;
|
ctx->pollptrs[p->x.idx] = p;
|
||||||
ctx->pollfds[p->x.idx].fd = fd;
|
ctx->pollfds[p->x.idx].fd = fd;
|
||||||
ctx->pollfds[p->x.idx].events = p->events;
|
ctx->pollfds[p->x.idx].events = p->events;
|
||||||
ctx->pollfds[p->x.idx].revents = 0;
|
ctx->pollfds[p->x.idx].revents = 0;
|
||||||
p->ctx = ctx;
|
p->ctx = ctx;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -627,20 +642,17 @@ int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p)
|
|||||||
*
|
*
|
||||||
* @return 0 on success, < 0 on error
|
* @return 0 on success, < 0 on error
|
||||||
*/
|
*/
|
||||||
int ssh_poll_ctx_add_socket (ssh_poll_ctx ctx, ssh_socket s)
|
int ssh_poll_ctx_add_socket(ssh_poll_ctx ctx, ssh_socket s)
|
||||||
{
|
{
|
||||||
ssh_poll_handle p = NULL;
|
ssh_poll_handle p = NULL;
|
||||||
int ret;
|
|
||||||
|
|
||||||
p = ssh_socket_get_poll_handle(s);
|
p = ssh_socket_get_poll_handle(s);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ret = ssh_poll_ctx_add(ctx,p);
|
return ssh_poll_ctx_add(ctx, p);
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Remove a poll object from a poll context.
|
* @brief Remove a poll object from a poll context.
|
||||||
*
|
*
|
||||||
@@ -649,25 +661,25 @@ int ssh_poll_ctx_add_socket (ssh_poll_ctx ctx, ssh_socket s)
|
|||||||
*/
|
*/
|
||||||
void ssh_poll_ctx_remove(ssh_poll_ctx ctx, ssh_poll_handle p)
|
void ssh_poll_ctx_remove(ssh_poll_ctx ctx, ssh_poll_handle p)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
i = p->x.idx;
|
i = p->x.idx;
|
||||||
p->x.fd = ctx->pollfds[i].fd;
|
p->x.fd = ctx->pollfds[i].fd;
|
||||||
p->ctx = NULL;
|
p->ctx = NULL;
|
||||||
|
|
||||||
ctx->polls_used--;
|
ctx->polls_used--;
|
||||||
|
|
||||||
/* fill the empty poll slot with the last one */
|
/* fill the empty poll slot with the last one */
|
||||||
if (ctx->polls_used > 0 && ctx->polls_used != i) {
|
if (ctx->polls_used > 0 && ctx->polls_used != i) {
|
||||||
ctx->pollfds[i] = ctx->pollfds[ctx->polls_used];
|
ctx->pollfds[i] = ctx->pollfds[ctx->polls_used];
|
||||||
ctx->pollptrs[i] = ctx->pollptrs[ctx->polls_used];
|
ctx->pollptrs[i] = ctx->pollptrs[ctx->polls_used];
|
||||||
ctx->pollptrs[i]->x.idx = i;
|
ctx->pollptrs[i]->x.idx = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this will always leave at least chunk_size polls allocated */
|
/* this will always leave at least chunk_size polls allocated */
|
||||||
if (ctx->polls_allocated - ctx->polls_used > ctx->chunk_size) {
|
if (ctx->polls_allocated - ctx->polls_used > ctx->chunk_size) {
|
||||||
ssh_poll_ctx_resize(ctx, ctx->polls_allocated - ctx->chunk_size);
|
ssh_poll_ctx_resize(ctx, ctx->polls_allocated - ctx->chunk_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -690,7 +702,7 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout)
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
size_t i, used;
|
size_t i, used;
|
||||||
ssh_poll_handle p;
|
ssh_poll_handle p = NULL;
|
||||||
socket_t fd;
|
socket_t fd;
|
||||||
int revents;
|
int revents;
|
||||||
struct ssh_timestamp ts;
|
struct ssh_timestamp ts;
|
||||||
@@ -745,7 +757,8 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout)
|
|||||||
if (ret == -2) {
|
if (ret == -2) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* the poll was removed, reload the used counter and start again */
|
/* the poll was removed, reload the used counter and start again
|
||||||
|
*/
|
||||||
used = ctx->polls_used;
|
used = ctx->polls_used;
|
||||||
i = 0;
|
i = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -771,8 +784,9 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout)
|
|||||||
*/
|
*/
|
||||||
ssh_poll_ctx ssh_poll_get_default_ctx(ssh_session session)
|
ssh_poll_ctx ssh_poll_get_default_ctx(ssh_session session)
|
||||||
{
|
{
|
||||||
if(session->default_poll_ctx != NULL)
|
if (session->default_poll_ctx != NULL) {
|
||||||
return session->default_poll_ctx;
|
return session->default_poll_ctx;
|
||||||
|
}
|
||||||
/* 2 is enough for the default one */
|
/* 2 is enough for the default one */
|
||||||
session->default_poll_ctx = ssh_poll_ctx_new(2);
|
session->default_poll_ctx = ssh_poll_ctx_new(2);
|
||||||
return session->default_poll_ctx;
|
return session->default_poll_ctx;
|
||||||
@@ -782,7 +796,7 @@ ssh_poll_ctx ssh_poll_get_default_ctx(ssh_session session)
|
|||||||
|
|
||||||
struct ssh_event_fd_wrapper {
|
struct ssh_event_fd_wrapper {
|
||||||
ssh_event_callback cb;
|
ssh_event_callback cb;
|
||||||
void * userdata;
|
void *userdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ssh_event_struct {
|
struct ssh_event_struct {
|
||||||
@@ -811,14 +825,14 @@ ssh_event ssh_event_new(void)
|
|||||||
ZERO_STRUCTP(event);
|
ZERO_STRUCTP(event);
|
||||||
|
|
||||||
event->ctx = ssh_poll_ctx_new(2);
|
event->ctx = ssh_poll_ctx_new(2);
|
||||||
if(event->ctx == NULL) {
|
if (event->ctx == NULL) {
|
||||||
free(event);
|
free(event);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_SERVER
|
#ifdef WITH_SERVER
|
||||||
event->sessions = ssh_list_new();
|
event->sessions = ssh_list_new();
|
||||||
if(event->sessions == NULL) {
|
if (event->sessions == NULL) {
|
||||||
ssh_poll_ctx_free(event->ctx);
|
ssh_poll_ctx_free(event->ctx);
|
||||||
free(event);
|
free(event);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -828,9 +842,10 @@ ssh_event ssh_event_new(void)
|
|||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int ssh_event_fd_wrapper_callback(ssh_poll_handle p,
|
||||||
ssh_event_fd_wrapper_callback(ssh_poll_handle p, socket_t fd, int revents,
|
socket_t fd,
|
||||||
void *userdata)
|
int revents,
|
||||||
|
void *userdata)
|
||||||
{
|
{
|
||||||
struct ssh_event_fd_wrapper *pw = (struct ssh_event_fd_wrapper *)userdata;
|
struct ssh_event_fd_wrapper *pw = (struct ssh_event_fd_wrapper *)userdata;
|
||||||
|
|
||||||
@@ -858,19 +873,22 @@ ssh_event_fd_wrapper_callback(ssh_poll_handle p, socket_t fd, int revents,
|
|||||||
* @returns SSH_OK on success
|
* @returns SSH_OK on success
|
||||||
* SSH_ERROR on failure
|
* SSH_ERROR on failure
|
||||||
*/
|
*/
|
||||||
int
|
int ssh_event_add_fd(ssh_event event,
|
||||||
ssh_event_add_fd(ssh_event event, socket_t fd, short events,
|
socket_t fd,
|
||||||
ssh_event_callback cb, void *userdata)
|
short events,
|
||||||
|
ssh_event_callback cb,
|
||||||
|
void *userdata)
|
||||||
{
|
{
|
||||||
ssh_poll_handle p;
|
ssh_poll_handle p = NULL;
|
||||||
struct ssh_event_fd_wrapper *pw = NULL;
|
struct ssh_event_fd_wrapper *pw = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if(event == NULL || event->ctx == NULL || cb == NULL
|
if (event == NULL || event->ctx == NULL || cb == NULL ||
|
||||||
|| fd == SSH_INVALID_SOCKET) {
|
fd == SSH_INVALID_SOCKET) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
pw = malloc(sizeof(struct ssh_event_fd_wrapper));
|
pw = malloc(sizeof(struct ssh_event_fd_wrapper));
|
||||||
if(pw == NULL) {
|
if (pw == NULL) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -879,12 +897,13 @@ ssh_event_add_fd(ssh_event event, socket_t fd, short events,
|
|||||||
|
|
||||||
/* pw is freed by ssh_event_remove_fd */
|
/* pw is freed by ssh_event_remove_fd */
|
||||||
p = ssh_poll_new(fd, events, ssh_event_fd_wrapper_callback, pw);
|
p = ssh_poll_new(fd, events, ssh_event_fd_wrapper_callback, pw);
|
||||||
if(p == NULL) {
|
if (p == NULL) {
|
||||||
free(pw);
|
free(pw);
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ssh_poll_ctx_add(event->ctx, p) < 0) {
|
rc = ssh_poll_ctx_add(event->ctx, p);
|
||||||
|
if (rc < 0) {
|
||||||
free(pw);
|
free(pw);
|
||||||
ssh_poll_free(p);
|
ssh_poll_free(p);
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
@@ -916,7 +935,7 @@ int ssh_event_add_poll(ssh_event event, ssh_poll_handle p)
|
|||||||
*/
|
*/
|
||||||
void ssh_event_remove_poll(ssh_event event, ssh_poll_handle p)
|
void ssh_event_remove_poll(ssh_event event, ssh_poll_handle p)
|
||||||
{
|
{
|
||||||
ssh_poll_ctx_remove(event->ctx,p);
|
ssh_poll_ctx_remove(event->ctx, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -931,15 +950,16 @@ void ssh_event_remove_poll(ssh_event event, ssh_poll_handle p)
|
|||||||
*/
|
*/
|
||||||
int ssh_event_add_session(ssh_event event, ssh_session session)
|
int ssh_event_add_session(ssh_event event, ssh_session session)
|
||||||
{
|
{
|
||||||
ssh_poll_handle p;
|
ssh_poll_handle p = NULL;
|
||||||
#ifdef WITH_SERVER
|
#ifdef WITH_SERVER
|
||||||
struct ssh_iterator *iterator = NULL;
|
struct ssh_iterator *iterator = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
int rc;
|
||||||
|
|
||||||
if(event == NULL || event->ctx == NULL || session == NULL) {
|
if (event == NULL || event->ctx == NULL || session == NULL) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
if(session->default_poll_ctx == NULL) {
|
if (session->default_poll_ctx == NULL) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
while (session->default_poll_ctx->polls_used > 0) {
|
while (session->default_poll_ctx->polls_used > 0) {
|
||||||
@@ -949,7 +969,10 @@ int ssh_event_add_session(ssh_event event, ssh_session session)
|
|||||||
* session->default_poll_ctx->polls_used
|
* session->default_poll_ctx->polls_used
|
||||||
*/
|
*/
|
||||||
ssh_poll_ctx_remove(session->default_poll_ctx, p);
|
ssh_poll_ctx_remove(session->default_poll_ctx, p);
|
||||||
ssh_poll_ctx_add(event->ctx, p);
|
rc = ssh_poll_ctx_add(event->ctx, p);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
/* associate the pollhandler with a session so we can put it back
|
/* associate the pollhandler with a session so we can put it back
|
||||||
* at ssh_event_free()
|
* at ssh_event_free()
|
||||||
*/
|
*/
|
||||||
@@ -957,14 +980,14 @@ int ssh_event_add_session(ssh_event event, ssh_session session)
|
|||||||
}
|
}
|
||||||
#ifdef WITH_SERVER
|
#ifdef WITH_SERVER
|
||||||
iterator = ssh_list_get_iterator(event->sessions);
|
iterator = ssh_list_get_iterator(event->sessions);
|
||||||
while(iterator != NULL) {
|
while (iterator != NULL) {
|
||||||
if((ssh_session)iterator->data == session) {
|
if ((ssh_session)iterator->data == session) {
|
||||||
/* allow only one instance of this session */
|
/* allow only one instance of this session */
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
iterator = iterator->next;
|
iterator = iterator->next;
|
||||||
}
|
}
|
||||||
if(ssh_list_append(event->sessions, session) == SSH_ERROR) {
|
if (ssh_list_append(event->sessions, session) == SSH_ERROR) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1032,17 +1055,17 @@ int ssh_event_remove_fd(ssh_event event, socket_t fd)
|
|||||||
register size_t i, used;
|
register size_t i, used;
|
||||||
int rc = SSH_ERROR;
|
int rc = SSH_ERROR;
|
||||||
|
|
||||||
if(event == NULL || event->ctx == NULL) {
|
if (event == NULL || event->ctx == NULL) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
used = event->ctx->polls_used;
|
used = event->ctx->polls_used;
|
||||||
for (i = 0; i < used; i++) {
|
for (i = 0; i < used; i++) {
|
||||||
if(fd == event->ctx->pollfds[i].fd) {
|
if (fd == event->ctx->pollfds[i].fd) {
|
||||||
ssh_poll_handle p = event->ctx->pollptrs[i];
|
ssh_poll_handle p = event->ctx->pollptrs[i];
|
||||||
if (p->session != NULL){
|
if (p->session != NULL) {
|
||||||
/* we cannot free that handle, it's owned by its session */
|
/* we cannot free that handle, it's owned by its session */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (p->cb == ssh_event_fd_wrapper_callback) {
|
if (p->cb == ssh_event_fd_wrapper_callback) {
|
||||||
struct ssh_event_fd_wrapper *pw = p->cb_data;
|
struct ssh_event_fd_wrapper *pw = p->cb_data;
|
||||||
@@ -1076,7 +1099,7 @@ int ssh_event_remove_fd(ssh_event event, socket_t fd)
|
|||||||
*/
|
*/
|
||||||
int ssh_event_remove_session(ssh_event event, ssh_session session)
|
int ssh_event_remove_session(ssh_event event, ssh_session session)
|
||||||
{
|
{
|
||||||
ssh_poll_handle p;
|
ssh_poll_handle p = NULL;
|
||||||
register size_t i, used;
|
register size_t i, used;
|
||||||
int rc = SSH_ERROR;
|
int rc = SSH_ERROR;
|
||||||
#ifdef WITH_SERVER
|
#ifdef WITH_SERVER
|
||||||
@@ -1097,7 +1120,10 @@ int ssh_event_remove_session(ssh_event event, ssh_session session)
|
|||||||
*/
|
*/
|
||||||
ssh_poll_ctx_remove(event->ctx, p);
|
ssh_poll_ctx_remove(event->ctx, p);
|
||||||
p->session = NULL;
|
p->session = NULL;
|
||||||
ssh_poll_ctx_add(session->default_poll_ctx, p);
|
rc = ssh_poll_ctx_add(session->default_poll_ctx, p);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
rc = SSH_OK;
|
rc = SSH_OK;
|
||||||
/*
|
/*
|
||||||
* Restart the loop!
|
* Restart the loop!
|
||||||
@@ -1105,7 +1131,6 @@ int ssh_event_remove_session(ssh_event event, ssh_session session)
|
|||||||
*/
|
*/
|
||||||
used = event->ctx->polls_used;
|
used = event->ctx->polls_used;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef WITH_SERVER
|
#ifdef WITH_SERVER
|
||||||
@@ -1146,7 +1171,7 @@ int ssh_event_remove_connector(ssh_event event, ssh_connector connector)
|
|||||||
void ssh_event_free(ssh_event event)
|
void ssh_event_free(ssh_event event)
|
||||||
{
|
{
|
||||||
size_t used, i;
|
size_t used, i;
|
||||||
ssh_poll_handle p;
|
ssh_poll_handle p = NULL;
|
||||||
|
|
||||||
if (event == NULL) {
|
if (event == NULL) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -744,7 +744,10 @@ int ssh_handle_packets(ssh_session session, int timeout)
|
|||||||
ssh_set_error_oom(session);
|
ssh_set_error_oom(session);
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
ssh_poll_ctx_add(ctx, spoll);
|
rc = ssh_poll_ctx_add(ctx, spoll);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeout == SSH_TIMEOUT_USER) {
|
if (timeout == SSH_TIMEOUT_USER) {
|
||||||
|
|||||||
42
src/socket.c
42
src/socket.c
@@ -202,7 +202,10 @@ void ssh_socket_reset(ssh_socket s)
|
|||||||
s->read_wontblock = 0;
|
s->read_wontblock = 0;
|
||||||
s->write_wontblock = 0;
|
s->write_wontblock = 0;
|
||||||
s->data_except = 0;
|
s->data_except = 0;
|
||||||
s->poll_handle = NULL;
|
if (s->poll_handle != NULL) {
|
||||||
|
ssh_poll_free(s->poll_handle);
|
||||||
|
s->poll_handle = NULL;
|
||||||
|
}
|
||||||
s->state=SSH_SOCKET_NONE;
|
s->state=SSH_SOCKET_NONE;
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
s->proxy_pid = 0;
|
s->proxy_pid = 0;
|
||||||
@@ -440,7 +443,7 @@ int ssh_socket_unix(ssh_socket s, const char *path)
|
|||||||
ssh_set_error(s->session, SSH_FATAL,
|
ssh_set_error(s->session, SSH_FATAL,
|
||||||
"Error from socket(AF_UNIX, SOCK_STREAM, 0): %s",
|
"Error from socket(AF_UNIX, SOCK_STREAM, 0): %s",
|
||||||
ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
|
ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
|
||||||
return -1;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
@@ -449,7 +452,7 @@ int ssh_socket_unix(ssh_socket s, const char *path)
|
|||||||
"Error from fcntl(fd, F_SETFD, 1): %s",
|
"Error from fcntl(fd, F_SETFD, 1): %s",
|
||||||
ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
|
ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
|
||||||
CLOSE_SOCKET(fd);
|
CLOSE_SOCKET(fd);
|
||||||
return -1;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -458,10 +461,9 @@ int ssh_socket_unix(ssh_socket s, const char *path)
|
|||||||
path,
|
path,
|
||||||
ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
|
ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
|
||||||
CLOSE_SOCKET(fd);
|
CLOSE_SOCKET(fd);
|
||||||
return -1;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
ssh_socket_set_fd(s,fd);
|
return ssh_socket_set_fd(s, fd);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
@@ -519,7 +521,7 @@ void ssh_socket_close(ssh_socket s)
|
|||||||
* @warning this function updates both the input and output
|
* @warning this function updates both the input and output
|
||||||
* file descriptors
|
* file descriptors
|
||||||
*/
|
*/
|
||||||
void ssh_socket_set_fd(ssh_socket s, socket_t fd)
|
int ssh_socket_set_fd(ssh_socket s, socket_t fd)
|
||||||
{
|
{
|
||||||
ssh_poll_handle h = NULL;
|
ssh_poll_handle h = NULL;
|
||||||
|
|
||||||
@@ -531,7 +533,7 @@ void ssh_socket_set_fd(ssh_socket s, socket_t fd)
|
|||||||
s->state = SSH_SOCKET_CONNECTING;
|
s->state = SSH_SOCKET_CONNECTING;
|
||||||
h = ssh_socket_get_poll_handle(s);
|
h = ssh_socket_get_poll_handle(s);
|
||||||
if (h == NULL) {
|
if (h == NULL) {
|
||||||
return;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* POLLOUT is the event to wait for in a nonblocking connect */
|
/* POLLOUT is the event to wait for in a nonblocking connect */
|
||||||
@@ -540,6 +542,7 @@ void ssh_socket_set_fd(ssh_socket s, socket_t fd)
|
|||||||
ssh_poll_add_events(h, POLLWRNORM);
|
ssh_poll_add_events(h, POLLWRNORM);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
@@ -889,9 +892,7 @@ int ssh_socket_connect(ssh_socket s,
|
|||||||
if (fd == SSH_INVALID_SOCKET) {
|
if (fd == SSH_INVALID_SOCKET) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
ssh_socket_set_fd(s,fd);
|
return ssh_socket_set_fd(s, fd);
|
||||||
|
|
||||||
return SSH_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_EXEC
|
#ifdef WITH_EXEC
|
||||||
@@ -985,8 +986,16 @@ ssh_socket_connect_proxycommand(ssh_socket s, const char *command)
|
|||||||
}
|
}
|
||||||
s->proxy_pid = pid;
|
s->proxy_pid = pid;
|
||||||
close(pair[0]);
|
close(pair[0]);
|
||||||
SSH_LOG(SSH_LOG_DEBUG, "ProxyCommand connection pipe: [%d,%d]",pair[0],pair[1]);
|
SSH_LOG(SSH_LOG_DEBUG,
|
||||||
ssh_socket_set_fd(s, pair[1]);
|
"ProxyCommand connection pipe: [%d,%d]",
|
||||||
|
pair[0],
|
||||||
|
pair[1]);
|
||||||
|
|
||||||
|
rc = ssh_socket_set_fd(s, pair[1]);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
s->fd_is_socket = 0;
|
s->fd_is_socket = 0;
|
||||||
h = ssh_socket_get_poll_handle(s);
|
h = ssh_socket_get_poll_handle(s);
|
||||||
if (h == NULL) {
|
if (h == NULL) {
|
||||||
@@ -1276,7 +1285,12 @@ ssh_socket_connect_proxyjump(ssh_socket s)
|
|||||||
"ProxyJump connection pipe: [%d,%d]",
|
"ProxyJump connection pipe: [%d,%d]",
|
||||||
pair[0],
|
pair[0],
|
||||||
pair[1]);
|
pair[1]);
|
||||||
ssh_socket_set_fd(s, pair[1]);
|
|
||||||
|
rc = ssh_socket_set_fd(s, pair[1]);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
s->fd_is_socket = 1;
|
s->fd_is_socket = 1;
|
||||||
h = ssh_socket_get_poll_handle(s);
|
h = ssh_socket_get_poll_handle(s);
|
||||||
if (h == NULL) {
|
if (h == NULL) {
|
||||||
|
|||||||
Reference in New Issue
Block a user