Lines Matching +full:async +full:- +full:prefix
4 * Copyright (c) 2003-2008 Fabrice Bellard
27 #include "io/channel-socket.h"
28 #include "io/channel-websock.h"
29 #include "qemu/error-report.h"
33 #include "qapi/clone-visitor.h"
34 #include "qapi/qapi-visit-sockets.h"
38 #include "chardev/char-io.h"
39 #include "chardev/char-socket.h"
50 assert(s->state == TCP_CHARDEV_STATE_DISCONNECTED); in tcp_chr_change_state()
53 assert(s->state == TCP_CHARDEV_STATE_CONNECTING); in tcp_chr_change_state()
56 s->state = state; in tcp_chr_change_state()
61 if (s->reconnect_timer) { in tcp_chr_reconn_timer_cancel()
62 g_source_destroy(s->reconnect_timer); in tcp_chr_reconn_timer_cancel()
63 g_source_unref(s->reconnect_timer); in tcp_chr_reconn_timer_cancel()
64 s->reconnect_timer = NULL; in tcp_chr_reconn_timer_cancel()
73 assert(s->state == TCP_CHARDEV_STATE_DISCONNECTED); in qemu_chr_socket_restart_timer()
74 assert(!s->reconnect_timer); in qemu_chr_socket_restart_timer()
75 name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label); in qemu_chr_socket_restart_timer()
76 s->reconnect_timer = qemu_chr_timeout_add_ms(chr, in qemu_chr_socket_restart_timer()
77 s->reconnect_time_ms, in qemu_chr_socket_restart_timer()
80 g_source_set_name(s->reconnect_timer, name); in qemu_chr_socket_restart_timer()
89 if (!s->connect_err_reported) { in check_report_connect_error()
92 chr->label); in check_report_connect_error()
93 s->connect_err_reported = true; in check_report_connect_error()
112 if (s->state == TCP_CHARDEV_STATE_CONNECTED) { in tcp_chr_write()
113 int ret = io_channel_send_full(s->ioc, buf, len, in tcp_chr_write()
114 s->write_msgfds, in tcp_chr_write()
115 s->write_msgfds_num); in tcp_chr_write()
121 && s->write_msgfds_num) { in tcp_chr_write()
122 g_free(s->write_msgfds); in tcp_chr_write()
123 s->write_msgfds = 0; in tcp_chr_write()
124 s->write_msgfds_num = 0; in tcp_chr_write()
130 trace_chr_socket_poll_err(chr, chr->label); in tcp_chr_write()
139 return -1; in tcp_chr_write()
147 if (s->state != TCP_CHARDEV_STATE_CONNECTED) { in tcp_chr_read_poll()
150 s->max_size = qemu_chr_be_can_write(chr); in tcp_chr_read_poll()
151 return s->max_size; in tcp_chr_read_poll()
179 if (s->do_telnetopt > 1) { in tcp_chr_process_IAC_bytes()
180 if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) { in tcp_chr_process_IAC_bytes()
186 s->do_telnetopt = 1; in tcp_chr_process_IAC_bytes()
189 && s->do_telnetopt == 2) { in tcp_chr_process_IAC_bytes()
192 s->do_telnetopt++; in tcp_chr_process_IAC_bytes()
193 } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_EOR in tcp_chr_process_IAC_bytes()
196 && s->do_telnetopt == 2) { in tcp_chr_process_IAC_bytes()
199 s->do_telnetopt++; in tcp_chr_process_IAC_bytes()
200 } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_IP in tcp_chr_process_IAC_bytes()
202 && s->do_telnetopt == 2) { in tcp_chr_process_IAC_bytes()
204 s->do_telnetopt++; in tcp_chr_process_IAC_bytes()
206 s->do_telnetopt++; in tcp_chr_process_IAC_bytes()
208 if (s->do_telnetopt >= 4) { in tcp_chr_process_IAC_bytes()
209 s->do_telnetopt = 1; in tcp_chr_process_IAC_bytes()
213 s->do_telnetopt = 2; in tcp_chr_process_IAC_bytes()
229 int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num; in tcp_get_msgfds()
236 memcpy(fds, s->read_msgfds, to_copy * sizeof(int)); in tcp_get_msgfds()
239 for (i = to_copy; i < s->read_msgfds_num; i++) { in tcp_get_msgfds()
240 close(s->read_msgfds[i]); in tcp_get_msgfds()
243 g_free(s->read_msgfds); in tcp_get_msgfds()
244 s->read_msgfds = 0; in tcp_get_msgfds()
245 s->read_msgfds_num = 0; in tcp_get_msgfds()
256 g_free(s->write_msgfds); in tcp_set_msgfds()
257 s->write_msgfds = NULL; in tcp_set_msgfds()
258 s->write_msgfds_num = 0; in tcp_set_msgfds()
260 if ((s->state != TCP_CHARDEV_STATE_CONNECTED) || in tcp_set_msgfds()
261 !qio_channel_has_feature(s->ioc, in tcp_set_msgfds()
263 return -1; in tcp_set_msgfds()
267 s->write_msgfds = g_new(int, num); in tcp_set_msgfds()
268 memcpy(s->write_msgfds, fds, num * sizeof(int)); in tcp_set_msgfds()
271 s->write_msgfds_num = num; in tcp_set_msgfds()
286 if (qio_channel_has_feature(s->ioc, QIO_CHANNEL_FEATURE_FD_PASS)) { in tcp_chr_recv()
287 ret = qio_channel_readv_full(s->ioc, &iov, 1, in tcp_chr_recv()
291 ret = qio_channel_readv_full(s->ioc, &iov, 1, in tcp_chr_recv()
298 for (i = 0; i < s->read_msgfds_num; i++) { in tcp_chr_recv()
299 close(s->read_msgfds[i]); in tcp_chr_recv()
302 if (s->read_msgfds_num) { in tcp_chr_recv()
303 g_free(s->read_msgfds); in tcp_chr_recv()
306 s->read_msgfds = msgfds; in tcp_chr_recv()
307 s->read_msgfds_num = msgfds_num; in tcp_chr_recv()
310 for (i = 0; i < s->read_msgfds_num; i++) { in tcp_chr_recv()
311 int fd = s->read_msgfds[i]; in tcp_chr_recv()
326 ret = -1; in tcp_chr_recv()
327 } else if (ret == -1) { in tcp_chr_recv()
328 trace_chr_socket_recv_err(chr, chr->label, error_get_pretty(err)); in tcp_chr_recv()
332 trace_chr_socket_recv_eof(chr, chr->label); in tcp_chr_recv()
341 if (!s->ioc) { in tcp_chr_add_watch()
344 return qio_channel_create_watch(s->ioc, cond); in tcp_chr_add_watch()
349 if (s->hup_source != NULL) { in remove_hup_source()
350 g_source_destroy(s->hup_source); in remove_hup_source()
351 g_source_unref(s->hup_source); in remove_hup_source()
352 s->hup_source = NULL; in remove_hup_source()
368 if (s->read_msgfds_num) { in tcp_chr_free_connection()
369 for (i = 0; i < s->read_msgfds_num; i++) { in tcp_chr_free_connection()
370 close(s->read_msgfds[i]); in tcp_chr_free_connection()
372 g_free(s->read_msgfds); in tcp_chr_free_connection()
373 s->read_msgfds = NULL; in tcp_chr_free_connection()
374 s->read_msgfds_num = 0; in tcp_chr_free_connection()
381 if (s->registered_yank && in tcp_chr_free_connection()
382 (s->state == TCP_CHARDEV_STATE_CONNECTING in tcp_chr_free_connection()
383 || s->state == TCP_CHARDEV_STATE_CONNECTED)) { in tcp_chr_free_connection()
384 yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label), in tcp_chr_free_connection()
386 QIO_CHANNEL(s->sioc)); in tcp_chr_free_connection()
389 if (s->ioc) { in tcp_chr_free_connection()
390 qio_channel_close(s->ioc, NULL); in tcp_chr_free_connection()
392 object_unref(OBJECT(s->sioc)); in tcp_chr_free_connection()
393 s->sioc = NULL; in tcp_chr_free_connection()
394 object_unref(OBJECT(s->ioc)); in tcp_chr_free_connection()
395 s->ioc = NULL; in tcp_chr_free_connection()
396 g_free(chr->filename); in tcp_chr_free_connection()
397 chr->filename = NULL; in tcp_chr_free_connection()
403 if (s->is_telnet) { in qemu_chr_socket_protocol()
406 return s->is_websock ? "websocket" : "tcp"; in qemu_chr_socket_protocol()
409 static char *qemu_chr_socket_address(SocketChardev *s, const char *prefix) in qemu_chr_socket_address() argument
411 switch (s->addr->type) { in qemu_chr_socket_address()
413 return g_strdup_printf("%s%s:%s:%s%s", prefix, in qemu_chr_socket_address()
415 s->addr->u.inet.host, in qemu_chr_socket_address()
416 s->addr->u.inet.port, in qemu_chr_socket_address()
417 s->is_listen ? ",server=on" : ""); in qemu_chr_socket_address()
422 UnixSocketAddress *sa = &s->addr->u.q_unix; in qemu_chr_socket_address()
425 if (sa->has_abstract && sa->abstract) { in qemu_chr_socket_address()
427 if (sa->has_tight && sa->tight) { in qemu_chr_socket_address()
433 return g_strdup_printf("%sunix:%s%s%s%s", prefix, sa->path, in qemu_chr_socket_address()
435 s->is_listen ? ",server=on" : ""); in qemu_chr_socket_address()
439 return g_strdup_printf("%sfd:%s%s", prefix, s->addr->u.fd.str, in qemu_chr_socket_address()
440 s->is_listen ? ",server=on" : ""); in qemu_chr_socket_address()
443 return g_strdup_printf("%svsock:%s:%s", prefix, in qemu_chr_socket_address()
444 s->addr->u.vsock.cid, in qemu_chr_socket_address()
445 s->addr->u.vsock.port); in qemu_chr_socket_address()
455 g_free(chr->filename); in update_disconnected_filename()
456 if (s->addr) { in update_disconnected_filename()
457 chr->filename = qemu_chr_socket_address(s, "disconnected:"); in update_disconnected_filename()
459 chr->filename = g_strdup("disconnected:socket"); in update_disconnected_filename()
465 * so can *not* assume s->state == TCP_CHARDEV_STATE_CONNECTED
466 * This must be called with chr->chr_write_lock held.
471 bool emit_close = s->state == TCP_CHARDEV_STATE_CONNECTED; in tcp_chr_disconnect_locked()
473 trace_chr_socket_disconnect(chr, chr->label); in tcp_chr_disconnect_locked()
476 if (s->listener) { in tcp_chr_disconnect_locked()
477 qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept, in tcp_chr_disconnect_locked()
478 chr, NULL, chr->gcontext); in tcp_chr_disconnect_locked()
484 if (s->reconnect_time_ms && !s->reconnect_timer) { in tcp_chr_disconnect_locked()
491 qemu_mutex_lock(&chr->chr_write_lock); in tcp_chr_disconnect()
493 qemu_mutex_unlock(&chr->chr_write_lock); in tcp_chr_disconnect()
503 if ((s->state != TCP_CHARDEV_STATE_CONNECTED) || in tcp_chr_read()
504 s->max_size <= 0) { in tcp_chr_read()
508 if (len > s->max_size) { in tcp_chr_read()
509 len = s->max_size; in tcp_chr_read()
512 if (size == 0 || (size == -1 && errno != EAGAIN)) { in tcp_chr_read()
516 if (s->do_telnetopt) { in tcp_chr_read()
532 trace_chr_socket_hangup(chr, chr->label); in tcp_chr_hup()
543 if (s->state != TCP_CHARDEV_STATE_CONNECTED) { in tcp_chr_sync_read()
547 qio_channel_set_blocking(s->ioc, true, NULL); in tcp_chr_sync_read()
550 if (s->state != TCP_CHARDEV_STATE_DISCONNECTED) { in tcp_chr_sync_read()
551 qio_channel_set_blocking(s->ioc, false, NULL); in tcp_chr_sync_read()
564 struct sockaddr_storage *ss = &s->sioc->localAddr; in qemu_chr_compute_filename()
565 struct sockaddr_storage *ps = &s->sioc->remoteAddr; in qemu_chr_compute_filename()
566 socklen_t ss_len = s->sioc->localAddrLen; in qemu_chr_compute_filename()
567 socklen_t ps_len = s->sioc->remoteAddrLen; in qemu_chr_compute_filename()
572 switch (ss->ss_family) { in qemu_chr_compute_filename()
574 if (s->is_listen) { in qemu_chr_compute_filename()
576 ((struct sockaddr_un *)(ss))->sun_path); in qemu_chr_compute_filename()
579 ((struct sockaddr_un *)(ps))->sun_path); in qemu_chr_compute_filename()
590 return g_strdup_printf("%s:%s%s%s:%s%s <-> %s%s%s:%s", in qemu_chr_compute_filename()
593 s->is_listen ? ",server=on" : "", in qemu_chr_compute_filename()
605 if (s->state != TCP_CHARDEV_STATE_CONNECTED) { in update_ioc_handlers()
610 chr->gsource = io_add_watch_poll(chr, s->ioc, in update_ioc_handlers()
613 chr->gcontext); in update_ioc_handlers()
616 s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP); in update_ioc_handlers()
632 g_source_set_priority(s->hup_source, G_PRIORITY_DEFAULT + 1); in update_ioc_handlers()
633 g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup, in update_ioc_handlers()
635 g_source_attach(s->hup_source, chr->gcontext); in update_ioc_handlers()
643 g_free(chr->filename); in tcp_chr_connect()
644 chr->filename = qemu_chr_compute_filename(s); in tcp_chr_connect()
653 if (s->telnet_source) { in tcp_chr_telnet_destroy()
654 g_source_destroy(s->telnet_source); in tcp_chr_telnet_destroy()
655 g_source_unref(s->telnet_source); in tcp_chr_telnet_destroy()
656 s->telnet_source = NULL; in tcp_chr_telnet_destroy()
664 if (s->listener && s->state == TCP_CHARDEV_STATE_DISCONNECTED) { in tcp_chr_update_read_handler()
670 qio_net_listener_set_client_func_full(s->listener, tcp_chr_accept, in tcp_chr_update_read_handler()
671 chr, NULL, chr->gcontext); in tcp_chr_update_read_handler()
674 if (s->telnet_source) { in tcp_chr_update_read_handler()
687 TCPChardevTelnetInit *init = s->telnet_init; in tcp_chr_telnet_init_io()
693 ret = qio_channel_write(ioc, init->buf, init->buflen, &err); in tcp_chr_telnet_init_io()
698 trace_chr_socket_write_err(chr, chr->label, error_get_pretty(err)); in tcp_chr_telnet_init_io()
704 init->buflen -= ret; in tcp_chr_telnet_init_io()
706 if (init->buflen == 0) { in tcp_chr_telnet_init_io()
711 memmove(init->buf, init->buf + ret, init->buflen); in tcp_chr_telnet_init_io()
716 g_free(s->telnet_init); in tcp_chr_telnet_init_io()
717 s->telnet_init = NULL; in tcp_chr_telnet_init_io()
718 g_source_unref(s->telnet_source); in tcp_chr_telnet_init_io()
719 s->telnet_source = NULL; in tcp_chr_telnet_init_io()
732 if (s->telnet_init) { in tcp_chr_telnet_init()
737 s->telnet_init = g_new0(TCPChardevTelnetInit, 1); in tcp_chr_telnet_init()
738 init = s->telnet_init; in tcp_chr_telnet_init()
747 if (!s->is_tn3270) { in tcp_chr_telnet_init()
748 init->buflen = 12; in tcp_chr_telnet_init()
751 IACSET(init->buf, 0xff, 0xfb, 0x01); /* IAC WILL ECHO */ in tcp_chr_telnet_init()
752 IACSET(init->buf, 0xff, 0xfb, 0x03); /* IAC WILL Suppress go ahead */ in tcp_chr_telnet_init()
753 IACSET(init->buf, 0xff, 0xfb, 0x00); /* IAC WILL Binary */ in tcp_chr_telnet_init()
754 IACSET(init->buf, 0xff, 0xfd, 0x00); /* IAC DO Binary */ in tcp_chr_telnet_init()
756 init->buflen = 21; in tcp_chr_telnet_init()
758 IACSET(init->buf, 0xff, 0xfd, 0x19); /* IAC DO EOR */ in tcp_chr_telnet_init()
759 IACSET(init->buf, 0xff, 0xfb, 0x19); /* IAC WILL EOR */ in tcp_chr_telnet_init()
760 IACSET(init->buf, 0xff, 0xfd, 0x00); /* IAC DO BINARY */ in tcp_chr_telnet_init()
761 IACSET(init->buf, 0xff, 0xfb, 0x00); /* IAC WILL BINARY */ in tcp_chr_telnet_init()
762 IACSET(init->buf, 0xff, 0xfd, 0x18); /* IAC DO TERMINAL TYPE */ in tcp_chr_telnet_init()
763 IACSET(init->buf, 0xff, 0xfa, 0x18); /* IAC SB TERMINAL TYPE */ in tcp_chr_telnet_init()
764 IACSET(init->buf, 0x01, 0xff, 0xf0); /* SEND IAC SE */ in tcp_chr_telnet_init()
770 s->telnet_source = qio_channel_add_watch_source(s->ioc, G_IO_OUT, in tcp_chr_telnet_init()
773 chr->gcontext); in tcp_chr_telnet_init()
784 trace_chr_socket_ws_handshake_err(chr, chr->label, in tcp_chr_websock_handshake()
789 if (s->do_telnetopt) { in tcp_chr_websock_handshake()
804 wioc = qio_channel_websock_new_server(s->ioc); in tcp_chr_websock_init()
806 name = g_strdup_printf("chardev-websocket-server-%s", chr->label); in tcp_chr_websock_init()
809 object_unref(OBJECT(s->ioc)); in tcp_chr_websock_init()
810 s->ioc = QIO_CHANNEL(wioc); in tcp_chr_websock_init()
824 trace_chr_socket_tls_handshake_err(chr, chr->label, in tcp_chr_tls_handshake()
829 if (s->is_websock) { in tcp_chr_tls_handshake()
831 } else if (s->do_telnetopt) { in tcp_chr_tls_handshake()
847 if (s->is_listen) { in tcp_chr_tls_init()
849 s->ioc, s->tls_creds, in tcp_chr_tls_init()
850 s->tls_authz, in tcp_chr_tls_init()
854 s->ioc, s->tls_creds, in tcp_chr_tls_init()
855 s->addr->u.inet.host, in tcp_chr_tls_init()
859 trace_chr_socket_tls_init_err(chr, chr->label, error_get_pretty(err)); in tcp_chr_tls_init()
864 name = g_strdup_printf("chardev-tls-%s-%s", in tcp_chr_tls_init()
865 s->is_listen ? "server" : "client", in tcp_chr_tls_init()
866 chr->label); in tcp_chr_tls_init()
869 object_unref(OBJECT(s->ioc)); in tcp_chr_tls_init()
870 s->ioc = QIO_CHANNEL(tioc); in tcp_chr_tls_init()
876 chr->gcontext); in tcp_chr_tls_init()
885 name = g_strdup_printf("chardev-tcp-%s-%s", in tcp_chr_set_client_ioc_name()
886 s->is_listen ? "server" : "client", in tcp_chr_set_client_ioc_name()
887 chr->label); in tcp_chr_set_client_ioc_name()
897 if (s->state != TCP_CHARDEV_STATE_CONNECTING) { in tcp_chr_new_client()
898 return -1; in tcp_chr_new_client()
901 s->ioc = QIO_CHANNEL(sioc); in tcp_chr_new_client()
903 s->sioc = sioc; in tcp_chr_new_client()
906 qio_channel_set_blocking(s->ioc, false, NULL); in tcp_chr_new_client()
908 if (s->do_nodelay) { in tcp_chr_new_client()
909 qio_channel_set_delay(s->ioc, false); in tcp_chr_new_client()
911 if (s->listener) { in tcp_chr_new_client()
912 qio_net_listener_set_client_func_full(s->listener, NULL, NULL, in tcp_chr_new_client()
913 NULL, chr->gcontext); in tcp_chr_new_client()
916 if (s->tls_creds) { in tcp_chr_new_client()
918 } else if (s->is_websock) { in tcp_chr_new_client()
920 } else if (s->do_telnetopt) { in tcp_chr_new_client()
936 if (s->state != TCP_CHARDEV_STATE_DISCONNECTED) { in tcp_chr_add_client()
937 return -1; in tcp_chr_add_client()
942 return -1; in tcp_chr_add_client()
946 if (s->registered_yank) { in tcp_chr_add_client()
947 yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), in tcp_chr_add_client()
965 if (s->registered_yank) { in tcp_chr_accept()
966 yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), in tcp_chr_accept()
980 if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) { in tcp_chr_connect_client_sync()
983 return -1; in tcp_chr_connect_client_sync()
985 if (s->registered_yank) { in tcp_chr_connect_client_sync()
986 yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), in tcp_chr_connect_client_sync()
1001 chr->filename); in tcp_chr_accept_server_sync()
1003 sioc = qio_net_listener_wait_client(s->listener); in tcp_chr_accept_server_sync()
1005 if (s->registered_yank) { in tcp_chr_accept_server_sync()
1006 yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), in tcp_chr_accept_server_sync()
1018 const char *opts[] = { "telnet", "tn3270", "websock", "tls-creds" }; in tcp_chr_wait_connected()
1019 bool optset[] = { s->is_telnet, s->is_tn3270, s->is_websock, s->tls_creds }; in tcp_chr_wait_connected()
1028 return -1; in tcp_chr_wait_connected()
1037 * - server in tcp_chr_wait_connected()
1038 * - wait -> CONNECTED in tcp_chr_wait_connected()
1039 * - nowait -> DISCONNECTED in tcp_chr_wait_connected()
1040 * - client in tcp_chr_wait_connected()
1041 * - reconnect == 0 -> CONNECTED in tcp_chr_wait_connected()
1042 * - reconnect != 0 -> CONNECTING in tcp_chr_wait_connected()
1045 if (s->state == TCP_CHARDEV_STATE_CONNECTING) { in tcp_chr_wait_connected()
1046 if (!s->connect_task) { in tcp_chr_wait_connected()
1050 return -1; in tcp_chr_wait_connected()
1054 * main loop thread associated with chr->gcontext, otherwise in tcp_chr_wait_connected()
1056 * free'ing of the s->connect_task object. in tcp_chr_wait_connected()
1063 g_main_context_acquire(chr->gcontext); in tcp_chr_wait_connected()
1064 qio_task_wait_thread(s->connect_task); in tcp_chr_wait_connected()
1065 g_main_context_release(chr->gcontext); in tcp_chr_wait_connected()
1069 * s->connect_task should have set this to NULL by the time in tcp_chr_wait_connected()
1072 assert(!s->connect_task); in tcp_chr_wait_connected()
1075 * NB we are *not* guaranteed to have "s->state == ..CONNECTED" in tcp_chr_wait_connected()
1081 while (s->state != TCP_CHARDEV_STATE_CONNECTED) { in tcp_chr_wait_connected()
1082 if (s->is_listen) { in tcp_chr_wait_connected()
1087 if (s->reconnect_time_ms) { in tcp_chr_wait_connected()
1089 g_usleep(s->reconnect_time_ms * 1000ULL); in tcp_chr_wait_connected()
1092 return -1; in tcp_chr_wait_connected()
1108 qapi_free_SocketAddress(s->addr); in char_socket_finalize()
1110 g_free(s->telnet_init); in char_socket_finalize()
1111 if (s->listener) { in char_socket_finalize()
1112 qio_net_listener_set_client_func_full(s->listener, NULL, NULL, in char_socket_finalize()
1113 NULL, chr->gcontext); in char_socket_finalize()
1114 object_unref(OBJECT(s->listener)); in char_socket_finalize()
1115 s->listener = NULL; in char_socket_finalize()
1117 if (s->tls_creds) { in char_socket_finalize()
1118 object_unref(OBJECT(s->tls_creds)); in char_socket_finalize()
1120 g_free(s->tls_authz); in char_socket_finalize()
1121 if (s->registered_yank) { in char_socket_finalize()
1123 * In the chardev-change special-case, we shouldn't unregister the yank in char_socket_finalize()
1126 if (!chr->handover_yank_instance) { in char_socket_finalize()
1127 yank_unregister_instance(CHARDEV_YANK_INSTANCE(chr->label)); in char_socket_finalize()
1141 s->connect_task = NULL; in qemu_chr_socket_connected()
1145 if (s->registered_yank) { in qemu_chr_socket_connected()
1146 yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label), in qemu_chr_socket_connected()
1154 s->connect_err_reported = false; in qemu_chr_socket_connected()
1183 if (s->registered_yank) { in tcp_chr_connect_client_async()
1184 yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), in tcp_chr_connect_client_async()
1194 * async APIs. Thus we must use QIOTask directly to implement in tcp_chr_connect_client_async()
1195 * the non-blocking concept locally. in tcp_chr_connect_client_async()
1197 s->connect_task = qio_task_new(OBJECT(sioc), in tcp_chr_connect_client_async()
1201 qio_task_run_in_thread(s->connect_task, in tcp_chr_connect_client_async()
1203 s->addr, in tcp_chr_connect_client_async()
1205 chr->gcontext); in tcp_chr_connect_client_async()
1213 qemu_mutex_lock(&chr->chr_write_lock); in socket_reconnect_timeout()
1214 g_source_unref(s->reconnect_timer); in socket_reconnect_timeout()
1215 s->reconnect_timer = NULL; in socket_reconnect_timeout()
1216 qemu_mutex_unlock(&chr->chr_write_lock); in socket_reconnect_timeout()
1218 if (chr->be_open) { in socket_reconnect_timeout()
1236 s->do_telnetopt = 1; in qmp_chardev_open_socket_server()
1238 s->listener = qio_net_listener_new(); in qmp_chardev_open_socket_server()
1240 name = g_strdup_printf("chardev-tcp-listener-%s", chr->label); in qmp_chardev_open_socket_server()
1241 qio_net_listener_set_name(s->listener, name); in qmp_chardev_open_socket_server()
1244 if (s->addr->type == SOCKET_ADDRESS_TYPE_FD && !*s->addr->u.fd.str) { in qmp_chardev_open_socket_server()
1248 if (qio_net_listener_open_sync(s->listener, s->addr, 1, errp) < 0) { in qmp_chardev_open_socket_server()
1249 object_unref(OBJECT(s->listener)); in qmp_chardev_open_socket_server()
1250 s->listener = NULL; in qmp_chardev_open_socket_server()
1251 return -1; in qmp_chardev_open_socket_server()
1254 qapi_free_SocketAddress(s->addr); in qmp_chardev_open_socket_server()
1255 s->addr = socket_local_address(s->listener->sioc[0]->fd, errp); in qmp_chardev_open_socket_server()
1263 qio_net_listener_set_client_func_full(s->listener, in qmp_chardev_open_socket_server()
1266 chr->gcontext); in qmp_chardev_open_socket_server()
1280 s->reconnect_time_ms = reconnect_ms; in qmp_chardev_open_socket_client()
1294 switch (addr->type) { in qmp_chardev_validate_socket()
1296 if (sock->has_reconnect) { in qmp_chardev_validate_socket()
1302 if (sock->tls_creds && in qmp_chardev_validate_socket()
1303 !(sock->has_server && sock->server)) { in qmp_chardev_validate_socket()
1312 if (sock->tls_creds) { in qmp_chardev_validate_socket()
1324 if (sock->tls_creds) { in qmp_chardev_validate_socket()
1335 if (sock->tls_authz && !sock->tls_creds) { in qmp_chardev_validate_socket()
1341 if (!sock->has_server || sock->server) { in qmp_chardev_validate_socket()
1342 if (sock->has_reconnect) { in qmp_chardev_validate_socket()
1349 if (sock->has_websocket && sock->websocket) { in qmp_chardev_validate_socket()
1353 if (sock->has_wait) { in qmp_chardev_validate_socket()
1361 if (sock->has_reconnect_ms && sock->has_reconnect) { in qmp_chardev_validate_socket()
1363 "'reconnect' and 'reconnect-ms' are mutually exclusive"); in qmp_chardev_validate_socket()
1377 ChardevSocket *sock = backend->u.socket.data; in qmp_chardev_open_socket()
1378 bool do_nodelay = sock->has_nodelay ? sock->nodelay : false; in qmp_chardev_open_socket()
1379 bool is_listen = sock->has_server ? sock->server : true; in qmp_chardev_open_socket()
1380 bool is_telnet = sock->has_telnet ? sock->telnet : false; in qmp_chardev_open_socket()
1381 bool is_tn3270 = sock->has_tn3270 ? sock->tn3270 : false; in qmp_chardev_open_socket()
1382 bool is_waitconnect = sock->has_wait ? sock->wait : false; in qmp_chardev_open_socket()
1383 bool is_websock = sock->has_websocket ? sock->websocket : false; in qmp_chardev_open_socket()
1387 s->is_listen = is_listen; in qmp_chardev_open_socket()
1388 s->is_telnet = is_telnet; in qmp_chardev_open_socket()
1389 s->is_tn3270 = is_tn3270; in qmp_chardev_open_socket()
1390 s->is_websock = is_websock; in qmp_chardev_open_socket()
1391 s->do_nodelay = do_nodelay; in qmp_chardev_open_socket()
1392 if (sock->tls_creds) { in qmp_chardev_open_socket()
1395 object_get_objects_root(), sock->tls_creds); in qmp_chardev_open_socket()
1398 sock->tls_creds); in qmp_chardev_open_socket()
1401 s->tls_creds = (QCryptoTLSCreds *) in qmp_chardev_open_socket()
1404 if (!s->tls_creds) { in qmp_chardev_open_socket()
1406 sock->tls_creds); in qmp_chardev_open_socket()
1409 object_ref(OBJECT(s->tls_creds)); in qmp_chardev_open_socket()
1410 if (!qcrypto_tls_creds_check_endpoint(s->tls_creds, in qmp_chardev_open_socket()
1418 s->tls_authz = g_strdup(sock->tls_authz); in qmp_chardev_open_socket()
1420 s->addr = addr = socket_address_flatten(sock->addr); in qmp_chardev_open_socket()
1429 if (addr->type == SOCKET_ADDRESS_TYPE_UNIX) { in qmp_chardev_open_socket()
1435 * In the chardev-change special-case, we shouldn't register a new yank in qmp_chardev_open_socket()
1438 if (!chr->handover_yank_instance) { in qmp_chardev_open_socket()
1439 if (!yank_register_instance(CHARDEV_YANK_INSTANCE(chr->label), errp)) { in qmp_chardev_open_socket()
1443 s->registered_yank = true; in qmp_chardev_open_socket()
1450 if (s->is_listen) { in qmp_chardev_open_socket()
1456 if (sock->has_reconnect) { in qmp_chardev_open_socket()
1457 reconnect_ms = sock->reconnect * 1000ULL; in qmp_chardev_open_socket()
1458 } else if (sock->has_reconnect_ms) { in qmp_chardev_open_socket()
1459 reconnect_ms = sock->reconnect_ms; in qmp_chardev_open_socket()
1493 backend->type = CHARDEV_BACKEND_KIND_SOCKET; in qemu_chr_parse_socket()
1494 sock = backend->u.socket.data = g_new0(ChardevSocket, 1); in qemu_chr_parse_socket()
1501 sock->has_nodelay = in qemu_chr_parse_socket()
1504 sock->nodelay = in qemu_chr_parse_socket()
1512 sock->has_server = true; in qemu_chr_parse_socket()
1513 sock->server = qemu_opt_get_bool(opts, "server", false); in qemu_chr_parse_socket()
1514 sock->has_telnet = qemu_opt_get(opts, "telnet"); in qemu_chr_parse_socket()
1515 sock->telnet = qemu_opt_get_bool(opts, "telnet", false); in qemu_chr_parse_socket()
1516 sock->has_tn3270 = qemu_opt_get(opts, "tn3270"); in qemu_chr_parse_socket()
1517 sock->tn3270 = qemu_opt_get_bool(opts, "tn3270", false); in qemu_chr_parse_socket()
1518 sock->has_websocket = qemu_opt_get(opts, "websocket"); in qemu_chr_parse_socket()
1519 sock->websocket = qemu_opt_get_bool(opts, "websocket", false); in qemu_chr_parse_socket()
1524 sock->has_wait = qemu_opt_find(opts, "wait") || sock->server; in qemu_chr_parse_socket()
1525 sock->wait = qemu_opt_get_bool(opts, "wait", true); in qemu_chr_parse_socket()
1526 sock->has_reconnect = qemu_opt_find(opts, "reconnect"); in qemu_chr_parse_socket()
1527 sock->reconnect = qemu_opt_get_number(opts, "reconnect", 0); in qemu_chr_parse_socket()
1528 sock->has_reconnect_ms = qemu_opt_find(opts, "reconnect-ms"); in qemu_chr_parse_socket()
1529 sock->reconnect_ms = qemu_opt_get_number(opts, "reconnect-ms", 0); in qemu_chr_parse_socket()
1531 sock->tls_creds = g_strdup(qemu_opt_get(opts, "tls-creds")); in qemu_chr_parse_socket()
1532 sock->tls_authz = g_strdup(qemu_opt_get(opts, "tls-authz")); in qemu_chr_parse_socket()
1537 addr->type = SOCKET_ADDRESS_TYPE_UNIX; in qemu_chr_parse_socket()
1538 q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1); in qemu_chr_parse_socket()
1539 q_unix->path = g_strdup(path); in qemu_chr_parse_socket()
1541 q_unix->has_tight = true; in qemu_chr_parse_socket()
1542 q_unix->tight = tight; in qemu_chr_parse_socket()
1543 q_unix->has_abstract = true; in qemu_chr_parse_socket()
1544 q_unix->abstract = abstract; in qemu_chr_parse_socket()
1547 addr->type = SOCKET_ADDRESS_TYPE_INET; in qemu_chr_parse_socket()
1548 addr->u.inet.data = g_new(InetSocketAddress, 1); in qemu_chr_parse_socket()
1549 *addr->u.inet.data = (InetSocketAddress) { in qemu_chr_parse_socket()
1560 addr->type = SOCKET_ADDRESS_TYPE_FD; in qemu_chr_parse_socket()
1561 addr->u.fd.data = g_new(FdSocketAddress, 1); in qemu_chr_parse_socket()
1562 addr->u.fd.data->str = g_strdup(fd); in qemu_chr_parse_socket()
1564 sock->addr = addr; in qemu_chr_parse_socket()
1573 visit_type_SocketAddress(v, name, &s->addr, errp); in char_socket_get_addr()
1581 return s->state == TCP_CHARDEV_STATE_CONNECTED; in char_socket_get_connected()
1588 cc->supports_yank = true; in char_socket_class_init()
1590 cc->parse = qemu_chr_parse_socket; in char_socket_class_init()
1591 cc->open = qmp_chardev_open_socket; in char_socket_class_init()
1592 cc->chr_wait_connected = tcp_chr_wait_connected; in char_socket_class_init()
1593 cc->chr_write = tcp_chr_write; in char_socket_class_init()
1594 cc->chr_sync_read = tcp_chr_sync_read; in char_socket_class_init()
1595 cc->chr_disconnect = tcp_chr_disconnect; in char_socket_class_init()
1596 cc->get_msgfds = tcp_get_msgfds; in char_socket_class_init()
1597 cc->set_msgfds = tcp_set_msgfds; in char_socket_class_init()
1598 cc->chr_add_client = tcp_chr_add_client; in char_socket_class_init()
1599 cc->chr_add_watch = tcp_chr_add_watch; in char_socket_class_init()
1600 cc->chr_update_read_handler = tcp_chr_update_read_handler; in char_socket_class_init()