/*
 *  Copyright Red Hat
 *  Copyright (C) 2005  Anthony Liguori <anthony@codemonkey.ws>
 *
 *  Network Block Device Client Side
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; under version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/queue.h"
#include "trace.h"
#include "nbd-internal.h"
#include "qemu/cutils.h"

/* Definitions for opaque data types */

static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);

/* That's all folks */

/* Basic flow for negotiation

   Server         Client
   Negotiate

   or

   Server         Client
   Negotiate #1
                  Option
   Negotiate #2

   ----

   followed by

   Server         Client
                  Request
   Response
                  Request
   Response
                  ...
   ...
                  Request (type == 2)

*/

/* Send an option request.
 *
 * The request is for option @opt, with @data containing @len bytes of
 * additional payload for the request (@len may be -1 to treat @data as
 * a C string; and @data may be NULL if @len is 0).
 * Return 0 if successful, -1 with errp set if it is impossible to
 * continue. */
static int nbd_send_option_request(QIOChannel *ioc, uint32_t opt,
                                   uint32_t len, const char *data,
                                   Error **errp)
{
    ERRP_GUARD();
    NBDOption req;
    QEMU_BUILD_BUG_ON(sizeof(req) != 16);

    if (len == -1) {
        req.length = len = strlen(data);
    }
    trace_nbd_send_option_request(opt, nbd_opt_lookup(opt), len);

    stq_be_p(&req.magic, NBD_OPTS_MAGIC);
    stl_be_p(&req.option, opt);
    stl_be_p(&req.length, len);

    if (nbd_write(ioc, &req, sizeof(req), errp) < 0) {
        error_prepend(errp, "Failed to send option request header: ");
        return -1;
    }

    if (len && nbd_write(ioc, (char *) data, len, errp) < 0) {
        error_prepend(errp, "Failed to send option request data: ");
        return -1;
    }

    return 0;
}

/* Send NBD_OPT_ABORT as a courtesy to let the server know that we are
 * not going to attempt further negotiation. */
static void nbd_send_opt_abort(QIOChannel *ioc)
{
    /* Technically, a compliant server is supposed to reply to us; but
     * older servers disconnected instead. At any rate, we're allowed
     * to disconnect without waiting for the server reply, so we don't
     * even care if the request makes it to the server, let alone
     * waiting around for whether the server replies. */
    nbd_send_option_request(ioc, NBD_OPT_ABORT, 0, NULL, NULL);
}


/* Receive the header of an option reply, which should match the given
 * opt.  Read through the length field, but NOT the length bytes of
 * payload. Return 0 if successful, -1 with errp set if it is
 * impossible to continue. */
static int nbd_receive_option_reply(QIOChannel *ioc, uint32_t opt,
                                    NBDOptionReply *reply, Error **errp)
{
    QEMU_BUILD_BUG_ON(sizeof(*reply) != 20);
    if (nbd_read(ioc, reply, sizeof(*reply), "option reply", errp) < 0) {
        nbd_send_opt_abort(ioc);
        return -1;
    }
    reply->magic = be64_to_cpu(reply->magic);
    reply->option = be32_to_cpu(reply->option);
    reply->type = be32_to_cpu(reply->type);
    reply->length = be32_to_cpu(reply->length);

    trace_nbd_receive_option_reply(reply->option, nbd_opt_lookup(reply->option),
                                   reply->type, nbd_rep_lookup(reply->type),
                                   reply->length);

    if (reply->magic != NBD_REP_MAGIC) {
        error_setg(errp, "Unexpected option reply magic");
        nbd_send_opt_abort(ioc);
        return -1;
    }
    if (reply->option != opt) {
        error_setg(errp, "Unexpected option type %u (%s), expected %u (%s)",
                   reply->option, nbd_opt_lookup(reply->option),
                   opt, nbd_opt_lookup(opt));
        nbd_send_opt_abort(ioc);
        return -1;
    }
    return 0;
}

/*
 * If reply represents success, return 1 without further action.  If
 * reply represents an error, consume the optional payload of the
 * packet on ioc.  Then return 0 for unsupported (so the client can
 * fall back to other approaches), where @strict determines if only
 * ERR_UNSUP or all errors fit that category, or -1 with errp set for
 * other errors.
 */
static int nbd_handle_reply_err(QIOChannel *ioc, NBDOptionReply *reply,
                                bool strict, Error **errp)
{
    ERRP_GUARD();
    g_autofree char *msg = NULL;

    if (!(reply->type & (1 << 31))) {
        return 1;
    }

    if (reply->length) {
        if (reply->length > NBD_MAX_BUFFER_SIZE) {
            error_setg(errp, "server error %" PRIu32
                       " (%s) message is too long",
                       reply->type, nbd_rep_lookup(reply->type));
            goto err;
        }
        msg = g_malloc(reply->length + 1);
        if (nbd_read(ioc, msg, reply->length, NULL, errp) < 0) {
            error_prepend(errp, "Failed to read option error %" PRIu32
                          " (%s) message: ",
                          reply->type, nbd_rep_lookup(reply->type));
            goto err;
        }
        msg[reply->length] = '\0';
        trace_nbd_server_error_msg(reply->type,
                                   nbd_reply_type_lookup(reply->type), msg);
    }

    if (reply->type == NBD_REP_ERR_UNSUP || !strict) {
        trace_nbd_reply_err_ignored(reply->option,
                                    nbd_opt_lookup(reply->option),
                                    reply->type, nbd_rep_lookup(reply->type));
        return 0;
    }

    switch (reply->type) {
    case NBD_REP_ERR_POLICY:
        error_setg(errp, "Denied by server for option %" PRIu32 " (%s)",
                   reply->option, nbd_opt_lookup(reply->option));
        break;

    case NBD_REP_ERR_INVALID:
        error_setg(errp, "Invalid parameters for option %" PRIu32 " (%s)",
                   reply->option, nbd_opt_lookup(reply->option));
        break;

    case NBD_REP_ERR_PLATFORM:
        error_setg(errp, "Server lacks support for option %" PRIu32 " (%s)",
                   reply->option, nbd_opt_lookup(reply->option));
        break;

    case NBD_REP_ERR_TLS_REQD:
        error_setg(errp, "TLS negotiation required before option %" PRIu32
                   " (%s)", reply->option, nbd_opt_lookup(reply->option));
        error_append_hint(errp, "Did you forget a valid tls-creds?\n");
        break;

    case NBD_REP_ERR_UNKNOWN:
        error_setg(errp, "Requested export not available");
        break;

    case NBD_REP_ERR_SHUTDOWN:
        error_setg(errp, "Server shutting down before option %" PRIu32 " (%s)",
                   reply->option, nbd_opt_lookup(reply->option));
        break;

    case NBD_REP_ERR_BLOCK_SIZE_REQD:
        error_setg(errp, "Server requires INFO_BLOCK_SIZE for option %" PRIu32
                   " (%s)", reply->option, nbd_opt_lookup(reply->option));
        break;

    default:
        error_setg(errp, "Unknown error code when asking for option %" PRIu32
                   " (%s)", reply->option, nbd_opt_lookup(reply->option));
        break;
    }

    if (msg) {
        error_append_hint(errp, "server reported: %s\n", msg);
    }

 err:
    nbd_send_opt_abort(ioc);
    return -1;
}

/* nbd_receive_list:
 * Process another portion of the NBD_OPT_LIST reply, populating any
 * name received into *@name. If @description is non-NULL, and the
 * server provided a description, that is also populated. The caller
 * must eventually call g_free() on success.
 * Returns 1 if name and description were set and iteration must continue,
 *         0 if iteration is complete (including if OPT_LIST unsupported),
 *         -1 with @errp set if an unrecoverable error occurred.
 */
static int nbd_receive_list(QIOChannel *ioc, char **name, char **description,
                            Error **errp)
{
    NBDOptionReply reply;
    uint32_t len;
    uint32_t namelen;
    g_autofree char *local_name = NULL;
    g_autofree char *local_desc = NULL;
    int error;

    if (nbd_receive_option_reply(ioc, NBD_OPT_LIST, &reply, errp) < 0) {
        return -1;
    }
    error = nbd_handle_reply_err(ioc, &reply, true, errp);
    if (error <= 0) {
        return error;
    }
    len = reply.length;

    if (reply.type == NBD_REP_ACK) {
        if (len != 0) {
            error_setg(errp, "length too long for option end");
            nbd_send_opt_abort(ioc);
            return -1;
        }
        return 0;
    } else if (reply.type != NBD_REP_SERVER) {
        error_setg(errp, "Unexpected reply type %u (%s), expected %u (%s)",
                   reply.type, nbd_rep_lookup(reply.type),
                   NBD_REP_SERVER, nbd_rep_lookup(NBD_REP_SERVER));
        nbd_send_opt_abort(ioc);
        return -1;
    }

    if (len < sizeof(namelen) || len > NBD_MAX_BUFFER_SIZE) {
        error_setg(errp, "incorrect option length %" PRIu32, len);
        nbd_send_opt_abort(ioc);
        return -1;
    }
    if (nbd_read32(ioc, &namelen, "option name length", errp) < 0) {
        nbd_send_opt_abort(ioc);
        return -1;
    }
    len -= sizeof(namelen);
    if (len < namelen || namelen > NBD_MAX_STRING_SIZE) {
        error_setg(errp, "incorrect name length in server's list response");
        nbd_send_opt_abort(ioc);
        return -1;
    }

    local_name = g_malloc(namelen + 1);
    if (nbd_read(ioc, local_name, namelen, "export name", errp) < 0) {
        nbd_send_opt_abort(ioc);
        return -1;
    }
    local_name[namelen] = '\0';
    len -= namelen;
    if (len) {
        if (len > NBD_MAX_STRING_SIZE) {
            error_setg(errp, "incorrect description length in server's "
                       "list response");
            nbd_send_opt_abort(ioc);
            return -1;
        }
        local_desc = g_malloc(len + 1);
        if (nbd_read(ioc, local_desc, len, "export description", errp) < 0) {
            nbd_send_opt_abort(ioc);
            return -1;
        }
        local_desc[len] = '\0';
    }

    trace_nbd_receive_list(local_name, local_desc ?: "");
    *name = g_steal_pointer(&local_name);
    if (description) {
        *description = g_steal_pointer(&local_desc);
    }
    return 1;
}


/*
 * nbd_opt_info_or_go:
 * Send option for NBD_OPT_INFO or NBD_OPT_GO and parse the reply.
 * Returns -1 if the option proves the export @info->name cannot be
 * used, 0 if the option is unsupported (fall back to NBD_OPT_LIST and
 * NBD_OPT_EXPORT_NAME in that case), and > 0 if the export is good to
 * go (with the rest of @info populated).
 */
static int nbd_opt_info_or_go(QIOChannel *ioc, uint32_t opt,
                              NBDExportInfo *info, Error **errp)
{
    ERRP_GUARD();
    NBDOptionReply reply;
    uint32_t len = strlen(info->name);
    uint16_t type;
    int error;
    char *buf;

    /* The protocol requires that the server send NBD_INFO_EXPORT with
     * a non-zero flags (at least NBD_FLAG_HAS_FLAGS must be set); so
     * flags still 0 is a witness of a broken server. */
    info->flags = 0;

    assert(opt == NBD_OPT_GO || opt == NBD_OPT_INFO);
    trace_nbd_opt_info_go_start(nbd_opt_lookup(opt), info->name);
    buf = g_malloc(4 + len + 2 + 2 * info->request_sizes + 1);
    stl_be_p(buf, len);
    memcpy(buf + 4, info->name, len);
    /* At most one request, everything else up to server */
    stw_be_p(buf + 4 + len, info->request_sizes);
    if (info->request_sizes) {
        stw_be_p(buf + 4 + len + 2, NBD_INFO_BLOCK_SIZE);
    }
    error = nbd_send_option_request(ioc, opt,
                                    4 + len + 2 + 2 * info->request_sizes,
                                    buf, errp);
    g_free(buf);
    if (error < 0) {
        return -1;
    }

    while (1) {
        if (nbd_receive_option_reply(ioc, opt, &reply, errp) < 0) {
            return -1;
        }
        error = nbd_handle_reply_err(ioc, &reply, true, errp);
        if (error <= 0) {
            return error;
        }
        len = reply.length;

        if (reply.type == NBD_REP_ACK) {
            /*
             * Server is done sending info, and moved into transmission
             * phase for NBD_OPT_GO, but make sure it sent flags
             */
            if (len) {
                error_setg(errp, "server sent invalid NBD_REP_ACK");
                return -1;
            }
            if (!info->flags) {
                error_setg(errp, "broken server omitted NBD_INFO_EXPORT");
                return -1;
            }
            trace_nbd_opt_info_go_success(nbd_opt_lookup(opt));
            return 1;
        }
        if (reply.type != NBD_REP_INFO) {
            error_setg(errp, "unexpected reply type %u (%s), expected %u (%s)",
                       reply.type, nbd_rep_lookup(reply.type),
                       NBD_REP_INFO, nbd_rep_lookup(NBD_REP_INFO));
            nbd_send_opt_abort(ioc);
            return -1;
        }
        if (len < sizeof(type)) {
            error_setg(errp, "NBD_REP_INFO length %" PRIu32 " is too short",
                       len);
            nbd_send_opt_abort(ioc);
            return -1;
        }
        if (nbd_read16(ioc, &type, "info type", errp) < 0) {
            nbd_send_opt_abort(ioc);
            return -1;
        }
        len -= sizeof(type);
        switch (type) {
        case NBD_INFO_EXPORT:
            if (len != sizeof(info->size) + sizeof(info->flags)) {
                error_setg(errp, "remaining export info len %" PRIu32
                           " is unexpected size", len);
                nbd_send_opt_abort(ioc);
                return -1;
            }
            if (nbd_read64(ioc, &info->size, "info size", errp) < 0) {
                nbd_send_opt_abort(ioc);
                return -1;
            }
            if (nbd_read16(ioc, &info->flags, "info flags", errp) < 0) {
                nbd_send_opt_abort(ioc);
                return -1;
            }
            if (info->min_block &&
                !QEMU_IS_ALIGNED(info->size, info->min_block)) {
                error_setg(errp, "export size %" PRIu64 " is not multiple of "
                           "minimum block size %" PRIu32, info->size,
                           info->min_block);
                nbd_send_opt_abort(ioc);
                return -1;
            }
            trace_nbd_receive_negotiate_size_flags(info->size, info->flags);
            break;

        case NBD_INFO_BLOCK_SIZE:
            if (len != sizeof(info->min_block) * 3) {
                error_setg(errp, "remaining export info len %" PRIu32
                           " is unexpected size", len);
                nbd_send_opt_abort(ioc);
                return -1;
            }
            if (nbd_read32(ioc, &info->min_block, "info minimum block size",
                           errp) < 0) {
                nbd_send_opt_abort(ioc);
                return -1;
            }
            if (!is_power_of_2(info->min_block)) {
                error_setg(errp, "server minimum block size %" PRIu32
                           " is not a power of two", info->min_block);
                nbd_send_opt_abort(ioc);
                return -1;
            }
            if (nbd_read32(ioc, &info->opt_block, "info preferred block size",
                           errp) < 0)
            {
                nbd_send_opt_abort(ioc);
                return -1;
            }
            if (!is_power_of_2(info->opt_block) ||
                info->opt_block < info->min_block) {
                error_setg(errp, "server preferred block size %" PRIu32
                           " is not valid", info->opt_block);
                nbd_send_opt_abort(ioc);
                return -1;
            }
            if (nbd_read32(ioc, &info->max_block, "info maximum block size",
                           errp) < 0)
            {
                nbd_send_opt_abort(ioc);
                return -1;
            }
            if (info->max_block < info->min_block) {
                error_setg(errp, "server maximum block size %" PRIu32
                           " is not valid", info->max_block);
                nbd_send_opt_abort(ioc);
                return -1;
            }
            trace_nbd_opt_info_block_size(info->min_block, info->opt_block,
                                          info->max_block);
            break;

        default:
            /*
             * Not worth the bother to check if NBD_INFO_NAME or
             * NBD_INFO_DESCRIPTION exceed NBD_MAX_STRING_SIZE.
             */
            trace_nbd_opt_info_unknown(type, nbd_info_lookup(type));
            if (nbd_drop(ioc, len, errp) < 0) {
                error_prepend(errp, "Failed to read info payload: ");
                nbd_send_opt_abort(ioc);
                return -1;
            }
            break;
        }
    }
}

/* Return -1 on failure, 0 if wantname is an available export. */
static int nbd_receive_query_exports(QIOChannel *ioc,
                                     const char *wantname,
                                     Error **errp)
{
    bool list_empty = true;
    bool found_export = false;

    trace_nbd_receive_query_exports_start(wantname);
    if (nbd_send_option_request(ioc, NBD_OPT_LIST, 0, NULL, errp) < 0) {
        return -1;
    }

    while (1) {
        char *name;
        int ret = nbd_receive_list(ioc, &name, NULL, errp);

        if (ret < 0) {
            /* Server gave unexpected reply */
            return -1;
        } else if (ret == 0) {
            /* Done iterating. */
            if (list_empty) {
                /*
                 * We don't have enough context to tell a server that
                 * sent an empty list apart from a server that does
                 * not support the list command; but as this function
                 * is just used to trigger a nicer error message
                 * before trying NBD_OPT_EXPORT_NAME, assume the
                 * export is available.
                 */
                return 0;
            } else if (!found_export) {
                error_setg(errp, "No export with name '%s' available",
                           wantname);
                nbd_send_opt_abort(ioc);
                return -1;
            }
            trace_nbd_receive_query_exports_success(wantname);
            return 0;
        }
        list_empty = false;
        if (!strcmp(name, wantname)) {
            found_export = true;
        }
        g_free(name);
    }
}

/*
 * nbd_request_simple_option: Send an option request, and parse the reply.
 * @strict controls whether ERR_UNSUP or all errors produce 0 status.
 * return 1 for successful negotiation,
 *        0 if operation is unsupported,
 *        -1 with errp set for any other error
 */
static int nbd_request_simple_option(QIOChannel *ioc, int opt, bool strict,
                                     Error **errp)
{
    NBDOptionReply reply;
    int error;

    if (nbd_send_option_request(ioc, opt, 0, NULL, errp) < 0) {
        return -1;
    }

    if (nbd_receive_option_reply(ioc, opt, &reply, errp) < 0) {
        return -1;
    }
    error = nbd_handle_reply_err(ioc, &reply, strict, errp);
    if (error <= 0) {
        return error;
    }

    if (reply.type != NBD_REP_ACK) {
        error_setg(errp, "Server answered option %d (%s) with unexpected "
                   "reply %" PRIu32 " (%s)", opt, nbd_opt_lookup(opt),
                   reply.type, nbd_rep_lookup(reply.type));
        nbd_send_opt_abort(ioc);
        return -1;
    }

    if (reply.length != 0) {
        error_setg(errp, "Option %d ('%s') response length is %" PRIu32
                   " (it should be zero)", opt, nbd_opt_lookup(opt),
                   reply.length);
        nbd_send_opt_abort(ioc);
        return -1;
    }

    return 1;
}

static QIOChannel *nbd_receive_starttls(QIOChannel *ioc,
                                        QCryptoTLSCreds *tlscreds,
                                        const char *hostname, Error **errp)
{
    int ret;
    QIOChannelTLS *tioc;
    struct NBDTLSHandshakeData data = { 0 };

    ret = nbd_request_simple_option(ioc, NBD_OPT_STARTTLS, true, errp);
    if (ret <= 0) {
        if (ret == 0) {
            error_setg(errp, "Server don't support STARTTLS option");
            nbd_send_opt_abort(ioc);
        }
        return NULL;
    }

    trace_nbd_receive_starttls_new_client();
    tioc = qio_channel_tls_new_client(ioc, tlscreds, hostname, errp);
    if (!tioc) {
        return NULL;
    }
    qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-client-tls");
    data.loop = g_main_loop_new(g_main_context_default(), FALSE);
    trace_nbd_receive_starttls_tls_handshake();
    qio_channel_tls_handshake(tioc,
                              nbd_tls_handshake,
                              &data,
                              NULL,
                              NULL);

    if (!data.complete) {
        g_main_loop_run(data.loop);
    }
    g_main_loop_unref(data.loop);
    if (data.error) {
        error_propagate(errp, data.error);
        object_unref(OBJECT(tioc));
        return NULL;
    }

    return QIO_CHANNEL(tioc);
}

/*
 * nbd_send_meta_query:
 * Send 0 or 1 set/list meta context queries.
 * Return 0 on success, -1 with errp set for any error
 */
static int nbd_send_meta_query(QIOChannel *ioc, uint32_t opt,
                               const char *export, const char *query,
                               Error **errp)
{
    int ret;
    uint32_t export_len;
    uint32_t queries = !!query;
    uint32_t query_len = 0;
    uint32_t data_len;
    char *data;
    char *p;

    assert(strnlen(export, NBD_MAX_STRING_SIZE + 1) <= NBD_MAX_STRING_SIZE);
    export_len = strlen(export);
    data_len = sizeof(export_len) + export_len + sizeof(queries);
    if (query) {
        assert(strnlen(query, NBD_MAX_STRING_SIZE + 1) <= NBD_MAX_STRING_SIZE);
        query_len = strlen(query);
        data_len += sizeof(query_len) + query_len;
    } else {
        assert(opt == NBD_OPT_LIST_META_CONTEXT);
    }
    p = data = g_malloc(data_len);

    trace_nbd_opt_meta_request(nbd_opt_lookup(opt), query ?: "(all)", export);
    stl_be_p(p, export_len);
    memcpy(p += sizeof(export_len), export, export_len);
    stl_be_p(p += export_len, queries);
    if (query) {
        stl_be_p(p += sizeof(queries), query_len);
        memcpy(p += sizeof(query_len), query, query_len);
    }

    ret = nbd_send_option_request(ioc, opt, data_len, data, errp);
    g_free(data);
    return ret;
}

/*
 * nbd_receive_one_meta_context:
 * Called in a loop to receive and trace one set/list meta context reply.
 * Pass non-NULL @name or @id to collect results back to the caller, which
 * must eventually call g_free().
 * return 1 if name is set and iteration must continue,
 *        0 if iteration is complete (including if option is unsupported),
 *        -1 with errp set for any error
 */
static int nbd_receive_one_meta_context(QIOChannel *ioc,
                                        uint32_t opt,
                                        char **name,
                                        uint32_t *id,
                                        Error **errp)
{
    int ret;
    NBDOptionReply reply;
    char *local_name = NULL;
    uint32_t local_id;

    if (nbd_receive_option_reply(ioc, opt, &reply, errp) < 0) {
        return -1;
    }

    ret = nbd_handle_reply_err(ioc, &reply, false, errp);
    if (ret <= 0) {
        return ret;
    }

    if (reply.type == NBD_REP_ACK) {
        if (reply.length != 0) {
            error_setg(errp, "Unexpected length to ACK response");
            nbd_send_opt_abort(ioc);
            return -1;
        }
        return 0;
    } else if (reply.type != NBD_REP_META_CONTEXT) {
        error_setg(errp, "Unexpected reply type %u (%s), expected %u (%s)",
                   reply.type, nbd_rep_lookup(reply.type),
                   NBD_REP_META_CONTEXT, nbd_rep_lookup(NBD_REP_META_CONTEXT));
        nbd_send_opt_abort(ioc);
        return -1;
    }

    if (reply.length <= sizeof(local_id) ||
        reply.length > NBD_MAX_BUFFER_SIZE) {
        error_setg(errp, "Failed to negotiate meta context, server "
                   "answered with unexpected length %" PRIu32,
                   reply.length);
        nbd_send_opt_abort(ioc);
        return -1;
    }

    if (nbd_read32(ioc, &local_id, "context id", errp) < 0) {
        return -1;
    }

    reply.length -= sizeof(local_id);
    local_name = g_malloc(reply.length + 1);
    if (nbd_read(ioc, local_name, reply.length, "context name", errp) < 0) {
        g_free(local_name);
        return -1;
    }
    local_name[reply.length] = '\0';
    trace_nbd_opt_meta_reply(nbd_opt_lookup(opt), local_name, local_id);

    if (name) {
        *name = local_name;
    } else {
        g_free(local_name);
    }
    if (id) {
        *id = local_id;
    }
    return 1;
}

/*
 * nbd_negotiate_simple_meta_context:
 * Request the server to set the meta context for export @info->name
 * using @info->x_dirty_bitmap with a fallback to "base:allocation",
 * setting @info->context_id to the resulting id. Fail if the server
 * responds with more than one context or with a context different
 * than the query.
 * return 1 for successful negotiation,
 *        0 if operation is unsupported,
 *        -1 with errp set for any other error
 */
static int nbd_negotiate_simple_meta_context(QIOChannel *ioc,
                                             NBDExportInfo *info,
                                             Error **errp)
{
    /*
     * TODO: Removing the x_dirty_bitmap hack will mean refactoring
     * this function to request and store ids for multiple contexts
     * (both base:allocation and a dirty bitmap), at which point this
     * function should lose the term _simple.
     */
    int ret;
    const char *context = info->x_dirty_bitmap ?: "base:allocation";
    bool received = false;
    char *name = NULL;

    if (nbd_send_meta_query(ioc, NBD_OPT_SET_META_CONTEXT,
                            info->name, context, errp) < 0) {
        return -1;
    }

    ret = nbd_receive_one_meta_context(ioc, NBD_OPT_SET_META_CONTEXT,
                                       &name, &info->context_id, errp);
    if (ret < 0) {
        return -1;
    }
    if (ret == 1) {
        if (strcmp(context, name)) {
            error_setg(errp, "Failed to negotiate meta context '%s', server "
                       "answered with different context '%s'", context,
                       name);
            g_free(name);
            nbd_send_opt_abort(ioc);
            return -1;
        }
        g_free(name);
        received = true;

        ret = nbd_receive_one_meta_context(ioc, NBD_OPT_SET_META_CONTEXT,
                                           NULL, NULL, errp);
        if (ret < 0) {
            return -1;
        }
    }
    if (ret != 0) {
        error_setg(errp, "Server answered with more than one context");
        nbd_send_opt_abort(ioc);
        return -1;
    }
    return received;
}

/*
 * nbd_list_meta_contexts:
 * Request the server to list all meta contexts for export @info->name.
 * return 0 if list is complete (even if empty),
 *        -1 with errp set for any error
 */
static int nbd_list_meta_contexts(QIOChannel *ioc,
                                  NBDExportInfo *info,
                                  Error **errp)
{
    int ret;
    int seen_any = false;
    int seen_qemu = false;

    if (nbd_send_meta_query(ioc, NBD_OPT_LIST_META_CONTEXT,
                            info->name, NULL, errp) < 0) {
        return -1;
    }

    while (1) {
        char *context;

        ret = nbd_receive_one_meta_context(ioc, NBD_OPT_LIST_META_CONTEXT,
                                           &context, NULL, errp);
        if (ret == 0 && seen_any && !seen_qemu) {
            /*
             * Work around qemu 3.0 bug: the server forgot to send
             * "qemu:" replies to 0 queries. If we saw at least one
             * reply (probably base:allocation), but none of them were
             * qemu:, then run a more specific query to make sure.
             */
            seen_qemu = true;
            if (nbd_send_meta_query(ioc, NBD_OPT_LIST_META_CONTEXT,
                                    info->name, "qemu:", errp) < 0) {
                return -1;
            }
            continue;
        }
        if (ret <= 0) {
            return ret;
        }
        seen_any = true;
        seen_qemu |= strstart(context, "qemu:", NULL);
        info->contexts = g_renew(char *, info->contexts, ++info->n_contexts);
        info->contexts[info->n_contexts - 1] = context;
    }
}

/*
 * nbd_start_negotiate:
 * Start the handshake to the server.  After a positive return, the server
 * is ready to accept additional NBD_OPT requests.
 * Returns: negative errno: failure talking to server
 *          non-negative: enum NBDMode describing server abilities
 */
static int nbd_start_negotiate(AioContext *aio_context, QIOChannel *ioc,
                               QCryptoTLSCreds *tlscreds,
                               const char *hostname, QIOChannel **outioc,
                               bool structured_reply, bool *zeroes,
                               Error **errp)
{
    ERRP_GUARD();
    uint64_t magic;

    trace_nbd_start_negotiate(tlscreds, hostname ? hostname : "<null>");

    if (zeroes) {
        *zeroes = true;
    }
    if (outioc) {
        *outioc = NULL;
    }
    if (tlscreds && !outioc) {
        error_setg(errp, "Output I/O channel required for TLS");
        return -EINVAL;
    }

    if (nbd_read64(ioc, &magic, "initial magic", errp) < 0) {
        return -EINVAL;
    }
    trace_nbd_receive_negotiate_magic(magic);

    if (magic != NBD_INIT_MAGIC) {
        error_setg(errp, "Bad initial magic received: 0x%" PRIx64, magic);
        return -EINVAL;
    }

    if (nbd_read64(ioc, &magic, "server magic", errp) < 0) {
        return -EINVAL;
    }
    trace_nbd_receive_negotiate_magic(magic);

    if (magic == NBD_OPTS_MAGIC) {
        uint32_t clientflags = 0;
        uint16_t globalflags;
        bool fixedNewStyle = false;

        if (nbd_read16(ioc, &globalflags, "server flags", errp) < 0) {
            return -EINVAL;
        }
        trace_nbd_receive_negotiate_server_flags(globalflags);
        if (globalflags & NBD_FLAG_FIXED_NEWSTYLE) {
            fixedNewStyle = true;
            clientflags |= NBD_FLAG_C_FIXED_NEWSTYLE;
        }
        if (globalflags & NBD_FLAG_NO_ZEROES) {
            if (zeroes) {
                *zeroes = false;
            }
            clientflags |= NBD_FLAG_C_NO_ZEROES;
        }
        /* client requested flags */
        clientflags = cpu_to_be32(clientflags);
        if (nbd_write(ioc, &clientflags, sizeof(clientflags), errp) < 0) {
            error_prepend(errp, "Failed to send clientflags field: ");
            return -EINVAL;
        }
        if (tlscreds) {
            if (fixedNewStyle) {
                *outioc = nbd_receive_starttls(ioc, tlscreds, hostname, errp);
                if (!*outioc) {
                    return -EINVAL;
                }
                ioc = *outioc;
                if (aio_context) {
                    qio_channel_set_blocking(ioc, false, NULL);
                    qio_channel_attach_aio_context(ioc, aio_context);
                }
            } else {
                error_setg(errp, "Server does not support STARTTLS");
                return -EINVAL;
            }
        }
        if (fixedNewStyle) {
            int result = 0;

            if (structured_reply) {
                result = nbd_request_simple_option(ioc,
                                                   NBD_OPT_STRUCTURED_REPLY,
                                                   false, errp);
                if (result < 0) {
                    return -EINVAL;
                }
            }
            return result ? NBD_MODE_STRUCTURED : NBD_MODE_SIMPLE;
        } else {
            return NBD_MODE_EXPORT_NAME;
        }
    } else if (magic == NBD_CLIENT_MAGIC) {
        if (tlscreds) {
            error_setg(errp, "Server does not support STARTTLS");
            return -EINVAL;
        }
        return NBD_MODE_OLDSTYLE;
    } else {
        error_setg(errp, "Bad server magic received: 0x%" PRIx64, magic);
        return -EINVAL;
    }
}

/*
 * nbd_negotiate_finish_oldstyle:
 * Populate @info with the size and export flags from an oldstyle server,
 * but does not consume 124 bytes of reserved zero padding.
 * Returns 0 on success, -1 with @errp set on failure
 */
static int nbd_negotiate_finish_oldstyle(QIOChannel *ioc, NBDExportInfo *info,
                                         Error **errp)
{
    uint32_t oldflags;

    if (nbd_read64(ioc, &info->size, "export length", errp) < 0) {
        return -EINVAL;
    }

    if (nbd_read32(ioc, &oldflags, "export flags", errp) < 0) {
        return -EINVAL;
    }
    if (oldflags & ~0xffff) {
        error_setg(errp, "Unexpected export flags %0x" PRIx32, oldflags);
        return -EINVAL;
    }
    info->flags = oldflags;
    return 0;
}

/*
 * nbd_receive_negotiate:
 * Connect to server, complete negotiation, and move into transmission phase.
 * Returns: negative errno: failure talking to server
 *          0: server is connected
 */
int nbd_receive_negotiate(AioContext *aio_context, QIOChannel *ioc,
                          QCryptoTLSCreds *tlscreds,
                          const char *hostname, QIOChannel **outioc,
                          NBDExportInfo *info, Error **errp)
{
    ERRP_GUARD();
    int result;
    bool zeroes;
    bool base_allocation = info->base_allocation;

    assert(info->name && strlen(info->name) <= NBD_MAX_STRING_SIZE);
    trace_nbd_receive_negotiate_name(info->name);

    result = nbd_start_negotiate(aio_context, ioc, tlscreds, hostname, outioc,
                                 info->structured_reply, &zeroes, errp);
    if (result < 0) {
        return result;
    }

    info->structured_reply = false;
    info->base_allocation = false;
    if (tlscreds && *outioc) {
        ioc = *outioc;
    }

    switch ((NBDMode)result) {
    case NBD_MODE_STRUCTURED:
        info->structured_reply = true;
        if (base_allocation) {
            result = nbd_negotiate_simple_meta_context(ioc, info, errp);
            if (result < 0) {
                return -EINVAL;
            }
            info->base_allocation = result == 1;
        }
        /* fall through */
    case NBD_MODE_SIMPLE:
        /* Try NBD_OPT_GO first - if it works, we are done (it
         * also gives us a good message if the server requires
         * TLS).  If it is not available, fall back to
         * NBD_OPT_LIST for nicer error messages about a missing
         * export, then use NBD_OPT_EXPORT_NAME.  */
        result = nbd_opt_info_or_go(ioc, NBD_OPT_GO, info, errp);
        if (result < 0) {
            return -EINVAL;
        }
        if (result > 0) {
            return 0;
        }
        /* Check our desired export is present in the
         * server export list. Since NBD_OPT_EXPORT_NAME
         * cannot return an error message, running this
         * query gives us better error reporting if the
         * export name is not available.
         */
        if (nbd_receive_query_exports(ioc, info->name, errp) < 0) {
            return -EINVAL;
        }
        /* fall through */
    case NBD_MODE_EXPORT_NAME:
        /* write the export name request */
        if (nbd_send_option_request(ioc, NBD_OPT_EXPORT_NAME, -1, info->name,
                                    errp) < 0) {
            return -EINVAL;
        }

        /* Read the response */
        if (nbd_read64(ioc, &info->size, "export length", errp) < 0) {
            return -EINVAL;
        }

        if (nbd_read16(ioc, &info->flags, "export flags", errp) < 0) {
            return -EINVAL;
        }
        break;
    case NBD_MODE_OLDSTYLE:
        if (*info->name) {
            error_setg(errp, "Server does not support non-empty export names");
            return -EINVAL;
        }
        if (nbd_negotiate_finish_oldstyle(ioc, info, errp) < 0) {
            return -EINVAL;
        }
        break;
    default:
        g_assert_not_reached();
    }

    trace_nbd_receive_negotiate_size_flags(info->size, info->flags);
    if (zeroes && nbd_drop(ioc, 124, errp) < 0) {
        error_prepend(errp, "Failed to read reserved block: ");
        return -EINVAL;
    }
    return 0;
}

/* Clean up result of nbd_receive_export_list */
void nbd_free_export_list(NBDExportInfo *info, int count)
{
    int i, j;

    if (!info) {
        return;
    }

    for (i = 0; i < count; i++) {
        g_free(info[i].name);
        g_free(info[i].description);
        for (j = 0; j < info[i].n_contexts; j++) {
            g_free(info[i].contexts[j]);
        }
        g_free(info[i].contexts);
    }
    g_free(info);
}

/*
 * nbd_receive_export_list:
 * Query details about a server's exports, then disconnect without
 * going into transmission phase. Return a count of the exports listed
 * in @info by the server, or -1 on error. Caller must free @info using
 * nbd_free_export_list().
 */
int nbd_receive_export_list(QIOChannel *ioc, QCryptoTLSCreds *tlscreds,
                            const char *hostname, NBDExportInfo **info,
                            Error **errp)
{
    int result;
    int count = 0;
    int i;
    int rc;
    int ret = -1;
    NBDExportInfo *array = NULL;
    QIOChannel *sioc = NULL;

    *info = NULL;
    result = nbd_start_negotiate(NULL, ioc, tlscreds, hostname, &sioc, true,
                                 NULL, errp);
    if (tlscreds && sioc) {
        ioc = sioc;
    }
    if (result < 0) {
        goto out;
    }

    switch ((NBDMode)result) {
    case NBD_MODE_SIMPLE:
    case NBD_MODE_STRUCTURED:
        /* newstyle - use NBD_OPT_LIST to populate array, then try
         * NBD_OPT_INFO on each array member. If structured replies
         * are enabled, also try NBD_OPT_LIST_META_CONTEXT. */
        if (nbd_send_option_request(ioc, NBD_OPT_LIST, 0, NULL, errp) < 0) {
            goto out;
        }
        while (1) {
            char *name;
            char *desc;

            rc = nbd_receive_list(ioc, &name, &desc, errp);
            if (rc < 0) {
                goto out;
            } else if (rc == 0) {
                break;
            }
            array = g_renew(NBDExportInfo, array, ++count);
            memset(&array[count - 1], 0, sizeof(*array));
            array[count - 1].name = name;
            array[count - 1].description = desc;
            array[count - 1].structured_reply = result == NBD_MODE_STRUCTURED;
        }

        for (i = 0; i < count; i++) {
            array[i].request_sizes = true;
            rc = nbd_opt_info_or_go(ioc, NBD_OPT_INFO, &array[i], errp);
            if (rc < 0) {
                goto out;
            } else if (rc == 0) {
                /*
                 * Pointless to try rest of loop. If OPT_INFO doesn't work,
                 * it's unlikely that meta contexts work either
                 */
                break;
            }

            if (result == NBD_MODE_STRUCTURED &&
                nbd_list_meta_contexts(ioc, &array[i], errp) < 0) {
                goto out;
            }
        }

        /* Send NBD_OPT_ABORT as a courtesy before hanging up */
        nbd_send_opt_abort(ioc);
        break;
    case NBD_MODE_EXPORT_NAME:
        error_setg(errp, "Server does not support export lists");
        /* We can't even send NBD_OPT_ABORT, so merely hang up */
        goto out;
    case NBD_MODE_OLDSTYLE:
        /* Lone export name is implied, but we can parse length and flags */
        array = g_new0(NBDExportInfo, 1);
        array->name = g_strdup("");
        count = 1;

        if (nbd_negotiate_finish_oldstyle(ioc, array, errp) < 0) {
            goto out;
        }

        /* Send NBD_CMD_DISC as a courtesy to the server, but ignore all
         * errors now that we have the information we wanted. */
        if (nbd_drop(ioc, 124, NULL) == 0) {
            NBDRequest request = { .type = NBD_CMD_DISC };

            nbd_send_request(ioc, &request);
        }
        break;
    default:
        g_assert_not_reached();
    }

    *info = array;
    array = NULL;
    ret = count;

 out:
    qio_channel_shutdown(ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
    qio_channel_close(ioc, NULL);
    object_unref(OBJECT(sioc));
    nbd_free_export_list(array, count);
    return ret;
}

#ifdef __linux__
int nbd_init(int fd, QIOChannelSocket *sioc, NBDExportInfo *info,
             Error **errp)
{
    unsigned long sector_size = MAX(BDRV_SECTOR_SIZE, info->min_block);
    unsigned long sectors = info->size / sector_size;

    /* FIXME: Once the kernel module is patched to honor block sizes,
     * and to advertise that fact to user space, we should update the
     * hand-off to the kernel to use any block sizes we learned. */
    assert(!info->request_sizes);
    if (info->size / sector_size != sectors) {
        error_setg(errp, "Export size %" PRIu64 " too large for 32-bit kernel",
                   info->size);
        return -E2BIG;
    }

    trace_nbd_init_set_socket();

    if (ioctl(fd, NBD_SET_SOCK, (unsigned long) sioc->fd) < 0) {
        int serrno = errno;
        error_setg(errp, "Failed to set NBD socket");
        return -serrno;
    }

    trace_nbd_init_set_block_size(sector_size);

    if (ioctl(fd, NBD_SET_BLKSIZE, sector_size) < 0) {
        int serrno = errno;
        error_setg(errp, "Failed setting NBD block size");
        return -serrno;
    }

    trace_nbd_init_set_size(sectors);
    if (info->size % sector_size) {
        trace_nbd_init_trailing_bytes(info->size % sector_size);
    }

    if (ioctl(fd, NBD_SET_SIZE_BLOCKS, sectors) < 0) {
        int serrno = errno;
        error_setg(errp, "Failed setting size (in blocks)");
        return -serrno;
    }

    if (ioctl(fd, NBD_SET_FLAGS, (unsigned long) info->flags) < 0) {
        if (errno == ENOTTY) {
            int read_only = (info->flags & NBD_FLAG_READ_ONLY) != 0;
            trace_nbd_init_set_readonly();

            if (ioctl(fd, BLKROSET, (unsigned long) &read_only) < 0) {
                int serrno = errno;
                error_setg(errp, "Failed setting read-only attribute");
                return -serrno;
            }
        } else {
            int serrno = errno;
            error_setg(errp, "Failed setting flags");
            return -serrno;
        }
    }

    trace_nbd_init_finish();

    return 0;
}

int nbd_client(int fd)
{
    int ret;
    int serrno;

    trace_nbd_client_loop();

    ret = ioctl(fd, NBD_DO_IT);
    if (ret < 0 && errno == EPIPE) {
        /* NBD_DO_IT normally returns EPIPE when someone has disconnected
         * the socket via NBD_DISCONNECT.  We do not want to return 1 in
         * that case.
         */
        ret = 0;
    }
    serrno = errno;

    trace_nbd_client_loop_ret(ret, strerror(serrno));

    trace_nbd_client_clear_queue();
    ioctl(fd, NBD_CLEAR_QUE);

    trace_nbd_client_clear_socket();
    ioctl(fd, NBD_CLEAR_SOCK);

    errno = serrno;
    return ret;
}

int nbd_disconnect(int fd)
{
    ioctl(fd, NBD_CLEAR_QUE);
    ioctl(fd, NBD_DISCONNECT);
    ioctl(fd, NBD_CLEAR_SOCK);
    return 0;
}

#endif /* __linux__ */

int nbd_send_request(QIOChannel *ioc, NBDRequest *request)
{
    uint8_t buf[NBD_REQUEST_SIZE];

    trace_nbd_send_request(request->from, request->len, request->cookie,
                           request->flags, request->type,
                           nbd_cmd_lookup(request->type));

    stl_be_p(buf, NBD_REQUEST_MAGIC);
    stw_be_p(buf + 4, request->flags);
    stw_be_p(buf + 6, request->type);
    stq_be_p(buf + 8, request->cookie);
    stq_be_p(buf + 16, request->from);
    stl_be_p(buf + 24, request->len);

    return nbd_write(ioc, buf, sizeof(buf), NULL);
}

/* nbd_receive_simple_reply
 * Read simple reply except magic field (which should be already read).
 * Payload is not read (payload is possible for CMD_READ, but here we even
 * don't know whether it take place or not).
 */
static int nbd_receive_simple_reply(QIOChannel *ioc, NBDSimpleReply *reply,
                                    Error **errp)
{
    int ret;

    assert(reply->magic == NBD_SIMPLE_REPLY_MAGIC);

    ret = nbd_read(ioc, (uint8_t *)reply + sizeof(reply->magic),
                   sizeof(*reply) - sizeof(reply->magic), "reply", errp);
    if (ret < 0) {
        return ret;
    }

    reply->error = be32_to_cpu(reply->error);
    reply->cookie = be64_to_cpu(reply->cookie);

    return 0;
}

/* nbd_receive_structured_reply_chunk
 * Read structured reply chunk except magic field (which should be already
 * read).
 * Payload is not read.
 */
static int nbd_receive_structured_reply_chunk(QIOChannel *ioc,
                                              NBDStructuredReplyChunk *chunk,
                                              Error **errp)
{
    int ret;

    assert(chunk->magic == NBD_STRUCTURED_REPLY_MAGIC);

    ret = nbd_read(ioc, (uint8_t *)chunk + sizeof(chunk->magic),
                   sizeof(*chunk) - sizeof(chunk->magic), "structured chunk",
                   errp);
    if (ret < 0) {
        return ret;
    }

    chunk->flags = be16_to_cpu(chunk->flags);
    chunk->type = be16_to_cpu(chunk->type);
    chunk->cookie = be64_to_cpu(chunk->cookie);
    chunk->length = be32_to_cpu(chunk->length);

    /*
     * Because we use BLOCK_STATUS with REQ_ONE, and cap READ requests
     * at 32M, no valid server should send us payload larger than
     * this.  Even if we stopped using REQ_ONE, sane servers will cap
     * the number of extents they return for block status.
     */
    if (chunk->length > NBD_MAX_BUFFER_SIZE + sizeof(NBDStructuredReadData)) {
        error_setg(errp, "server chunk %" PRIu32 " (%s) payload is too long",
                   chunk->type, nbd_rep_lookup(chunk->type));
        return -EINVAL;
    }

    return 0;
}

/* nbd_read_eof
 * Tries to read @size bytes from @ioc.
 * Returns 1 on success
 *         0 on eof, when no data was read (errp is not set)
 *         negative errno on failure (errp is set)
 */
static inline int coroutine_fn
nbd_read_eof(BlockDriverState *bs, QIOChannel *ioc, void *buffer, size_t size,
             Error **errp)
{
    bool partial = false;

    assert(size);
    while (size > 0) {
        struct iovec iov = { .iov_base = buffer, .iov_len = size };
        ssize_t len;

        len = qio_channel_readv(ioc, &iov, 1, errp);
        if (len == QIO_CHANNEL_ERR_BLOCK) {
            qio_channel_yield(ioc, G_IO_IN);
            continue;
        } else if (len < 0) {
            return -EIO;
        } else if (len == 0) {
            if (partial) {
                error_setg(errp,
                           "Unexpected end-of-file before all bytes were read");
                return -EIO;
            } else {
                return 0;
            }
        }

        partial = true;
        size -= len;
        buffer = (uint8_t*) buffer + len;
    }
    return 1;
}

/* nbd_receive_reply
 *
 * Decreases bs->in_flight while waiting for a new reply. This yield is where
 * we wait indefinitely and the coroutine must be able to be safely reentered
 * for nbd_client_attach_aio_context().
 *
 * Returns 1 on success
 *         0 on eof, when no data was read (errp is not set)
 *         negative errno on failure (errp is set)
 */
int coroutine_fn nbd_receive_reply(BlockDriverState *bs, QIOChannel *ioc,
                                   NBDReply *reply, Error **errp)
{
    int ret;
    const char *type;

    ret = nbd_read_eof(bs, ioc, &reply->magic, sizeof(reply->magic), errp);
    if (ret <= 0) {
        return ret;
    }

    reply->magic = be32_to_cpu(reply->magic);

    switch (reply->magic) {
    case NBD_SIMPLE_REPLY_MAGIC:
        ret = nbd_receive_simple_reply(ioc, &reply->simple, errp);
        if (ret < 0) {
            break;
        }
        trace_nbd_receive_simple_reply(reply->simple.error,
                                       nbd_err_lookup(reply->simple.error),
                                       reply->cookie);
        break;
    case NBD_STRUCTURED_REPLY_MAGIC:
        ret = nbd_receive_structured_reply_chunk(ioc, &reply->structured, errp);
        if (ret < 0) {
            break;
        }
        type = nbd_reply_type_lookup(reply->structured.type);
        trace_nbd_receive_structured_reply_chunk(reply->structured.flags,
                                                 reply->structured.type, type,
                                                 reply->structured.cookie,
                                                 reply->structured.length);
        break;
    default:
        error_setg(errp, "invalid magic (got 0x%" PRIx32 ")", reply->magic);
        return -EINVAL;
    }
    if (ret < 0) {
        return ret;
    }

    return 1;
}

