qemu/chardev/char-socket.c
<<
>>
Prefs
   1/*
   2 * QEMU System Emulator
   3 *
   4 * Copyright (c) 2003-2008 Fabrice Bellard
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a copy
   7 * of this software and associated documentation files (the "Software"), to deal
   8 * in the Software without restriction, including without limitation the rights
   9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 * copies of the Software, and to permit persons to whom the Software is
  11 * furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 * THE SOFTWARE.
  23 */
  24
  25#include "qemu/osdep.h"
  26#include "chardev/char.h"
  27#include "io/channel-socket.h"
  28#include "io/channel-tls.h"
  29#include "io/channel-websock.h"
  30#include "io/net-listener.h"
  31#include "qemu/error-report.h"
  32#include "qemu/module.h"
  33#include "qemu/option.h"
  34#include "qapi/error.h"
  35#include "qapi/clone-visitor.h"
  36#include "qapi/qapi-visit-sockets.h"
  37#include "qemu/yank.h"
  38
  39#include "chardev/char-io.h"
  40#include "qom/object.h"
  41
  42/***********************************************************/
  43/* TCP Net console */
  44
  45#define TCP_MAX_FDS 16
  46
  47typedef struct {
  48    char buf[21];
  49    size_t buflen;
  50} TCPChardevTelnetInit;
  51
  52typedef enum {
  53    TCP_CHARDEV_STATE_DISCONNECTED,
  54    TCP_CHARDEV_STATE_CONNECTING,
  55    TCP_CHARDEV_STATE_CONNECTED,
  56} TCPChardevState;
  57
  58struct SocketChardev {
  59    Chardev parent;
  60    QIOChannel *ioc; /* Client I/O channel */
  61    QIOChannelSocket *sioc; /* Client master channel */
  62    QIONetListener *listener;
  63    GSource *hup_source;
  64    QCryptoTLSCreds *tls_creds;
  65    char *tls_authz;
  66    TCPChardevState state;
  67    int max_size;
  68    int do_telnetopt;
  69    int do_nodelay;
  70    int *read_msgfds;
  71    size_t read_msgfds_num;
  72    int *write_msgfds;
  73    size_t write_msgfds_num;
  74    bool registered_yank;
  75
  76    SocketAddress *addr;
  77    bool is_listen;
  78    bool is_telnet;
  79    bool is_tn3270;
  80    GSource *telnet_source;
  81    TCPChardevTelnetInit *telnet_init;
  82
  83    bool is_websock;
  84
  85    GSource *reconnect_timer;
  86    int64_t reconnect_time;
  87    bool connect_err_reported;
  88
  89    QIOTask *connect_task;
  90};
  91typedef struct SocketChardev SocketChardev;
  92
  93DECLARE_INSTANCE_CHECKER(SocketChardev, SOCKET_CHARDEV,
  94                         TYPE_CHARDEV_SOCKET)
  95
  96static gboolean socket_reconnect_timeout(gpointer opaque);
  97static void tcp_chr_telnet_init(Chardev *chr);
  98
  99static void tcp_chr_change_state(SocketChardev *s, TCPChardevState state)
 100{
 101    switch (state) {
 102    case TCP_CHARDEV_STATE_DISCONNECTED:
 103        break;
 104    case TCP_CHARDEV_STATE_CONNECTING:
 105        assert(s->state == TCP_CHARDEV_STATE_DISCONNECTED);
 106        break;
 107    case TCP_CHARDEV_STATE_CONNECTED:
 108        assert(s->state == TCP_CHARDEV_STATE_CONNECTING);
 109        break;
 110    }
 111    s->state = state;
 112}
 113
 114static void tcp_chr_reconn_timer_cancel(SocketChardev *s)
 115{
 116    if (s->reconnect_timer) {
 117        g_source_destroy(s->reconnect_timer);
 118        g_source_unref(s->reconnect_timer);
 119        s->reconnect_timer = NULL;
 120    }
 121}
 122
 123static void qemu_chr_socket_restart_timer(Chardev *chr)
 124{
 125    SocketChardev *s = SOCKET_CHARDEV(chr);
 126    char *name;
 127
 128    assert(s->state == TCP_CHARDEV_STATE_DISCONNECTED);
 129    assert(!s->reconnect_timer);
 130    name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label);
 131    s->reconnect_timer = qemu_chr_timeout_add_ms(chr,
 132                                                 s->reconnect_time * 1000,
 133                                                 socket_reconnect_timeout,
 134                                                 chr);
 135    g_source_set_name(s->reconnect_timer, name);
 136    g_free(name);
 137}
 138
 139static void check_report_connect_error(Chardev *chr,
 140                                       Error *err)
 141{
 142    SocketChardev *s = SOCKET_CHARDEV(chr);
 143
 144    if (!s->connect_err_reported) {
 145        error_reportf_err(err,
 146                          "Unable to connect character device %s: ",
 147                          chr->label);
 148        s->connect_err_reported = true;
 149    } else {
 150        error_free(err);
 151    }
 152    qemu_chr_socket_restart_timer(chr);
 153}
 154
 155static void tcp_chr_accept(QIONetListener *listener,
 156                           QIOChannelSocket *cioc,
 157                           void *opaque);
 158
 159static int tcp_chr_read_poll(void *opaque);
 160static void tcp_chr_disconnect_locked(Chardev *chr);
 161
 162/* Called with chr_write_lock held.  */
 163static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
 164{
 165    SocketChardev *s = SOCKET_CHARDEV(chr);
 166
 167    if (s->state == TCP_CHARDEV_STATE_CONNECTED) {
 168        int ret =  io_channel_send_full(s->ioc, buf, len,
 169                                        s->write_msgfds,
 170                                        s->write_msgfds_num);
 171
 172        /* free the written msgfds in any cases
 173         * other than ret < 0 && errno == EAGAIN
 174         */
 175        if (!(ret < 0 && EAGAIN == errno)
 176            && s->write_msgfds_num) {
 177            g_free(s->write_msgfds);
 178            s->write_msgfds = 0;
 179            s->write_msgfds_num = 0;
 180        }
 181
 182        if (ret < 0 && errno != EAGAIN) {
 183            if (tcp_chr_read_poll(chr) <= 0) {
 184                /* Perform disconnect and return error. */
 185                tcp_chr_disconnect_locked(chr);
 186            } /* else let the read handler finish it properly */
 187        }
 188
 189        return ret;
 190    } else {
 191        /* Indicate an error. */
 192        errno = EIO;
 193        return -1;
 194    }
 195}
 196
 197static int tcp_chr_read_poll(void *opaque)
 198{
 199    Chardev *chr = CHARDEV(opaque);
 200    SocketChardev *s = SOCKET_CHARDEV(opaque);
 201    if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
 202        return 0;
 203    }
 204    s->max_size = qemu_chr_be_can_write(chr);
 205    return s->max_size;
 206}
 207
 208static void tcp_chr_process_IAC_bytes(Chardev *chr,
 209                                      SocketChardev *s,
 210                                      uint8_t *buf, int *size)
 211{
 212    /* Handle any telnet or tn3270 client's basic IAC options.
 213     * For telnet options, it satisfies char by char mode with no echo.
 214     * For tn3270 options, it satisfies binary mode with EOR.
 215     * All IAC options will be removed from the buf and the do_opt
 216     * pointer will be used to track the state of the width of the
 217     * IAC information.
 218     *
 219     * RFC854: "All TELNET commands consist of at least a two byte sequence.
 220     * The commands dealing with option negotiation are three byte sequences,
 221     * the third byte being the code for the option referenced."
 222     * "IAC BREAK", "IAC IP", "IAC NOP" and the double IAC are two bytes.
 223     * "IAC SB", "IAC SE" and "IAC EOR" are saved to split up data boundary
 224     * for tn3270.
 225     * NOP, Break and Interrupt Process(IP) might be encountered during a TN3270
 226     * session, and NOP and IP need to be done later.
 227     */
 228
 229    int i;
 230    int j = 0;
 231
 232    for (i = 0; i < *size; i++) {
 233        if (s->do_telnetopt > 1) {
 234            if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
 235                /* Double IAC means send an IAC */
 236                if (j != i) {
 237                    buf[j] = buf[i];
 238                }
 239                j++;
 240                s->do_telnetopt = 1;
 241            } else {
 242                if ((unsigned char)buf[i] == IAC_BREAK
 243                    && s->do_telnetopt == 2) {
 244                    /* Handle IAC break commands by sending a serial break */
 245                    qemu_chr_be_event(chr, CHR_EVENT_BREAK);
 246                    s->do_telnetopt++;
 247                } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_EOR
 248                           || (unsigned char)buf[i] == IAC_SB
 249                           || (unsigned char)buf[i] == IAC_SE)
 250                           && s->do_telnetopt == 2) {
 251                    buf[j++] = IAC;
 252                    buf[j++] = buf[i];
 253                    s->do_telnetopt++;
 254                } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_IP
 255                           || (unsigned char)buf[i] == IAC_NOP)
 256                           && s->do_telnetopt == 2) {
 257                    /* TODO: IP and NOP need to be implemented later. */
 258                    s->do_telnetopt++;
 259                }
 260                s->do_telnetopt++;
 261            }
 262            if (s->do_telnetopt >= 4) {
 263                s->do_telnetopt = 1;
 264            }
 265        } else {
 266            if ((unsigned char)buf[i] == IAC) {
 267                s->do_telnetopt = 2;
 268            } else {
 269                if (j != i) {
 270                    buf[j] = buf[i];
 271                }
 272                j++;
 273            }
 274        }
 275    }
 276    *size = j;
 277}
 278
 279static int tcp_get_msgfds(Chardev *chr, int *fds, int num)
 280{
 281    SocketChardev *s = SOCKET_CHARDEV(chr);
 282
 283    int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num;
 284
 285    assert(num <= TCP_MAX_FDS);
 286
 287    if (to_copy) {
 288        int i;
 289
 290        memcpy(fds, s->read_msgfds, to_copy * sizeof(int));
 291
 292        /* Close unused fds */
 293        for (i = to_copy; i < s->read_msgfds_num; i++) {
 294            close(s->read_msgfds[i]);
 295        }
 296
 297        g_free(s->read_msgfds);
 298        s->read_msgfds = 0;
 299        s->read_msgfds_num = 0;
 300    }
 301
 302    return to_copy;
 303}
 304
 305static int tcp_set_msgfds(Chardev *chr, int *fds, int num)
 306{
 307    SocketChardev *s = SOCKET_CHARDEV(chr);
 308
 309    /* clear old pending fd array */
 310    g_free(s->write_msgfds);
 311    s->write_msgfds = NULL;
 312    s->write_msgfds_num = 0;
 313
 314    if ((s->state != TCP_CHARDEV_STATE_CONNECTED) ||
 315        !qio_channel_has_feature(s->ioc,
 316                                 QIO_CHANNEL_FEATURE_FD_PASS)) {
 317        return -1;
 318    }
 319
 320    if (num) {
 321        s->write_msgfds = g_new(int, num);
 322        memcpy(s->write_msgfds, fds, num * sizeof(int));
 323    }
 324
 325    s->write_msgfds_num = num;
 326
 327    return 0;
 328}
 329
 330static ssize_t tcp_chr_recv(Chardev *chr, char *buf, size_t len)
 331{
 332    SocketChardev *s = SOCKET_CHARDEV(chr);
 333    struct iovec iov = { .iov_base = buf, .iov_len = len };
 334    int ret;
 335    size_t i;
 336    int *msgfds = NULL;
 337    size_t msgfds_num = 0;
 338
 339    if (qio_channel_has_feature(s->ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
 340        ret = qio_channel_readv_full(s->ioc, &iov, 1,
 341                                     &msgfds, &msgfds_num,
 342                                     NULL);
 343    } else {
 344        ret = qio_channel_readv_full(s->ioc, &iov, 1,
 345                                     NULL, NULL,
 346                                     NULL);
 347    }
 348
 349    if (ret == QIO_CHANNEL_ERR_BLOCK) {
 350        errno = EAGAIN;
 351        ret = -1;
 352    } else if (ret == -1) {
 353        errno = EIO;
 354    }
 355
 356    if (msgfds_num) {
 357        /* close and clean read_msgfds */
 358        for (i = 0; i < s->read_msgfds_num; i++) {
 359            close(s->read_msgfds[i]);
 360        }
 361
 362        if (s->read_msgfds_num) {
 363            g_free(s->read_msgfds);
 364        }
 365
 366        s->read_msgfds = msgfds;
 367        s->read_msgfds_num = msgfds_num;
 368    }
 369
 370    for (i = 0; i < s->read_msgfds_num; i++) {
 371        int fd = s->read_msgfds[i];
 372        if (fd < 0) {
 373            continue;
 374        }
 375
 376        /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
 377        qemu_set_block(fd);
 378
 379#ifndef MSG_CMSG_CLOEXEC
 380        qemu_set_cloexec(fd);
 381#endif
 382    }
 383
 384    return ret;
 385}
 386
 387static GSource *tcp_chr_add_watch(Chardev *chr, GIOCondition cond)
 388{
 389    SocketChardev *s = SOCKET_CHARDEV(chr);
 390    if (!s->ioc) {
 391        return NULL;
 392    }
 393    return qio_channel_create_watch(s->ioc, cond);
 394}
 395
 396static void remove_hup_source(SocketChardev *s)
 397{
 398    if (s->hup_source != NULL) {
 399        g_source_destroy(s->hup_source);
 400        g_source_unref(s->hup_source);
 401        s->hup_source = NULL;
 402    }
 403}
 404
 405static void char_socket_yank_iochannel(void *opaque)
 406{
 407    QIOChannel *ioc = QIO_CHANNEL(opaque);
 408
 409    qio_channel_shutdown(ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
 410}
 411
 412static void tcp_chr_free_connection(Chardev *chr)
 413{
 414    SocketChardev *s = SOCKET_CHARDEV(chr);
 415    int i;
 416
 417    if (s->read_msgfds_num) {
 418        for (i = 0; i < s->read_msgfds_num; i++) {
 419            close(s->read_msgfds[i]);
 420        }
 421        g_free(s->read_msgfds);
 422        s->read_msgfds = NULL;
 423        s->read_msgfds_num = 0;
 424    }
 425
 426    remove_hup_source(s);
 427
 428    tcp_set_msgfds(chr, NULL, 0);
 429    remove_fd_in_watch(chr);
 430    if (s->registered_yank &&
 431        (s->state == TCP_CHARDEV_STATE_CONNECTING
 432        || s->state == TCP_CHARDEV_STATE_CONNECTED)) {
 433        yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label),
 434                                 char_socket_yank_iochannel,
 435                                 QIO_CHANNEL(s->sioc));
 436    }
 437    object_unref(OBJECT(s->sioc));
 438    s->sioc = NULL;
 439    object_unref(OBJECT(s->ioc));
 440    s->ioc = NULL;
 441    g_free(chr->filename);
 442    chr->filename = NULL;
 443    tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
 444}
 445
 446static const char *qemu_chr_socket_protocol(SocketChardev *s)
 447{
 448    if (s->is_telnet) {
 449        return "telnet";
 450    }
 451    return s->is_websock ? "websocket" : "tcp";
 452}
 453
 454static char *qemu_chr_socket_address(SocketChardev *s, const char *prefix)
 455{
 456    switch (s->addr->type) {
 457    case SOCKET_ADDRESS_TYPE_INET:
 458        return g_strdup_printf("%s%s:%s:%s%s", prefix,
 459                               qemu_chr_socket_protocol(s),
 460                               s->addr->u.inet.host,
 461                               s->addr->u.inet.port,
 462                               s->is_listen ? ",server=on" : "");
 463        break;
 464    case SOCKET_ADDRESS_TYPE_UNIX:
 465    {
 466        const char *tight = "", *abstract = "";
 467        UnixSocketAddress *sa = &s->addr->u.q_unix;
 468
 469#ifdef CONFIG_LINUX
 470        if (sa->has_abstract && sa->abstract) {
 471            abstract = ",abstract=on";
 472            if (sa->has_tight && sa->tight) {
 473                tight = ",tight=on";
 474            }
 475        }
 476#endif
 477
 478        return g_strdup_printf("%sunix:%s%s%s%s", prefix, sa->path,
 479                               abstract, tight,
 480                               s->is_listen ? ",server=on" : "");
 481        break;
 482    }
 483    case SOCKET_ADDRESS_TYPE_FD:
 484        return g_strdup_printf("%sfd:%s%s", prefix, s->addr->u.fd.str,
 485                               s->is_listen ? ",server=on" : "");
 486        break;
 487    case SOCKET_ADDRESS_TYPE_VSOCK:
 488        return g_strdup_printf("%svsock:%s:%s", prefix,
 489                               s->addr->u.vsock.cid,
 490                               s->addr->u.vsock.port);
 491    default:
 492        abort();
 493    }
 494}
 495
 496static void update_disconnected_filename(SocketChardev *s)
 497{
 498    Chardev *chr = CHARDEV(s);
 499
 500    g_free(chr->filename);
 501    if (s->addr) {
 502        chr->filename = qemu_chr_socket_address(s, "disconnected:");
 503    } else {
 504        chr->filename = g_strdup("disconnected:socket");
 505    }
 506}
 507
 508/* NB may be called even if tcp_chr_connect has not been
 509 * reached, due to TLS or telnet initialization failure,
 510 * so can *not* assume s->state == TCP_CHARDEV_STATE_CONNECTED
 511 * This must be called with chr->chr_write_lock held.
 512 */
 513static void tcp_chr_disconnect_locked(Chardev *chr)
 514{
 515    SocketChardev *s = SOCKET_CHARDEV(chr);
 516    bool emit_close = s->state == TCP_CHARDEV_STATE_CONNECTED;
 517
 518    tcp_chr_free_connection(chr);
 519
 520    if (s->listener) {
 521        qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
 522                                              chr, NULL, chr->gcontext);
 523    }
 524    update_disconnected_filename(s);
 525    if (emit_close) {
 526        qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
 527    }
 528    if (s->reconnect_time && !s->reconnect_timer) {
 529        qemu_chr_socket_restart_timer(chr);
 530    }
 531}
 532
 533static void tcp_chr_disconnect(Chardev *chr)
 534{
 535    qemu_mutex_lock(&chr->chr_write_lock);
 536    tcp_chr_disconnect_locked(chr);
 537    qemu_mutex_unlock(&chr->chr_write_lock);
 538}
 539
 540static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
 541{
 542    Chardev *chr = CHARDEV(opaque);
 543    SocketChardev *s = SOCKET_CHARDEV(opaque);
 544    uint8_t buf[CHR_READ_BUF_LEN];
 545    int len, size;
 546
 547    if ((s->state != TCP_CHARDEV_STATE_CONNECTED) ||
 548        s->max_size <= 0) {
 549        return TRUE;
 550    }
 551    len = sizeof(buf);
 552    if (len > s->max_size) {
 553        len = s->max_size;
 554    }
 555    size = tcp_chr_recv(chr, (void *)buf, len);
 556    if (size == 0 || (size == -1 && errno != EAGAIN)) {
 557        /* connection closed */
 558        tcp_chr_disconnect(chr);
 559    } else if (size > 0) {
 560        if (s->do_telnetopt) {
 561            tcp_chr_process_IAC_bytes(chr, s, buf, &size);
 562        }
 563        if (size > 0) {
 564            qemu_chr_be_write(chr, buf, size);
 565        }
 566    }
 567
 568    return TRUE;
 569}
 570
 571static gboolean tcp_chr_hup(QIOChannel *channel,
 572                               GIOCondition cond,
 573                               void *opaque)
 574{
 575    Chardev *chr = CHARDEV(opaque);
 576    tcp_chr_disconnect(chr);
 577    return G_SOURCE_REMOVE;
 578}
 579
 580static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len)
 581{
 582    SocketChardev *s = SOCKET_CHARDEV(chr);
 583    int size;
 584
 585    if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
 586        return 0;
 587    }
 588
 589    qio_channel_set_blocking(s->ioc, true, NULL);
 590    size = tcp_chr_recv(chr, (void *) buf, len);
 591    if (s->state != TCP_CHARDEV_STATE_DISCONNECTED) {
 592        qio_channel_set_blocking(s->ioc, false, NULL);
 593    }
 594    if (size == 0) {
 595        /* connection closed */
 596        tcp_chr_disconnect(chr);
 597    }
 598
 599    return size;
 600}
 601
 602static char *qemu_chr_compute_filename(SocketChardev *s)
 603{
 604    struct sockaddr_storage *ss = &s->sioc->localAddr;
 605    struct sockaddr_storage *ps = &s->sioc->remoteAddr;
 606    socklen_t ss_len = s->sioc->localAddrLen;
 607    socklen_t ps_len = s->sioc->remoteAddrLen;
 608    char shost[NI_MAXHOST], sserv[NI_MAXSERV];
 609    char phost[NI_MAXHOST], pserv[NI_MAXSERV];
 610    const char *left = "", *right = "";
 611
 612    switch (ss->ss_family) {
 613#ifndef _WIN32
 614    case AF_UNIX:
 615        return g_strdup_printf("unix:%s%s",
 616                               ((struct sockaddr_un *)(ss))->sun_path,
 617                               s->is_listen ? ",server=on" : "");
 618#endif
 619    case AF_INET6:
 620        left  = "[";
 621        right = "]";
 622        /* fall through */
 623    case AF_INET:
 624        getnameinfo((struct sockaddr *) ss, ss_len, shost, sizeof(shost),
 625                    sserv, sizeof(sserv), NI_NUMERICHOST | NI_NUMERICSERV);
 626        getnameinfo((struct sockaddr *) ps, ps_len, phost, sizeof(phost),
 627                    pserv, sizeof(pserv), NI_NUMERICHOST | NI_NUMERICSERV);
 628        return g_strdup_printf("%s:%s%s%s:%s%s <-> %s%s%s:%s",
 629                               qemu_chr_socket_protocol(s),
 630                               left, shost, right, sserv,
 631                               s->is_listen ? ",server=on" : "",
 632                               left, phost, right, pserv);
 633
 634    default:
 635        return g_strdup_printf("unknown");
 636    }
 637}
 638
 639static void update_ioc_handlers(SocketChardev *s)
 640{
 641    Chardev *chr = CHARDEV(s);
 642
 643    if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
 644        return;
 645    }
 646
 647    remove_fd_in_watch(chr);
 648    chr->gsource = io_add_watch_poll(chr, s->ioc,
 649                                     tcp_chr_read_poll,
 650                                     tcp_chr_read, chr,
 651                                     chr->gcontext);
 652
 653    remove_hup_source(s);
 654    s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP);
 655    g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup,
 656                          chr, NULL);
 657    g_source_attach(s->hup_source, chr->gcontext);
 658}
 659
 660static void tcp_chr_connect(void *opaque)
 661{
 662    Chardev *chr = CHARDEV(opaque);
 663    SocketChardev *s = SOCKET_CHARDEV(opaque);
 664
 665    g_free(chr->filename);
 666    chr->filename = qemu_chr_compute_filename(s);
 667
 668    tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTED);
 669    update_ioc_handlers(s);
 670    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 671}
 672
 673static void tcp_chr_telnet_destroy(SocketChardev *s)
 674{
 675    if (s->telnet_source) {
 676        g_source_destroy(s->telnet_source);
 677        g_source_unref(s->telnet_source);
 678        s->telnet_source = NULL;
 679    }
 680}
 681
 682static void tcp_chr_update_read_handler(Chardev *chr)
 683{
 684    SocketChardev *s = SOCKET_CHARDEV(chr);
 685
 686    if (s->listener && s->state == TCP_CHARDEV_STATE_DISCONNECTED) {
 687        /*
 688         * It's possible that chardev context is changed in
 689         * qemu_chr_be_update_read_handlers().  Reset it for QIO net
 690         * listener if there is.
 691         */
 692        qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
 693                                              chr, NULL, chr->gcontext);
 694    }
 695
 696    if (s->telnet_source) {
 697        tcp_chr_telnet_init(CHARDEV(s));
 698    }
 699
 700    update_ioc_handlers(s);
 701}
 702
 703static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc,
 704                                       GIOCondition cond G_GNUC_UNUSED,
 705                                       gpointer user_data)
 706{
 707    SocketChardev *s = user_data;
 708    Chardev *chr = CHARDEV(s);
 709    TCPChardevTelnetInit *init = s->telnet_init;
 710    ssize_t ret;
 711
 712    assert(init);
 713
 714    ret = qio_channel_write(ioc, init->buf, init->buflen, NULL);
 715    if (ret < 0) {
 716        if (ret == QIO_CHANNEL_ERR_BLOCK) {
 717            ret = 0;
 718        } else {
 719            tcp_chr_disconnect(chr);
 720            goto end;
 721        }
 722    }
 723    init->buflen -= ret;
 724
 725    if (init->buflen == 0) {
 726        tcp_chr_connect(chr);
 727        goto end;
 728    }
 729
 730    memmove(init->buf, init->buf + ret, init->buflen);
 731
 732    return G_SOURCE_CONTINUE;
 733
 734end:
 735    g_free(s->telnet_init);
 736    s->telnet_init = NULL;
 737    g_source_unref(s->telnet_source);
 738    s->telnet_source = NULL;
 739    return G_SOURCE_REMOVE;
 740}
 741
 742static void tcp_chr_telnet_init(Chardev *chr)
 743{
 744    SocketChardev *s = SOCKET_CHARDEV(chr);
 745    TCPChardevTelnetInit *init;
 746    size_t n = 0;
 747
 748    /* Destroy existing task */
 749    tcp_chr_telnet_destroy(s);
 750
 751    if (s->telnet_init) {
 752        /* We are possibly during a handshake already */
 753        goto cont;
 754    }
 755
 756    s->telnet_init = g_new0(TCPChardevTelnetInit, 1);
 757    init = s->telnet_init;
 758
 759#define IACSET(x, a, b, c)                      \
 760    do {                                        \
 761        x[n++] = a;                             \
 762        x[n++] = b;                             \
 763        x[n++] = c;                             \
 764    } while (0)
 765
 766    if (!s->is_tn3270) {
 767        init->buflen = 12;
 768        /* Prep the telnet negotion to put telnet in binary,
 769         * no echo, single char mode */
 770        IACSET(init->buf, 0xff, 0xfb, 0x01);  /* IAC WILL ECHO */
 771        IACSET(init->buf, 0xff, 0xfb, 0x03);  /* IAC WILL Suppress go ahead */
 772        IACSET(init->buf, 0xff, 0xfb, 0x00);  /* IAC WILL Binary */
 773        IACSET(init->buf, 0xff, 0xfd, 0x00);  /* IAC DO Binary */
 774    } else {
 775        init->buflen = 21;
 776        /* Prep the TN3270 negotion based on RFC1576 */
 777        IACSET(init->buf, 0xff, 0xfd, 0x19);  /* IAC DO EOR */
 778        IACSET(init->buf, 0xff, 0xfb, 0x19);  /* IAC WILL EOR */
 779        IACSET(init->buf, 0xff, 0xfd, 0x00);  /* IAC DO BINARY */
 780        IACSET(init->buf, 0xff, 0xfb, 0x00);  /* IAC WILL BINARY */
 781        IACSET(init->buf, 0xff, 0xfd, 0x18);  /* IAC DO TERMINAL TYPE */
 782        IACSET(init->buf, 0xff, 0xfa, 0x18);  /* IAC SB TERMINAL TYPE */
 783        IACSET(init->buf, 0x01, 0xff, 0xf0);  /* SEND IAC SE */
 784    }
 785
 786#undef IACSET
 787
 788cont:
 789    s->telnet_source = qio_channel_add_watch_source(s->ioc, G_IO_OUT,
 790                                                    tcp_chr_telnet_init_io,
 791                                                    s, NULL,
 792                                                    chr->gcontext);
 793}
 794
 795
 796static void tcp_chr_websock_handshake(QIOTask *task, gpointer user_data)
 797{
 798    Chardev *chr = user_data;
 799    SocketChardev *s = user_data;
 800
 801    if (qio_task_propagate_error(task, NULL)) {
 802        tcp_chr_disconnect(chr);
 803    } else {
 804        if (s->do_telnetopt) {
 805            tcp_chr_telnet_init(chr);
 806        } else {
 807            tcp_chr_connect(chr);
 808        }
 809    }
 810}
 811
 812
 813static void tcp_chr_websock_init(Chardev *chr)
 814{
 815    SocketChardev *s = SOCKET_CHARDEV(chr);
 816    QIOChannelWebsock *wioc = NULL;
 817    gchar *name;
 818
 819    wioc = qio_channel_websock_new_server(s->ioc);
 820
 821    name = g_strdup_printf("chardev-websocket-server-%s", chr->label);
 822    qio_channel_set_name(QIO_CHANNEL(wioc), name);
 823    g_free(name);
 824    object_unref(OBJECT(s->ioc));
 825    s->ioc = QIO_CHANNEL(wioc);
 826
 827    qio_channel_websock_handshake(wioc, tcp_chr_websock_handshake, chr, NULL);
 828}
 829
 830
 831static void tcp_chr_tls_handshake(QIOTask *task,
 832                                  gpointer user_data)
 833{
 834    Chardev *chr = user_data;
 835    SocketChardev *s = user_data;
 836
 837    if (qio_task_propagate_error(task, NULL)) {
 838        tcp_chr_disconnect(chr);
 839    } else {
 840        if (s->is_websock) {
 841            tcp_chr_websock_init(chr);
 842        } else if (s->do_telnetopt) {
 843            tcp_chr_telnet_init(chr);
 844        } else {
 845            tcp_chr_connect(chr);
 846        }
 847    }
 848}
 849
 850
 851static void tcp_chr_tls_init(Chardev *chr)
 852{
 853    SocketChardev *s = SOCKET_CHARDEV(chr);
 854    QIOChannelTLS *tioc;
 855    gchar *name;
 856
 857    if (s->is_listen) {
 858        tioc = qio_channel_tls_new_server(
 859            s->ioc, s->tls_creds,
 860            s->tls_authz,
 861            NULL);
 862    } else {
 863        tioc = qio_channel_tls_new_client(
 864            s->ioc, s->tls_creds,
 865            s->addr->u.inet.host,
 866            NULL);
 867    }
 868    if (tioc == NULL) {
 869        tcp_chr_disconnect(chr);
 870        return;
 871    }
 872    name = g_strdup_printf("chardev-tls-%s-%s",
 873                           s->is_listen ? "server" : "client",
 874                           chr->label);
 875    qio_channel_set_name(QIO_CHANNEL(tioc), name);
 876    g_free(name);
 877    object_unref(OBJECT(s->ioc));
 878    s->ioc = QIO_CHANNEL(tioc);
 879
 880    qio_channel_tls_handshake(tioc,
 881                              tcp_chr_tls_handshake,
 882                              chr,
 883                              NULL,
 884                              chr->gcontext);
 885}
 886
 887
 888static void tcp_chr_set_client_ioc_name(Chardev *chr,
 889                                        QIOChannelSocket *sioc)
 890{
 891    SocketChardev *s = SOCKET_CHARDEV(chr);
 892    char *name;
 893    name = g_strdup_printf("chardev-tcp-%s-%s",
 894                           s->is_listen ? "server" : "client",
 895                           chr->label);
 896    qio_channel_set_name(QIO_CHANNEL(sioc), name);
 897    g_free(name);
 898
 899}
 900
 901static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc)
 902{
 903    SocketChardev *s = SOCKET_CHARDEV(chr);
 904
 905    if (s->state != TCP_CHARDEV_STATE_CONNECTING) {
 906        return -1;
 907    }
 908
 909    s->ioc = QIO_CHANNEL(sioc);
 910    object_ref(OBJECT(sioc));
 911    s->sioc = sioc;
 912    object_ref(OBJECT(sioc));
 913
 914    qio_channel_set_blocking(s->ioc, false, NULL);
 915
 916    if (s->do_nodelay) {
 917        qio_channel_set_delay(s->ioc, false);
 918    }
 919    if (s->listener) {
 920        qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
 921                                              NULL, chr->gcontext);
 922    }
 923
 924    if (s->tls_creds) {
 925        tcp_chr_tls_init(chr);
 926    } else if (s->is_websock) {
 927        tcp_chr_websock_init(chr);
 928    } else if (s->do_telnetopt) {
 929        tcp_chr_telnet_init(chr);
 930    } else {
 931        tcp_chr_connect(chr);
 932    }
 933
 934    return 0;
 935}
 936
 937
 938static int tcp_chr_add_client(Chardev *chr, int fd)
 939{
 940    int ret;
 941    QIOChannelSocket *sioc;
 942    SocketChardev *s = SOCKET_CHARDEV(chr);
 943
 944    if (s->state != TCP_CHARDEV_STATE_DISCONNECTED) {
 945        return -1;
 946    }
 947
 948    sioc = qio_channel_socket_new_fd(fd, NULL);
 949    if (!sioc) {
 950        return -1;
 951    }
 952    tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
 953    tcp_chr_set_client_ioc_name(chr, sioc);
 954    if (s->registered_yank) {
 955        yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
 956                               char_socket_yank_iochannel,
 957                               QIO_CHANNEL(sioc));
 958    }
 959    ret = tcp_chr_new_client(chr, sioc);
 960    object_unref(OBJECT(sioc));
 961    return ret;
 962}
 963
 964static void tcp_chr_accept(QIONetListener *listener,
 965                           QIOChannelSocket *cioc,
 966                           void *opaque)
 967{
 968    Chardev *chr = CHARDEV(opaque);
 969    SocketChardev *s = SOCKET_CHARDEV(chr);
 970
 971    tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
 972    tcp_chr_set_client_ioc_name(chr, cioc);
 973    if (s->registered_yank) {
 974        yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
 975                               char_socket_yank_iochannel,
 976                               QIO_CHANNEL(cioc));
 977    }
 978    tcp_chr_new_client(chr, cioc);
 979}
 980
 981
 982static int tcp_chr_connect_client_sync(Chardev *chr, Error **errp)
 983{
 984    SocketChardev *s = SOCKET_CHARDEV(chr);
 985    QIOChannelSocket *sioc = qio_channel_socket_new();
 986    tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
 987    tcp_chr_set_client_ioc_name(chr, sioc);
 988    if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) {
 989        tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
 990        object_unref(OBJECT(sioc));
 991        return -1;
 992    }
 993    if (s->registered_yank) {
 994        yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
 995                               char_socket_yank_iochannel,
 996                               QIO_CHANNEL(sioc));
 997    }
 998    tcp_chr_new_client(chr, sioc);
 999    object_unref(OBJECT(sioc));
1000    return 0;
1001}
1002
1003
1004static void tcp_chr_accept_server_sync(Chardev *chr)
1005{
1006    SocketChardev *s = SOCKET_CHARDEV(chr);
1007    QIOChannelSocket *sioc;
1008    info_report("QEMU waiting for connection on: %s",
1009                chr->filename);
1010    tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
1011    sioc = qio_net_listener_wait_client(s->listener);
1012    tcp_chr_set_client_ioc_name(chr, sioc);
1013    if (s->registered_yank) {
1014        yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
1015                               char_socket_yank_iochannel,
1016                               QIO_CHANNEL(sioc));
1017    }
1018    tcp_chr_new_client(chr, sioc);
1019    object_unref(OBJECT(sioc));
1020}
1021
1022
1023static int tcp_chr_wait_connected(Chardev *chr, Error **errp)
1024{
1025    SocketChardev *s = SOCKET_CHARDEV(chr);
1026    const char *opts[] = { "telnet", "tn3270", "websock", "tls-creds" };
1027    bool optset[] = { s->is_telnet, s->is_tn3270, s->is_websock, s->tls_creds };
1028    size_t i;
1029
1030    QEMU_BUILD_BUG_ON(G_N_ELEMENTS(opts) != G_N_ELEMENTS(optset));
1031    for (i = 0; i < G_N_ELEMENTS(opts); i++) {
1032        if (optset[i]) {
1033            error_setg(errp,
1034                       "'%s' option is incompatible with waiting for "
1035                       "connection completion", opts[i]);
1036            return -1;
1037        }
1038    }
1039
1040    tcp_chr_reconn_timer_cancel(s);
1041
1042    /*
1043     * We expect states to be as follows:
1044     *
1045     *  - server
1046     *    - wait   -> CONNECTED
1047     *    - nowait -> DISCONNECTED
1048     *  - client
1049     *    - reconnect == 0 -> CONNECTED
1050     *    - reconnect != 0 -> CONNECTING
1051     *
1052     */
1053    if (s->state == TCP_CHARDEV_STATE_CONNECTING) {
1054        if (!s->connect_task) {
1055            error_setg(errp,
1056                       "Unexpected 'connecting' state without connect task "
1057                       "while waiting for connection completion");
1058            return -1;
1059        }
1060        /*
1061         * tcp_chr_wait_connected should only ever be run from the
1062         * main loop thread associated with chr->gcontext, otherwise
1063         * qio_task_wait_thread has a dangerous race condition with
1064         * free'ing of the s->connect_task object.
1065         *
1066         * Acquiring the main context doesn't 100% prove we're in
1067         * the main loop thread, but it does at least guarantee
1068         * that the main loop won't be executed by another thread
1069         * avoiding the race condition with the task idle callback.
1070         */
1071        g_main_context_acquire(chr->gcontext);
1072        qio_task_wait_thread(s->connect_task);
1073        g_main_context_release(chr->gcontext);
1074
1075        /*
1076         * The completion callback (qemu_chr_socket_connected) for
1077         * s->connect_task should have set this to NULL by the time
1078         * qio_task_wait_thread has returned.
1079         */
1080        assert(!s->connect_task);
1081
1082        /*
1083         * NB we are *not* guaranteed to have "s->state == ..CONNECTED"
1084         * at this point as this first connect may be failed, so
1085         * allow the next loop to run regardless.
1086         */
1087    }
1088
1089    while (s->state != TCP_CHARDEV_STATE_CONNECTED) {
1090        if (s->is_listen) {
1091            tcp_chr_accept_server_sync(chr);
1092        } else {
1093            Error *err = NULL;
1094            if (tcp_chr_connect_client_sync(chr, &err) < 0) {
1095                if (s->reconnect_time) {
1096                    error_free(err);
1097                    g_usleep(s->reconnect_time * 1000ULL * 1000ULL);
1098                } else {
1099                    error_propagate(errp, err);
1100                    return -1;
1101                }
1102            }
1103        }
1104    }
1105
1106    return 0;
1107}
1108
1109static void char_socket_finalize(Object *obj)
1110{
1111    Chardev *chr = CHARDEV(obj);
1112    SocketChardev *s = SOCKET_CHARDEV(obj);
1113
1114    tcp_chr_free_connection(chr);
1115    tcp_chr_reconn_timer_cancel(s);
1116    qapi_free_SocketAddress(s->addr);
1117    tcp_chr_telnet_destroy(s);
1118    g_free(s->telnet_init);
1119    if (s->listener) {
1120        qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
1121                                              NULL, chr->gcontext);
1122        object_unref(OBJECT(s->listener));
1123    }
1124    if (s->tls_creds) {
1125        object_unref(OBJECT(s->tls_creds));
1126    }
1127    g_free(s->tls_authz);
1128    if (s->registered_yank) {
1129        /*
1130         * In the chardev-change special-case, we shouldn't unregister the yank
1131         * instance, as it still may be needed.
1132         */
1133        if (!chr->handover_yank_instance) {
1134            yank_unregister_instance(CHARDEV_YANK_INSTANCE(chr->label));
1135        }
1136    }
1137
1138    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1139}
1140
1141static void qemu_chr_socket_connected(QIOTask *task, void *opaque)
1142{
1143    QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
1144    Chardev *chr = CHARDEV(opaque);
1145    SocketChardev *s = SOCKET_CHARDEV(chr);
1146    Error *err = NULL;
1147
1148    s->connect_task = NULL;
1149
1150    if (qio_task_propagate_error(task, &err)) {
1151        tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
1152        if (s->registered_yank) {
1153            yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label),
1154                                     char_socket_yank_iochannel,
1155                                     QIO_CHANNEL(sioc));
1156        }
1157        check_report_connect_error(chr, err);
1158        goto cleanup;
1159    }
1160
1161    s->connect_err_reported = false;
1162    tcp_chr_new_client(chr, sioc);
1163
1164cleanup:
1165    object_unref(OBJECT(sioc));
1166}
1167
1168
1169static void tcp_chr_connect_client_task(QIOTask *task,
1170                                        gpointer opaque)
1171{
1172    QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
1173    SocketAddress *addr = opaque;
1174    Error *err = NULL;
1175
1176    qio_channel_socket_connect_sync(ioc, addr, &err);
1177
1178    qio_task_set_error(task, err);
1179}
1180
1181
1182static void tcp_chr_connect_client_async(Chardev *chr)
1183{
1184    SocketChardev *s = SOCKET_CHARDEV(chr);
1185    QIOChannelSocket *sioc;
1186
1187    tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
1188    sioc = qio_channel_socket_new();
1189    tcp_chr_set_client_ioc_name(chr, sioc);
1190    if (s->registered_yank) {
1191        yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
1192                               char_socket_yank_iochannel,
1193                               QIO_CHANNEL(sioc));
1194    }
1195    /*
1196     * Normally code would use the qio_channel_socket_connect_async
1197     * method which uses a QIOTask + qio_task_set_error internally
1198     * to avoid blocking. The tcp_chr_wait_connected method, however,
1199     * needs a way to synchronize with completion of the background
1200     * connect task which can't be done with the QIOChannelSocket
1201     * async APIs. Thus we must use QIOTask directly to implement
1202     * the non-blocking concept locally.
1203     */
1204    s->connect_task = qio_task_new(OBJECT(sioc),
1205                                   qemu_chr_socket_connected,
1206                                   object_ref(OBJECT(chr)),
1207                                   (GDestroyNotify)object_unref);
1208    qio_task_run_in_thread(s->connect_task,
1209                           tcp_chr_connect_client_task,
1210                           s->addr,
1211                           NULL,
1212                           chr->gcontext);
1213}
1214
1215static gboolean socket_reconnect_timeout(gpointer opaque)
1216{
1217    Chardev *chr = CHARDEV(opaque);
1218    SocketChardev *s = SOCKET_CHARDEV(opaque);
1219
1220    qemu_mutex_lock(&chr->chr_write_lock);
1221    g_source_unref(s->reconnect_timer);
1222    s->reconnect_timer = NULL;
1223    qemu_mutex_unlock(&chr->chr_write_lock);
1224
1225    if (chr->be_open) {
1226        return false;
1227    }
1228
1229    tcp_chr_connect_client_async(chr);
1230
1231    return false;
1232}
1233
1234
1235static int qmp_chardev_open_socket_server(Chardev *chr,
1236                                          bool is_telnet,
1237                                          bool is_waitconnect,
1238                                          Error **errp)
1239{
1240    SocketChardev *s = SOCKET_CHARDEV(chr);
1241    char *name;
1242    if (is_telnet) {
1243        s->do_telnetopt = 1;
1244    }
1245    s->listener = qio_net_listener_new();
1246
1247    name = g_strdup_printf("chardev-tcp-listener-%s", chr->label);
1248    qio_net_listener_set_name(s->listener, name);
1249    g_free(name);
1250
1251    if (qio_net_listener_open_sync(s->listener, s->addr, 1, errp) < 0) {
1252        object_unref(OBJECT(s->listener));
1253        s->listener = NULL;
1254        return -1;
1255    }
1256
1257    qapi_free_SocketAddress(s->addr);
1258    s->addr = socket_local_address(s->listener->sioc[0]->fd, errp);
1259    update_disconnected_filename(s);
1260
1261    if (is_waitconnect) {
1262        tcp_chr_accept_server_sync(chr);
1263    } else {
1264        qio_net_listener_set_client_func_full(s->listener,
1265                                              tcp_chr_accept,
1266                                              chr, NULL,
1267                                              chr->gcontext);
1268    }
1269
1270    return 0;
1271}
1272
1273
1274static int qmp_chardev_open_socket_client(Chardev *chr,
1275                                          int64_t reconnect,
1276                                          Error **errp)
1277{
1278    SocketChardev *s = SOCKET_CHARDEV(chr);
1279
1280    if (reconnect > 0) {
1281        s->reconnect_time = reconnect;
1282        tcp_chr_connect_client_async(chr);
1283        return 0;
1284    } else {
1285        return tcp_chr_connect_client_sync(chr, errp);
1286    }
1287}
1288
1289
1290static bool qmp_chardev_validate_socket(ChardevSocket *sock,
1291                                        SocketAddress *addr,
1292                                        Error **errp)
1293{
1294    /* Validate any options which have a dependency on address type */
1295    switch (addr->type) {
1296    case SOCKET_ADDRESS_TYPE_FD:
1297        if (sock->has_reconnect) {
1298            error_setg(errp,
1299                       "'reconnect' option is incompatible with "
1300                       "'fd' address type");
1301            return false;
1302        }
1303        if (sock->has_tls_creds &&
1304            !(sock->has_server && sock->server)) {
1305            error_setg(errp,
1306                       "'tls_creds' option is incompatible with "
1307                       "'fd' address type as client");
1308            return false;
1309        }
1310        break;
1311
1312    case SOCKET_ADDRESS_TYPE_UNIX:
1313        if (sock->has_tls_creds) {
1314            error_setg(errp,
1315                       "'tls_creds' option is incompatible with "
1316                       "'unix' address type");
1317            return false;
1318        }
1319        break;
1320
1321    case SOCKET_ADDRESS_TYPE_INET:
1322        break;
1323
1324    case SOCKET_ADDRESS_TYPE_VSOCK:
1325        if (sock->has_tls_creds) {
1326            error_setg(errp,
1327                       "'tls_creds' option is incompatible with "
1328                       "'vsock' address type");
1329            return false;
1330        }
1331
1332    default:
1333        break;
1334    }
1335
1336    if (sock->has_tls_authz && !sock->has_tls_creds) {
1337        error_setg(errp, "'tls_authz' option requires 'tls_creds' option");
1338        return false;
1339    }
1340
1341    /* Validate any options which have a dependancy on client vs server */
1342    if (!sock->has_server || sock->server) {
1343        if (sock->has_reconnect) {
1344            error_setg(errp,
1345                       "'reconnect' option is incompatible with "
1346                       "socket in server listen mode");
1347            return false;
1348        }
1349    } else {
1350        if (sock->has_websocket && sock->websocket) {
1351            error_setg(errp, "%s", "Websocket client is not implemented");
1352            return false;
1353        }
1354        if (sock->has_wait) {
1355            error_setg(errp, "%s",
1356                       "'wait' option is incompatible with "
1357                       "socket in client connect mode");
1358            return false;
1359        }
1360    }
1361
1362    return true;
1363}
1364
1365
1366static void qmp_chardev_open_socket(Chardev *chr,
1367                                    ChardevBackend *backend,
1368                                    bool *be_opened,
1369                                    Error **errp)
1370{
1371    SocketChardev *s = SOCKET_CHARDEV(chr);
1372    ChardevSocket *sock = backend->u.socket.data;
1373    bool do_nodelay     = sock->has_nodelay ? sock->nodelay : false;
1374    bool is_listen      = sock->has_server  ? sock->server  : true;
1375    bool is_telnet      = sock->has_telnet  ? sock->telnet  : false;
1376    bool is_tn3270      = sock->has_tn3270  ? sock->tn3270  : false;
1377    bool is_waitconnect = sock->has_wait    ? sock->wait    : false;
1378    bool is_websock     = sock->has_websocket ? sock->websocket : false;
1379    int64_t reconnect   = sock->has_reconnect ? sock->reconnect : 0;
1380    SocketAddress *addr;
1381
1382    s->is_listen = is_listen;
1383    s->is_telnet = is_telnet;
1384    s->is_tn3270 = is_tn3270;
1385    s->is_websock = is_websock;
1386    s->do_nodelay = do_nodelay;
1387    if (sock->tls_creds) {
1388        Object *creds;
1389        creds = object_resolve_path_component(
1390            object_get_objects_root(), sock->tls_creds);
1391        if (!creds) {
1392            error_setg(errp, "No TLS credentials with id '%s'",
1393                       sock->tls_creds);
1394            return;
1395        }
1396        s->tls_creds = (QCryptoTLSCreds *)
1397            object_dynamic_cast(creds,
1398                                TYPE_QCRYPTO_TLS_CREDS);
1399        if (!s->tls_creds) {
1400            error_setg(errp, "Object with id '%s' is not TLS credentials",
1401                       sock->tls_creds);
1402            return;
1403        }
1404        object_ref(OBJECT(s->tls_creds));
1405        if (!qcrypto_tls_creds_check_endpoint(s->tls_creds,
1406                                          is_listen
1407                                          ? QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
1408                                          : QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT,
1409                                          errp)) {
1410            return;
1411        }
1412    }
1413    s->tls_authz = g_strdup(sock->tls_authz);
1414
1415    s->addr = addr = socket_address_flatten(sock->addr);
1416
1417    if (!qmp_chardev_validate_socket(sock, addr, errp)) {
1418        return;
1419    }
1420
1421    qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE);
1422    /* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */
1423    if (addr->type == SOCKET_ADDRESS_TYPE_UNIX) {
1424        qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS);
1425    }
1426
1427    /*
1428     * In the chardev-change special-case, we shouldn't register a new yank
1429     * instance, as there already may be one.
1430     */
1431    if (!chr->handover_yank_instance) {
1432        if (!yank_register_instance(CHARDEV_YANK_INSTANCE(chr->label), errp)) {
1433            return;
1434        }
1435    }
1436    s->registered_yank = true;
1437
1438    /* be isn't opened until we get a connection */
1439    *be_opened = false;
1440
1441    update_disconnected_filename(s);
1442
1443    if (s->is_listen) {
1444        if (qmp_chardev_open_socket_server(chr, is_telnet || is_tn3270,
1445                                           is_waitconnect, errp) < 0) {
1446            return;
1447        }
1448    } else {
1449        if (qmp_chardev_open_socket_client(chr, reconnect, errp) < 0) {
1450            return;
1451        }
1452    }
1453}
1454
1455static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
1456                                  Error **errp)
1457{
1458    const char *path = qemu_opt_get(opts, "path");
1459    const char *host = qemu_opt_get(opts, "host");
1460    const char *port = qemu_opt_get(opts, "port");
1461    const char *fd = qemu_opt_get(opts, "fd");
1462#ifdef CONFIG_LINUX
1463    bool tight = qemu_opt_get_bool(opts, "tight", true);
1464    bool abstract = qemu_opt_get_bool(opts, "abstract", false);
1465#endif
1466    SocketAddressLegacy *addr;
1467    ChardevSocket *sock;
1468
1469    if ((!!path + !!fd + !!host) != 1) {
1470        error_setg(errp,
1471                   "Exactly one of 'path', 'fd' or 'host' required");
1472        return;
1473    }
1474
1475    if (host && !port) {
1476        error_setg(errp, "chardev: socket: no port given");
1477        return;
1478    }
1479
1480    backend->type = CHARDEV_BACKEND_KIND_SOCKET;
1481    sock = backend->u.socket.data = g_new0(ChardevSocket, 1);
1482    qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock));
1483
1484    if (qemu_opt_get(opts, "delay") && qemu_opt_get(opts, "nodelay")) {
1485        error_setg(errp, "'delay' and 'nodelay' are mutually exclusive");
1486        return;
1487    }
1488    sock->has_nodelay =
1489        qemu_opt_get(opts, "delay") ||
1490        qemu_opt_get(opts, "nodelay");
1491    sock->nodelay =
1492        !qemu_opt_get_bool(opts, "delay", true) ||
1493        qemu_opt_get_bool(opts, "nodelay", false);
1494
1495    /*
1496     * We have different default to QMP for 'server', hence
1497     * we can't just check for existence of 'server'
1498     */
1499    sock->has_server = true;
1500    sock->server = qemu_opt_get_bool(opts, "server", false);
1501    sock->has_telnet = qemu_opt_get(opts, "telnet");
1502    sock->telnet = qemu_opt_get_bool(opts, "telnet", false);
1503    sock->has_tn3270 = qemu_opt_get(opts, "tn3270");
1504    sock->tn3270 = qemu_opt_get_bool(opts, "tn3270", false);
1505    sock->has_websocket = qemu_opt_get(opts, "websocket");
1506    sock->websocket = qemu_opt_get_bool(opts, "websocket", false);
1507    /*
1508     * We have different default to QMP for 'wait' when 'server'
1509     * is set, hence we can't just check for existence of 'wait'
1510     */
1511    sock->has_wait = qemu_opt_find(opts, "wait") || sock->server;
1512    sock->wait = qemu_opt_get_bool(opts, "wait", true);
1513    sock->has_reconnect = qemu_opt_find(opts, "reconnect");
1514    sock->reconnect = qemu_opt_get_number(opts, "reconnect", 0);
1515    sock->has_tls_creds = qemu_opt_get(opts, "tls-creds");
1516    sock->tls_creds = g_strdup(qemu_opt_get(opts, "tls-creds"));
1517    sock->has_tls_authz = qemu_opt_get(opts, "tls-authz");
1518    sock->tls_authz = g_strdup(qemu_opt_get(opts, "tls-authz"));
1519
1520    addr = g_new0(SocketAddressLegacy, 1);
1521    if (path) {
1522        UnixSocketAddress *q_unix;
1523        addr->type = SOCKET_ADDRESS_TYPE_UNIX;
1524        q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
1525        q_unix->path = g_strdup(path);
1526#ifdef CONFIG_LINUX
1527        q_unix->has_tight = true;
1528        q_unix->tight = tight;
1529        q_unix->has_abstract = true;
1530        q_unix->abstract = abstract;
1531#endif
1532    } else if (host) {
1533        addr->type = SOCKET_ADDRESS_TYPE_INET;
1534        addr->u.inet.data = g_new(InetSocketAddress, 1);
1535        *addr->u.inet.data = (InetSocketAddress) {
1536            .host = g_strdup(host),
1537            .port = g_strdup(port),
1538            .has_to = qemu_opt_get(opts, "to"),
1539            .to = qemu_opt_get_number(opts, "to", 0),
1540            .has_ipv4 = qemu_opt_get(opts, "ipv4"),
1541            .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0),
1542            .has_ipv6 = qemu_opt_get(opts, "ipv6"),
1543            .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
1544        };
1545    } else if (fd) {
1546        addr->type = SOCKET_ADDRESS_TYPE_FD;
1547        addr->u.fd.data = g_new(String, 1);
1548        addr->u.fd.data->str = g_strdup(fd);
1549    } else {
1550        g_assert_not_reached();
1551    }
1552    sock->addr = addr;
1553}
1554
1555static void
1556char_socket_get_addr(Object *obj, Visitor *v, const char *name,
1557                     void *opaque, Error **errp)
1558{
1559    SocketChardev *s = SOCKET_CHARDEV(obj);
1560
1561    visit_type_SocketAddress(v, name, &s->addr, errp);
1562}
1563
1564static bool
1565char_socket_get_connected(Object *obj, Error **errp)
1566{
1567    SocketChardev *s = SOCKET_CHARDEV(obj);
1568
1569    return s->state == TCP_CHARDEV_STATE_CONNECTED;
1570}
1571
1572static void char_socket_class_init(ObjectClass *oc, void *data)
1573{
1574    ChardevClass *cc = CHARDEV_CLASS(oc);
1575
1576    cc->supports_yank = true;
1577
1578    cc->parse = qemu_chr_parse_socket;
1579    cc->open = qmp_chardev_open_socket;
1580    cc->chr_wait_connected = tcp_chr_wait_connected;
1581    cc->chr_write = tcp_chr_write;
1582    cc->chr_sync_read = tcp_chr_sync_read;
1583    cc->chr_disconnect = tcp_chr_disconnect;
1584    cc->get_msgfds = tcp_get_msgfds;
1585    cc->set_msgfds = tcp_set_msgfds;
1586    cc->chr_add_client = tcp_chr_add_client;
1587    cc->chr_add_watch = tcp_chr_add_watch;
1588    cc->chr_update_read_handler = tcp_chr_update_read_handler;
1589
1590    object_class_property_add(oc, "addr", "SocketAddress",
1591                              char_socket_get_addr, NULL,
1592                              NULL, NULL);
1593
1594    object_class_property_add_bool(oc, "connected", char_socket_get_connected,
1595                                   NULL);
1596}
1597
1598static const TypeInfo char_socket_type_info = {
1599    .name = TYPE_CHARDEV_SOCKET,
1600    .parent = TYPE_CHARDEV,
1601    .instance_size = sizeof(SocketChardev),
1602    .instance_finalize = char_socket_finalize,
1603    .class_init = char_socket_class_init,
1604};
1605
1606static void register_types(void)
1607{
1608    type_register_static(&char_socket_type_info);
1609}
1610
1611type_init(register_types);
1612