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;
|
unsigned long id = session->next_channel;
|
||||||
LIBSSH2_CHANNEL *channel;
|
LIBSSH2_CHANNEL *channel;
|
||||||
|
|
||||||
channel = session->channels.head;
|
channel = _libssh2_list_first(&session->channels);
|
||||||
|
|
||||||
while (channel) {
|
while (channel) {
|
||||||
if (channel->local.id > id) {
|
if (channel->local.id > id) {
|
||||||
id = channel->local.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
|
/* 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_CHANNEL *channel;
|
||||||
LIBSSH2_LISTENER *l;
|
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)
|
if (channel->local.id == channel_id)
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We didn't find the channel in the session, let's then check its
|
/* 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;
|
for(l = _libssh2_list_first(&session->listeners); l;
|
||||||
l = _libssh2_list_next(&l->node)) {
|
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)
|
if (channel->local.id == channel_id)
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
@ -112,20 +117,6 @@ _libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long channel_id)
|
|||||||
return NULL;
|
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
|
* _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 = window_size;
|
||||||
session->open_channel->remote.window_size_initial = window_size;
|
session->open_channel->remote.window_size_initial = window_size;
|
||||||
session->open_channel->remote.packet_size = packet_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 =
|
s = session->open_packet =
|
||||||
LIBSSH2_ALLOC(session, session->open_packet_len);
|
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];
|
unsigned char channel_id[4];
|
||||||
LIBSSH2_FREE(session, session->open_channel->channel_type);
|
LIBSSH2_FREE(session, session->open_channel->channel_type);
|
||||||
|
|
||||||
if (session->open_channel->next) {
|
_libssh2_list_remove(&session->open_channel->node);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear out packets meant for this channel */
|
/* Clear out packets meant for this channel */
|
||||||
_libssh2_htonu32(channel_id, session->open_channel->local.id);
|
_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)
|
static int channel_forward_cancel(LIBSSH2_LISTENER *listener)
|
||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session = listener->session;
|
LIBSSH2_SESSION *session = listener->session;
|
||||||
LIBSSH2_CHANNEL *queued = listener->queue;
|
LIBSSH2_CHANNEL *queued;
|
||||||
unsigned char *packet, *s;
|
unsigned char *packet, *s;
|
||||||
unsigned long host_len = strlen(listener->host);
|
unsigned long host_len = strlen(listener->host);
|
||||||
/* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) +
|
/* 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;
|
listener->chanFwdCncl_state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
queued = _libssh2_list_first(&listener->queue);
|
||||||
while (queued) {
|
while (queued) {
|
||||||
LIBSSH2_CHANNEL *next = queued->next;
|
LIBSSH2_CHANNEL *next = _libssh2_list_next(&queued->node);
|
||||||
|
|
||||||
rc = libssh2_channel_free(queued);
|
rc = libssh2_channel_free(queued);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
@ -755,28 +738,17 @@ channel_forward_accept(LIBSSH2_LISTENER *listener)
|
|||||||
}
|
}
|
||||||
} while (rc > 0);
|
} while (rc > 0);
|
||||||
|
|
||||||
if (listener->queue) {
|
if (_libssh2_list_first(&listener->queue)) {
|
||||||
LIBSSH2_SESSION *session = listener->session;
|
LIBSSH2_CHANNEL *channel = _libssh2_list_first(&listener->queue);
|
||||||
LIBSSH2_CHANNEL *channel;
|
|
||||||
|
|
||||||
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--;
|
listener->queue_size--;
|
||||||
|
|
||||||
|
/* add channel to session's channel list */
|
||||||
|
_libssh2_list_add(&channel->session->channels, &channel->node);
|
||||||
|
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1455,14 +1427,14 @@ libssh2_channel_set_blocking(LIBSSH2_CHANNEL * channel, int blocking)
|
|||||||
int
|
int
|
||||||
_libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
|
_libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
|
||||||
{
|
{
|
||||||
LIBSSH2_PACKET *packet = channel->session->packets.head;
|
|
||||||
|
|
||||||
if (channel->flush_state == libssh2_NB_state_idle) {
|
if (channel->flush_state == libssh2_NB_state_idle) {
|
||||||
|
LIBSSH2_PACKET *packet =
|
||||||
|
_libssh2_list_first(&channel->session->packets);
|
||||||
channel->flush_refund_bytes = 0;
|
channel->flush_refund_bytes = 0;
|
||||||
channel->flush_flush_bytes = 0;
|
channel->flush_flush_bytes = 0;
|
||||||
|
|
||||||
while (packet) {
|
while (packet) {
|
||||||
LIBSSH2_PACKET *next = packet->next;
|
LIBSSH2_PACKET *next = _libssh2_list_next(&packet->node);
|
||||||
unsigned char packet_type = packet->data[0];
|
unsigned char packet_type = packet->data[0];
|
||||||
|
|
||||||
if (((packet_type == SSH_MSG_CHANNEL_DATA)
|
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)) {
|
&& (_libssh2_ntohu32(packet->data + 1) == channel->local.id)) {
|
||||||
/* It's our channel at least */
|
/* It's our channel at least */
|
||||||
long packet_stream_id =
|
long packet_stream_id =
|
||||||
(packet_type ==
|
(packet_type == SSH_MSG_CHANNEL_DATA) ? 0 :
|
||||||
SSH_MSG_CHANNEL_DATA) ? 0 : _libssh2_ntohu32(packet->data +
|
_libssh2_ntohu32(packet->data + 5);
|
||||||
5);
|
|
||||||
if ((streamid == LIBSSH2_CHANNEL_FLUSH_ALL)
|
if ((streamid == LIBSSH2_CHANNEL_FLUSH_ALL)
|
||||||
|| ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)
|
|| ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)
|
||||||
&& ((streamid == LIBSSH2_CHANNEL_FLUSH_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;
|
channel->flush_flush_bytes += bytes_to_flush;
|
||||||
|
|
||||||
LIBSSH2_FREE(channel->session, packet->data);
|
LIBSSH2_FREE(channel->session, packet->data);
|
||||||
if (packet->prev) {
|
|
||||||
packet->prev->next = packet->next;
|
/* remove this packet from the parent's list */
|
||||||
} else {
|
_libssh2_list_remove(&packet->node);
|
||||||
channel->session->packets.head = packet->next;
|
|
||||||
}
|
|
||||||
if (packet->next) {
|
|
||||||
packet->next->prev = packet->prev;
|
|
||||||
} else {
|
|
||||||
channel->session->packets.tail = packet->prev;
|
|
||||||
}
|
|
||||||
LIBSSH2_FREE(channel->session, packet);
|
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_read = 0;
|
||||||
int bytes_want;
|
int bytes_want;
|
||||||
int unlink_packet;
|
int unlink_packet;
|
||||||
|
LIBSSH2_PACKET *read_packet;
|
||||||
|
LIBSSH2_PACKET *read_next;
|
||||||
|
|
||||||
if (channel->read_state == libssh2_NB_state_idle) {
|
if (channel->read_state == libssh2_NB_state_idle) {
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||||
@ -1785,9 +1751,8 @@ static ssize_t channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
|
|||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
channel->read_packet = session->packets.head;
|
read_packet = _libssh2_list_first(&session->packets);
|
||||||
while (channel->read_packet &&
|
while (read_packet && (bytes_read < (int) buflen)) {
|
||||||
(bytes_read < (int) buflen)) {
|
|
||||||
/* previously this loop condition also checked for
|
/* previously this loop condition also checked for
|
||||||
!channel->remote.close but we cannot let it do this:
|
!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.
|
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 */
|
/* In case packet gets destroyed during this iteration */
|
||||||
channel->read_next = readpkt->next;
|
read_next = _libssh2_list_next(&readpkt->node);
|
||||||
|
|
||||||
channel->read_local_id =
|
channel->read_local_id =
|
||||||
_libssh2_ntohu32(readpkt->data + 1);
|
_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 drained, remove from list */
|
||||||
if (unlink_packet) {
|
if (unlink_packet) {
|
||||||
if (readpkt->prev) {
|
/* detach readpkt from session->packets list */
|
||||||
readpkt->prev->next = readpkt->next;
|
_libssh2_list_remove(&readpkt->node);
|
||||||
} else {
|
|
||||||
session->packets.head = readpkt->next;
|
|
||||||
}
|
|
||||||
if (readpkt->next) {
|
|
||||||
readpkt->next->prev = readpkt->prev;
|
|
||||||
} else {
|
|
||||||
session->packets.tail = readpkt->prev;
|
|
||||||
}
|
|
||||||
LIBSSH2_FREE(session, readpkt->data);
|
LIBSSH2_FREE(session, readpkt->data);
|
||||||
LIBSSH2_FREE(session, readpkt);
|
LIBSSH2_FREE(session, readpkt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check the next struct in the chain */
|
/* check the next struct in the chain */
|
||||||
channel->read_packet = channel->read_next;
|
read_packet = read_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes_read == 0) {
|
if (bytes_read == 0) {
|
||||||
@ -1949,9 +1907,9 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
|
|||||||
LIBSSH2_PACKET *read_packet;
|
LIBSSH2_PACKET *read_packet;
|
||||||
uint32_t read_local_id;
|
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;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
while (read_packet) {
|
while (read_packet) {
|
||||||
read_local_id = _libssh2_ntohu32(read_packet->data + 1);
|
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);
|
return (read_packet->data_len - read_packet->data_head);
|
||||||
}
|
}
|
||||||
read_packet = read_packet->next;
|
read_packet = _libssh2_list_next(&read_packet->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -2205,7 +2163,7 @@ LIBSSH2_API int
|
|||||||
libssh2_channel_eof(LIBSSH2_CHANNEL * channel)
|
libssh2_channel_eof(LIBSSH2_CHANNEL * channel)
|
||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
LIBSSH2_PACKET *packet = session->packets.head;
|
LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
|
||||||
|
|
||||||
while (packet) {
|
while (packet) {
|
||||||
if (((packet->data[0] == SSH_MSG_CHANNEL_DATA)
|
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 */
|
/* There's data waiting to be read yet, mask the EOF status */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
packet = packet->next;
|
packet = _libssh2_list_next(&packet->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
return channel->remote.eof;
|
return channel->remote.eof;
|
||||||
@ -2473,17 +2431,8 @@ int _libssh2_channel_free(LIBSSH2_CHANNEL *channel)
|
|||||||
LIBSSH2_FREE(session, channel->channel_type);
|
LIBSSH2_FREE(session, channel->channel_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unlink from channel brigade */
|
/* Unlink from channel list */
|
||||||
if (channel->prev) {
|
_libssh2_list_remove(&channel->node);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure all memory used in the state variables are free
|
* 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) {
|
if (read_avail) {
|
||||||
unsigned long bytes_queued = 0;
|
unsigned long bytes_queued = 0;
|
||||||
LIBSSH2_PACKET *packet = channel->session->packets.head;
|
LIBSSH2_PACKET *packet =
|
||||||
|
_libssh2_list_first(&channel->session->packets);
|
||||||
|
|
||||||
while (packet) {
|
while (packet) {
|
||||||
unsigned char packet_type = packet->data[0];
|
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;
|
bytes_queued += packet->data_len - packet->data_head;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet = packet->next;
|
packet = _libssh2_list_next(&packet->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
*read_avail = bytes_queued;
|
*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_COMP_METHOD LIBSSH2_COMP_METHOD;
|
||||||
|
|
||||||
typedef struct _LIBSSH2_PACKET LIBSSH2_PACKET;
|
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;
|
typedef int libssh2pack_t;
|
||||||
|
|
||||||
@ -289,6 +287,7 @@ typedef struct packet_queue_listener_state_t
|
|||||||
uint32_t sport;
|
uint32_t sport;
|
||||||
uint32_t host_len;
|
uint32_t host_len;
|
||||||
uint32_t shost_len;
|
uint32_t shost_len;
|
||||||
|
LIBSSH2_CHANNEL *channel;
|
||||||
} packet_queue_listener_state_t;
|
} packet_queue_listener_state_t;
|
||||||
|
|
||||||
#define X11FwdUnAvil "X11 Forward Unavailable"
|
#define X11FwdUnAvil "X11 Forward Unavailable"
|
||||||
@ -303,10 +302,13 @@ typedef struct packet_x11_open_state_t
|
|||||||
uint32_t packet_size;
|
uint32_t packet_size;
|
||||||
uint32_t sport;
|
uint32_t sport;
|
||||||
uint32_t shost_len;
|
uint32_t shost_len;
|
||||||
|
LIBSSH2_CHANNEL *channel;
|
||||||
} packet_x11_open_state_t;
|
} packet_x11_open_state_t;
|
||||||
|
|
||||||
struct _LIBSSH2_PACKET
|
struct _LIBSSH2_PACKET
|
||||||
{
|
{
|
||||||
|
struct list_node node; /* linked list header */
|
||||||
|
|
||||||
unsigned char type;
|
unsigned char type;
|
||||||
|
|
||||||
/* Unencrypted Payload (no type byte, no padding, just the facts ma'am) */
|
/* Unencrypted Payload (no type byte, no padding, just the facts ma'am) */
|
||||||
@ -319,15 +321,6 @@ struct _LIBSSH2_PACKET
|
|||||||
|
|
||||||
/* Can the message be confirmed? */
|
/* Can the message be confirmed? */
|
||||||
int mac;
|
int mac;
|
||||||
|
|
||||||
LIBSSH2_PACKET_BRIGADE *brigade;
|
|
||||||
|
|
||||||
LIBSSH2_PACKET *next, *prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _LIBSSH2_PACKET_BRIGADE
|
|
||||||
{
|
|
||||||
LIBSSH2_PACKET *head, *tail;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _libssh2_channel_data
|
typedef struct _libssh2_channel_data
|
||||||
@ -344,6 +337,8 @@ typedef struct _libssh2_channel_data
|
|||||||
|
|
||||||
struct _LIBSSH2_CHANNEL
|
struct _LIBSSH2_CHANNEL
|
||||||
{
|
{
|
||||||
|
struct list_node node;
|
||||||
|
|
||||||
unsigned char *channel_type;
|
unsigned char *channel_type;
|
||||||
unsigned channel_type_len;
|
unsigned channel_type_len;
|
||||||
|
|
||||||
@ -356,8 +351,6 @@ struct _LIBSSH2_CHANNEL
|
|||||||
|
|
||||||
LIBSSH2_SESSION *session;
|
LIBSSH2_SESSION *session;
|
||||||
|
|
||||||
LIBSSH2_CHANNEL *next, *prev;
|
|
||||||
|
|
||||||
void *abstract;
|
void *abstract;
|
||||||
LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb));
|
LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb));
|
||||||
|
|
||||||
@ -400,8 +393,6 @@ struct _LIBSSH2_CHANNEL
|
|||||||
|
|
||||||
/* State variables used in libssh2_channel_read_ex() */
|
/* State variables used in libssh2_channel_read_ex() */
|
||||||
libssh2_nonblocking_states read_state;
|
libssh2_nonblocking_states read_state;
|
||||||
LIBSSH2_PACKET *read_packet;
|
|
||||||
LIBSSH2_PACKET *read_next;
|
|
||||||
|
|
||||||
uint32_t read_local_id;
|
uint32_t read_local_id;
|
||||||
|
|
||||||
@ -430,11 +421,6 @@ struct _LIBSSH2_CHANNEL
|
|||||||
libssh2_nonblocking_states extData2_state;
|
libssh2_nonblocking_states extData2_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _LIBSSH2_CHANNEL_BRIGADE
|
|
||||||
{
|
|
||||||
LIBSSH2_CHANNEL *head, *tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _LIBSSH2_LISTENER
|
struct _LIBSSH2_LISTENER
|
||||||
{
|
{
|
||||||
struct list_node node; /* linked list header */
|
struct list_node node; /* linked list header */
|
||||||
@ -444,7 +430,9 @@ struct _LIBSSH2_LISTENER
|
|||||||
char *host;
|
char *host;
|
||||||
int port;
|
int port;
|
||||||
|
|
||||||
LIBSSH2_CHANNEL *queue;
|
/* a list of CHANNELs for this listener */
|
||||||
|
struct list_head queue;
|
||||||
|
|
||||||
int queue_size;
|
int queue_size;
|
||||||
int queue_maxsize;
|
int queue_maxsize;
|
||||||
|
|
||||||
@ -588,7 +576,7 @@ struct _LIBSSH2_SFTP
|
|||||||
|
|
||||||
unsigned long request_id, version;
|
unsigned long request_id, version;
|
||||||
|
|
||||||
LIBSSH2_PACKET_BRIGADE packets;
|
struct list_head packets;
|
||||||
|
|
||||||
/* a list of _LIBSSH2_SFTP_HANDLE structs */
|
/* a list of _LIBSSH2_SFTP_HANDLE structs */
|
||||||
struct list_head sftp_handles;
|
struct list_head sftp_handles;
|
||||||
@ -716,12 +704,13 @@ struct _LIBSSH2_SESSION
|
|||||||
/* (local as source of data -- packet_write ) */
|
/* (local as source of data -- packet_write ) */
|
||||||
libssh2_endpoint_data local;
|
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 */
|
packet we're ready for */
|
||||||
LIBSSH2_PACKET_BRIGADE packets;
|
struct list_head packets;
|
||||||
|
|
||||||
/* Active connection channels */
|
/* Active connection channels */
|
||||||
LIBSSH2_CHANNEL_BRIGADE channels;
|
struct list_head channels;
|
||||||
|
|
||||||
unsigned long next_channel;
|
unsigned long next_channel;
|
||||||
|
|
||||||
struct list_head listeners; /* list of LIBSSH2_LISTENER structs */
|
struct list_head listeners; /* list of LIBSSH2_LISTENER structs */
|
||||||
@ -814,7 +803,7 @@ struct _LIBSSH2_SESSION
|
|||||||
unsigned char *userauth_pblc_b;
|
unsigned char *userauth_pblc_b;
|
||||||
packet_requirev_state_t userauth_pblc_packet_requirev_state;
|
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;
|
libssh2_nonblocking_states userauth_kybd_state;
|
||||||
unsigned char *userauth_kybd_data;
|
unsigned char *userauth_kybd_data;
|
||||||
unsigned long userauth_kybd_data_len;
|
unsigned long userauth_kybd_data_len;
|
||||||
@ -863,7 +852,6 @@ struct _LIBSSH2_SESSION
|
|||||||
|
|
||||||
/* State variables used in libssh2_packet_add() */
|
/* State variables used in libssh2_packet_add() */
|
||||||
libssh2_nonblocking_states packAdd_state;
|
libssh2_nonblocking_states packAdd_state;
|
||||||
LIBSSH2_PACKET *packAdd_packet;
|
|
||||||
LIBSSH2_CHANNEL *packAdd_channel;
|
LIBSSH2_CHANNEL *packAdd_channel;
|
||||||
unsigned long packAdd_data_head;
|
unsigned long packAdd_data_head;
|
||||||
key_exchange_state_t packAdd_key_state;
|
key_exchange_state_t packAdd_key_state;
|
||||||
|
154
src/packet.c
154
src/packet.c
@ -69,7 +69,7 @@
|
|||||||
static inline int
|
static inline int
|
||||||
packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
||||||
unsigned long datalen,
|
unsigned long datalen,
|
||||||
packet_queue_listener_state_t * listen_state)
|
packet_queue_listener_state_t *listen_state)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Look for a matching listener
|
* Look for a matching listener
|
||||||
@ -119,13 +119,12 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
while (listen) {
|
while (listen) {
|
||||||
if ((listen->port == (int) listen_state->port) &&
|
if ((listen->port == (int) listen_state->port) &&
|
||||||
(strlen(listen->host) == listen_state->host_len) &&
|
(strlen(listen->host) == listen_state->host_len) &&
|
||||||
(memcmp
|
(memcmp (listen->host, listen_state->host,
|
||||||
(listen->host, listen_state->host,
|
listen_state->host_len) == 0)) {
|
||||||
listen_state->host_len) == 0)) {
|
|
||||||
/* This is our listener */
|
/* 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_state->state == libssh2_NB_state_allocated) {
|
||||||
if (listen->queue_maxsize &&
|
if (listen->queue_maxsize &&
|
||||||
(listen->queue_maxsize <= listen->queue_size)) {
|
(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) {
|
if (listen_state->state == libssh2_NB_state_created) {
|
||||||
rc = _libssh2_transport_write(session, listen_state->packet,
|
rc = _libssh2_transport_write(session, listen_state->packet,
|
||||||
17);
|
17);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN)
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (rc) {
|
else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send channel open confirmation",
|
"Unable to send channel open confirmation",
|
||||||
0);
|
0);
|
||||||
@ -217,20 +216,8 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Link the channel into the end of the queue list */
|
/* Link the channel into the end of the queue list */
|
||||||
|
_libssh2_list_add(&listen->queue,
|
||||||
if (!last_queued) {
|
&listen_state->channel->node);
|
||||||
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;
|
|
||||||
|
|
||||||
listen->queue_size++;
|
listen->queue_size++;
|
||||||
|
|
||||||
listen_state->state = libssh2_NB_state_idle;
|
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 */
|
/* We're not listening to you */
|
||||||
{
|
p = listen_state->packet;
|
||||||
p = listen_state->packet;
|
*(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
|
||||||
*(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
|
_libssh2_htonu32(p, listen_state->sender_channel);
|
||||||
_libssh2_htonu32(p, listen_state->sender_channel);
|
p += 4;
|
||||||
p += 4;
|
_libssh2_htonu32(p, failure_code);
|
||||||
_libssh2_htonu32(p, failure_code);
|
p += 4;
|
||||||
p += 4;
|
_libssh2_htonu32(p, sizeof(FwdNotReq) - 1);
|
||||||
_libssh2_htonu32(p, sizeof(FwdNotReq) - 1);
|
p += 4;
|
||||||
p += 4;
|
memcpy(s, FwdNotReq, sizeof(FwdNotReq) - 1);
|
||||||
memcpy(s, FwdNotReq, sizeof(FwdNotReq) - 1);
|
p += sizeof(FwdNotReq) - 1;
|
||||||
p += sizeof(FwdNotReq) - 1;
|
_libssh2_htonu32(p, 0);
|
||||||
_libssh2_htonu32(p, 0);
|
|
||||||
|
|
||||||
rc = _libssh2_transport_write(session, listen_state->packet,
|
rc = _libssh2_transport_write(session, listen_state->packet,
|
||||||
packet_len);
|
packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send open failure", 0);
|
"Unable to send open failure", 0);
|
||||||
listen_state->state = libssh2_NB_state_idle;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
listen_state->state = libssh2_NB_state_idle;
|
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
|
static inline int
|
||||||
packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
|
packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
|
||||||
unsigned long datalen,
|
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 */
|
int failure_code = 2; /* SSH_OPEN_CONNECT_FAILED */
|
||||||
unsigned char *s = data + (sizeof("x11") - 1) + 5;
|
unsigned char *s = data + (sizeof("x11") - 1) + 5;
|
||||||
/* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
|
/* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
|
||||||
unsigned long packet_len = 17 + (sizeof(X11FwdUnAvil) - 1);
|
unsigned long packet_len = 17 + (sizeof(X11FwdUnAvil) - 1);
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
LIBSSH2_CHANNEL *channel = NULL;
|
LIBSSH2_CHANNEL *channel = x11open_state->channel;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
(void) datalen;
|
(void) datalen;
|
||||||
@ -388,21 +373,13 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Link the channel into the session */
|
/* Link the channel into the session */
|
||||||
if (session->channels.tail) {
|
_libssh2_list_add(&session->channels, &channel->node);
|
||||||
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;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pass control to the callback, they may turn right around and
|
* Pass control to the callback, they may turn right around and
|
||||||
* free the channel, or actually use it
|
* 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->sport);
|
||||||
|
|
||||||
x11open_state->state = libssh2_NB_state_idle;
|
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)) &&
|
if ((datalen >= (sizeof("forwarded-tcpip") + 4)) &&
|
||||||
((sizeof("forwarded-tcpip") - 1) == _libssh2_ntohu32(data + 1))
|
((sizeof("forwarded-tcpip") - 1) == _libssh2_ntohu32(data + 1))
|
||||||
&&
|
&&
|
||||||
(memcmp
|
(memcmp(data + 5, "forwarded-tcpip",
|
||||||
(data + 5, "forwarded-tcpip",
|
sizeof("forwarded-tcpip") - 1) == 0)) {
|
||||||
sizeof("forwarded-tcpip") - 1) == 0)) {
|
|
||||||
|
|
||||||
libssh2_packet_add_jump_point2:
|
libssh2_packet_add_jump_point2:
|
||||||
session->packAdd_state = libssh2_NB_state_jump2;
|
session->packAdd_state = libssh2_NB_state_jump2;
|
||||||
rc = packet_queue_listener(session, data, datalen,
|
rc = packet_queue_listener(session, data, datalen,
|
||||||
&session->packAdd_Qlstn_state);
|
&session->packAdd_Qlstn_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN)
|
||||||
session->socket_block_directions =
|
|
||||||
LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
}
|
|
||||||
|
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
session->packAdd_state = libssh2_NB_state_idle;
|
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;
|
session->packAdd_state = libssh2_NB_state_jump3;
|
||||||
rc = packet_x11_open(session, data, datalen,
|
rc = packet_x11_open(session, data, datalen,
|
||||||
&session->packAdd_x11open_state);
|
&session->packAdd_x11open_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN)
|
||||||
session->socket_block_directions =
|
|
||||||
LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
}
|
|
||||||
|
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
session->packAdd_state = libssh2_NB_state_idle;
|
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) {
|
if (session->packAdd_state == libssh2_NB_state_sent) {
|
||||||
session->packAdd_packet =
|
LIBSSH2_PACKET *packAdd_packet;
|
||||||
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
|
packAdd_packet =
|
||||||
if (!session->packAdd_packet) {
|
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
|
||||||
|
if (!packAdd_packet) {
|
||||||
_libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
|
_libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory for LIBSSH2_PACKET");
|
"Unable to allocate memory for LIBSSH2_PACKET");
|
||||||
LIBSSH2_FREE(session, data);
|
|
||||||
session->packAdd_state = libssh2_NB_state_idle;
|
session->packAdd_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memset(session->packAdd_packet, 0, sizeof(LIBSSH2_PACKET));
|
memset(packAdd_packet, 0, sizeof(LIBSSH2_PACKET));
|
||||||
|
|
||||||
session->packAdd_packet->data = data;
|
packAdd_packet->data = data;
|
||||||
session->packAdd_packet->data_len = datalen;
|
packAdd_packet->data_len = datalen;
|
||||||
session->packAdd_packet->data_head = session->packAdd_data_head;
|
packAdd_packet->data_head = session->packAdd_data_head;
|
||||||
session->packAdd_packet->mac = macstate;
|
packAdd_packet->mac = macstate;
|
||||||
session->packAdd_packet->brigade = &session->packets;
|
|
||||||
session->packAdd_packet->next = NULL;
|
|
||||||
|
|
||||||
if (session->packets.tail) {
|
_libssh2_list_add(&session->packets, &packAdd_packet->node);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
session->packAdd_state = libssh2_NB_state_sent1;
|
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_ofs, const unsigned char *match_buf,
|
||||||
unsigned long match_len)
|
unsigned long match_len)
|
||||||
{
|
{
|
||||||
LIBSSH2_PACKET *packet = session->packets.head;
|
LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||||
"Looking for packet of type: %d", (int) packet_type);
|
"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 = packet->data;
|
||||||
*data_len = packet->data_len;
|
*data_len = packet->data_len;
|
||||||
|
|
||||||
/* unlink struct */
|
/* unlink struct from session->packets */
|
||||||
if (packet->prev) {
|
_libssh2_list_remove(&packet->node);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
LIBSSH2_FREE(session, packet);
|
LIBSSH2_FREE(session, packet);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
packet = packet->next;
|
packet = _libssh2_list_next(&packet->node);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -699,6 +699,9 @@ static int
|
|||||||
session_free(LIBSSH2_SESSION *session)
|
session_free(LIBSSH2_SESSION *session)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
LIBSSH2_PACKET *pkg;
|
||||||
|
LIBSSH2_CHANNEL *ch;
|
||||||
|
LIBSSH2_LISTENER *l;
|
||||||
|
|
||||||
if (session->free_state == libssh2_NB_state_idle) {
|
if (session->free_state == libssh2_NB_state_idle) {
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource",
|
_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) {
|
if (session->free_state == libssh2_NB_state_created) {
|
||||||
while (session->channels.head) {
|
while ((ch = _libssh2_list_first(&session->channels))) {
|
||||||
LIBSSH2_CHANNEL *tmp = session->channels.head;
|
|
||||||
|
|
||||||
rc = libssh2_channel_free(session->channels.head);
|
rc = libssh2_channel_free(ch);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN)
|
||||||
return 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) {
|
if (tmp == session->channels.head) {
|
||||||
/* channel_free couldn't do it's job, perform a messy cleanup */
|
/* channel_free couldn't do it's job, perform a messy cleanup */
|
||||||
tmp = session->channels.head;
|
tmp = session->channels.head;
|
||||||
@ -728,14 +733,14 @@ session_free(LIBSSH2_SESSION *session)
|
|||||||
/* reverse linking isn't important here, we're killing the
|
/* reverse linking isn't important here, we're killing the
|
||||||
* structure */
|
* structure */
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
session->state = libssh2_NB_state_sent;
|
session->state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (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);
|
rc = libssh2_channel_forward_cancel(l);
|
||||||
if (rc == PACKET_EAGAIN)
|
if (rc == PACKET_EAGAIN)
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
@ -908,16 +913,14 @@ session_free(LIBSSH2_SESSION *session)
|
|||||||
LIBSSH2_FREE(session, session->err_msg);
|
LIBSSH2_FREE(session, session->err_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup any remaining packets */
|
/* Cleanup all remaining packets */
|
||||||
while (session->packets.head) {
|
while ((pkg = _libssh2_list_first(&session->packets))) {
|
||||||
LIBSSH2_PACKET *tmp = session->packets.head;
|
/* unlink the node */
|
||||||
|
_libssh2_list_remove(&pkg->node);
|
||||||
/* unlink */
|
|
||||||
session->packets.head = tmp->next;
|
|
||||||
|
|
||||||
/* free */
|
/* free */
|
||||||
LIBSSH2_FREE(session, tmp->data);
|
LIBSSH2_FREE(session, pkg->data);
|
||||||
LIBSSH2_FREE(session, tmp);
|
LIBSSH2_FREE(session, pkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(session->socket_prev_blockstate)
|
if(session->socket_prev_blockstate)
|
||||||
@ -1245,7 +1248,7 @@ LIBSSH2_API int
|
|||||||
libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel, int extended)
|
libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel, int extended)
|
||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
LIBSSH2_PACKET *packet = session->packets.head;
|
LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
|
||||||
|
|
||||||
while (packet) {
|
while (packet) {
|
||||||
if ( channel->local.id == _libssh2_ntohu32(packet->data + 1)) {
|
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 */
|
/* else - no data of any type is ready to be read */
|
||||||
}
|
}
|
||||||
packet = packet->next;
|
packet = _libssh2_list_next(&packet->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1285,7 +1288,7 @@ poll_channel_write(LIBSSH2_CHANNEL * channel)
|
|||||||
static inline int
|
static inline int
|
||||||
poll_listener_queued(LIBSSH2_LISTENER * listener)
|
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)) {
|
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) {
|
||||||
/* No connections known of yet */
|
/* No connections known of yet */
|
||||||
fds[i].revents |=
|
fds[i].revents |=
|
||||||
poll_listener_queued(fds[i].fd.
|
poll_listener_queued(fds[i].fd. listener) ?
|
||||||
listener) ?
|
|
||||||
LIBSSH2_POLLFD_POLLIN : 0;
|
LIBSSH2_POLLFD_POLLIN : 0;
|
||||||
}
|
}
|
||||||
if (fds[i].fd.listener->session->socket_state ==
|
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 = data;
|
||||||
packet->data_len = data_len;
|
packet->data_len = data_len;
|
||||||
packet->data_head = 5;
|
packet->data_head = 5;
|
||||||
packet->brigade = &sftp->packets;
|
|
||||||
packet->next = NULL;
|
_libssh2_list_add(&sftp->packets, &packet->node);
|
||||||
packet->prev = sftp->packets.tail;
|
|
||||||
if (packet->prev) {
|
|
||||||
packet->prev->next = packet;
|
|
||||||
} else {
|
|
||||||
sftp->packets.head = packet;
|
|
||||||
}
|
|
||||||
sftp->packets.tail = packet;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -253,7 +246,7 @@ sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type,
|
|||||||
unsigned long *data_len)
|
unsigned long *data_len)
|
||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session = sftp->channel->session;
|
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];
|
unsigned char match_buf[5];
|
||||||
int match_len;
|
int match_len;
|
||||||
|
|
||||||
@ -277,24 +270,13 @@ sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type,
|
|||||||
*data_len = packet->data_len;
|
*data_len = packet->data_len;
|
||||||
|
|
||||||
/* unlink and free this struct */
|
/* unlink and free this struct */
|
||||||
if (packet->prev) {
|
_libssh2_list_remove(&packet->node);
|
||||||
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_FREE(session, packet);
|
LIBSSH2_FREE(session, packet);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* check next struct in the list */
|
/* check next struct in the list */
|
||||||
packet = packet->next;
|
packet = _libssh2_list_next(&packet->node);
|
||||||
}
|
}
|
||||||
return -1;
|
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
|
* This function reads the binary stream as specified in chapter 6 of RFC4253
|
||||||
* "The Secure Shell (SSH) Transport Layer Protocol"
|
* "The Secure Shell (SSH) Transport Layer Protocol"
|
||||||
|
*
|
||||||
|
* DOES NOT call libssh2_error() for ANY error case.
|
||||||
*/
|
*/
|
||||||
libssh2pack_t
|
libssh2pack_t
|
||||||
_libssh2_transport_read(LIBSSH2_SESSION * session)
|
_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"
|
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Redirecting into the"
|
||||||
" key re-exchange");
|
" key re-exchange");
|
||||||
status = libssh2_kex_exchange(session, 1, &session->startup_key_state);
|
status = libssh2_kex_exchange(session, 1, &session->startup_key_state);
|
||||||
if (status == PACKET_EAGAIN) {
|
if (status == PACKET_EAGAIN)
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
|
||||||
"Would block exchanging encryption keys", 0);
|
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (status) {
|
else if (status)
|
||||||
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
|
|
||||||
"Unable to exchange encryption keys",0);
|
|
||||||
return LIBSSH2_ERROR_KEX_FAILURE;
|
return LIBSSH2_ERROR_KEX_FAILURE;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user