1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-12-02 01:17:52 +03:00

Some work for async channel requests

This commit is contained in:
Aris Adamantiadis
2010-01-03 22:14:21 +01:00
parent 49de20aa5c
commit 648e5d62ba
3 changed files with 49 additions and 7 deletions

View File

@@ -23,6 +23,23 @@
#define CHANNELS_H_ #define CHANNELS_H_
#include "libssh/priv.h" #include "libssh/priv.h"
/** @internal
* Describes the different possible states in a
* outgoing (client) channel request
*/
enum ssh_channel_request_state_e {
/** No request has been made */
SSH_CHANNEL_REQ_STATE_NONE = 0,
/** A request has been made and answer is pending */
SSH_CHANNEL_REQ_STATE_PENDING,
/** A request has been replied and accepted */
SSH_CHANNEL_REQ_STATE_ACCEPTED,
/** A request has been replied and refused */
SSH_CHANNEL_REQ_STATE_DENIED,
/** A request has been replied and an error happend */
SSH_CHANNEL_REQ_STATE_ERROR
};
struct ssh_channel_struct { struct ssh_channel_struct {
struct ssh_channel_struct *prev; struct ssh_channel_struct *prev;
struct ssh_channel_struct *next; struct ssh_channel_struct *next;
@@ -44,10 +61,13 @@ struct ssh_channel_struct {
int version; int version;
int blocking; int blocking;
int exit_status; int exit_status;
enum ssh_channel_request_state_e request_state;
}; };
SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf); SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf);
SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail); SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail);
SSH_PACKET_CALLBACK(ssh_packet_channel_success);
SSH_PACKET_CALLBACK(ssh_packet_channel_failure);
void channel_handle(ssh_session session, int type); void channel_handle(ssh_session session, int type);
ssh_channel channel_new(ssh_session session); ssh_channel channel_new(ssh_session session);

View File

@@ -172,6 +172,16 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){
return 0; return 0;
} }
/** @internal
* @brief open a channel by sending a SSH_OPEN_CHANNEL message and
* waiting reply.
* @param channel the current channel.
* @param type_c C string describing kind of channel (e.g. "exec").
* @param window receiving window of the channel. The window is the
* maximum size of data that can stay in buffers and network.
* @param maxpacket maximum packet size allowed (like MTU).
* @param payload buffer containing additionnal payload for the query.
*/
static int channel_open(ssh_channel channel, const char *type_c, int window, static int channel_open(ssh_channel channel, const char *type_c, int window,
int maxpacket, ssh_buffer payload) { int maxpacket, ssh_buffer payload) {
ssh_session session = channel->session; ssh_session session = channel->session;
@@ -179,12 +189,11 @@ static int channel_open(ssh_channel channel, const char *type_c, int window,
uint32_t tmp = 0; uint32_t tmp = 0;
enter_function(); enter_function();
channel->local_channel = ssh_channel_new_id(session); channel->local_channel = ssh_channel_new_id(session);
channel->local_maxpacket = maxpacket; channel->local_maxpacket = maxpacket;
channel->local_window = window; channel->local_window = window;
ssh_log(session, SSH_LOG_RARE, ssh_log(session, SSH_LOG_PROTOCOL,
"Creating a channel %d with %d window and %d max packet", "Creating a channel %d with %d window and %d max packet",
channel->local_channel, window, maxpacket); channel->local_channel, window, maxpacket);
@@ -218,7 +227,7 @@ static int channel_open(ssh_channel channel, const char *type_c, int window,
return -1; return -1;
} }
ssh_log(session, SSH_LOG_RARE, ssh_log(session, SSH_LOG_PACKET,
"Sent a SSH_MSG_CHANNEL_OPEN type %s for channel %d", "Sent a SSH_MSG_CHANNEL_OPEN type %s for channel %d",
type_c, channel->local_channel); type_c, channel->local_channel);
@@ -1066,6 +1075,14 @@ void channel_set_blocking(ssh_channel channel, int blocking) {
channel->blocking = (blocking == 0 ? 0 : 1); channel->blocking = (blocking == 0 ? 0 : 1);
} }
SSH_PACKET_CALLBACK(ssh_packet_channel_success){
return SSH_PACKET_USED;
}
SSH_PACKET_CALLBACK(ssh_packet_channel_failure){
return SSH_PACKET_USED;
}
static int channel_request(ssh_channel channel, const char *request, static int channel_request(ssh_channel channel, const char *request,
ssh_buffer buffer, int reply) { ssh_buffer buffer, int reply) {
ssh_session session = channel->session; ssh_session session = channel->session;
@@ -1073,6 +1090,11 @@ static int channel_request(ssh_channel channel, const char *request,
int rc = SSH_ERROR; int rc = SSH_ERROR;
enter_function(); enter_function();
if(channel->request_state != SSH_CHANNEL_REQ_STATE_NONE){
ssh_set_error(session,SSH_REQUEST_DENIED,"channel_request_* used in incorrect state");
leave_function();
return SSH_ERROR;
}
req = string_from_char(request); req = string_from_char(request);
if (req == NULL) { if (req == NULL) {
@@ -1093,13 +1115,13 @@ static int channel_request(ssh_channel channel, const char *request,
goto error; goto error;
} }
} }
channel->request_state = SSH_CHANNEL_REQ_STATE_PENDING;
if (packet_send(session) != SSH_OK) { if (packet_send(session) != SSH_OK) {
leave_function(); leave_function();
return rc; return rc;
} }
ssh_log(session, SSH_LOG_RARE, ssh_log(session, SSH_LOG_PACKET,
"Sent a SSH_MSG_CHANNEL_REQUEST %s", request); "Sent a SSH_MSG_CHANNEL_REQUEST %s", request);
if (reply == 0) { if (reply == 0) {
leave_function(); leave_function();

View File

@@ -90,8 +90,8 @@ ssh_packet_callback default_packet_handlers[]= {
channel_rcv_eof, //#define SSH2_MSG_CHANNEL_EOF 96 channel_rcv_eof, //#define SSH2_MSG_CHANNEL_EOF 96
channel_rcv_close, //#define SSH2_MSG_CHANNEL_CLOSE 97 channel_rcv_close, //#define SSH2_MSG_CHANNEL_CLOSE 97
channel_rcv_request, //#define SSH2_MSG_CHANNEL_REQUEST 98 channel_rcv_request, //#define SSH2_MSG_CHANNEL_REQUEST 98
NULL, //#define SSH2_MSG_CHANNEL_SUCCESS 99 ssh_packet_channel_success, //#define SSH2_MSG_CHANNEL_SUCCESS 99
NULL, //#define SSH2_MSG_CHANNEL_FAILURE 100 ssh_packet_channel_failure, //#define SSH2_MSG_CHANNEL_FAILURE 100
}; };
/* XXX include selected mac size */ /* XXX include selected mac size */