move over lots of code to the _libssh2_list_* functions
and I fixed a few minor bugs at the same time
Этот коммит содержится в:
родитель
a871f0b214
Коммит
d8b6f3c7b8
154
src/channel.c
154
src/channel.c
@ -61,13 +61,13 @@ _libssh2_channel_nextid(LIBSSH2_SESSION * session)
|
||||
unsigned long id = session->next_channel;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
|
||||
channel = session->channels.head;
|
||||
channel = _libssh2_list_first(&session->channels);
|
||||
|
||||
while (channel) {
|
||||
if (channel->local.id > id) {
|
||||
id = channel->local.id;
|
||||
}
|
||||
channel = channel->next;
|
||||
channel = _libssh2_list_next(&channel->node);
|
||||
}
|
||||
|
||||
/* This is a shortcut to avoid waiting for close packets on channels we've
|
||||
@ -94,16 +94,21 @@ _libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long channel_id)
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
LIBSSH2_LISTENER *l;
|
||||
|
||||
for(channel = session->channels.head; channel; channel = channel->next) {
|
||||
for(channel = _libssh2_list_first(&session->channels);
|
||||
channel;
|
||||
channel = _libssh2_list_next(&channel->node)) {
|
||||
if (channel->local.id == channel_id)
|
||||
return channel;
|
||||
}
|
||||
|
||||
/* We didn't find the channel in the session, let's then check its
|
||||
listeners... */
|
||||
listeners since each listener may have its own set of pending channels
|
||||
*/
|
||||
for(l = _libssh2_list_first(&session->listeners); l;
|
||||
l = _libssh2_list_next(&l->node)) {
|
||||
for(channel = l->queue; channel; channel = channel->next) {
|
||||
for(channel = _libssh2_list_first(&l->queue);
|
||||
channel;
|
||||
channel = _libssh2_list_next(&channel->node)) {
|
||||
if (channel->local.id == channel_id)
|
||||
return channel;
|
||||
}
|
||||
@ -112,20 +117,6 @@ _libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long channel_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define CHANNEL_ADD(session, channel) \
|
||||
{ \
|
||||
if ((session)->channels.tail) { \
|
||||
(session)->channels.tail->next = (channel); \
|
||||
(channel)->prev = (session)->channels.tail; \
|
||||
} else { \
|
||||
(session)->channels.head = (channel); \
|
||||
(channel)->prev = NULL; \
|
||||
} \
|
||||
(channel)->next = NULL; \
|
||||
(session)->channels.tail = (channel); \
|
||||
(channel)->session = (session); \
|
||||
}
|
||||
|
||||
/*
|
||||
* _libssh2_channel_open
|
||||
*
|
||||
@ -188,8 +179,10 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
|
||||
session->open_channel->remote.window_size = window_size;
|
||||
session->open_channel->remote.window_size_initial = window_size;
|
||||
session->open_channel->remote.packet_size = packet_size;
|
||||
session->open_channel->session = session;
|
||||
|
||||
CHANNEL_ADD(session, session->open_channel);
|
||||
_libssh2_list_add(&session->channels,
|
||||
&session->open_channel->node);
|
||||
|
||||
s = session->open_packet =
|
||||
LIBSSH2_ALLOC(session, session->open_packet_len);
|
||||
@ -299,18 +292,7 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
|
||||
unsigned char channel_id[4];
|
||||
LIBSSH2_FREE(session, session->open_channel->channel_type);
|
||||
|
||||
if (session->open_channel->next) {
|
||||
session->open_channel->next->prev = session->open_channel->prev;
|
||||
}
|
||||
if (session->open_channel->prev) {
|
||||
session->open_channel->prev->next = session->open_channel->next;
|
||||
}
|
||||
if (session->channels.head == session->open_channel) {
|
||||
session->channels.head = session->open_channel->next;
|
||||
}
|
||||
if (session->channels.tail == session->open_channel) {
|
||||
session->channels.tail = session->open_channel->prev;
|
||||
}
|
||||
_libssh2_list_remove(&session->open_channel->node);
|
||||
|
||||
/* Clear out packets meant for this channel */
|
||||
_libssh2_htonu32(channel_id, session->open_channel->local.id);
|
||||
@ -639,7 +621,7 @@ libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host,
|
||||
static int channel_forward_cancel(LIBSSH2_LISTENER *listener)
|
||||
{
|
||||
LIBSSH2_SESSION *session = listener->session;
|
||||
LIBSSH2_CHANNEL *queued = listener->queue;
|
||||
LIBSSH2_CHANNEL *queued;
|
||||
unsigned char *packet, *s;
|
||||
unsigned long host_len = strlen(listener->host);
|
||||
/* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) +
|
||||
@ -699,8 +681,9 @@ static int channel_forward_cancel(LIBSSH2_LISTENER *listener)
|
||||
listener->chanFwdCncl_state = libssh2_NB_state_sent;
|
||||
}
|
||||
|
||||
queued = _libssh2_list_first(&listener->queue);
|
||||
while (queued) {
|
||||
LIBSSH2_CHANNEL *next = queued->next;
|
||||
LIBSSH2_CHANNEL *next = _libssh2_list_next(&queued->node);
|
||||
|
||||
rc = libssh2_channel_free(queued);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
@ -755,28 +738,17 @@ channel_forward_accept(LIBSSH2_LISTENER *listener)
|
||||
}
|
||||
} while (rc > 0);
|
||||
|
||||
if (listener->queue) {
|
||||
LIBSSH2_SESSION *session = listener->session;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
if (_libssh2_list_first(&listener->queue)) {
|
||||
LIBSSH2_CHANNEL *channel = _libssh2_list_first(&listener->queue);
|
||||
|
||||
channel = listener->queue;
|
||||
/* detach channel from listener's queue */
|
||||
_libssh2_list_remove(&channel->node);
|
||||
|
||||
listener->queue = listener->queue->next;
|
||||
if (listener->queue) {
|
||||
listener->queue->prev = NULL;
|
||||
}
|
||||
|
||||
channel->prev = NULL;
|
||||
channel->next = session->channels.head;
|
||||
session->channels.head = channel;
|
||||
|
||||
if (channel->next) {
|
||||
channel->next->prev = channel;
|
||||
} else {
|
||||
session->channels.tail = channel;
|
||||
}
|
||||
listener->queue_size--;
|
||||
|
||||
/* add channel to session's channel list */
|
||||
_libssh2_list_add(&channel->session->channels, &channel->node);
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
@ -1455,14 +1427,14 @@ libssh2_channel_set_blocking(LIBSSH2_CHANNEL * channel, int blocking)
|
||||
int
|
||||
_libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
|
||||
{
|
||||
LIBSSH2_PACKET *packet = channel->session->packets.head;
|
||||
|
||||
if (channel->flush_state == libssh2_NB_state_idle) {
|
||||
LIBSSH2_PACKET *packet =
|
||||
_libssh2_list_first(&channel->session->packets);
|
||||
channel->flush_refund_bytes = 0;
|
||||
channel->flush_flush_bytes = 0;
|
||||
|
||||
while (packet) {
|
||||
LIBSSH2_PACKET *next = packet->next;
|
||||
LIBSSH2_PACKET *next = _libssh2_list_next(&packet->node);
|
||||
unsigned char packet_type = packet->data[0];
|
||||
|
||||
if (((packet_type == SSH_MSG_CHANNEL_DATA)
|
||||
@ -1470,9 +1442,8 @@ _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
|
||||
&& (_libssh2_ntohu32(packet->data + 1) == channel->local.id)) {
|
||||
/* It's our channel at least */
|
||||
long packet_stream_id =
|
||||
(packet_type ==
|
||||
SSH_MSG_CHANNEL_DATA) ? 0 : _libssh2_ntohu32(packet->data +
|
||||
5);
|
||||
(packet_type == SSH_MSG_CHANNEL_DATA) ? 0 :
|
||||
_libssh2_ntohu32(packet->data + 5);
|
||||
if ((streamid == LIBSSH2_CHANNEL_FLUSH_ALL)
|
||||
|| ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)
|
||||
&& ((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA)
|
||||
@ -1492,16 +1463,9 @@ _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
|
||||
channel->flush_flush_bytes += bytes_to_flush;
|
||||
|
||||
LIBSSH2_FREE(channel->session, packet->data);
|
||||
if (packet->prev) {
|
||||
packet->prev->next = packet->next;
|
||||
} else {
|
||||
channel->session->packets.head = packet->next;
|
||||
}
|
||||
if (packet->next) {
|
||||
packet->next->prev = packet->prev;
|
||||
} else {
|
||||
channel->session->packets.tail = packet->prev;
|
||||
}
|
||||
|
||||
/* remove this packet from the parent's list */
|
||||
_libssh2_list_remove(&packet->node);
|
||||
LIBSSH2_FREE(channel->session, packet);
|
||||
}
|
||||
}
|
||||
@ -1754,6 +1718,8 @@ static ssize_t channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
int bytes_read = 0;
|
||||
int bytes_want;
|
||||
int unlink_packet;
|
||||
LIBSSH2_PACKET *read_packet;
|
||||
LIBSSH2_PACKET *read_next;
|
||||
|
||||
if (channel->read_state == libssh2_NB_state_idle) {
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||
@ -1785,9 +1751,8 @@ static ssize_t channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
|
||||
rc = 0;
|
||||
|
||||
channel->read_packet = session->packets.head;
|
||||
while (channel->read_packet &&
|
||||
(bytes_read < (int) buflen)) {
|
||||
read_packet = _libssh2_list_first(&session->packets);
|
||||
while (read_packet && (bytes_read < (int) buflen)) {
|
||||
/* previously this loop condition also checked for
|
||||
!channel->remote.close but we cannot let it do this:
|
||||
|
||||
@ -1796,10 +1761,10 @@ static ssize_t channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
makes us flush buffers prematurely and loose data.
|
||||
*/
|
||||
|
||||
LIBSSH2_PACKET *readpkt = channel->read_packet;
|
||||
LIBSSH2_PACKET *readpkt = read_packet;
|
||||
|
||||
/* In case packet gets destroyed during this iteration */
|
||||
channel->read_next = readpkt->next;
|
||||
read_next = _libssh2_list_next(&readpkt->node);
|
||||
|
||||
channel->read_local_id =
|
||||
_libssh2_ntohu32(readpkt->data + 1);
|
||||
@ -1850,23 +1815,16 @@ static ssize_t channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
|
||||
/* if drained, remove from list */
|
||||
if (unlink_packet) {
|
||||
if (readpkt->prev) {
|
||||
readpkt->prev->next = readpkt->next;
|
||||
} else {
|
||||
session->packets.head = readpkt->next;
|
||||
}
|
||||
if (readpkt->next) {
|
||||
readpkt->next->prev = readpkt->prev;
|
||||
} else {
|
||||
session->packets.tail = readpkt->prev;
|
||||
}
|
||||
/* detach readpkt from session->packets list */
|
||||
_libssh2_list_remove(&readpkt->node);
|
||||
|
||||
LIBSSH2_FREE(session, readpkt->data);
|
||||
LIBSSH2_FREE(session, readpkt);
|
||||
}
|
||||
}
|
||||
|
||||
/* check the next struct in the chain */
|
||||
channel->read_packet = channel->read_next;
|
||||
read_packet = read_next;
|
||||
}
|
||||
|
||||
if (bytes_read == 0) {
|
||||
@ -1949,9 +1907,9 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
|
||||
LIBSSH2_PACKET *read_packet;
|
||||
uint32_t read_local_id;
|
||||
|
||||
if ((read_packet = session->packets.head) == NULL) {
|
||||
read_packet = _libssh2_list_first(&session->packets);
|
||||
if (read_packet == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (read_packet) {
|
||||
read_local_id = _libssh2_ntohu32(read_packet->data + 1);
|
||||
@ -1980,7 +1938,7 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
|
||||
{
|
||||
return (read_packet->data_len - read_packet->data_head);
|
||||
}
|
||||
read_packet = read_packet->next;
|
||||
read_packet = _libssh2_list_next(&read_packet->node);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -2205,7 +2163,7 @@ LIBSSH2_API int
|
||||
libssh2_channel_eof(LIBSSH2_CHANNEL * channel)
|
||||
{
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
LIBSSH2_PACKET *packet = session->packets.head;
|
||||
LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
|
||||
|
||||
while (packet) {
|
||||
if (((packet->data[0] == SSH_MSG_CHANNEL_DATA)
|
||||
@ -2214,7 +2172,7 @@ libssh2_channel_eof(LIBSSH2_CHANNEL * channel)
|
||||
/* There's data waiting to be read yet, mask the EOF status */
|
||||
return 0;
|
||||
}
|
||||
packet = packet->next;
|
||||
packet = _libssh2_list_next(&packet->node);
|
||||
}
|
||||
|
||||
return channel->remote.eof;
|
||||
@ -2473,17 +2431,8 @@ int _libssh2_channel_free(LIBSSH2_CHANNEL *channel)
|
||||
LIBSSH2_FREE(session, channel->channel_type);
|
||||
}
|
||||
|
||||
/* Unlink from channel brigade */
|
||||
if (channel->prev) {
|
||||
channel->prev->next = channel->next;
|
||||
} else {
|
||||
session->channels.head = channel->next;
|
||||
}
|
||||
if (channel->next) {
|
||||
channel->next->prev = channel->prev;
|
||||
} else {
|
||||
session->channels.tail = channel->prev;
|
||||
}
|
||||
/* Unlink from channel list */
|
||||
_libssh2_list_remove(&channel->node);
|
||||
|
||||
/*
|
||||
* Make sure all memory used in the state variables are free
|
||||
@ -2544,7 +2493,8 @@ libssh2_channel_window_read_ex(LIBSSH2_CHANNEL * channel,
|
||||
|
||||
if (read_avail) {
|
||||
unsigned long bytes_queued = 0;
|
||||
LIBSSH2_PACKET *packet = channel->session->packets.head;
|
||||
LIBSSH2_PACKET *packet =
|
||||
_libssh2_list_first(&channel->session->packets);
|
||||
|
||||
while (packet) {
|
||||
unsigned char packet_type = packet->data[0];
|
||||
@ -2555,7 +2505,7 @@ libssh2_channel_window_read_ex(LIBSSH2_CHANNEL * channel,
|
||||
bytes_queued += packet->data_len - packet->data_head;
|
||||
}
|
||||
|
||||
packet = packet->next;
|
||||
packet = _libssh2_list_next(&packet->node);
|
||||
}
|
||||
|
||||
*read_avail = bytes_queued;
|
||||
|
@ -188,8 +188,6 @@ typedef struct _LIBSSH2_CRYPT_METHOD LIBSSH2_CRYPT_METHOD;
|
||||
typedef struct _LIBSSH2_COMP_METHOD LIBSSH2_COMP_METHOD;
|
||||
|
||||
typedef struct _LIBSSH2_PACKET LIBSSH2_PACKET;
|
||||
typedef struct _LIBSSH2_PACKET_BRIGADE LIBSSH2_PACKET_BRIGADE;
|
||||
typedef struct _LIBSSH2_CHANNEL_BRIGADE LIBSSH2_CHANNEL_BRIGADE;
|
||||
|
||||
typedef int libssh2pack_t;
|
||||
|
||||
@ -289,6 +287,7 @@ typedef struct packet_queue_listener_state_t
|
||||
uint32_t sport;
|
||||
uint32_t host_len;
|
||||
uint32_t shost_len;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
} packet_queue_listener_state_t;
|
||||
|
||||
#define X11FwdUnAvil "X11 Forward Unavailable"
|
||||
@ -303,10 +302,13 @@ typedef struct packet_x11_open_state_t
|
||||
uint32_t packet_size;
|
||||
uint32_t sport;
|
||||
uint32_t shost_len;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
} packet_x11_open_state_t;
|
||||
|
||||
struct _LIBSSH2_PACKET
|
||||
{
|
||||
struct list_node node; /* linked list header */
|
||||
|
||||
unsigned char type;
|
||||
|
||||
/* Unencrypted Payload (no type byte, no padding, just the facts ma'am) */
|
||||
@ -319,15 +321,6 @@ struct _LIBSSH2_PACKET
|
||||
|
||||
/* Can the message be confirmed? */
|
||||
int mac;
|
||||
|
||||
LIBSSH2_PACKET_BRIGADE *brigade;
|
||||
|
||||
LIBSSH2_PACKET *next, *prev;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_PACKET_BRIGADE
|
||||
{
|
||||
LIBSSH2_PACKET *head, *tail;
|
||||
};
|
||||
|
||||
typedef struct _libssh2_channel_data
|
||||
@ -344,6 +337,8 @@ typedef struct _libssh2_channel_data
|
||||
|
||||
struct _LIBSSH2_CHANNEL
|
||||
{
|
||||
struct list_node node;
|
||||
|
||||
unsigned char *channel_type;
|
||||
unsigned channel_type_len;
|
||||
|
||||
@ -356,8 +351,6 @@ struct _LIBSSH2_CHANNEL
|
||||
|
||||
LIBSSH2_SESSION *session;
|
||||
|
||||
LIBSSH2_CHANNEL *next, *prev;
|
||||
|
||||
void *abstract;
|
||||
LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb));
|
||||
|
||||
@ -400,8 +393,6 @@ struct _LIBSSH2_CHANNEL
|
||||
|
||||
/* State variables used in libssh2_channel_read_ex() */
|
||||
libssh2_nonblocking_states read_state;
|
||||
LIBSSH2_PACKET *read_packet;
|
||||
LIBSSH2_PACKET *read_next;
|
||||
|
||||
uint32_t read_local_id;
|
||||
|
||||
@ -430,11 +421,6 @@ struct _LIBSSH2_CHANNEL
|
||||
libssh2_nonblocking_states extData2_state;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_CHANNEL_BRIGADE
|
||||
{
|
||||
LIBSSH2_CHANNEL *head, *tail;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_LISTENER
|
||||
{
|
||||
struct list_node node; /* linked list header */
|
||||
@ -444,7 +430,9 @@ struct _LIBSSH2_LISTENER
|
||||
char *host;
|
||||
int port;
|
||||
|
||||
LIBSSH2_CHANNEL *queue;
|
||||
/* a list of CHANNELs for this listener */
|
||||
struct list_head queue;
|
||||
|
||||
int queue_size;
|
||||
int queue_maxsize;
|
||||
|
||||
@ -588,7 +576,7 @@ struct _LIBSSH2_SFTP
|
||||
|
||||
unsigned long request_id, version;
|
||||
|
||||
LIBSSH2_PACKET_BRIGADE packets;
|
||||
struct list_head packets;
|
||||
|
||||
/* a list of _LIBSSH2_SFTP_HANDLE structs */
|
||||
struct list_head sftp_handles;
|
||||
@ -716,12 +704,13 @@ struct _LIBSSH2_SESSION
|
||||
/* (local as source of data -- packet_write ) */
|
||||
libssh2_endpoint_data local;
|
||||
|
||||
/* Inbound Data buffer -- Sometimes the packet that comes in isn't the
|
||||
/* Inbound Data linked list -- Sometimes the packet that comes in isn't the
|
||||
packet we're ready for */
|
||||
LIBSSH2_PACKET_BRIGADE packets;
|
||||
struct list_head packets;
|
||||
|
||||
/* Active connection channels */
|
||||
LIBSSH2_CHANNEL_BRIGADE channels;
|
||||
struct list_head channels;
|
||||
|
||||
unsigned long next_channel;
|
||||
|
||||
struct list_head listeners; /* list of LIBSSH2_LISTENER structs */
|
||||
@ -814,7 +803,7 @@ struct _LIBSSH2_SESSION
|
||||
unsigned char *userauth_pblc_b;
|
||||
packet_requirev_state_t userauth_pblc_packet_requirev_state;
|
||||
|
||||
/* State variables used in llibssh2_userauth_keyboard_interactive_ex() */
|
||||
/* State variables used in libssh2_userauth_keyboard_interactive_ex() */
|
||||
libssh2_nonblocking_states userauth_kybd_state;
|
||||
unsigned char *userauth_kybd_data;
|
||||
unsigned long userauth_kybd_data_len;
|
||||
@ -863,7 +852,6 @@ struct _LIBSSH2_SESSION
|
||||
|
||||
/* State variables used in libssh2_packet_add() */
|
||||
libssh2_nonblocking_states packAdd_state;
|
||||
LIBSSH2_PACKET *packAdd_packet;
|
||||
LIBSSH2_CHANNEL *packAdd_channel;
|
||||
unsigned long packAdd_data_head;
|
||||
key_exchange_state_t packAdd_key_state;
|
||||
|
154
src/packet.c
154
src/packet.c
@ -69,7 +69,7 @@
|
||||
static inline int
|
||||
packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
unsigned long datalen,
|
||||
packet_queue_listener_state_t * listen_state)
|
||||
packet_queue_listener_state_t *listen_state)
|
||||
{
|
||||
/*
|
||||
* Look for a matching listener
|
||||
@ -119,13 +119,12 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
while (listen) {
|
||||
if ((listen->port == (int) listen_state->port) &&
|
||||
(strlen(listen->host) == listen_state->host_len) &&
|
||||
(memcmp
|
||||
(listen->host, listen_state->host,
|
||||
listen_state->host_len) == 0)) {
|
||||
(memcmp (listen->host, listen_state->host,
|
||||
listen_state->host_len) == 0)) {
|
||||
/* This is our listener */
|
||||
LIBSSH2_CHANNEL *channel = NULL, *last_queued = listen->queue;
|
||||
LIBSSH2_CHANNEL *channel = NULL;
|
||||
listen_state->channel = NULL;
|
||||
|
||||
last_queued = listen->queue;
|
||||
if (listen_state->state == libssh2_NB_state_allocated) {
|
||||
if (listen->queue_maxsize &&
|
||||
(listen->queue_maxsize <= listen->queue_size)) {
|
||||
@ -206,9 +205,9 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
if (listen_state->state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, listen_state->packet,
|
||||
17);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
if (rc == PACKET_EAGAIN)
|
||||
return PACKET_EAGAIN;
|
||||
} else if (rc) {
|
||||
else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send channel open confirmation",
|
||||
0);
|
||||
@ -217,20 +216,8 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
}
|
||||
|
||||
/* Link the channel into the end of the queue list */
|
||||
|
||||
if (!last_queued) {
|
||||
listen->queue = channel;
|
||||
listen_state->state = libssh2_NB_state_idle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (last_queued->next) {
|
||||
last_queued = last_queued->next;
|
||||
}
|
||||
|
||||
last_queued->next = channel;
|
||||
channel->prev = last_queued;
|
||||
|
||||
_libssh2_list_add(&listen->queue,
|
||||
&listen_state->channel->node);
|
||||
listen->queue_size++;
|
||||
|
||||
listen_state->state = libssh2_NB_state_idle;
|
||||
@ -245,32 +232,30 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
}
|
||||
|
||||
/* We're not listening to you */
|
||||
{
|
||||
p = listen_state->packet;
|
||||
*(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
|
||||
_libssh2_htonu32(p, listen_state->sender_channel);
|
||||
p += 4;
|
||||
_libssh2_htonu32(p, failure_code);
|
||||
p += 4;
|
||||
_libssh2_htonu32(p, sizeof(FwdNotReq) - 1);
|
||||
p += 4;
|
||||
memcpy(s, FwdNotReq, sizeof(FwdNotReq) - 1);
|
||||
p += sizeof(FwdNotReq) - 1;
|
||||
_libssh2_htonu32(p, 0);
|
||||
p = listen_state->packet;
|
||||
*(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
|
||||
_libssh2_htonu32(p, listen_state->sender_channel);
|
||||
p += 4;
|
||||
_libssh2_htonu32(p, failure_code);
|
||||
p += 4;
|
||||
_libssh2_htonu32(p, sizeof(FwdNotReq) - 1);
|
||||
p += 4;
|
||||
memcpy(s, FwdNotReq, sizeof(FwdNotReq) - 1);
|
||||
p += sizeof(FwdNotReq) - 1;
|
||||
_libssh2_htonu32(p, 0);
|
||||
|
||||
rc = _libssh2_transport_write(session, listen_state->packet,
|
||||
packet_len);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
} else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send open failure", 0);
|
||||
listen_state->state = libssh2_NB_state_idle;
|
||||
return -1;
|
||||
}
|
||||
rc = _libssh2_transport_write(session, listen_state->packet,
|
||||
packet_len);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
} else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send open failure", 0);
|
||||
listen_state->state = libssh2_NB_state_idle;
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
listen_state->state = libssh2_NB_state_idle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -281,14 +266,14 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
static inline int
|
||||
packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
unsigned long datalen,
|
||||
packet_x11_open_state_t * x11open_state)
|
||||
packet_x11_open_state_t *x11open_state)
|
||||
{
|
||||
int failure_code = 2; /* SSH_OPEN_CONNECT_FAILED */
|
||||
unsigned char *s = data + (sizeof("x11") - 1) + 5;
|
||||
/* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
|
||||
unsigned long packet_len = 17 + (sizeof(X11FwdUnAvil) - 1);
|
||||
unsigned char *p;
|
||||
LIBSSH2_CHANNEL *channel = NULL;
|
||||
LIBSSH2_CHANNEL *channel = x11open_state->channel;
|
||||
int rc;
|
||||
|
||||
(void) datalen;
|
||||
@ -388,21 +373,13 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
}
|
||||
|
||||
/* Link the channel into the session */
|
||||
if (session->channels.tail) {
|
||||
session->channels.tail->next = channel;
|
||||
channel->prev = session->channels.tail;
|
||||
} else {
|
||||
session->channels.head = channel;
|
||||
channel->prev = NULL;
|
||||
}
|
||||
channel->next = NULL;
|
||||
session->channels.tail = channel;
|
||||
_libssh2_list_add(&session->channels, &channel->node);
|
||||
|
||||
/*
|
||||
* Pass control to the callback, they may turn right around and
|
||||
* free the channel, or actually use it
|
||||
*/
|
||||
LIBSSH2_X11_OPEN(channel, (char *) x11open_state->shost,
|
||||
LIBSSH2_X11_OPEN(channel, (char *)x11open_state->shost,
|
||||
x11open_state->sport);
|
||||
|
||||
x11open_state->state = libssh2_NB_state_idle;
|
||||
@ -813,19 +790,15 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
if ((datalen >= (sizeof("forwarded-tcpip") + 4)) &&
|
||||
((sizeof("forwarded-tcpip") - 1) == _libssh2_ntohu32(data + 1))
|
||||
&&
|
||||
(memcmp
|
||||
(data + 5, "forwarded-tcpip",
|
||||
sizeof("forwarded-tcpip") - 1) == 0)) {
|
||||
(memcmp(data + 5, "forwarded-tcpip",
|
||||
sizeof("forwarded-tcpip") - 1) == 0)) {
|
||||
|
||||
libssh2_packet_add_jump_point2:
|
||||
session->packAdd_state = libssh2_NB_state_jump2;
|
||||
rc = packet_queue_listener(session, data, datalen,
|
||||
&session->packAdd_Qlstn_state);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
session->socket_block_directions =
|
||||
LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||
if (rc == PACKET_EAGAIN)
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
|
||||
LIBSSH2_FREE(session, data);
|
||||
session->packAdd_state = libssh2_NB_state_idle;
|
||||
@ -839,11 +812,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
session->packAdd_state = libssh2_NB_state_jump3;
|
||||
rc = packet_x11_open(session, data, datalen,
|
||||
&session->packAdd_x11open_state);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
session->socket_block_directions =
|
||||
LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||
if (rc == PACKET_EAGAIN)
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
|
||||
LIBSSH2_FREE(session, data);
|
||||
session->packAdd_state = libssh2_NB_state_idle;
|
||||
@ -879,33 +849,23 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
}
|
||||
|
||||
if (session->packAdd_state == libssh2_NB_state_sent) {
|
||||
session->packAdd_packet =
|
||||
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
|
||||
if (!session->packAdd_packet) {
|
||||
LIBSSH2_PACKET *packAdd_packet;
|
||||
packAdd_packet =
|
||||
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
|
||||
if (!packAdd_packet) {
|
||||
_libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for LIBSSH2_PACKET");
|
||||
LIBSSH2_FREE(session, data);
|
||||
session->packAdd_state = libssh2_NB_state_idle;
|
||||
return -1;
|
||||
}
|
||||
memset(session->packAdd_packet, 0, sizeof(LIBSSH2_PACKET));
|
||||
memset(packAdd_packet, 0, sizeof(LIBSSH2_PACKET));
|
||||
|
||||
session->packAdd_packet->data = data;
|
||||
session->packAdd_packet->data_len = datalen;
|
||||
session->packAdd_packet->data_head = session->packAdd_data_head;
|
||||
session->packAdd_packet->mac = macstate;
|
||||
session->packAdd_packet->brigade = &session->packets;
|
||||
session->packAdd_packet->next = NULL;
|
||||
packAdd_packet->data = data;
|
||||
packAdd_packet->data_len = datalen;
|
||||
packAdd_packet->data_head = session->packAdd_data_head;
|
||||
packAdd_packet->mac = macstate;
|
||||
|
||||
if (session->packets.tail) {
|
||||
session->packAdd_packet->prev = session->packets.tail;
|
||||
session->packAdd_packet->prev->next = session->packAdd_packet;
|
||||
session->packets.tail = session->packAdd_packet;
|
||||
} else {
|
||||
session->packets.head = session->packAdd_packet;
|
||||
session->packets.tail = session->packAdd_packet;
|
||||
session->packAdd_packet->prev = NULL;
|
||||
}
|
||||
_libssh2_list_add(&session->packets, &packAdd_packet->node);
|
||||
|
||||
session->packAdd_state = libssh2_NB_state_sent1;
|
||||
}
|
||||
@ -968,7 +928,7 @@ _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
|
||||
unsigned long match_ofs, const unsigned char *match_buf,
|
||||
unsigned long match_len)
|
||||
{
|
||||
LIBSSH2_PACKET *packet = session->packets.head;
|
||||
LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||
"Looking for packet of type: %d", (int) packet_type);
|
||||
@ -982,24 +942,14 @@ _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
|
||||
*data = packet->data;
|
||||
*data_len = packet->data_len;
|
||||
|
||||
/* unlink struct */
|
||||
if (packet->prev) {
|
||||
packet->prev->next = packet->next;
|
||||
} else {
|
||||
session->packets.head = packet->next;
|
||||
}
|
||||
|
||||
if (packet->next) {
|
||||
packet->next->prev = packet->prev;
|
||||
} else {
|
||||
session->packets.tail = packet->prev;
|
||||
}
|
||||
/* unlink struct from session->packets */
|
||||
_libssh2_list_remove(&packet->node);
|
||||
|
||||
LIBSSH2_FREE(session, packet);
|
||||
|
||||
return 0;
|
||||
}
|
||||
packet = packet->next;
|
||||
packet = _libssh2_list_next(&packet->node);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -699,6 +699,9 @@ static int
|
||||
session_free(LIBSSH2_SESSION *session)
|
||||
{
|
||||
int rc;
|
||||
LIBSSH2_PACKET *pkg;
|
||||
LIBSSH2_CHANNEL *ch;
|
||||
LIBSSH2_LISTENER *l;
|
||||
|
||||
if (session->free_state == libssh2_NB_state_idle) {
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource",
|
||||
@ -708,13 +711,15 @@ session_free(LIBSSH2_SESSION *session)
|
||||
}
|
||||
|
||||
if (session->free_state == libssh2_NB_state_created) {
|
||||
while (session->channels.head) {
|
||||
LIBSSH2_CHANNEL *tmp = session->channels.head;
|
||||
while ((ch = _libssh2_list_first(&session->channels))) {
|
||||
|
||||
rc = libssh2_channel_free(session->channels.head);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
rc = libssh2_channel_free(ch);
|
||||
if (rc == PACKET_EAGAIN)
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
#if 0
|
||||
/* Daniel's note: I'm leaving this code here right now since it
|
||||
looks so weird I'm stumped. Why would libssh2_channel_free()
|
||||
fail and forces this to be done? */
|
||||
if (tmp == session->channels.head) {
|
||||
/* channel_free couldn't do it's job, perform a messy cleanup */
|
||||
tmp = session->channels.head;
|
||||
@ -728,14 +733,14 @@ session_free(LIBSSH2_SESSION *session)
|
||||
/* reverse linking isn't important here, we're killing the
|
||||
* structure */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
session->state = libssh2_NB_state_sent;
|
||||
}
|
||||
|
||||
if (session->state == libssh2_NB_state_sent) {
|
||||
LIBSSH2_LISTENER *l;
|
||||
while (l = _libssh2_list_first(&session->listeners)) {
|
||||
while ((l = _libssh2_list_first(&session->listeners))) {
|
||||
rc = libssh2_channel_forward_cancel(l);
|
||||
if (rc == PACKET_EAGAIN)
|
||||
return PACKET_EAGAIN;
|
||||
@ -908,16 +913,14 @@ session_free(LIBSSH2_SESSION *session)
|
||||
LIBSSH2_FREE(session, session->err_msg);
|
||||
}
|
||||
|
||||
/* Cleanup any remaining packets */
|
||||
while (session->packets.head) {
|
||||
LIBSSH2_PACKET *tmp = session->packets.head;
|
||||
|
||||
/* unlink */
|
||||
session->packets.head = tmp->next;
|
||||
/* Cleanup all remaining packets */
|
||||
while ((pkg = _libssh2_list_first(&session->packets))) {
|
||||
/* unlink the node */
|
||||
_libssh2_list_remove(&pkg->node);
|
||||
|
||||
/* free */
|
||||
LIBSSH2_FREE(session, tmp->data);
|
||||
LIBSSH2_FREE(session, tmp);
|
||||
LIBSSH2_FREE(session, pkg->data);
|
||||
LIBSSH2_FREE(session, pkg);
|
||||
}
|
||||
|
||||
if(session->socket_prev_blockstate)
|
||||
@ -1245,7 +1248,7 @@ LIBSSH2_API int
|
||||
libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel, int extended)
|
||||
{
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
LIBSSH2_PACKET *packet = session->packets.head;
|
||||
LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
|
||||
|
||||
while (packet) {
|
||||
if ( channel->local.id == _libssh2_ntohu32(packet->data + 1)) {
|
||||
@ -1259,7 +1262,7 @@ libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel, int extended)
|
||||
}
|
||||
/* else - no data of any type is ready to be read */
|
||||
}
|
||||
packet = packet->next;
|
||||
packet = _libssh2_list_next(&packet->node);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1285,7 +1288,7 @@ poll_channel_write(LIBSSH2_CHANNEL * channel)
|
||||
static inline int
|
||||
poll_listener_queued(LIBSSH2_LISTENER * listener)
|
||||
{
|
||||
return listener->queue ? 1 : 0;
|
||||
return _libssh2_list_first(&listener->queue) ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1456,8 +1459,7 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
|
||||
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) {
|
||||
/* No connections known of yet */
|
||||
fds[i].revents |=
|
||||
poll_listener_queued(fds[i].fd.
|
||||
listener) ?
|
||||
poll_listener_queued(fds[i].fd. listener) ?
|
||||
LIBSSH2_POLLFD_POLLIN : 0;
|
||||
}
|
||||
if (fds[i].fd.listener->session->socket_state ==
|
||||
|
28
src/sftp.c
28
src/sftp.c
@ -131,15 +131,8 @@ sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data,
|
||||
packet->data = data;
|
||||
packet->data_len = data_len;
|
||||
packet->data_head = 5;
|
||||
packet->brigade = &sftp->packets;
|
||||
packet->next = NULL;
|
||||
packet->prev = sftp->packets.tail;
|
||||
if (packet->prev) {
|
||||
packet->prev->next = packet;
|
||||
} else {
|
||||
sftp->packets.head = packet;
|
||||
}
|
||||
sftp->packets.tail = packet;
|
||||
|
||||
_libssh2_list_add(&sftp->packets, &packet->node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -253,7 +246,7 @@ sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type,
|
||||
unsigned long *data_len)
|
||||
{
|
||||
LIBSSH2_SESSION *session = sftp->channel->session;
|
||||
LIBSSH2_PACKET *packet = sftp->packets.head;
|
||||
LIBSSH2_PACKET *packet = _libssh2_list_first(&sftp->packets);
|
||||
unsigned char match_buf[5];
|
||||
int match_len;
|
||||
|
||||
@ -277,24 +270,13 @@ sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type,
|
||||
*data_len = packet->data_len;
|
||||
|
||||
/* unlink and free this struct */
|
||||
if (packet->prev) {
|
||||
packet->prev->next = packet->next;
|
||||
} else {
|
||||
sftp->packets.head = packet->next;
|
||||
}
|
||||
|
||||
if (packet->next) {
|
||||
packet->next->prev = packet->prev;
|
||||
} else {
|
||||
sftp->packets.tail = packet->prev;
|
||||
}
|
||||
|
||||
_libssh2_list_remove(&packet->node);
|
||||
LIBSSH2_FREE(session, packet);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* check next struct in the list */
|
||||
packet = packet->next;
|
||||
packet = _libssh2_list_next(&packet->node);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -259,6 +259,8 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
|
||||
/*
|
||||
* This function reads the binary stream as specified in chapter 6 of RFC4253
|
||||
* "The Secure Shell (SSH) Transport Layer Protocol"
|
||||
*
|
||||
* DOES NOT call libssh2_error() for ANY error case.
|
||||
*/
|
||||
libssh2pack_t
|
||||
_libssh2_transport_read(LIBSSH2_SESSION * session)
|
||||
@ -298,15 +300,10 @@ _libssh2_transport_read(LIBSSH2_SESSION * session)
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Redirecting into the"
|
||||
" key re-exchange");
|
||||
status = libssh2_kex_exchange(session, 1, &session->startup_key_state);
|
||||
if (status == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block exchanging encryption keys", 0);
|
||||
if (status == PACKET_EAGAIN)
|
||||
return PACKET_EAGAIN;
|
||||
} else if (status) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
|
||||
"Unable to exchange encryption keys",0);
|
||||
else if (status)
|
||||
return LIBSSH2_ERROR_KEX_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user