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