added the socket class and created wrappers
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@137 7dcaeef0-15fb-0310-b436-a5af3365683c
Этот коммит содержится в:
родитель
9b5f893513
Коммит
077dd81fcc
@ -285,7 +285,7 @@ struct error_struct {
|
||||
|
||||
struct ssh_session {
|
||||
struct error_struct error;
|
||||
int fd;
|
||||
struct socket *socket;
|
||||
SSH_OPTIONS *options;
|
||||
char *serverbanner;
|
||||
char *clientbanner;
|
||||
@ -422,6 +422,21 @@ struct ssh_message {
|
||||
struct ssh_channel_request channel_request;
|
||||
};
|
||||
|
||||
/* socketc.c */
|
||||
|
||||
struct socket;
|
||||
struct socket *ssh_socket_new();
|
||||
void ssh_socket_free(struct socket *s);
|
||||
void ssh_socket_set_fd(struct socket *s, int fd);
|
||||
int ssh_socket_get_fd(struct socket *s);
|
||||
void ssh_socket_close(struct socket *s);
|
||||
int ssh_socket_read(struct socket *s, void *buffer, int len);
|
||||
int ssh_socket_write(struct socket *s,const void *buffer, int len);
|
||||
int ssh_socket_is_open(struct socket *s);
|
||||
int ssh_socket_fd_isset(struct socket *s, fd_set *set);
|
||||
void ssh_socket_fd_set(struct socket *s, fd_set *set, int *fd_max);
|
||||
int ssh_socket_completeread(struct socket *s, void *buffer, int len);
|
||||
|
||||
/* session.c */
|
||||
|
||||
void ssh_cleanup(SSH_SESSION *session);
|
||||
@ -603,7 +618,7 @@ char *my_gcry_bn2dec(bignum bn);
|
||||
#endif /* !HAVE_LIBGCRYPT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} ;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIBSSH_PRIV_H */
|
||||
|
@ -6,7 +6,8 @@ libssh_la_SOURCES = auth1.c auth.c base64.c buffer.c \
|
||||
gzip.c init.c kex.c keyfiles.c \
|
||||
keys.c messages.c misc.c options.c \
|
||||
packet.c server.c session.c sftp.c \
|
||||
sftpserver.c string.c wrapper.c
|
||||
sftpserver.c string.c wrapper.c \
|
||||
socket.c
|
||||
|
||||
libssh_la_CPPFLAGS = -I$(top_srcdir)/include
|
||||
|
||||
|
@ -905,7 +905,7 @@ static int channel_protocol_select(CHANNEL **rchans, CHANNEL **wchans, CHANNEL *
|
||||
j=0;
|
||||
for(i=0;echans[i];++i){
|
||||
chan=echans[i];
|
||||
if(chan->session->fd==-1 || !chan->open || chan->session->data_except){
|
||||
if(!ssh_socket_is_open(chan->session->socket) || !chan->open || chan->session->data_except){
|
||||
eout[j]=chan;
|
||||
++j;
|
||||
}
|
||||
@ -940,7 +940,7 @@ int channel_select(CHANNEL **readchans, CHANNEL **writechans, CHANNEL **exceptch
|
||||
CHANNEL *dummy=NULL;
|
||||
CHANNEL **rchans, **wchans, **echans;
|
||||
int fdmax=-1;
|
||||
int i,fd;
|
||||
int i;
|
||||
int r;
|
||||
/* don't allow NULL pointers */
|
||||
if(!readchans)
|
||||
@ -980,12 +980,25 @@ int channel_select(CHANNEL **readchans, CHANNEL **writechans, CHANNEL **exceptch
|
||||
FD_ZERO(&wset);
|
||||
FD_ZERO(&eset);
|
||||
for(i=0;readchans[i];++i){
|
||||
fd=readchans[i]->session->fd;
|
||||
if(!ssh_socket_fd_isset(readchans[i]->session->socket,&rset))
|
||||
ssh_socket_fd_set(readchans[i]->session->socket, &rset, &fdmax);
|
||||
}
|
||||
for(i=0;writechans[i];++i){
|
||||
if(!ssh_socket_fd_isset(writechans[i]->session->socket,&wset))
|
||||
ssh_socket_fd_set(writechans[i]->session->socket,&wset, &fdmax);
|
||||
}
|
||||
for(i=0;exceptchans[i];++i){
|
||||
if(!ssh_socket_fd_isset(exceptchans[i]->session->socket,&eset))
|
||||
ssh_socket_fd_set(exceptchans[i]->session->socket,&eset,&fdmax);
|
||||
}
|
||||
|
||||
/* fd=readchans[i]->session->fd;
|
||||
if(!FD_ISSET(fd,&rset)){
|
||||
FD_SET(fd,&rset);
|
||||
if(fd>=fdmax)
|
||||
fdmax=fd+1;
|
||||
}
|
||||
|
||||
}
|
||||
for(i=0;writechans[i];++i){
|
||||
fd=writechans[i]->session->fd;
|
||||
@ -995,6 +1008,7 @@ int channel_select(CHANNEL **readchans, CHANNEL **writechans, CHANNEL **exceptch
|
||||
fdmax=fd+1;
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0;exceptchans[i];++i){
|
||||
fd=exceptchans[i]->session->fd;
|
||||
if(!FD_ISSET(fd,&eset)){
|
||||
@ -1003,6 +1017,7 @@ int channel_select(CHANNEL **readchans, CHANNEL **writechans, CHANNEL **exceptch
|
||||
fdmax=fd+1;
|
||||
}
|
||||
}
|
||||
*/
|
||||
/* here we go */
|
||||
r=select(fdmax,&rset,&wset,&eset,timeout);
|
||||
/* leave if select was interrupted */
|
||||
@ -1013,15 +1028,15 @@ int channel_select(CHANNEL **readchans, CHANNEL **writechans, CHANNEL **exceptch
|
||||
return SSH_EINTR;
|
||||
}
|
||||
for(i=0;readchans[i];++i){
|
||||
if(FD_ISSET(readchans[i]->session->fd,&rset))
|
||||
if(ssh_socket_fd_isset(readchans[i]->session->socket,&rset))
|
||||
readchans[i]->session->data_to_read=1;
|
||||
}
|
||||
for(i=0;writechans[i];++i){
|
||||
if(FD_ISSET(writechans[i]->session->fd,&wset))
|
||||
if(ssh_socket_fd_isset(writechans[i]->session->socket,&wset))
|
||||
writechans[i]->session->data_to_write=1;
|
||||
}
|
||||
for(i=0;exceptchans[i];++i){
|
||||
if(FD_ISSET(exceptchans[i]->session->fd,&eset))
|
||||
if(ssh_socket_fd_isset(exceptchans[i]->session->socket,&eset))
|
||||
exceptchans[i]->session->data_except=1;
|
||||
}
|
||||
} while(1); /* return to do loop */
|
||||
|
@ -36,7 +36,7 @@ char *ssh_get_banner(SSH_SESSION *session){
|
||||
char buffer[128];
|
||||
int i = 0;
|
||||
while (i < 127) {
|
||||
if(session->fd <0 || read(session->fd, &buffer[i], 1)<=0){
|
||||
if(!ssh_socket_is_open(session->socket) || ssh_socket_read(session->socket, &buffer[i], 1)<=0){
|
||||
ssh_set_error(session,SSH_FATAL,"Remote host closed connection");
|
||||
return NULL;
|
||||
}
|
||||
@ -98,7 +98,7 @@ int ssh_send_banner(SSH_SESSION *session,int server){
|
||||
else
|
||||
session->clientbanner=strdup(banner);
|
||||
snprintf(buffer,128,"%s\r\n",banner);
|
||||
write(session->fd,buffer,strlen(buffer));
|
||||
ssh_socket_write(session->socket,buffer,strlen(buffer));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -247,12 +247,10 @@ int ssh_connect(SSH_SESSION *session){
|
||||
if(fd<0)
|
||||
return -1;
|
||||
set_status(options,0.2);
|
||||
session->fd=fd;
|
||||
ssh_socket_set_fd(session->socket,fd);
|
||||
session->alive=1;
|
||||
if(!(session->serverbanner=ssh_get_banner(session))){
|
||||
if(session->fd>=0)
|
||||
close(session->fd);
|
||||
session->fd=-1;
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive=0;
|
||||
return -1;
|
||||
}
|
||||
@ -260,9 +258,7 @@ int ssh_connect(SSH_SESSION *session){
|
||||
ssh_say(2,"banner : %s\n",session->serverbanner);
|
||||
/* here we analyse the different protocols the server allows */
|
||||
if(ssh_analyze_banner(session,&ssh1,&ssh2)){
|
||||
if(session->fd>=0)
|
||||
close(session->fd);
|
||||
session->fd=-1;
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive=0;
|
||||
return -1;
|
||||
}
|
||||
@ -275,8 +271,7 @@ int ssh_connect(SSH_SESSION *session){
|
||||
ssh_set_error(session,SSH_FATAL,
|
||||
"no version of SSH protocol usable (banner: %s)",
|
||||
session->serverbanner);
|
||||
close(session->fd);
|
||||
session->fd=-1;
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive=0;
|
||||
return -1;
|
||||
}
|
||||
@ -285,27 +280,21 @@ int ssh_connect(SSH_SESSION *session){
|
||||
switch(session->version){
|
||||
case 2:
|
||||
if(ssh_get_kex(session,0)){
|
||||
if(session->fd>=0)
|
||||
close(session->fd);
|
||||
session->fd=-1;
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive=0;
|
||||
return -1;
|
||||
}
|
||||
set_status(options,0.6);
|
||||
ssh_list_kex(&session->server_kex);
|
||||
if(set_kex(session)){
|
||||
if(session->fd>=0)
|
||||
close(session->fd);
|
||||
session->fd=-1;
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive=0;
|
||||
return -1;
|
||||
}
|
||||
ssh_send_kex(session,0);
|
||||
set_status(options,0.8);
|
||||
if(dh_handshake(session)){
|
||||
if(session->fd>=0)
|
||||
close(session->fd);
|
||||
session->fd=-1;
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive=0;
|
||||
return -1;
|
||||
}
|
||||
@ -314,9 +303,7 @@ int ssh_connect(SSH_SESSION *session){
|
||||
break;
|
||||
case 1:
|
||||
if(ssh_get_kex1(session)){
|
||||
if(session->fd>=0)
|
||||
close(session->fd);
|
||||
session->fd=-1;
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive=0;
|
||||
return -1;
|
||||
}
|
||||
@ -344,7 +331,7 @@ char *ssh_get_issue_banner(SSH_SESSION *session){
|
||||
*/
|
||||
void ssh_disconnect(SSH_SESSION *session){
|
||||
STRING *str;
|
||||
if(session->fd!= -1) {
|
||||
if(ssh_socket_is_open(session->socket)) {
|
||||
packet_clear_out(session);
|
||||
buffer_add_u8(session->out_buffer,SSH2_MSG_DISCONNECT);
|
||||
buffer_add_u32(session->out_buffer,htonl(SSH2_DISCONNECT_BY_APPLICATION));
|
||||
@ -352,15 +339,14 @@ void ssh_disconnect(SSH_SESSION *session){
|
||||
buffer_add_ssh_string(session->out_buffer,str);
|
||||
free(str);
|
||||
packet_send(session);
|
||||
close(session->fd);
|
||||
session->fd=-1;
|
||||
ssh_socket_close(session->socket);
|
||||
}
|
||||
session->alive=0;
|
||||
ssh_cleanup(session);
|
||||
}
|
||||
|
||||
const char *ssh_copyright(){
|
||||
return LIBSSH_VERSION " (c) 2003-2006 Aris Adamantiadis (aris@0xbadc0de.be)"
|
||||
return LIBSSH_VERSION " (c) 2003-2008 Aris Adamantiadis (aris@0xbadc0de.be)"
|
||||
" Distributed under the LGPL, please refer to COPYING file for informations"
|
||||
" about your rights" ;
|
||||
}
|
||||
|
@ -189,37 +189,38 @@ int ssh_fd_poll(SSH_SESSION *session, int *write, int *except){
|
||||
fd_set rdes; // read set
|
||||
fd_set wdes; // writing set
|
||||
fd_set edes; // exception set
|
||||
int fdmax=-1;
|
||||
|
||||
FD_ZERO(&rdes);
|
||||
FD_ZERO(&wdes);
|
||||
FD_ZERO(&edes);
|
||||
|
||||
if(!session->alive || session->fd<0){
|
||||
if(!session->alive || !ssh_socket_is_open(session->socket)){
|
||||
*except=1;
|
||||
*write=0;
|
||||
session->alive=0;
|
||||
return 0;
|
||||
}
|
||||
if(!session->data_to_read)
|
||||
FD_SET(session->fd,&rdes);
|
||||
ssh_socket_fd_set(session->socket,&rdes,&fdmax);
|
||||
if(!session->data_to_write)
|
||||
FD_SET(session->fd,&wdes);
|
||||
FD_SET(session->fd,&edes);
|
||||
ssh_socket_fd_set(session->socket,&wdes,&fdmax);
|
||||
ssh_socket_fd_set(session->socket,&edes,&fdmax);
|
||||
|
||||
/* Set to return immediately (no blocking) */
|
||||
sometime.tv_sec = 0;
|
||||
sometime.tv_usec = 0;
|
||||
|
||||
/* Make the call, and listen for errors */
|
||||
if (select(session->fd + 1, &rdes,&wdes,&edes, &sometime) < 0) {
|
||||
if (select(fdmax, &rdes,&wdes,&edes, &sometime) < 0) {
|
||||
ssh_set_error(NULL,SSH_FATAL, "select: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(!session->data_to_read)
|
||||
session->data_to_read=FD_ISSET(session->fd,&rdes);
|
||||
session->data_to_read=ssh_socket_fd_isset(session->socket,&rdes);
|
||||
if(!session->data_to_write)
|
||||
session->data_to_write=FD_ISSET(session->fd,&wdes);
|
||||
*except=FD_ISSET(session->fd,&edes);
|
||||
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;
|
||||
}
|
||||
@ -285,9 +286,7 @@ int ssh_select(CHANNEL **channels,CHANNEL **outchannels, int maxfd, fd_set *read
|
||||
memcpy(&localset,readfds,sizeof(fd_set));
|
||||
for(i=0;channels[i];i++){
|
||||
if(channels[i]->session->alive){
|
||||
FD_SET(channels[i]->session->fd,&localset);
|
||||
if(channels[i]->session->fd>maxfd-1)
|
||||
maxfd=channels[i]->session->fd+1;
|
||||
ssh_socket_fd_set(channels[i]->session->socket,&localset,&maxfd);
|
||||
}
|
||||
}
|
||||
rep=select(maxfd,&localset,NULL,NULL,timeout);
|
||||
@ -301,13 +300,13 @@ int ssh_select(CHANNEL **channels,CHANNEL **outchannels, int maxfd, fd_set *read
|
||||
}
|
||||
/* set the data_to_read flag on each session */
|
||||
for(i=0;channels[i];i++)
|
||||
if(channels[i]->session->alive && FD_ISSET(channels[i]->session->fd,&localset))
|
||||
if(channels[i]->session->alive && ssh_socket_fd_isset(channels[i]->session->socket,&localset))
|
||||
channels[i]->session->data_to_read=1;
|
||||
|
||||
/* now, test each channel */
|
||||
j=0;
|
||||
for(i=0;channels[i];i++){
|
||||
if(channels[i]->session->alive && FD_ISSET(channels[i]->session->fd,&localset))
|
||||
if(channels[i]->session->alive && ssh_socket_fd_isset(channels[i]->session->socket,&localset))
|
||||
if((channel_poll(channels[i],0)>0) || (channel_poll(channels[i],1)>0)){
|
||||
outchannels[j]=channels[i];
|
||||
j++;
|
||||
|
@ -34,25 +34,7 @@ MA 02111-1307, USA. */
|
||||
/* XXX include selected mac size */
|
||||
static int macsize=SHA_DIGEST_LEN;
|
||||
|
||||
/* completeread will read blocking until len bytes have been read */
|
||||
static int completeread(int fd, void *buffer, int len){
|
||||
int r;
|
||||
int total=0;
|
||||
int toread=len;
|
||||
if(fd<0)
|
||||
return SSH_ERROR;
|
||||
while((r=read(fd,buffer+total,toread))){
|
||||
if(r==-1)
|
||||
return SSH_ERROR;
|
||||
total += r;
|
||||
toread-=r;
|
||||
if(total==len)
|
||||
return len;
|
||||
if(r==0)
|
||||
return 0;
|
||||
}
|
||||
return total ; /* connection closed */
|
||||
}
|
||||
|
||||
|
||||
/* in nonblocking mode, socket_read will read as much as it can, and return */
|
||||
/* SSH_OK if it has read at least len bytes, otherwise, SSH_AGAIN. */
|
||||
@ -71,13 +53,12 @@ static int socket_read(SSH_SESSION *session,int len){
|
||||
return SSH_OK;
|
||||
if(session->blocking){
|
||||
buf=malloc(to_read);
|
||||
r=completeread(session->fd,buf,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");
|
||||
close(session->fd);
|
||||
session->fd=-1;
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive=0;
|
||||
session->data_except=1;
|
||||
return SSH_ERROR;
|
||||
@ -94,16 +75,14 @@ static int socket_read(SSH_SESSION *session,int len){
|
||||
return SSH_AGAIN;
|
||||
session->data_to_read=0;
|
||||
/* read as much as we can */
|
||||
if(session->fd>0)
|
||||
r=read(session->fd,buffer,sizeof(buffer));
|
||||
if(ssh_socket_is_open(session->socket))
|
||||
r=ssh_socket_read(session->socket,buffer,sizeof(buffer));
|
||||
else
|
||||
r=-1;
|
||||
if(r<=0){
|
||||
ssh_set_error(session,SSH_FATAL,
|
||||
(r==0)?"Connection closed by remote host" : "Error reading socket");
|
||||
if(session->fd>=0)
|
||||
close(session->fd);
|
||||
session->fd=-1;
|
||||
ssh_socket_close(session->socket);
|
||||
session->data_except=1;
|
||||
session->alive=0;
|
||||
return SSH_ERROR;
|
||||
@ -341,12 +320,13 @@ int packet_translate(SSH_SESSION *session){
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atomic_write(int fd, void *buffer, int len){
|
||||
// FIXME moves it in socket.c and rename it ssh_socket_completewrite()
|
||||
static int atomic_write(struct socket *s, void *buffer, int len){
|
||||
int written;
|
||||
if(fd<0)
|
||||
if(!ssh_socket_is_open(s))
|
||||
return SSH_ERROR;
|
||||
while(len >0) {
|
||||
written=write(fd,buffer,len);
|
||||
written=ssh_socket_write(s,buffer,len);
|
||||
if(written==0 || written==-1)
|
||||
return SSH_ERROR;
|
||||
len-=written;
|
||||
@ -361,14 +341,15 @@ static int packet_nonblocking_flush(SSH_SESSION *session){
|
||||
int except, can_write;
|
||||
int w;
|
||||
ssh_fd_poll(session,&can_write,&except); /* internally sets data_to_write */
|
||||
if(session->fd<0){
|
||||
if(!ssh_socket_is_open(session->socket)){
|
||||
session->alive=0;
|
||||
// FIXME use ssh_socket_get_errno
|
||||
ssh_set_error(session,SSH_FATAL,"Writing packet : error on socket (or connection closed): %s",strerror(errno));
|
||||
return SSH_ERROR;
|
||||
}
|
||||
while(session->data_to_write && buffer_get_rest_len(session->out_socket_buffer)>0){
|
||||
if(session->fd>=0){
|
||||
w=write(session->fd,buffer_get_rest(session->out_socket_buffer),
|
||||
if(ssh_socket_is_open(session->socket)){
|
||||
w=ssh_socket_write(session->socket,buffer_get_rest(session->out_socket_buffer),
|
||||
buffer_get_rest_len(session->out_socket_buffer));
|
||||
session->data_to_write=0;
|
||||
} else
|
||||
@ -377,8 +358,8 @@ static int packet_nonblocking_flush(SSH_SESSION *session){
|
||||
session->data_to_write=0;
|
||||
session->data_except=1;
|
||||
session->alive=0;
|
||||
close(session->fd);
|
||||
session->fd=-1;
|
||||
ssh_socket_close(session->socket);
|
||||
// FIXME use ssh_socket_get_errno()
|
||||
ssh_set_error(session,SSH_FATAL,"Writing packet : error on socket (or connection closed): %s",
|
||||
strerror(errno));
|
||||
return SSH_ERROR;
|
||||
@ -394,7 +375,7 @@ static int packet_nonblocking_flush(SSH_SESSION *session){
|
||||
|
||||
/* blocking packet flush */
|
||||
static int packet_blocking_flush(SSH_SESSION *session){
|
||||
if(session->fd<0) {
|
||||
if(!ssh_socket_is_open(session->socket)) {
|
||||
session->alive=0;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
@ -402,13 +383,13 @@ static int packet_blocking_flush(SSH_SESSION *session){
|
||||
return SSH_ERROR;
|
||||
if(buffer_get_rest(session->out_socket_buffer)==0)
|
||||
return SSH_OK;
|
||||
if(atomic_write(session->fd,buffer_get_rest(session->out_socket_buffer),
|
||||
if(atomic_write(session->socket,buffer_get_rest(session->out_socket_buffer),
|
||||
buffer_get_rest_len(session->out_socket_buffer))){
|
||||
session->data_to_write=0;
|
||||
session->data_except=1;
|
||||
session->alive=0;
|
||||
close(session->fd);
|
||||
session->fd=-1;
|
||||
ssh_socket_close(session->socket);
|
||||
// FIXME use the proper errno
|
||||
ssh_set_error(session,SSH_FATAL,"Writing packet : error on socket (or connection closed): %s",
|
||||
strerror(errno));
|
||||
return SSH_ERROR;
|
||||
@ -545,8 +526,7 @@ void packet_parse(SSH_SESSION *session){
|
||||
case SSH_MSG_DISCONNECT:
|
||||
ssh_say(2,"Received SSH_MSG_DISCONNECT\n");
|
||||
ssh_set_error(session,SSH_FATAL,"Received SSH_MSG_DISCONNECT");
|
||||
close(session->fd);
|
||||
session->fd=-1;
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive=0;
|
||||
return;
|
||||
case SSH_SMSG_STDOUT_DATA:
|
||||
@ -572,8 +552,7 @@ void packet_parse(SSH_SESSION *session){
|
||||
free(error_s);
|
||||
free(error);
|
||||
}
|
||||
close(session->fd);
|
||||
session->fd=-1;
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive=0;
|
||||
return;
|
||||
case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
|
||||
|
@ -148,7 +148,8 @@ SSH_SESSION *ssh_bind_accept(SSH_BIND *ssh_bind){
|
||||
session=ssh_new();
|
||||
session->server=1;
|
||||
session->version=2;
|
||||
session->fd=fd;
|
||||
session->socket=ssh_socket_new();
|
||||
ssh_socket_set_fd(session->socket,fd);
|
||||
session->options=ssh_options_copy(ssh_bind->options);
|
||||
session->dsa_key=dsa;
|
||||
session->rsa_key=rsa;
|
||||
|
@ -42,7 +42,7 @@ SSH_SESSION *ssh_new() {
|
||||
memset(session,0,sizeof(SSH_SESSION));
|
||||
session->next_crypto=crypto_new();
|
||||
session->maxchannel=FIRST_CHANNEL;
|
||||
session->fd=-1;
|
||||
session->socket=ssh_socket_new();
|
||||
session->alive=0;
|
||||
session->blocking=1;
|
||||
return session;
|
||||
@ -70,7 +70,8 @@ void ssh_cleanup(SSH_SESSION *session){
|
||||
crypto_free(session->current_crypto);
|
||||
if(session->next_crypto)
|
||||
crypto_free(session->next_crypto);
|
||||
|
||||
if(session->socket)
|
||||
ssh_socket_free(session->socket);
|
||||
// delete all channels
|
||||
while(session->channels)
|
||||
channel_free(session->channels);
|
||||
@ -101,10 +102,8 @@ void ssh_cleanup(SSH_SESSION *session){
|
||||
* \param session current ssh session
|
||||
*/
|
||||
void ssh_silent_disconnect(SSH_SESSION *session){
|
||||
if(session->fd>=0)
|
||||
close(session->fd);
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive=0;
|
||||
session->fd=-1;
|
||||
ssh_disconnect(session);
|
||||
}
|
||||
|
||||
@ -135,7 +134,7 @@ void ssh_set_blocking(SSH_SESSION *session,int blocking){
|
||||
* not connected
|
||||
*/
|
||||
int ssh_get_fd(SSH_SESSION *session){
|
||||
return session->fd;
|
||||
return ssh_socket_get_fd(session->socket);
|
||||
}
|
||||
|
||||
/** \brief say to the session it has data to read on the file descriptor without blocking
|
||||
|
150
libssh/socket.c
Обычный файл
150
libssh/socket.c
Обычный файл
@ -0,0 +1,150 @@
|
||||
/* socket.c */
|
||||
/* the Socket class */
|
||||
/*
|
||||
* Copyright 2008 Aris Adamantiadis
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA. */
|
||||
#include "libssh/priv.h"
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#ifdef _WIN_32
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
struct socket {
|
||||
int fd;
|
||||
int last_errno;
|
||||
};
|
||||
|
||||
/*
|
||||
* \internal
|
||||
* \brief creates a new Socket object
|
||||
*/
|
||||
struct socket *ssh_socket_new(){
|
||||
struct socket *s=malloc(sizeof(struct socket));
|
||||
s->fd=-1;
|
||||
s->last_errno=-1;
|
||||
return s;
|
||||
}
|
||||
|
||||
/* \internal
|
||||
* \brief Deletes a socket object
|
||||
*/
|
||||
void ssh_socket_free(struct socket *s){
|
||||
free(s);
|
||||
}
|
||||
|
||||
/* \internal
|
||||
* \brief closes a socket
|
||||
*/
|
||||
void ssh_socket_close(struct socket *s){
|
||||
if(ssh_socket_is_open(s)){
|
||||
#ifdef _WIN_32
|
||||
closesocket(s->fd);
|
||||
#else
|
||||
close(s->fd);
|
||||
#endif
|
||||
s->last_errno=errno;
|
||||
s->fd=-1;
|
||||
}
|
||||
}
|
||||
|
||||
/* \internal
|
||||
* \brief sets the file descriptor of the socket
|
||||
*/
|
||||
void ssh_socket_set_fd(struct socket *s, int fd){
|
||||
s->fd=fd;
|
||||
}
|
||||
|
||||
/* \internal
|
||||
* \brief returns the file descriptor of the socket
|
||||
*/
|
||||
int ssh_socket_get_fd(struct socket *s){
|
||||
return s->fd;
|
||||
}
|
||||
|
||||
/* \internal
|
||||
* \brief returns nonzero if the socket is open
|
||||
*/
|
||||
int ssh_socket_is_open(struct socket *s){
|
||||
return s->fd != -1;
|
||||
}
|
||||
|
||||
/* \internal
|
||||
* \brief read len bytes from socket into buffer
|
||||
*/
|
||||
int ssh_socket_read(struct socket *s, void *buffer, int len){
|
||||
int r=recv(s->fd,buffer,len,0);
|
||||
s->last_errno=errno;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* \internal
|
||||
* \brief writes len bytes from byffer to socket
|
||||
*/
|
||||
int ssh_socket_write(struct socket *s,const void *buffer, int len){
|
||||
int w=send(s->fd,buffer,len,0);
|
||||
s->last_errno=errno;
|
||||
return w;
|
||||
}
|
||||
|
||||
/* \internal
|
||||
* \brief returns nonzero if the current socket is in the fd_set
|
||||
*/
|
||||
int ssh_socket_fd_isset(struct socket *s, fd_set *set){
|
||||
if(s->fd==-1)
|
||||
return 0;
|
||||
return FD_ISSET(s->fd,set);
|
||||
}
|
||||
|
||||
/* \internal
|
||||
* \brief sets the current fd in a fd_set and updates the fd_max
|
||||
*/
|
||||
|
||||
void ssh_socket_fd_set(struct socket *s, fd_set *set, int *fd_max){
|
||||
if(s->fd==-1)
|
||||
return;
|
||||
FD_SET(s->fd,set);
|
||||
if(s->fd>= *fd_max){
|
||||
*fd_max=s->fd+1;
|
||||
}
|
||||
}
|
||||
|
||||
/* \internal
|
||||
* \brief reads blocking until len bytes have been read
|
||||
*/
|
||||
int ssh_socket_completeread(struct socket *s, void *buffer, int len){
|
||||
int r;
|
||||
int total=0;
|
||||
int toread=len;
|
||||
if(!ssh_socket_is_open(s))
|
||||
return SSH_ERROR;
|
||||
while((r=ssh_socket_read(s,buffer+total,toread))){
|
||||
if(r==-1)
|
||||
return SSH_ERROR;
|
||||
total += r;
|
||||
toread-=r;
|
||||
if(total==len)
|
||||
return len;
|
||||
if(r==0)
|
||||
return 0;
|
||||
}
|
||||
return total ; /* connection closed */
|
||||
}
|
Загрузка…
Ссылка в новой задаче
Block a user