1
1

move over lots of code to the _libssh2_list_* functions

and I fixed a few minor bugs at the same time
Этот коммит содержится в:
Daniel Stenberg 2009-08-20 00:56:05 +02:00
родитель a871f0b214
Коммит d8b6f3c7b8
6 изменённых файлов: 150 добавлений и 281 удалений

Просмотреть файл

@ -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;

Просмотреть файл

@ -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 ==

Просмотреть файл

@ -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;
}
} }
/* /*