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#include "qemu/osdep.h"
  25#include "chardev/char.h"
  26#include "io/channel-socket.h"
  27#include "io/channel-tls.h"
  28#include "qemu/error-report.h"
  29#include "qapi/error.h"
  30#include "qapi/clone-visitor.h"
  31
  32#include "chardev/char-io.h"
  33
  34/***********************************************************/
  35/* TCP Net console */
  36
  37#define TCP_MAX_FDS 16
  38
  39typedef struct {
  40    Chardev parent;
  41    QIOChannel *ioc; /* Client I/O channel */
  42    QIOChannelSocket *sioc; /* Client master channel */
  43    QIOChannelSocket *listen_ioc;
  44    guint listen_tag;
  45    QCryptoTLSCreds *tls_creds;
  46    int connected;
  47    int max_size;
  48    int do_telnetopt;
  49    int do_nodelay;
  50    int *read_msgfds;
  51    size_t read_msgfds_num;
  52    int *write_msgfds;
  53    size_t write_msgfds_num;
  54
  55    SocketAddress *addr;
  56    bool is_listen;
  57    bool is_telnet;
  58    bool is_tn3270;
  59
  60    guint reconnect_timer;
  61    int64_t reconnect_time;
  62    bool connect_err_reported;
  63} SocketChardev;
  64
  65#define SOCKET_CHARDEV(obj)                                     \
  66    OBJECT_CHECK(SocketChardev, (obj), TYPE_CHARDEV_SOCKET)
  67
  68static gboolean socket_reconnect_timeout(gpointer opaque);
  69
  70static void qemu_chr_socket_restart_timer(Chardev *chr)
  71{
  72    SocketChardev *s = SOCKET_CHARDEV(chr);
  73    char *name;
  74
  75    assert(s->connected == 0);
  76    s->reconnect_timer = g_timeout_add_seconds(s->reconnect_time,
  77                                               socket_reconnect_timeout, chr);
  78    name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label);
  79    g_source_set_name_by_id(s->reconnect_timer, name);
  80    g_free(name);
  81}
  82
  83static void check_report_connect_error(Chardev *chr,
  84                                       Error *err)
  85{
  86    SocketChardev *s = SOCKET_CHARDEV(chr);
  87
  88    if (!s->connect_err_reported) {
  89        error_report("Unable to connect character device %s: %s",
  90                     chr->label, error_get_pretty(err));
  91        s->connect_err_reported = true;
  92    }
  93    qemu_chr_socket_restart_timer(chr);
  94}
  95
  96static gboolean tcp_chr_accept(QIOChannel *chan,
  97                               GIOCondition cond,
  98                               void *opaque);
  99
 100static int tcp_chr_read_poll(void *opaque);
 101static void tcp_chr_disconnect(Chardev *chr);
 102
 103/* Called with chr_write_lock held.  */
 104static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
 105{
 106    SocketChardev *s = SOCKET_CHARDEV(chr);
 107
 108    if (s->connected) {
 109        int ret =  io_channel_send_full(s->ioc, buf, len,
 110                                        s->write_msgfds,
 111                                        s->write_msgfds_num);
 112
 113        /* free the written msgfds, no matter what */
 114        if (s->write_msgfds_num) {
 115            g_free(s->write_msgfds);
 116            s->write_msgfds = 0;
 117            s->write_msgfds_num = 0;
 118        }
 119
 120        if (ret < 0 && errno != EAGAIN) {
 121            if (tcp_chr_read_poll(chr) <= 0) {
 122                tcp_chr_disconnect(chr);
 123                return len;
 124            } /* else let the read handler finish it properly */
 125        }
 126
 127        return ret;
 128    } else {
 129        /* XXX: indicate an error ? */
 130        return len;
 131    }
 132}
 133
 134static int tcp_chr_read_poll(void *opaque)
 135{
 136    Chardev *chr = CHARDEV(opaque);
 137    SocketChardev *s = SOCKET_CHARDEV(opaque);
 138    if (!s->connected) {
 139        return 0;
 140    }
 141    s->max_size = qemu_chr_be_can_write(chr);
 142    return s->max_size;
 143}
 144
 145static void tcp_chr_process_IAC_bytes(Chardev *chr,
 146                                      SocketChardev *s,
 147                                      uint8_t *buf, int *size)
 148{
 149    /* Handle any telnet or tn3270 client's basic IAC options.
 150     * For telnet options, it satisfies char by char mode with no echo.
 151     * For tn3270 options, it satisfies binary mode with EOR.
 152     * All IAC options will be removed from the buf and the do_opt
 153     * pointer will be used to track the state of the width of the
 154     * IAC information.
 155     *
 156     * RFC854: "All TELNET commands consist of at least a two byte sequence.
 157     * The commands dealing with option negotiation are three byte sequences,
 158     * the third byte being the code for the option referenced."
 159     * "IAC BREAK", "IAC IP", "IAC NOP" and the double IAC are two bytes.
 160     * "IAC SB", "IAC SE" and "IAC EOR" are saved to split up data boundary
 161     * for tn3270.
 162     * NOP, Break and Interrupt Process(IP) might be encountered during a TN3270
 163     * session, and NOP and IP need to be done later.
 164     */
 165
 166    int i;
 167    int j = 0;
 168
 169    for (i = 0; i < *size; i++) {
 170        if (s->do_telnetopt > 1) {
 171            if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
 172                /* Double IAC means send an IAC */
 173                if (j != i) {
 174                    buf[j] = buf[i];
 175                }
 176                j++;
 177                s->do_telnetopt = 1;
 178            } else {
 179                if ((unsigned char)buf[i] == IAC_BREAK
 180                    && s->do_telnetopt == 2) {
 181                    /* Handle IAC break commands by sending a serial break */
 182                    qemu_chr_be_event(chr, CHR_EVENT_BREAK);
 183                    s->do_telnetopt++;
 184                } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_EOR
 185                           || (unsigned char)buf[i] == IAC_SB
 186                           || (unsigned char)buf[i] == IAC_SE)
 187                           && s->do_telnetopt == 2) {
 188                    buf[j++] = IAC;
 189                    buf[j++] = buf[i];
 190                    s->do_telnetopt++;
 191                } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_IP
 192                           || (unsigned char)buf[i] == IAC_NOP)
 193                           && s->do_telnetopt == 2) {
 194                    /* TODO: IP and NOP need to be implemented later. */
 195                    s->do_telnetopt++;
 196                }
 197                s->do_telnetopt++;
 198            }
 199            if (s->do_telnetopt >= 4) {
 200                s->do_telnetopt = 1;
 201            }
 202        } else {
 203            if ((unsigned char)buf[i] == IAC) {
 204                s->do_telnetopt = 2;
 205            } else {
 206                if (j != i) {
 207                    buf[j] = buf[i];
 208                }
 209                j++;
 210            }
 211        }
 212    }
 213    *size = j;
 214}
 215
 216static int tcp_get_msgfds(Chardev *chr, int *fds, int num)
 217{
 218    SocketChardev *s = SOCKET_CHARDEV(chr);
 219
 220    int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num;
 221
 222    assert(num <= TCP_MAX_FDS);
 223
 224    if (to_copy) {
 225        int i;
 226
 227        memcpy(fds, s->read_msgfds, to_copy * sizeof(int));
 228
 229        /* Close unused fds */
 230        for (i = to_copy; i < s->read_msgfds_num; i++) {
 231            close(s->read_msgfds[i]);
 232        }
 233
 234        g_free(s->read_msgfds);
 235        s->read_msgfds = 0;
 236        s->read_msgfds_num = 0;
 237    }
 238
 239    return to_copy;
 240}
 241
 242static int tcp_set_msgfds(Chardev *chr, int *fds, int num)
 243{
 244    SocketChardev *s = SOCKET_CHARDEV(chr);
 245
 246    /* clear old pending fd array */
 247    g_free(s->write_msgfds);
 248    s->write_msgfds = NULL;
 249    s->write_msgfds_num = 0;
 250
 251    if (!s->connected ||
 252        !qio_channel_has_feature(s->ioc,
 253                                 QIO_CHANNEL_FEATURE_FD_PASS)) {
 254        return -1;
 255    }
 256
 257    if (num) {
 258        s->write_msgfds = g_new(int, num);
 259        memcpy(s->write_msgfds, fds, num * sizeof(int));
 260    }
 261
 262    s->write_msgfds_num = num;
 263
 264    return 0;
 265}
 266
 267static ssize_t tcp_chr_recv(Chardev *chr, char *buf, size_t len)
 268{
 269    SocketChardev *s = SOCKET_CHARDEV(chr);
 270    struct iovec iov = { .iov_base = buf, .iov_len = len };
 271    int ret;
 272    size_t i;
 273    int *msgfds = NULL;
 274    size_t msgfds_num = 0;
 275
 276    if (qio_channel_has_feature(s->ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
 277        ret = qio_channel_readv_full(s->ioc, &iov, 1,
 278                                     &msgfds, &msgfds_num,
 279                                     NULL);
 280    } else {
 281        ret = qio_channel_readv_full(s->ioc, &iov, 1,
 282                                     NULL, NULL,
 283                                     NULL);
 284    }
 285
 286    if (ret == QIO_CHANNEL_ERR_BLOCK) {
 287        errno = EAGAIN;
 288        ret = -1;
 289    } else if (ret == -1) {
 290        errno = EIO;
 291    }
 292
 293    if (msgfds_num) {
 294        /* close and clean read_msgfds */
 295        for (i = 0; i < s->read_msgfds_num; i++) {
 296            close(s->read_msgfds[i]);
 297        }
 298
 299        if (s->read_msgfds_num) {
 300            g_free(s->read_msgfds);
 301        }
 302
 303        s->read_msgfds = msgfds;
 304        s->read_msgfds_num = msgfds_num;
 305    }
 306
 307    for (i = 0; i < s->read_msgfds_num; i++) {
 308        int fd = s->read_msgfds[i];
 309        if (fd < 0) {
 310            continue;
 311        }
 312
 313        /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
 314        qemu_set_block(fd);
 315
 316#ifndef MSG_CMSG_CLOEXEC
 317        qemu_set_cloexec(fd);
 318#endif
 319    }
 320
 321    return ret;
 322}
 323
 324static GSource *tcp_chr_add_watch(Chardev *chr, GIOCondition cond)
 325{
 326    SocketChardev *s = SOCKET_CHARDEV(chr);
 327    return qio_channel_create_watch(s->ioc, cond);
 328}
 329
 330static void tcp_chr_free_connection(Chardev *chr)
 331{
 332    SocketChardev *s = SOCKET_CHARDEV(chr);
 333    int i;
 334
 335    if (s->read_msgfds_num) {
 336        for (i = 0; i < s->read_msgfds_num; i++) {
 337            close(s->read_msgfds[i]);
 338        }
 339        g_free(s->read_msgfds);
 340        s->read_msgfds = NULL;
 341        s->read_msgfds_num = 0;
 342    }
 343
 344    tcp_set_msgfds(chr, NULL, 0);
 345    remove_fd_in_watch(chr);
 346    object_unref(OBJECT(s->sioc));
 347    s->sioc = NULL;
 348    object_unref(OBJECT(s->ioc));
 349    s->ioc = NULL;
 350    g_free(chr->filename);
 351    chr->filename = NULL;
 352    s->connected = 0;
 353}
 354
 355static char *SocketAddress_to_str(const char *prefix, SocketAddress *addr,
 356                                  bool is_listen, bool is_telnet)
 357{
 358    switch (addr->type) {
 359    case SOCKET_ADDRESS_TYPE_INET:
 360        return g_strdup_printf("%s%s:%s:%s%s", prefix,
 361                               is_telnet ? "telnet" : "tcp",
 362                               addr->u.inet.host,
 363                               addr->u.inet.port,
 364                               is_listen ? ",server" : "");
 365        break;
 366    case SOCKET_ADDRESS_TYPE_UNIX:
 367        return g_strdup_printf("%sunix:%s%s", prefix,
 368                               addr->u.q_unix.path,
 369                               is_listen ? ",server" : "");
 370        break;
 371    case SOCKET_ADDRESS_TYPE_FD:
 372        return g_strdup_printf("%sfd:%s%s", prefix, addr->u.fd.str,
 373                               is_listen ? ",server" : "");
 374        break;
 375    case SOCKET_ADDRESS_TYPE_VSOCK:
 376        return g_strdup_printf("%svsock:%s:%s", prefix,
 377                               addr->u.vsock.cid,
 378                               addr->u.vsock.port);
 379    default:
 380        abort();
 381    }
 382}
 383
 384static void update_disconnected_filename(SocketChardev *s)
 385{
 386    Chardev *chr = CHARDEV(s);
 387
 388    g_free(chr->filename);
 389    chr->filename = SocketAddress_to_str("disconnected:", s->addr,
 390                                         s->is_listen, s->is_telnet);
 391}
 392
 393/* NB may be called even if tcp_chr_connect has not been
 394 * reached, due to TLS or telnet initialization failure,
 395 * so can *not* assume s->connected == true
 396 */
 397static void tcp_chr_disconnect(Chardev *chr)
 398{
 399    SocketChardev *s = SOCKET_CHARDEV(chr);
 400    bool emit_close = s->connected;
 401
 402    tcp_chr_free_connection(chr);
 403
 404    if (s->listen_ioc && s->listen_tag == 0) {
 405        s->listen_tag = qio_channel_add_watch(
 406            QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL);
 407    }
 408    update_disconnected_filename(s);
 409    if (emit_close) {
 410        qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
 411    }
 412    if (s->reconnect_time) {
 413        qemu_chr_socket_restart_timer(chr);
 414    }
 415}
 416
 417static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
 418{
 419    Chardev *chr = CHARDEV(opaque);
 420    SocketChardev *s = SOCKET_CHARDEV(opaque);
 421    uint8_t buf[CHR_READ_BUF_LEN];
 422    int len, size;
 423
 424    if (!s->connected || s->max_size <= 0) {
 425        return TRUE;
 426    }
 427    len = sizeof(buf);
 428    if (len > s->max_size) {
 429        len = s->max_size;
 430    }
 431    size = tcp_chr_recv(chr, (void *)buf, len);
 432    if (size == 0 || size == -1) {
 433        /* connection closed */
 434        tcp_chr_disconnect(chr);
 435    } else if (size > 0) {
 436        if (s->do_telnetopt) {
 437            tcp_chr_process_IAC_bytes(chr, s, buf, &size);
 438        }
 439        if (size > 0) {
 440            qemu_chr_be_write(chr, buf, size);
 441        }
 442    }
 443
 444    return TRUE;
 445}
 446
 447static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len)
 448{
 449    SocketChardev *s = SOCKET_CHARDEV(chr);
 450    int size;
 451
 452    if (!s->connected) {
 453        return 0;
 454    }
 455
 456    qio_channel_set_blocking(s->ioc, true, NULL);
 457    size = tcp_chr_recv(chr, (void *) buf, len);
 458    qio_channel_set_blocking(s->ioc, false, NULL);
 459    if (size == 0) {
 460        /* connection closed */
 461        tcp_chr_disconnect(chr);
 462    }
 463
 464    return size;
 465}
 466
 467static char *sockaddr_to_str(struct sockaddr_storage *ss, socklen_t ss_len,
 468                             struct sockaddr_storage *ps, socklen_t ps_len,
 469                             bool is_listen, bool is_telnet)
 470{
 471    char shost[NI_MAXHOST], sserv[NI_MAXSERV];
 472    char phost[NI_MAXHOST], pserv[NI_MAXSERV];
 473    const char *left = "", *right = "";
 474
 475    switch (ss->ss_family) {
 476#ifndef _WIN32
 477    case AF_UNIX:
 478        return g_strdup_printf("unix:%s%s",
 479                               ((struct sockaddr_un *)(ss))->sun_path,
 480                               is_listen ? ",server" : "");
 481#endif
 482    case AF_INET6:
 483        left  = "[";
 484        right = "]";
 485        /* fall through */
 486    case AF_INET:
 487        getnameinfo((struct sockaddr *) ss, ss_len, shost, sizeof(shost),
 488                    sserv, sizeof(sserv), NI_NUMERICHOST | NI_NUMERICSERV);
 489        getnameinfo((struct sockaddr *) ps, ps_len, phost, sizeof(phost),
 490                    pserv, sizeof(pserv), NI_NUMERICHOST | NI_NUMERICSERV);
 491        return g_strdup_printf("%s:%s%s%s:%s%s <-> %s%s%s:%s",
 492                               is_telnet ? "telnet" : "tcp",
 493                               left, shost, right, sserv,
 494                               is_listen ? ",server" : "",
 495                               left, phost, right, pserv);
 496
 497    default:
 498        return g_strdup_printf("unknown");
 499    }
 500}
 501
 502static void tcp_chr_connect(void *opaque)
 503{
 504    Chardev *chr = CHARDEV(opaque);
 505    SocketChardev *s = SOCKET_CHARDEV(opaque);
 506
 507    g_free(chr->filename);
 508    chr->filename = sockaddr_to_str(
 509        &s->sioc->localAddr, s->sioc->localAddrLen,
 510        &s->sioc->remoteAddr, s->sioc->remoteAddrLen,
 511        s->is_listen, s->is_telnet);
 512
 513    s->connected = 1;
 514    if (s->ioc) {
 515        chr->gsource = io_add_watch_poll(chr, s->ioc,
 516                                           tcp_chr_read_poll,
 517                                           tcp_chr_read,
 518                                           chr, chr->gcontext);
 519    }
 520    qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 521}
 522
 523static void tcp_chr_update_read_handler(Chardev *chr)
 524{
 525    SocketChardev *s = SOCKET_CHARDEV(chr);
 526
 527    if (!s->connected) {
 528        return;
 529    }
 530
 531    remove_fd_in_watch(chr);
 532    if (s->ioc) {
 533        chr->gsource = io_add_watch_poll(chr, s->ioc,
 534                                           tcp_chr_read_poll,
 535                                           tcp_chr_read, chr,
 536                                           chr->gcontext);
 537    }
 538}
 539
 540typedef struct {
 541    Chardev *chr;
 542    char buf[21];
 543    size_t buflen;
 544} TCPChardevTelnetInit;
 545
 546static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc,
 547                                       GIOCondition cond G_GNUC_UNUSED,
 548                                       gpointer user_data)
 549{
 550    TCPChardevTelnetInit *init = user_data;
 551    ssize_t ret;
 552
 553    ret = qio_channel_write(ioc, init->buf, init->buflen, NULL);
 554    if (ret < 0) {
 555        if (ret == QIO_CHANNEL_ERR_BLOCK) {
 556            ret = 0;
 557        } else {
 558            tcp_chr_disconnect(init->chr);
 559            return FALSE;
 560        }
 561    }
 562    init->buflen -= ret;
 563
 564    if (init->buflen == 0) {
 565        tcp_chr_connect(init->chr);
 566        return FALSE;
 567    }
 568
 569    memmove(init->buf, init->buf + ret, init->buflen);
 570
 571    return TRUE;
 572}
 573
 574static void tcp_chr_telnet_init(Chardev *chr)
 575{
 576    SocketChardev *s = SOCKET_CHARDEV(chr);
 577    TCPChardevTelnetInit *init = g_new0(TCPChardevTelnetInit, 1);
 578    size_t n = 0;
 579
 580#define IACSET(x, a, b, c)                      \
 581    do {                                        \
 582        x[n++] = a;                             \
 583        x[n++] = b;                             \
 584        x[n++] = c;                             \
 585    } while (0)
 586
 587    init->chr = chr;
 588    if (!s->is_tn3270) {
 589        init->buflen = 12;
 590        /* Prep the telnet negotion to put telnet in binary,
 591         * no echo, single char mode */
 592        IACSET(init->buf, 0xff, 0xfb, 0x01);  /* IAC WILL ECHO */
 593        IACSET(init->buf, 0xff, 0xfb, 0x03);  /* IAC WILL Suppress go ahead */
 594        IACSET(init->buf, 0xff, 0xfb, 0x00);  /* IAC WILL Binary */
 595        IACSET(init->buf, 0xff, 0xfd, 0x00);  /* IAC DO Binary */
 596    } else {
 597        init->buflen = 21;
 598        /* Prep the TN3270 negotion based on RFC1576 */
 599        IACSET(init->buf, 0xff, 0xfd, 0x19);  /* IAC DO EOR */
 600        IACSET(init->buf, 0xff, 0xfb, 0x19);  /* IAC WILL EOR */
 601        IACSET(init->buf, 0xff, 0xfd, 0x00);  /* IAC DO BINARY */
 602        IACSET(init->buf, 0xff, 0xfb, 0x00);  /* IAC WILL BINARY */
 603        IACSET(init->buf, 0xff, 0xfd, 0x18);  /* IAC DO TERMINAL TYPE */
 604        IACSET(init->buf, 0xff, 0xfa, 0x18);  /* IAC SB TERMINAL TYPE */
 605        IACSET(init->buf, 0x01, 0xff, 0xf0);  /* SEND IAC SE */
 606    }
 607
 608#undef IACSET
 609
 610    qio_channel_add_watch(
 611        s->ioc, G_IO_OUT,
 612        tcp_chr_telnet_init_io,
 613        init, NULL);
 614}
 615
 616
 617static void tcp_chr_tls_handshake(QIOTask *task,
 618                                  gpointer user_data)
 619{
 620    Chardev *chr = user_data;
 621    SocketChardev *s = user_data;
 622
 623    if (qio_task_propagate_error(task, NULL)) {
 624        tcp_chr_disconnect(chr);
 625    } else {
 626        /* tn3270 does not support TLS yet */
 627        if (s->do_telnetopt && !s->is_tn3270) {
 628            tcp_chr_telnet_init(chr);
 629        } else {
 630            tcp_chr_connect(chr);
 631        }
 632    }
 633}
 634
 635
 636static void tcp_chr_tls_init(Chardev *chr)
 637{
 638    SocketChardev *s = SOCKET_CHARDEV(chr);
 639    QIOChannelTLS *tioc;
 640    Error *err = NULL;
 641    gchar *name;
 642
 643    if (s->is_listen) {
 644        tioc = qio_channel_tls_new_server(
 645            s->ioc, s->tls_creds,
 646            NULL, /* XXX Use an ACL */
 647            &err);
 648    } else {
 649        tioc = qio_channel_tls_new_client(
 650            s->ioc, s->tls_creds,
 651            s->addr->u.inet.host,
 652            &err);
 653    }
 654    if (tioc == NULL) {
 655        error_free(err);
 656        tcp_chr_disconnect(chr);
 657        return;
 658    }
 659    name = g_strdup_printf("chardev-tls-%s-%s",
 660                           s->is_listen ? "server" : "client",
 661                           chr->label);
 662    qio_channel_set_name(QIO_CHANNEL(tioc), name);
 663    g_free(name);
 664    object_unref(OBJECT(s->ioc));
 665    s->ioc = QIO_CHANNEL(tioc);
 666
 667    qio_channel_tls_handshake(tioc,
 668                              tcp_chr_tls_handshake,
 669                              chr,
 670                              NULL);
 671}
 672
 673
 674static void tcp_chr_set_client_ioc_name(Chardev *chr,
 675                                        QIOChannelSocket *sioc)
 676{
 677    SocketChardev *s = SOCKET_CHARDEV(chr);
 678    char *name;
 679    name = g_strdup_printf("chardev-tcp-%s-%s",
 680                           s->is_listen ? "server" : "client",
 681                           chr->label);
 682    qio_channel_set_name(QIO_CHANNEL(sioc), name);
 683    g_free(name);
 684
 685}
 686
 687static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc)
 688{
 689    SocketChardev *s = SOCKET_CHARDEV(chr);
 690
 691    if (s->ioc != NULL) {
 692        return -1;
 693    }
 694
 695    s->ioc = QIO_CHANNEL(sioc);
 696    object_ref(OBJECT(sioc));
 697    s->sioc = sioc;
 698    object_ref(OBJECT(sioc));
 699
 700    qio_channel_set_blocking(s->ioc, false, NULL);
 701
 702    if (s->do_nodelay) {
 703        qio_channel_set_delay(s->ioc, false);
 704    }
 705    if (s->listen_tag) {
 706        g_source_remove(s->listen_tag);
 707        s->listen_tag = 0;
 708    }
 709
 710    if (s->tls_creds) {
 711        tcp_chr_tls_init(chr);
 712    } else {
 713        if (s->do_telnetopt) {
 714            tcp_chr_telnet_init(chr);
 715        } else {
 716            tcp_chr_connect(chr);
 717        }
 718    }
 719
 720    return 0;
 721}
 722
 723
 724static int tcp_chr_add_client(Chardev *chr, int fd)
 725{
 726    int ret;
 727    QIOChannelSocket *sioc;
 728
 729    sioc = qio_channel_socket_new_fd(fd, NULL);
 730    if (!sioc) {
 731        return -1;
 732    }
 733    tcp_chr_set_client_ioc_name(chr, sioc);
 734    ret = tcp_chr_new_client(chr, sioc);
 735    object_unref(OBJECT(sioc));
 736    return ret;
 737}
 738
 739static gboolean tcp_chr_accept(QIOChannel *channel,
 740                               GIOCondition cond,
 741                               void *opaque)
 742{
 743    Chardev *chr = CHARDEV(opaque);
 744    QIOChannelSocket *sioc;
 745
 746    sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(channel),
 747                                     NULL);
 748    if (!sioc) {
 749        return TRUE;
 750    }
 751
 752    tcp_chr_new_client(chr, sioc);
 753
 754    object_unref(OBJECT(sioc));
 755
 756    return TRUE;
 757}
 758
 759static int tcp_chr_wait_connected(Chardev *chr, Error **errp)
 760{
 761    SocketChardev *s = SOCKET_CHARDEV(chr);
 762    QIOChannelSocket *sioc;
 763
 764    /* It can't wait on s->connected, since it is set asynchronously
 765     * in TLS and telnet cases, only wait for an accepted socket */
 766    while (!s->ioc) {
 767        if (s->is_listen) {
 768            info_report("QEMU waiting for connection on: %s",
 769                        chr->filename);
 770            qio_channel_set_blocking(QIO_CHANNEL(s->listen_ioc), true, NULL);
 771            tcp_chr_accept(QIO_CHANNEL(s->listen_ioc), G_IO_IN, chr);
 772            qio_channel_set_blocking(QIO_CHANNEL(s->listen_ioc), false, NULL);
 773        } else {
 774            sioc = qio_channel_socket_new();
 775            tcp_chr_set_client_ioc_name(chr, sioc);
 776            if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) {
 777                object_unref(OBJECT(sioc));
 778                return -1;
 779            }
 780            tcp_chr_new_client(chr, sioc);
 781            object_unref(OBJECT(sioc));
 782        }
 783    }
 784
 785    return 0;
 786}
 787
 788static void char_socket_finalize(Object *obj)
 789{
 790    Chardev *chr = CHARDEV(obj);
 791    SocketChardev *s = SOCKET_CHARDEV(obj);
 792
 793    tcp_chr_free_connection(chr);
 794
 795    if (s->reconnect_timer) {
 796        g_source_remove(s->reconnect_timer);
 797        s->reconnect_timer = 0;
 798    }
 799    qapi_free_SocketAddress(s->addr);
 800    if (s->listen_tag) {
 801        g_source_remove(s->listen_tag);
 802        s->listen_tag = 0;
 803    }
 804    if (s->listen_ioc) {
 805        object_unref(OBJECT(s->listen_ioc));
 806    }
 807    if (s->tls_creds) {
 808        object_unref(OBJECT(s->tls_creds));
 809    }
 810
 811    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
 812}
 813
 814static void qemu_chr_socket_connected(QIOTask *task, void *opaque)
 815{
 816    QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
 817    Chardev *chr = CHARDEV(opaque);
 818    SocketChardev *s = SOCKET_CHARDEV(chr);
 819    Error *err = NULL;
 820
 821    if (qio_task_propagate_error(task, &err)) {
 822        check_report_connect_error(chr, err);
 823        error_free(err);
 824        goto cleanup;
 825    }
 826
 827    s->connect_err_reported = false;
 828    tcp_chr_new_client(chr, sioc);
 829
 830cleanup:
 831    object_unref(OBJECT(sioc));
 832}
 833
 834static gboolean socket_reconnect_timeout(gpointer opaque)
 835{
 836    Chardev *chr = CHARDEV(opaque);
 837    SocketChardev *s = SOCKET_CHARDEV(opaque);
 838    QIOChannelSocket *sioc;
 839
 840    s->reconnect_timer = 0;
 841
 842    if (chr->be_open) {
 843        return false;
 844    }
 845
 846    sioc = qio_channel_socket_new();
 847    tcp_chr_set_client_ioc_name(chr, sioc);
 848    qio_channel_socket_connect_async(sioc, s->addr,
 849                                     qemu_chr_socket_connected,
 850                                     chr, NULL);
 851
 852    return false;
 853}
 854
 855static void qmp_chardev_open_socket(Chardev *chr,
 856                                    ChardevBackend *backend,
 857                                    bool *be_opened,
 858                                    Error **errp)
 859{
 860    SocketChardev *s = SOCKET_CHARDEV(chr);
 861    ChardevSocket *sock = backend->u.socket.data;
 862    bool do_nodelay     = sock->has_nodelay ? sock->nodelay : false;
 863    bool is_listen      = sock->has_server  ? sock->server  : true;
 864    bool is_telnet      = sock->has_telnet  ? sock->telnet  : false;
 865    bool is_tn3270      = sock->has_tn3270  ? sock->tn3270  : false;
 866    bool is_waitconnect = sock->has_wait    ? sock->wait    : false;
 867    int64_t reconnect   = sock->has_reconnect ? sock->reconnect : 0;
 868    QIOChannelSocket *sioc = NULL;
 869    SocketAddress *addr;
 870
 871    s->is_listen = is_listen;
 872    s->is_telnet = is_telnet;
 873    s->is_tn3270 = is_tn3270;
 874    s->do_nodelay = do_nodelay;
 875    if (sock->tls_creds) {
 876        Object *creds;
 877        creds = object_resolve_path_component(
 878            object_get_objects_root(), sock->tls_creds);
 879        if (!creds) {
 880            error_setg(errp, "No TLS credentials with id '%s'",
 881                       sock->tls_creds);
 882            goto error;
 883        }
 884        s->tls_creds = (QCryptoTLSCreds *)
 885            object_dynamic_cast(creds,
 886                                TYPE_QCRYPTO_TLS_CREDS);
 887        if (!s->tls_creds) {
 888            error_setg(errp, "Object with id '%s' is not TLS credentials",
 889                       sock->tls_creds);
 890            goto error;
 891        }
 892        object_ref(OBJECT(s->tls_creds));
 893        if (is_listen) {
 894            if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
 895                error_setg(errp, "%s",
 896                           "Expected TLS credentials for server endpoint");
 897                goto error;
 898            }
 899        } else {
 900            if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
 901                error_setg(errp, "%s",
 902                           "Expected TLS credentials for client endpoint");
 903                goto error;
 904            }
 905        }
 906    }
 907
 908    s->addr = addr = socket_address_flatten(sock->addr);
 909
 910    qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE);
 911    /* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */
 912    if (addr->type == SOCKET_ADDRESS_TYPE_UNIX) {
 913        qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS);
 914    }
 915
 916    /* be isn't opened until we get a connection */
 917    *be_opened = false;
 918
 919    update_disconnected_filename(s);
 920
 921    if (is_listen) {
 922        if (is_telnet || is_tn3270) {
 923            s->do_telnetopt = 1;
 924        }
 925    } else if (reconnect > 0) {
 926        s->reconnect_time = reconnect;
 927    }
 928
 929    if (s->reconnect_time) {
 930        sioc = qio_channel_socket_new();
 931        tcp_chr_set_client_ioc_name(chr, sioc);
 932        qio_channel_socket_connect_async(sioc, s->addr,
 933                                         qemu_chr_socket_connected,
 934                                         chr, NULL);
 935    } else {
 936        if (s->is_listen) {
 937            char *name;
 938            sioc = qio_channel_socket_new();
 939
 940            name = g_strdup_printf("chardev-tcp-listener-%s", chr->label);
 941            qio_channel_set_name(QIO_CHANNEL(sioc), name);
 942            g_free(name);
 943
 944            if (qio_channel_socket_listen_sync(sioc, s->addr, errp) < 0) {
 945                goto error;
 946            }
 947
 948            qapi_free_SocketAddress(s->addr);
 949            s->addr = socket_local_address(sioc->fd, errp);
 950            update_disconnected_filename(s);
 951
 952            s->listen_ioc = sioc;
 953            if (is_waitconnect &&
 954                qemu_chr_wait_connected(chr, errp) < 0) {
 955                return;
 956            }
 957            if (!s->ioc) {
 958                s->listen_tag = qio_channel_add_watch(
 959                    QIO_CHANNEL(s->listen_ioc), G_IO_IN,
 960                    tcp_chr_accept, chr, NULL);
 961            }
 962        } else if (qemu_chr_wait_connected(chr, errp) < 0) {
 963            goto error;
 964        }
 965    }
 966
 967    return;
 968
 969error:
 970    if (sioc) {
 971        object_unref(OBJECT(sioc));
 972    }
 973}
 974
 975static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
 976                                  Error **errp)
 977{
 978    bool is_listen      = qemu_opt_get_bool(opts, "server", false);
 979    bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true);
 980    bool is_telnet      = qemu_opt_get_bool(opts, "telnet", false);
 981    bool is_tn3270      = qemu_opt_get_bool(opts, "tn3270", false);
 982    bool do_nodelay     = !qemu_opt_get_bool(opts, "delay", true);
 983    int64_t reconnect   = qemu_opt_get_number(opts, "reconnect", 0);
 984    const char *path = qemu_opt_get(opts, "path");
 985    const char *host = qemu_opt_get(opts, "host");
 986    const char *port = qemu_opt_get(opts, "port");
 987    const char *tls_creds = qemu_opt_get(opts, "tls-creds");
 988    SocketAddressLegacy *addr;
 989    ChardevSocket *sock;
 990
 991    backend->type = CHARDEV_BACKEND_KIND_SOCKET;
 992    if (!path) {
 993        if (!host) {
 994            error_setg(errp, "chardev: socket: no host given");
 995            return;
 996        }
 997        if (!port) {
 998            error_setg(errp, "chardev: socket: no port given");
 999            return;
1000        }
1001    } else {
1002        if (tls_creds) {
1003            error_setg(errp, "TLS can only be used over TCP socket");
1004            return;
1005        }
1006    }
1007
1008    sock = backend->u.socket.data = g_new0(ChardevSocket, 1);
1009    qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock));
1010
1011    sock->has_nodelay = true;
1012    sock->nodelay = do_nodelay;
1013    sock->has_server = true;
1014    sock->server = is_listen;
1015    sock->has_telnet = true;
1016    sock->telnet = is_telnet;
1017    sock->has_tn3270 = true;
1018    sock->tn3270 = is_tn3270;
1019    sock->has_wait = true;
1020    sock->wait = is_waitconnect;
1021    sock->has_reconnect = true;
1022    sock->reconnect = reconnect;
1023    sock->tls_creds = g_strdup(tls_creds);
1024
1025    addr = g_new0(SocketAddressLegacy, 1);
1026    if (path) {
1027        UnixSocketAddress *q_unix;
1028        addr->type = SOCKET_ADDRESS_LEGACY_KIND_UNIX;
1029        q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
1030        q_unix->path = g_strdup(path);
1031    } else {
1032        addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET;
1033        addr->u.inet.data = g_new(InetSocketAddress, 1);
1034        *addr->u.inet.data = (InetSocketAddress) {
1035            .host = g_strdup(host),
1036            .port = g_strdup(port),
1037            .has_to = qemu_opt_get(opts, "to"),
1038            .to = qemu_opt_get_number(opts, "to", 0),
1039            .has_ipv4 = qemu_opt_get(opts, "ipv4"),
1040            .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0),
1041            .has_ipv6 = qemu_opt_get(opts, "ipv6"),
1042            .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
1043        };
1044    }
1045    sock->addr = addr;
1046}
1047
1048static void
1049char_socket_get_addr(Object *obj, Visitor *v, const char *name,
1050                     void *opaque, Error **errp)
1051{
1052    SocketChardev *s = SOCKET_CHARDEV(obj);
1053
1054    visit_type_SocketAddress(v, name, &s->addr, errp);
1055}
1056
1057static bool
1058char_socket_get_connected(Object *obj, Error **errp)
1059{
1060    SocketChardev *s = SOCKET_CHARDEV(obj);
1061
1062    return s->connected;
1063}
1064
1065static void char_socket_class_init(ObjectClass *oc, void *data)
1066{
1067    ChardevClass *cc = CHARDEV_CLASS(oc);
1068
1069    cc->parse = qemu_chr_parse_socket;
1070    cc->open = qmp_chardev_open_socket;
1071    cc->chr_wait_connected = tcp_chr_wait_connected;
1072    cc->chr_write = tcp_chr_write;
1073    cc->chr_sync_read = tcp_chr_sync_read;
1074    cc->chr_disconnect = tcp_chr_disconnect;
1075    cc->get_msgfds = tcp_get_msgfds;
1076    cc->set_msgfds = tcp_set_msgfds;
1077    cc->chr_add_client = tcp_chr_add_client;
1078    cc->chr_add_watch = tcp_chr_add_watch;
1079    cc->chr_update_read_handler = tcp_chr_update_read_handler;
1080
1081    object_class_property_add(oc, "addr", "SocketAddress",
1082                              char_socket_get_addr, NULL,
1083                              NULL, NULL, &error_abort);
1084
1085    object_class_property_add_bool(oc, "connected", char_socket_get_connected,
1086                                   NULL, &error_abort);
1087}
1088
1089static const TypeInfo char_socket_type_info = {
1090    .name = TYPE_CHARDEV_SOCKET,
1091    .parent = TYPE_CHARDEV,
1092    .instance_size = sizeof(SocketChardev),
1093    .instance_finalize = char_socket_finalize,
1094    .class_init = char_socket_class_init,
1095};
1096
1097static void register_types(void)
1098{
1099    type_register_static(&char_socket_type_info);
1100}
1101
1102type_init(register_types);
1103