4 * Copyright (c) 2003-2008 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
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"
36 #include "chardev/char-io.h"
38 /***********************************************************/
41 #define TCP_MAX_FDS 16
45 QIOChannel *ioc; /* Client I/O channel */
46 QIOChannelSocket *sioc; /* Client master channel */
47 QIONetListener *listener;
49 QCryptoTLSCreds *tls_creds;
55 size_t read_msgfds_num;
57 size_t write_msgfds_num;
64 GSource *reconnect_timer;
65 int64_t reconnect_time;
66 bool connect_err_reported;
69 #define SOCKET_CHARDEV(obj) \
70 OBJECT_CHECK(SocketChardev, (obj), TYPE_CHARDEV_SOCKET)
72 static gboolean socket_reconnect_timeout(gpointer opaque);
74 static void tcp_chr_reconn_timer_cancel(SocketChardev *s)
76 if (s->reconnect_timer) {
77 g_source_destroy(s->reconnect_timer);
78 g_source_unref(s->reconnect_timer);
79 s->reconnect_timer = NULL;
83 static void qemu_chr_socket_restart_timer(Chardev *chr)
85 SocketChardev *s = SOCKET_CHARDEV(chr);
88 assert(s->connected == 0);
89 name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label);
90 s->reconnect_timer = qemu_chr_timeout_add_ms(chr,
91 s->reconnect_time * 1000,
92 socket_reconnect_timeout,
94 g_source_set_name(s->reconnect_timer, name);
98 static void check_report_connect_error(Chardev *chr,
101 SocketChardev *s = SOCKET_CHARDEV(chr);
103 if (!s->connect_err_reported) {
104 error_report("Unable to connect character device %s: %s",
105 chr->label, error_get_pretty(err));
106 s->connect_err_reported = true;
108 qemu_chr_socket_restart_timer(chr);
111 static void tcp_chr_accept(QIONetListener *listener,
112 QIOChannelSocket *cioc,
115 static int tcp_chr_read_poll(void *opaque);
116 static void tcp_chr_disconnect(Chardev *chr);
118 /* Called with chr_write_lock held. */
119 static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
121 SocketChardev *s = SOCKET_CHARDEV(chr);
124 int ret = io_channel_send_full(s->ioc, buf, len,
126 s->write_msgfds_num);
128 /* free the written msgfds, no matter what */
129 if (s->write_msgfds_num) {
130 g_free(s->write_msgfds);
132 s->write_msgfds_num = 0;
135 if (ret < 0 && errno != EAGAIN) {
136 if (tcp_chr_read_poll(chr) <= 0) {
137 tcp_chr_disconnect(chr);
139 } /* else let the read handler finish it properly */
144 /* XXX: indicate an error ? */
149 static int tcp_chr_read_poll(void *opaque)
151 Chardev *chr = CHARDEV(opaque);
152 SocketChardev *s = SOCKET_CHARDEV(opaque);
156 s->max_size = qemu_chr_be_can_write(chr);
160 static void tcp_chr_process_IAC_bytes(Chardev *chr,
162 uint8_t *buf, int *size)
164 /* Handle any telnet or tn3270 client's basic IAC options.
165 * For telnet options, it satisfies char by char mode with no echo.
166 * For tn3270 options, it satisfies binary mode with EOR.
167 * All IAC options will be removed from the buf and the do_opt
168 * pointer will be used to track the state of the width of the
171 * RFC854: "All TELNET commands consist of at least a two byte sequence.
172 * The commands dealing with option negotiation are three byte sequences,
173 * the third byte being the code for the option referenced."
174 * "IAC BREAK", "IAC IP", "IAC NOP" and the double IAC are two bytes.
175 * "IAC SB", "IAC SE" and "IAC EOR" are saved to split up data boundary
177 * NOP, Break and Interrupt Process(IP) might be encountered during a TN3270
178 * session, and NOP and IP need to be done later.
184 for (i = 0; i < *size; i++) {
185 if (s->do_telnetopt > 1) {
186 if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
187 /* Double IAC means send an IAC */
194 if ((unsigned char)buf[i] == IAC_BREAK
195 && s->do_telnetopt == 2) {
196 /* Handle IAC break commands by sending a serial break */
197 qemu_chr_be_event(chr, CHR_EVENT_BREAK);
199 } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_EOR
200 || (unsigned char)buf[i] == IAC_SB
201 || (unsigned char)buf[i] == IAC_SE)
202 && s->do_telnetopt == 2) {
206 } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_IP
207 || (unsigned char)buf[i] == IAC_NOP)
208 && s->do_telnetopt == 2) {
209 /* TODO: IP and NOP need to be implemented later. */
214 if (s->do_telnetopt >= 4) {
218 if ((unsigned char)buf[i] == IAC) {
231 static int tcp_get_msgfds(Chardev *chr, int *fds, int num)
233 SocketChardev *s = SOCKET_CHARDEV(chr);
235 int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num;
237 assert(num <= TCP_MAX_FDS);
242 memcpy(fds, s->read_msgfds, to_copy * sizeof(int));
244 /* Close unused fds */
245 for (i = to_copy; i < s->read_msgfds_num; i++) {
246 close(s->read_msgfds[i]);
249 g_free(s->read_msgfds);
251 s->read_msgfds_num = 0;
257 static int tcp_set_msgfds(Chardev *chr, int *fds, int num)
259 SocketChardev *s = SOCKET_CHARDEV(chr);
261 /* clear old pending fd array */
262 g_free(s->write_msgfds);
263 s->write_msgfds = NULL;
264 s->write_msgfds_num = 0;
267 !qio_channel_has_feature(s->ioc,
268 QIO_CHANNEL_FEATURE_FD_PASS)) {
273 s->write_msgfds = g_new(int, num);
274 memcpy(s->write_msgfds, fds, num * sizeof(int));
277 s->write_msgfds_num = num;
282 static ssize_t tcp_chr_recv(Chardev *chr, char *buf, size_t len)
284 SocketChardev *s = SOCKET_CHARDEV(chr);
285 struct iovec iov = { .iov_base = buf, .iov_len = len };
289 size_t msgfds_num = 0;
291 if (qio_channel_has_feature(s->ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
292 ret = qio_channel_readv_full(s->ioc, &iov, 1,
293 &msgfds, &msgfds_num,
296 ret = qio_channel_readv_full(s->ioc, &iov, 1,
301 if (ret == QIO_CHANNEL_ERR_BLOCK) {
304 } else if (ret == -1) {
309 /* close and clean read_msgfds */
310 for (i = 0; i < s->read_msgfds_num; i++) {
311 close(s->read_msgfds[i]);
314 if (s->read_msgfds_num) {
315 g_free(s->read_msgfds);
318 s->read_msgfds = msgfds;
319 s->read_msgfds_num = msgfds_num;
322 for (i = 0; i < s->read_msgfds_num; i++) {
323 int fd = s->read_msgfds[i];
328 /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
331 #ifndef MSG_CMSG_CLOEXEC
332 qemu_set_cloexec(fd);
339 static GSource *tcp_chr_add_watch(Chardev *chr, GIOCondition cond)
341 SocketChardev *s = SOCKET_CHARDEV(chr);
342 return qio_channel_create_watch(s->ioc, cond);
345 static void tcp_chr_free_connection(Chardev *chr)
347 SocketChardev *s = SOCKET_CHARDEV(chr);
350 if (s->read_msgfds_num) {
351 for (i = 0; i < s->read_msgfds_num; i++) {
352 close(s->read_msgfds[i]);
354 g_free(s->read_msgfds);
355 s->read_msgfds = NULL;
356 s->read_msgfds_num = 0;
359 if (s->hup_source != NULL) {
360 g_source_destroy(s->hup_source);
361 g_source_unref(s->hup_source);
362 s->hup_source = NULL;
365 tcp_set_msgfds(chr, NULL, 0);
366 remove_fd_in_watch(chr);
367 object_unref(OBJECT(s->sioc));
369 object_unref(OBJECT(s->ioc));
371 g_free(chr->filename);
372 chr->filename = NULL;
376 static char *SocketAddress_to_str(const char *prefix, SocketAddress *addr,
377 bool is_listen, bool is_telnet)
379 switch (addr->type) {
380 case SOCKET_ADDRESS_TYPE_INET:
381 return g_strdup_printf("%s%s:%s:%s%s", prefix,
382 is_telnet ? "telnet" : "tcp",
385 is_listen ? ",server" : "");
387 case SOCKET_ADDRESS_TYPE_UNIX:
388 return g_strdup_printf("%sunix:%s%s", prefix,
390 is_listen ? ",server" : "");
392 case SOCKET_ADDRESS_TYPE_FD:
393 return g_strdup_printf("%sfd:%s%s", prefix, addr->u.fd.str,
394 is_listen ? ",server" : "");
396 case SOCKET_ADDRESS_TYPE_VSOCK:
397 return g_strdup_printf("%svsock:%s:%s", prefix,
405 static void update_disconnected_filename(SocketChardev *s)
407 Chardev *chr = CHARDEV(s);
409 g_free(chr->filename);
410 chr->filename = SocketAddress_to_str("disconnected:", s->addr,
411 s->is_listen, s->is_telnet);
414 /* NB may be called even if tcp_chr_connect has not been
415 * reached, due to TLS or telnet initialization failure,
416 * so can *not* assume s->connected == true
418 static void tcp_chr_disconnect(Chardev *chr)
420 SocketChardev *s = SOCKET_CHARDEV(chr);
421 bool emit_close = s->connected;
423 tcp_chr_free_connection(chr);
426 qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
427 chr, NULL, chr->gcontext);
429 update_disconnected_filename(s);
431 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
433 if (s->reconnect_time) {
434 qemu_chr_socket_restart_timer(chr);
438 static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
440 Chardev *chr = CHARDEV(opaque);
441 SocketChardev *s = SOCKET_CHARDEV(opaque);
442 uint8_t buf[CHR_READ_BUF_LEN];
445 if (!s->connected || s->max_size <= 0) {
449 if (len > s->max_size) {
452 size = tcp_chr_recv(chr, (void *)buf, len);
453 if (size == 0 || (size == -1 && errno != EAGAIN)) {
454 /* connection closed */
455 tcp_chr_disconnect(chr);
456 } else if (size > 0) {
457 if (s->do_telnetopt) {
458 tcp_chr_process_IAC_bytes(chr, s, buf, &size);
461 qemu_chr_be_write(chr, buf, size);
468 static gboolean tcp_chr_hup(QIOChannel *channel,
472 Chardev *chr = CHARDEV(opaque);
473 tcp_chr_disconnect(chr);
474 return G_SOURCE_REMOVE;
477 static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len)
479 SocketChardev *s = SOCKET_CHARDEV(chr);
486 qio_channel_set_blocking(s->ioc, true, NULL);
487 size = tcp_chr_recv(chr, (void *) buf, len);
488 qio_channel_set_blocking(s->ioc, false, NULL);
490 /* connection closed */
491 tcp_chr_disconnect(chr);
497 static char *sockaddr_to_str(struct sockaddr_storage *ss, socklen_t ss_len,
498 struct sockaddr_storage *ps, socklen_t ps_len,
499 bool is_listen, bool is_telnet)
501 char shost[NI_MAXHOST], sserv[NI_MAXSERV];
502 char phost[NI_MAXHOST], pserv[NI_MAXSERV];
503 const char *left = "", *right = "";
505 switch (ss->ss_family) {
508 return g_strdup_printf("unix:%s%s",
509 ((struct sockaddr_un *)(ss))->sun_path,
510 is_listen ? ",server" : "");
517 getnameinfo((struct sockaddr *) ss, ss_len, shost, sizeof(shost),
518 sserv, sizeof(sserv), NI_NUMERICHOST | NI_NUMERICSERV);
519 getnameinfo((struct sockaddr *) ps, ps_len, phost, sizeof(phost),
520 pserv, sizeof(pserv), NI_NUMERICHOST | NI_NUMERICSERV);
521 return g_strdup_printf("%s:%s%s%s:%s%s <-> %s%s%s:%s",
522 is_telnet ? "telnet" : "tcp",
523 left, shost, right, sserv,
524 is_listen ? ",server" : "",
525 left, phost, right, pserv);
528 return g_strdup_printf("unknown");
532 static void tcp_chr_connect(void *opaque)
534 Chardev *chr = CHARDEV(opaque);
535 SocketChardev *s = SOCKET_CHARDEV(opaque);
537 g_free(chr->filename);
538 chr->filename = sockaddr_to_str(
539 &s->sioc->localAddr, s->sioc->localAddrLen,
540 &s->sioc->remoteAddr, s->sioc->remoteAddrLen,
541 s->is_listen, s->is_telnet);
545 chr->gsource = io_add_watch_poll(chr, s->ioc,
551 s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP);
552 g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup,
554 g_source_attach(s->hup_source, chr->gcontext);
556 qemu_chr_be_event(chr, CHR_EVENT_OPENED);
559 static void tcp_chr_update_read_handler(Chardev *chr)
561 SocketChardev *s = SOCKET_CHARDEV(chr);
565 * It's possible that chardev context is changed in
566 * qemu_chr_be_update_read_handlers(). Reset it for QIO net
567 * listener if there is.
569 qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept,
570 chr, NULL, chr->gcontext);
577 remove_fd_in_watch(chr);
579 chr->gsource = io_add_watch_poll(chr, s->ioc,
590 } TCPChardevTelnetInit;
592 static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc,
593 GIOCondition cond G_GNUC_UNUSED,
596 TCPChardevTelnetInit *init = user_data;
599 ret = qio_channel_write(ioc, init->buf, init->buflen, NULL);
601 if (ret == QIO_CHANNEL_ERR_BLOCK) {
604 tcp_chr_disconnect(init->chr);
610 if (init->buflen == 0) {
611 tcp_chr_connect(init->chr);
615 memmove(init->buf, init->buf + ret, init->buflen);
617 return G_SOURCE_CONTINUE;
621 return G_SOURCE_REMOVE;
624 static void tcp_chr_telnet_init(Chardev *chr)
626 SocketChardev *s = SOCKET_CHARDEV(chr);
627 TCPChardevTelnetInit *init = g_new0(TCPChardevTelnetInit, 1);
630 #define IACSET(x, a, b, c) \
640 /* Prep the telnet negotion to put telnet in binary,
641 * no echo, single char mode */
642 IACSET(init->buf, 0xff, 0xfb, 0x01); /* IAC WILL ECHO */
643 IACSET(init->buf, 0xff, 0xfb, 0x03); /* IAC WILL Suppress go ahead */
644 IACSET(init->buf, 0xff, 0xfb, 0x00); /* IAC WILL Binary */
645 IACSET(init->buf, 0xff, 0xfd, 0x00); /* IAC DO Binary */
648 /* Prep the TN3270 negotion based on RFC1576 */
649 IACSET(init->buf, 0xff, 0xfd, 0x19); /* IAC DO EOR */
650 IACSET(init->buf, 0xff, 0xfb, 0x19); /* IAC WILL EOR */
651 IACSET(init->buf, 0xff, 0xfd, 0x00); /* IAC DO BINARY */
652 IACSET(init->buf, 0xff, 0xfb, 0x00); /* IAC WILL BINARY */
653 IACSET(init->buf, 0xff, 0xfd, 0x18); /* IAC DO TERMINAL TYPE */
654 IACSET(init->buf, 0xff, 0xfa, 0x18); /* IAC SB TERMINAL TYPE */
655 IACSET(init->buf, 0x01, 0xff, 0xf0); /* SEND IAC SE */
660 qio_channel_add_watch(
662 tcp_chr_telnet_init_io,
667 static void tcp_chr_tls_handshake(QIOTask *task,
670 Chardev *chr = user_data;
671 SocketChardev *s = user_data;
673 if (qio_task_propagate_error(task, NULL)) {
674 tcp_chr_disconnect(chr);
676 /* tn3270 does not support TLS yet */
677 if (s->do_telnetopt && !s->is_tn3270) {
678 tcp_chr_telnet_init(chr);
680 tcp_chr_connect(chr);
686 static void tcp_chr_tls_init(Chardev *chr)
688 SocketChardev *s = SOCKET_CHARDEV(chr);
694 tioc = qio_channel_tls_new_server(
695 s->ioc, s->tls_creds,
696 NULL, /* XXX Use an ACL */
699 tioc = qio_channel_tls_new_client(
700 s->ioc, s->tls_creds,
701 s->addr->u.inet.host,
706 tcp_chr_disconnect(chr);
709 name = g_strdup_printf("chardev-tls-%s-%s",
710 s->is_listen ? "server" : "client",
712 qio_channel_set_name(QIO_CHANNEL(tioc), name);
714 object_unref(OBJECT(s->ioc));
715 s->ioc = QIO_CHANNEL(tioc);
717 qio_channel_tls_handshake(tioc,
718 tcp_chr_tls_handshake,
725 static void tcp_chr_set_client_ioc_name(Chardev *chr,
726 QIOChannelSocket *sioc)
728 SocketChardev *s = SOCKET_CHARDEV(chr);
730 name = g_strdup_printf("chardev-tcp-%s-%s",
731 s->is_listen ? "server" : "client",
733 qio_channel_set_name(QIO_CHANNEL(sioc), name);
738 static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc)
740 SocketChardev *s = SOCKET_CHARDEV(chr);
742 if (s->ioc != NULL) {
746 s->ioc = QIO_CHANNEL(sioc);
747 object_ref(OBJECT(sioc));
749 object_ref(OBJECT(sioc));
751 qio_channel_set_blocking(s->ioc, false, NULL);
754 qio_channel_set_delay(s->ioc, false);
757 qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
758 NULL, chr->gcontext);
762 tcp_chr_tls_init(chr);
764 if (s->do_telnetopt) {
765 tcp_chr_telnet_init(chr);
767 tcp_chr_connect(chr);
775 static int tcp_chr_add_client(Chardev *chr, int fd)
778 QIOChannelSocket *sioc;
780 sioc = qio_channel_socket_new_fd(fd, NULL);
784 tcp_chr_set_client_ioc_name(chr, sioc);
785 ret = tcp_chr_new_client(chr, sioc);
786 object_unref(OBJECT(sioc));
790 static void tcp_chr_accept(QIONetListener *listener,
791 QIOChannelSocket *cioc,
794 Chardev *chr = CHARDEV(opaque);
796 tcp_chr_set_client_ioc_name(chr, cioc);
797 tcp_chr_new_client(chr, cioc);
800 static int tcp_chr_wait_connected(Chardev *chr, Error **errp)
802 SocketChardev *s = SOCKET_CHARDEV(chr);
803 QIOChannelSocket *sioc;
805 /* It can't wait on s->connected, since it is set asynchronously
806 * in TLS and telnet cases, only wait for an accepted socket */
809 info_report("QEMU waiting for connection on: %s",
811 sioc = qio_net_listener_wait_client(s->listener);
812 tcp_chr_set_client_ioc_name(chr, sioc);
813 tcp_chr_new_client(chr, sioc);
814 object_unref(OBJECT(sioc));
816 sioc = qio_channel_socket_new();
817 tcp_chr_set_client_ioc_name(chr, sioc);
818 if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) {
819 object_unref(OBJECT(sioc));
822 tcp_chr_new_client(chr, sioc);
823 object_unref(OBJECT(sioc));
830 static void char_socket_finalize(Object *obj)
832 Chardev *chr = CHARDEV(obj);
833 SocketChardev *s = SOCKET_CHARDEV(obj);
835 tcp_chr_free_connection(chr);
836 tcp_chr_reconn_timer_cancel(s);
837 qapi_free_SocketAddress(s->addr);
839 qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
840 NULL, chr->gcontext);
841 object_unref(OBJECT(s->listener));
844 object_unref(OBJECT(s->tls_creds));
847 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
850 static void qemu_chr_socket_connected(QIOTask *task, void *opaque)
852 QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
853 Chardev *chr = CHARDEV(opaque);
854 SocketChardev *s = SOCKET_CHARDEV(chr);
857 if (qio_task_propagate_error(task, &err)) {
858 check_report_connect_error(chr, err);
863 s->connect_err_reported = false;
864 tcp_chr_new_client(chr, sioc);
867 object_unref(OBJECT(sioc));
870 static gboolean socket_reconnect_timeout(gpointer opaque)
872 Chardev *chr = CHARDEV(opaque);
873 SocketChardev *s = SOCKET_CHARDEV(opaque);
874 QIOChannelSocket *sioc;
876 g_source_unref(s->reconnect_timer);
877 s->reconnect_timer = NULL;
883 sioc = qio_channel_socket_new();
884 tcp_chr_set_client_ioc_name(chr, sioc);
885 qio_channel_socket_connect_async(sioc, s->addr,
886 qemu_chr_socket_connected,
892 static void qmp_chardev_open_socket(Chardev *chr,
893 ChardevBackend *backend,
897 SocketChardev *s = SOCKET_CHARDEV(chr);
898 ChardevSocket *sock = backend->u.socket.data;
899 bool do_nodelay = sock->has_nodelay ? sock->nodelay : false;
900 bool is_listen = sock->has_server ? sock->server : true;
901 bool is_telnet = sock->has_telnet ? sock->telnet : false;
902 bool is_tn3270 = sock->has_tn3270 ? sock->tn3270 : false;
903 bool is_waitconnect = sock->has_wait ? sock->wait : false;
904 int64_t reconnect = sock->has_reconnect ? sock->reconnect : 0;
905 QIOChannelSocket *sioc = NULL;
908 s->is_listen = is_listen;
909 s->is_telnet = is_telnet;
910 s->is_tn3270 = is_tn3270;
911 s->do_nodelay = do_nodelay;
912 if (sock->tls_creds) {
914 creds = object_resolve_path_component(
915 object_get_objects_root(), sock->tls_creds);
917 error_setg(errp, "No TLS credentials with id '%s'",
921 s->tls_creds = (QCryptoTLSCreds *)
922 object_dynamic_cast(creds,
923 TYPE_QCRYPTO_TLS_CREDS);
925 error_setg(errp, "Object with id '%s' is not TLS credentials",
929 object_ref(OBJECT(s->tls_creds));
931 if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
932 error_setg(errp, "%s",
933 "Expected TLS credentials for server endpoint");
937 if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
938 error_setg(errp, "%s",
939 "Expected TLS credentials for client endpoint");
945 s->addr = addr = socket_address_flatten(sock->addr);
947 qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE);
948 /* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */
949 if (addr->type == SOCKET_ADDRESS_TYPE_UNIX) {
950 qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS);
953 /* be isn't opened until we get a connection */
956 update_disconnected_filename(s);
959 if (is_telnet || is_tn3270) {
962 } else if (reconnect > 0) {
963 s->reconnect_time = reconnect;
966 if (s->reconnect_time) {
967 sioc = qio_channel_socket_new();
968 tcp_chr_set_client_ioc_name(chr, sioc);
969 qio_channel_socket_connect_async(sioc, s->addr,
970 qemu_chr_socket_connected,
975 s->listener = qio_net_listener_new();
977 name = g_strdup_printf("chardev-tcp-listener-%s", chr->label);
978 qio_net_listener_set_name(s->listener, name);
981 if (qio_net_listener_open_sync(s->listener, s->addr, errp) < 0) {
982 object_unref(OBJECT(s->listener));
987 qapi_free_SocketAddress(s->addr);
988 s->addr = socket_local_address(s->listener->sioc[0]->fd, errp);
989 update_disconnected_filename(s);
991 if (is_waitconnect &&
992 qemu_chr_wait_connected(chr, errp) < 0) {
996 qio_net_listener_set_client_func_full(s->listener,
1001 } else if (qemu_chr_wait_connected(chr, errp) < 0) {
1010 object_unref(OBJECT(sioc));
1014 static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
1017 bool is_listen = qemu_opt_get_bool(opts, "server", false);
1018 bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true);
1019 bool is_telnet = qemu_opt_get_bool(opts, "telnet", false);
1020 bool is_tn3270 = qemu_opt_get_bool(opts, "tn3270", false);
1021 bool do_nodelay = !qemu_opt_get_bool(opts, "delay", true);
1022 int64_t reconnect = qemu_opt_get_number(opts, "reconnect", 0);
1023 const char *path = qemu_opt_get(opts, "path");
1024 const char *host = qemu_opt_get(opts, "host");
1025 const char *port = qemu_opt_get(opts, "port");
1026 const char *tls_creds = qemu_opt_get(opts, "tls-creds");
1027 SocketAddressLegacy *addr;
1028 ChardevSocket *sock;
1030 backend->type = CHARDEV_BACKEND_KIND_SOCKET;
1033 error_setg(errp, "chardev: socket: no host given");
1037 error_setg(errp, "chardev: socket: no port given");
1042 error_setg(errp, "TLS can only be used over TCP socket");
1047 sock = backend->u.socket.data = g_new0(ChardevSocket, 1);
1048 qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock));
1050 sock->has_nodelay = true;
1051 sock->nodelay = do_nodelay;
1052 sock->has_server = true;
1053 sock->server = is_listen;
1054 sock->has_telnet = true;
1055 sock->telnet = is_telnet;
1056 sock->has_tn3270 = true;
1057 sock->tn3270 = is_tn3270;
1058 sock->has_wait = true;
1059 sock->wait = is_waitconnect;
1060 sock->has_reconnect = true;
1061 sock->reconnect = reconnect;
1062 sock->tls_creds = g_strdup(tls_creds);
1064 addr = g_new0(SocketAddressLegacy, 1);
1066 UnixSocketAddress *q_unix;
1067 addr->type = SOCKET_ADDRESS_LEGACY_KIND_UNIX;
1068 q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
1069 q_unix->path = g_strdup(path);
1071 addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET;
1072 addr->u.inet.data = g_new(InetSocketAddress, 1);
1073 *addr->u.inet.data = (InetSocketAddress) {
1074 .host = g_strdup(host),
1075 .port = g_strdup(port),
1076 .has_to = qemu_opt_get(opts, "to"),
1077 .to = qemu_opt_get_number(opts, "to", 0),
1078 .has_ipv4 = qemu_opt_get(opts, "ipv4"),
1079 .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0),
1080 .has_ipv6 = qemu_opt_get(opts, "ipv6"),
1081 .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
1088 char_socket_get_addr(Object *obj, Visitor *v, const char *name,
1089 void *opaque, Error **errp)
1091 SocketChardev *s = SOCKET_CHARDEV(obj);
1093 visit_type_SocketAddress(v, name, &s->addr, errp);
1097 char_socket_get_connected(Object *obj, Error **errp)
1099 SocketChardev *s = SOCKET_CHARDEV(obj);
1101 return s->connected;
1104 static void char_socket_class_init(ObjectClass *oc, void *data)
1106 ChardevClass *cc = CHARDEV_CLASS(oc);
1108 cc->parse = qemu_chr_parse_socket;
1109 cc->open = qmp_chardev_open_socket;
1110 cc->chr_wait_connected = tcp_chr_wait_connected;
1111 cc->chr_write = tcp_chr_write;
1112 cc->chr_sync_read = tcp_chr_sync_read;
1113 cc->chr_disconnect = tcp_chr_disconnect;
1114 cc->get_msgfds = tcp_get_msgfds;
1115 cc->set_msgfds = tcp_set_msgfds;
1116 cc->chr_add_client = tcp_chr_add_client;
1117 cc->chr_add_watch = tcp_chr_add_watch;
1118 cc->chr_update_read_handler = tcp_chr_update_read_handler;
1120 object_class_property_add(oc, "addr", "SocketAddress",
1121 char_socket_get_addr, NULL,
1122 NULL, NULL, &error_abort);
1124 object_class_property_add_bool(oc, "connected", char_socket_get_connected,
1125 NULL, &error_abort);
1128 static const TypeInfo char_socket_type_info = {
1129 .name = TYPE_CHARDEV_SOCKET,
1130 .parent = TYPE_CHARDEV,
1131 .instance_size = sizeof(SocketChardev),
1132 .instance_finalize = char_socket_finalize,
1133 .class_init = char_socket_class_init,
1136 static void register_types(void)
1138 type_register_static(&char_socket_type_info);
1141 type_init(register_types);