1
1

Add "ignore extended data" option to avoid having stderr data fill up

the receive window and leaving no room for stdio data.
Этот коммит содержится в:
Sara Golemon 2004-12-08 03:39:29 +00:00
родитель 2f41af6cdf
Коммит 82e9e2ba0f
4 изменённых файлов: 80 добавлений и 9 удалений

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

@ -202,6 +202,7 @@ LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id
#define libssh2_channel_write_stderr(channel, buf, buflen) libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking);
LIBSSH2_API void libssh2_channel_ignore_extended_data(LIBSSH2_CHANNEL *channel, int ignore);
LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel);
LIBSSH2_API int libssh2_channel_eof(LIBSSH2_CHANNEL *channel);

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

@ -98,7 +98,7 @@ typedef struct _libssh2_channel_data {
unsigned long window_size_initial, window_size, packet_size;
/* Set to 1 when CHANNEL_CLOSE / CHANNEL_EOF sent/received */
int close, eof;
char close, eof, ignore_extended_data;
} libssh2_channel_data;
struct _LIBSSH2_CHANNEL {

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

@ -434,6 +434,56 @@ LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int bloc
}
/* }}} */
/* {{{ libssh2_channel_ignore_extended_data
* Ignore (or stop ignoring) extended data
*/
LIBSSH2_API void libssh2_channel_ignore_extended_data(LIBSSH2_CHANNEL *channel, int ignore)
{
channel->remote.ignore_extended_data = ignore;
if (ignore) {
/* Flush queued extended data */
LIBSSH2_PACKET *packet = channel->session->packets.head;
unsigned long refund_bytes = 0;
while (packet) {
LIBSSH2_PACKET *next = packet->next;
if ((packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (libssh2_ntohu32(packet->data + 1) == channel->local.id)) {
refund_bytes += packet->data_len - 13;
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;
}
LIBSSH2_FREE(channel->session, packet);
}
packet = next;
}
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);
if (libssh2_packet_write(channel->session, adjust, 9)) {
libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send transfer-window adjustment packet", 0);
} else {
channel->remote.window_size += refund_bytes;
}
}
}
}
/* }}} */
/* {{{ libssh2_channel_read_ex
* Read data from a channel
*/
@ -481,16 +531,18 @@ LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id,
}
LIBSSH2_FREE(session, packet->data);
/* 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 (channel->remote.window_size_initial) {
/* 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);
if (libssh2_packet_write(session, adjust, 9)) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send transfer-window adjustment packet", 0);
}
LIBSSH2_FREE(session, packet);
}
LIBSSH2_FREE(session, packet);
}
}
packet = next;

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

@ -153,6 +153,24 @@ static int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, siz
LIBSSH2_FREE(session, data);
return 0;
}
if (channel->remote.ignore_extended_data && (data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) {
/* Pretend we didn't receive this */
LIBSSH2_FREE(session, data);
if (channel->remote.window_size_initial) {
/* Adjust the window based on the block we just freed */
unsigned char adjust[9];
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);
}
}
return 0;
}
/* REMEMBER! remote means remote as source of data, NOT remote window! */
if (channel->remote.packet_size < (datalen - data_head)) {