/*
 * QEMU System Emulator
 *
 * Copyright (c) 2003-2008 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "chardev/char.h"
#include "io/channel-socket.h"
#include "io/channel-websock.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qapi/error.h"
#include "qapi/clone-visitor.h"
#include "qapi/qapi-visit-sockets.h"
#include "qemu/yank.h"

#include "chardev/char-io.h"
#include "chardev/char-socket.h"

static gboolean socket_reconnect_timeout(gpointer opaque);
static void tcp_chr_telnet_init(Chardev *chr);

static void tcp_chr_change_state(SocketChardev *s, TCPChardevState state)
{
    switch (state) {
    case TCP_CHARDEV_STATE_DISCONNECTED:
        break;
    case TCP_CHARDEV_STATE_CONNECTING:
        assert(s->state == TCP_CHARDEV_STATE_DISCONNECTED);
        break;
    case TCP_CHARDEV_STATE_CONNECTED:
        assert(s->state == TCP_CHARDEV_STATE_CONNECTING);
        break;
    }
    s->state = state;
}

static void tcp_chr_reconn_timer_cancel(SocketChardev *s)
{
    if (s->reconnect_timer) {
        g_source_destroy(s->reconnect_timer);
        g_source_unref(s->reconnect_timer);
        s->reconnect_timer = NULL;
    }
}

static void qemu_chr_socket_restart_timer(Chardev *chr)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);
    char *name;

    assert(s->state == TCP_CHARDEV_STATE_DISCONNECTED);
    assert(!s->reconnect_timer);
    name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label);
    s->reconnect_timer = qemu_chr_timeout_add_ms(chr,
                                                 s->reconnect_time * 1000,
                                                 socket_reconnect_timeout,
                                                 chr);
    g_source_set_name(s->reconnect_timer, name);
    g_free(name);
}

static void check_report_connect_error(Chardev *chr,
                                       Error *err)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);

    if (!s->connect_err_reported) {
        error_reportf_err(err,
                          "Unable to connect character device %s: ",
                          chr->label);
        s->connect_err_reported = true;
    } else {
        error_free(err);
    }
    qemu_chr_socket_restart_timer(chr);
}

static void tcp_chr_accept(QIONetListener *listener,
                           QIOChannelSocket *cioc,
                           void *opaque);

static int tcp_chr_read_poll(void *opaque);
static void tcp_chr_disconnect_locked(Chardev *chr);

/* Called with chr_write_lock held.  */
static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);

    if (s->state == TCP_CHARDEV_STATE_CONNECTED) {
        int ret =  io_channel_send_full(s->ioc, buf, len,
                                        s->write_msgfds,
                                        s->write_msgfds_num);

        /* free the written msgfds in any cases
         * other than ret < 0 && errno == EAGAIN
         */
        if (!(ret < 0 && EAGAIN == errno)
            && s->write_msgfds_num) {
            g_free(s->write_msgfds);
            s->write_msgfds = 0;
            s->write_msgfds_num = 0;
        }

        if (ret < 0 && errno != EAGAIN) {
            if (tcp_chr_read_poll(chr) <= 0) {
                /* Perform disconnect and return error. */
                tcp_chr_disconnect_locked(chr);
            } /* else let the read handler finish it properly */
        }

        return ret;
    } else {
        /* Indicate an error. */
        errno = EIO;
        return -1;
    }
}

static int tcp_chr_read_poll(void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    SocketChardev *s = SOCKET_CHARDEV(opaque);
    if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
        return 0;
    }
    s->max_size = qemu_chr_be_can_write(chr);
    return s->max_size;
}

static void tcp_chr_process_IAC_bytes(Chardev *chr,
                                      SocketChardev *s,
                                      uint8_t *buf, int *size)
{
    /* Handle any telnet or tn3270 client's basic IAC options.
     * For telnet options, it satisfies char by char mode with no echo.
     * For tn3270 options, it satisfies binary mode with EOR.
     * All IAC options will be removed from the buf and the do_opt
     * pointer will be used to track the state of the width of the
     * IAC information.
     *
     * RFC854: "All TELNET commands consist of at least a two byte sequence.
     * The commands dealing with option negotiation are three byte sequences,
     * the third byte being the code for the option referenced."
     * "IAC BREAK", "IAC IP", "IAC NOP" and the double IAC are two bytes.
     * "IAC SB", "IAC SE" and "IAC EOR" are saved to split up data boundary
     * for tn3270.
     * NOP, Break and Interrupt Process(IP) might be encountered during a TN3270
     * session, and NOP and IP need to be done later.
     */

    int i;
    int j = 0;

    for (i = 0; i < *size; i++) {
        if (s->do_telnetopt > 1) {
            if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
                /* Double IAC means send an IAC */
                if (j != i) {
                    buf[j] = buf[i];
                }
                j++;
                s->do_telnetopt = 1;
            } else {
                if ((unsigned char)buf[i] == IAC_BREAK
                    && s->do_telnetopt == 2) {
                    /* Handle IAC break commands by sending a serial break */
                    qemu_chr_be_event(chr, CHR_EVENT_BREAK);
                    s->do_telnetopt++;
                } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_EOR
                           || (unsigned char)buf[i] == IAC_SB
                           || (unsigned char)buf[i] == IAC_SE)
                           && s->do_telnetopt == 2) {
                    buf[j++] = IAC;
                    buf[j++] = buf[i];
                    s->do_telnetopt++;
                } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_IP
                           || (unsigned char)buf[i] == IAC_NOP)
                           && s->do_telnetopt == 2) {
                    /* TODO: IP and NOP need to be implemented later. */
                    s->do_telnetopt++;
                }
                s->do_telnetopt++;
            }
            if (s->do_telnetopt >= 4) {
                s->do_telnetopt = 1;
            }
        } else {
            if ((unsigned char)buf[i] == IAC) {
                s->do_telnetopt = 2;
            } else {
                if (j != i) {
                    buf[j] = buf[i];
                }
                j++;
            }
        }
    }
    *size = j;
}

static int tcp_get_msgfds(Chardev *chr, int *fds, int num)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);

    int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num;

    assert(num <= TCP_MAX_FDS);

    if (to_copy) {
        int i;

        memcpy(fds, s->read_msgfds, to_copy * sizeof(int));

        /* Close unused fds */
        for (i = to_copy; i < s->read_msgfds_num; i++) {
            close(s->read_msgfds[i]);
        }

        g_free(s->read_msgfds);
        s->read_msgfds = 0;
        s->read_msgfds_num = 0;
    }

    return to_copy;
}

static int tcp_set_msgfds(Chardev *chr, int *fds, int num)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);

    /* clear old pending fd array */
    g_free(s->write_msgfds);
    s->write_msgfds = NULL;
    s->write_msgfds_num = 0;

    if ((s->state != TCP_CHARDEV_STATE_CONNECTED) ||
        !qio_channel_has_feature(s->ioc,
                                 QIO_CHANNEL_FEATURE_FD_PASS)) {
        return -1;
    }

    if (num) {
        s->write_msgfds = g_new(int, num);
        memcpy(s->write_msgfds, fds, num * sizeof(int));
    }

    s->write_msgfds_num = num;

    return 0;
}

static ssize_t tcp_chr_recv(Chardev *chr, char *buf, size_t len)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);
    struct iovec iov = { .iov_base = buf, .iov_len = len };
    int ret;
    size_t i;
    int *msgfds = NULL;
    size_t msgfds_num = 0;

    if (qio_channel_has_feature(s->ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
        ret = qio_channel_readv_full(s->ioc, &iov, 1,
                                     &msgfds, &msgfds_num,
                                     0, NULL);
    } else {
        ret = qio_channel_readv_full(s->ioc, &iov, 1,
                                     NULL, NULL,
                                     0, NULL);
    }

    if (msgfds_num) {
        /* close and clean read_msgfds */
        for (i = 0; i < s->read_msgfds_num; i++) {
            close(s->read_msgfds[i]);
        }

        if (s->read_msgfds_num) {
            g_free(s->read_msgfds);
        }

        s->read_msgfds = msgfds;
        s->read_msgfds_num = msgfds_num;
    }

    for (i = 0; i < s->read_msgfds_num; i++) {
        int fd = s->read_msgfds[i];
        if (fd < 0) {
            continue;
        }

        /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
        qemu_socket_set_block(fd);

#ifndef MSG_CMSG_CLOEXEC
        qemu_set_cloexec(fd);
#endif
    }

    if (ret == QIO_CHANNEL_ERR_BLOCK) {
        errno = EAGAIN;
        ret = -1;
    } else if (ret == -1) {
        errno = EIO;
    }

    return ret;
}

static GSource *tcp_chr_add_watch(Chardev *chr, GIOCondition cond)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);
    if (!s->ioc) {
        return NULL;
    }
    return qio_channel_create_watch(s->ioc, cond);
}

static void remove_hup_source(SocketChardev *s)
{
    if (s->hup_source != NULL) {
        g_source_destroy(s->hup_source);
        g_source_unref(s->hup_source);
        s->hup_source = NULL;
    }
}

static void char_socket_yank_iochannel(void *opaque)
{
    QIOChannel *ioc = QIO_CHANNEL(opaque);

    qio_channel_shutdown(ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
}

static void tcp_chr_free_connection(Chardev *chr)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);
    int i;

    if (s->read_msgfds_num) {
        for (i = 0; i < s->read_msgfds_num; i++) {
            close(s->read_msgfds[i]);
        }
        g_free(s->read_msgfds);
        s->read_msgfds = NULL;
        s->read_msgfds_num = 0;
    }

    remove_hup_source(s);

    tcp_set_msgfds(chr, NULL, 0);
    remove_fd_in_watch(chr);
    if (s->registered_yank &&
        (s->state == TCP_CHARDEV_STATE_CONNECTING
        || s->state == TCP_CHARDEV_STATE_CONNECTED)) {
        yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label),
                                 char_socket_yank_iochannel,
                                 QIO_CHANNEL(s->sioc));
    }

    if (s->ioc) {
        qio_channel_close(s->ioc, NULL);
    }
    object_unref(OBJECT(s->sioc));
    s->sioc = NULL;
    object_unref(OBJECT(s->ioc));
    s->ioc = NULL;
    g_free(chr->filename);
    chr->filename = NULL;
    tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
}

static const char *qemu_chr_socket_protocol(SocketChardev *s)
{
    if (s->is_telnet) {
        return "telnet";
    }
    return s->is_websock ? "websocket" : "tcp";
}

static char *qemu_chr_socket_address(SocketChardev *s, const char *prefix)
{
    switch (s->addr->type) {
    case SOCKET_ADDRESS_TYPE_INET:
        return g_strdup_printf("%s%s:%s:%s%s", prefix,
                               qemu_chr_socket_protocol(s),
                               s->addr->u.inet.host,
                               s->addr->u.inet.port,
                               s->is_listen ? ",server=on" : "");
        break;
    case SOCKET_ADDRESS_TYPE_UNIX:
    {
        const char *tight = "", *abstract = "";
        UnixSocketAddress *sa = &s->addr->u.q_unix;

#ifdef CONFIG_LINUX
        if (sa->has_abstract && sa->abstract) {
            abstract = ",abstract=on";
            if (sa->has_tight && sa->tight) {
                tight = ",tight=on";
            }
        }
#endif

        return g_strdup_printf("%sunix:%s%s%s%s", prefix, sa->path,
                               abstract, tight,
                               s->is_listen ? ",server=on" : "");
        break;
    }
    case SOCKET_ADDRESS_TYPE_FD:
        return g_strdup_printf("%sfd:%s%s", prefix, s->addr->u.fd.str,
                               s->is_listen ? ",server=on" : "");
        break;
    case SOCKET_ADDRESS_TYPE_VSOCK:
        return g_strdup_printf("%svsock:%s:%s", prefix,
                               s->addr->u.vsock.cid,
                               s->addr->u.vsock.port);
    default:
        abort();
    }
}

static void update_disconnected_filename(SocketChardev *s)
{
    Chardev *chr = CHARDEV(s);

    g_free(chr->filename);
    if (s->addr) {
        chr->filename = qemu_chr_socket_address(s, "disconnected:");
    } else {
        chr->filename = g_strdup("disconnected:socket");
    }
}

/* NB may be called even if tcp_chr_connect has not been
 * reached, due to TLS or telnet initialization failure,
 * so can *not* assume s->state == TCP_CHARDEV_STATE_CONNECTED
 * This must be called with chr->chr_write_lock held.
 */
static void tcp_chr_disconnect_locked(Chardev *chr)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);
    bool emit_close = s->state == TCP_CHARDEV_STATE_CONNECTED;

    tcp_chr_free_connection(chr);

    if (s->listener) {
        qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
                                              chr, NULL, chr->gcontext);
    }
    update_disconnected_filename(s);
    if (emit_close) {
        qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
    }
    if (s->reconnect_time && !s->reconnect_timer) {
        qemu_chr_socket_restart_timer(chr);
    }
}

static void tcp_chr_disconnect(Chardev *chr)
{
    qemu_mutex_lock(&chr->chr_write_lock);
    tcp_chr_disconnect_locked(chr);
    qemu_mutex_unlock(&chr->chr_write_lock);
}

static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    SocketChardev *s = SOCKET_CHARDEV(opaque);
    uint8_t buf[CHR_READ_BUF_LEN];
    int len, size;

    if ((s->state != TCP_CHARDEV_STATE_CONNECTED) ||
        s->max_size <= 0) {
        return TRUE;
    }
    len = tcp_chr_read_poll(opaque);
    if (len > sizeof(buf)) {
        len = sizeof(buf);
    }
    size = tcp_chr_recv(chr, (void *)buf, len);
    if (size == 0 || (size == -1 && errno != EAGAIN)) {
        /* connection closed */
        tcp_chr_disconnect(chr);
    } else if (size > 0) {
        if (s->do_telnetopt) {
            tcp_chr_process_IAC_bytes(chr, s, buf, &size);
        }
        if (size > 0) {
            qemu_chr_be_write(chr, buf, size);
        }
    }

    return TRUE;
}

static gboolean tcp_chr_hup(QIOChannel *channel,
                               GIOCondition cond,
                               void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    tcp_chr_disconnect(chr);
    return G_SOURCE_REMOVE;
}

static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);
    int size;
    int saved_errno;

    if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
        return 0;
    }

    qio_channel_set_blocking(s->ioc, true, NULL);
    size = tcp_chr_recv(chr, (void *) buf, len);
    saved_errno = errno;
    if (s->state != TCP_CHARDEV_STATE_DISCONNECTED) {
        qio_channel_set_blocking(s->ioc, false, NULL);
    }
    if (size == 0) {
        /* connection closed */
        tcp_chr_disconnect(chr);
    }

    errno = saved_errno;
    return size;
}

static char *qemu_chr_compute_filename(SocketChardev *s)
{
    struct sockaddr_storage *ss = &s->sioc->localAddr;
    struct sockaddr_storage *ps = &s->sioc->remoteAddr;
    socklen_t ss_len = s->sioc->localAddrLen;
    socklen_t ps_len = s->sioc->remoteAddrLen;
    char shost[NI_MAXHOST], sserv[NI_MAXSERV];
    char phost[NI_MAXHOST], pserv[NI_MAXSERV];
    const char *left = "", *right = "";

    switch (ss->ss_family) {
    case AF_UNIX:
        return g_strdup_printf("unix:%s%s",
                               ((struct sockaddr_un *)(ss))->sun_path,
                               s->is_listen ? ",server=on" : "");
    case AF_INET6:
        left  = "[";
        right = "]";
        /* fall through */
    case AF_INET:
        getnameinfo((struct sockaddr *) ss, ss_len, shost, sizeof(shost),
                    sserv, sizeof(sserv), NI_NUMERICHOST | NI_NUMERICSERV);
        getnameinfo((struct sockaddr *) ps, ps_len, phost, sizeof(phost),
                    pserv, sizeof(pserv), NI_NUMERICHOST | NI_NUMERICSERV);
        return g_strdup_printf("%s:%s%s%s:%s%s <-> %s%s%s:%s",
                               qemu_chr_socket_protocol(s),
                               left, shost, right, sserv,
                               s->is_listen ? ",server=on" : "",
                               left, phost, right, pserv);

    default:
        return g_strdup_printf("unknown");
    }
}

static void update_ioc_handlers(SocketChardev *s)
{
    Chardev *chr = CHARDEV(s);

    if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
        return;
    }

    remove_fd_in_watch(chr);
    chr->gsource = io_add_watch_poll(chr, s->ioc,
                                     tcp_chr_read_poll,
                                     tcp_chr_read, chr,
                                     chr->gcontext);

    remove_hup_source(s);
    s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP);
    g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup,
                          chr, NULL);
    g_source_attach(s->hup_source, chr->gcontext);
}

static void tcp_chr_connect(void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    SocketChardev *s = SOCKET_CHARDEV(opaque);

    g_free(chr->filename);
    chr->filename = qemu_chr_compute_filename(s);

    tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTED);
    update_ioc_handlers(s);
    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
}

static void tcp_chr_telnet_destroy(SocketChardev *s)
{
    if (s->telnet_source) {
        g_source_destroy(s->telnet_source);
        g_source_unref(s->telnet_source);
        s->telnet_source = NULL;
    }
}

static void tcp_chr_update_read_handler(Chardev *chr)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);

    if (s->listener && s->state == TCP_CHARDEV_STATE_DISCONNECTED) {
        /*
         * It's possible that chardev context is changed in
         * qemu_chr_be_update_read_handlers().  Reset it for QIO net
         * listener if there is.
         */
        qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
                                              chr, NULL, chr->gcontext);
    }

    if (s->telnet_source) {
        tcp_chr_telnet_init(CHARDEV(s));
    }

    update_ioc_handlers(s);
}

static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc,
                                       GIOCondition cond G_GNUC_UNUSED,
                                       gpointer user_data)
{
    SocketChardev *s = user_data;
    Chardev *chr = CHARDEV(s);
    TCPChardevTelnetInit *init = s->telnet_init;
    ssize_t ret;

    assert(init);

    ret = qio_channel_write(ioc, init->buf, init->buflen, NULL);
    if (ret < 0) {
        if (ret == QIO_CHANNEL_ERR_BLOCK) {
            ret = 0;
        } else {
            tcp_chr_disconnect(chr);
            goto end;
        }
    }
    init->buflen -= ret;

    if (init->buflen == 0) {
        tcp_chr_connect(chr);
        goto end;
    }

    memmove(init->buf, init->buf + ret, init->buflen);

    return G_SOURCE_CONTINUE;

end:
    g_free(s->telnet_init);
    s->telnet_init = NULL;
    g_source_unref(s->telnet_source);
    s->telnet_source = NULL;
    return G_SOURCE_REMOVE;
}

static void tcp_chr_telnet_init(Chardev *chr)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);
    TCPChardevTelnetInit *init;
    size_t n = 0;

    /* Destroy existing task */
    tcp_chr_telnet_destroy(s);

    if (s->telnet_init) {
        /* We are possibly during a handshake already */
        goto cont;
    }

    s->telnet_init = g_new0(TCPChardevTelnetInit, 1);
    init = s->telnet_init;

#define IACSET(x, a, b, c)                      \
    do {                                        \
        x[n++] = a;                             \
        x[n++] = b;                             \
        x[n++] = c;                             \
    } while (0)

    if (!s->is_tn3270) {
        init->buflen = 12;
        /* Prep the telnet negotiation to put telnet in binary,
         * no echo, single char mode */
        IACSET(init->buf, 0xff, 0xfb, 0x01);  /* IAC WILL ECHO */
        IACSET(init->buf, 0xff, 0xfb, 0x03);  /* IAC WILL Suppress go ahead */
        IACSET(init->buf, 0xff, 0xfb, 0x00);  /* IAC WILL Binary */
        IACSET(init->buf, 0xff, 0xfd, 0x00);  /* IAC DO Binary */
    } else {
        init->buflen = 21;
        /* Prep the TN3270 negotiation based on RFC1576 */
        IACSET(init->buf, 0xff, 0xfd, 0x19);  /* IAC DO EOR */
        IACSET(init->buf, 0xff, 0xfb, 0x19);  /* IAC WILL EOR */
        IACSET(init->buf, 0xff, 0xfd, 0x00);  /* IAC DO BINARY */
        IACSET(init->buf, 0xff, 0xfb, 0x00);  /* IAC WILL BINARY */
        IACSET(init->buf, 0xff, 0xfd, 0x18);  /* IAC DO TERMINAL TYPE */
        IACSET(init->buf, 0xff, 0xfa, 0x18);  /* IAC SB TERMINAL TYPE */
        IACSET(init->buf, 0x01, 0xff, 0xf0);  /* SEND IAC SE */
    }

#undef IACSET

cont:
    s->telnet_source = qio_channel_add_watch_source(s->ioc, G_IO_OUT,
                                                    tcp_chr_telnet_init_io,
                                                    s, NULL,
                                                    chr->gcontext);
}


static void tcp_chr_websock_handshake(QIOTask *task, gpointer user_data)
{
    Chardev *chr = user_data;
    SocketChardev *s = user_data;
    Error *err = NULL;

    if (qio_task_propagate_error(task, &err)) {
        error_reportf_err(err,
                          "websock handshake of character device %s failed: ",
                          chr->label);
        tcp_chr_disconnect(chr);
    } else {
        if (s->do_telnetopt) {
            tcp_chr_telnet_init(chr);
        } else {
            tcp_chr_connect(chr);
        }
    }
}


static void tcp_chr_websock_init(Chardev *chr)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);
    QIOChannelWebsock *wioc = NULL;
    gchar *name;

    wioc = qio_channel_websock_new_server(s->ioc);

    name = g_strdup_printf("chardev-websocket-server-%s", chr->label);
    qio_channel_set_name(QIO_CHANNEL(wioc), name);
    g_free(name);
    object_unref(OBJECT(s->ioc));
    s->ioc = QIO_CHANNEL(wioc);

    qio_channel_websock_handshake(wioc, tcp_chr_websock_handshake, chr, NULL);
}


static void tcp_chr_tls_handshake(QIOTask *task,
                                  gpointer user_data)
{
    Chardev *chr = user_data;
    SocketChardev *s = user_data;
    Error *err = NULL;

    if (qio_task_propagate_error(task, &err)) {
        error_reportf_err(err,
                          "TLS handshake of character device %s failed: ",
                          chr->label);
        tcp_chr_disconnect(chr);
    } else {
        if (s->is_websock) {
            tcp_chr_websock_init(chr);
        } else if (s->do_telnetopt) {
            tcp_chr_telnet_init(chr);
        } else {
            tcp_chr_connect(chr);
        }
    }
}


static void tcp_chr_tls_init(Chardev *chr)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);
    QIOChannelTLS *tioc;
    gchar *name;

    if (s->is_listen) {
        tioc = qio_channel_tls_new_server(
            s->ioc, s->tls_creds,
            s->tls_authz,
            NULL);
    } else {
        tioc = qio_channel_tls_new_client(
            s->ioc, s->tls_creds,
            s->addr->u.inet.host,
            NULL);
    }
    if (tioc == NULL) {
        tcp_chr_disconnect(chr);
        return;
    }
    name = g_strdup_printf("chardev-tls-%s-%s",
                           s->is_listen ? "server" : "client",
                           chr->label);
    qio_channel_set_name(QIO_CHANNEL(tioc), name);
    g_free(name);
    object_unref(OBJECT(s->ioc));
    s->ioc = QIO_CHANNEL(tioc);

    qio_channel_tls_handshake(tioc,
                              tcp_chr_tls_handshake,
                              chr,
                              NULL,
                              chr->gcontext);
}


static void tcp_chr_set_client_ioc_name(Chardev *chr,
                                        QIOChannelSocket *sioc)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);
    char *name;
    name = g_strdup_printf("chardev-tcp-%s-%s",
                           s->is_listen ? "server" : "client",
                           chr->label);
    qio_channel_set_name(QIO_CHANNEL(sioc), name);
    g_free(name);

}

static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);

    if (s->state != TCP_CHARDEV_STATE_CONNECTING) {
        return -1;
    }

    s->ioc = QIO_CHANNEL(sioc);
    object_ref(OBJECT(sioc));
    s->sioc = sioc;
    object_ref(OBJECT(sioc));

    qio_channel_set_blocking(s->ioc, false, NULL);

    if (s->do_nodelay) {
        qio_channel_set_delay(s->ioc, false);
    }
    if (s->listener) {
        qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
                                              NULL, chr->gcontext);
    }

    if (s->tls_creds) {
        tcp_chr_tls_init(chr);
    } else if (s->is_websock) {
        tcp_chr_websock_init(chr);
    } else if (s->do_telnetopt) {
        tcp_chr_telnet_init(chr);
    } else {
        tcp_chr_connect(chr);
    }

    return 0;
}


static int tcp_chr_add_client(Chardev *chr, int fd)
{
    int ret;
    QIOChannelSocket *sioc;
    SocketChardev *s = SOCKET_CHARDEV(chr);

    if (s->state != TCP_CHARDEV_STATE_DISCONNECTED) {
        return -1;
    }

    sioc = qio_channel_socket_new_fd(fd, NULL);
    if (!sioc) {
        return -1;
    }
    tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
    tcp_chr_set_client_ioc_name(chr, sioc);
    if (s->registered_yank) {
        yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
                               char_socket_yank_iochannel,
                               QIO_CHANNEL(sioc));
    }
    ret = tcp_chr_new_client(chr, sioc);
    object_unref(OBJECT(sioc));
    return ret;
}

static void tcp_chr_accept(QIONetListener *listener,
                           QIOChannelSocket *cioc,
                           void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    SocketChardev *s = SOCKET_CHARDEV(chr);

    tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
    tcp_chr_set_client_ioc_name(chr, cioc);
    if (s->registered_yank) {
        yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
                               char_socket_yank_iochannel,
                               QIO_CHANNEL(cioc));
    }
    tcp_chr_new_client(chr, cioc);
}


static int tcp_chr_connect_client_sync(Chardev *chr, Error **errp)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);
    QIOChannelSocket *sioc = qio_channel_socket_new();
    tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
    tcp_chr_set_client_ioc_name(chr, sioc);
    if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) {
        tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
        object_unref(OBJECT(sioc));
        return -1;
    }
    if (s->registered_yank) {
        yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
                               char_socket_yank_iochannel,
                               QIO_CHANNEL(sioc));
    }
    tcp_chr_new_client(chr, sioc);
    object_unref(OBJECT(sioc));
    return 0;
}


static void tcp_chr_accept_server_sync(Chardev *chr)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);
    QIOChannelSocket *sioc;
    info_report("QEMU waiting for connection on: %s",
                chr->filename);
    tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
    sioc = qio_net_listener_wait_client(s->listener);
    tcp_chr_set_client_ioc_name(chr, sioc);
    if (s->registered_yank) {
        yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
                               char_socket_yank_iochannel,
                               QIO_CHANNEL(sioc));
    }
    tcp_chr_new_client(chr, sioc);
    object_unref(OBJECT(sioc));
}


static int tcp_chr_wait_connected(Chardev *chr, Error **errp)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);
    const char *opts[] = { "telnet", "tn3270", "websock", "tls-creds" };
    bool optset[] = { s->is_telnet, s->is_tn3270, s->is_websock, s->tls_creds };
    size_t i;

    QEMU_BUILD_BUG_ON(G_N_ELEMENTS(opts) != G_N_ELEMENTS(optset));
    for (i = 0; i < G_N_ELEMENTS(opts); i++) {
        if (optset[i]) {
            error_setg(errp,
                       "'%s' option is incompatible with waiting for "
                       "connection completion", opts[i]);
            return -1;
        }
    }

    tcp_chr_reconn_timer_cancel(s);

    /*
     * We expect states to be as follows:
     *
     *  - server
     *    - wait   -> CONNECTED
     *    - nowait -> DISCONNECTED
     *  - client
     *    - reconnect == 0 -> CONNECTED
     *    - reconnect != 0 -> CONNECTING
     *
     */
    if (s->state == TCP_CHARDEV_STATE_CONNECTING) {
        if (!s->connect_task) {
            error_setg(errp,
                       "Unexpected 'connecting' state without connect task "
                       "while waiting for connection completion");
            return -1;
        }
        /*
         * tcp_chr_wait_connected should only ever be run from the
         * main loop thread associated with chr->gcontext, otherwise
         * qio_task_wait_thread has a dangerous race condition with
         * free'ing of the s->connect_task object.
         *
         * Acquiring the main context doesn't 100% prove we're in
         * the main loop thread, but it does at least guarantee
         * that the main loop won't be executed by another thread
         * avoiding the race condition with the task idle callback.
         */
        g_main_context_acquire(chr->gcontext);
        qio_task_wait_thread(s->connect_task);
        g_main_context_release(chr->gcontext);

        /*
         * The completion callback (qemu_chr_socket_connected) for
         * s->connect_task should have set this to NULL by the time
         * qio_task_wait_thread has returned.
         */
        assert(!s->connect_task);

        /*
         * NB we are *not* guaranteed to have "s->state == ..CONNECTED"
         * at this point as this first connect may be failed, so
         * allow the next loop to run regardless.
         */
    }

    while (s->state != TCP_CHARDEV_STATE_CONNECTED) {
        if (s->is_listen) {
            tcp_chr_accept_server_sync(chr);
        } else {
            Error *err = NULL;
            if (tcp_chr_connect_client_sync(chr, &err) < 0) {
                if (s->reconnect_time) {
                    error_free(err);
                    g_usleep(s->reconnect_time * 1000ULL * 1000ULL);
                } else {
                    error_propagate(errp, err);
                    return -1;
                }
            }
        }
    }

    return 0;
}

static void char_socket_finalize(Object *obj)
{
    Chardev *chr = CHARDEV(obj);
    SocketChardev *s = SOCKET_CHARDEV(obj);

    tcp_chr_free_connection(chr);
    tcp_chr_reconn_timer_cancel(s);
    qapi_free_SocketAddress(s->addr);
    tcp_chr_telnet_destroy(s);
    g_free(s->telnet_init);
    if (s->listener) {
        qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
                                              NULL, chr->gcontext);
        object_unref(OBJECT(s->listener));
        s->listener = NULL;
    }
    if (s->tls_creds) {
        object_unref(OBJECT(s->tls_creds));
    }
    g_free(s->tls_authz);
    if (s->registered_yank) {
        /*
         * In the chardev-change special-case, we shouldn't unregister the yank
         * instance, as it still may be needed.
         */
        if (!chr->handover_yank_instance) {
            yank_unregister_instance(CHARDEV_YANK_INSTANCE(chr->label));
        }
    }

    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}

static void qemu_chr_socket_connected(QIOTask *task, void *opaque)
{
    QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
    Chardev *chr = CHARDEV(opaque);
    SocketChardev *s = SOCKET_CHARDEV(chr);
    Error *err = NULL;

    s->connect_task = NULL;

    if (qio_task_propagate_error(task, &err)) {
        tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
        if (s->registered_yank) {
            yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label),
                                     char_socket_yank_iochannel,
                                     QIO_CHANNEL(sioc));
        }
        check_report_connect_error(chr, err);
        goto cleanup;
    }

    s->connect_err_reported = false;
    tcp_chr_new_client(chr, sioc);

cleanup:
    object_unref(OBJECT(sioc));
}


static void tcp_chr_connect_client_task(QIOTask *task,
                                        gpointer opaque)
{
    QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
    SocketAddress *addr = opaque;
    Error *err = NULL;

    qio_channel_socket_connect_sync(ioc, addr, &err);

    qio_task_set_error(task, err);
}


static void tcp_chr_connect_client_async(Chardev *chr)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);
    QIOChannelSocket *sioc;

    tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
    sioc = qio_channel_socket_new();
    tcp_chr_set_client_ioc_name(chr, sioc);
    if (s->registered_yank) {
        yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
                               char_socket_yank_iochannel,
                               QIO_CHANNEL(sioc));
    }
    /*
     * Normally code would use the qio_channel_socket_connect_async
     * method which uses a QIOTask + qio_task_set_error internally
     * to avoid blocking. The tcp_chr_wait_connected method, however,
     * needs a way to synchronize with completion of the background
     * connect task which can't be done with the QIOChannelSocket
     * async APIs. Thus we must use QIOTask directly to implement
     * the non-blocking concept locally.
     */
    s->connect_task = qio_task_new(OBJECT(sioc),
                                   qemu_chr_socket_connected,
                                   object_ref(OBJECT(chr)),
                                   (GDestroyNotify)object_unref);
    qio_task_run_in_thread(s->connect_task,
                           tcp_chr_connect_client_task,
                           s->addr,
                           NULL,
                           chr->gcontext);
}

static gboolean socket_reconnect_timeout(gpointer opaque)
{
    Chardev *chr = CHARDEV(opaque);
    SocketChardev *s = SOCKET_CHARDEV(opaque);

    qemu_mutex_lock(&chr->chr_write_lock);
    g_source_unref(s->reconnect_timer);
    s->reconnect_timer = NULL;
    qemu_mutex_unlock(&chr->chr_write_lock);

    if (chr->be_open) {
        return false;
    }

    tcp_chr_connect_client_async(chr);

    return false;
}


static int qmp_chardev_open_socket_server(Chardev *chr,
                                          bool is_telnet,
                                          bool is_waitconnect,
                                          Error **errp)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);
    char *name;
    if (is_telnet) {
        s->do_telnetopt = 1;
    }
    s->listener = qio_net_listener_new();

    name = g_strdup_printf("chardev-tcp-listener-%s", chr->label);
    qio_net_listener_set_name(s->listener, name);
    g_free(name);

    if (s->addr->type == SOCKET_ADDRESS_TYPE_FD && !*s->addr->u.fd.str) {
        goto skip_listen;
    }

    if (qio_net_listener_open_sync(s->listener, s->addr, 1, errp) < 0) {
        object_unref(OBJECT(s->listener));
        s->listener = NULL;
        return -1;
    }

    qapi_free_SocketAddress(s->addr);
    s->addr = socket_local_address(s->listener->sioc[0]->fd, errp);

skip_listen:
    update_disconnected_filename(s);

    if (is_waitconnect) {
        tcp_chr_accept_server_sync(chr);
    } else {
        qio_net_listener_set_client_func_full(s->listener,
                                              tcp_chr_accept,
                                              chr, NULL,
                                              chr->gcontext);
    }

    return 0;
}


static int qmp_chardev_open_socket_client(Chardev *chr,
                                          int64_t reconnect,
                                          Error **errp)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);

    if (reconnect > 0) {
        s->reconnect_time = reconnect;
        tcp_chr_connect_client_async(chr);
        return 0;
    } else {
        return tcp_chr_connect_client_sync(chr, errp);
    }
}


static bool qmp_chardev_validate_socket(ChardevSocket *sock,
                                        SocketAddress *addr,
                                        Error **errp)
{
    /* Validate any options which have a dependency on address type */
    switch (addr->type) {
    case SOCKET_ADDRESS_TYPE_FD:
        if (sock->has_reconnect) {
            error_setg(errp,
                       "'reconnect' option is incompatible with "
                       "'fd' address type");
            return false;
        }
        if (sock->tls_creds &&
            !(sock->has_server && sock->server)) {
            error_setg(errp,
                       "'tls_creds' option is incompatible with "
                       "'fd' address type as client");
            return false;
        }
        break;

    case SOCKET_ADDRESS_TYPE_UNIX:
        if (sock->tls_creds) {
            error_setg(errp,
                       "'tls_creds' option is incompatible with "
                       "'unix' address type");
            return false;
        }
        break;

    case SOCKET_ADDRESS_TYPE_INET:
        break;

    case SOCKET_ADDRESS_TYPE_VSOCK:
        if (sock->tls_creds) {
            error_setg(errp,
                       "'tls_creds' option is incompatible with "
                       "'vsock' address type");
            return false;
        }

    default:
        break;
    }

    if (sock->tls_authz && !sock->tls_creds) {
        error_setg(errp, "'tls_authz' option requires 'tls_creds' option");
        return false;
    }

    /* Validate any options which have a dependency on client vs server */
    if (!sock->has_server || sock->server) {
        if (sock->has_reconnect) {
            error_setg(errp,
                       "'reconnect' option is incompatible with "
                       "socket in server listen mode");
            return false;
        }
    } else {
        if (sock->has_websocket && sock->websocket) {
            error_setg(errp, "%s", "Websocket client is not implemented");
            return false;
        }
        if (sock->has_wait) {
            error_setg(errp, "%s",
                       "'wait' option is incompatible with "
                       "socket in client connect mode");
            return false;
        }
    }

    return true;
}


static void qmp_chardev_open_socket(Chardev *chr,
                                    ChardevBackend *backend,
                                    bool *be_opened,
                                    Error **errp)
{
    SocketChardev *s = SOCKET_CHARDEV(chr);
    ChardevSocket *sock = backend->u.socket.data;
    bool do_nodelay     = sock->has_nodelay ? sock->nodelay : false;
    bool is_listen      = sock->has_server  ? sock->server  : true;
    bool is_telnet      = sock->has_telnet  ? sock->telnet  : false;
    bool is_tn3270      = sock->has_tn3270  ? sock->tn3270  : false;
    bool is_waitconnect = sock->has_wait    ? sock->wait    : false;
    bool is_websock     = sock->has_websocket ? sock->websocket : false;
    int64_t reconnect   = sock->has_reconnect ? sock->reconnect : 0;
    SocketAddress *addr;

    s->is_listen = is_listen;
    s->is_telnet = is_telnet;
    s->is_tn3270 = is_tn3270;
    s->is_websock = is_websock;
    s->do_nodelay = do_nodelay;
    if (sock->tls_creds) {
        Object *creds;
        creds = object_resolve_path_component(
            object_get_objects_root(), sock->tls_creds);
        if (!creds) {
            error_setg(errp, "No TLS credentials with id '%s'",
                       sock->tls_creds);
            return;
        }
        s->tls_creds = (QCryptoTLSCreds *)
            object_dynamic_cast(creds,
                                TYPE_QCRYPTO_TLS_CREDS);
        if (!s->tls_creds) {
            error_setg(errp, "Object with id '%s' is not TLS credentials",
                       sock->tls_creds);
            return;
        }
        object_ref(OBJECT(s->tls_creds));
        if (!qcrypto_tls_creds_check_endpoint(s->tls_creds,
                                          is_listen
                                          ? QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
                                          : QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT,
                                          errp)) {
            return;
        }
    }
    s->tls_authz = g_strdup(sock->tls_authz);

    s->addr = addr = socket_address_flatten(sock->addr);

    if (!qmp_chardev_validate_socket(sock, addr, errp)) {
        return;
    }

    qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE);
#ifndef _WIN32
    /* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */
    if (addr->type == SOCKET_ADDRESS_TYPE_UNIX) {
        qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS);
    }
#endif

    /*
     * In the chardev-change special-case, we shouldn't register a new yank
     * instance, as there already may be one.
     */
    if (!chr->handover_yank_instance) {
        if (!yank_register_instance(CHARDEV_YANK_INSTANCE(chr->label), errp)) {
            return;
        }
    }
    s->registered_yank = true;

    /* be isn't opened until we get a connection */
    *be_opened = false;

    update_disconnected_filename(s);

    if (s->is_listen) {
        if (qmp_chardev_open_socket_server(chr, is_telnet || is_tn3270,
                                           is_waitconnect, errp) < 0) {
            return;
        }
    } else {
        if (qmp_chardev_open_socket_client(chr, reconnect, errp) < 0) {
            return;
        }
    }
}

static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
                                  Error **errp)
{
    const char *path = qemu_opt_get(opts, "path");
    const char *host = qemu_opt_get(opts, "host");
    const char *port = qemu_opt_get(opts, "port");
    const char *fd = qemu_opt_get(opts, "fd");
#ifdef CONFIG_LINUX
    bool tight = qemu_opt_get_bool(opts, "tight", true);
    bool abstract = qemu_opt_get_bool(opts, "abstract", false);
#endif
    SocketAddressLegacy *addr;
    ChardevSocket *sock;

    if ((!!path + !!fd + !!host) > 1) {
        error_setg(errp,
                   "None or one of 'path', 'fd' or 'host' option required.");
        return;
    }

    if (host && !port) {
        error_setg(errp, "chardev: socket: no port given");
        return;
    }

    backend->type = CHARDEV_BACKEND_KIND_SOCKET;
    sock = backend->u.socket.data = g_new0(ChardevSocket, 1);
    qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock));

    if (qemu_opt_get(opts, "delay") && qemu_opt_get(opts, "nodelay")) {
        error_setg(errp, "'delay' and 'nodelay' are mutually exclusive");
        return;
    }
    sock->has_nodelay =
        qemu_opt_get(opts, "delay") ||
        qemu_opt_get(opts, "nodelay");
    sock->nodelay =
        !qemu_opt_get_bool(opts, "delay", true) ||
        qemu_opt_get_bool(opts, "nodelay", false);

    /*
     * We have different default to QMP for 'server', hence
     * we can't just check for existence of 'server'
     */
    sock->has_server = true;
    sock->server = qemu_opt_get_bool(opts, "server", false);
    sock->has_telnet = qemu_opt_get(opts, "telnet");
    sock->telnet = qemu_opt_get_bool(opts, "telnet", false);
    sock->has_tn3270 = qemu_opt_get(opts, "tn3270");
    sock->tn3270 = qemu_opt_get_bool(opts, "tn3270", false);
    sock->has_websocket = qemu_opt_get(opts, "websocket");
    sock->websocket = qemu_opt_get_bool(opts, "websocket", false);
    /*
     * We have different default to QMP for 'wait' when 'server'
     * is set, hence we can't just check for existence of 'wait'
     */
    sock->has_wait = qemu_opt_find(opts, "wait") || sock->server;
    sock->wait = qemu_opt_get_bool(opts, "wait", true);
    sock->has_reconnect = qemu_opt_find(opts, "reconnect");
    sock->reconnect = qemu_opt_get_number(opts, "reconnect", 0);
    sock->tls_creds = g_strdup(qemu_opt_get(opts, "tls-creds"));
    sock->tls_authz = g_strdup(qemu_opt_get(opts, "tls-authz"));

    addr = g_new0(SocketAddressLegacy, 1);
    if (path) {
        UnixSocketAddress *q_unix;
        addr->type = SOCKET_ADDRESS_TYPE_UNIX;
        q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
        q_unix->path = g_strdup(path);
#ifdef CONFIG_LINUX
        q_unix->has_tight = true;
        q_unix->tight = tight;
        q_unix->has_abstract = true;
        q_unix->abstract = abstract;
#endif
    } else if (host) {
        addr->type = SOCKET_ADDRESS_TYPE_INET;
        addr->u.inet.data = g_new(InetSocketAddress, 1);
        *addr->u.inet.data = (InetSocketAddress) {
            .host = g_strdup(host),
            .port = g_strdup(port),
            .has_to = qemu_opt_get(opts, "to"),
            .to = qemu_opt_get_number(opts, "to", 0),
            .has_ipv4 = qemu_opt_get(opts, "ipv4"),
            .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0),
            .has_ipv6 = qemu_opt_get(opts, "ipv6"),
            .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
        };
    } else {
        addr->type = SOCKET_ADDRESS_TYPE_FD;
        addr->u.fd.data = g_new(FdSocketAddress, 1);
        addr->u.fd.data->str = g_strdup(fd);
    }
    sock->addr = addr;
}

static void
char_socket_get_addr(Object *obj, Visitor *v, const char *name,
                     void *opaque, Error **errp)
{
    SocketChardev *s = SOCKET_CHARDEV(obj);

    visit_type_SocketAddress(v, name, &s->addr, errp);
}

static bool
char_socket_get_connected(Object *obj, Error **errp)
{
    SocketChardev *s = SOCKET_CHARDEV(obj);

    return s->state == TCP_CHARDEV_STATE_CONNECTED;
}

static void char_socket_class_init(ObjectClass *oc, void *data)
{
    ChardevClass *cc = CHARDEV_CLASS(oc);

    cc->supports_yank = true;

    cc->parse = qemu_chr_parse_socket;
    cc->open = qmp_chardev_open_socket;
    cc->chr_wait_connected = tcp_chr_wait_connected;
    cc->chr_write = tcp_chr_write;
    cc->chr_sync_read = tcp_chr_sync_read;
    cc->chr_disconnect = tcp_chr_disconnect;
    cc->get_msgfds = tcp_get_msgfds;
    cc->set_msgfds = tcp_set_msgfds;
    cc->chr_add_client = tcp_chr_add_client;
    cc->chr_add_watch = tcp_chr_add_watch;
    cc->chr_update_read_handler = tcp_chr_update_read_handler;

    object_class_property_add(oc, "addr", "SocketAddress",
                              char_socket_get_addr, NULL,
                              NULL, NULL);

    object_class_property_add_bool(oc, "connected", char_socket_get_connected,
                                   NULL);
}

static const TypeInfo char_socket_type_info = {
    .name = TYPE_CHARDEV_SOCKET,
    .parent = TYPE_CHARDEV,
    .instance_size = sizeof(SocketChardev),
    .instance_finalize = char_socket_finalize,
    .class_init = char_socket_class_init,
};

static void register_types(void)
{
    type_register_static(&char_socket_type_info);
}

type_init(register_types);
