summaryrefslogtreecommitdiffstats
path: root/libssh/channels.c
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2009-11-27 20:42:43 +0100
committerAris Adamantiadis <aris@0xbadc0de.be>2009-11-27 20:42:43 +0100
commit91bb1b2de66a62723e0cbdda02e455f728522181 (patch)
tree2609d87fcf24107e3507237ec22a80da37994f7c /libssh/channels.c
parent810adadf2e8a5c68460b864994055ece6f1a3096 (diff)
downloadlibssh-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.c308
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,