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