I think this should fix various problems with queued incoming data not being
authorjacob <jacob@cda61777-01e9-0310-a592-d414129be87e>
Fri, 26 Aug 2005 21:17:49 +0000 (21:17 +0000)
committerjacob <jacob@cda61777-01e9-0310-a592-d414129be87e>
Fri, 26 Aug 2005 21:17:49 +0000 (21:17 +0000)
processed and incoming data being processed out of order, which I suspect is
the cause of `ssh1-fwd-trouble' as noted by Gevan Dutton. I'm not able to
test the failure case, but it doesn't seem to have obviously broken anything
in the cases I have tested, anyway.

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

ssh.c

diff --git a/ssh.c b/ssh.c
index e0556a6..349ef18 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -2496,24 +2496,29 @@ static void ssh_gotdata(Ssh ssh, unsigned char *data, int datalen)
      * everything to s_rdpkt, and then pass the resulting packets
      * to the proper protocol handler.
      */
-    if (datalen == 0)
-       crReturnV;
-
-    /*
-     * Process queued data if there is any.
-     */
-    ssh_process_queued_incoming_data(ssh);
 
     while (1) {
-       while (datalen > 0) {
-           if (ssh->frozen)
+       while (bufchain_size(&ssh->queued_incoming_data) > 0 || datalen > 0) {
+           if (ssh->frozen) {
                ssh_queue_incoming_data(ssh, &data, &datalen);
-
-           ssh_process_incoming_data(ssh, &data, &datalen);
-
+               /* This uses up all data and cannot cause anything interesting
+                * to happen; indeed, for anything to happen at all, we must
+                * return, so break out. */
+               break;
+           } else if (bufchain_size(&ssh->queued_incoming_data) > 0) {
+               /* This uses up some or all data, and may freeze the
+                * session. */
+               ssh_process_queued_incoming_data(ssh);
+           } else {
+               /* This uses up some or all data, and may freeze the
+                * session. */
+               ssh_process_incoming_data(ssh, &data, &datalen);
+           }
+           /* FIXME this is probably EBW. */
            if (ssh->state == SSH_STATE_CLOSED)
                return;
        }
+       /* We're out of data. Go and get some more. */
        crReturnV;
     }
     crFinishV;