"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
fix spurious flush packet error from gotsh
To:
gameoftrees@openbsd.org
Date:
Wed, 18 Jan 2023 18:19:47 +0100

Download raw body.

Thread
This fixes the spurious "gotsh: unexpected flush packet" error
which sometimes shows up when a client trying to fetch changes
is already up-to-date.

Still explicitly check for a zero-length packet with a payload
to keep test_request_bad_length_zero passing.

ok?
 
diff 05594ba5c50d7a7b10882b9504d75bdd5df348a3 dd990646894efbf02dc48384fade1054276c5521
commit - 05594ba5c50d7a7b10882b9504d75bdd5df348a3
commit + dd990646894efbf02dc48384fade1054276c5521
blob - 02c4cb511fe756c9101538c93243233f34941dd2
blob + ff9cd1e8a402bfed028e0aa1db7d6cf94c159eb4
--- lib/serve.c
+++ lib/serve.c
@@ -898,13 +898,36 @@ serve_read(int infd, int outfd, int gotd_sock, const c
 		if (err)
 			break;
 		if (n == 0) {
-			if (curstate != STATE_EXPECT_MORE_WANT &&
+			if (curstate != STATE_EXPECT_WANT &&
+			    curstate != STATE_EXPECT_MORE_WANT &&
 			    curstate != STATE_EXPECT_HAVE &&
 			    curstate != STATE_EXPECT_DONE) {
 				err = got_error_msg(GOT_ERR_BAD_PACKET,
 				    "unexpected flush packet received");
 				goto done;
 			}
+
+			if (curstate == STATE_EXPECT_WANT) {
+				ssize_t r;
+				/*
+				 * If the client does not want to fetch
+				 * anything we should receive a flush
+				 * packet followed by EOF.
+				 */
+				r = read(infd, buf, sizeof(buf));
+				if (r == -1) {
+					err = got_error_from_errno("read");
+					goto done;
+				}
+				if (r == 0) /* EOF */
+					goto done;
+
+				/* Zero-length field followed by payload. */
+				err = got_error_msg(GOT_ERR_BAD_PACKET,
+				    "unexpected flush packet received");
+				goto done;
+			}
+
 			err = forward_flushpkt(&ibuf);
 			if (err)
 				goto done;