Split out nbd_receive_simple_option to be reused for structured reply option.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> --- nbd/client.c | 54 +++++++++++++++++++++++++++++++++++------------------- nbd/nbd-internal.h | 14 ++++++++++++++ 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/nbd/client.c b/nbd/client.c index de5c9366c7..6caf6bda6d 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -395,39 +395,55 @@ static int nbd_receive_query_exports(QIOChannel *ioc, } } -static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, - QCryptoTLSCreds *tlscreds, - const char *hostname, Error **errp) +static int nbd_receive_simple_option(QIOChannel *ioc, int opt, + bool abort_on_notsup, Error **errp) { nbd_opt_reply reply; - QIOChannelTLS *tioc; - struct NBDTLSHandshakeData data = { 0 }; - TRACE("Requesting TLS from server"); - if (nbd_send_option_request(ioc, NBD_OPT_STARTTLS, 0, NULL, errp) < 0) { - return NULL; + TRACE("Requesting '%s' option from server", nbd_opt_name(opt)); + if (nbd_send_option_request(ioc, opt, 0, NULL, errp) < 0) { + return -1; } - TRACE("Getting TLS reply from server"); - if (nbd_receive_option_reply(ioc, NBD_OPT_STARTTLS, &reply, errp) < 0) { - return NULL; + TRACE("Getting '%s' option reply from server", nbd_opt_name(opt)); + if (nbd_receive_option_reply(ioc, opt, &reply, errp) < 0) { + return -1; } if (reply.type != NBD_REP_ACK) { - error_setg(errp, "Server rejected request to start TLS %" PRIx32, - reply.type); - nbd_send_opt_abort(ioc); - return NULL; + error_setg(errp, "Server rejected request for '%s' option: %" PRIx32, + nbd_opt_name(opt), reply.type); + if (abort_on_notsup) { + nbd_send_opt_abort(ioc); + } + return -1; } if (reply.length != 0) { - error_setg(errp, "Start TLS response was not zero %" PRIu32, - reply.length); - nbd_send_opt_abort(ioc); + error_setg(errp, "'%s' option response was not zero %" PRIu32, + nbd_opt_name(opt), reply.length); + if (abort_on_notsup) { + nbd_send_opt_abort(ioc); + } + return -1; + } + + TRACE("%s 'option' approved", nbd_opt_name(opt)); + return 0; +} + +static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, + QCryptoTLSCreds *tlscreds, + const char *hostname, Error **errp) +{ + QIOChannelTLS *tioc; + struct NBDTLSHandshakeData data = { 0 }; + + if (nbd_receive_simple_option(ioc, NBD_OPT_STARTTLS, true, errp) < 0) { return NULL; } - TRACE("TLS request approved, setting up TLS"); + TRACE("Setting up TLS"); tioc = qio_channel_tls_new_client(ioc, tlscreds, hostname, errp); if (!tioc) { return NULL; diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h index 489eeaf887..3284bfc85a 100644 --- a/nbd/nbd-internal.h +++ b/nbd/nbd-internal.h @@ -96,6 +96,20 @@ #define NBD_ENOSPC 28 #define NBD_ESHUTDOWN 108 +static inline const char *nbd_opt_name(int opt) +{ + switch (opt) { + case NBD_OPT_EXPORT_NAME: return "export_name"; + case NBD_OPT_ABORT: return "abort"; + case NBD_OPT_LIST: return "list"; + case NBD_OPT_PEEK_EXPORT: return "peek_export"; + case NBD_OPT_STARTTLS: return "tls"; + case NBD_OPT_STRUCTURED_REPLY: return "structured_reply"; + } + + return "<unknown option>"; +} + static inline ssize_t read_sync(QIOChannel *ioc, void *buffer, size_t size) { struct iovec iov = { .iov_base = buffer, .iov_len = size }; -- 2.11.0