From: Simon Tatham Date: Wed, 15 Feb 2017 19:19:38 +0000 (+0000) Subject: Fix multiple bugs in freeze/thaw of Windows handle-sockets. X-Git-Tag: 0.68~16 X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=commitdiff_plain;h=2fb3e26584315e1d962226de40686c4cd7530bb7;p=PuTTY.git Fix multiple bugs in freeze/thaw of Windows handle-sockets. 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! --- diff --git a/windows/winhsock.c b/windows/winhsock.c index 6c001815..7fe02f63 100644 --- a/windows/winhsock.c +++ b/windows/winhsock.c @@ -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) { /*