[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[Nbd] [PATCH v2 5/6] nbd: Test recent bug fixes



Add a test of intentionally provoking a server error during option
negotiation to prove that a client can still fall back to known
options; thus covering two recent bug fixes for a server sending
the wrong length in an error reply, and for a server not reading
enough data when replying to an unknown command.

Signed-off-by: Eric Blake <eblake@...696...>
---
 tests/run/nbd-tester-client.c | 47 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/tests/run/nbd-tester-client.c b/tests/run/nbd-tester-client.c
index 28db8ee..099bec1 100644
--- a/tests/run/nbd-tester-client.c
+++ b/tests/run/nbd-tester-client.c
@@ -403,6 +403,53 @@ int setup_connection_common(int sock, char *name, CONNECTION_TYPE ctype,
 	negotiationflags = htonl(negotiationflags);
 	WRITE_ALL_ERRCHK(sock, &negotiationflags, sizeof(negotiationflags), err,
 			 "Could not write reserved field: %s", strerror(errno));
+	if (handshakeflags & NBD_FLAG_FIXED_NEWSTYLE) {
+		/* Intentionally throw an unknown option at the server */
+		tmp64 = htonll(opts_magic);
+		WRITE_ALL_ERRCHK(sock, &tmp64, sizeof(tmp64), err,
+				 "Could not write magic: %s", strerror(errno));
+		tmp32 = htonl(0x7654321);
+		WRITE_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
+				 "Could not write option: %s", strerror(errno));
+		tmp32 = htonl((uint32_t) sizeof(tmp32));
+		WRITE_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
+				 "Could not write option length: %s", strerror(errno));
+		WRITE_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
+				 "Could not write option payload: %s", strerror(errno));
+		/* Expect proper error from server */
+		READ_ALL_ERRCHK(sock, &tmp64, sizeof(tmp64), err,
+				"Could not read magic: %s", strerror(errno));
+		tmp64 = ntohll(tmp64);
+		if (tmp64 != 0x3e889045565a9LL) {
+			strncpy(errstr, "magic does not match", errstr_len);
+			goto err;
+		}
+		READ_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
+				"Could not read option: %s", strerror(errno));
+		tmp32 = ntohl(tmp32);
+		if (tmp32 != 0x7654321) {
+			strncpy(errstr, "option does not match", errstr_len);
+			goto err;
+		}
+		READ_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
+				"Could not read status: %s", strerror(errno));
+		tmp32 = ntohl(tmp32);
+		if (tmp32 != NBD_REP_ERR_UNSUP) {
+			strncpy(errstr, "status does not match", errstr_len);
+			goto err;
+		}
+		READ_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
+				"Could not read length: %s", strerror(errno));
+		tmp32 = ntohl(tmp32);
+		while (tmp32) {
+			char buf[1024];
+			size_t len = tmp32 < sizeof(buf) ? tmp32 : sizeof(buf);
+			READ_ALL_ERRCHK(sock, buf, len, err,
+					"Could not read payload: %s", strerror(errno));
+			tmp32 -= len;
+		}
+	}
+	/* Now for the real connection */
 	/* magic */
 	tmp64 = htonll(opts_magic);
 	WRITE_ALL_ERRCHK(sock, &tmp64, sizeof(tmp64), err,
-- 
2.7.4




Reply to: