xref: /openbmc/qemu/chardev/char-socket.c (revision a10b9d93)
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     return qio_channel_create_watch(s->ioc, cond);
391 }
392 
393 static void remove_hup_source(SocketChardev *s)
394 {
395     if (s->hup_source != NULL) {
396         g_source_destroy(s->hup_source);
397         g_source_unref(s->hup_source);
398         s->hup_source = NULL;
399     }
400 }
401 
402 static void tcp_chr_free_connection(Chardev *chr)
403 {
404     SocketChardev *s = SOCKET_CHARDEV(chr);
405     int i;
406 
407     if (s->read_msgfds_num) {
408         for (i = 0; i < s->read_msgfds_num; i++) {
409             close(s->read_msgfds[i]);
410         }
411         g_free(s->read_msgfds);
412         s->read_msgfds = NULL;
413         s->read_msgfds_num = 0;
414     }
415 
416     remove_hup_source(s);
417 
418     tcp_set_msgfds(chr, NULL, 0);
419     remove_fd_in_watch(chr);
420     if (s->state == TCP_CHARDEV_STATE_CONNECTING
421         || s->state == TCP_CHARDEV_STATE_CONNECTED) {
422         yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label),
423                                  yank_generic_iochannel,
424                                  QIO_CHANNEL(s->sioc));
425     }
426     object_unref(OBJECT(s->sioc));
427     s->sioc = NULL;
428     object_unref(OBJECT(s->ioc));
429     s->ioc = NULL;
430     g_free(chr->filename);
431     chr->filename = NULL;
432     tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
433 }
434 
435 static const char *qemu_chr_socket_protocol(SocketChardev *s)
436 {
437     if (s->is_telnet) {
438         return "telnet";
439     }
440     return s->is_websock ? "websocket" : "tcp";
441 }
442 
443 static char *qemu_chr_socket_address(SocketChardev *s, const char *prefix)
444 {
445     switch (s->addr->type) {
446     case SOCKET_ADDRESS_TYPE_INET:
447         return g_strdup_printf("%s%s:%s:%s%s", prefix,
448                                qemu_chr_socket_protocol(s),
449                                s->addr->u.inet.host,
450                                s->addr->u.inet.port,
451                                s->is_listen ? ",server" : "");
452         break;
453     case SOCKET_ADDRESS_TYPE_UNIX:
454     {
455         const char *tight = "", *abstract = "";
456         UnixSocketAddress *sa = &s->addr->u.q_unix;
457 
458 #ifdef CONFIG_LINUX
459         if (sa->has_abstract && sa->abstract) {
460             abstract = ",abstract";
461             if (sa->has_tight && sa->tight) {
462                 tight = ",tight";
463             }
464         }
465 #endif
466 
467         return g_strdup_printf("%sunix:%s%s%s%s", prefix, sa->path,
468                                abstract, tight,
469                                s->is_listen ? ",server" : "");
470         break;
471     }
472     case SOCKET_ADDRESS_TYPE_FD:
473         return g_strdup_printf("%sfd:%s%s", prefix, s->addr->u.fd.str,
474                                s->is_listen ? ",server" : "");
475         break;
476     case SOCKET_ADDRESS_TYPE_VSOCK:
477         return g_strdup_printf("%svsock:%s:%s", prefix,
478                                s->addr->u.vsock.cid,
479                                s->addr->u.vsock.port);
480     default:
481         abort();
482     }
483 }
484 
485 static void update_disconnected_filename(SocketChardev *s)
486 {
487     Chardev *chr = CHARDEV(s);
488 
489     g_free(chr->filename);
490     if (s->addr) {
491         chr->filename = qemu_chr_socket_address(s, "disconnected:");
492     } else {
493         chr->filename = g_strdup("disconnected:socket");
494     }
495 }
496 
497 /* NB may be called even if tcp_chr_connect has not been
498  * reached, due to TLS or telnet initialization failure,
499  * so can *not* assume s->state == TCP_CHARDEV_STATE_CONNECTED
500  * This must be called with chr->chr_write_lock held.
501  */
502 static void tcp_chr_disconnect_locked(Chardev *chr)
503 {
504     SocketChardev *s = SOCKET_CHARDEV(chr);
505     bool emit_close = s->state == TCP_CHARDEV_STATE_CONNECTED;
506 
507     tcp_chr_free_connection(chr);
508 
509     if (s->listener) {
510         qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
511                                               chr, NULL, chr->gcontext);
512     }
513     update_disconnected_filename(s);
514     if (emit_close) {
515         qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
516     }
517     if (s->reconnect_time && !s->reconnect_timer) {
518         qemu_chr_socket_restart_timer(chr);
519     }
520 }
521 
522 static void tcp_chr_disconnect(Chardev *chr)
523 {
524     qemu_mutex_lock(&chr->chr_write_lock);
525     tcp_chr_disconnect_locked(chr);
526     qemu_mutex_unlock(&chr->chr_write_lock);
527 }
528 
529 static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
530 {
531     Chardev *chr = CHARDEV(opaque);
532     SocketChardev *s = SOCKET_CHARDEV(opaque);
533     uint8_t buf[CHR_READ_BUF_LEN];
534     int len, size;
535 
536     if ((s->state != TCP_CHARDEV_STATE_CONNECTED) ||
537         s->max_size <= 0) {
538         return TRUE;
539     }
540     len = sizeof(buf);
541     if (len > s->max_size) {
542         len = s->max_size;
543     }
544     size = tcp_chr_recv(chr, (void *)buf, len);
545     if (size == 0 || (size == -1 && errno != EAGAIN)) {
546         /* connection closed */
547         tcp_chr_disconnect(chr);
548     } else if (size > 0) {
549         if (s->do_telnetopt) {
550             tcp_chr_process_IAC_bytes(chr, s, buf, &size);
551         }
552         if (size > 0) {
553             qemu_chr_be_write(chr, buf, size);
554         }
555     }
556 
557     return TRUE;
558 }
559 
560 static gboolean tcp_chr_hup(QIOChannel *channel,
561                                GIOCondition cond,
562                                void *opaque)
563 {
564     Chardev *chr = CHARDEV(opaque);
565     tcp_chr_disconnect(chr);
566     return G_SOURCE_REMOVE;
567 }
568 
569 static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len)
570 {
571     SocketChardev *s = SOCKET_CHARDEV(chr);
572     int size;
573 
574     if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
575         return 0;
576     }
577 
578     qio_channel_set_blocking(s->ioc, true, NULL);
579     size = tcp_chr_recv(chr, (void *) buf, len);
580     if (s->state != TCP_CHARDEV_STATE_DISCONNECTED) {
581         qio_channel_set_blocking(s->ioc, false, NULL);
582     }
583     if (size == 0) {
584         /* connection closed */
585         tcp_chr_disconnect(chr);
586     }
587 
588     return size;
589 }
590 
591 static char *qemu_chr_compute_filename(SocketChardev *s)
592 {
593     struct sockaddr_storage *ss = &s->sioc->localAddr;
594     struct sockaddr_storage *ps = &s->sioc->remoteAddr;
595     socklen_t ss_len = s->sioc->localAddrLen;
596     socklen_t ps_len = s->sioc->remoteAddrLen;
597     char shost[NI_MAXHOST], sserv[NI_MAXSERV];
598     char phost[NI_MAXHOST], pserv[NI_MAXSERV];
599     const char *left = "", *right = "";
600 
601     switch (ss->ss_family) {
602 #ifndef _WIN32
603     case AF_UNIX:
604         return g_strdup_printf("unix:%s%s",
605                                ((struct sockaddr_un *)(ss))->sun_path,
606                                s->is_listen ? ",server" : "");
607 #endif
608     case AF_INET6:
609         left  = "[";
610         right = "]";
611         /* fall through */
612     case AF_INET:
613         getnameinfo((struct sockaddr *) ss, ss_len, shost, sizeof(shost),
614                     sserv, sizeof(sserv), NI_NUMERICHOST | NI_NUMERICSERV);
615         getnameinfo((struct sockaddr *) ps, ps_len, phost, sizeof(phost),
616                     pserv, sizeof(pserv), NI_NUMERICHOST | NI_NUMERICSERV);
617         return g_strdup_printf("%s:%s%s%s:%s%s <-> %s%s%s:%s",
618                                qemu_chr_socket_protocol(s),
619                                left, shost, right, sserv,
620                                s->is_listen ? ",server" : "",
621                                left, phost, right, pserv);
622 
623     default:
624         return g_strdup_printf("unknown");
625     }
626 }
627 
628 static void update_ioc_handlers(SocketChardev *s)
629 {
630     Chardev *chr = CHARDEV(s);
631 
632     if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
633         return;
634     }
635 
636     remove_fd_in_watch(chr);
637     chr->gsource = io_add_watch_poll(chr, s->ioc,
638                                      tcp_chr_read_poll,
639                                      tcp_chr_read, chr,
640                                      chr->gcontext);
641 
642     remove_hup_source(s);
643     s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP);
644     g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup,
645                           chr, NULL);
646     g_source_attach(s->hup_source, chr->gcontext);
647 }
648 
649 static void tcp_chr_connect(void *opaque)
650 {
651     Chardev *chr = CHARDEV(opaque);
652     SocketChardev *s = SOCKET_CHARDEV(opaque);
653 
654     g_free(chr->filename);
655     chr->filename = qemu_chr_compute_filename(s);
656 
657     tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTED);
658     update_ioc_handlers(s);
659     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
660 }
661 
662 static void tcp_chr_telnet_destroy(SocketChardev *s)
663 {
664     if (s->telnet_source) {
665         g_source_destroy(s->telnet_source);
666         g_source_unref(s->telnet_source);
667         s->telnet_source = NULL;
668     }
669 }
670 
671 static void tcp_chr_update_read_handler(Chardev *chr)
672 {
673     SocketChardev *s = SOCKET_CHARDEV(chr);
674 
675     if (s->listener && s->state == TCP_CHARDEV_STATE_DISCONNECTED) {
676         /*
677          * It's possible that chardev context is changed in
678          * qemu_chr_be_update_read_handlers().  Reset it for QIO net
679          * listener if there is.
680          */
681         qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
682                                               chr, NULL, chr->gcontext);
683     }
684 
685     if (s->telnet_source) {
686         tcp_chr_telnet_init(CHARDEV(s));
687     }
688 
689     update_ioc_handlers(s);
690 }
691 
692 static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc,
693                                        GIOCondition cond G_GNUC_UNUSED,
694                                        gpointer user_data)
695 {
696     SocketChardev *s = user_data;
697     Chardev *chr = CHARDEV(s);
698     TCPChardevTelnetInit *init = s->telnet_init;
699     ssize_t ret;
700 
701     assert(init);
702 
703     ret = qio_channel_write(ioc, init->buf, init->buflen, NULL);
704     if (ret < 0) {
705         if (ret == QIO_CHANNEL_ERR_BLOCK) {
706             ret = 0;
707         } else {
708             tcp_chr_disconnect(chr);
709             goto end;
710         }
711     }
712     init->buflen -= ret;
713 
714     if (init->buflen == 0) {
715         tcp_chr_connect(chr);
716         goto end;
717     }
718 
719     memmove(init->buf, init->buf + ret, init->buflen);
720 
721     return G_SOURCE_CONTINUE;
722 
723 end:
724     g_free(s->telnet_init);
725     s->telnet_init = NULL;
726     g_source_unref(s->telnet_source);
727     s->telnet_source = NULL;
728     return G_SOURCE_REMOVE;
729 }
730 
731 static void tcp_chr_telnet_init(Chardev *chr)
732 {
733     SocketChardev *s = SOCKET_CHARDEV(chr);
734     TCPChardevTelnetInit *init;
735     size_t n = 0;
736 
737     /* Destroy existing task */
738     tcp_chr_telnet_destroy(s);
739 
740     if (s->telnet_init) {
741         /* We are possibly during a handshake already */
742         goto cont;
743     }
744 
745     s->telnet_init = g_new0(TCPChardevTelnetInit, 1);
746     init = s->telnet_init;
747 
748 #define IACSET(x, a, b, c)                      \
749     do {                                        \
750         x[n++] = a;                             \
751         x[n++] = b;                             \
752         x[n++] = c;                             \
753     } while (0)
754 
755     if (!s->is_tn3270) {
756         init->buflen = 12;
757         /* Prep the telnet negotion to put telnet in binary,
758          * no echo, single char mode */
759         IACSET(init->buf, 0xff, 0xfb, 0x01);  /* IAC WILL ECHO */
760         IACSET(init->buf, 0xff, 0xfb, 0x03);  /* IAC WILL Suppress go ahead */
761         IACSET(init->buf, 0xff, 0xfb, 0x00);  /* IAC WILL Binary */
762         IACSET(init->buf, 0xff, 0xfd, 0x00);  /* IAC DO Binary */
763     } else {
764         init->buflen = 21;
765         /* Prep the TN3270 negotion based on RFC1576 */
766         IACSET(init->buf, 0xff, 0xfd, 0x19);  /* IAC DO EOR */
767         IACSET(init->buf, 0xff, 0xfb, 0x19);  /* IAC WILL EOR */
768         IACSET(init->buf, 0xff, 0xfd, 0x00);  /* IAC DO BINARY */
769         IACSET(init->buf, 0xff, 0xfb, 0x00);  /* IAC WILL BINARY */
770         IACSET(init->buf, 0xff, 0xfd, 0x18);  /* IAC DO TERMINAL TYPE */
771         IACSET(init->buf, 0xff, 0xfa, 0x18);  /* IAC SB TERMINAL TYPE */
772         IACSET(init->buf, 0x01, 0xff, 0xf0);  /* SEND IAC SE */
773     }
774 
775 #undef IACSET
776 
777 cont:
778     s->telnet_source = qio_channel_add_watch_source(s->ioc, G_IO_OUT,
779                                                     tcp_chr_telnet_init_io,
780                                                     s, NULL,
781                                                     chr->gcontext);
782 }
783 
784 
785 static void tcp_chr_websock_handshake(QIOTask *task, gpointer user_data)
786 {
787     Chardev *chr = user_data;
788     SocketChardev *s = user_data;
789 
790     if (qio_task_propagate_error(task, NULL)) {
791         tcp_chr_disconnect(chr);
792     } else {
793         if (s->do_telnetopt) {
794             tcp_chr_telnet_init(chr);
795         } else {
796             tcp_chr_connect(chr);
797         }
798     }
799 }
800 
801 
802 static void tcp_chr_websock_init(Chardev *chr)
803 {
804     SocketChardev *s = SOCKET_CHARDEV(chr);
805     QIOChannelWebsock *wioc = NULL;
806     gchar *name;
807 
808     wioc = qio_channel_websock_new_server(s->ioc);
809 
810     name = g_strdup_printf("chardev-websocket-server-%s", chr->label);
811     qio_channel_set_name(QIO_CHANNEL(wioc), name);
812     g_free(name);
813     object_unref(OBJECT(s->ioc));
814     s->ioc = QIO_CHANNEL(wioc);
815 
816     qio_channel_websock_handshake(wioc, tcp_chr_websock_handshake, chr, NULL);
817 }
818 
819 
820 static void tcp_chr_tls_handshake(QIOTask *task,
821                                   gpointer user_data)
822 {
823     Chardev *chr = user_data;
824     SocketChardev *s = user_data;
825 
826     if (qio_task_propagate_error(task, NULL)) {
827         tcp_chr_disconnect(chr);
828     } else {
829         if (s->is_websock) {
830             tcp_chr_websock_init(chr);
831         } else if (s->do_telnetopt) {
832             tcp_chr_telnet_init(chr);
833         } else {
834             tcp_chr_connect(chr);
835         }
836     }
837 }
838 
839 
840 static void tcp_chr_tls_init(Chardev *chr)
841 {
842     SocketChardev *s = SOCKET_CHARDEV(chr);
843     QIOChannelTLS *tioc;
844     gchar *name;
845 
846     if (s->is_listen) {
847         tioc = qio_channel_tls_new_server(
848             s->ioc, s->tls_creds,
849             s->tls_authz,
850             NULL);
851     } else {
852         tioc = qio_channel_tls_new_client(
853             s->ioc, s->tls_creds,
854             s->addr->u.inet.host,
855             NULL);
856     }
857     if (tioc == NULL) {
858         tcp_chr_disconnect(chr);
859         return;
860     }
861     name = g_strdup_printf("chardev-tls-%s-%s",
862                            s->is_listen ? "server" : "client",
863                            chr->label);
864     qio_channel_set_name(QIO_CHANNEL(tioc), name);
865     g_free(name);
866     object_unref(OBJECT(s->ioc));
867     s->ioc = QIO_CHANNEL(tioc);
868 
869     qio_channel_tls_handshake(tioc,
870                               tcp_chr_tls_handshake,
871                               chr,
872                               NULL,
873                               chr->gcontext);
874 }
875 
876 
877 static void tcp_chr_set_client_ioc_name(Chardev *chr,
878                                         QIOChannelSocket *sioc)
879 {
880     SocketChardev *s = SOCKET_CHARDEV(chr);
881     char *name;
882     name = g_strdup_printf("chardev-tcp-%s-%s",
883                            s->is_listen ? "server" : "client",
884                            chr->label);
885     qio_channel_set_name(QIO_CHANNEL(sioc), name);
886     g_free(name);
887 
888 }
889 
890 static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc)
891 {
892     SocketChardev *s = SOCKET_CHARDEV(chr);
893 
894     if (s->state != TCP_CHARDEV_STATE_CONNECTING) {
895         return -1;
896     }
897 
898     s->ioc = QIO_CHANNEL(sioc);
899     object_ref(OBJECT(sioc));
900     s->sioc = sioc;
901     object_ref(OBJECT(sioc));
902 
903     qio_channel_set_blocking(s->ioc, false, NULL);
904 
905     if (s->do_nodelay) {
906         qio_channel_set_delay(s->ioc, false);
907     }
908     if (s->listener) {
909         qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
910                                               NULL, chr->gcontext);
911     }
912 
913     if (s->tls_creds) {
914         tcp_chr_tls_init(chr);
915     } else if (s->is_websock) {
916         tcp_chr_websock_init(chr);
917     } else if (s->do_telnetopt) {
918         tcp_chr_telnet_init(chr);
919     } else {
920         tcp_chr_connect(chr);
921     }
922 
923     return 0;
924 }
925 
926 
927 static int tcp_chr_add_client(Chardev *chr, int fd)
928 {
929     int ret;
930     QIOChannelSocket *sioc;
931     SocketChardev *s = SOCKET_CHARDEV(chr);
932 
933     if (s->state != TCP_CHARDEV_STATE_DISCONNECTED) {
934         return -1;
935     }
936 
937     sioc = qio_channel_socket_new_fd(fd, NULL);
938     if (!sioc) {
939         return -1;
940     }
941     tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
942     tcp_chr_set_client_ioc_name(chr, sioc);
943     yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
944                            yank_generic_iochannel,
945                            QIO_CHANNEL(sioc));
946     ret = tcp_chr_new_client(chr, sioc);
947     object_unref(OBJECT(sioc));
948     return ret;
949 }
950 
951 static void tcp_chr_accept(QIONetListener *listener,
952                            QIOChannelSocket *cioc,
953                            void *opaque)
954 {
955     Chardev *chr = CHARDEV(opaque);
956     SocketChardev *s = SOCKET_CHARDEV(chr);
957 
958     tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
959     tcp_chr_set_client_ioc_name(chr, cioc);
960     yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
961                            yank_generic_iochannel,
962                            QIO_CHANNEL(cioc));
963     tcp_chr_new_client(chr, cioc);
964 }
965 
966 
967 static int tcp_chr_connect_client_sync(Chardev *chr, Error **errp)
968 {
969     SocketChardev *s = SOCKET_CHARDEV(chr);
970     QIOChannelSocket *sioc = qio_channel_socket_new();
971     tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
972     tcp_chr_set_client_ioc_name(chr, sioc);
973     if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) {
974         tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
975         object_unref(OBJECT(sioc));
976         return -1;
977     }
978     yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
979                            yank_generic_iochannel,
980                            QIO_CHANNEL(sioc));
981     tcp_chr_new_client(chr, sioc);
982     object_unref(OBJECT(sioc));
983     return 0;
984 }
985 
986 
987 static void tcp_chr_accept_server_sync(Chardev *chr)
988 {
989     SocketChardev *s = SOCKET_CHARDEV(chr);
990     QIOChannelSocket *sioc;
991     info_report("QEMU waiting for connection on: %s",
992                 chr->filename);
993     tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
994     sioc = qio_net_listener_wait_client(s->listener);
995     tcp_chr_set_client_ioc_name(chr, sioc);
996     yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
997                            yank_generic_iochannel,
998                            QIO_CHANNEL(sioc));
999     tcp_chr_new_client(chr, sioc);
1000     object_unref(OBJECT(sioc));
1001 }
1002 
1003 
1004 static int tcp_chr_wait_connected(Chardev *chr, Error **errp)
1005 {
1006     SocketChardev *s = SOCKET_CHARDEV(chr);
1007     const char *opts[] = { "telnet", "tn3270", "websock", "tls-creds" };
1008     bool optset[] = { s->is_telnet, s->is_tn3270, s->is_websock, s->tls_creds };
1009     size_t i;
1010 
1011     QEMU_BUILD_BUG_ON(G_N_ELEMENTS(opts) != G_N_ELEMENTS(optset));
1012     for (i = 0; i < G_N_ELEMENTS(opts); i++) {
1013         if (optset[i]) {
1014             error_setg(errp,
1015                        "'%s' option is incompatible with waiting for "
1016                        "connection completion", opts[i]);
1017             return -1;
1018         }
1019     }
1020 
1021     tcp_chr_reconn_timer_cancel(s);
1022 
1023     /*
1024      * We expect states to be as follows:
1025      *
1026      *  - server
1027      *    - wait   -> CONNECTED
1028      *    - nowait -> DISCONNECTED
1029      *  - client
1030      *    - reconnect == 0 -> CONNECTED
1031      *    - reconnect != 0 -> CONNECTING
1032      *
1033      */
1034     if (s->state == TCP_CHARDEV_STATE_CONNECTING) {
1035         if (!s->connect_task) {
1036             error_setg(errp,
1037                        "Unexpected 'connecting' state without connect task "
1038                        "while waiting for connection completion");
1039             return -1;
1040         }
1041         /*
1042          * tcp_chr_wait_connected should only ever be run from the
1043          * main loop thread associated with chr->gcontext, otherwise
1044          * qio_task_wait_thread has a dangerous race condition with
1045          * free'ing of the s->connect_task object.
1046          *
1047          * Acquiring the main context doesn't 100% prove we're in
1048          * the main loop thread, but it does at least guarantee
1049          * that the main loop won't be executed by another thread
1050          * avoiding the race condition with the task idle callback.
1051          */
1052         g_main_context_acquire(chr->gcontext);
1053         qio_task_wait_thread(s->connect_task);
1054         g_main_context_release(chr->gcontext);
1055 
1056         /*
1057          * The completion callback (qemu_chr_socket_connected) for
1058          * s->connect_task should have set this to NULL by the time
1059          * qio_task_wait_thread has returned.
1060          */
1061         assert(!s->connect_task);
1062 
1063         /*
1064          * NB we are *not* guaranteed to have "s->state == ..CONNECTED"
1065          * at this point as this first connect may be failed, so
1066          * allow the next loop to run regardless.
1067          */
1068     }
1069 
1070     while (s->state != TCP_CHARDEV_STATE_CONNECTED) {
1071         if (s->is_listen) {
1072             tcp_chr_accept_server_sync(chr);
1073         } else {
1074             Error *err = NULL;
1075             if (tcp_chr_connect_client_sync(chr, &err) < 0) {
1076                 if (s->reconnect_time) {
1077                     error_free(err);
1078                     g_usleep(s->reconnect_time * 1000ULL * 1000ULL);
1079                 } else {
1080                     error_propagate(errp, err);
1081                     return -1;
1082                 }
1083             }
1084         }
1085     }
1086 
1087     return 0;
1088 }
1089 
1090 static void char_socket_finalize(Object *obj)
1091 {
1092     Chardev *chr = CHARDEV(obj);
1093     SocketChardev *s = SOCKET_CHARDEV(obj);
1094 
1095     tcp_chr_free_connection(chr);
1096     tcp_chr_reconn_timer_cancel(s);
1097     qapi_free_SocketAddress(s->addr);
1098     tcp_chr_telnet_destroy(s);
1099     g_free(s->telnet_init);
1100     if (s->listener) {
1101         qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
1102                                               NULL, chr->gcontext);
1103         object_unref(OBJECT(s->listener));
1104     }
1105     if (s->tls_creds) {
1106         object_unref(OBJECT(s->tls_creds));
1107     }
1108     g_free(s->tls_authz);
1109     if (s->registered_yank) {
1110         yank_unregister_instance(CHARDEV_YANK_INSTANCE(chr->label));
1111     }
1112 
1113     qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1114 }
1115 
1116 static void qemu_chr_socket_connected(QIOTask *task, void *opaque)
1117 {
1118     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
1119     Chardev *chr = CHARDEV(opaque);
1120     SocketChardev *s = SOCKET_CHARDEV(chr);
1121     Error *err = NULL;
1122 
1123     s->connect_task = NULL;
1124 
1125     if (qio_task_propagate_error(task, &err)) {
1126         tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
1127         yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label),
1128                                  yank_generic_iochannel,
1129                                  QIO_CHANNEL(sioc));
1130         check_report_connect_error(chr, err);
1131         goto cleanup;
1132     }
1133 
1134     s->connect_err_reported = false;
1135     tcp_chr_new_client(chr, sioc);
1136 
1137 cleanup:
1138     object_unref(OBJECT(sioc));
1139 }
1140 
1141 
1142 static void tcp_chr_connect_client_task(QIOTask *task,
1143                                         gpointer opaque)
1144 {
1145     QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
1146     SocketAddress *addr = opaque;
1147     Error *err = NULL;
1148 
1149     qio_channel_socket_connect_sync(ioc, addr, &err);
1150 
1151     qio_task_set_error(task, err);
1152 }
1153 
1154 
1155 static void tcp_chr_connect_client_async(Chardev *chr)
1156 {
1157     SocketChardev *s = SOCKET_CHARDEV(chr);
1158     QIOChannelSocket *sioc;
1159 
1160     tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
1161     sioc = qio_channel_socket_new();
1162     tcp_chr_set_client_ioc_name(chr, sioc);
1163     yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
1164                            yank_generic_iochannel,
1165                            QIO_CHANNEL(sioc));
1166     /*
1167      * Normally code would use the qio_channel_socket_connect_async
1168      * method which uses a QIOTask + qio_task_set_error internally
1169      * to avoid blocking. The tcp_chr_wait_connected method, however,
1170      * needs a way to synchronize with completion of the background
1171      * connect task which can't be done with the QIOChannelSocket
1172      * async APIs. Thus we must use QIOTask directly to implement
1173      * the non-blocking concept locally.
1174      */
1175     s->connect_task = qio_task_new(OBJECT(sioc),
1176                                    qemu_chr_socket_connected,
1177                                    object_ref(OBJECT(chr)),
1178                                    (GDestroyNotify)object_unref);
1179     qio_task_run_in_thread(s->connect_task,
1180                            tcp_chr_connect_client_task,
1181                            s->addr,
1182                            NULL,
1183                            chr->gcontext);
1184 }
1185 
1186 static gboolean socket_reconnect_timeout(gpointer opaque)
1187 {
1188     Chardev *chr = CHARDEV(opaque);
1189     SocketChardev *s = SOCKET_CHARDEV(opaque);
1190 
1191     qemu_mutex_lock(&chr->chr_write_lock);
1192     g_source_unref(s->reconnect_timer);
1193     s->reconnect_timer = NULL;
1194     qemu_mutex_unlock(&chr->chr_write_lock);
1195 
1196     if (chr->be_open) {
1197         return false;
1198     }
1199 
1200     tcp_chr_connect_client_async(chr);
1201 
1202     return false;
1203 }
1204 
1205 
1206 static int qmp_chardev_open_socket_server(Chardev *chr,
1207                                           bool is_telnet,
1208                                           bool is_waitconnect,
1209                                           Error **errp)
1210 {
1211     SocketChardev *s = SOCKET_CHARDEV(chr);
1212     char *name;
1213     if (is_telnet) {
1214         s->do_telnetopt = 1;
1215     }
1216     s->listener = qio_net_listener_new();
1217 
1218     name = g_strdup_printf("chardev-tcp-listener-%s", chr->label);
1219     qio_net_listener_set_name(s->listener, name);
1220     g_free(name);
1221 
1222     if (qio_net_listener_open_sync(s->listener, s->addr, 1, errp) < 0) {
1223         object_unref(OBJECT(s->listener));
1224         s->listener = NULL;
1225         return -1;
1226     }
1227 
1228     qapi_free_SocketAddress(s->addr);
1229     s->addr = socket_local_address(s->listener->sioc[0]->fd, errp);
1230     update_disconnected_filename(s);
1231 
1232     if (is_waitconnect) {
1233         tcp_chr_accept_server_sync(chr);
1234     } else {
1235         qio_net_listener_set_client_func_full(s->listener,
1236                                               tcp_chr_accept,
1237                                               chr, NULL,
1238                                               chr->gcontext);
1239     }
1240 
1241     return 0;
1242 }
1243 
1244 
1245 static int qmp_chardev_open_socket_client(Chardev *chr,
1246                                           int64_t reconnect,
1247                                           Error **errp)
1248 {
1249     SocketChardev *s = SOCKET_CHARDEV(chr);
1250 
1251     if (reconnect > 0) {
1252         s->reconnect_time = reconnect;
1253         tcp_chr_connect_client_async(chr);
1254         return 0;
1255     } else {
1256         return tcp_chr_connect_client_sync(chr, errp);
1257     }
1258 }
1259 
1260 
1261 static bool qmp_chardev_validate_socket(ChardevSocket *sock,
1262                                         SocketAddress *addr,
1263                                         Error **errp)
1264 {
1265     /* Validate any options which have a dependency on address type */
1266     switch (addr->type) {
1267     case SOCKET_ADDRESS_TYPE_FD:
1268         if (sock->has_reconnect) {
1269             error_setg(errp,
1270                        "'reconnect' option is incompatible with "
1271                        "'fd' address type");
1272             return false;
1273         }
1274         if (sock->has_tls_creds &&
1275             !(sock->has_server && sock->server)) {
1276             error_setg(errp,
1277                        "'tls_creds' option is incompatible with "
1278                        "'fd' address type as client");
1279             return false;
1280         }
1281         break;
1282 
1283     case SOCKET_ADDRESS_TYPE_UNIX:
1284         if (sock->has_tls_creds) {
1285             error_setg(errp,
1286                        "'tls_creds' option is incompatible with "
1287                        "'unix' address type");
1288             return false;
1289         }
1290         break;
1291 
1292     case SOCKET_ADDRESS_TYPE_INET:
1293         break;
1294 
1295     case SOCKET_ADDRESS_TYPE_VSOCK:
1296         if (sock->has_tls_creds) {
1297             error_setg(errp,
1298                        "'tls_creds' option is incompatible with "
1299                        "'vsock' address type");
1300             return false;
1301         }
1302 
1303     default:
1304         break;
1305     }
1306 
1307     if (sock->has_tls_authz && !sock->has_tls_creds) {
1308         error_setg(errp, "'tls_authz' option requires 'tls_creds' option");
1309         return false;
1310     }
1311 
1312     /* Validate any options which have a dependancy on client vs server */
1313     if (!sock->has_server || sock->server) {
1314         if (sock->has_reconnect) {
1315             error_setg(errp,
1316                        "'reconnect' option is incompatible with "
1317                        "socket in server listen mode");
1318             return false;
1319         }
1320     } else {
1321         if (sock->has_websocket && sock->websocket) {
1322             error_setg(errp, "%s", "Websocket client is not implemented");
1323             return false;
1324         }
1325         if (sock->has_wait) {
1326             warn_report("'wait' option is deprecated with "
1327                         "socket in client connect mode");
1328             if (sock->wait) {
1329                 error_setg(errp, "%s",
1330                            "'wait' option is incompatible with "
1331                            "socket in client connect mode");
1332                 return false;
1333             }
1334         }
1335     }
1336 
1337     return true;
1338 }
1339 
1340 
1341 static void qmp_chardev_open_socket(Chardev *chr,
1342                                     ChardevBackend *backend,
1343                                     bool *be_opened,
1344                                     Error **errp)
1345 {
1346     SocketChardev *s = SOCKET_CHARDEV(chr);
1347     ChardevSocket *sock = backend->u.socket.data;
1348     bool do_nodelay     = sock->has_nodelay ? sock->nodelay : false;
1349     bool is_listen      = sock->has_server  ? sock->server  : true;
1350     bool is_telnet      = sock->has_telnet  ? sock->telnet  : false;
1351     bool is_tn3270      = sock->has_tn3270  ? sock->tn3270  : false;
1352     bool is_waitconnect = sock->has_wait    ? sock->wait    : false;
1353     bool is_websock     = sock->has_websocket ? sock->websocket : false;
1354     int64_t reconnect   = sock->has_reconnect ? sock->reconnect : 0;
1355     SocketAddress *addr;
1356 
1357     s->is_listen = is_listen;
1358     s->is_telnet = is_telnet;
1359     s->is_tn3270 = is_tn3270;
1360     s->is_websock = is_websock;
1361     s->do_nodelay = do_nodelay;
1362     if (sock->tls_creds) {
1363         Object *creds;
1364         creds = object_resolve_path_component(
1365             object_get_objects_root(), sock->tls_creds);
1366         if (!creds) {
1367             error_setg(errp, "No TLS credentials with id '%s'",
1368                        sock->tls_creds);
1369             return;
1370         }
1371         s->tls_creds = (QCryptoTLSCreds *)
1372             object_dynamic_cast(creds,
1373                                 TYPE_QCRYPTO_TLS_CREDS);
1374         if (!s->tls_creds) {
1375             error_setg(errp, "Object with id '%s' is not TLS credentials",
1376                        sock->tls_creds);
1377             return;
1378         }
1379         object_ref(OBJECT(s->tls_creds));
1380         if (is_listen) {
1381             if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
1382                 error_setg(errp, "%s",
1383                            "Expected TLS credentials for server endpoint");
1384                 return;
1385             }
1386         } else {
1387             if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
1388                 error_setg(errp, "%s",
1389                            "Expected TLS credentials for client endpoint");
1390                 return;
1391             }
1392         }
1393     }
1394     s->tls_authz = g_strdup(sock->tls_authz);
1395 
1396     s->addr = addr = socket_address_flatten(sock->addr);
1397 
1398     if (!qmp_chardev_validate_socket(sock, addr, errp)) {
1399         return;
1400     }
1401 
1402     qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE);
1403     /* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */
1404     if (addr->type == SOCKET_ADDRESS_TYPE_UNIX) {
1405         qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS);
1406     }
1407 
1408     if (!yank_register_instance(CHARDEV_YANK_INSTANCE(chr->label), errp)) {
1409         return;
1410     }
1411     s->registered_yank = true;
1412 
1413     /* be isn't opened until we get a connection */
1414     *be_opened = false;
1415 
1416     update_disconnected_filename(s);
1417 
1418     if (s->is_listen) {
1419         if (qmp_chardev_open_socket_server(chr, is_telnet || is_tn3270,
1420                                            is_waitconnect, errp) < 0) {
1421             return;
1422         }
1423     } else {
1424         if (qmp_chardev_open_socket_client(chr, reconnect, errp) < 0) {
1425             return;
1426         }
1427     }
1428 }
1429 
1430 static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
1431                                   Error **errp)
1432 {
1433     const char *path = qemu_opt_get(opts, "path");
1434     const char *host = qemu_opt_get(opts, "host");
1435     const char *port = qemu_opt_get(opts, "port");
1436     const char *fd = qemu_opt_get(opts, "fd");
1437 #ifdef CONFIG_LINUX
1438     bool tight = qemu_opt_get_bool(opts, "tight", true);
1439     bool abstract = qemu_opt_get_bool(opts, "abstract", false);
1440 #endif
1441     SocketAddressLegacy *addr;
1442     ChardevSocket *sock;
1443 
1444     if ((!!path + !!fd + !!host) != 1) {
1445         error_setg(errp,
1446                    "Exactly one of 'path', 'fd' or 'host' required");
1447         return;
1448     }
1449 
1450     if (host && !port) {
1451         error_setg(errp, "chardev: socket: no port given");
1452         return;
1453     }
1454 
1455     backend->type = CHARDEV_BACKEND_KIND_SOCKET;
1456     sock = backend->u.socket.data = g_new0(ChardevSocket, 1);
1457     qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock));
1458 
1459     sock->has_nodelay = qemu_opt_get(opts, "delay");
1460     sock->nodelay = !qemu_opt_get_bool(opts, "delay", true);
1461     /*
1462      * We have different default to QMP for 'server', hence
1463      * we can't just check for existence of 'server'
1464      */
1465     sock->has_server = true;
1466     sock->server = qemu_opt_get_bool(opts, "server", false);
1467     sock->has_telnet = qemu_opt_get(opts, "telnet");
1468     sock->telnet = qemu_opt_get_bool(opts, "telnet", false);
1469     sock->has_tn3270 = qemu_opt_get(opts, "tn3270");
1470     sock->tn3270 = qemu_opt_get_bool(opts, "tn3270", false);
1471     sock->has_websocket = qemu_opt_get(opts, "websocket");
1472     sock->websocket = qemu_opt_get_bool(opts, "websocket", false);
1473     /*
1474      * We have different default to QMP for 'wait' when 'server'
1475      * is set, hence we can't just check for existence of 'wait'
1476      */
1477     sock->has_wait = qemu_opt_find(opts, "wait") || sock->server;
1478     sock->wait = qemu_opt_get_bool(opts, "wait", true);
1479     sock->has_reconnect = qemu_opt_find(opts, "reconnect");
1480     sock->reconnect = qemu_opt_get_number(opts, "reconnect", 0);
1481     sock->has_tls_creds = qemu_opt_get(opts, "tls-creds");
1482     sock->tls_creds = g_strdup(qemu_opt_get(opts, "tls-creds"));
1483     sock->has_tls_authz = qemu_opt_get(opts, "tls-authz");
1484     sock->tls_authz = g_strdup(qemu_opt_get(opts, "tls-authz"));
1485 
1486     addr = g_new0(SocketAddressLegacy, 1);
1487     if (path) {
1488         UnixSocketAddress *q_unix;
1489         addr->type = SOCKET_ADDRESS_LEGACY_KIND_UNIX;
1490         q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
1491         q_unix->path = g_strdup(path);
1492 #ifdef CONFIG_LINUX
1493         q_unix->has_tight = true;
1494         q_unix->tight = tight;
1495         q_unix->has_abstract = true;
1496         q_unix->abstract = abstract;
1497 #endif
1498     } else if (host) {
1499         addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET;
1500         addr->u.inet.data = g_new(InetSocketAddress, 1);
1501         *addr->u.inet.data = (InetSocketAddress) {
1502             .host = g_strdup(host),
1503             .port = g_strdup(port),
1504             .has_to = qemu_opt_get(opts, "to"),
1505             .to = qemu_opt_get_number(opts, "to", 0),
1506             .has_ipv4 = qemu_opt_get(opts, "ipv4"),
1507             .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0),
1508             .has_ipv6 = qemu_opt_get(opts, "ipv6"),
1509             .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
1510         };
1511     } else if (fd) {
1512         addr->type = SOCKET_ADDRESS_LEGACY_KIND_FD;
1513         addr->u.fd.data = g_new(String, 1);
1514         addr->u.fd.data->str = g_strdup(fd);
1515     } else {
1516         g_assert_not_reached();
1517     }
1518     sock->addr = addr;
1519 }
1520 
1521 static void
1522 char_socket_get_addr(Object *obj, Visitor *v, const char *name,
1523                      void *opaque, Error **errp)
1524 {
1525     SocketChardev *s = SOCKET_CHARDEV(obj);
1526 
1527     visit_type_SocketAddress(v, name, &s->addr, errp);
1528 }
1529 
1530 static bool
1531 char_socket_get_connected(Object *obj, Error **errp)
1532 {
1533     SocketChardev *s = SOCKET_CHARDEV(obj);
1534 
1535     return s->state == TCP_CHARDEV_STATE_CONNECTED;
1536 }
1537 
1538 static void char_socket_class_init(ObjectClass *oc, void *data)
1539 {
1540     ChardevClass *cc = CHARDEV_CLASS(oc);
1541 
1542     cc->parse = qemu_chr_parse_socket;
1543     cc->open = qmp_chardev_open_socket;
1544     cc->chr_wait_connected = tcp_chr_wait_connected;
1545     cc->chr_write = tcp_chr_write;
1546     cc->chr_sync_read = tcp_chr_sync_read;
1547     cc->chr_disconnect = tcp_chr_disconnect;
1548     cc->get_msgfds = tcp_get_msgfds;
1549     cc->set_msgfds = tcp_set_msgfds;
1550     cc->chr_add_client = tcp_chr_add_client;
1551     cc->chr_add_watch = tcp_chr_add_watch;
1552     cc->chr_update_read_handler = tcp_chr_update_read_handler;
1553 
1554     object_class_property_add(oc, "addr", "SocketAddress",
1555                               char_socket_get_addr, NULL,
1556                               NULL, NULL);
1557 
1558     object_class_property_add_bool(oc, "connected", char_socket_get_connected,
1559                                    NULL);
1560 }
1561 
1562 static const TypeInfo char_socket_type_info = {
1563     .name = TYPE_CHARDEV_SOCKET,
1564     .parent = TYPE_CHARDEV,
1565     .instance_size = sizeof(SocketChardev),
1566     .instance_finalize = char_socket_finalize,
1567     .class_init = char_socket_class_init,
1568 };
1569 
1570 static void register_types(void)
1571 {
1572     type_register_static(&char_socket_type_info);
1573 }
1574 
1575 type_init(register_types);
1576