version 1.308, 2010/07/13 23:13:16 |
version 1.309, 2010/08/05 13:08:42 |
|
|
{ |
{ |
struct termios tio; |
struct termios tio; |
u_char *data = NULL, *buf; |
u_char *data = NULL, *buf; |
u_int dlen; |
u_int dlen, olen = 0; |
int len; |
int len; |
|
|
/* Send buffered output data to the socket. */ |
/* Send buffered output data to the socket. */ |
if (c->wfd != -1 && |
if (c->wfd != -1 && |
FD_ISSET(c->wfd, writeset) && |
FD_ISSET(c->wfd, writeset) && |
buffer_len(&c->output) > 0) { |
buffer_len(&c->output) > 0) { |
|
olen = buffer_len(&c->output); |
if (c->output_filter != NULL) { |
if (c->output_filter != NULL) { |
if ((buf = c->output_filter(c, &data, &dlen)) == NULL) { |
if ((buf = c->output_filter(c, &data, &dlen)) == NULL) { |
debug2("channel %d: filter stops", c->self); |
debug2("channel %d: filter stops", c->self); |
|
|
|
|
if (c->datagram) { |
if (c->datagram) { |
/* ignore truncated writes, datagrams might get lost */ |
/* ignore truncated writes, datagrams might get lost */ |
c->local_consumed += dlen + 4; |
|
len = write(c->wfd, buf, dlen); |
len = write(c->wfd, buf, dlen); |
xfree(data); |
xfree(data); |
if (len < 0 && (errno == EINTR || errno == EAGAIN)) |
if (len < 0 && (errno == EINTR || errno == EAGAIN)) |
|
|
chan_write_failed(c); |
chan_write_failed(c); |
return -1; |
return -1; |
} |
} |
return 1; |
goto out; |
} |
} |
|
|
len = write(c->wfd, buf, dlen); |
len = write(c->wfd, buf, dlen); |
|
|
} |
} |
} |
} |
buffer_consume(&c->output, len); |
buffer_consume(&c->output, len); |
if (compat20 && len > 0) { |
|
c->local_consumed += len; |
|
} |
|
} |
} |
|
out: |
|
if (compat20 && olen > 0) |
|
c->local_consumed += olen - buffer_len(&c->output); |
return 1; |
return 1; |
} |
} |
|
|
|
|
|
|
data = buffer_get_string(&c->input, |
data = buffer_get_string(&c->input, |
&dlen); |
&dlen); |
|
if (dlen > c->remote_window || |
|
dlen > c->remote_maxpacket) { |
|
debug("channel %d: datagram " |
|
"too big for channel", |
|
c->self); |
|
xfree(data); |
|
continue; |
|
} |
packet_start(SSH2_MSG_CHANNEL_DATA); |
packet_start(SSH2_MSG_CHANNEL_DATA); |
packet_put_int(c->remote_id); |
packet_put_int(c->remote_id); |
packet_put_string(data, dlen); |
packet_put_string(data, dlen); |
|
|
{ |
{ |
int id; |
int id; |
char *data; |
char *data; |
u_int data_len; |
u_int data_len, win_len; |
Channel *c; |
Channel *c; |
|
|
/* Get the channel number and verify it. */ |
/* Get the channel number and verify it. */ |
|
|
|
|
/* Get the data. */ |
/* Get the data. */ |
data = packet_get_string_ptr(&data_len); |
data = packet_get_string_ptr(&data_len); |
|
win_len = data_len; |
|
if (c->datagram) |
|
win_len += 4; /* string length header */ |
|
|
/* |
/* |
* Ignore data for protocol > 1.3 if output end is no longer open. |
* Ignore data for protocol > 1.3 if output end is no longer open. |
|
|
*/ |
*/ |
if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) { |
if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) { |
if (compat20) { |
if (compat20) { |
c->local_window -= data_len; |
c->local_window -= win_len; |
c->local_consumed += data_len; |
c->local_consumed += win_len; |
} |
} |
return; |
return; |
} |
} |
|
|
if (compat20) { |
if (compat20) { |
if (data_len > c->local_maxpacket) { |
if (win_len > c->local_maxpacket) { |
logit("channel %d: rcvd big packet %d, maxpack %d", |
logit("channel %d: rcvd big packet %d, maxpack %d", |
c->self, data_len, c->local_maxpacket); |
c->self, win_len, c->local_maxpacket); |
} |
} |
if (data_len > c->local_window) { |
if (win_len > c->local_window) { |
logit("channel %d: rcvd too much data %d, win %d", |
logit("channel %d: rcvd too much data %d, win %d", |
c->self, data_len, c->local_window); |
c->self, win_len, c->local_window); |
return; |
return; |
} |
} |
c->local_window -= data_len; |
c->local_window -= win_len; |
} |
} |
if (c->datagram) |
if (c->datagram) |
buffer_put_string(&c->output, data, data_len); |
buffer_put_string(&c->output, data, data_len); |