diff options
author | Aris Adamantiadis <aris@0xbadc0de.be> | 2009-11-27 20:42:43 +0100 |
---|---|---|
committer | Aris Adamantiadis <aris@0xbadc0de.be> | 2009-11-27 20:42:43 +0100 |
commit | 91bb1b2de66a62723e0cbdda02e455f728522181 (patch) | |
tree | 2609d87fcf24107e3507237ec22a80da37994f7c /libssh/channels.c | |
parent | 810adadf2e8a5c68460b864994055ece6f1a3096 (diff) | |
download | libssh-91bb1b2de66a62723e0cbdda02e455f728522181.tar.gz libssh-91bb1b2de66a62723e0cbdda02e455f728522181.tar.xz libssh-91bb1b2de66a62723e0cbdda02e455f728522181.zip |
Squashed commit of the following:
commit 43fad8dfd977637c31fade76ace2905f6528c3bc
Author: Aris Adamantiadis <aris@0xbadc0de.be>
Date: Fri Nov 27 18:39:06 2009 +0100
adaptation to the new ssh_poll_handle object name
commit 1e5e6ac4605adf10d437d04f0fd4b7e66024853c
Merge: 3fd92a0... 810adad...
Author: Aris Adamantiadis <aris@0xbadc0de.be>
Date: Fri Nov 27 18:33:06 2009 +0100
Merge branch 'master' into badcode/libssh_async
commit 3fd92a08eb74b1447a9ff4ca4e1d137475c62cc6
Author: Aris Adamantiadis <aris@0xbadc0de.be>
Date: Mon Nov 2 14:25:46 2009 +0100
Compiles again
commit 8910d7b9692418c9ccea0234f6d49674d238dc16
Merge: e83f1b5... cce34a6...
Author: Aris Adamantiadis <aris@0xbadc0de.be>
Date: Mon Nov 2 12:47:34 2009 +0100
Merge branch 'master' into libssh_async
Very big merge !
Conflicts:
include/libssh/callbacks.h
include/libssh/priv.h
libssh/channels.c
libssh/messages.c
libssh/packet.c
libssh/server.c
libssh/session.c
libssh/socket.c
commit e83f1b593219e183082b015315f09bfe95a29cfc
Author: Aris Adamantiadis <aris@0xbadc0de.be>
Date: Mon Nov 2 12:07:01 2009 +0100
rename callback.h
commit dffa7b730e8f39e2198de18ab69a8e57bef95e58
Merge: 5a8b748... de8808c...
Author: Aris Adamantiadis <aris@0xbadc0de.be>
Date: Tue Sep 15 10:50:07 2009 +0200
Merge branch 'master' of git://git.libssh.org/projects/libssh/libssh into libssh_async
commit 5a8b7484f36599d28f2c0c14a23b76bfc7257638
Author: Aris Adamantiadis <aris@0xbadc0de.be>
Date: Sun Sep 13 12:55:18 2009 +0200
More updates to callback system
commit 18620c20d5e4e62107093f7fd330e553493253fa
Author: Aris Adamantiadis <aris@0xbadc0de.be>
Date: Sat Sep 12 22:26:52 2009 +0200
Same thing with channel_rcv_data
commit fc4a56f6726e409a5866272923f1cbebfc821af3
Author: Aris Adamantiadis <aris@0xbadc0de.be>
Date: Sat Sep 12 22:17:45 2009 +0200
added a few packet handlers for channels
commit 4b6bb4fd00b10cf1321a764126f277ab204bffe3
Author: Aris Adamantiadis <aris@0xbadc0de.be>
Date: Fri Sep 11 23:15:25 2009 +0300
sample packet handlers + bugfixes
commit 2784d09d6dec0a8f868912d14f90d860233b3f82
Author: Aris Adamantiadis <aris@0xbadc0de.be>
Date: Fri Sep 11 20:30:50 2009 +0300
Packet callbacks nearly finished
Need tests and implementation of some packet callbacks
commit cd3ea43f20c9ae2f54576ca98a0ea75c5d4299d3
Author: Aris Adamantiadis <aris@0xbadc0de.be>
Date: Thu Sep 10 12:46:02 2009 +0300
First step of async packet handling
The socket to packet handler is nearly done (needs testing)
I still need to define the interface for callbacks.
commit 487f4d2a900a5fe3b90ceda4460ab7d38d7ad722
Author: Aris Adamantiadis <aris@0xbadc0de.be>
Date: Tue Sep 8 23:24:09 2009 +0300
Almost complete socket callback system
Finished the callback function so it bufferizes data when
callee does not use it.
Flushes the buffer automaticaly after a ssh_socket_nonblocking_flush
commit 23571f22fac9e40c855dfa99569bba181a39648b
Author: Aris Adamantiadis <aris@0xbadc0de.be>
Date: Tue Sep 8 22:22:32 2009 +0300
First draft of a callback system
Diffstat (limited to 'libssh/channels.c')
-rw-r--r-- | libssh/channels.c | 308 |
1 files changed, 159 insertions, 149 deletions
diff --git a/libssh/channels.c b/libssh/channels.c index 13ea25f..8af3a03 100644 --- a/libssh/channels.c +++ b/libssh/channels.c @@ -314,11 +314,13 @@ static ssh_channel channel_from_msg(ssh_session session) { return channel; } -static void channel_rcv_change_window(ssh_session session) { +int channel_rcv_change_window(ssh_session session, void *user, u_int8_t type, ssh_buffer packet) { ssh_channel channel; uint32_t bytes; int rc; - + (void)user; + (void)type; + (void)packet; enter_function(); channel = channel_from_msg(session); @@ -331,7 +333,7 @@ static void channel_rcv_change_window(ssh_session session) { ssh_log(session, SSH_LOG_PACKET, "Error getting a window adjust message: invalid packet"); leave_function(); - return; + return SSH_PACKET_USED; } bytes = ntohl(bytes); @@ -345,22 +347,29 @@ static void channel_rcv_change_window(ssh_session session) { channel->remote_window += bytes; leave_function(); + return SSH_PACKET_USED; } /* is_stderr is set to 1 if the data are extended, ie stderr */ -static void channel_rcv_data(ssh_session session,int is_stderr) { +int channel_rcv_data(ssh_session session, void *user, u_int8_t type, ssh_buffer packet) { ssh_channel channel; ssh_string str; size_t len; - + int is_stderr; + (void)user; + (void)packet; enter_function(); + if(type==SSH2_MSG_CHANNEL_DATA) + is_stderr=0; + else + is_stderr=1; channel = channel_from_msg(session); if (channel == NULL) { ssh_log(session, SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session)); leave_function(); - return; + return SSH_PACKET_USED; } if (is_stderr) { @@ -373,7 +382,7 @@ static void channel_rcv_data(ssh_session session,int is_stderr) { if (str == NULL) { ssh_log(session, SSH_LOG_PACKET, "Invalid data packet!"); leave_function(); - return; + return SSH_PACKET_USED; } len = string_len(str); @@ -396,7 +405,7 @@ static void channel_rcv_data(ssh_session session,int is_stderr) { is_stderr) < 0) { string_free(str); leave_function(); - return; + return SSH_PACKET_USED; } if (len <= channel->local_window) { @@ -412,18 +421,21 @@ static void channel_rcv_data(ssh_session session,int is_stderr) { string_free(str); leave_function(); + return SSH_PACKET_USED; } -static void channel_rcv_eof(ssh_session session) { +int channel_rcv_eof(ssh_session session, void *user, u_int8_t type, ssh_buffer packet) { ssh_channel channel; - + (void)user; + (void)type; + (void)packet; enter_function(); channel = channel_from_msg(session); if (channel == NULL) { ssh_log(session, SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session)); leave_function(); - return; + return SSH_PACKET_USED; } ssh_log(session, SSH_LOG_PACKET, @@ -434,134 +446,142 @@ static void channel_rcv_eof(ssh_session session) { channel->remote_eof = 1; leave_function(); + return SSH_PACKET_USED; } -static void channel_rcv_close(ssh_session session) { - ssh_channel channel; - - enter_function(); - - channel = channel_from_msg(session); - if (channel == NULL) { - ssh_log(session, SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session)); - leave_function(); - return; - } - - ssh_log(session, SSH_LOG_PACKET, - "Received close on channel (%d:%d)", - channel->local_channel, - channel->remote_channel); - - if ((channel->stdout_buffer && - buffer_get_rest_len(channel->stdout_buffer) > 0) || - (channel->stderr_buffer && - buffer_get_rest_len(channel->stderr_buffer) > 0)) { - channel->delayed_close = 1; - } else { - channel->open = 0; - } - - if (channel->remote_eof == 0) { - ssh_log(session, SSH_LOG_PACKET, - "Remote host not polite enough to send an eof before close"); - } - channel->remote_eof = 1; - /* - * The remote eof doesn't break things if there was still data into read - * buffer because the eof is ignored until the buffer is empty. - */ - - leave_function(); +int channel_rcv_close(ssh_session session, void *user, u_int8_t type, ssh_buffer packet) { + ssh_channel channel; + (void)user; + (void)type; + (void)packet; + enter_function(); + + channel = channel_from_msg(session); + if (channel == NULL) { + ssh_log(session, SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session)); + leave_function(); + return SSH_PACKET_USED; + } + + ssh_log(session, SSH_LOG_PACKET, + "Received close on channel (%d:%d)", + channel->local_channel, + channel->remote_channel); + + if ((channel->stdout_buffer && + buffer_get_rest_len(channel->stdout_buffer) > 0) || + (channel->stderr_buffer && + buffer_get_rest_len(channel->stderr_buffer) > 0)) { + channel->delayed_close = 1; + } else { + channel->open = 0; + } + + if (channel->remote_eof == 0) { + ssh_log(session, SSH_LOG_PACKET, + "Remote host not polite enough to send an eof before close"); + } + channel->remote_eof = 1; + /* + * The remote eof doesn't break things if there was still data into read + * buffer because the eof is ignored until the buffer is empty. + */ + + leave_function(); + return SSH_PACKET_USED; } -static void channel_rcv_request(ssh_session session) { - ssh_channel channel; - ssh_string request_s; - char *request; - uint32_t status; - uint32_t startpos = session->in_buffer->pos; - - enter_function(); - - channel = channel_from_msg(session); - if (channel == NULL) { - ssh_log(session, SSH_LOG_FUNCTIONS,"%s", ssh_get_error(session)); - leave_function(); - return; - } - - request_s = buffer_get_ssh_string(session->in_buffer); - if (request_s == NULL) { - ssh_log(session, SSH_LOG_PACKET, "Invalid MSG_CHANNEL_REQUEST"); - leave_function(); - return; - } - - request = string_to_char(request_s); - string_free(request_s); - if (request == NULL) { - leave_function(); - return; - } - - buffer_get_u8(session->in_buffer, (uint8_t *) &status); - - if (strcmp(request,"exit-status") == 0) { - SAFE_FREE(request); - ssh_log(session, SSH_LOG_PACKET, "received exit-status"); - buffer_get_u32(session->in_buffer, &status); - channel->exit_status = ntohl(status); - - leave_function(); - return ; - } - - if (strcmp(request, "exit-signal") == 0) { - const char *core = "(core dumped)"; - ssh_string signal_s; - char *signal; - uint8_t i; - - SAFE_FREE(request); - - signal_s = buffer_get_ssh_string(session->in_buffer); - if (signal_s == NULL) { - ssh_log(session, SSH_LOG_PACKET, "Invalid MSG_CHANNEL_REQUEST"); - leave_function(); - return; - } - - signal = string_to_char(signal_s); - string_free(signal_s); - if (signal == NULL) { - leave_function(); - return; - } - - buffer_get_u8(session->in_buffer, &i); - if (i == 0) { - core = ""; - } - - ssh_log(session, SSH_LOG_PACKET, - "Remote connection closed by signal SIG %s %s", signal, core); - SAFE_FREE(signal); - - leave_function(); - return; - } - - /* TODO call message_handle since it handles channel requests as messages */ - /* *but* reset buffer before !! */ - - session->in_buffer->pos = startpos; - message_handle(session, SSH2_MSG_CHANNEL_REQUEST); - - ssh_log(session, SSH_LOG_PACKET, "Unknown request %s", request); - SAFE_FREE(request); - - leave_function(); +int channel_rcv_request(ssh_session session, void *user, u_int8_t type, ssh_buffer packet) { + ssh_channel channel; + ssh_string request_s; + char *request; + uint32_t status; + uint32_t startpos = session->in_buffer->pos; + (void)user; + (void)type; + (void)packet; + + enter_function(); + + channel = channel_from_msg(session); + if (channel == NULL) { + ssh_log(session, SSH_LOG_FUNCTIONS,"%s", ssh_get_error(session)); + leave_function(); + return SSH_PACKET_USED; + } + + request_s = buffer_get_ssh_string(session->in_buffer); + if (request_s == NULL) { + ssh_log(session, SSH_LOG_PACKET, "Invalid MSG_CHANNEL_REQUEST"); + leave_function(); + return SSH_PACKET_USED; + } + + request = string_to_char(request_s); + string_free(request_s); + if (request == NULL) { + leave_function(); + return SSH_PACKET_USED; + } + + buffer_get_u8(session->in_buffer, (uint8_t *) &status); + + if (strcmp(request,"exit-status") == 0) { + SAFE_FREE(request); + ssh_log(session, SSH_LOG_PACKET, "received exit-status"); + buffer_get_u32(session->in_buffer, &status); + channel->exit_status = ntohl(status); + + leave_function(); + return SSH_PACKET_USED; + } + + if (strcmp(request, "exit-signal") == 0) { + const char *core = "(core dumped)"; + ssh_string signal_s; + char *signal; + uint8_t i; + + SAFE_FREE(request); + + signal_s = buffer_get_ssh_string(session->in_buffer); + if (signal_s == NULL) { + ssh_log(session, SSH_LOG_PACKET, "Invalid MSG_CHANNEL_REQUEST"); + leave_function(); + return SSH_PACKET_USED; + } + + signal = string_to_char(signal_s); + string_free(signal_s); + if (signal == NULL) { + leave_function(); + return SSH_PACKET_USED; + } + + buffer_get_u8(session->in_buffer, &i); + if (i == 0) { + core = ""; + } + + ssh_log(session, SSH_LOG_PACKET, + "Remote connection closed by signal SIG %s %s", signal, core); + SAFE_FREE(signal); + + leave_function(); + return SSH_PACKET_USED; + } + + /* TODO call message_handle since it handles channel requests as messages */ + /* *but* reset buffer before !! */ + + session->in_buffer->pos = startpos; + message_handle(session, NULL, SSH2_MSG_CHANNEL_REQUEST, session->in_buffer); + + ssh_log(session, SSH_LOG_PACKET, "Unknown request %s", request); + SAFE_FREE(request); + + leave_function(); + return SSH_PACKET_USED; } /* @@ -575,22 +595,12 @@ void channel_handle(ssh_session session, int type){ switch(type) { case SSH2_MSG_CHANNEL_WINDOW_ADJUST: - channel_rcv_change_window(session); - break; + case SSH2_MSG_CHANNEL_REQUEST: + case SSH2_MSG_CHANNEL_CLOSE: + case SSH2_MSG_CHANNEL_EOF: case SSH2_MSG_CHANNEL_DATA: - channel_rcv_data(session,0); - break; case SSH2_MSG_CHANNEL_EXTENDED_DATA: - channel_rcv_data(session,1); - break; - case SSH2_MSG_CHANNEL_EOF: - channel_rcv_eof(session); - break; - case SSH2_MSG_CHANNEL_CLOSE: - channel_rcv_close(session); - break; - case SSH2_MSG_CHANNEL_REQUEST: - channel_rcv_request(session); + ssh_packet_process(session, type); break; default: ssh_log(session, SSH_LOG_FUNCTIONS, |