From d8b6f3c7b8bcf541d557c286b5622ca420010514 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 20 Aug 2009 00:56:05 +0200 Subject: [PATCH] move over lots of code to the _libssh2_list_* functions and I fixed a few minor bugs at the same time --- src/channel.c | 154 +++++++++++++++------------------------------ src/libssh2_priv.h | 42 +++++-------- src/packet.c | 154 +++++++++++++++------------------------------ src/session.c | 42 +++++++------ src/sftp.c | 28 ++------- src/transport.c | 11 ++-- 6 files changed, 150 insertions(+), 281 deletions(-) diff --git a/src/channel.c b/src/channel.c index e5be1cd..105f197 100644 --- a/src/channel.c +++ b/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; diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h index 96af41f..7b9abad 100644 --- a/src/libssh2_priv.h +++ b/src/libssh2_priv.h @@ -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; diff --git a/src/packet.c b/src/packet.c index 4bc0626..aa120f0 100644 --- a/src/packet.c +++ b/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; } diff --git a/src/session.c b/src/session.c index 7b6e88f..158a854 100644 --- a/src/session.c +++ b/src/session.c @@ -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 == diff --git a/src/sftp.c b/src/sftp.c index a3c5b95..ba6c3d9 100644 --- a/src/sftp.c +++ b/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; } diff --git a/src/transport.c b/src/transport.c index ade3826..044a0e6 100644 --- a/src/transport.c +++ b/src/transport.c @@ -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; - } } /*