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