diff options
author | Aris Adamantiadis <aris@0xbadc0de.be> | 2008-06-16 23:55:12 +0000 |
---|---|---|
committer | Aris Adamantiadis <aris@0xbadc0de.be> | 2008-06-16 23:55:12 +0000 |
commit | 8ce42c279ec470bc600fcf9dd3450b450f6c32f0 (patch) | |
tree | 227054b8513168f0c36be7c8b6c4a486d0b72020 | |
parent | 1fce8c72e79a69b0478b2f3bf84d058ebaf5211c (diff) | |
download | libssh-8ce42c279ec470bc600fcf9dd3450b450f6c32f0.tar.gz libssh-8ce42c279ec470bc600fcf9dd3450b450f6c32f0.tar.xz libssh-8ce42c279ec470bc600fcf9dd3450b450f6c32f0.zip |
displaced the data_to_* into socket
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@171 7dcaeef0-15fb-0310-b436-a5af3365683c
-rw-r--r-- | include/libssh/priv.h | 14 | ||||
-rw-r--r-- | libssh/channels.c | 12 | ||||
-rw-r--r-- | libssh/connect.c | 2 | ||||
-rw-r--r-- | libssh/packet.c | 4 | ||||
-rw-r--r-- | libssh/session.c | 12 | ||||
-rw-r--r-- | libssh/socket.c | 92 |
6 files changed, 87 insertions, 49 deletions
diff --git a/include/libssh/priv.h b/include/libssh/priv.h index db8fe955..203d14e0 100644 --- a/include/libssh/priv.h +++ b/include/libssh/priv.h @@ -307,10 +307,6 @@ struct ssh_session { int auth_service_asked; /* 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 STRING *banner; /* that's the issue banner from @@ -336,9 +332,6 @@ struct ssh_session { CRYPTO *current_crypto; 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 */ int maxchannel; 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_blocking_flush(struct socket *s); 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 */ void ssh_cleanup(SSH_SESSION *session); diff --git a/libssh/channels.c b/libssh/channels.c index 10e9223b..09ae3982 100644 --- a/libssh/channels.c +++ b/libssh/channels.c @@ -957,7 +957,7 @@ static int channel_protocol_select(CHANNEL **rchans, CHANNEL **wchans, CHANNEL * j=0; for(i=0;rchans[i];++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); } 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){ chan=wchans[i]; /* 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; ++j; } @@ -981,7 +981,7 @@ static int channel_protocol_select(CHANNEL **rchans, CHANNEL **wchans, CHANNEL * j=0; for(i=0;echans[i];++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; ++j; } @@ -1105,15 +1105,15 @@ int channel_select(CHANNEL **readchans, CHANNEL **writechans, CHANNEL **exceptch } for(i=0;readchans[i];++i){ 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){ 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){ 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 */ /* not reached */ diff --git a/libssh/connect.c b/libssh/connect.c index a5156763..9f444787 100644 --- a/libssh/connect.c +++ b/libssh/connect.c @@ -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 */ for(i=0;channels[i];i++) 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 */ j=0; diff --git a/libssh/packet.c b/libssh/packet.c index c81ff289..bc867438 100644 --- a/libssh/packet.c +++ b/libssh/packet.c @@ -52,7 +52,7 @@ static int packet_read2(SSH_SESSION *session){ unsigned int blocksize=(session->current_crypto?session->current_crypto->in_cipher->blocksize:8); int current_macsize=session->current_crypto?macsize:0; enter_function(); - if(!session->alive || session->data_except){ + if(!session->alive){ leave_function(); 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 crc; enter_function(); - if(!session->alive || session->data_except){ + if(!session->alive){ leave_function(); return SSH_ERROR; // the error message was already set } diff --git a/libssh/session.c b/libssh/session.c index 80b9e3a1..b346ddb4 100644 --- a/libssh/session.c +++ b/libssh/session.c @@ -145,21 +145,22 @@ socket_t ssh_get_fd(SSH_SESSION *session){ * \param session ssh 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 * \param session ssh 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 * \param session ssh 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 @@ -193,11 +194,12 @@ int ssh_handle_packets(SSH_SESSION *session){ */ int ssh_get_status(SSH_SESSION *session){ int ret=0; + int socketstate=ssh_socket_get_status(session->socket); if(session->closed) ret |= SSH_CLOSED; - if(session->channel_bytes_toread > 0 || session->data_to_read) + if(socketstate & 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; return ret; } diff --git a/libssh/socket.c b/libssh/socket.c index 0aefa017..41a16a8d 100644 --- a/libssh/socket.c +++ b/libssh/socket.c @@ -39,6 +39,10 @@ struct socket { socket_t fd; 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 *in_buffer; SSH_SESSION *session; @@ -121,12 +125,18 @@ int ssh_socket_is_open(struct socket *s){ * \brief read len bytes from socket into buffer */ 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 s->last_errno=errno; #else s->last_errno=WSAGetLastError(); -#endif +#endif + s->data_to_read=0; + if(r<0) + s->data_except=1; 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 */ 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 s->last_errno=errno; #else s->last_errno=WSAGetLastError(); #endif - + s->data_to_write=0; + if(w<0) + s->data_except=1; return w; } @@ -276,13 +291,12 @@ int ssh_socket_wait_for_data(struct socket *s, SSH_SESSION *session,int len){ if(session->blocking){ buf=malloc(to_read); r=ssh_socket_completeread(session->socket,buf,to_read); - session->data_to_read=0; if(r==SSH_ERROR || r ==0){ ssh_set_error(session,SSH_FATAL, (r==0)?"Connection closed by remote host" : "Error reading socket"); ssh_socket_close(session->socket); session->alive=0; - session->data_except=1; + free(buf); leave_function(); return SSH_ERROR; } @@ -295,11 +309,11 @@ int ssh_socket_wait_for_data(struct socket *s, SSH_SESSION *session,int len){ /* nonblocking read */ do { ssh_socket_poll(s,&can_write,&except); /* internally sets data_to_read */ - if(!session->data_to_read){ + if(!s->data_to_read){ leave_function(); return SSH_AGAIN; } - session->data_to_read=0; + /* read as much as we can */ if(ssh_socket_is_open(session->socket)) 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, (r==0)?"Connection closed by remote host" : "Error reading socket"); ssh_socket_close(session->socket); - session->data_except=1; session->alive=0; leave_function(); return SSH_ERROR; @@ -343,9 +356,9 @@ int ssh_socket_poll(struct socket *s, int *write, int *except){ *write=0; return 0; } - if(!session->data_to_read) + if(!s->data_to_read) 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,&edes,&fdmax); @@ -359,13 +372,15 @@ int ssh_socket_poll(struct socket *s, int *write, int *except){ leave_function(); return -1; } - if(!session->data_to_read) - session->data_to_read=ssh_socket_fd_isset(session->socket,&rdes); - if(!session->data_to_write) - session->data_to_write=ssh_socket_fd_isset(session->socket,&wdes); - *except=ssh_socket_fd_isset(session->socket,&edes); - *write=session->data_to_write; - return session->data_to_read; + if(!s->data_to_read) + s->data_to_read=ssh_socket_fd_isset(s,&rdes); + if(!s->data_to_write) + s->data_to_write=ssh_socket_fd_isset(s,&wdes); + if(!s->data_except) + s->data_except=ssh_socket_fd_isset(s,&edes); + *except=s->data_except; + *write=s->data_to_write; + return s->data_to_read; } /** \internal @@ -384,16 +399,13 @@ int ssh_socket_nonblocking_flush(struct socket *s){ leave_function(); 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)){ w=ssh_socket_unbuffered_write(s,buffer_get_rest(s->out_buffer), buffer_get_rest_len(s->out_buffer)); - session->data_to_write=0; } else w=-1; /* write failed */ if(w<0){ - session->data_to_write=0; - session->data_except=1; session->alive=0; ssh_socket_close(s); // FIXME use ssh_socket_get_errno() @@ -416,7 +428,7 @@ int ssh_socket_nonblocking_flush(struct socket *s){ /** \internal - * \brief locking flush of the output buffer + * \brief locking flush of the output packet buffer */ int ssh_socket_blocking_flush(struct socket *s){ SSH_SESSION *session=s->session; @@ -426,7 +438,7 @@ int ssh_socket_blocking_flush(struct socket *s){ leave_function(); return SSH_ERROR; } - if(session->data_except){ + if(s->data_except){ leave_function(); 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), buffer_get_rest_len(s->out_buffer))){ - session->data_to_write=0; - session->data_except=1; session->alive=0; ssh_socket_close(s); // FIXME use the proper errno @@ -446,11 +456,39 @@ int ssh_socket_blocking_flush(struct socket *s){ leave_function(); return SSH_ERROR; } - session->data_to_write=0; buffer_reinit(s->out_buffer); leave_function(); 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; +} + /** @} */ |