Add a bug-compatibility flag to disable the
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sat, 28 Jul 2012 19:30:12 +0000 (19:30 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sat, 28 Jul 2012 19:30:12 +0000 (19:30 +0000)
winadj@putty.projects.tartarus.org request. Not currently enabled
automatically, but should be usable as a manual workaround.

git-svn-id: svn://svn.tartarus.org/sgt/putty@9592 cda61777-01e9-0310-a592-d414129be87e

config.c
doc/config.but
putty.h
settings.c
ssh.c
windows/winhelp.h

index e2a7951..b0b0092 100644 (file)
--- a/config.c
+++ b/config.c
@@ -2457,6 +2457,9 @@ void setup_config_box(struct controlbox *b, int midsession,
            ctrl_droplist(s, "Chokes on SSH-2 ignore messages", '2', 20,
                          HELPCTX(ssh_bugs_ignore2),
                          sshbug_handler, I(CONF_sshbug_ignore2));
            ctrl_droplist(s, "Chokes on SSH-2 ignore messages", '2', 20,
                          HELPCTX(ssh_bugs_ignore2),
                          sshbug_handler, I(CONF_sshbug_ignore2));
+           ctrl_droplist(s, "Chokes on PuTTY's SSH-2 'winadj' requests", 'j',
+                          20, HELPCTX(ssh_bugs_winadj),
+                         sshbug_handler, I(CONF_sshbug_winadj));
            ctrl_droplist(s, "Miscomputes SSH-2 HMAC keys", 'm', 20,
                          HELPCTX(ssh_bugs_hmac2),
                          sshbug_handler, I(CONF_sshbug_hmac2));
            ctrl_droplist(s, "Miscomputes SSH-2 HMAC keys", 'm', 20,
                          HELPCTX(ssh_bugs_hmac2),
                          sshbug_handler, I(CONF_sshbug_hmac2));
index 9842758..6d81248 100644 (file)
@@ -3208,6 +3208,29 @@ send an over-sized packet.  If this bug is enabled when talking to a
 correct server, the session will work correctly, but download
 performance will be less than it could be.
 
 correct server, the session will work correctly, but download
 performance will be less than it could be.
 
+\S{config-ssh-bug-winadj} \q{Chokes on PuTTY's SSH-2 \cq{winadj} requests}
+
+\cfg{winhelp-topic}{ssh.bugs.winadj}
+
+PuTTY sometimes sends a special request to SSH servers in the middle
+of channel data, with the name \cw{winadj@putty.projects.tartarus.org}
+(see \k{sshnames-channel}). The purpose of this request is to measure
+the round-trip time to the server, which PuTTY uses to tune its flow
+control. The server does not actually have to \e{understand} the
+message; it is expected to send back a \cw{SSH_MSG_CHANNEL_FAILURE}
+message indicating that it didn't understand it. (All PuTTY needs for
+its timing calculations is \e{some} kind of response.)
+
+It has been known for some SSH servers to get confused by this message
+in one way or another \dash because it has a long name, or because
+they can't cope with unrecognised request names even to the extent of
+sending back the correct failure response, or because they handle it
+sensibly but fill up the server's log file with pointless spam, or
+whatever. PuTTY therefore supports this bug-compatibility flag: if it
+believes the server has this bug, it will never send its
+\cq{winadj@putty.projects.tartarus.org} request, and will make do
+without its timing data.
+
 \H{config-serial} The Serial panel
 
 The \i{Serial} panel allows you to configure options that only apply
 \H{config-serial} The Serial panel
 
 The \i{Serial} panel allows you to configure options that only apply
diff --git a/putty.h b/putty.h
index dcc80db..bc400fb 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -836,6 +836,7 @@ void cleanup_exit(int);
     X(INT, NONE, sshbug_rekey2) \
     X(INT, NONE, sshbug_maxpkt2) \
     X(INT, NONE, sshbug_ignore2) \
     X(INT, NONE, sshbug_rekey2) \
     X(INT, NONE, sshbug_maxpkt2) \
     X(INT, NONE, sshbug_ignore2) \
+    X(INT, NONE, sshbug_winadj) \
     /*                                                                \
      * ssh_simple means that we promise never to open any channel     \
      * other than the main one, which means it can safely use a very  \
     /*                                                                \
      * ssh_simple means that we promise never to open any channel     \
      * other than the main one, which means it can safely use a very  \
index 5d8f0c4..a561602 100644 (file)
@@ -620,6 +620,7 @@ void save_open_settings(void *sesskey, Conf *conf)
     write_setting_i(sesskey, "BugPKSessID2", 2-conf_get_int(conf, CONF_sshbug_pksessid2));
     write_setting_i(sesskey, "BugRekey2", 2-conf_get_int(conf, CONF_sshbug_rekey2));
     write_setting_i(sesskey, "BugMaxPkt2", 2-conf_get_int(conf, CONF_sshbug_maxpkt2));
     write_setting_i(sesskey, "BugPKSessID2", 2-conf_get_int(conf, CONF_sshbug_pksessid2));
     write_setting_i(sesskey, "BugRekey2", 2-conf_get_int(conf, CONF_sshbug_rekey2));
     write_setting_i(sesskey, "BugMaxPkt2", 2-conf_get_int(conf, CONF_sshbug_maxpkt2));
+    write_setting_i(sesskey, "BugWinadj", 2-conf_get_int(conf, CONF_sshbug_winadj));
     write_setting_i(sesskey, "StampUtmp", conf_get_int(conf, CONF_stamp_utmp));
     write_setting_i(sesskey, "LoginShell", conf_get_int(conf, CONF_login_shell));
     write_setting_i(sesskey, "ScrollbarOnLeft", conf_get_int(conf, CONF_scrollbar_on_left));
     write_setting_i(sesskey, "StampUtmp", conf_get_int(conf, CONF_stamp_utmp));
     write_setting_i(sesskey, "LoginShell", conf_get_int(conf, CONF_login_shell));
     write_setting_i(sesskey, "ScrollbarOnLeft", conf_get_int(conf, CONF_scrollbar_on_left));
@@ -960,6 +961,7 @@ void load_open_settings(void *sesskey, Conf *conf)
     i = gppi_raw(sesskey, "BugPKSessID2", 0); conf_set_int(conf, CONF_sshbug_pksessid2, 2-i);
     i = gppi_raw(sesskey, "BugRekey2", 0); conf_set_int(conf, CONF_sshbug_rekey2, 2-i);
     i = gppi_raw(sesskey, "BugMaxPkt2", 0); conf_set_int(conf, CONF_sshbug_maxpkt2, 2-i);
     i = gppi_raw(sesskey, "BugPKSessID2", 0); conf_set_int(conf, CONF_sshbug_pksessid2, 2-i);
     i = gppi_raw(sesskey, "BugRekey2", 0); conf_set_int(conf, CONF_sshbug_rekey2, 2-i);
     i = gppi_raw(sesskey, "BugMaxPkt2", 0); conf_set_int(conf, CONF_sshbug_maxpkt2, 2-i);
+    i = gppi_raw(sesskey, "BugWinadj", 0); conf_set_int(conf, CONF_sshbug_winadj, 2-i);
     conf_set_int(conf, CONF_ssh_simple, FALSE);
     gppi(sesskey, "StampUtmp", 1, conf, CONF_stamp_utmp);
     gppi(sesskey, "LoginShell", 1, conf, CONF_login_shell);
     conf_set_int(conf, CONF_ssh_simple, FALSE);
     gppi(sesskey, "StampUtmp", 1, conf, CONF_stamp_utmp);
     gppi(sesskey, "LoginShell", 1, conf, CONF_login_shell);
diff --git a/ssh.c b/ssh.c
index 1f1a265..351003f 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -196,6 +196,7 @@ static const char *const ssh2_disconnect_reasons[] = {
 #define BUG_SSH2_PK_SESSIONID                   128
 #define BUG_SSH2_MAXPKT                                256
 #define BUG_CHOKES_ON_SSH2_IGNORE               512
 #define BUG_SSH2_PK_SESSIONID                   128
 #define BUG_SSH2_MAXPKT                                256
 #define BUG_CHOKES_ON_SSH2_IGNORE               512
+#define BUG_CHOKES_ON_WINADJ                   1024
 
 /*
  * Codes for terminal modes.
 
 /*
  * Codes for terminal modes.
@@ -2580,6 +2581,15 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring)
        ssh->remote_bugs |= BUG_CHOKES_ON_SSH2_IGNORE;
        logevent("We believe remote version has SSH-2 ignore bug");
     }
        ssh->remote_bugs |= BUG_CHOKES_ON_SSH2_IGNORE;
        logevent("We believe remote version has SSH-2 ignore bug");
     }
+
+    if (conf_get_int(ssh->conf, CONF_sshbug_winadj) == FORCE_ON) {
+       /*
+        * Servers that don't support our winadj request for one
+        * reason or another. Currently, none detected automatically.
+        */
+       ssh->remote_bugs |= BUG_CHOKES_ON_WINADJ;
+       logevent("We believe remote version has winadj bug");
+    }
 }
 
 /*
 }
 
 /*
@@ -6635,7 +6645,8 @@ static void ssh2_set_window(struct ssh_channel *c, int newwin)
         * unexpected CHANNEL_FAILUREs.
         */
        if (newwin == c->v.v2.locmaxwin &&
         * unexpected CHANNEL_FAILUREs.
         */
        if (newwin == c->v.v2.locmaxwin &&
-           ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE]) {
+           ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE] &&
+            !(ssh->remote_bugs & BUG_CHOKES_ON_WINADJ)) {
            pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
            ssh2_pkt_adduint32(pktout, c->remoteid);
            ssh2_pkt_addstring(pktout, "winadj@putty.projects.tartarus.org");
            pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
            ssh2_pkt_adduint32(pktout, c->remoteid);
            ssh2_pkt_addstring(pktout, "winadj@putty.projects.tartarus.org");
index fbc03f3..ca9c721 100644 (file)
 #define WINHELP_CTX_ssh_bugs_pksessid2 "ssh.bugs.pksessid2:config-ssh-bug-pksessid2"
 #define WINHELP_CTX_ssh_bugs_rekey2 "ssh.bugs.rekey2:config-ssh-bug-rekey"
 #define WINHELP_CTX_ssh_bugs_maxpkt2 "ssh.bugs.maxpkt2:config-ssh-bug-maxpkt2"
 #define WINHELP_CTX_ssh_bugs_pksessid2 "ssh.bugs.pksessid2:config-ssh-bug-pksessid2"
 #define WINHELP_CTX_ssh_bugs_rekey2 "ssh.bugs.rekey2:config-ssh-bug-rekey"
 #define WINHELP_CTX_ssh_bugs_maxpkt2 "ssh.bugs.maxpkt2:config-ssh-bug-maxpkt2"
+#define WINHELP_CTX_ssh_bugs_winadj "ssh.bugs.winadj:config-ssh-bug-winadj"
 #define WINHELP_CTX_serial_line "serial.line:config-serial-line"
 #define WINHELP_CTX_serial_speed "serial.speed:config-serial-speed"
 #define WINHELP_CTX_serial_databits "serial.databits:config-serial-databits"
 #define WINHELP_CTX_serial_line "serial.line:config-serial-line"
 #define WINHELP_CTX_serial_speed "serial.speed:config-serial-speed"
 #define WINHELP_CTX_serial_databits "serial.databits:config-serial-databits"