xref: /openbmc/qemu/chardev/char-socket.c (revision b86c6ba6)
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-websock.h"
29 #include "qemu/error-report.h"
30 #include "qemu/module.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 "qemu/yank.h"
36 
37 #include "chardev/char-io.h"
38 #include "chardev/char-socket.h"
39 
40 static gboolean socket_reconnect_timeout(gpointer opaque);
41 static void tcp_chr_telnet_init(Chardev *chr);
42 
43 static void tcp_chr_change_state(SocketChardev *s, TCPChardevState state)
44 {
45     switch (state) {
46     case TCP_CHARDEV_STATE_DISCONNECTED:
47         break;
48     case TCP_CHARDEV_STATE_CONNECTING:
49         assert(s->state == TCP_CHARDEV_STATE_DISCONNECTED);
50         break;
51     case TCP_CHARDEV_STATE_CONNECTED:
52         assert(s->state == TCP_CHARDEV_STATE_CONNECTING);
53         break;
54     }
55     s->state = state;
56 }
57 
58 static void tcp_chr_reconn_timer_cancel(SocketChardev *s)
59 {
60     if (s->reconnect_timer) {
61         g_source_destroy(s->reconnect_timer);
62         g_source_unref(s->reconnect_timer);
63         s->reconnect_timer = NULL;
64     }
65 }
66 
67 static void qemu_chr_socket_restart_timer(Chardev *chr)
68 {
69     SocketChardev *s = SOCKET_CHARDEV(chr);
70     char *name;
71 
72     assert(s->state == TCP_CHARDEV_STATE_DISCONNECTED);
73     assert(!s->reconnect_timer);
74     name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label);
75     s->reconnect_timer = qemu_chr_timeout_add_ms(chr,
76                                                  s->reconnect_time * 1000,
77                                                  socket_reconnect_timeout,
78                                                  chr);
79     g_source_set_name(s->reconnect_timer, name);
80     g_free(name);
81 }
82 
83 static void check_report_connect_error(Chardev *chr,
84                                        Error *err)
85 {
86     SocketChardev *s = SOCKET_CHARDEV(chr);
87 
88     if (!s->connect_err_reported) {
89         error_reportf_err(err,
90                           "Unable to connect character device %s: ",
91                           chr->label);
92         s->connect_err_reported = true;
93     } else {
94         error_free(err);
95     }
96     qemu_chr_socket_restart_timer(chr);
97 }
98 
99 static void tcp_chr_accept(QIONetListener *listener,
100                            QIOChannelSocket *cioc,
101                            void *opaque);
102 
103 static int tcp_chr_read_poll(void *opaque);
104 static void tcp_chr_disconnect_locked(Chardev *chr);
105 
106 /* Called with chr_write_lock held.  */
107 static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
108 {
109     SocketChardev *s = SOCKET_CHARDEV(chr);
110 
111     if (s->state == TCP_CHARDEV_STATE_CONNECTED) {
112         int ret =  io_channel_send_full(s->ioc, buf, len,
113                                         s->write_msgfds,
114                                         s->write_msgfds_num);
115 
116         /* free the written msgfds in any cases
117          * other than ret < 0 && errno == EAGAIN
118          */
119         if (!(ret < 0 && EAGAIN == errno)
120             && s->write_msgfds_num) {
121             g_free(s->write_msgfds);
122             s->write_msgfds = 0;
123             s->write_msgfds_num = 0;
124         }
125 
126         if (ret < 0 && errno != EAGAIN) {
127             if (tcp_chr_read_poll(chr) <= 0) {
128                 /* Perform disconnect and return error. */
129                 tcp_chr_disconnect_locked(chr);
130             } /* else let the read handler finish it properly */
131         }
132 
133         return ret;
134     } else {
135         /* Indicate an error. */
136         errno = EIO;
137         return -1;
138     }
139 }
140 
141 static int tcp_chr_read_poll(void *opaque)
142 {
143     Chardev *chr = CHARDEV(opaque);
144     SocketChardev *s = SOCKET_CHARDEV(opaque);
145     if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
146         return 0;
147     }
148     s->max_size = qemu_chr_be_can_write(chr);
149     return s->max_size;
150 }
151 
152 static void tcp_chr_process_IAC_bytes(Chardev *chr,
153                                       SocketChardev *s,
154                                       uint8_t *buf, int *size)
155 {
156     /* Handle any telnet or tn3270 client's basic IAC options.
157      * For telnet options, it satisfies char by char mode with no echo.
158      * For tn3270 options, it satisfies binary mode with EOR.
159      * All IAC options will be removed from the buf and the do_opt
160      * pointer will be used to track the state of the width of the
161      * IAC information.
162      *
163      * RFC854: "All TELNET commands consist of at least a two byte sequence.
164      * The commands dealing with option negotiation are three byte sequences,
165      * the third byte being the code for the option referenced."
166      * "IAC BREAK", "IAC IP", "IAC NOP" and the double IAC are two bytes.
167      * "IAC SB", "IAC SE" and "IAC EOR" are saved to split up data boundary
168      * for tn3270.
169      * NOP, Break and Interrupt Process(IP) might be encountered during a TN3270
170      * session, and NOP and IP need to be done later.
171      */
172 
173     int i;
174     int j = 0;
175 
176     for (i = 0; i < *size; i++) {
177         if (s->do_telnetopt > 1) {
178             if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
179                 /* Double IAC means send an IAC */
180                 if (j != i) {
181                     buf[j] = buf[i];
182                 }
183                 j++;
184                 s->do_telnetopt = 1;
185             } else {
186                 if ((unsigned char)buf[i] == IAC_BREAK
187                     && s->do_telnetopt == 2) {
188                     /* Handle IAC break commands by sending a serial break */
189                     qemu_chr_be_event(chr, CHR_EVENT_BREAK);
190                     s->do_telnetopt++;
191                 } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_EOR
192                            || (unsigned char)buf[i] == IAC_SB
193                            || (unsigned char)buf[i] == IAC_SE)
194                            && s->do_telnetopt == 2) {
195                     buf[j++] = IAC;
196                     buf[j++] = buf[i];
197                     s->do_telnetopt++;
198                 } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_IP
199                            || (unsigned char)buf[i] == IAC_NOP)
200                            && s->do_telnetopt == 2) {
201                     /* TODO: IP and NOP need to be implemented later. */
202                     s->do_telnetopt++;
203                 }
204                 s->do_telnetopt++;
205             }
206             if (s->do_telnetopt >= 4) {
207                 s->do_telnetopt = 1;
208             }
209         } else {
210             if ((unsigned char)buf[i] == IAC) {
211                 s->do_telnetopt = 2;
212             } else {
213                 if (j != i) {
214                     buf[j] = buf[i];
215                 }
216                 j++;
217             }
218         }
219     }
220     *size = j;
221 }
222 
223 static int tcp_get_msgfds(Chardev *chr, int *fds, int num)
224 {
225     SocketChardev *s = SOCKET_CHARDEV(chr);
226 
227     int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num;
228 
229     assert(num <= TCP_MAX_FDS);
230 
231     if (to_copy) {
232         int i;
233 
234         memcpy(fds, s->read_msgfds, to_copy * sizeof(int));
235 
236         /* Close unused fds */
237         for (i = to_copy; i < s->read_msgfds_num; i++) {
238             close(s->read_msgfds[i]);
239         }
240 
241         g_free(s->read_msgfds);
242         s->read_msgfds = 0;
243         s->read_msgfds_num = 0;
244     }
245 
246     return to_copy;
247 }
248 
249 static int tcp_set_msgfds(Chardev *chr, int *fds, int num)
250 {
251     SocketChardev *s = SOCKET_CHARDEV(chr);
252 
253     /* clear old pending fd array */
254     g_free(s->write_msgfds);
255     s->write_msgfds = NULL;
256     s->write_msgfds_num = 0;
257 
258     if ((s->state != TCP_CHARDEV_STATE_CONNECTED) ||
259         !qio_channel_has_feature(s->ioc,
260                                  QIO_CHANNEL_FEATURE_FD_PASS)) {
261         return -1;
262     }
263 
264     if (num) {
265         s->write_msgfds = g_new(int, num);
266         memcpy(s->write_msgfds, fds, num * sizeof(int));
267     }
268 
269     s->write_msgfds_num = num;
270 
271     return 0;
272 }
273 
274 static ssize_t tcp_chr_recv(Chardev *chr, char *buf, size_t len)
275 {
276     SocketChardev *s = SOCKET_CHARDEV(chr);
277     struct iovec iov = { .iov_base = buf, .iov_len = len };
278     int ret;
279     size_t i;
280     int *msgfds = NULL;
281     size_t msgfds_num = 0;
282 
283     if (qio_channel_has_feature(s->ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
284         ret = qio_channel_readv_full(s->ioc, &iov, 1,
285                                      &msgfds, &msgfds_num,
286                                      0, NULL);
287     } else {
288         ret = qio_channel_readv_full(s->ioc, &iov, 1,
289                                      NULL, NULL,
290                                      0, NULL);
291     }
292 
293     if (msgfds_num) {
294         /* close and clean read_msgfds */
295         for (i = 0; i < s->read_msgfds_num; i++) {
296             close(s->read_msgfds[i]);
297         }
298 
299         if (s->read_msgfds_num) {
300             g_free(s->read_msgfds);
301         }
302 
303         s->read_msgfds = msgfds;
304         s->read_msgfds_num = msgfds_num;
305     }
306 
307     for (i = 0; i < s->read_msgfds_num; i++) {
308         int fd = s->read_msgfds[i];
309         if (fd < 0) {
310             continue;
311         }
312 
313         /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
314         qemu_socket_set_block(fd);
315 
316 #ifndef MSG_CMSG_CLOEXEC
317         qemu_set_cloexec(fd);
318 #endif
319     }
320 
321     if (ret == QIO_CHANNEL_ERR_BLOCK) {
322         errno = EAGAIN;
323         ret = -1;
324     } else if (ret == -1) {
325         errno = EIO;
326     }
327 
328     return ret;
329 }
330 
331 static GSource *tcp_chr_add_watch(Chardev *chr, GIOCondition cond)
332 {
333     SocketChardev *s = SOCKET_CHARDEV(chr);
334     if (!s->ioc) {
335         return NULL;
336     }
337     return qio_channel_create_watch(s->ioc, cond);
338 }
339 
340 static void remove_hup_source(SocketChardev *s)
341 {
342     if (s->hup_source != NULL) {
343         g_source_destroy(s->hup_source);
344         g_source_unref(s->hup_source);
345         s->hup_source = NULL;
346     }
347 }
348 
349 static void char_socket_yank_iochannel(void *opaque)
350 {
351     QIOChannel *ioc = QIO_CHANNEL(opaque);
352 
353     qio_channel_shutdown(ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
354 }
355 
356 static void tcp_chr_free_connection(Chardev *chr)
357 {
358     SocketChardev *s = SOCKET_CHARDEV(chr);
359     int i;
360 
361     if (s->read_msgfds_num) {
362         for (i = 0; i < s->read_msgfds_num; i++) {
363             close(s->read_msgfds[i]);
364         }
365         g_free(s->read_msgfds);
366         s->read_msgfds = NULL;
367         s->read_msgfds_num = 0;
368     }
369 
370     remove_hup_source(s);
371 
372     tcp_set_msgfds(chr, NULL, 0);
373     remove_fd_in_watch(chr);
374     if (s->registered_yank &&
375         (s->state == TCP_CHARDEV_STATE_CONNECTING
376         || s->state == TCP_CHARDEV_STATE_CONNECTED)) {
377         yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label),
378                                  char_socket_yank_iochannel,
379                                  QIO_CHANNEL(s->sioc));
380     }
381 
382     if (s->ioc) {
383         qio_channel_close(s->ioc, NULL);
384     }
385     object_unref(OBJECT(s->sioc));
386     s->sioc = NULL;
387     object_unref(OBJECT(s->ioc));
388     s->ioc = NULL;
389     g_free(chr->filename);
390     chr->filename = NULL;
391     tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
392 }
393 
394 static const char *qemu_chr_socket_protocol(SocketChardev *s)
395 {
396     if (s->is_telnet) {
397         return "telnet";
398     }
399     return s->is_websock ? "websocket" : "tcp";
400 }
401 
402 static char *qemu_chr_socket_address(SocketChardev *s, const char *prefix)
403 {
404     switch (s->addr->type) {
405     case SOCKET_ADDRESS_TYPE_INET:
406         return g_strdup_printf("%s%s:%s:%s%s", prefix,
407                                qemu_chr_socket_protocol(s),
408                                s->addr->u.inet.host,
409                                s->addr->u.inet.port,
410                                s->is_listen ? ",server=on" : "");
411         break;
412     case SOCKET_ADDRESS_TYPE_UNIX:
413     {
414         const char *tight = "", *abstract = "";
415         UnixSocketAddress *sa = &s->addr->u.q_unix;
416 
417 #ifdef CONFIG_LINUX
418         if (sa->has_abstract && sa->abstract) {
419             abstract = ",abstract=on";
420             if (sa->has_tight && sa->tight) {
421                 tight = ",tight=on";
422             }
423         }
424 #endif
425 
426         return g_strdup_printf("%sunix:%s%s%s%s", prefix, sa->path,
427                                abstract, tight,
428                                s->is_listen ? ",server=on" : "");
429         break;
430     }
431     case SOCKET_ADDRESS_TYPE_FD:
432         return g_strdup_printf("%sfd:%s%s", prefix, s->addr->u.fd.str,
433                                s->is_listen ? ",server=on" : "");
434         break;
435     case SOCKET_ADDRESS_TYPE_VSOCK:
436         return g_strdup_printf("%svsock:%s:%s", prefix,
437                                s->addr->u.vsock.cid,
438                                s->addr->u.vsock.port);
439     default:
440         abort();
441     }
442 }
443 
444 static void update_disconnected_filename(SocketChardev *s)
445 {
446     Chardev *chr = CHARDEV(s);
447 
448     g_free(chr->filename);
449     if (s->addr) {
450         chr->filename = qemu_chr_socket_address(s, "disconnected:");
451     } else {
452         chr->filename = g_strdup("disconnected:socket");
453     }
454 }
455 
456 /* NB may be called even if tcp_chr_connect has not been
457  * reached, due to TLS or telnet initialization failure,
458  * so can *not* assume s->state == TCP_CHARDEV_STATE_CONNECTED
459  * This must be called with chr->chr_write_lock held.
460  */
461 static void tcp_chr_disconnect_locked(Chardev *chr)
462 {
463     SocketChardev *s = SOCKET_CHARDEV(chr);
464     bool emit_close = s->state == TCP_CHARDEV_STATE_CONNECTED;
465 
466     tcp_chr_free_connection(chr);
467 
468     if (s->listener) {
469         qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
470                                               chr, NULL, chr->gcontext);
471     }
472     update_disconnected_filename(s);
473     if (emit_close) {
474         qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
475     }
476     if (s->reconnect_time && !s->reconnect_timer) {
477         qemu_chr_socket_restart_timer(chr);
478     }
479 }
480 
481 static void tcp_chr_disconnect(Chardev *chr)
482 {
483     qemu_mutex_lock(&chr->chr_write_lock);
484     tcp_chr_disconnect_locked(chr);
485     qemu_mutex_unlock(&chr->chr_write_lock);
486 }
487 
488 static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
489 {
490     Chardev *chr = CHARDEV(opaque);
491     SocketChardev *s = SOCKET_CHARDEV(opaque);
492     uint8_t buf[CHR_READ_BUF_LEN];
493     int len, size;
494 
495     if ((s->state != TCP_CHARDEV_STATE_CONNECTED) ||
496         s->max_size <= 0) {
497         return TRUE;
498     }
499     len = sizeof(buf);
500     if (len > s->max_size) {
501         len = s->max_size;
502     }
503     size = tcp_chr_recv(chr, (void *)buf, len);
504     if (size == 0 || (size == -1 && errno != EAGAIN)) {
505         /* connection closed */
506         tcp_chr_disconnect(chr);
507     } else if (size > 0) {
508         if (s->do_telnetopt) {
509             tcp_chr_process_IAC_bytes(chr, s, buf, &size);
510         }
511         if (size > 0) {
512             qemu_chr_be_write(chr, buf, size);
513         }
514     }
515 
516     return TRUE;
517 }
518 
519 static gboolean tcp_chr_hup(QIOChannel *channel,
520                                GIOCondition cond,
521                                void *opaque)
522 {
523     Chardev *chr = CHARDEV(opaque);
524     tcp_chr_disconnect(chr);
525     return G_SOURCE_REMOVE;
526 }
527 
528 static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len)
529 {
530     SocketChardev *s = SOCKET_CHARDEV(chr);
531     int size;
532     int saved_errno;
533 
534     if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
535         return 0;
536     }
537 
538     qio_channel_set_blocking(s->ioc, true, NULL);
539     size = tcp_chr_recv(chr, (void *) buf, len);
540     saved_errno = errno;
541     if (s->state != TCP_CHARDEV_STATE_DISCONNECTED) {
542         qio_channel_set_blocking(s->ioc, false, NULL);
543     }
544     if (size == 0) {
545         /* connection closed */
546         tcp_chr_disconnect(chr);
547     }
548 
549     errno = saved_errno;
550     return size;
551 }
552 
553 static char *qemu_chr_compute_filename(SocketChardev *s)
554 {
555     struct sockaddr_storage *ss = &s->sioc->localAddr;
556     struct sockaddr_storage *ps = &s->sioc->remoteAddr;
557     socklen_t ss_len = s->sioc->localAddrLen;
558     socklen_t ps_len = s->sioc->remoteAddrLen;
559     char shost[NI_MAXHOST], sserv[NI_MAXSERV];
560     char phost[NI_MAXHOST], pserv[NI_MAXSERV];
561     const char *left = "", *right = "";
562 
563     switch (ss->ss_family) {
564     case AF_UNIX:
565         return g_strdup_printf("unix:%s%s",
566                                ((struct sockaddr_un *)(ss))->sun_path,
567                                s->is_listen ? ",server=on" : "");
568     case AF_INET6:
569         left  = "[";
570         right = "]";
571         /* fall through */
572     case AF_INET:
573         getnameinfo((struct sockaddr *) ss, ss_len, shost, sizeof(shost),
574                     sserv, sizeof(sserv), NI_NUMERICHOST | NI_NUMERICSERV);
575         getnameinfo((struct sockaddr *) ps, ps_len, phost, sizeof(phost),
576                     pserv, sizeof(pserv), NI_NUMERICHOST | NI_NUMERICSERV);
577         return g_strdup_printf("%s:%s%s%s:%s%s <-> %s%s%s:%s",
578                                qemu_chr_socket_protocol(s),
579                                left, shost, right, sserv,
580                                s->is_listen ? ",server=on" : "",
581                                left, phost, right, pserv);
582 
583     default:
584         return g_strdup_printf("unknown");
585     }
586 }
587 
588 static void update_ioc_handlers(SocketChardev *s)
589 {
590     Chardev *chr = CHARDEV(s);
591 
592     if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
593         return;
594     }
595 
596     remove_fd_in_watch(chr);
597     chr->gsource = io_add_watch_poll(chr, s->ioc,
598                                      tcp_chr_read_poll,
599                                      tcp_chr_read, chr,
600                                      chr->gcontext);
601 
602     remove_hup_source(s);
603     s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP);
604     /*
605      * poll() is liable to return POLLHUP even when there is
606      * still incoming data available to read on the FD. If
607      * we have the hup_source at the same priority as the
608      * main io_add_watch_poll GSource, then we might end up
609      * processing the POLLHUP event first, closing the FD,
610      * and as a result silently discard data we should have
611      * read.
612      *
613      * By setting the hup_source to G_PRIORITY_DEFAULT + 1,
614      * we ensure that io_add_watch_poll GSource will always
615      * be dispatched first, thus guaranteeing we will be
616      * able to process all incoming data before closing the
617      * FD
618      */
619     g_source_set_priority(s->hup_source, G_PRIORITY_DEFAULT + 1);
620     g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup,
621                           chr, NULL);
622     g_source_attach(s->hup_source, chr->gcontext);
623 }
624 
625 static void tcp_chr_connect(void *opaque)
626 {
627     Chardev *chr = CHARDEV(opaque);
628     SocketChardev *s = SOCKET_CHARDEV(opaque);
629 
630     g_free(chr->filename);
631     chr->filename = qemu_chr_compute_filename(s);
632 
633     tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTED);
634     update_ioc_handlers(s);
635     qemu_chr_be_event(chr, CHR_EVENT_OPENED);
636 }
637 
638 static void tcp_chr_telnet_destroy(SocketChardev *s)
639 {
640     if (s->telnet_source) {
641         g_source_destroy(s->telnet_source);
642         g_source_unref(s->telnet_source);
643         s->telnet_source = NULL;
644     }
645 }
646 
647 static void tcp_chr_update_read_handler(Chardev *chr)
648 {
649     SocketChardev *s = SOCKET_CHARDEV(chr);
650 
651     if (s->listener && s->state == TCP_CHARDEV_STATE_DISCONNECTED) {
652         /*
653          * It's possible that chardev context is changed in
654          * qemu_chr_be_update_read_handlers().  Reset it for QIO net
655          * listener if there is.
656          */
657         qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
658                                               chr, NULL, chr->gcontext);
659     }
660 
661     if (s->telnet_source) {
662         tcp_chr_telnet_init(CHARDEV(s));
663     }
664 
665     update_ioc_handlers(s);
666 }
667 
668 static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc,
669                                        GIOCondition cond G_GNUC_UNUSED,
670                                        gpointer user_data)
671 {
672     SocketChardev *s = user_data;
673     Chardev *chr = CHARDEV(s);
674     TCPChardevTelnetInit *init = s->telnet_init;
675     ssize_t ret;
676 
677     assert(init);
678 
679     ret = qio_channel_write(ioc, init->buf, init->buflen, NULL);
680     if (ret < 0) {
681         if (ret == QIO_CHANNEL_ERR_BLOCK) {
682             ret = 0;
683         } else {
684             tcp_chr_disconnect(chr);
685             goto end;
686         }
687     }
688     init->buflen -= ret;
689 
690     if (init->buflen == 0) {
691         tcp_chr_connect(chr);
692         goto end;
693     }
694 
695     memmove(init->buf, init->buf + ret, init->buflen);
696 
697     return G_SOURCE_CONTINUE;
698 
699 end:
700     g_free(s->telnet_init);
701     s->telnet_init = NULL;
702     g_source_unref(s->telnet_source);
703     s->telnet_source = NULL;
704     return G_SOURCE_REMOVE;
705 }
706 
707 static void tcp_chr_telnet_init(Chardev *chr)
708 {
709     SocketChardev *s = SOCKET_CHARDEV(chr);
710     TCPChardevTelnetInit *init;
711     size_t n = 0;
712 
713     /* Destroy existing task */
714     tcp_chr_telnet_destroy(s);
715 
716     if (s->telnet_init) {
717         /* We are possibly during a handshake already */
718         goto cont;
719     }
720 
721     s->telnet_init = g_new0(TCPChardevTelnetInit, 1);
722     init = s->telnet_init;
723 
724 #define IACSET(x, a, b, c)                      \
725     do {                                        \
726         x[n++] = a;                             \
727         x[n++] = b;                             \
728         x[n++] = c;                             \
729     } while (0)
730 
731     if (!s->is_tn3270) {
732         init->buflen = 12;
733         /* Prep the telnet negotiation to put telnet in binary,
734          * no echo, single char mode */
735         IACSET(init->buf, 0xff, 0xfb, 0x01);  /* IAC WILL ECHO */
736         IACSET(init->buf, 0xff, 0xfb, 0x03);  /* IAC WILL Suppress go ahead */
737         IACSET(init->buf, 0xff, 0xfb, 0x00);  /* IAC WILL Binary */
738         IACSET(init->buf, 0xff, 0xfd, 0x00);  /* IAC DO Binary */
739     } else {
740         init->buflen = 21;
741         /* Prep the TN3270 negotiation based on RFC1576 */
742         IACSET(init->buf, 0xff, 0xfd, 0x19);  /* IAC DO EOR */
743         IACSET(init->buf, 0xff, 0xfb, 0x19);  /* IAC WILL EOR */
744         IACSET(init->buf, 0xff, 0xfd, 0x00);  /* IAC DO BINARY */
745         IACSET(init->buf, 0xff, 0xfb, 0x00);  /* IAC WILL BINARY */
746         IACSET(init->buf, 0xff, 0xfd, 0x18);  /* IAC DO TERMINAL TYPE */
747         IACSET(init->buf, 0xff, 0xfa, 0x18);  /* IAC SB TERMINAL TYPE */
748         IACSET(init->buf, 0x01, 0xff, 0xf0);  /* SEND IAC SE */
749     }
750 
751 #undef IACSET
752 
753 cont:
754     s->telnet_source = qio_channel_add_watch_source(s->ioc, G_IO_OUT,
755                                                     tcp_chr_telnet_init_io,
756                                                     s, NULL,
757                                                     chr->gcontext);
758 }
759 
760 
761 static void tcp_chr_websock_handshake(QIOTask *task, gpointer user_data)
762 {
763     Chardev *chr = user_data;
764     SocketChardev *s = user_data;
765     Error *err = NULL;
766 
767     if (qio_task_propagate_error(task, &err)) {
768         error_reportf_err(err,
769                           "websock handshake of character device %s failed: ",
770                           chr->label);
771         tcp_chr_disconnect(chr);
772     } else {
773         if (s->do_telnetopt) {
774             tcp_chr_telnet_init(chr);
775         } else {
776             tcp_chr_connect(chr);
777         }
778     }
779 }
780 
781 
782 static void tcp_chr_websock_init(Chardev *chr)
783 {
784     SocketChardev *s = SOCKET_CHARDEV(chr);
785     QIOChannelWebsock *wioc = NULL;
786     gchar *name;
787 
788     wioc = qio_channel_websock_new_server(s->ioc);
789 
790     name = g_strdup_printf("chardev-websocket-server-%s", chr->label);
791     qio_channel_set_name(QIO_CHANNEL(wioc), name);
792     g_free(name);
793     object_unref(OBJECT(s->ioc));
794     s->ioc = QIO_CHANNEL(wioc);
795 
796     qio_channel_websock_handshake(wioc, tcp_chr_websock_handshake, chr, NULL);
797 }
798 
799 
800 static void tcp_chr_tls_handshake(QIOTask *task,
801                                   gpointer user_data)
802 {
803     Chardev *chr = user_data;
804     SocketChardev *s = user_data;
805     Error *err = NULL;
806 
807     if (qio_task_propagate_error(task, &err)) {
808         error_reportf_err(err,
809                           "TLS handshake of character device %s failed: ",
810                           chr->label);
811         tcp_chr_disconnect(chr);
812     } else {
813         if (s->is_websock) {
814             tcp_chr_websock_init(chr);
815         } else if (s->do_telnetopt) {
816             tcp_chr_telnet_init(chr);
817         } else {
818             tcp_chr_connect(chr);
819         }
820     }
821 }
822 
823 
824 static void tcp_chr_tls_init(Chardev *chr)
825 {
826     SocketChardev *s = SOCKET_CHARDEV(chr);
827     QIOChannelTLS *tioc;
828     gchar *name;
829 
830     if (s->is_listen) {
831         tioc = qio_channel_tls_new_server(
832             s->ioc, s->tls_creds,
833             s->tls_authz,
834             NULL);
835     } else {
836         tioc = qio_channel_tls_new_client(
837             s->ioc, s->tls_creds,
838             s->addr->u.inet.host,
839             NULL);
840     }
841     if (tioc == NULL) {
842         tcp_chr_disconnect(chr);
843         return;
844     }
845     name = g_strdup_printf("chardev-tls-%s-%s",
846                            s->is_listen ? "server" : "client",
847                            chr->label);
848     qio_channel_set_name(QIO_CHANNEL(tioc), name);
849     g_free(name);
850     object_unref(OBJECT(s->ioc));
851     s->ioc = QIO_CHANNEL(tioc);
852 
853     qio_channel_tls_handshake(tioc,
854                               tcp_chr_tls_handshake,
855                               chr,
856                               NULL,
857                               chr->gcontext);
858 }
859 
860 
861 static void tcp_chr_set_client_ioc_name(Chardev *chr,
862                                         QIOChannelSocket *sioc)
863 {
864     SocketChardev *s = SOCKET_CHARDEV(chr);
865     char *name;
866     name = g_strdup_printf("chardev-tcp-%s-%s",
867                            s->is_listen ? "server" : "client",
868                            chr->label);
869     qio_channel_set_name(QIO_CHANNEL(sioc), name);
870     g_free(name);
871 
872 }
873 
874 static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc)
875 {
876     SocketChardev *s = SOCKET_CHARDEV(chr);
877 
878     if (s->state != TCP_CHARDEV_STATE_CONNECTING) {
879         return -1;
880     }
881 
882     s->ioc = QIO_CHANNEL(sioc);
883     object_ref(OBJECT(sioc));
884     s->sioc = sioc;
885     object_ref(OBJECT(sioc));
886 
887     qio_channel_set_blocking(s->ioc, false, NULL);
888 
889     if (s->do_nodelay) {
890         qio_channel_set_delay(s->ioc, false);
891     }
892     if (s->listener) {
893         qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
894                                               NULL, chr->gcontext);
895     }
896 
897     if (s->tls_creds) {
898         tcp_chr_tls_init(chr);
899     } else if (s->is_websock) {
900         tcp_chr_websock_init(chr);
901     } else if (s->do_telnetopt) {
902         tcp_chr_telnet_init(chr);
903     } else {
904         tcp_chr_connect(chr);
905     }
906 
907     return 0;
908 }
909 
910 
911 static int tcp_chr_add_client(Chardev *chr, int fd)
912 {
913     int ret;
914     QIOChannelSocket *sioc;
915     SocketChardev *s = SOCKET_CHARDEV(chr);
916 
917     if (s->state != TCP_CHARDEV_STATE_DISCONNECTED) {
918         return -1;
919     }
920 
921     sioc = qio_channel_socket_new_fd(fd, NULL);
922     if (!sioc) {
923         return -1;
924     }
925     tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
926     tcp_chr_set_client_ioc_name(chr, sioc);
927     if (s->registered_yank) {
928         yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
929                                char_socket_yank_iochannel,
930                                QIO_CHANNEL(sioc));
931     }
932     ret = tcp_chr_new_client(chr, sioc);
933     object_unref(OBJECT(sioc));
934     return ret;
935 }
936 
937 static void tcp_chr_accept(QIONetListener *listener,
938                            QIOChannelSocket *cioc,
939                            void *opaque)
940 {
941     Chardev *chr = CHARDEV(opaque);
942     SocketChardev *s = SOCKET_CHARDEV(chr);
943 
944     tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
945     tcp_chr_set_client_ioc_name(chr, cioc);
946     if (s->registered_yank) {
947         yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
948                                char_socket_yank_iochannel,
949                                QIO_CHANNEL(cioc));
950     }
951     tcp_chr_new_client(chr, cioc);
952 }
953 
954 
955 static int tcp_chr_connect_client_sync(Chardev *chr, Error **errp)
956 {
957     SocketChardev *s = SOCKET_CHARDEV(chr);
958     QIOChannelSocket *sioc = qio_channel_socket_new();
959     tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
960     tcp_chr_set_client_ioc_name(chr, sioc);
961     if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) {
962         tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
963         object_unref(OBJECT(sioc));
964         return -1;
965     }
966     if (s->registered_yank) {
967         yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
968                                char_socket_yank_iochannel,
969                                QIO_CHANNEL(sioc));
970     }
971     tcp_chr_new_client(chr, sioc);
972     object_unref(OBJECT(sioc));
973     return 0;
974 }
975 
976 
977 static void tcp_chr_accept_server_sync(Chardev *chr)
978 {
979     SocketChardev *s = SOCKET_CHARDEV(chr);
980     QIOChannelSocket *sioc;
981     info_report("QEMU waiting for connection on: %s",
982                 chr->filename);
983     tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
984     sioc = qio_net_listener_wait_client(s->listener);
985     tcp_chr_set_client_ioc_name(chr, sioc);
986     if (s->registered_yank) {
987         yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
988                                char_socket_yank_iochannel,
989                                QIO_CHANNEL(sioc));
990     }
991     tcp_chr_new_client(chr, sioc);
992     object_unref(OBJECT(sioc));
993 }
994 
995 
996 static int tcp_chr_wait_connected(Chardev *chr, Error **errp)
997 {
998     SocketChardev *s = SOCKET_CHARDEV(chr);
999     const char *opts[] = { "telnet", "tn3270", "websock", "tls-creds" };
1000     bool optset[] = { s->is_telnet, s->is_tn3270, s->is_websock, s->tls_creds };
1001     size_t i;
1002 
1003     QEMU_BUILD_BUG_ON(G_N_ELEMENTS(opts) != G_N_ELEMENTS(optset));
1004     for (i = 0; i < G_N_ELEMENTS(opts); i++) {
1005         if (optset[i]) {
1006             error_setg(errp,
1007                        "'%s' option is incompatible with waiting for "
1008                        "connection completion", opts[i]);
1009             return -1;
1010         }
1011     }
1012 
1013     tcp_chr_reconn_timer_cancel(s);
1014 
1015     /*
1016      * We expect states to be as follows:
1017      *
1018      *  - server
1019      *    - wait   -> CONNECTED
1020      *    - nowait -> DISCONNECTED
1021      *  - client
1022      *    - reconnect == 0 -> CONNECTED
1023      *    - reconnect != 0 -> CONNECTING
1024      *
1025      */
1026     if (s->state == TCP_CHARDEV_STATE_CONNECTING) {
1027         if (!s->connect_task) {
1028             error_setg(errp,
1029                        "Unexpected 'connecting' state without connect task "
1030                        "while waiting for connection completion");
1031             return -1;
1032         }
1033         /*
1034          * tcp_chr_wait_connected should only ever be run from the
1035          * main loop thread associated with chr->gcontext, otherwise
1036          * qio_task_wait_thread has a dangerous race condition with
1037          * free'ing of the s->connect_task object.
1038          *
1039          * Acquiring the main context doesn't 100% prove we're in
1040          * the main loop thread, but it does at least guarantee
1041          * that the main loop won't be executed by another thread
1042          * avoiding the race condition with the task idle callback.
1043          */
1044         g_main_context_acquire(chr->gcontext);
1045         qio_task_wait_thread(s->connect_task);
1046         g_main_context_release(chr->gcontext);
1047 
1048         /*
1049          * The completion callback (qemu_chr_socket_connected) for
1050          * s->connect_task should have set this to NULL by the time
1051          * qio_task_wait_thread has returned.
1052          */
1053         assert(!s->connect_task);
1054 
1055         /*
1056          * NB we are *not* guaranteed to have "s->state == ..CONNECTED"
1057          * at this point as this first connect may be failed, so
1058          * allow the next loop to run regardless.
1059          */
1060     }
1061 
1062     while (s->state != TCP_CHARDEV_STATE_CONNECTED) {
1063         if (s->is_listen) {
1064             tcp_chr_accept_server_sync(chr);
1065         } else {
1066             Error *err = NULL;
1067             if (tcp_chr_connect_client_sync(chr, &err) < 0) {
1068                 if (s->reconnect_time) {
1069                     error_free(err);
1070                     g_usleep(s->reconnect_time * 1000ULL * 1000ULL);
1071                 } else {
1072                     error_propagate(errp, err);
1073                     return -1;
1074                 }
1075             }
1076         }
1077     }
1078 
1079     return 0;
1080 }
1081 
1082 static void char_socket_finalize(Object *obj)
1083 {
1084     Chardev *chr = CHARDEV(obj);
1085     SocketChardev *s = SOCKET_CHARDEV(obj);
1086 
1087     tcp_chr_free_connection(chr);
1088     tcp_chr_reconn_timer_cancel(s);
1089     qapi_free_SocketAddress(s->addr);
1090     tcp_chr_telnet_destroy(s);
1091     g_free(s->telnet_init);
1092     if (s->listener) {
1093         qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
1094                                               NULL, chr->gcontext);
1095         object_unref(OBJECT(s->listener));
1096         s->listener = NULL;
1097     }
1098     if (s->tls_creds) {
1099         object_unref(OBJECT(s->tls_creds));
1100     }
1101     g_free(s->tls_authz);
1102     if (s->registered_yank) {
1103         /*
1104          * In the chardev-change special-case, we shouldn't unregister the yank
1105          * instance, as it still may be needed.
1106          */
1107         if (!chr->handover_yank_instance) {
1108             yank_unregister_instance(CHARDEV_YANK_INSTANCE(chr->label));
1109         }
1110     }
1111 
1112     qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
1113 }
1114 
1115 static void qemu_chr_socket_connected(QIOTask *task, void *opaque)
1116 {
1117     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
1118     Chardev *chr = CHARDEV(opaque);
1119     SocketChardev *s = SOCKET_CHARDEV(chr);
1120     Error *err = NULL;
1121 
1122     s->connect_task = NULL;
1123 
1124     if (qio_task_propagate_error(task, &err)) {
1125         tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
1126         if (s->registered_yank) {
1127             yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label),
1128                                      char_socket_yank_iochannel,
1129                                      QIO_CHANNEL(sioc));
1130         }
1131         check_report_connect_error(chr, err);
1132         goto cleanup;
1133     }
1134 
1135     s->connect_err_reported = false;
1136     tcp_chr_new_client(chr, sioc);
1137 
1138 cleanup:
1139     object_unref(OBJECT(sioc));
1140 }
1141 
1142 
1143 static void tcp_chr_connect_client_task(QIOTask *task,
1144                                         gpointer opaque)
1145 {
1146     QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
1147     SocketAddress *addr = opaque;
1148     Error *err = NULL;
1149 
1150     qio_channel_socket_connect_sync(ioc, addr, &err);
1151 
1152     qio_task_set_error(task, err);
1153 }
1154 
1155 
1156 static void tcp_chr_connect_client_async(Chardev *chr)
1157 {
1158     SocketChardev *s = SOCKET_CHARDEV(chr);
1159     QIOChannelSocket *sioc;
1160 
1161     tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
1162     sioc = qio_channel_socket_new();
1163     tcp_chr_set_client_ioc_name(chr, sioc);
1164     if (s->registered_yank) {
1165         yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
1166                                char_socket_yank_iochannel,
1167                                QIO_CHANNEL(sioc));
1168     }
1169     /*
1170      * Normally code would use the qio_channel_socket_connect_async
1171      * method which uses a QIOTask + qio_task_set_error internally
1172      * to avoid blocking. The tcp_chr_wait_connected method, however,
1173      * needs a way to synchronize with completion of the background
1174      * connect task which can't be done with the QIOChannelSocket
1175      * async APIs. Thus we must use QIOTask directly to implement
1176      * the non-blocking concept locally.
1177      */
1178     s->connect_task = qio_task_new(OBJECT(sioc),
1179                                    qemu_chr_socket_connected,
1180                                    object_ref(OBJECT(chr)),
1181                                    (GDestroyNotify)object_unref);
1182     qio_task_run_in_thread(s->connect_task,
1183                            tcp_chr_connect_client_task,
1184                            s->addr,
1185                            NULL,
1186                            chr->gcontext);
1187 }
1188 
1189 static gboolean socket_reconnect_timeout(gpointer opaque)
1190 {
1191     Chardev *chr = CHARDEV(opaque);
1192     SocketChardev *s = SOCKET_CHARDEV(opaque);
1193 
1194     qemu_mutex_lock(&chr->chr_write_lock);
1195     g_source_unref(s->reconnect_timer);
1196     s->reconnect_timer = NULL;
1197     qemu_mutex_unlock(&chr->chr_write_lock);
1198 
1199     if (chr->be_open) {
1200         return false;
1201     }
1202 
1203     tcp_chr_connect_client_async(chr);
1204 
1205     return false;
1206 }
1207 
1208 
1209 static int qmp_chardev_open_socket_server(Chardev *chr,
1210                                           bool is_telnet,
1211                                           bool is_waitconnect,
1212                                           Error **errp)
1213 {
1214     SocketChardev *s = SOCKET_CHARDEV(chr);
1215     char *name;
1216     if (is_telnet) {
1217         s->do_telnetopt = 1;
1218     }
1219     s->listener = qio_net_listener_new();
1220 
1221     name = g_strdup_printf("chardev-tcp-listener-%s", chr->label);
1222     qio_net_listener_set_name(s->listener, name);
1223     g_free(name);
1224 
1225     if (s->addr->type == SOCKET_ADDRESS_TYPE_FD && !*s->addr->u.fd.str) {
1226         goto skip_listen;
1227     }
1228 
1229     if (qio_net_listener_open_sync(s->listener, s->addr, 1, errp) < 0) {
1230         object_unref(OBJECT(s->listener));
1231         s->listener = NULL;
1232         return -1;
1233     }
1234 
1235     qapi_free_SocketAddress(s->addr);
1236     s->addr = socket_local_address(s->listener->sioc[0]->fd, errp);
1237 
1238 skip_listen:
1239     update_disconnected_filename(s);
1240 
1241     if (is_waitconnect) {
1242         tcp_chr_accept_server_sync(chr);
1243     } else {
1244         qio_net_listener_set_client_func_full(s->listener,
1245                                               tcp_chr_accept,
1246                                               chr, NULL,
1247                                               chr->gcontext);
1248     }
1249 
1250     return 0;
1251 }
1252 
1253 
1254 static int qmp_chardev_open_socket_client(Chardev *chr,
1255                                           int64_t reconnect,
1256                                           Error **errp)
1257 {
1258     SocketChardev *s = SOCKET_CHARDEV(chr);
1259 
1260     if (reconnect > 0) {
1261         s->reconnect_time = reconnect;
1262         tcp_chr_connect_client_async(chr);
1263         return 0;
1264     } else {
1265         return tcp_chr_connect_client_sync(chr, errp);
1266     }
1267 }
1268 
1269 
1270 static bool qmp_chardev_validate_socket(ChardevSocket *sock,
1271                                         SocketAddress *addr,
1272                                         Error **errp)
1273 {
1274     /* Validate any options which have a dependency on address type */
1275     switch (addr->type) {
1276     case SOCKET_ADDRESS_TYPE_FD:
1277         if (sock->has_reconnect) {
1278             error_setg(errp,
1279                        "'reconnect' option is incompatible with "
1280                        "'fd' address type");
1281             return false;
1282         }
1283         if (sock->tls_creds &&
1284             !(sock->has_server && sock->server)) {
1285             error_setg(errp,
1286                        "'tls_creds' option is incompatible with "
1287                        "'fd' address type as client");
1288             return false;
1289         }
1290         break;
1291 
1292     case SOCKET_ADDRESS_TYPE_UNIX:
1293         if (sock->tls_creds) {
1294             error_setg(errp,
1295                        "'tls_creds' option is incompatible with "
1296                        "'unix' address type");
1297             return false;
1298         }
1299         break;
1300 
1301     case SOCKET_ADDRESS_TYPE_INET:
1302         break;
1303 
1304     case SOCKET_ADDRESS_TYPE_VSOCK:
1305         if (sock->tls_creds) {
1306             error_setg(errp,
1307                        "'tls_creds' option is incompatible with "
1308                        "'vsock' address type");
1309             return false;
1310         }
1311 
1312     default:
1313         break;
1314     }
1315 
1316     if (sock->tls_authz && !sock->tls_creds) {
1317         error_setg(errp, "'tls_authz' option requires 'tls_creds' option");
1318         return false;
1319     }
1320 
1321     /* Validate any options which have a dependency on client vs server */
1322     if (!sock->has_server || sock->server) {
1323         if (sock->has_reconnect) {
1324             error_setg(errp,
1325                        "'reconnect' option is incompatible with "
1326                        "socket in server listen mode");
1327             return false;
1328         }
1329     } else {
1330         if (sock->has_websocket && sock->websocket) {
1331             error_setg(errp, "%s", "Websocket client is not implemented");
1332             return false;
1333         }
1334         if (sock->has_wait) {
1335             error_setg(errp, "%s",
1336                        "'wait' option is incompatible with "
1337                        "socket in client connect mode");
1338             return false;
1339         }
1340     }
1341 
1342     return true;
1343 }
1344 
1345 
1346 static void qmp_chardev_open_socket(Chardev *chr,
1347                                     ChardevBackend *backend,
1348                                     bool *be_opened,
1349                                     Error **errp)
1350 {
1351     SocketChardev *s = SOCKET_CHARDEV(chr);
1352     ChardevSocket *sock = backend->u.socket.data;
1353     bool do_nodelay     = sock->has_nodelay ? sock->nodelay : false;
1354     bool is_listen      = sock->has_server  ? sock->server  : true;
1355     bool is_telnet      = sock->has_telnet  ? sock->telnet  : false;
1356     bool is_tn3270      = sock->has_tn3270  ? sock->tn3270  : false;
1357     bool is_waitconnect = sock->has_wait    ? sock->wait    : false;
1358     bool is_websock     = sock->has_websocket ? sock->websocket : false;
1359     int64_t reconnect   = sock->has_reconnect ? sock->reconnect : 0;
1360     SocketAddress *addr;
1361 
1362     s->is_listen = is_listen;
1363     s->is_telnet = is_telnet;
1364     s->is_tn3270 = is_tn3270;
1365     s->is_websock = is_websock;
1366     s->do_nodelay = do_nodelay;
1367     if (sock->tls_creds) {
1368         Object *creds;
1369         creds = object_resolve_path_component(
1370             object_get_objects_root(), sock->tls_creds);
1371         if (!creds) {
1372             error_setg(errp, "No TLS credentials with id '%s'",
1373                        sock->tls_creds);
1374             return;
1375         }
1376         s->tls_creds = (QCryptoTLSCreds *)
1377             object_dynamic_cast(creds,
1378                                 TYPE_QCRYPTO_TLS_CREDS);
1379         if (!s->tls_creds) {
1380             error_setg(errp, "Object with id '%s' is not TLS credentials",
1381                        sock->tls_creds);
1382             return;
1383         }
1384         object_ref(OBJECT(s->tls_creds));
1385         if (!qcrypto_tls_creds_check_endpoint(s->tls_creds,
1386                                           is_listen
1387                                           ? QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
1388                                           : QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT,
1389                                           errp)) {
1390             return;
1391         }
1392     }
1393     s->tls_authz = g_strdup(sock->tls_authz);
1394 
1395     s->addr = addr = socket_address_flatten(sock->addr);
1396 
1397     if (!qmp_chardev_validate_socket(sock, addr, errp)) {
1398         return;
1399     }
1400 
1401     qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE);
1402 #ifndef _WIN32
1403     /* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */
1404     if (addr->type == SOCKET_ADDRESS_TYPE_UNIX) {
1405         qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS);
1406     }
1407 #endif
1408 
1409     /*
1410      * In the chardev-change special-case, we shouldn't register a new yank
1411      * instance, as there already may be one.
1412      */
1413     if (!chr->handover_yank_instance) {
1414         if (!yank_register_instance(CHARDEV_YANK_INSTANCE(chr->label), errp)) {
1415             return;
1416         }
1417     }
1418     s->registered_yank = true;
1419 
1420     /* be isn't opened until we get a connection */
1421     *be_opened = false;
1422 
1423     update_disconnected_filename(s);
1424 
1425     if (s->is_listen) {
1426         if (qmp_chardev_open_socket_server(chr, is_telnet || is_tn3270,
1427                                            is_waitconnect, errp) < 0) {
1428             return;
1429         }
1430     } else {
1431         if (qmp_chardev_open_socket_client(chr, reconnect, errp) < 0) {
1432             return;
1433         }
1434     }
1435 }
1436 
1437 static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
1438                                   Error **errp)
1439 {
1440     const char *path = qemu_opt_get(opts, "path");
1441     const char *host = qemu_opt_get(opts, "host");
1442     const char *port = qemu_opt_get(opts, "port");
1443     const char *fd = qemu_opt_get(opts, "fd");
1444 #ifdef CONFIG_LINUX
1445     bool tight = qemu_opt_get_bool(opts, "tight", true);
1446     bool abstract = qemu_opt_get_bool(opts, "abstract", false);
1447 #endif
1448     SocketAddressLegacy *addr;
1449     ChardevSocket *sock;
1450 
1451     if ((!!path + !!fd + !!host) > 1) {
1452         error_setg(errp,
1453                    "None or one of 'path', 'fd' or 'host' option required.");
1454         return;
1455     }
1456 
1457     if (host && !port) {
1458         error_setg(errp, "chardev: socket: no port given");
1459         return;
1460     }
1461 
1462     backend->type = CHARDEV_BACKEND_KIND_SOCKET;
1463     sock = backend->u.socket.data = g_new0(ChardevSocket, 1);
1464     qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock));
1465 
1466     if (qemu_opt_get(opts, "delay") && qemu_opt_get(opts, "nodelay")) {
1467         error_setg(errp, "'delay' and 'nodelay' are mutually exclusive");
1468         return;
1469     }
1470     sock->has_nodelay =
1471         qemu_opt_get(opts, "delay") ||
1472         qemu_opt_get(opts, "nodelay");
1473     sock->nodelay =
1474         !qemu_opt_get_bool(opts, "delay", true) ||
1475         qemu_opt_get_bool(opts, "nodelay", false);
1476 
1477     /*
1478      * We have different default to QMP for 'server', hence
1479      * we can't just check for existence of 'server'
1480      */
1481     sock->has_server = true;
1482     sock->server = qemu_opt_get_bool(opts, "server", false);
1483     sock->has_telnet = qemu_opt_get(opts, "telnet");
1484     sock->telnet = qemu_opt_get_bool(opts, "telnet", false);
1485     sock->has_tn3270 = qemu_opt_get(opts, "tn3270");
1486     sock->tn3270 = qemu_opt_get_bool(opts, "tn3270", false);
1487     sock->has_websocket = qemu_opt_get(opts, "websocket");
1488     sock->websocket = qemu_opt_get_bool(opts, "websocket", false);
1489     /*
1490      * We have different default to QMP for 'wait' when 'server'
1491      * is set, hence we can't just check for existence of 'wait'
1492      */
1493     sock->has_wait = qemu_opt_find(opts, "wait") || sock->server;
1494     sock->wait = qemu_opt_get_bool(opts, "wait", true);
1495     sock->has_reconnect = qemu_opt_find(opts, "reconnect");
1496     sock->reconnect = qemu_opt_get_number(opts, "reconnect", 0);
1497     sock->tls_creds = g_strdup(qemu_opt_get(opts, "tls-creds"));
1498     sock->tls_authz = g_strdup(qemu_opt_get(opts, "tls-authz"));
1499 
1500     addr = g_new0(SocketAddressLegacy, 1);
1501     if (path) {
1502         UnixSocketAddress *q_unix;
1503         addr->type = SOCKET_ADDRESS_TYPE_UNIX;
1504         q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
1505         q_unix->path = g_strdup(path);
1506 #ifdef CONFIG_LINUX
1507         q_unix->has_tight = true;
1508         q_unix->tight = tight;
1509         q_unix->has_abstract = true;
1510         q_unix->abstract = abstract;
1511 #endif
1512     } else if (host) {
1513         addr->type = SOCKET_ADDRESS_TYPE_INET;
1514         addr->u.inet.data = g_new(InetSocketAddress, 1);
1515         *addr->u.inet.data = (InetSocketAddress) {
1516             .host = g_strdup(host),
1517             .port = g_strdup(port),
1518             .has_to = qemu_opt_get(opts, "to"),
1519             .to = qemu_opt_get_number(opts, "to", 0),
1520             .has_ipv4 = qemu_opt_get(opts, "ipv4"),
1521             .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0),
1522             .has_ipv6 = qemu_opt_get(opts, "ipv6"),
1523             .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
1524         };
1525     } else {
1526         addr->type = SOCKET_ADDRESS_TYPE_FD;
1527         addr->u.fd.data = g_new(FdSocketAddress, 1);
1528         addr->u.fd.data->str = g_strdup(fd);
1529     }
1530     sock->addr = addr;
1531 }
1532 
1533 static void
1534 char_socket_get_addr(Object *obj, Visitor *v, const char *name,
1535                      void *opaque, Error **errp)
1536 {
1537     SocketChardev *s = SOCKET_CHARDEV(obj);
1538 
1539     visit_type_SocketAddress(v, name, &s->addr, errp);
1540 }
1541 
1542 static bool
1543 char_socket_get_connected(Object *obj, Error **errp)
1544 {
1545     SocketChardev *s = SOCKET_CHARDEV(obj);
1546 
1547     return s->state == TCP_CHARDEV_STATE_CONNECTED;
1548 }
1549 
1550 static void char_socket_class_init(ObjectClass *oc, void *data)
1551 {
1552     ChardevClass *cc = CHARDEV_CLASS(oc);
1553 
1554     cc->supports_yank = true;
1555 
1556     cc->parse = qemu_chr_parse_socket;
1557     cc->open = qmp_chardev_open_socket;
1558     cc->chr_wait_connected = tcp_chr_wait_connected;
1559     cc->chr_write = tcp_chr_write;
1560     cc->chr_sync_read = tcp_chr_sync_read;
1561     cc->chr_disconnect = tcp_chr_disconnect;
1562     cc->get_msgfds = tcp_get_msgfds;
1563     cc->set_msgfds = tcp_set_msgfds;
1564     cc->chr_add_client = tcp_chr_add_client;
1565     cc->chr_add_watch = tcp_chr_add_watch;
1566     cc->chr_update_read_handler = tcp_chr_update_read_handler;
1567 
1568     object_class_property_add(oc, "addr", "SocketAddress",
1569                               char_socket_get_addr, NULL,
1570                               NULL, NULL);
1571 
1572     object_class_property_add_bool(oc, "connected", char_socket_get_connected,
1573                                    NULL);
1574 }
1575 
1576 static const TypeInfo char_socket_type_info = {
1577     .name = TYPE_CHARDEV_SOCKET,
1578     .parent = TYPE_CHARDEV,
1579     .instance_size = sizeof(SocketChardev),
1580     .instance_finalize = char_socket_finalize,
1581     .class_init = char_socket_class_init,
1582 };
1583 
1584 static void register_types(void)
1585 {
1586     type_register_static(&char_socket_type_info);
1587 }
1588 
1589 type_init(register_types);
1590