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