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 <[email protected]> --- 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 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot _______________________________________________ Nbd-general mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/nbd-general
