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