1
1

Save up multiple small refunds in order to cut down on unnecessary WINDOW_ADJUST packets

Этот коммит содержится в:
Sara Golemon 2005-05-18 17:08:29 +00:00
родитель 7502920c7f
Коммит cc7703092f
4 изменённых файлов: 56 добавлений и 42 удалений

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

@ -67,7 +67,7 @@ typedef unsigned long long libssh2_uint64_t;
typedef long long libssh2_int64_t;
#endif
#define LIBSSH2_VERSION "0.9"
#define LIBSSH2_VERSION "0.10"
#define LIBSSH2_APINO 200503281457
/* Part of every banner, user specified or not */
@ -279,6 +279,7 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
/* Channel API */
#define LIBSSH2_CHANNEL_WINDOW_DEFAULT 65536
#define LIBSSH2_CHANNEL_PACKET_DEFAULT 16384
#define LIBSSH2_CHANNEL_MINADJUST 1024
/* Extended Data Handling */
#define LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL 0
@ -321,6 +322,8 @@ LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id,
LIBSSH2_API unsigned long libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, unsigned long *read_avail, unsigned long *window_size_initial);
#define libssh2_channel_window_read(channel) libssh2_channel_window_read_ex((channel), NULL, NULL)
LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, unsigned long adjustment, unsigned char force);
LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id, const char *buf, size_t buflen);
#define libssh2_channel_write(channel, buf, buflen) libssh2_channel_write_ex((channel), 0, (buf), (buflen))
#define libssh2_channel_write_stderr(channel, buf, buflen) libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))

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

@ -113,6 +113,7 @@ struct _LIBSSH2_CHANNEL {
int blocking;
libssh2_channel_data local, remote;
unsigned long adjust_queue; /* Amount of bytes to be refunded to receive window (but not yet sent) */
LIBSSH2_SESSION *session;

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

@ -780,28 +780,59 @@ LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid)
}
if (refund_bytes && channel->remote.window_size_initial) {
unsigned char adjust[9]; /* packet_type(1) + channel(4) + adjustment(4) */
/* Adjust the window based on the block we just freed */
adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST;
libssh2_htonu32(adjust + 1, channel->remote.id);
libssh2_htonu32(adjust + 5, refund_bytes);
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Adjusting window %lu bytes for data flushed from channel %lu/%lu", refund_bytes, channel->local.id, channel->remote.id);
#endif
if (libssh2_packet_write(channel->session, adjust, 9)) {
libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send transfer-window adjustment packet", 0);
return -1;
} else {
channel->remote.window_size += refund_bytes;
}
libssh2_channel_receive_window_adjust(channel, refund_bytes, 0);
}
return flush_bytes;
}
/* }}} */
/* {{{ libssh2_channel_receive_window_adjust
* Adjust the receive window for a channel by adjustment bytes
* If the amount to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0
* The adjustment amount will be queued for a later packet
*
* Returns the new size of the receive window (as understood by remote end)
*/
LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, unsigned long adjustment, unsigned char force)
{
unsigned char adjust[9]; /* packet_type(1) + channel(4) + adjustment(4) */
if (!force && (adjustment + channel->adjust_queue < LIBSSH2_CHANNEL_MINADJUST)) {
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Queing %lu bytes for receive window adjustment for channel %lu/%lu", adjustment, channel->local.id, channel->remote.id);
#endif
channel->adjust_queue += adjustment;
return channel->remote.window_size;
}
if (!adjustment && !channel->adjust_queue) {
return channel->remote.window_size;
}
adjustment += channel->adjust_queue;
channel->adjust_queue = 0;
/* Adjust the window based on the block we just freed */
adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST;
libssh2_htonu32(adjust + 1, channel->remote.id);
libssh2_htonu32(adjust + 5, adjustment);
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Adjusting window %lu bytes for data flushed from channel %lu/%lu", adjustment, channel->local.id, channel->remote.id);
#endif
if (libssh2_packet_write(channel->session, adjust, 9)) {
libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send transfer-window adjustment packet, deferring", 0);
channel->adjust_queue = adjustment;
} else {
channel->remote.window_size += adjustment;
}
return channel->remote.window_size;
}
/* }}} */
/* {{{ libssh2_channel_handle_extended_data
* How should extended data look to the calling app?
* Keep it in separate channels[_read() _read_stdder()]? (NORMAL)
@ -866,8 +897,6 @@ LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id,
bytes_read += want;
if (unlink_packet) {
unsigned char adjust[9]; /* packet_type(1) + channel(4) + adjustment(4) */
if (packet->prev) {
packet->prev->next = packet->next;
} else {
@ -881,20 +910,9 @@ LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id,
LIBSSH2_FREE(session, packet->data);
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Unlinking empty packet buffer from channel %lu/%lu sending window adjust for %d bytes", channel->local.id, channel->remote.id, (int)(packet->data_len - (stream_id ? 13 : 9)));
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Unlinking empty packet buffer from channel %lu/%lu", channel->local.id, channel->remote.id);
#endif
/* Adjust the window based on the block we just freed */
adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST;
libssh2_htonu32(adjust + 1, channel->remote.id);
libssh2_htonu32(adjust + 5, packet->data_len - (stream_id ? 13 : 9));
if (libssh2_packet_write(session, adjust, 9)) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send transfer-window adjustment packet", 0);
} else {
/* Don't forget to acknowledge the adjust on this end */
channel->remote.window_size += (packet->data_len - (stream_id ? 13 : 9));
}
libssh2_channel_receive_window_adjust(channel, packet->data_len - (stream_id ? 13 : 9), 0);
LIBSSH2_FREE(session, packet);
}
}

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

@ -446,19 +446,11 @@ static int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, siz
LIBSSH2_FREE(session, data);
if (channel->remote.window_size_initial) {
/* Adjust the window based on the block we just freed */
unsigned char adjust[9];
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Ignoring extended data and refunding %d bytes", (int)(datalen - 13));
#endif
adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST;
libssh2_htonu32(adjust + 1, channel->remote.id);
libssh2_htonu32(adjust + 5, datalen - 13);
if (libssh2_packet_write(channel->session, adjust, 9)) {
libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send transfer-window adjustment packet", 0);
}
/* Adjust the window based on the block we just freed */
libssh2_channel_receive_window_adjust(channel, datalen - 13, 0);
}
return 0;
}