qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

char-socket.c (48482B)


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