mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 12:20:42 +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);
|
||||
void ssh_socket_reset(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);
|
||||
void ssh_socket_set_connected(ssh_socket s, struct ssh_poll_handle_struct *p);
|
||||
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;
|
||||
}
|
||||
|
||||
ssh_socket_set_fd(session->agent->sock, fd);
|
||||
return SSH_OK;
|
||||
return ssh_socket_set_fd(session->agent->sock, fd);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -505,7 +505,10 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd)
|
||||
ssh_set_error_oom(sshbind);
|
||||
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);
|
||||
if (handle == NULL) {
|
||||
ssh_set_error_oom(sshbind);
|
||||
|
||||
@@ -602,8 +602,7 @@ int ssh_connect(ssh_session session)
|
||||
|
||||
if (session->opts.fd != SSH_INVALID_SOCKET) {
|
||||
session->session_state = SSH_SESSION_STATE_SOCKET_CONNECTED;
|
||||
ssh_socket_set_fd(session->socket, session->opts.fd);
|
||||
ret = SSH_OK;
|
||||
ret = ssh_socket_set_fd(session->socket, session->opts.fd);
|
||||
#ifndef _WIN32
|
||||
#ifdef HAVE_PTHREAD
|
||||
} 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.
|
||||
*/
|
||||
tmp = ssh_path_expand_escape(session, id);
|
||||
free(id);
|
||||
if (tmp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
free(id);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
if (rc != SSH_OK) {
|
||||
free(tmp);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -2010,13 +2011,14 @@ int ssh_options_apply(ssh_session session)
|
||||
char *id = tmp;
|
||||
|
||||
tmp = ssh_path_expand_escape(session, id);
|
||||
free(id);
|
||||
if (tmp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
free(id);
|
||||
|
||||
rc = ssh_list_append(session->opts.certificate, tmp);
|
||||
if (rc != SSH_OK) {
|
||||
free(tmp);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
243
src/poll.c
243
src/poll.c
@@ -61,24 +61,24 @@
|
||||
*/
|
||||
|
||||
struct ssh_poll_handle_struct {
|
||||
ssh_poll_ctx ctx;
|
||||
ssh_session session;
|
||||
union {
|
||||
socket_t fd;
|
||||
size_t idx;
|
||||
} x;
|
||||
short events;
|
||||
uint32_t lock_cnt;
|
||||
ssh_poll_callback cb;
|
||||
void *cb_data;
|
||||
ssh_poll_ctx ctx;
|
||||
ssh_session session;
|
||||
union {
|
||||
socket_t fd;
|
||||
size_t idx;
|
||||
} x;
|
||||
short events;
|
||||
uint32_t lock_cnt;
|
||||
ssh_poll_callback cb;
|
||||
void *cb_data;
|
||||
};
|
||||
|
||||
struct ssh_poll_ctx_struct {
|
||||
ssh_poll_handle *pollptrs;
|
||||
ssh_pollfd_t *pollfds;
|
||||
size_t polls_allocated;
|
||||
size_t polls_used;
|
||||
size_t chunk_size;
|
||||
ssh_poll_handle *pollptrs;
|
||||
ssh_pollfd_t *pollfds;
|
||||
size_t polls_allocated;
|
||||
size_t polls_used;
|
||||
size_t chunk_size;
|
||||
};
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
@@ -96,7 +96,7 @@ void ssh_poll_cleanup(void)
|
||||
|
||||
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 */
|
||||
@@ -249,14 +249,15 @@ static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout)
|
||||
}
|
||||
#endif
|
||||
|
||||
// we use the readfds to get POLLHUP and POLLERR, which are provided even when not requested
|
||||
FD_SET (fds[i].fd, &readfds);
|
||||
// we use the readfds to get POLLHUP and POLLERR, which are provided
|
||||
// even when not requested
|
||||
FD_SET(fds[i].fd, &readfds);
|
||||
|
||||
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)) {
|
||||
FD_SET (fds[i].fd, &exceptfds);
|
||||
FD_SET(fds[i].fd, &exceptfds);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (FD_ISSET(fds[i].fd, &readfds)) {
|
||||
fds[i].revents = bsd_socket_compute_revents(fds[i].fd,
|
||||
fds[i].events);
|
||||
fds[i].revents =
|
||||
bsd_socket_compute_revents(fds[i].fd, fds[i].events);
|
||||
}
|
||||
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)) {
|
||||
@@ -319,22 +321,26 @@ static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout)
|
||||
return rc;
|
||||
}
|
||||
|
||||
void ssh_poll_init(void) {
|
||||
void ssh_poll_init(void)
|
||||
{
|
||||
ssh_poll_emu = bsd_poll;
|
||||
}
|
||||
|
||||
void ssh_poll_cleanup(void) {
|
||||
void ssh_poll_cleanup(void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
#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] 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_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));
|
||||
if (p == NULL) {
|
||||
@@ -370,7 +376,6 @@ ssh_poll_new(socket_t fd, short events, ssh_poll_callback cb, void *userdata)
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
* to an associated poll context.
|
||||
* @brief Set the file descriptor of a poll object. The FD will also be
|
||||
* propagated to an associated poll context.
|
||||
*
|
||||
* @param p Pointer to an already allocated poll object.
|
||||
* @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
|
||||
* 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) {
|
||||
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)
|
||||
{
|
||||
if (ctx->polls_allocated > 0) {
|
||||
while (ctx->polls_used > 0){
|
||||
while (ctx->polls_used > 0) {
|
||||
ssh_poll_handle p = ctx->pollptrs[0];
|
||||
/*
|
||||
* 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);
|
||||
if (pollptrs == NULL) {
|
||||
return -1;
|
||||
/* Fail, but keep the old value to be freed later */
|
||||
return SSH_ERROR;
|
||||
}
|
||||
ctx->pollptrs = pollptrs;
|
||||
|
||||
pollfds = realloc(ctx->pollfds, sizeof(ssh_pollfd_t) * new_size);
|
||||
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,
|
||||
sizeof(ssh_poll_handle) * ctx->polls_allocated);
|
||||
if (pollptrs == NULL) {
|
||||
return -1;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
ctx->pollptrs = pollptrs;
|
||||
return -1;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
ctx->pollfds = pollfds;
|
||||
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)
|
||||
{
|
||||
socket_t fd;
|
||||
socket_t fd;
|
||||
|
||||
if (p->ctx != NULL) {
|
||||
/* already attached to a context */
|
||||
return -1;
|
||||
}
|
||||
if (p->ctx != NULL) {
|
||||
/* already attached to a context */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ctx->polls_used == ctx->polls_allocated &&
|
||||
ssh_poll_ctx_resize(ctx, ctx->polls_allocated + ctx->chunk_size) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (ctx->polls_used == ctx->polls_allocated &&
|
||||
ssh_poll_ctx_resize(ctx, ctx->polls_allocated + ctx->chunk_size) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = p->x.fd;
|
||||
p->x.idx = ctx->polls_used++;
|
||||
ctx->pollptrs[p->x.idx] = p;
|
||||
ctx->pollfds[p->x.idx].fd = fd;
|
||||
ctx->pollfds[p->x.idx].events = p->events;
|
||||
ctx->pollfds[p->x.idx].revents = 0;
|
||||
p->ctx = ctx;
|
||||
fd = p->x.fd;
|
||||
p->x.idx = ctx->polls_used++;
|
||||
ctx->pollptrs[p->x.idx] = p;
|
||||
ctx->pollfds[p->x.idx].fd = fd;
|
||||
ctx->pollfds[p->x.idx].events = p->events;
|
||||
ctx->pollfds[p->x.idx].revents = 0;
|
||||
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
|
||||
*/
|
||||
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;
|
||||
int ret;
|
||||
|
||||
p = ssh_socket_get_poll_handle(s);
|
||||
if (p == NULL) {
|
||||
return -1;
|
||||
}
|
||||
ret = ssh_poll_ctx_add(ctx,p);
|
||||
return ret;
|
||||
return ssh_poll_ctx_add(ctx, p);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
size_t i;
|
||||
size_t i;
|
||||
|
||||
i = p->x.idx;
|
||||
p->x.fd = ctx->pollfds[i].fd;
|
||||
p->ctx = NULL;
|
||||
i = p->x.idx;
|
||||
p->x.fd = ctx->pollfds[i].fd;
|
||||
p->ctx = NULL;
|
||||
|
||||
ctx->polls_used--;
|
||||
ctx->polls_used--;
|
||||
|
||||
/* fill the empty poll slot with the last one */
|
||||
if (ctx->polls_used > 0 && ctx->polls_used != i) {
|
||||
ctx->pollfds[i] = ctx->pollfds[ctx->polls_used];
|
||||
ctx->pollptrs[i] = ctx->pollptrs[ctx->polls_used];
|
||||
ctx->pollptrs[i]->x.idx = i;
|
||||
}
|
||||
/* fill the empty poll slot with the last one */
|
||||
if (ctx->polls_used > 0 && ctx->polls_used != i) {
|
||||
ctx->pollfds[i] = ctx->pollfds[ctx->polls_used];
|
||||
ctx->pollptrs[i] = ctx->pollptrs[ctx->polls_used];
|
||||
ctx->pollptrs[i]->x.idx = i;
|
||||
}
|
||||
|
||||
/* this will always leave at least chunk_size polls allocated */
|
||||
if (ctx->polls_allocated - ctx->polls_used > ctx->chunk_size) {
|
||||
ssh_poll_ctx_resize(ctx, ctx->polls_allocated - ctx->chunk_size);
|
||||
}
|
||||
/* this will always leave at least chunk_size polls allocated */
|
||||
if (ctx->polls_allocated - ctx->polls_used > 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;
|
||||
size_t i, used;
|
||||
ssh_poll_handle p;
|
||||
ssh_poll_handle p = NULL;
|
||||
socket_t fd;
|
||||
int revents;
|
||||
struct ssh_timestamp ts;
|
||||
@@ -745,7 +757,8 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout)
|
||||
if (ret == -2) {
|
||||
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;
|
||||
i = 0;
|
||||
} 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)
|
||||
{
|
||||
if(session->default_poll_ctx != NULL)
|
||||
if (session->default_poll_ctx != NULL) {
|
||||
return session->default_poll_ctx;
|
||||
}
|
||||
/* 2 is enough for the default one */
|
||||
session->default_poll_ctx = ssh_poll_ctx_new(2);
|
||||
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 {
|
||||
ssh_event_callback cb;
|
||||
void * userdata;
|
||||
void *userdata;
|
||||
};
|
||||
|
||||
struct ssh_event_struct {
|
||||
@@ -811,14 +825,14 @@ ssh_event ssh_event_new(void)
|
||||
ZERO_STRUCTP(event);
|
||||
|
||||
event->ctx = ssh_poll_ctx_new(2);
|
||||
if(event->ctx == NULL) {
|
||||
if (event->ctx == NULL) {
|
||||
free(event);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
event->sessions = ssh_list_new();
|
||||
if(event->sessions == NULL) {
|
||||
if (event->sessions == NULL) {
|
||||
ssh_poll_ctx_free(event->ctx);
|
||||
free(event);
|
||||
return NULL;
|
||||
@@ -828,9 +842,10 @@ ssh_event ssh_event_new(void)
|
||||
return event;
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_event_fd_wrapper_callback(ssh_poll_handle p, socket_t fd, int revents,
|
||||
void *userdata)
|
||||
static int ssh_event_fd_wrapper_callback(ssh_poll_handle p,
|
||||
socket_t fd,
|
||||
int revents,
|
||||
void *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
|
||||
* SSH_ERROR on failure
|
||||
*/
|
||||
int
|
||||
ssh_event_add_fd(ssh_event event, socket_t fd, short events,
|
||||
ssh_event_callback cb, void *userdata)
|
||||
int ssh_event_add_fd(ssh_event event,
|
||||
socket_t fd,
|
||||
short events,
|
||||
ssh_event_callback cb,
|
||||
void *userdata)
|
||||
{
|
||||
ssh_poll_handle p;
|
||||
ssh_poll_handle p = NULL;
|
||||
struct ssh_event_fd_wrapper *pw = NULL;
|
||||
int rc;
|
||||
|
||||
if(event == NULL || event->ctx == NULL || cb == NULL
|
||||
|| fd == SSH_INVALID_SOCKET) {
|
||||
if (event == NULL || event->ctx == NULL || cb == NULL ||
|
||||
fd == SSH_INVALID_SOCKET) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
pw = malloc(sizeof(struct ssh_event_fd_wrapper));
|
||||
if(pw == NULL) {
|
||||
if (pw == NULL) {
|
||||
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 */
|
||||
p = ssh_poll_new(fd, events, ssh_event_fd_wrapper_callback, pw);
|
||||
if(p == NULL) {
|
||||
if (p == NULL) {
|
||||
free(pw);
|
||||
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);
|
||||
ssh_poll_free(p);
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
ssh_poll_handle p;
|
||||
ssh_poll_handle p = NULL;
|
||||
#ifdef WITH_SERVER
|
||||
struct ssh_iterator *iterator = NULL;
|
||||
#endif
|
||||
int rc;
|
||||
|
||||
if(event == NULL || event->ctx == NULL || session == NULL) {
|
||||
if (event == NULL || event->ctx == NULL || session == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if(session->default_poll_ctx == NULL) {
|
||||
if (session->default_poll_ctx == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
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
|
||||
*/
|
||||
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
|
||||
* at ssh_event_free()
|
||||
*/
|
||||
@@ -957,14 +980,14 @@ int ssh_event_add_session(ssh_event event, ssh_session session)
|
||||
}
|
||||
#ifdef WITH_SERVER
|
||||
iterator = ssh_list_get_iterator(event->sessions);
|
||||
while(iterator != NULL) {
|
||||
if((ssh_session)iterator->data == session) {
|
||||
while (iterator != NULL) {
|
||||
if ((ssh_session)iterator->data == session) {
|
||||
/* allow only one instance of this session */
|
||||
return SSH_OK;
|
||||
}
|
||||
iterator = iterator->next;
|
||||
}
|
||||
if(ssh_list_append(event->sessions, session) == SSH_ERROR) {
|
||||
if (ssh_list_append(event->sessions, session) == SSH_ERROR) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
#endif
|
||||
@@ -1032,17 +1055,17 @@ int ssh_event_remove_fd(ssh_event event, socket_t fd)
|
||||
register size_t i, used;
|
||||
int rc = SSH_ERROR;
|
||||
|
||||
if(event == NULL || event->ctx == NULL) {
|
||||
if (event == NULL || event->ctx == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
used = event->ctx->polls_used;
|
||||
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];
|
||||
if (p->session != NULL){
|
||||
/* we cannot free that handle, it's owned by its session */
|
||||
continue;
|
||||
if (p->session != NULL) {
|
||||
/* we cannot free that handle, it's owned by its session */
|
||||
continue;
|
||||
}
|
||||
if (p->cb == ssh_event_fd_wrapper_callback) {
|
||||
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)
|
||||
{
|
||||
ssh_poll_handle p;
|
||||
ssh_poll_handle p = NULL;
|
||||
register size_t i, used;
|
||||
int rc = SSH_ERROR;
|
||||
#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);
|
||||
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;
|
||||
/*
|
||||
* Restart the loop!
|
||||
@@ -1105,7 +1131,6 @@ int ssh_event_remove_session(ssh_event event, ssh_session session)
|
||||
*/
|
||||
used = event->ctx->polls_used;
|
||||
i = 0;
|
||||
|
||||
}
|
||||
}
|
||||
#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)
|
||||
{
|
||||
size_t used, i;
|
||||
ssh_poll_handle p;
|
||||
ssh_poll_handle p = NULL;
|
||||
|
||||
if (event == NULL) {
|
||||
return;
|
||||
|
||||
@@ -744,7 +744,10 @@ int ssh_handle_packets(ssh_session session, int timeout)
|
||||
ssh_set_error_oom(session);
|
||||
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) {
|
||||
|
||||
42
src/socket.c
42
src/socket.c
@@ -202,7 +202,10 @@ void ssh_socket_reset(ssh_socket s)
|
||||
s->read_wontblock = 0;
|
||||
s->write_wontblock = 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;
|
||||
#ifndef _WIN32
|
||||
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,
|
||||
"Error from socket(AF_UNIX, SOCK_STREAM, 0): %s",
|
||||
ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
|
||||
return -1;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
@@ -449,7 +452,7 @@ int ssh_socket_unix(ssh_socket s, const char *path)
|
||||
"Error from fcntl(fd, F_SETFD, 1): %s",
|
||||
ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
|
||||
CLOSE_SOCKET(fd);
|
||||
return -1;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -458,10 +461,9 @@ int ssh_socket_unix(ssh_socket s, const char *path)
|
||||
path,
|
||||
ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
|
||||
CLOSE_SOCKET(fd);
|
||||
return -1;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
ssh_socket_set_fd(s,fd);
|
||||
return 0;
|
||||
return ssh_socket_set_fd(s, fd);
|
||||
}
|
||||
|
||||
/** \internal
|
||||
@@ -519,7 +521,7 @@ void ssh_socket_close(ssh_socket s)
|
||||
* @warning this function updates both the input and output
|
||||
* 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;
|
||||
|
||||
@@ -531,7 +533,7 @@ void ssh_socket_set_fd(ssh_socket s, socket_t fd)
|
||||
s->state = SSH_SOCKET_CONNECTING;
|
||||
h = ssh_socket_get_poll_handle(s);
|
||||
if (h == NULL) {
|
||||
return;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
#endif
|
||||
}
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
@@ -889,9 +892,7 @@ int ssh_socket_connect(ssh_socket s,
|
||||
if (fd == SSH_INVALID_SOCKET) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
ssh_socket_set_fd(s,fd);
|
||||
|
||||
return SSH_OK;
|
||||
return ssh_socket_set_fd(s, fd);
|
||||
}
|
||||
|
||||
#ifdef WITH_EXEC
|
||||
@@ -985,8 +986,16 @@ ssh_socket_connect_proxycommand(ssh_socket s, const char *command)
|
||||
}
|
||||
s->proxy_pid = pid;
|
||||
close(pair[0]);
|
||||
SSH_LOG(SSH_LOG_DEBUG, "ProxyCommand connection pipe: [%d,%d]",pair[0],pair[1]);
|
||||
ssh_socket_set_fd(s, pair[1]);
|
||||
SSH_LOG(SSH_LOG_DEBUG,
|
||||
"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;
|
||||
h = ssh_socket_get_poll_handle(s);
|
||||
if (h == NULL) {
|
||||
@@ -1276,7 +1285,12 @@ ssh_socket_connect_proxyjump(ssh_socket s)
|
||||
"ProxyJump connection pipe: [%d,%d]",
|
||||
pair[0],
|
||||
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;
|
||||
h = ssh_socket_get_poll_handle(s);
|
||||
if (h == NULL) {
|
||||
|
||||
Reference in New Issue
Block a user