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