1 /* 2 * inet and unix socket functions for qemu 3 * 4 * (c) 2008 Gerd Hoffmann <kraxel@redhat.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; under version 2 of the License. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * Contributions after 2012-01-13 are licensed under the terms of the 16 * GNU GPL, version 2 or (at your option) any later version. 17 */ 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include <ctype.h> 22 #include <errno.h> 23 #include <unistd.h> 24 25 #include "monitor/monitor.h" 26 #include "qemu/sockets.h" 27 #include "qemu/main-loop.h" 28 29 #ifndef AI_ADDRCONFIG 30 # define AI_ADDRCONFIG 0 31 #endif 32 #ifndef AI_V4MAPPED 33 # define AI_V4MAPPED 0 34 #endif 35 36 /* used temporarily until all users are converted to QemuOpts */ 37 QemuOptsList socket_optslist = { 38 .name = "socket", 39 .head = QTAILQ_HEAD_INITIALIZER(socket_optslist.head), 40 .desc = { 41 { 42 .name = "path", 43 .type = QEMU_OPT_STRING, 44 },{ 45 .name = "host", 46 .type = QEMU_OPT_STRING, 47 },{ 48 .name = "port", 49 .type = QEMU_OPT_STRING, 50 },{ 51 .name = "localaddr", 52 .type = QEMU_OPT_STRING, 53 },{ 54 .name = "localport", 55 .type = QEMU_OPT_STRING, 56 },{ 57 .name = "to", 58 .type = QEMU_OPT_NUMBER, 59 },{ 60 .name = "ipv4", 61 .type = QEMU_OPT_BOOL, 62 },{ 63 .name = "ipv6", 64 .type = QEMU_OPT_BOOL, 65 }, 66 { /* end if list */ } 67 }, 68 }; 69 70 static int inet_getport(struct addrinfo *e) 71 { 72 struct sockaddr_in *i4; 73 struct sockaddr_in6 *i6; 74 75 switch (e->ai_family) { 76 case PF_INET6: 77 i6 = (void*)e->ai_addr; 78 return ntohs(i6->sin6_port); 79 case PF_INET: 80 i4 = (void*)e->ai_addr; 81 return ntohs(i4->sin_port); 82 default: 83 return 0; 84 } 85 } 86 87 static void inet_setport(struct addrinfo *e, int port) 88 { 89 struct sockaddr_in *i4; 90 struct sockaddr_in6 *i6; 91 92 switch (e->ai_family) { 93 case PF_INET6: 94 i6 = (void*)e->ai_addr; 95 i6->sin6_port = htons(port); 96 break; 97 case PF_INET: 98 i4 = (void*)e->ai_addr; 99 i4->sin_port = htons(port); 100 break; 101 } 102 } 103 104 NetworkAddressFamily inet_netfamily(int family) 105 { 106 switch (family) { 107 case PF_INET6: return NETWORK_ADDRESS_FAMILY_IPV6; 108 case PF_INET: return NETWORK_ADDRESS_FAMILY_IPV4; 109 case PF_UNIX: return NETWORK_ADDRESS_FAMILY_UNIX; 110 } 111 return NETWORK_ADDRESS_FAMILY_UNKNOWN; 112 } 113 114 int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp) 115 { 116 struct addrinfo ai,*res,*e; 117 const char *addr; 118 char port[33]; 119 char uaddr[INET6_ADDRSTRLEN+1]; 120 char uport[33]; 121 int slisten, rc, to, port_min, port_max, p; 122 123 memset(&ai,0, sizeof(ai)); 124 ai.ai_flags = AI_PASSIVE; 125 ai.ai_family = PF_UNSPEC; 126 ai.ai_socktype = SOCK_STREAM; 127 128 if ((qemu_opt_get(opts, "host") == NULL) || 129 (qemu_opt_get(opts, "port") == NULL)) { 130 error_setg(errp, "host and/or port not specified"); 131 return -1; 132 } 133 pstrcpy(port, sizeof(port), qemu_opt_get(opts, "port")); 134 addr = qemu_opt_get(opts, "host"); 135 136 to = qemu_opt_get_number(opts, "to", 0); 137 if (qemu_opt_get_bool(opts, "ipv4", 0)) 138 ai.ai_family = PF_INET; 139 if (qemu_opt_get_bool(opts, "ipv6", 0)) 140 ai.ai_family = PF_INET6; 141 142 /* lookup */ 143 if (port_offset) { 144 unsigned long long baseport; 145 if (parse_uint_full(port, &baseport, 10) < 0) { 146 error_setg(errp, "can't convert to a number: %s", port); 147 return -1; 148 } 149 if (baseport > 65535 || 150 baseport + port_offset > 65535) { 151 error_setg(errp, "port %s out of range", port); 152 return -1; 153 } 154 snprintf(port, sizeof(port), "%d", (int)baseport + port_offset); 155 } 156 rc = getaddrinfo(strlen(addr) ? addr : NULL, port, &ai, &res); 157 if (rc != 0) { 158 error_setg(errp, "address resolution failed for %s:%s: %s", addr, port, 159 gai_strerror(rc)); 160 return -1; 161 } 162 163 /* create socket + bind */ 164 for (e = res; e != NULL; e = e->ai_next) { 165 getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen, 166 uaddr,INET6_ADDRSTRLEN,uport,32, 167 NI_NUMERICHOST | NI_NUMERICSERV); 168 slisten = qemu_socket(e->ai_family, e->ai_socktype, e->ai_protocol); 169 if (slisten < 0) { 170 if (!e->ai_next) { 171 error_setg_errno(errp, errno, "Failed to create socket"); 172 } 173 continue; 174 } 175 176 socket_set_fast_reuse(slisten); 177 #ifdef IPV6_V6ONLY 178 if (e->ai_family == PF_INET6) { 179 /* listen on both ipv4 and ipv6 */ 180 const int off = 0; 181 qemu_setsockopt(slisten, IPPROTO_IPV6, IPV6_V6ONLY, &off, 182 sizeof(off)); 183 } 184 #endif 185 186 port_min = inet_getport(e); 187 port_max = to ? to + port_offset : port_min; 188 for (p = port_min; p <= port_max; p++) { 189 inet_setport(e, p); 190 if (bind(slisten, e->ai_addr, e->ai_addrlen) == 0) { 191 goto listen; 192 } 193 if (p == port_max) { 194 if (!e->ai_next) { 195 error_setg_errno(errp, errno, "Failed to bind socket"); 196 } 197 } 198 } 199 closesocket(slisten); 200 } 201 freeaddrinfo(res); 202 return -1; 203 204 listen: 205 if (listen(slisten,1) != 0) { 206 error_setg_errno(errp, errno, "Failed to listen on socket"); 207 closesocket(slisten); 208 freeaddrinfo(res); 209 return -1; 210 } 211 qemu_opt_set(opts, "host", uaddr, &error_abort); 212 qemu_opt_set_number(opts, "port", inet_getport(e) - port_offset, 213 &error_abort); 214 qemu_opt_set_bool(opts, "ipv6", e->ai_family == PF_INET6, 215 &error_abort); 216 qemu_opt_set_bool(opts, "ipv4", e->ai_family != PF_INET6, 217 &error_abort); 218 freeaddrinfo(res); 219 return slisten; 220 } 221 222 #ifdef _WIN32 223 #define QEMU_SOCKET_RC_INPROGRESS(rc) \ 224 ((rc) == -EINPROGRESS || (rc) == -EWOULDBLOCK || (rc) == -WSAEALREADY) 225 #else 226 #define QEMU_SOCKET_RC_INPROGRESS(rc) \ 227 ((rc) == -EINPROGRESS) 228 #endif 229 230 /* Struct to store connect state for non blocking connect */ 231 typedef struct ConnectState { 232 int fd; 233 struct addrinfo *addr_list; 234 struct addrinfo *current_addr; 235 NonBlockingConnectHandler *callback; 236 void *opaque; 237 } ConnectState; 238 239 static int inet_connect_addr(struct addrinfo *addr, bool *in_progress, 240 ConnectState *connect_state, Error **errp); 241 242 static void wait_for_connect(void *opaque) 243 { 244 ConnectState *s = opaque; 245 int val = 0, rc = 0; 246 socklen_t valsize = sizeof(val); 247 bool in_progress; 248 Error *err = NULL; 249 250 qemu_set_fd_handler(s->fd, NULL, NULL, NULL); 251 252 do { 253 rc = qemu_getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &val, &valsize); 254 } while (rc == -1 && socket_error() == EINTR); 255 256 /* update rc to contain error */ 257 if (!rc && val) { 258 rc = -1; 259 errno = val; 260 } 261 262 /* connect error */ 263 if (rc < 0) { 264 error_setg_errno(&err, errno, "Error connecting to socket"); 265 closesocket(s->fd); 266 s->fd = rc; 267 } 268 269 /* try to connect to the next address on the list */ 270 if (s->current_addr) { 271 while (s->current_addr->ai_next != NULL && s->fd < 0) { 272 s->current_addr = s->current_addr->ai_next; 273 s->fd = inet_connect_addr(s->current_addr, &in_progress, s, NULL); 274 if (s->fd < 0) { 275 error_free(err); 276 err = NULL; 277 error_setg_errno(&err, errno, "Unable to start socket connect"); 278 } 279 /* connect in progress */ 280 if (in_progress) { 281 goto out; 282 } 283 } 284 285 freeaddrinfo(s->addr_list); 286 } 287 288 if (s->callback) { 289 s->callback(s->fd, err, s->opaque); 290 } 291 g_free(s); 292 out: 293 error_free(err); 294 } 295 296 static int inet_connect_addr(struct addrinfo *addr, bool *in_progress, 297 ConnectState *connect_state, Error **errp) 298 { 299 int sock, rc; 300 301 *in_progress = false; 302 303 sock = qemu_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); 304 if (sock < 0) { 305 error_setg_errno(errp, errno, "Failed to create socket"); 306 return -1; 307 } 308 socket_set_fast_reuse(sock); 309 if (connect_state != NULL) { 310 qemu_set_nonblock(sock); 311 } 312 /* connect to peer */ 313 do { 314 rc = 0; 315 if (connect(sock, addr->ai_addr, addr->ai_addrlen) < 0) { 316 rc = -socket_error(); 317 } 318 } while (rc == -EINTR); 319 320 if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) { 321 connect_state->fd = sock; 322 qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state); 323 *in_progress = true; 324 } else if (rc < 0) { 325 error_setg_errno(errp, errno, "Failed to connect socket"); 326 closesocket(sock); 327 return -1; 328 } 329 return sock; 330 } 331 332 static struct addrinfo *inet_parse_connect_opts(QemuOpts *opts, Error **errp) 333 { 334 struct addrinfo ai, *res; 335 int rc; 336 const char *addr; 337 const char *port; 338 339 memset(&ai, 0, sizeof(ai)); 340 341 ai.ai_flags = AI_CANONNAME | AI_V4MAPPED | AI_ADDRCONFIG; 342 ai.ai_family = PF_UNSPEC; 343 ai.ai_socktype = SOCK_STREAM; 344 345 addr = qemu_opt_get(opts, "host"); 346 port = qemu_opt_get(opts, "port"); 347 if (addr == NULL || port == NULL) { 348 error_setg(errp, "host and/or port not specified"); 349 return NULL; 350 } 351 352 if (qemu_opt_get_bool(opts, "ipv4", 0)) { 353 ai.ai_family = PF_INET; 354 } 355 if (qemu_opt_get_bool(opts, "ipv6", 0)) { 356 ai.ai_family = PF_INET6; 357 } 358 359 /* lookup */ 360 rc = getaddrinfo(addr, port, &ai, &res); 361 if (rc != 0) { 362 error_setg(errp, "address resolution failed for %s:%s: %s", addr, port, 363 gai_strerror(rc)); 364 return NULL; 365 } 366 return res; 367 } 368 369 /** 370 * Create a socket and connect it to an address. 371 * 372 * @opts: QEMU options, recognized parameters strings "host" and "port", 373 * bools "ipv4" and "ipv6". 374 * @errp: set on error 375 * @callback: callback function for non-blocking connect 376 * @opaque: opaque for callback function 377 * 378 * Returns: -1 on error, file descriptor on success. 379 * 380 * If @callback is non-null, the connect is non-blocking. If this 381 * function succeeds, callback will be called when the connection 382 * completes, with the file descriptor on success, or -1 on error. 383 */ 384 int inet_connect_opts(QemuOpts *opts, Error **errp, 385 NonBlockingConnectHandler *callback, void *opaque) 386 { 387 Error *local_err = NULL; 388 struct addrinfo *res, *e; 389 int sock = -1; 390 bool in_progress; 391 ConnectState *connect_state = NULL; 392 393 res = inet_parse_connect_opts(opts, errp); 394 if (!res) { 395 return -1; 396 } 397 398 if (callback != NULL) { 399 connect_state = g_malloc0(sizeof(*connect_state)); 400 connect_state->addr_list = res; 401 connect_state->callback = callback; 402 connect_state->opaque = opaque; 403 } 404 405 for (e = res; e != NULL; e = e->ai_next) { 406 error_free(local_err); 407 local_err = NULL; 408 if (connect_state != NULL) { 409 connect_state->current_addr = e; 410 } 411 sock = inet_connect_addr(e, &in_progress, connect_state, &local_err); 412 if (sock >= 0) { 413 break; 414 } 415 } 416 417 if (sock < 0) { 418 error_propagate(errp, local_err); 419 } else if (in_progress) { 420 /* wait_for_connect() will do the rest */ 421 return sock; 422 } else { 423 if (callback) { 424 callback(sock, NULL, opaque); 425 } 426 } 427 g_free(connect_state); 428 freeaddrinfo(res); 429 return sock; 430 } 431 432 int inet_dgram_opts(QemuOpts *opts, Error **errp) 433 { 434 struct addrinfo ai, *peer = NULL, *local = NULL; 435 const char *addr; 436 const char *port; 437 int sock = -1, rc; 438 439 /* lookup peer addr */ 440 memset(&ai,0, sizeof(ai)); 441 ai.ai_flags = AI_CANONNAME | AI_V4MAPPED | AI_ADDRCONFIG; 442 ai.ai_family = PF_UNSPEC; 443 ai.ai_socktype = SOCK_DGRAM; 444 445 addr = qemu_opt_get(opts, "host"); 446 port = qemu_opt_get(opts, "port"); 447 if (addr == NULL || strlen(addr) == 0) { 448 addr = "localhost"; 449 } 450 if (port == NULL || strlen(port) == 0) { 451 error_setg(errp, "remote port not specified"); 452 return -1; 453 } 454 455 if (qemu_opt_get_bool(opts, "ipv4", 0)) 456 ai.ai_family = PF_INET; 457 if (qemu_opt_get_bool(opts, "ipv6", 0)) 458 ai.ai_family = PF_INET6; 459 460 if (0 != (rc = getaddrinfo(addr, port, &ai, &peer))) { 461 error_setg(errp, "address resolution failed for %s:%s: %s", addr, port, 462 gai_strerror(rc)); 463 return -1; 464 } 465 466 /* lookup local addr */ 467 memset(&ai,0, sizeof(ai)); 468 ai.ai_flags = AI_PASSIVE; 469 ai.ai_family = peer->ai_family; 470 ai.ai_socktype = SOCK_DGRAM; 471 472 addr = qemu_opt_get(opts, "localaddr"); 473 port = qemu_opt_get(opts, "localport"); 474 if (addr == NULL || strlen(addr) == 0) { 475 addr = NULL; 476 } 477 if (!port || strlen(port) == 0) 478 port = "0"; 479 480 if (0 != (rc = getaddrinfo(addr, port, &ai, &local))) { 481 error_setg(errp, "address resolution failed for %s:%s: %s", addr, port, 482 gai_strerror(rc)); 483 goto err; 484 } 485 486 /* create socket */ 487 sock = qemu_socket(peer->ai_family, peer->ai_socktype, peer->ai_protocol); 488 if (sock < 0) { 489 error_setg_errno(errp, errno, "Failed to create socket"); 490 goto err; 491 } 492 socket_set_fast_reuse(sock); 493 494 /* bind socket */ 495 if (bind(sock, local->ai_addr, local->ai_addrlen) < 0) { 496 error_setg_errno(errp, errno, "Failed to bind socket"); 497 goto err; 498 } 499 500 /* connect to peer */ 501 if (connect(sock,peer->ai_addr,peer->ai_addrlen) < 0) { 502 error_setg_errno(errp, errno, "Failed to connect socket"); 503 goto err; 504 } 505 506 freeaddrinfo(local); 507 freeaddrinfo(peer); 508 return sock; 509 510 err: 511 if (-1 != sock) 512 closesocket(sock); 513 if (local) 514 freeaddrinfo(local); 515 if (peer) 516 freeaddrinfo(peer); 517 return -1; 518 } 519 520 /* compatibility wrapper */ 521 InetSocketAddress *inet_parse(const char *str, Error **errp) 522 { 523 InetSocketAddress *addr; 524 const char *optstr, *h; 525 char host[65]; 526 char port[33]; 527 int to; 528 int pos; 529 530 addr = g_new0(InetSocketAddress, 1); 531 532 /* parse address */ 533 if (str[0] == ':') { 534 /* no host given */ 535 host[0] = '\0'; 536 if (1 != sscanf(str, ":%32[^,]%n", port, &pos)) { 537 error_setg(errp, "error parsing port in address '%s'", str); 538 goto fail; 539 } 540 } else if (str[0] == '[') { 541 /* IPv6 addr */ 542 if (2 != sscanf(str, "[%64[^]]]:%32[^,]%n", host, port, &pos)) { 543 error_setg(errp, "error parsing IPv6 address '%s'", str); 544 goto fail; 545 } 546 addr->ipv6 = addr->has_ipv6 = true; 547 } else { 548 /* hostname or IPv4 addr */ 549 if (2 != sscanf(str, "%64[^:]:%32[^,]%n", host, port, &pos)) { 550 error_setg(errp, "error parsing address '%s'", str); 551 goto fail; 552 } 553 if (host[strspn(host, "0123456789.")] == '\0') { 554 addr->ipv4 = addr->has_ipv4 = true; 555 } 556 } 557 558 addr->host = g_strdup(host); 559 addr->port = g_strdup(port); 560 561 /* parse options */ 562 optstr = str + pos; 563 h = strstr(optstr, ",to="); 564 if (h) { 565 h += 4; 566 if (sscanf(h, "%d%n", &to, &pos) != 1 || 567 (h[pos] != '\0' && h[pos] != ',')) { 568 error_setg(errp, "error parsing to= argument"); 569 goto fail; 570 } 571 addr->has_to = true; 572 addr->to = to; 573 } 574 if (strstr(optstr, ",ipv4")) { 575 addr->ipv4 = addr->has_ipv4 = true; 576 } 577 if (strstr(optstr, ",ipv6")) { 578 addr->ipv6 = addr->has_ipv6 = true; 579 } 580 return addr; 581 582 fail: 583 qapi_free_InetSocketAddress(addr); 584 return NULL; 585 } 586 587 static void inet_addr_to_opts(QemuOpts *opts, const InetSocketAddress *addr) 588 { 589 bool ipv4 = addr->has_ipv4 && addr->ipv4; 590 bool ipv6 = addr->has_ipv6 && addr->ipv6; 591 592 if (ipv4 || ipv6) { 593 qemu_opt_set_bool(opts, "ipv4", ipv4, &error_abort); 594 qemu_opt_set_bool(opts, "ipv6", ipv6, &error_abort); 595 } else if (addr->has_ipv4 || addr->has_ipv6) { 596 qemu_opt_set_bool(opts, "ipv4", !addr->has_ipv4, &error_abort); 597 qemu_opt_set_bool(opts, "ipv6", !addr->has_ipv6, &error_abort); 598 } 599 if (addr->has_to) { 600 qemu_opt_set_number(opts, "to", addr->to, &error_abort); 601 } 602 qemu_opt_set(opts, "host", addr->host, &error_abort); 603 qemu_opt_set(opts, "port", addr->port, &error_abort); 604 } 605 606 int inet_listen(const char *str, char *ostr, int olen, 607 int socktype, int port_offset, Error **errp) 608 { 609 QemuOpts *opts; 610 char *optstr; 611 int sock = -1; 612 InetSocketAddress *addr; 613 614 addr = inet_parse(str, errp); 615 if (addr != NULL) { 616 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 617 inet_addr_to_opts(opts, addr); 618 qapi_free_InetSocketAddress(addr); 619 sock = inet_listen_opts(opts, port_offset, errp); 620 if (sock != -1 && ostr) { 621 optstr = strchr(str, ','); 622 if (qemu_opt_get_bool(opts, "ipv6", 0)) { 623 snprintf(ostr, olen, "[%s]:%s%s", 624 qemu_opt_get(opts, "host"), 625 qemu_opt_get(opts, "port"), 626 optstr ? optstr : ""); 627 } else { 628 snprintf(ostr, olen, "%s:%s%s", 629 qemu_opt_get(opts, "host"), 630 qemu_opt_get(opts, "port"), 631 optstr ? optstr : ""); 632 } 633 } 634 qemu_opts_del(opts); 635 } 636 return sock; 637 } 638 639 /** 640 * Create a blocking socket and connect it to an address. 641 * 642 * @str: address string 643 * @errp: set in case of an error 644 * 645 * Returns -1 in case of error, file descriptor on success 646 **/ 647 int inet_connect(const char *str, Error **errp) 648 { 649 QemuOpts *opts; 650 int sock = -1; 651 InetSocketAddress *addr; 652 653 addr = inet_parse(str, errp); 654 if (addr != NULL) { 655 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 656 inet_addr_to_opts(opts, addr); 657 qapi_free_InetSocketAddress(addr); 658 sock = inet_connect_opts(opts, errp, NULL, NULL); 659 qemu_opts_del(opts); 660 } 661 return sock; 662 } 663 664 /** 665 * Create a non-blocking socket and connect it to an address. 666 * Calls the callback function with fd in case of success or -1 in case of 667 * error. 668 * 669 * @str: address string 670 * @callback: callback function that is called when connect completes, 671 * cannot be NULL. 672 * @opaque: opaque for callback function 673 * @errp: set in case of an error 674 * 675 * Returns: -1 on immediate error, file descriptor on success. 676 **/ 677 int inet_nonblocking_connect(const char *str, 678 NonBlockingConnectHandler *callback, 679 void *opaque, Error **errp) 680 { 681 QemuOpts *opts; 682 int sock = -1; 683 InetSocketAddress *addr; 684 685 g_assert(callback != NULL); 686 687 addr = inet_parse(str, errp); 688 if (addr != NULL) { 689 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 690 inet_addr_to_opts(opts, addr); 691 qapi_free_InetSocketAddress(addr); 692 sock = inet_connect_opts(opts, errp, callback, opaque); 693 qemu_opts_del(opts); 694 } 695 return sock; 696 } 697 698 #ifndef _WIN32 699 700 int unix_listen_opts(QemuOpts *opts, Error **errp) 701 { 702 struct sockaddr_un un; 703 const char *path = qemu_opt_get(opts, "path"); 704 int sock, fd; 705 706 sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0); 707 if (sock < 0) { 708 error_setg_errno(errp, errno, "Failed to create Unix socket"); 709 return -1; 710 } 711 712 memset(&un, 0, sizeof(un)); 713 un.sun_family = AF_UNIX; 714 if (path && strlen(path)) { 715 snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); 716 } else { 717 const char *tmpdir = getenv("TMPDIR"); 718 tmpdir = tmpdir ? tmpdir : "/tmp"; 719 if (snprintf(un.sun_path, sizeof(un.sun_path), "%s/qemu-socket-XXXXXX", 720 tmpdir) >= sizeof(un.sun_path)) { 721 error_setg_errno(errp, errno, 722 "TMPDIR environment variable (%s) too large", tmpdir); 723 goto err; 724 } 725 726 /* 727 * This dummy fd usage silences the mktemp() unsecure warning. 728 * Using mkstemp() doesn't make things more secure here 729 * though. bind() complains about existing files, so we have 730 * to unlink first and thus re-open the race window. The 731 * worst case possible is bind() failing, i.e. a DoS attack. 732 */ 733 fd = mkstemp(un.sun_path); 734 if (fd < 0) { 735 error_setg_errno(errp, errno, 736 "Failed to make a temporary socket name in %s", tmpdir); 737 goto err; 738 } 739 close(fd); 740 qemu_opt_set(opts, "path", un.sun_path, &error_abort); 741 } 742 743 if ((access(un.sun_path, F_OK) == 0) && 744 unlink(un.sun_path) < 0) { 745 error_setg_errno(errp, errno, 746 "Failed to unlink socket %s", un.sun_path); 747 goto err; 748 } 749 if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) { 750 error_setg_errno(errp, errno, "Failed to bind socket to %s", un.sun_path); 751 goto err; 752 } 753 if (listen(sock, 1) < 0) { 754 error_setg_errno(errp, errno, "Failed to listen on socket"); 755 goto err; 756 } 757 758 return sock; 759 760 err: 761 closesocket(sock); 762 return -1; 763 } 764 765 int unix_connect_opts(QemuOpts *opts, Error **errp, 766 NonBlockingConnectHandler *callback, void *opaque) 767 { 768 struct sockaddr_un un; 769 const char *path = qemu_opt_get(opts, "path"); 770 ConnectState *connect_state = NULL; 771 int sock, rc; 772 773 if (path == NULL) { 774 error_setg(errp, "unix connect: no path specified"); 775 return -1; 776 } 777 778 sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0); 779 if (sock < 0) { 780 error_setg_errno(errp, errno, "Failed to create socket"); 781 return -1; 782 } 783 if (callback != NULL) { 784 connect_state = g_malloc0(sizeof(*connect_state)); 785 connect_state->callback = callback; 786 connect_state->opaque = opaque; 787 qemu_set_nonblock(sock); 788 } 789 790 memset(&un, 0, sizeof(un)); 791 un.sun_family = AF_UNIX; 792 snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); 793 794 /* connect to peer */ 795 do { 796 rc = 0; 797 if (connect(sock, (struct sockaddr *) &un, sizeof(un)) < 0) { 798 rc = -socket_error(); 799 } 800 } while (rc == -EINTR); 801 802 if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) { 803 connect_state->fd = sock; 804 qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state); 805 return sock; 806 } else if (rc >= 0) { 807 /* non blocking socket immediate success, call callback */ 808 if (callback != NULL) { 809 callback(sock, NULL, opaque); 810 } 811 } 812 813 if (rc < 0) { 814 error_setg_errno(errp, -rc, "Failed to connect socket"); 815 close(sock); 816 sock = -1; 817 } 818 819 g_free(connect_state); 820 return sock; 821 } 822 823 #else 824 825 int unix_listen_opts(QemuOpts *opts, Error **errp) 826 { 827 error_setg(errp, "unix sockets are not available on windows"); 828 errno = ENOTSUP; 829 return -1; 830 } 831 832 int unix_connect_opts(QemuOpts *opts, Error **errp, 833 NonBlockingConnectHandler *callback, void *opaque) 834 { 835 error_setg(errp, "unix sockets are not available on windows"); 836 errno = ENOTSUP; 837 return -1; 838 } 839 #endif 840 841 /* compatibility wrapper */ 842 int unix_listen(const char *str, char *ostr, int olen, Error **errp) 843 { 844 QemuOpts *opts; 845 char *path, *optstr; 846 int sock, len; 847 848 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 849 850 optstr = strchr(str, ','); 851 if (optstr) { 852 len = optstr - str; 853 if (len) { 854 path = g_malloc(len+1); 855 snprintf(path, len+1, "%.*s", len, str); 856 qemu_opt_set(opts, "path", path, &error_abort); 857 g_free(path); 858 } 859 } else { 860 qemu_opt_set(opts, "path", str, &error_abort); 861 } 862 863 sock = unix_listen_opts(opts, errp); 864 865 if (sock != -1 && ostr) 866 snprintf(ostr, olen, "%s%s", qemu_opt_get(opts, "path"), optstr ? optstr : ""); 867 qemu_opts_del(opts); 868 return sock; 869 } 870 871 int unix_connect(const char *path, Error **errp) 872 { 873 QemuOpts *opts; 874 int sock; 875 876 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 877 qemu_opt_set(opts, "path", path, &error_abort); 878 sock = unix_connect_opts(opts, errp, NULL, NULL); 879 qemu_opts_del(opts); 880 return sock; 881 } 882 883 884 int unix_nonblocking_connect(const char *path, 885 NonBlockingConnectHandler *callback, 886 void *opaque, Error **errp) 887 { 888 QemuOpts *opts; 889 int sock = -1; 890 891 g_assert(callback != NULL); 892 893 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 894 qemu_opt_set(opts, "path", path, &error_abort); 895 sock = unix_connect_opts(opts, errp, callback, opaque); 896 qemu_opts_del(opts); 897 return sock; 898 } 899 900 SocketAddress *socket_parse(const char *str, Error **errp) 901 { 902 SocketAddress *addr; 903 904 addr = g_new0(SocketAddress, 1); 905 if (strstart(str, "unix:", NULL)) { 906 if (str[5] == '\0') { 907 error_setg(errp, "invalid Unix socket address"); 908 goto fail; 909 } else { 910 addr->kind = SOCKET_ADDRESS_KIND_UNIX; 911 addr->q_unix = g_new(UnixSocketAddress, 1); 912 addr->q_unix->path = g_strdup(str + 5); 913 } 914 } else if (strstart(str, "fd:", NULL)) { 915 if (str[3] == '\0') { 916 error_setg(errp, "invalid file descriptor address"); 917 goto fail; 918 } else { 919 addr->kind = SOCKET_ADDRESS_KIND_FD; 920 addr->fd = g_new(String, 1); 921 addr->fd->str = g_strdup(str + 3); 922 } 923 } else { 924 addr->kind = SOCKET_ADDRESS_KIND_INET; 925 addr->inet = inet_parse(str, errp); 926 if (addr->inet == NULL) { 927 goto fail; 928 } 929 } 930 return addr; 931 932 fail: 933 qapi_free_SocketAddress(addr); 934 return NULL; 935 } 936 937 int socket_connect(SocketAddress *addr, Error **errp, 938 NonBlockingConnectHandler *callback, void *opaque) 939 { 940 QemuOpts *opts; 941 int fd; 942 943 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 944 switch (addr->kind) { 945 case SOCKET_ADDRESS_KIND_INET: 946 inet_addr_to_opts(opts, addr->inet); 947 fd = inet_connect_opts(opts, errp, callback, opaque); 948 break; 949 950 case SOCKET_ADDRESS_KIND_UNIX: 951 qemu_opt_set(opts, "path", addr->q_unix->path, &error_abort); 952 fd = unix_connect_opts(opts, errp, callback, opaque); 953 break; 954 955 case SOCKET_ADDRESS_KIND_FD: 956 fd = monitor_get_fd(cur_mon, addr->fd->str, errp); 957 if (fd >= 0 && callback) { 958 qemu_set_nonblock(fd); 959 callback(fd, NULL, opaque); 960 } 961 break; 962 963 default: 964 abort(); 965 } 966 qemu_opts_del(opts); 967 return fd; 968 } 969 970 int socket_listen(SocketAddress *addr, Error **errp) 971 { 972 QemuOpts *opts; 973 int fd; 974 975 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 976 switch (addr->kind) { 977 case SOCKET_ADDRESS_KIND_INET: 978 inet_addr_to_opts(opts, addr->inet); 979 fd = inet_listen_opts(opts, 0, errp); 980 break; 981 982 case SOCKET_ADDRESS_KIND_UNIX: 983 qemu_opt_set(opts, "path", addr->q_unix->path, &error_abort); 984 fd = unix_listen_opts(opts, errp); 985 break; 986 987 case SOCKET_ADDRESS_KIND_FD: 988 fd = monitor_get_fd(cur_mon, addr->fd->str, errp); 989 break; 990 991 default: 992 abort(); 993 } 994 qemu_opts_del(opts); 995 return fd; 996 } 997 998 int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp) 999 { 1000 QemuOpts *opts; 1001 int fd; 1002 1003 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 1004 switch (remote->kind) { 1005 case SOCKET_ADDRESS_KIND_INET: 1006 inet_addr_to_opts(opts, remote->inet); 1007 if (local) { 1008 qemu_opt_set(opts, "localaddr", local->inet->host, &error_abort); 1009 qemu_opt_set(opts, "localport", local->inet->port, &error_abort); 1010 } 1011 fd = inet_dgram_opts(opts, errp); 1012 break; 1013 1014 default: 1015 error_setg(errp, "socket type unsupported for datagram"); 1016 fd = -1; 1017 } 1018 qemu_opts_del(opts); 1019 return fd; 1020 } 1021