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 #include "qemu/osdep.h" 25 #include "chardev/char.h" 26 #include "io/channel-socket.h" 27 #include "io/channel-tls.h" 28 #include "io/net-listener.h" 29 #include "qemu/error-report.h" 30 #include "qapi/error.h" 31 #include "qapi/clone-visitor.h" 32 33 #include "chardev/char-io.h" 34 35 /***********************************************************/ 36 /* TCP Net console */ 37 38 #define TCP_MAX_FDS 16 39 40 typedef struct { 41 Chardev parent; 42 QIOChannel *ioc; /* Client I/O channel */ 43 QIOChannelSocket *sioc; /* Client master channel */ 44 QIONetListener *listener; 45 QCryptoTLSCreds *tls_creds; 46 int connected; 47 int max_size; 48 int do_telnetopt; 49 int do_nodelay; 50 int *read_msgfds; 51 size_t read_msgfds_num; 52 int *write_msgfds; 53 size_t write_msgfds_num; 54 55 SocketAddress *addr; 56 bool is_listen; 57 bool is_telnet; 58 bool is_tn3270; 59 60 GSource *reconnect_timer; 61 int64_t reconnect_time; 62 bool connect_err_reported; 63 } SocketChardev; 64 65 #define SOCKET_CHARDEV(obj) \ 66 OBJECT_CHECK(SocketChardev, (obj), TYPE_CHARDEV_SOCKET) 67 68 static gboolean socket_reconnect_timeout(gpointer opaque); 69 70 static void tcp_chr_reconn_timer_cancel(SocketChardev *s) 71 { 72 if (s->reconnect_timer) { 73 g_source_destroy(s->reconnect_timer); 74 g_source_unref(s->reconnect_timer); 75 s->reconnect_timer = NULL; 76 } 77 } 78 79 static void qemu_chr_socket_restart_timer(Chardev *chr) 80 { 81 SocketChardev *s = SOCKET_CHARDEV(chr); 82 char *name; 83 84 assert(s->connected == 0); 85 name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label); 86 s->reconnect_timer = qemu_chr_timeout_add_ms(chr, 87 s->reconnect_time * 1000, 88 socket_reconnect_timeout, 89 chr); 90 g_source_set_name(s->reconnect_timer, name); 91 g_free(name); 92 } 93 94 static void check_report_connect_error(Chardev *chr, 95 Error *err) 96 { 97 SocketChardev *s = SOCKET_CHARDEV(chr); 98 99 if (!s->connect_err_reported) { 100 error_report("Unable to connect character device %s: %s", 101 chr->label, error_get_pretty(err)); 102 s->connect_err_reported = true; 103 } 104 qemu_chr_socket_restart_timer(chr); 105 } 106 107 static void tcp_chr_accept(QIONetListener *listener, 108 QIOChannelSocket *cioc, 109 void *opaque); 110 111 static int tcp_chr_read_poll(void *opaque); 112 static void tcp_chr_disconnect(Chardev *chr); 113 114 /* Called with chr_write_lock held. */ 115 static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len) 116 { 117 SocketChardev *s = SOCKET_CHARDEV(chr); 118 119 if (s->connected) { 120 int ret = io_channel_send_full(s->ioc, buf, len, 121 s->write_msgfds, 122 s->write_msgfds_num); 123 124 /* free the written msgfds, no matter what */ 125 if (s->write_msgfds_num) { 126 g_free(s->write_msgfds); 127 s->write_msgfds = 0; 128 s->write_msgfds_num = 0; 129 } 130 131 if (ret < 0 && errno != EAGAIN) { 132 if (tcp_chr_read_poll(chr) <= 0) { 133 tcp_chr_disconnect(chr); 134 return len; 135 } /* else let the read handler finish it properly */ 136 } 137 138 return ret; 139 } else { 140 /* XXX: indicate an error ? */ 141 return len; 142 } 143 } 144 145 static int tcp_chr_read_poll(void *opaque) 146 { 147 Chardev *chr = CHARDEV(opaque); 148 SocketChardev *s = SOCKET_CHARDEV(opaque); 149 if (!s->connected) { 150 return 0; 151 } 152 s->max_size = qemu_chr_be_can_write(chr); 153 return s->max_size; 154 } 155 156 static void tcp_chr_process_IAC_bytes(Chardev *chr, 157 SocketChardev *s, 158 uint8_t *buf, int *size) 159 { 160 /* Handle any telnet or tn3270 client's basic IAC options. 161 * For telnet options, it satisfies char by char mode with no echo. 162 * For tn3270 options, it satisfies binary mode with EOR. 163 * All IAC options will be removed from the buf and the do_opt 164 * pointer will be used to track the state of the width of the 165 * IAC information. 166 * 167 * RFC854: "All TELNET commands consist of at least a two byte sequence. 168 * The commands dealing with option negotiation are three byte sequences, 169 * the third byte being the code for the option referenced." 170 * "IAC BREAK", "IAC IP", "IAC NOP" and the double IAC are two bytes. 171 * "IAC SB", "IAC SE" and "IAC EOR" are saved to split up data boundary 172 * for tn3270. 173 * NOP, Break and Interrupt Process(IP) might be encountered during a TN3270 174 * session, and NOP and IP need to be done later. 175 */ 176 177 int i; 178 int j = 0; 179 180 for (i = 0; i < *size; i++) { 181 if (s->do_telnetopt > 1) { 182 if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) { 183 /* Double IAC means send an IAC */ 184 if (j != i) { 185 buf[j] = buf[i]; 186 } 187 j++; 188 s->do_telnetopt = 1; 189 } else { 190 if ((unsigned char)buf[i] == IAC_BREAK 191 && s->do_telnetopt == 2) { 192 /* Handle IAC break commands by sending a serial break */ 193 qemu_chr_be_event(chr, CHR_EVENT_BREAK); 194 s->do_telnetopt++; 195 } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_EOR 196 || (unsigned char)buf[i] == IAC_SB 197 || (unsigned char)buf[i] == IAC_SE) 198 && s->do_telnetopt == 2) { 199 buf[j++] = IAC; 200 buf[j++] = buf[i]; 201 s->do_telnetopt++; 202 } else if (s->is_tn3270 && ((unsigned char)buf[i] == IAC_IP 203 || (unsigned char)buf[i] == IAC_NOP) 204 && s->do_telnetopt == 2) { 205 /* TODO: IP and NOP need to be implemented later. */ 206 s->do_telnetopt++; 207 } 208 s->do_telnetopt++; 209 } 210 if (s->do_telnetopt >= 4) { 211 s->do_telnetopt = 1; 212 } 213 } else { 214 if ((unsigned char)buf[i] == IAC) { 215 s->do_telnetopt = 2; 216 } else { 217 if (j != i) { 218 buf[j] = buf[i]; 219 } 220 j++; 221 } 222 } 223 } 224 *size = j; 225 } 226 227 static int tcp_get_msgfds(Chardev *chr, int *fds, int num) 228 { 229 SocketChardev *s = SOCKET_CHARDEV(chr); 230 231 int to_copy = (s->read_msgfds_num < num) ? s->read_msgfds_num : num; 232 233 assert(num <= TCP_MAX_FDS); 234 235 if (to_copy) { 236 int i; 237 238 memcpy(fds, s->read_msgfds, to_copy * sizeof(int)); 239 240 /* Close unused fds */ 241 for (i = to_copy; i < s->read_msgfds_num; i++) { 242 close(s->read_msgfds[i]); 243 } 244 245 g_free(s->read_msgfds); 246 s->read_msgfds = 0; 247 s->read_msgfds_num = 0; 248 } 249 250 return to_copy; 251 } 252 253 static int tcp_set_msgfds(Chardev *chr, int *fds, int num) 254 { 255 SocketChardev *s = SOCKET_CHARDEV(chr); 256 257 /* clear old pending fd array */ 258 g_free(s->write_msgfds); 259 s->write_msgfds = NULL; 260 s->write_msgfds_num = 0; 261 262 if (!s->connected || 263 !qio_channel_has_feature(s->ioc, 264 QIO_CHANNEL_FEATURE_FD_PASS)) { 265 return -1; 266 } 267 268 if (num) { 269 s->write_msgfds = g_new(int, num); 270 memcpy(s->write_msgfds, fds, num * sizeof(int)); 271 } 272 273 s->write_msgfds_num = num; 274 275 return 0; 276 } 277 278 static ssize_t tcp_chr_recv(Chardev *chr, char *buf, size_t len) 279 { 280 SocketChardev *s = SOCKET_CHARDEV(chr); 281 struct iovec iov = { .iov_base = buf, .iov_len = len }; 282 int ret; 283 size_t i; 284 int *msgfds = NULL; 285 size_t msgfds_num = 0; 286 287 if (qio_channel_has_feature(s->ioc, QIO_CHANNEL_FEATURE_FD_PASS)) { 288 ret = qio_channel_readv_full(s->ioc, &iov, 1, 289 &msgfds, &msgfds_num, 290 NULL); 291 } else { 292 ret = qio_channel_readv_full(s->ioc, &iov, 1, 293 NULL, NULL, 294 NULL); 295 } 296 297 if (ret == QIO_CHANNEL_ERR_BLOCK) { 298 errno = EAGAIN; 299 ret = -1; 300 } else if (ret == -1) { 301 errno = EIO; 302 } 303 304 if (msgfds_num) { 305 /* close and clean read_msgfds */ 306 for (i = 0; i < s->read_msgfds_num; i++) { 307 close(s->read_msgfds[i]); 308 } 309 310 if (s->read_msgfds_num) { 311 g_free(s->read_msgfds); 312 } 313 314 s->read_msgfds = msgfds; 315 s->read_msgfds_num = msgfds_num; 316 } 317 318 for (i = 0; i < s->read_msgfds_num; i++) { 319 int fd = s->read_msgfds[i]; 320 if (fd < 0) { 321 continue; 322 } 323 324 /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */ 325 qemu_set_block(fd); 326 327 #ifndef MSG_CMSG_CLOEXEC 328 qemu_set_cloexec(fd); 329 #endif 330 } 331 332 return ret; 333 } 334 335 static GSource *tcp_chr_add_watch(Chardev *chr, GIOCondition cond) 336 { 337 SocketChardev *s = SOCKET_CHARDEV(chr); 338 return qio_channel_create_watch(s->ioc, cond); 339 } 340 341 static void tcp_chr_free_connection(Chardev *chr) 342 { 343 SocketChardev *s = SOCKET_CHARDEV(chr); 344 int i; 345 346 if (s->read_msgfds_num) { 347 for (i = 0; i < s->read_msgfds_num; i++) { 348 close(s->read_msgfds[i]); 349 } 350 g_free(s->read_msgfds); 351 s->read_msgfds = NULL; 352 s->read_msgfds_num = 0; 353 } 354 355 tcp_set_msgfds(chr, NULL, 0); 356 remove_fd_in_watch(chr); 357 object_unref(OBJECT(s->sioc)); 358 s->sioc = NULL; 359 object_unref(OBJECT(s->ioc)); 360 s->ioc = NULL; 361 g_free(chr->filename); 362 chr->filename = NULL; 363 s->connected = 0; 364 } 365 366 static char *SocketAddress_to_str(const char *prefix, SocketAddress *addr, 367 bool is_listen, bool is_telnet) 368 { 369 switch (addr->type) { 370 case SOCKET_ADDRESS_TYPE_INET: 371 return g_strdup_printf("%s%s:%s:%s%s", prefix, 372 is_telnet ? "telnet" : "tcp", 373 addr->u.inet.host, 374 addr->u.inet.port, 375 is_listen ? ",server" : ""); 376 break; 377 case SOCKET_ADDRESS_TYPE_UNIX: 378 return g_strdup_printf("%sunix:%s%s", prefix, 379 addr->u.q_unix.path, 380 is_listen ? ",server" : ""); 381 break; 382 case SOCKET_ADDRESS_TYPE_FD: 383 return g_strdup_printf("%sfd:%s%s", prefix, addr->u.fd.str, 384 is_listen ? ",server" : ""); 385 break; 386 case SOCKET_ADDRESS_TYPE_VSOCK: 387 return g_strdup_printf("%svsock:%s:%s", prefix, 388 addr->u.vsock.cid, 389 addr->u.vsock.port); 390 default: 391 abort(); 392 } 393 } 394 395 static void update_disconnected_filename(SocketChardev *s) 396 { 397 Chardev *chr = CHARDEV(s); 398 399 g_free(chr->filename); 400 chr->filename = SocketAddress_to_str("disconnected:", s->addr, 401 s->is_listen, s->is_telnet); 402 } 403 404 /* NB may be called even if tcp_chr_connect has not been 405 * reached, due to TLS or telnet initialization failure, 406 * so can *not* assume s->connected == true 407 */ 408 static void tcp_chr_disconnect(Chardev *chr) 409 { 410 SocketChardev *s = SOCKET_CHARDEV(chr); 411 bool emit_close = s->connected; 412 413 tcp_chr_free_connection(chr); 414 415 if (s->listener) { 416 qio_net_listener_set_client_func(s->listener, tcp_chr_accept, 417 chr, NULL); 418 } 419 update_disconnected_filename(s); 420 if (emit_close) { 421 qemu_chr_be_event(chr, CHR_EVENT_CLOSED); 422 } 423 if (s->reconnect_time) { 424 qemu_chr_socket_restart_timer(chr); 425 } 426 } 427 428 static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) 429 { 430 Chardev *chr = CHARDEV(opaque); 431 SocketChardev *s = SOCKET_CHARDEV(opaque); 432 uint8_t buf[CHR_READ_BUF_LEN]; 433 int len, size; 434 435 if (!s->connected || s->max_size <= 0) { 436 return TRUE; 437 } 438 len = sizeof(buf); 439 if (len > s->max_size) { 440 len = s->max_size; 441 } 442 size = tcp_chr_recv(chr, (void *)buf, len); 443 if (size == 0 || size == -1) { 444 /* connection closed */ 445 tcp_chr_disconnect(chr); 446 } else if (size > 0) { 447 if (s->do_telnetopt) { 448 tcp_chr_process_IAC_bytes(chr, s, buf, &size); 449 } 450 if (size > 0) { 451 qemu_chr_be_write(chr, buf, size); 452 } 453 } 454 455 return TRUE; 456 } 457 458 static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len) 459 { 460 SocketChardev *s = SOCKET_CHARDEV(chr); 461 int size; 462 463 if (!s->connected) { 464 return 0; 465 } 466 467 qio_channel_set_blocking(s->ioc, true, NULL); 468 size = tcp_chr_recv(chr, (void *) buf, len); 469 qio_channel_set_blocking(s->ioc, false, NULL); 470 if (size == 0) { 471 /* connection closed */ 472 tcp_chr_disconnect(chr); 473 } 474 475 return size; 476 } 477 478 static char *sockaddr_to_str(struct sockaddr_storage *ss, socklen_t ss_len, 479 struct sockaddr_storage *ps, socklen_t ps_len, 480 bool is_listen, bool is_telnet) 481 { 482 char shost[NI_MAXHOST], sserv[NI_MAXSERV]; 483 char phost[NI_MAXHOST], pserv[NI_MAXSERV]; 484 const char *left = "", *right = ""; 485 486 switch (ss->ss_family) { 487 #ifndef _WIN32 488 case AF_UNIX: 489 return g_strdup_printf("unix:%s%s", 490 ((struct sockaddr_un *)(ss))->sun_path, 491 is_listen ? ",server" : ""); 492 #endif 493 case AF_INET6: 494 left = "["; 495 right = "]"; 496 /* fall through */ 497 case AF_INET: 498 getnameinfo((struct sockaddr *) ss, ss_len, shost, sizeof(shost), 499 sserv, sizeof(sserv), NI_NUMERICHOST | NI_NUMERICSERV); 500 getnameinfo((struct sockaddr *) ps, ps_len, phost, sizeof(phost), 501 pserv, sizeof(pserv), NI_NUMERICHOST | NI_NUMERICSERV); 502 return g_strdup_printf("%s:%s%s%s:%s%s <-> %s%s%s:%s", 503 is_telnet ? "telnet" : "tcp", 504 left, shost, right, sserv, 505 is_listen ? ",server" : "", 506 left, phost, right, pserv); 507 508 default: 509 return g_strdup_printf("unknown"); 510 } 511 } 512 513 static void tcp_chr_connect(void *opaque) 514 { 515 Chardev *chr = CHARDEV(opaque); 516 SocketChardev *s = SOCKET_CHARDEV(opaque); 517 518 g_free(chr->filename); 519 chr->filename = sockaddr_to_str( 520 &s->sioc->localAddr, s->sioc->localAddrLen, 521 &s->sioc->remoteAddr, s->sioc->remoteAddrLen, 522 s->is_listen, s->is_telnet); 523 524 s->connected = 1; 525 if (s->ioc) { 526 chr->gsource = io_add_watch_poll(chr, s->ioc, 527 tcp_chr_read_poll, 528 tcp_chr_read, 529 chr, chr->gcontext); 530 } 531 qemu_chr_be_event(chr, CHR_EVENT_OPENED); 532 } 533 534 static void tcp_chr_update_read_handler(Chardev *chr) 535 { 536 SocketChardev *s = SOCKET_CHARDEV(chr); 537 538 if (!s->connected) { 539 return; 540 } 541 542 remove_fd_in_watch(chr); 543 if (s->ioc) { 544 chr->gsource = io_add_watch_poll(chr, s->ioc, 545 tcp_chr_read_poll, 546 tcp_chr_read, chr, 547 chr->gcontext); 548 } 549 } 550 551 typedef struct { 552 Chardev *chr; 553 char buf[21]; 554 size_t buflen; 555 } TCPChardevTelnetInit; 556 557 static gboolean tcp_chr_telnet_init_io(QIOChannel *ioc, 558 GIOCondition cond G_GNUC_UNUSED, 559 gpointer user_data) 560 { 561 TCPChardevTelnetInit *init = user_data; 562 ssize_t ret; 563 564 ret = qio_channel_write(ioc, init->buf, init->buflen, NULL); 565 if (ret < 0) { 566 if (ret == QIO_CHANNEL_ERR_BLOCK) { 567 ret = 0; 568 } else { 569 tcp_chr_disconnect(init->chr); 570 return FALSE; 571 } 572 } 573 init->buflen -= ret; 574 575 if (init->buflen == 0) { 576 tcp_chr_connect(init->chr); 577 return FALSE; 578 } 579 580 memmove(init->buf, init->buf + ret, init->buflen); 581 582 return TRUE; 583 } 584 585 static void tcp_chr_telnet_init(Chardev *chr) 586 { 587 SocketChardev *s = SOCKET_CHARDEV(chr); 588 TCPChardevTelnetInit *init = g_new0(TCPChardevTelnetInit, 1); 589 size_t n = 0; 590 591 #define IACSET(x, a, b, c) \ 592 do { \ 593 x[n++] = a; \ 594 x[n++] = b; \ 595 x[n++] = c; \ 596 } while (0) 597 598 init->chr = chr; 599 if (!s->is_tn3270) { 600 init->buflen = 12; 601 /* Prep the telnet negotion to put telnet in binary, 602 * no echo, single char mode */ 603 IACSET(init->buf, 0xff, 0xfb, 0x01); /* IAC WILL ECHO */ 604 IACSET(init->buf, 0xff, 0xfb, 0x03); /* IAC WILL Suppress go ahead */ 605 IACSET(init->buf, 0xff, 0xfb, 0x00); /* IAC WILL Binary */ 606 IACSET(init->buf, 0xff, 0xfd, 0x00); /* IAC DO Binary */ 607 } else { 608 init->buflen = 21; 609 /* Prep the TN3270 negotion based on RFC1576 */ 610 IACSET(init->buf, 0xff, 0xfd, 0x19); /* IAC DO EOR */ 611 IACSET(init->buf, 0xff, 0xfb, 0x19); /* IAC WILL EOR */ 612 IACSET(init->buf, 0xff, 0xfd, 0x00); /* IAC DO BINARY */ 613 IACSET(init->buf, 0xff, 0xfb, 0x00); /* IAC WILL BINARY */ 614 IACSET(init->buf, 0xff, 0xfd, 0x18); /* IAC DO TERMINAL TYPE */ 615 IACSET(init->buf, 0xff, 0xfa, 0x18); /* IAC SB TERMINAL TYPE */ 616 IACSET(init->buf, 0x01, 0xff, 0xf0); /* SEND IAC SE */ 617 } 618 619 #undef IACSET 620 621 qio_channel_add_watch( 622 s->ioc, G_IO_OUT, 623 tcp_chr_telnet_init_io, 624 init, NULL); 625 } 626 627 628 static void tcp_chr_tls_handshake(QIOTask *task, 629 gpointer user_data) 630 { 631 Chardev *chr = user_data; 632 SocketChardev *s = user_data; 633 634 if (qio_task_propagate_error(task, NULL)) { 635 tcp_chr_disconnect(chr); 636 } else { 637 /* tn3270 does not support TLS yet */ 638 if (s->do_telnetopt && !s->is_tn3270) { 639 tcp_chr_telnet_init(chr); 640 } else { 641 tcp_chr_connect(chr); 642 } 643 } 644 } 645 646 647 static void tcp_chr_tls_init(Chardev *chr) 648 { 649 SocketChardev *s = SOCKET_CHARDEV(chr); 650 QIOChannelTLS *tioc; 651 Error *err = NULL; 652 gchar *name; 653 654 if (s->is_listen) { 655 tioc = qio_channel_tls_new_server( 656 s->ioc, s->tls_creds, 657 NULL, /* XXX Use an ACL */ 658 &err); 659 } else { 660 tioc = qio_channel_tls_new_client( 661 s->ioc, s->tls_creds, 662 s->addr->u.inet.host, 663 &err); 664 } 665 if (tioc == NULL) { 666 error_free(err); 667 tcp_chr_disconnect(chr); 668 return; 669 } 670 name = g_strdup_printf("chardev-tls-%s-%s", 671 s->is_listen ? "server" : "client", 672 chr->label); 673 qio_channel_set_name(QIO_CHANNEL(tioc), name); 674 g_free(name); 675 object_unref(OBJECT(s->ioc)); 676 s->ioc = QIO_CHANNEL(tioc); 677 678 qio_channel_tls_handshake(tioc, 679 tcp_chr_tls_handshake, 680 chr, 681 NULL); 682 } 683 684 685 static void tcp_chr_set_client_ioc_name(Chardev *chr, 686 QIOChannelSocket *sioc) 687 { 688 SocketChardev *s = SOCKET_CHARDEV(chr); 689 char *name; 690 name = g_strdup_printf("chardev-tcp-%s-%s", 691 s->is_listen ? "server" : "client", 692 chr->label); 693 qio_channel_set_name(QIO_CHANNEL(sioc), name); 694 g_free(name); 695 696 } 697 698 static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc) 699 { 700 SocketChardev *s = SOCKET_CHARDEV(chr); 701 702 if (s->ioc != NULL) { 703 return -1; 704 } 705 706 s->ioc = QIO_CHANNEL(sioc); 707 object_ref(OBJECT(sioc)); 708 s->sioc = sioc; 709 object_ref(OBJECT(sioc)); 710 711 qio_channel_set_blocking(s->ioc, false, NULL); 712 713 if (s->do_nodelay) { 714 qio_channel_set_delay(s->ioc, false); 715 } 716 if (s->listener) { 717 qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL); 718 } 719 720 if (s->tls_creds) { 721 tcp_chr_tls_init(chr); 722 } else { 723 if (s->do_telnetopt) { 724 tcp_chr_telnet_init(chr); 725 } else { 726 tcp_chr_connect(chr); 727 } 728 } 729 730 return 0; 731 } 732 733 734 static int tcp_chr_add_client(Chardev *chr, int fd) 735 { 736 int ret; 737 QIOChannelSocket *sioc; 738 739 sioc = qio_channel_socket_new_fd(fd, NULL); 740 if (!sioc) { 741 return -1; 742 } 743 tcp_chr_set_client_ioc_name(chr, sioc); 744 ret = tcp_chr_new_client(chr, sioc); 745 object_unref(OBJECT(sioc)); 746 return ret; 747 } 748 749 static void tcp_chr_accept(QIONetListener *listener, 750 QIOChannelSocket *cioc, 751 void *opaque) 752 { 753 Chardev *chr = CHARDEV(opaque); 754 755 tcp_chr_set_client_ioc_name(chr, cioc); 756 tcp_chr_new_client(chr, cioc); 757 } 758 759 static int tcp_chr_wait_connected(Chardev *chr, Error **errp) 760 { 761 SocketChardev *s = SOCKET_CHARDEV(chr); 762 QIOChannelSocket *sioc; 763 764 /* It can't wait on s->connected, since it is set asynchronously 765 * in TLS and telnet cases, only wait for an accepted socket */ 766 while (!s->ioc) { 767 if (s->is_listen) { 768 info_report("QEMU waiting for connection on: %s", 769 chr->filename); 770 sioc = qio_net_listener_wait_client(s->listener); 771 tcp_chr_set_client_ioc_name(chr, sioc); 772 tcp_chr_new_client(chr, sioc); 773 object_unref(OBJECT(sioc)); 774 } else { 775 sioc = qio_channel_socket_new(); 776 tcp_chr_set_client_ioc_name(chr, sioc); 777 if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) { 778 object_unref(OBJECT(sioc)); 779 return -1; 780 } 781 tcp_chr_new_client(chr, sioc); 782 object_unref(OBJECT(sioc)); 783 } 784 } 785 786 return 0; 787 } 788 789 static void char_socket_finalize(Object *obj) 790 { 791 Chardev *chr = CHARDEV(obj); 792 SocketChardev *s = SOCKET_CHARDEV(obj); 793 794 tcp_chr_free_connection(chr); 795 tcp_chr_reconn_timer_cancel(s); 796 qapi_free_SocketAddress(s->addr); 797 if (s->listener) { 798 qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL); 799 object_unref(OBJECT(s->listener)); 800 } 801 if (s->tls_creds) { 802 object_unref(OBJECT(s->tls_creds)); 803 } 804 805 qemu_chr_be_event(chr, CHR_EVENT_CLOSED); 806 } 807 808 static void qemu_chr_socket_connected(QIOTask *task, void *opaque) 809 { 810 QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task)); 811 Chardev *chr = CHARDEV(opaque); 812 SocketChardev *s = SOCKET_CHARDEV(chr); 813 Error *err = NULL; 814 815 if (qio_task_propagate_error(task, &err)) { 816 check_report_connect_error(chr, err); 817 error_free(err); 818 goto cleanup; 819 } 820 821 s->connect_err_reported = false; 822 tcp_chr_new_client(chr, sioc); 823 824 cleanup: 825 object_unref(OBJECT(sioc)); 826 } 827 828 static gboolean socket_reconnect_timeout(gpointer opaque) 829 { 830 Chardev *chr = CHARDEV(opaque); 831 SocketChardev *s = SOCKET_CHARDEV(opaque); 832 QIOChannelSocket *sioc; 833 834 g_source_unref(s->reconnect_timer); 835 s->reconnect_timer = NULL; 836 837 if (chr->be_open) { 838 return false; 839 } 840 841 sioc = qio_channel_socket_new(); 842 tcp_chr_set_client_ioc_name(chr, sioc); 843 qio_channel_socket_connect_async(sioc, s->addr, 844 qemu_chr_socket_connected, 845 chr, NULL); 846 847 return false; 848 } 849 850 static void qmp_chardev_open_socket(Chardev *chr, 851 ChardevBackend *backend, 852 bool *be_opened, 853 Error **errp) 854 { 855 SocketChardev *s = SOCKET_CHARDEV(chr); 856 ChardevSocket *sock = backend->u.socket.data; 857 bool do_nodelay = sock->has_nodelay ? sock->nodelay : false; 858 bool is_listen = sock->has_server ? sock->server : true; 859 bool is_telnet = sock->has_telnet ? sock->telnet : false; 860 bool is_tn3270 = sock->has_tn3270 ? sock->tn3270 : false; 861 bool is_waitconnect = sock->has_wait ? sock->wait : false; 862 int64_t reconnect = sock->has_reconnect ? sock->reconnect : 0; 863 QIOChannelSocket *sioc = NULL; 864 SocketAddress *addr; 865 866 s->is_listen = is_listen; 867 s->is_telnet = is_telnet; 868 s->is_tn3270 = is_tn3270; 869 s->do_nodelay = do_nodelay; 870 if (sock->tls_creds) { 871 Object *creds; 872 creds = object_resolve_path_component( 873 object_get_objects_root(), sock->tls_creds); 874 if (!creds) { 875 error_setg(errp, "No TLS credentials with id '%s'", 876 sock->tls_creds); 877 goto error; 878 } 879 s->tls_creds = (QCryptoTLSCreds *) 880 object_dynamic_cast(creds, 881 TYPE_QCRYPTO_TLS_CREDS); 882 if (!s->tls_creds) { 883 error_setg(errp, "Object with id '%s' is not TLS credentials", 884 sock->tls_creds); 885 goto error; 886 } 887 object_ref(OBJECT(s->tls_creds)); 888 if (is_listen) { 889 if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) { 890 error_setg(errp, "%s", 891 "Expected TLS credentials for server endpoint"); 892 goto error; 893 } 894 } else { 895 if (s->tls_creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) { 896 error_setg(errp, "%s", 897 "Expected TLS credentials for client endpoint"); 898 goto error; 899 } 900 } 901 } 902 903 s->addr = addr = socket_address_flatten(sock->addr); 904 905 qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE); 906 /* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */ 907 if (addr->type == SOCKET_ADDRESS_TYPE_UNIX) { 908 qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS); 909 } 910 911 /* be isn't opened until we get a connection */ 912 *be_opened = false; 913 914 update_disconnected_filename(s); 915 916 if (is_listen) { 917 if (is_telnet || is_tn3270) { 918 s->do_telnetopt = 1; 919 } 920 } else if (reconnect > 0) { 921 s->reconnect_time = reconnect; 922 } 923 924 if (s->reconnect_time) { 925 sioc = qio_channel_socket_new(); 926 tcp_chr_set_client_ioc_name(chr, sioc); 927 qio_channel_socket_connect_async(sioc, s->addr, 928 qemu_chr_socket_connected, 929 chr, NULL); 930 } else { 931 if (s->is_listen) { 932 char *name; 933 s->listener = qio_net_listener_new(); 934 935 name = g_strdup_printf("chardev-tcp-listener-%s", chr->label); 936 qio_net_listener_set_name(s->listener, name); 937 g_free(name); 938 939 if (qio_net_listener_open_sync(s->listener, s->addr, errp) < 0) { 940 object_unref(OBJECT(s->listener)); 941 s->listener = NULL; 942 goto error; 943 } 944 945 qapi_free_SocketAddress(s->addr); 946 s->addr = socket_local_address(s->listener->sioc[0]->fd, errp); 947 update_disconnected_filename(s); 948 949 if (is_waitconnect && 950 qemu_chr_wait_connected(chr, errp) < 0) { 951 return; 952 } 953 if (!s->ioc) { 954 qio_net_listener_set_client_func(s->listener, tcp_chr_accept, 955 chr, NULL); 956 } 957 } else if (qemu_chr_wait_connected(chr, errp) < 0) { 958 goto error; 959 } 960 } 961 962 return; 963 964 error: 965 if (sioc) { 966 object_unref(OBJECT(sioc)); 967 } 968 } 969 970 static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, 971 Error **errp) 972 { 973 bool is_listen = qemu_opt_get_bool(opts, "server", false); 974 bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true); 975 bool is_telnet = qemu_opt_get_bool(opts, "telnet", false); 976 bool is_tn3270 = qemu_opt_get_bool(opts, "tn3270", false); 977 bool do_nodelay = !qemu_opt_get_bool(opts, "delay", true); 978 int64_t reconnect = qemu_opt_get_number(opts, "reconnect", 0); 979 const char *path = qemu_opt_get(opts, "path"); 980 const char *host = qemu_opt_get(opts, "host"); 981 const char *port = qemu_opt_get(opts, "port"); 982 const char *tls_creds = qemu_opt_get(opts, "tls-creds"); 983 SocketAddressLegacy *addr; 984 ChardevSocket *sock; 985 986 backend->type = CHARDEV_BACKEND_KIND_SOCKET; 987 if (!path) { 988 if (!host) { 989 error_setg(errp, "chardev: socket: no host given"); 990 return; 991 } 992 if (!port) { 993 error_setg(errp, "chardev: socket: no port given"); 994 return; 995 } 996 } else { 997 if (tls_creds) { 998 error_setg(errp, "TLS can only be used over TCP socket"); 999 return; 1000 } 1001 } 1002 1003 sock = backend->u.socket.data = g_new0(ChardevSocket, 1); 1004 qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock)); 1005 1006 sock->has_nodelay = true; 1007 sock->nodelay = do_nodelay; 1008 sock->has_server = true; 1009 sock->server = is_listen; 1010 sock->has_telnet = true; 1011 sock->telnet = is_telnet; 1012 sock->has_tn3270 = true; 1013 sock->tn3270 = is_tn3270; 1014 sock->has_wait = true; 1015 sock->wait = is_waitconnect; 1016 sock->has_reconnect = true; 1017 sock->reconnect = reconnect; 1018 sock->tls_creds = g_strdup(tls_creds); 1019 1020 addr = g_new0(SocketAddressLegacy, 1); 1021 if (path) { 1022 UnixSocketAddress *q_unix; 1023 addr->type = SOCKET_ADDRESS_LEGACY_KIND_UNIX; 1024 q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1); 1025 q_unix->path = g_strdup(path); 1026 } else { 1027 addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET; 1028 addr->u.inet.data = g_new(InetSocketAddress, 1); 1029 *addr->u.inet.data = (InetSocketAddress) { 1030 .host = g_strdup(host), 1031 .port = g_strdup(port), 1032 .has_to = qemu_opt_get(opts, "to"), 1033 .to = qemu_opt_get_number(opts, "to", 0), 1034 .has_ipv4 = qemu_opt_get(opts, "ipv4"), 1035 .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0), 1036 .has_ipv6 = qemu_opt_get(opts, "ipv6"), 1037 .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0), 1038 }; 1039 } 1040 sock->addr = addr; 1041 } 1042 1043 static void 1044 char_socket_get_addr(Object *obj, Visitor *v, const char *name, 1045 void *opaque, Error **errp) 1046 { 1047 SocketChardev *s = SOCKET_CHARDEV(obj); 1048 1049 visit_type_SocketAddress(v, name, &s->addr, errp); 1050 } 1051 1052 static bool 1053 char_socket_get_connected(Object *obj, Error **errp) 1054 { 1055 SocketChardev *s = SOCKET_CHARDEV(obj); 1056 1057 return s->connected; 1058 } 1059 1060 static void char_socket_class_init(ObjectClass *oc, void *data) 1061 { 1062 ChardevClass *cc = CHARDEV_CLASS(oc); 1063 1064 cc->parse = qemu_chr_parse_socket; 1065 cc->open = qmp_chardev_open_socket; 1066 cc->chr_wait_connected = tcp_chr_wait_connected; 1067 cc->chr_write = tcp_chr_write; 1068 cc->chr_sync_read = tcp_chr_sync_read; 1069 cc->chr_disconnect = tcp_chr_disconnect; 1070 cc->get_msgfds = tcp_get_msgfds; 1071 cc->set_msgfds = tcp_set_msgfds; 1072 cc->chr_add_client = tcp_chr_add_client; 1073 cc->chr_add_watch = tcp_chr_add_watch; 1074 cc->chr_update_read_handler = tcp_chr_update_read_handler; 1075 1076 object_class_property_add(oc, "addr", "SocketAddress", 1077 char_socket_get_addr, NULL, 1078 NULL, NULL, &error_abort); 1079 1080 object_class_property_add_bool(oc, "connected", char_socket_get_connected, 1081 NULL, &error_abort); 1082 } 1083 1084 static const TypeInfo char_socket_type_info = { 1085 .name = TYPE_CHARDEV_SOCKET, 1086 .parent = TYPE_CHARDEV, 1087 .instance_size = sizeof(SocketChardev), 1088 .instance_finalize = char_socket_finalize, 1089 .class_init = char_socket_class_init, 1090 }; 1091 1092 static void register_types(void) 1093 { 1094 type_register_static(&char_socket_type_info); 1095 } 1096 1097 type_init(register_types); 1098