summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
885f465)
as well. This won't be triggered in the usual case, but it's useful
if the remote end ignores our window, or if we're in "simple" mode and
setting the window far larger than is necessary.
git-svn-id: svn://svn.tartarus.org/sgt/putty@7756
cda61777-01e9-0310-a592-
d414129be87e
* A channel is completely finished with when all four bits are set.
*/
int closes;
* A channel is completely finished with when all four bits are set.
*/
int closes;
+ /*
+ * True if this channel is causing the underlying connection to be
+ * throttled.
+ */
+ int throttling_conn;
- struct ssh1_data_channel {
- int throttling;
- } v1;
struct ssh2_data_channel {
bufchain outbuffer;
unsigned remwindow, remmaxpkt;
struct ssh2_data_channel {
bufchain outbuffer;
unsigned remwindow, remmaxpkt;
void *x11auth;
int version;
void *x11auth;
int version;
+ int conn_throttle_count;
int overall_bufsize;
int throttled_all;
int v1_stdout_throttling;
int overall_bufsize;
int throttled_all;
int v1_stdout_throttling;
/*
* Throttle or unthrottle the SSH connection.
*/
/*
* Throttle or unthrottle the SSH connection.
*/
-static void ssh1_throttle(Ssh ssh, int adjust)
+static void ssh_throttle_conn(Ssh ssh, int adjust)
- int old_count = ssh->v1_throttle_count;
- ssh->v1_throttle_count += adjust;
- assert(ssh->v1_throttle_count >= 0);
- if (ssh->v1_throttle_count && !old_count) {
+ int old_count = ssh->conn_throttle_count;
+ ssh->conn_throttle_count += adjust;
+ assert(ssh->conn_throttle_count >= 0);
+ if (ssh->conn_throttle_count && !old_count) {
- } else if (!ssh->v1_throttle_count && old_count) {
+ } else if (!ssh->conn_throttle_count && old_count) {
ssh_set_frozen(ssh, 0);
}
}
ssh_set_frozen(ssh, 0);
}
}
void sshfwd_unthrottle(struct ssh_channel *c, int bufsize)
{
Ssh ssh = c->ssh;
void sshfwd_unthrottle(struct ssh_channel *c, int bufsize)
{
Ssh ssh = c->ssh;
if (ssh->state == SSH_STATE_CLOSED)
return;
if (ssh->version == 1) {
if (ssh->state == SSH_STATE_CLOSED)
return;
if (ssh->version == 1) {
- if (c->v.v1.throttling && bufsize < SSH1_BUFFER_LIMIT) {
- c->v.v1.throttling = 0;
- ssh1_throttle(ssh, -1);
- }
+ buflimit = SSH1_BUFFER_LIMIT;
- ssh2_set_window(c, c->v.v2.locmaxwin - bufsize);
+ buflimit = c->v.v2.locmaxwin;
+ ssh2_set_window(c, bufsize < buflimit ? buflimit - bufsize : 0);
+ }
+ if (c->throttling_conn && bufsize <= buflimit) {
+ c->throttling_conn = 0;
+ ssh_throttle_conn(ssh, -1);
string, stringlen);
if (!ssh->v1_stdout_throttling && bufsize > SSH1_BUFFER_LIMIT) {
ssh->v1_stdout_throttling = 1;
string, stringlen);
if (!ssh->v1_stdout_throttling && bufsize > SSH1_BUFFER_LIMIT) {
ssh->v1_stdout_throttling = 1;
- ssh1_throttle(ssh, +1);
+ ssh_throttle_conn(ssh, +1);
c->halfopen = FALSE;
c->localid = alloc_channel_id(ssh);
c->closes = 0;
c->halfopen = FALSE;
c->localid = alloc_channel_id(ssh);
c->closes = 0;
- c->v.v1.throttling = 0;
+ c->throttling_conn = 0;
c->type = CHAN_X11; /* identify channel type */
add234(ssh->channels, c);
send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
c->type = CHAN_X11; /* identify channel type */
add234(ssh->channels, c);
send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
c->halfopen = FALSE;
c->localid = alloc_channel_id(ssh);
c->closes = 0;
c->halfopen = FALSE;
c->localid = alloc_channel_id(ssh);
c->closes = 0;
- c->v.v1.throttling = 0;
+ c->throttling_conn = 0;
c->type = CHAN_AGENT; /* identify channel type */
c->u.a.lensofar = 0;
add234(ssh->channels, c);
c->type = CHAN_AGENT; /* identify channel type */
c->u.a.lensofar = 0;
add234(ssh->channels, c);
c->halfopen = FALSE;
c->localid = alloc_channel_id(ssh);
c->closes = 0;
c->halfopen = FALSE;
c->localid = alloc_channel_id(ssh);
c->closes = 0;
- c->v.v1.throttling = 0;
+ c->throttling_conn = 0;
c->type = CHAN_SOCKDATA; /* identify channel type */
add234(ssh->channels, c);
send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
c->type = CHAN_SOCKDATA; /* identify channel type */
add234(ssh->channels, c);
send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
c->remoteid = localid;
c->halfopen = FALSE;
c->type = CHAN_SOCKDATA;
c->remoteid = localid;
c->halfopen = FALSE;
c->type = CHAN_SOCKDATA;
- c->v.v1.throttling = 0;
+ c->throttling_conn = 0;
pfd_confirm(c->u.pfd.s);
}
pfd_confirm(c->u.pfd.s);
}
bufsize = 0; /* agent channels never back up */
break;
}
bufsize = 0; /* agent channels never back up */
break;
}
- if (!c->v.v1.throttling && bufsize > SSH1_BUFFER_LIMIT) {
- c->v.v1.throttling = 1;
- ssh1_throttle(ssh, +1);
+ if (!c->throttling_conn && bufsize > SSH1_BUFFER_LIMIT) {
+ c->throttling_conn = 1;
+ ssh_throttle_conn(ssh, +1);
*/
ssh2_set_window(c, bufsize < c->v.v2.locmaxwin ?
c->v.v2.locmaxwin - bufsize : 0);
*/
ssh2_set_window(c, bufsize < c->v.v2.locmaxwin ?
c->v.v2.locmaxwin - bufsize : 0);
+ /*
+ * If we're either buffering way too much data, or if we're
+ * buffering anything at all and we're in "simple" mode,
+ * throttle the whole channel.
+ */
+ if ((bufsize > c->v.v2.locmaxwin ||
+ (ssh->cfg.ssh_simple && bufsize > 0)) &&
+ !c->throttling_conn) {
+ c->throttling_conn = 1;
+ ssh_throttle_conn(ssh, +1);
+ }
} else {
c->localid = alloc_channel_id(ssh);
c->closes = 0;
} else {
c->localid = alloc_channel_id(ssh);
c->closes = 0;
+ c->throttling_conn = FALSE;
c->v.v2.locwindow = c->v.v2.locmaxwin = OUR_V2_WINSIZE;
c->v.v2.remwindow = winsize;
c->v.v2.remmaxpkt = pktsize;
c->v.v2.locwindow = c->v.v2.locmaxwin = OUR_V2_WINSIZE;
c->v.v2.remwindow = winsize;
c->v.v2.remmaxpkt = pktsize;
s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
ssh2_pkt_addstring(s->pktout, "direct-tcpip");
ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
ssh2_pkt_addstring(s->pktout, "direct-tcpip");
ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
+ ssh->mainchan->throttling_conn = FALSE;
ssh->mainchan->v.v2.locwindow = ssh->mainchan->v.v2.locmaxwin =
ssh->mainchan->v.v2.remlocwin =
ssh->cfg.ssh_simple ? OUR_V2_BIGWIN : OUR_V2_WINSIZE;
ssh->mainchan->v.v2.locwindow = ssh->mainchan->v.v2.locmaxwin =
ssh->mainchan->v.v2.remlocwin =
ssh->cfg.ssh_simple ? OUR_V2_BIGWIN : OUR_V2_WINSIZE;
s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
ssh2_pkt_addstring(s->pktout, "session");
ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
ssh2_pkt_addstring(s->pktout, "session");
ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
+ ssh->mainchan->throttling_conn = FALSE;
ssh->mainchan->v.v2.locwindow = ssh->mainchan->v.v2.locmaxwin =
ssh->mainchan->v.v2.remlocwin =
ssh->cfg.ssh_simple ? OUR_V2_BIGWIN : OUR_V2_WINSIZE;
ssh->mainchan->v.v2.locwindow = ssh->mainchan->v.v2.locmaxwin =
ssh->mainchan->v.v2.remlocwin =
ssh->cfg.ssh_simple ? OUR_V2_BIGWIN : OUR_V2_WINSIZE;
ssh->send_ok = 0;
ssh->editing = 0;
ssh->echoing = 0;
ssh->send_ok = 0;
ssh->editing = 0;
ssh->echoing = 0;
- ssh->v1_throttle_count = 0;
+ ssh->conn_throttle_count = 0;
ssh->overall_bufsize = 0;
ssh->fallback_cmd = 0;
ssh->overall_bufsize = 0;
ssh->fallback_cmd = 0;
static void ssh_unthrottle(void *handle, int bufsize)
{
Ssh ssh = (Ssh) handle;
static void ssh_unthrottle(void *handle, int bufsize)
{
Ssh ssh = (Ssh) handle;
if (ssh->version == 1) {
if (ssh->v1_stdout_throttling && bufsize < SSH1_BUFFER_LIMIT) {
ssh->v1_stdout_throttling = 0;
if (ssh->version == 1) {
if (ssh->v1_stdout_throttling && bufsize < SSH1_BUFFER_LIMIT) {
ssh->v1_stdout_throttling = 0;
- ssh1_throttle(ssh, -1);
+ ssh_throttle_conn(ssh, -1);
ssh2_set_window(ssh->mainchan,
ssh2_set_window(ssh->mainchan,
- ssh->mainchan->v.v2.locmaxwin - bufsize);
+ bufsize < ssh->mainchan->v.v2.locmaxwin ?
+ ssh->mainchan->v.v2.locmaxwin - bufsize : 0);
+ if (ssh->cfg.ssh_simple)
+ buflimit = 0;
+ else
+ buflimit = ssh->mainchan->v.v2.locmaxwin;
+ if (ssh->mainchan->throttling_conn && bufsize <= buflimit) {
+ ssh->mainchan->throttling_conn = 0;
+ ssh_throttle_conn(ssh, -1);
+ }
+ }
pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
ssh2_pkt_addstring(pktout, "direct-tcpip");
ssh2_pkt_adduint32(pktout, c->localid);
pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
ssh2_pkt_addstring(pktout, "direct-tcpip");
ssh2_pkt_adduint32(pktout, c->localid);
+ c->throttling_conn = FALSE;
c->v.v2.locwindow = c->v.v2.locmaxwin = OUR_V2_WINSIZE;
c->v.v2.remlocwin = OUR_V2_WINSIZE;
c->v.v2.winadj_head = c->v.v2.winadj_head = NULL;
c->v.v2.locwindow = c->v.v2.locmaxwin = OUR_V2_WINSIZE;
c->v.v2.remlocwin = OUR_V2_WINSIZE;
c->v.v2.winadj_head = c->v.v2.winadj_head = NULL;