1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-08-05 20:55:46 +03:00

displaced the data_to_* into socket

git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@171 7dcaeef0-15fb-0310-b436-a5af3365683c
This commit is contained in:
Aris Adamantiadis
2008-06-16 23:55:12 +00:00
parent 1fce8c72e7
commit 8ce42c279e
6 changed files with 87 additions and 49 deletions

View File

@@ -307,10 +307,6 @@ struct ssh_session {
int auth_service_asked; int auth_service_asked;
/* socket status */ /* socket status */
int data_to_read; /* reading now on socket will
not block */
int data_to_write;
int data_except;
int blocking; // functions should block int blocking; // functions should block
STRING *banner; /* that's the issue banner from STRING *banner; /* that's the issue banner from
@@ -336,9 +332,6 @@ struct ssh_session {
CRYPTO *current_crypto; CRYPTO *current_crypto;
CRYPTO *next_crypto; /* next_crypto is going to be used after a SSH2_MSG_NEWKEYS */ CRYPTO *next_crypto; /* next_crypto is going to be used after a SSH2_MSG_NEWKEYS */
int channel_bytes_toread; /* left number of bytes
in the channel buffers
*/
CHANNEL *channels; /* linked list of channels */ CHANNEL *channels; /* linked list of channels */
int maxchannel; int maxchannel;
int exec_channel_opened; /* version 1 only. more int exec_channel_opened; /* version 1 only. more
@@ -442,7 +435,12 @@ int ssh_socket_wait_for_data(struct socket *s, SSH_SESSION *session,int len);
int ssh_socket_nonblocking_flush(struct socket *s); int ssh_socket_nonblocking_flush(struct socket *s);
int ssh_socket_blocking_flush(struct socket *s); int ssh_socket_blocking_flush(struct socket *s);
int ssh_socket_poll(struct socket *s, int *write, int *except); int ssh_socket_poll(struct socket *s, int *write, int *except);
void ssh_socket_set_towrite(struct socket *s);
void ssh_socket_set_toread(struct socket *s);
void ssh_socket_set_except(struct socket *s);
int ssh_socket_get_status(struct socket *s);
int ssh_socket_data_available(struct socket *s);
int ssh_socket_data_writable(struct socket *s);
/* session.c */ /* session.c */
void ssh_cleanup(SSH_SESSION *session); void ssh_cleanup(SSH_SESSION *session);

View File

@@ -957,7 +957,7 @@ static int channel_protocol_select(CHANNEL **rchans, CHANNEL **wchans, CHANNEL *
j=0; j=0;
for(i=0;rchans[i];++i){ for(i=0;rchans[i];++i){
chan=rchans[i]; chan=rchans[i];
while(chan->open && chan->session->data_to_read){ while(chan->open && ssh_socket_data_available(chan->session->socket)){
ssh_handle_packets(chan->session); ssh_handle_packets(chan->session);
} }
if( (chan->stdout_buffer && buffer_get_len(chan->stdout_buffer)>0) || if( (chan->stdout_buffer && buffer_get_len(chan->stdout_buffer)>0) ||
@@ -972,7 +972,7 @@ static int channel_protocol_select(CHANNEL **rchans, CHANNEL **wchans, CHANNEL *
for(i=0;wchans[i];++i){ for(i=0;wchans[i];++i){
chan=wchans[i]; chan=wchans[i];
/* it's not our business to seek if the file descriptor is writable */ /* it's not our business to seek if the file descriptor is writable */
if(chan->session->data_to_write && chan->open && (chan->remote_window>0)){ if(ssh_socket_data_writable(chan->session->socket) && chan->open && (chan->remote_window>0)){
wout[j]=chan; wout[j]=chan;
++j; ++j;
} }
@@ -981,7 +981,7 @@ static int channel_protocol_select(CHANNEL **rchans, CHANNEL **wchans, CHANNEL *
j=0; j=0;
for(i=0;echans[i];++i){ for(i=0;echans[i];++i){
chan=echans[i]; chan=echans[i];
if(!ssh_socket_is_open(chan->session->socket) || !chan->open || chan->session->data_except){ if(!ssh_socket_is_open(chan->session->socket) || !chan->open){
eout[j]=chan; eout[j]=chan;
++j; ++j;
} }
@@ -1105,15 +1105,15 @@ int channel_select(CHANNEL **readchans, CHANNEL **writechans, CHANNEL **exceptch
} }
for(i=0;readchans[i];++i){ for(i=0;readchans[i];++i){
if(ssh_socket_fd_isset(readchans[i]->session->socket,&rset)) if(ssh_socket_fd_isset(readchans[i]->session->socket,&rset))
readchans[i]->session->data_to_read=1; ssh_socket_set_toread(readchans[i]->session->socket);
} }
for(i=0;writechans[i];++i){ for(i=0;writechans[i];++i){
if(ssh_socket_fd_isset(writechans[i]->session->socket,&wset)) if(ssh_socket_fd_isset(writechans[i]->session->socket,&wset))
writechans[i]->session->data_to_write=1; ssh_socket_set_towrite(writechans[i]->session->socket);
} }
for(i=0;exceptchans[i];++i){ for(i=0;exceptchans[i];++i){
if(ssh_socket_fd_isset(exceptchans[i]->session->socket,&eset)) if(ssh_socket_fd_isset(exceptchans[i]->session->socket,&eset))
exceptchans[i]->session->data_except=1; ssh_socket_set_except(exceptchans[i]->session->socket);
} }
} while(1); /* return to do loop */ } while(1); /* return to do loop */
/* not reached */ /* not reached */

View File

@@ -299,7 +299,7 @@ int ssh_select(CHANNEL **channels,CHANNEL **outchannels, socket_t maxfd, fd_set
/* set the data_to_read flag on each session */ /* set the data_to_read flag on each session */
for(i=0;channels[i];i++) for(i=0;channels[i];i++)
if(channels[i]->session->alive && ssh_socket_fd_isset(channels[i]->session->socket,&localset)) if(channels[i]->session->alive && ssh_socket_fd_isset(channels[i]->session->socket,&localset))
channels[i]->session->data_to_read=1; ssh_socket_set_toread(channels[i]->session->socket);
/* now, test each channel */ /* now, test each channel */
j=0; j=0;

View File

@@ -52,7 +52,7 @@ static int packet_read2(SSH_SESSION *session){
unsigned int blocksize=(session->current_crypto?session->current_crypto->in_cipher->blocksize:8); unsigned int blocksize=(session->current_crypto?session->current_crypto->in_cipher->blocksize:8);
int current_macsize=session->current_crypto?macsize:0; int current_macsize=session->current_crypto?macsize:0;
enter_function(); enter_function();
if(!session->alive || session->data_except){ if(!session->alive){
leave_function(); leave_function();
return SSH_ERROR; // the error message was already set into this session return SSH_ERROR; // the error message was already set into this session
} }
@@ -162,7 +162,7 @@ static int packet_read1(SSH_SESSION *session){
u32 padding; u32 padding;
u32 crc; u32 crc;
enter_function(); enter_function();
if(!session->alive || session->data_except){ if(!session->alive){
leave_function(); leave_function();
return SSH_ERROR; // the error message was already set return SSH_ERROR; // the error message was already set
} }

View File

@@ -145,21 +145,22 @@ socket_t ssh_get_fd(SSH_SESSION *session){
* \param session ssh session * \param session ssh session
*/ */
void ssh_set_fd_toread(SSH_SESSION *session){ void ssh_set_fd_toread(SSH_SESSION *session){
session->data_to_read=1; ssh_socket_set_toread(session->socket);
} }
/** \brief say the session it may write to the file descriptor without blocking /** \brief say the session it may write to the file descriptor without blocking
* \param session ssh session * \param session ssh session
*/ */
void ssh_set_fd_towrite(SSH_SESSION *session){ void ssh_set_fd_towrite(SSH_SESSION *session){
session->data_to_write=1; ssh_socket_set_towrite(session->socket);
} }
/** \brief say the session it has an exception to catch on the file descriptor /** \brief say the session it has an exception to catch on the file descriptor
* \param session ssh session * \param session ssh session
*/ */
void ssh_set_fd_except(SSH_SESSION *session){ void ssh_set_fd_except(SSH_SESSION *session){
session->data_except=1; ssh_socket_set_except(session->socket);
} }
/** \warning I don't remember if this should be internal or not /** \warning I don't remember if this should be internal or not
@@ -193,11 +194,12 @@ int ssh_handle_packets(SSH_SESSION *session){
*/ */
int ssh_get_status(SSH_SESSION *session){ int ssh_get_status(SSH_SESSION *session){
int ret=0; int ret=0;
int socketstate=ssh_socket_get_status(session->socket);
if(session->closed) if(session->closed)
ret |= SSH_CLOSED; ret |= SSH_CLOSED;
if(session->channel_bytes_toread > 0 || session->data_to_read) if(socketstate & SSH_READ_PENDING)
ret |= SSH_READ_PENDING; ret |= SSH_READ_PENDING;
if(session->closed && session->closed_by_except) if(session->closed && socketstate & SSH_CLOSED_ERROR)
ret |= SSH_CLOSED_ERROR; ret |= SSH_CLOSED_ERROR;
return ret; return ret;
} }

View File

@@ -39,6 +39,10 @@
struct socket { struct socket {
socket_t fd; socket_t fd;
int last_errno; int last_errno;
int data_to_read; /* reading now on socket will
not block */
int data_to_write;
int data_except;
BUFFER *out_buffer; BUFFER *out_buffer;
BUFFER *in_buffer; BUFFER *in_buffer;
SSH_SESSION *session; SSH_SESSION *session;
@@ -121,12 +125,18 @@ int ssh_socket_is_open(struct socket *s){
* \brief read len bytes from socket into buffer * \brief read len bytes from socket into buffer
*/ */
int ssh_socket_unbuffered_read(struct socket *s, void *buffer, int len){ int ssh_socket_unbuffered_read(struct socket *s, void *buffer, int len){
int r=recv(s->fd,buffer,len,0); int r;
if(s->data_except)
return -1;
r=recv(s->fd,buffer,len,0);
#ifndef _WIN32 #ifndef _WIN32
s->last_errno=errno; s->last_errno=errno;
#else #else
s->last_errno=WSAGetLastError(); s->last_errno=WSAGetLastError();
#endif #endif
s->data_to_read=0;
if(r<0)
s->data_except=1;
return r; return r;
} }
@@ -134,13 +144,18 @@ int ssh_socket_unbuffered_read(struct socket *s, void *buffer, int len){
* \brief writes len bytes from buffer to socket * \brief writes len bytes from buffer to socket
*/ */
int ssh_socket_unbuffered_write(struct socket *s,const void *buffer, int len){ int ssh_socket_unbuffered_write(struct socket *s,const void *buffer, int len){
int w=send(s->fd,buffer,len,0); int w;
if(s->data_except)
return -1;
w=send(s->fd,buffer,len,0);
#ifndef _WIN32 #ifndef _WIN32
s->last_errno=errno; s->last_errno=errno;
#else #else
s->last_errno=WSAGetLastError(); s->last_errno=WSAGetLastError();
#endif #endif
s->data_to_write=0;
if(w<0)
s->data_except=1;
return w; return w;
} }
@@ -276,13 +291,12 @@ int ssh_socket_wait_for_data(struct socket *s, SSH_SESSION *session,int len){
if(session->blocking){ if(session->blocking){
buf=malloc(to_read); buf=malloc(to_read);
r=ssh_socket_completeread(session->socket,buf,to_read); r=ssh_socket_completeread(session->socket,buf,to_read);
session->data_to_read=0;
if(r==SSH_ERROR || r ==0){ if(r==SSH_ERROR || r ==0){
ssh_set_error(session,SSH_FATAL, ssh_set_error(session,SSH_FATAL,
(r==0)?"Connection closed by remote host" : "Error reading socket"); (r==0)?"Connection closed by remote host" : "Error reading socket");
ssh_socket_close(session->socket); ssh_socket_close(session->socket);
session->alive=0; session->alive=0;
session->data_except=1; free(buf);
leave_function(); leave_function();
return SSH_ERROR; return SSH_ERROR;
} }
@@ -295,11 +309,11 @@ int ssh_socket_wait_for_data(struct socket *s, SSH_SESSION *session,int len){
/* nonblocking read */ /* nonblocking read */
do { do {
ssh_socket_poll(s,&can_write,&except); /* internally sets data_to_read */ ssh_socket_poll(s,&can_write,&except); /* internally sets data_to_read */
if(!session->data_to_read){ if(!s->data_to_read){
leave_function(); leave_function();
return SSH_AGAIN; return SSH_AGAIN;
} }
session->data_to_read=0;
/* read as much as we can */ /* read as much as we can */
if(ssh_socket_is_open(session->socket)) if(ssh_socket_is_open(session->socket))
r=ssh_socket_unbuffered_read(session->socket,buffer,sizeof(buffer)); r=ssh_socket_unbuffered_read(session->socket,buffer,sizeof(buffer));
@@ -309,7 +323,6 @@ int ssh_socket_wait_for_data(struct socket *s, SSH_SESSION *session,int len){
ssh_set_error(session,SSH_FATAL, ssh_set_error(session,SSH_FATAL,
(r==0)?"Connection closed by remote host" : "Error reading socket"); (r==0)?"Connection closed by remote host" : "Error reading socket");
ssh_socket_close(session->socket); ssh_socket_close(session->socket);
session->data_except=1;
session->alive=0; session->alive=0;
leave_function(); leave_function();
return SSH_ERROR; return SSH_ERROR;
@@ -343,9 +356,9 @@ int ssh_socket_poll(struct socket *s, int *write, int *except){
*write=0; *write=0;
return 0; return 0;
} }
if(!session->data_to_read) if(!s->data_to_read)
ssh_socket_fd_set(s,&rdes,&fdmax); ssh_socket_fd_set(s,&rdes,&fdmax);
if(!session->data_to_write) if(!s->data_to_write)
ssh_socket_fd_set(s,&wdes,&fdmax); ssh_socket_fd_set(s,&wdes,&fdmax);
ssh_socket_fd_set(s,&edes,&fdmax); ssh_socket_fd_set(s,&edes,&fdmax);
@@ -359,13 +372,15 @@ int ssh_socket_poll(struct socket *s, int *write, int *except){
leave_function(); leave_function();
return -1; return -1;
} }
if(!session->data_to_read) if(!s->data_to_read)
session->data_to_read=ssh_socket_fd_isset(session->socket,&rdes); s->data_to_read=ssh_socket_fd_isset(s,&rdes);
if(!session->data_to_write) if(!s->data_to_write)
session->data_to_write=ssh_socket_fd_isset(session->socket,&wdes); s->data_to_write=ssh_socket_fd_isset(s,&wdes);
*except=ssh_socket_fd_isset(session->socket,&edes); if(!s->data_except)
*write=session->data_to_write; s->data_except=ssh_socket_fd_isset(s,&edes);
return session->data_to_read; *except=s->data_except;
*write=s->data_to_write;
return s->data_to_read;
} }
/** \internal /** \internal
@@ -384,16 +399,13 @@ int ssh_socket_nonblocking_flush(struct socket *s){
leave_function(); leave_function();
return SSH_ERROR; return SSH_ERROR;
} }
while(session->data_to_write && buffer_get_rest_len(s->out_buffer)>0){ while(s->data_to_write && buffer_get_rest_len(s->out_buffer)>0){
if(ssh_socket_is_open(s)){ if(ssh_socket_is_open(s)){
w=ssh_socket_unbuffered_write(s,buffer_get_rest(s->out_buffer), w=ssh_socket_unbuffered_write(s,buffer_get_rest(s->out_buffer),
buffer_get_rest_len(s->out_buffer)); buffer_get_rest_len(s->out_buffer));
session->data_to_write=0;
} else } else
w=-1; /* write failed */ w=-1; /* write failed */
if(w<0){ if(w<0){
session->data_to_write=0;
session->data_except=1;
session->alive=0; session->alive=0;
ssh_socket_close(s); ssh_socket_close(s);
// FIXME use ssh_socket_get_errno() // FIXME use ssh_socket_get_errno()
@@ -416,7 +428,7 @@ int ssh_socket_nonblocking_flush(struct socket *s){
/** \internal /** \internal
* \brief locking flush of the output buffer * \brief locking flush of the output packet buffer
*/ */
int ssh_socket_blocking_flush(struct socket *s){ int ssh_socket_blocking_flush(struct socket *s){
SSH_SESSION *session=s->session; SSH_SESSION *session=s->session;
@@ -426,7 +438,7 @@ int ssh_socket_blocking_flush(struct socket *s){
leave_function(); leave_function();
return SSH_ERROR; return SSH_ERROR;
} }
if(session->data_except){ if(s->data_except){
leave_function(); leave_function();
return SSH_ERROR; return SSH_ERROR;
} }
@@ -436,8 +448,6 @@ int ssh_socket_blocking_flush(struct socket *s){
} }
if(ssh_socket_completewrite(s,buffer_get_rest(s->out_buffer), if(ssh_socket_completewrite(s,buffer_get_rest(s->out_buffer),
buffer_get_rest_len(s->out_buffer))){ buffer_get_rest_len(s->out_buffer))){
session->data_to_write=0;
session->data_except=1;
session->alive=0; session->alive=0;
ssh_socket_close(s); ssh_socket_close(s);
// FIXME use the proper errno // FIXME use the proper errno
@@ -446,11 +456,39 @@ int ssh_socket_blocking_flush(struct socket *s){
leave_function(); leave_function();
return SSH_ERROR; return SSH_ERROR;
} }
session->data_to_write=0;
buffer_reinit(s->out_buffer); buffer_reinit(s->out_buffer);
leave_function(); leave_function();
return SSH_OK; // no data pending return SSH_OK; // no data pending
} }
void ssh_socket_set_towrite(struct socket *s){
s->data_to_write=1;
}
void ssh_socket_set_toread(struct socket *s){
s->data_to_read=1;
}
void ssh_socket_set_except(struct socket *s){
s->data_except=1;
}
int ssh_socket_data_available(struct socket *s){
return s->data_to_read;
}
int ssh_socket_data_writable(struct socket *s){
return s->data_to_write;
}
int ssh_socket_get_status(struct socket *s){
int r=0;
if(s->data_to_read)
r |= SSH_READ_PENDING;
if(s->data_except)
r|= SSH_CLOSED_ERROR;
return r;
}
/** @} /** @}
*/ */