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