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