socket: Fix style of ssh_socket_pollcallback
Signed-off-by: Alan Dunn <amdunn@gmail.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Этот коммит содержится в:
родитель
47bd0b6d1f
Коммит
d5aeebe323
219
src/socket.c
219
src/socket.c
@ -204,7 +204,7 @@ void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SSH poll callback. This callback will be used when an event
|
* @brief SSH poll callback. This callback will be used when an event
|
||||||
* caught on the socket.
|
* caught on the socket.
|
||||||
*
|
*
|
||||||
* @param p Poll object this callback belongs to.
|
* @param p Poll object this callback belongs to.
|
||||||
@ -216,128 +216,131 @@ void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks){
|
|||||||
* @return 0 on success, < 0 when the poll object has been removed
|
* @return 0 on success, < 0 when the poll object has been removed
|
||||||
* from its poll context.
|
* from its poll context.
|
||||||
*/
|
*/
|
||||||
int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, int revents, void *v_s){
|
int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd,
|
||||||
ssh_socket s=(ssh_socket )v_s;
|
int revents, void *v_s) {
|
||||||
char buffer[MAX_BUF_SIZE];
|
ssh_socket s = (ssh_socket)v_s;
|
||||||
int r;
|
char buffer[MAX_BUF_SIZE];
|
||||||
int err=0;
|
int r;
|
||||||
socklen_t errlen=sizeof(err);
|
int err = 0;
|
||||||
/* Do not do anything if this socket was already closed */
|
socklen_t errlen = sizeof(err);
|
||||||
if(!ssh_socket_is_open(s)){
|
/* Do not do anything if this socket was already closed */
|
||||||
return -1;
|
if (!ssh_socket_is_open(s)) {
|
||||||
}
|
return -1;
|
||||||
if(revents & POLLERR || revents & POLLHUP){
|
}
|
||||||
/* Check if we are in a connecting state */
|
if (revents & POLLERR || revents & POLLHUP) {
|
||||||
if(s->state==SSH_SOCKET_CONNECTING){
|
/* Check if we are in a connecting state */
|
||||||
s->state=SSH_SOCKET_ERROR;
|
if (s->state == SSH_SOCKET_CONNECTING) {
|
||||||
r = getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&err, &errlen);
|
s->state = SSH_SOCKET_ERROR;
|
||||||
|
r = getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&err, &errlen);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
err = errno;
|
err = errno;
|
||||||
}
|
}
|
||||||
s->last_errno=err;
|
s->last_errno = err;
|
||||||
ssh_socket_close(s);
|
ssh_socket_close(s);
|
||||||
if(s->callbacks && s->callbacks->connected)
|
if (s->callbacks && s->callbacks->connected) {
|
||||||
s->callbacks->connected(SSH_SOCKET_CONNECTED_ERROR,err,
|
s->callbacks->connected(SSH_SOCKET_CONNECTED_ERROR, err,
|
||||||
s->callbacks->userdata);
|
s->callbacks->userdata);
|
||||||
return -1;
|
}
|
||||||
}
|
return -1;
|
||||||
/* Then we are in a more standard kind of error */
|
}
|
||||||
/* force a read to get an explanation */
|
/* Then we are in a more standard kind of error */
|
||||||
revents |= POLLIN;
|
/* force a read to get an explanation */
|
||||||
}
|
revents |= POLLIN;
|
||||||
if((revents & POLLIN) && s->state == SSH_SOCKET_CONNECTED){
|
}
|
||||||
s->read_wontblock=1;
|
if ((revents & POLLIN) && s->state == SSH_SOCKET_CONNECTED) {
|
||||||
r=ssh_socket_unbuffered_read(s,buffer,sizeof(buffer));
|
s->read_wontblock = 1;
|
||||||
if(r<0){
|
r = ssh_socket_unbuffered_read(s, buffer, sizeof(buffer));
|
||||||
if(p != NULL) {
|
if (r < 0) {
|
||||||
ssh_poll_remove_events(p, POLLIN);
|
if (p != NULL) {
|
||||||
}
|
ssh_poll_remove_events(p, POLLIN);
|
||||||
if(s->callbacks && s->callbacks->exception){
|
}
|
||||||
s->callbacks->exception(
|
if (s->callbacks && s->callbacks->exception) {
|
||||||
SSH_SOCKET_EXCEPTION_ERROR,
|
s->callbacks->exception(SSH_SOCKET_EXCEPTION_ERROR,
|
||||||
s->last_errno,s->callbacks->userdata);
|
s->last_errno, s->callbacks->userdata);
|
||||||
/* p may have been freed, so don't use it
|
/* p may have been freed, so don't use it
|
||||||
* anymore in this function */
|
* anymore in this function */
|
||||||
p = NULL;
|
p = NULL;
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(r==0){
|
if (r == 0) {
|
||||||
if(p != NULL) {
|
if (p != NULL) {
|
||||||
ssh_poll_remove_events(p, POLLIN);
|
ssh_poll_remove_events(p, POLLIN);
|
||||||
}
|
}
|
||||||
if(p != NULL) {
|
if (p != NULL) {
|
||||||
ssh_poll_remove_events(p, POLLIN);
|
ssh_poll_remove_events(p, POLLIN);
|
||||||
}
|
}
|
||||||
if(s->callbacks && s->callbacks->exception){
|
if (s->callbacks && s->callbacks->exception) {
|
||||||
s->callbacks->exception(
|
s->callbacks->exception(SSH_SOCKET_EXCEPTION_EOF,
|
||||||
SSH_SOCKET_EXCEPTION_EOF,
|
0, s->callbacks->userdata);
|
||||||
0,s->callbacks->userdata);
|
/* p may have been freed, so don't use it
|
||||||
/* p may have been freed, so don't use it
|
* anymore in this function */
|
||||||
* anymore in this function */
|
p = NULL;
|
||||||
p = NULL;
|
return -2;
|
||||||
return -2;
|
}
|
||||||
}
|
}
|
||||||
}
|
if (r > 0) {
|
||||||
if(r>0){
|
|
||||||
if (s->session->socket_counter != NULL) {
|
if (s->session->socket_counter != NULL) {
|
||||||
s->session->socket_counter->in_bytes += r;
|
s->session->socket_counter->in_bytes += r;
|
||||||
}
|
}
|
||||||
/* Bufferize the data and then call the callback */
|
/* Bufferize the data and then call the callback */
|
||||||
r = ssh_buffer_add_data(s->in_buffer,buffer,r);
|
r = ssh_buffer_add_data(s->in_buffer, buffer, r);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(s->callbacks && s->callbacks->data){
|
if (s->callbacks && s->callbacks->data) {
|
||||||
do {
|
do {
|
||||||
r= s->callbacks->data(buffer_get_rest(s->in_buffer),
|
r = s->callbacks->data(buffer_get_rest(s->in_buffer),
|
||||||
buffer_get_rest_len(s->in_buffer),
|
buffer_get_rest_len(s->in_buffer),
|
||||||
s->callbacks->userdata);
|
s->callbacks->userdata);
|
||||||
buffer_pass_bytes(s->in_buffer,r);
|
buffer_pass_bytes(s->in_buffer, r);
|
||||||
} while ((r > 0) && (s->state == SSH_SOCKET_CONNECTED));
|
} while ((r > 0) && (s->state == SSH_SOCKET_CONNECTED));
|
||||||
/* p may have been freed, so don't use it
|
/* p may have been freed, so don't use it
|
||||||
* anymore in this function */
|
* anymore in this function */
|
||||||
p = NULL;
|
p = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if(revents & POLLOUT || revents & POLLWRNORM){
|
if (revents & POLLOUT || revents & POLLWRNORM) {
|
||||||
#else
|
#else
|
||||||
if(revents & POLLOUT){
|
if (revents & POLLOUT) {
|
||||||
#endif
|
#endif
|
||||||
/* First, POLLOUT is a sign we may be connected */
|
/* First, POLLOUT is a sign we may be connected */
|
||||||
if(s->state == SSH_SOCKET_CONNECTING){
|
if (s->state == SSH_SOCKET_CONNECTING) {
|
||||||
SSH_LOG(SSH_LOG_PACKET,"Received POLLOUT in connecting state");
|
SSH_LOG(SSH_LOG_PACKET, "Received POLLOUT in connecting state");
|
||||||
s->state = SSH_SOCKET_CONNECTED;
|
s->state = SSH_SOCKET_CONNECTED;
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
ssh_poll_set_events(p,POLLOUT | POLLIN);
|
ssh_poll_set_events(p, POLLOUT | POLLIN);
|
||||||
}
|
}
|
||||||
r = ssh_socket_set_blocking(ssh_socket_get_fd_in(s));
|
r = ssh_socket_set_blocking(ssh_socket_get_fd_in(s));
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(s->callbacks && s->callbacks->connected)
|
if (s->callbacks && s->callbacks->connected) {
|
||||||
s->callbacks->connected(SSH_SOCKET_CONNECTED_OK,0,s->callbacks->userdata);
|
s->callbacks->connected(SSH_SOCKET_CONNECTED_OK, 0,
|
||||||
return 0;
|
s->callbacks->userdata);
|
||||||
}
|
}
|
||||||
/* So, we can write data */
|
return 0;
|
||||||
s->write_wontblock=1;
|
}
|
||||||
if(p != NULL) {
|
/* So, we can write data */
|
||||||
|
s->write_wontblock=1;
|
||||||
|
if (p != NULL) {
|
||||||
ssh_poll_remove_events(p, POLLOUT);
|
ssh_poll_remove_events(p, POLLOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If buffered data is pending, write it */
|
/* If buffered data is pending, write it */
|
||||||
if(buffer_get_rest_len(s->out_buffer) > 0){
|
if (buffer_get_rest_len(s->out_buffer) > 0) {
|
||||||
ssh_socket_nonblocking_flush(s);
|
ssh_socket_nonblocking_flush(s);
|
||||||
} else if(s->callbacks && s->callbacks->controlflow){
|
} else if (s->callbacks && s->callbacks->controlflow) {
|
||||||
/* Otherwise advertise the upper level that write can be done */
|
/* Otherwise advertise the upper level that write can be done */
|
||||||
s->callbacks->controlflow(SSH_SOCKET_FLOW_WRITEWONTBLOCK,s->callbacks->userdata);
|
s->callbacks->controlflow(SSH_SOCKET_FLOW_WRITEWONTBLOCK,
|
||||||
}
|
s->callbacks->userdata);
|
||||||
/* TODO: Find a way to put back POLLOUT when buffering occurs */
|
}
|
||||||
}
|
/* TODO: Find a way to put back POLLOUT when buffering occurs */
|
||||||
/* Return -1 if one of the poll handlers disappeared */
|
}
|
||||||
return (s->poll_in == NULL || s->poll_out == NULL) ? -1 : 0;
|
/* Return -1 if one of the poll handlers disappeared */
|
||||||
|
return (s->poll_in == NULL || s->poll_out == NULL) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal
|
/** @internal
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user