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