xref: /openbmc/qemu/chardev/char-socket.c (revision dc5bd18f)
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 }
712 
713 
714 static void tcp_chr_set_client_ioc_name(Chardev *chr,
715                                         QIOChannelSocket *sioc)
716 {
717     SocketChardev *s = SOCKET_CHARDEV(chr);
718     char *name;
719     name = g_strdup_printf("chardev-tcp-%s-%s",
720                            s->is_listen ? "server" : "client",
721                            chr->label);
722     qio_channel_set_name(QIO_CHANNEL(sioc), name);
723     g_free(name);
724 
725 }
726 
727 static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc)
728 {
729     SocketChardev *s = SOCKET_CHARDEV(chr);
730 
731     if (s->ioc != NULL) {
732         return -1;
733     }
734 
735     s->ioc = QIO_CHANNEL(sioc);
736     object_ref(OBJECT(sioc));
737     s->sioc = sioc;
738     object_ref(OBJECT(sioc));
739 
740     qio_channel_set_blocking(s->ioc, false, NULL);
741 
742     if (s->do_nodelay) {
743         qio_channel_set_delay(s->ioc, false);
744     }
745     if (s->listener) {
746         qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL);
747     }
748 
749     if (s->tls_creds) {
750         tcp_chr_tls_init(chr);
751     } else {
752         if (s->do_telnetopt) {
753             tcp_chr_telnet_init(chr);
754         } else {
755             tcp_chr_connect(chr);
756         }
757     }
758 
759     return 0;
760 }
761 
762 
763 static int tcp_chr_add_client(Chardev *chr, int fd)
764 {
765     int ret;
766     QIOChannelSocket *sioc;
767 
768     sioc = qio_channel_socket_new_fd(fd, NULL);
769     if (!sioc) {
770         return -1;
771     }
772     tcp_chr_set_client_ioc_name(chr, sioc);
773     ret = tcp_chr_new_client(chr, sioc);
774     object_unref(OBJECT(sioc));
775     return ret;
776 }
777 
778 static void tcp_chr_accept(QIONetListener *listener,
779                            QIOChannelSocket *cioc,
780                            void *opaque)
781 {
782     Chardev *chr = CHARDEV(opaque);
783 
784     tcp_chr_set_client_ioc_name(chr, cioc);
785     tcp_chr_new_client(chr, cioc);
786 }
787 
788 static int tcp_chr_wait_connected(Chardev *chr, Error **errp)
789 {
790     SocketChardev *s = SOCKET_CHARDEV(chr);
791     QIOChannelSocket *sioc;
792 
793     /* It can't wait on s->connected, since it is set asynchronously
794      * in TLS and telnet cases, only wait for an accepted socket */
795     while (!s->ioc) {
796         if (s->is_listen) {
797             info_report("QEMU waiting for connection on: %s",
798                         chr->filename);
799             sioc = qio_net_listener_wait_client(s->listener);
800             tcp_chr_set_client_ioc_name(chr, sioc);
801             tcp_chr_new_client(chr, sioc);
802             object_unref(OBJECT(sioc));
803         } else {
804             sioc = qio_channel_socket_new();
805             tcp_chr_set_client_ioc_name(chr, sioc);
806             if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) {
807                 object_unref(OBJECT(sioc));
808                 return -1;
809             }
810             tcp_chr_new_client(chr, sioc);
811             object_unref(OBJECT(sioc));
812         }
813     }
814 
815     return 0;
816 }
817 
818 static void char_socket_finalize(Object *obj)
819 {
820     Chardev *chr = CHARDEV(obj);
821     SocketChardev *s = SOCKET_CHARDEV(obj);
822 
823     tcp_chr_free_connection(chr);
824     tcp_chr_reconn_timer_cancel(s);
825     qapi_free_SocketAddress(s->addr);
826     if (s->listener) {
827         qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL);
828         object_unref(OBJECT(s->listener));
829     }
830     if (s->tls_creds) {
831         object_unref(OBJECT(s->tls_creds));
832     }
833 
834     qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
835 }
836 
837 static void qemu_chr_socket_connected(QIOTask *task, void *opaque)
838 {
839     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
840     Chardev *chr = CHARDEV(opaque);
841     SocketChardev *s = SOCKET_CHARDEV(chr);
842     Error *err = NULL;
843 
844     if (qio_task_propagate_error(task, &err)) {
845         check_report_connect_error(chr, err);
846         error_free(err);
847         goto cleanup;
848     }
849 
850     s->connect_err_reported = false;
851     tcp_chr_new_client(chr, sioc);
852 
853 cleanup:
854     object_unref(OBJECT(sioc));
855 }
856 
857 static gboolean socket_reconnect_timeout(gpointer opaque)
858 {
859     Chardev *chr = CHARDEV(opaque);
860     SocketChardev *s = SOCKET_CHARDEV(opaque);
861     QIOChannelSocket *sioc;
862 
863     g_source_unref(s->reconnect_timer);
864     s->reconnect_timer = NULL;
865 
866     if (chr->be_open) {
867         return false;
868     }
869 
870     sioc = qio_channel_socket_new();
871     tcp_chr_set_client_ioc_name(chr, sioc);
872     qio_channel_socket_connect_async(sioc, s->addr,
873                                      qemu_chr_socket_connected,
874                                      chr, NULL);
875 
876     return false;
877 }
878 
879 static void qmp_chardev_open_socket(Chardev *chr,
880                                     ChardevBackend *backend,
881                                     bool *be_opened,
882                                     Error **errp)
883 {
884     SocketChardev *s = SOCKET_CHARDEV(chr);
885     ChardevSocket *sock = backend->u.socket.data;
886     bool do_nodelay     = sock->has_nodelay ? sock->nodelay : false;
887     bool is_listen      = sock->has_server  ? sock->server  : true;
888     bool is_telnet      = sock->has_telnet  ? sock->telnet  : false;
889     bool is_tn3270      = sock->has_tn3270  ? sock->tn3270  : false;
890     bool is_waitconnect = sock->has_wait    ? sock->wait    : false;
891     int64_t reconnect   = sock->has_reconnect ? sock->reconnect : 0;
892     QIOChannelSocket *sioc = NULL;
893     SocketAddress *addr;
894 
895     s->is_listen = is_listen;
896     s->is_telnet = is_telnet;
897     s->is_tn3270 = is_tn3270;
898     s->do_nodelay = do_nodelay;
899     if (sock->tls_creds) {
900         Object *creds;
901         creds = object_resolve_path_component(
902             object_get_objects_root(), sock->tls_creds);
903         if (!creds) {
904             error_setg(errp, "No TLS credentials with id '%s'",
905                        sock->tls_creds);
906             goto error;
907         }
908         s->tls_creds = (QCryptoTLSCreds *)
909             object_dynamic_cast(creds,
910                                 TYPE_QCRYPTO_TLS_CREDS);
911         if (!s->tls_creds) {
912             error_setg(errp, "Object with id '%s' is not TLS credentials",
913                        sock->tls_creds);
914             goto error;
915         }
916         object_ref(OBJECT(s->tls_creds));
917         if (is_listen) {
918             if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
919                 error_setg(errp, "%s",
920                            "Expected TLS credentials for server endpoint");
921                 goto error;
922             }
923         } else {
924             if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
925                 error_setg(errp, "%s",
926                            "Expected TLS credentials for client endpoint");
927                 goto error;
928             }
929         }
930     }
931 
932     s->addr = addr = socket_address_flatten(sock->addr);
933 
934     qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE);
935     /* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */
936     if (addr->type == SOCKET_ADDRESS_TYPE_UNIX) {
937         qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS);
938     }
939 
940     /* be isn't opened until we get a connection */
941     *be_opened = false;
942 
943     update_disconnected_filename(s);
944 
945     if (is_listen) {
946         if (is_telnet || is_tn3270) {
947             s->do_telnetopt = 1;
948         }
949     } else if (reconnect > 0) {
950         s->reconnect_time = reconnect;
951     }
952 
953     if (s->reconnect_time) {
954         sioc = qio_channel_socket_new();
955         tcp_chr_set_client_ioc_name(chr, sioc);
956         qio_channel_socket_connect_async(sioc, s->addr,
957                                          qemu_chr_socket_connected,
958                                          chr, NULL);
959     } else {
960         if (s->is_listen) {
961             char *name;
962             s->listener = qio_net_listener_new();
963 
964             name = g_strdup_printf("chardev-tcp-listener-%s", chr->label);
965             qio_net_listener_set_name(s->listener, name);
966             g_free(name);
967 
968             if (qio_net_listener_open_sync(s->listener, s->addr, errp) < 0) {
969                 object_unref(OBJECT(s->listener));
970                 s->listener = NULL;
971                 goto error;
972             }
973 
974             qapi_free_SocketAddress(s->addr);
975             s->addr = socket_local_address(s->listener->sioc[0]->fd, errp);
976             update_disconnected_filename(s);
977 
978             if (is_waitconnect &&
979                 qemu_chr_wait_connected(chr, errp) < 0) {
980                 return;
981             }
982             if (!s->ioc) {
983                 qio_net_listener_set_client_func(s->listener, tcp_chr_accept,
984                                                  chr, NULL);
985             }
986         } else if (qemu_chr_wait_connected(chr, errp) < 0) {
987             goto error;
988         }
989     }
990 
991     return;
992 
993 error:
994     if (sioc) {
995         object_unref(OBJECT(sioc));
996     }
997 }
998 
999 static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
1000                                   Error **errp)
1001 {
1002     bool is_listen      = qemu_opt_get_bool(opts, "server", false);
1003     bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true);
1004     bool is_telnet      = qemu_opt_get_bool(opts, "telnet", false);
1005     bool is_tn3270      = qemu_opt_get_bool(opts, "tn3270", false);
1006     bool do_nodelay     = !qemu_opt_get_bool(opts, "delay", true);
1007     int64_t reconnect   = qemu_opt_get_number(opts, "reconnect", 0);
1008     const char *path = qemu_opt_get(opts, "path");
1009     const char *host = qemu_opt_get(opts, "host");
1010     const char *port = qemu_opt_get(opts, "port");
1011     const char *tls_creds = qemu_opt_get(opts, "tls-creds");
1012     SocketAddressLegacy *addr;
1013     ChardevSocket *sock;
1014 
1015     backend->type = CHARDEV_BACKEND_KIND_SOCKET;
1016     if (!path) {
1017         if (!host) {
1018             error_setg(errp, "chardev: socket: no host given");
1019             return;
1020         }
1021         if (!port) {
1022             error_setg(errp, "chardev: socket: no port given");
1023             return;
1024         }
1025     } else {
1026         if (tls_creds) {
1027             error_setg(errp, "TLS can only be used over TCP socket");
1028             return;
1029         }
1030     }
1031 
1032     sock = backend->u.socket.data = g_new0(ChardevSocket, 1);
1033     qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock));
1034 
1035     sock->has_nodelay = true;
1036     sock->nodelay = do_nodelay;
1037     sock->has_server = true;
1038     sock->server = is_listen;
1039     sock->has_telnet = true;
1040     sock->telnet = is_telnet;
1041     sock->has_tn3270 = true;
1042     sock->tn3270 = is_tn3270;
1043     sock->has_wait = true;
1044     sock->wait = is_waitconnect;
1045     sock->has_reconnect = true;
1046     sock->reconnect = reconnect;
1047     sock->tls_creds = g_strdup(tls_creds);
1048 
1049     addr = g_new0(SocketAddressLegacy, 1);
1050     if (path) {
1051         UnixSocketAddress *q_unix;
1052         addr->type = SOCKET_ADDRESS_LEGACY_KIND_UNIX;
1053         q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
1054         q_unix->path = g_strdup(path);
1055     } else {
1056         addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET;
1057         addr->u.inet.data = g_new(InetSocketAddress, 1);
1058         *addr->u.inet.data = (InetSocketAddress) {
1059             .host = g_strdup(host),
1060             .port = g_strdup(port),
1061             .has_to = qemu_opt_get(opts, "to"),
1062             .to = qemu_opt_get_number(opts, "to", 0),
1063             .has_ipv4 = qemu_opt_get(opts, "ipv4"),
1064             .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0),
1065             .has_ipv6 = qemu_opt_get(opts, "ipv6"),
1066             .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
1067         };
1068     }
1069     sock->addr = addr;
1070 }
1071 
1072 static void
1073 char_socket_get_addr(Object *obj, Visitor *v, const char *name,
1074                      void *opaque, Error **errp)
1075 {
1076     SocketChardev *s = SOCKET_CHARDEV(obj);
1077 
1078     visit_type_SocketAddress(v, name, &s->addr, errp);
1079 }
1080 
1081 static bool
1082 char_socket_get_connected(Object *obj, Error **errp)
1083 {
1084     SocketChardev *s = SOCKET_CHARDEV(obj);
1085 
1086     return s->connected;
1087 }
1088 
1089 static void char_socket_class_init(ObjectClass *oc, void *data)
1090 {
1091     ChardevClass *cc = CHARDEV_CLASS(oc);
1092 
1093     cc->parse = qemu_chr_parse_socket;
1094     cc->open = qmp_chardev_open_socket;
1095     cc->chr_wait_connected = tcp_chr_wait_connected;
1096     cc->chr_write = tcp_chr_write;
1097     cc->chr_sync_read = tcp_chr_sync_read;
1098     cc->chr_disconnect = tcp_chr_disconnect;
1099     cc->get_msgfds = tcp_get_msgfds;
1100     cc->set_msgfds = tcp_set_msgfds;
1101     cc->chr_add_client = tcp_chr_add_client;
1102     cc->chr_add_watch = tcp_chr_add_watch;
1103     cc->chr_update_read_handler = tcp_chr_update_read_handler;
1104 
1105     object_class_property_add(oc, "addr", "SocketAddress",
1106                               char_socket_get_addr, NULL,
1107                               NULL, NULL, &error_abort);
1108 
1109     object_class_property_add_bool(oc, "connected", char_socket_get_connected,
1110                                    NULL, &error_abort);
1111 }
1112 
1113 static const TypeInfo char_socket_type_info = {
1114     .name = TYPE_CHARDEV_SOCKET,
1115     .parent = TYPE_CHARDEV,
1116     .instance_size = sizeof(SocketChardev),
1117     .instance_finalize = char_socket_finalize,
1118     .class_init = char_socket_class_init,
1119 };
1120 
1121 static void register_types(void)
1122 {
1123     type_register_static(&char_socket_type_info);
1124 }
1125 
1126 type_init(register_types);
1127