]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Fix multiple bugs in freeze/thaw of Windows handle-sockets.
authorSimon Tatham <anakin@pobox.com>
Wed, 15 Feb 2017 19:19:38 +0000 (19:19 +0000)
committerSimon Tatham <anakin@pobox.com>
Wed, 15 Feb 2017 19:19:38 +0000 (19:19 +0000)
Firstly, I had asserted that data would never arrive on a handle
socket in state FREEZING, which is just an error, because FREEZING is
precisely the state of not being quite frozen _yet_ because one last
read is still expected to arrive from the winhandl.c reading subthread
which it's too late to cancel. I meant to assert that it wasn't
FROZEN.

Secondly, when the handle socket was in state FREEZING, I failed to
actually _set_ it to FROZEN.

And thirdly, when the handle socket starts thawing again (i.e. there's
now outgoing buffer space so we can start sending our backlogged
data), I forgot to ever call bufchain_consume, so that the same block
of data would get sent repeatedly.

I can only assume that nothing I've ever done has actually exercised
this code!

windows/winhsock.c

index 6c00181589b6f5693facb622b583ab2ab61f1162..7fe02f634d789aad52491cd7b50c7899b1fc5fee 100644 (file)
@@ -57,7 +57,7 @@ static int handle_gotdata(struct handle *h, void *data, int len)
     } else if (len == 0) {
        return plug_closing(ps->plug, NULL, 0, 0);
     } else {
-        assert(ps->frozen != FREEZING && ps->frozen != THAWING);
+        assert(ps->frozen != FROZEN && ps->frozen != THAWING);
         if (ps->frozen == FREEZING) {
             /*
              * If we've received data while this socket is supposed to
@@ -66,6 +66,7 @@ static int handle_gotdata(struct handle *h, void *data, int len)
              * the data for when we unfreeze.
              */
             bufchain_add(&ps->inputdata, data, len);
+            ps->frozen = FROZEN;
 
             /*
              * And return a very large backlog, to prevent further
@@ -171,6 +172,7 @@ static void handle_socket_unfreeze(void *psv)
      * Hand it off to the plug.
      */
     new_backlog = plug_receive(ps->plug, 0, data, len);
+    bufchain_consume(&ps->inputdata, len);
 
     if (bufchain_size(&ps->inputdata) > 0) {
         /*