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