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->ipv4 || !addr->has_ipv4; 590 bool ipv6 = addr->ipv6 || !addr->has_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 } 596 if (addr->has_to) { 597 qemu_opt_set_number(opts, "to", addr->to, &error_abort); 598 } 599 qemu_opt_set(opts, "host", addr->host, &error_abort); 600 qemu_opt_set(opts, "port", addr->port, &error_abort); 601 } 602 603 int inet_listen(const char *str, char *ostr, int olen, 604 int socktype, int port_offset, Error **errp) 605 { 606 QemuOpts *opts; 607 char *optstr; 608 int sock = -1; 609 InetSocketAddress *addr; 610 611 addr = inet_parse(str, errp); 612 if (addr != NULL) { 613 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 614 inet_addr_to_opts(opts, addr); 615 qapi_free_InetSocketAddress(addr); 616 sock = inet_listen_opts(opts, port_offset, errp); 617 if (sock != -1 && ostr) { 618 optstr = strchr(str, ','); 619 if (qemu_opt_get_bool(opts, "ipv6", 0)) { 620 snprintf(ostr, olen, "[%s]:%s%s", 621 qemu_opt_get(opts, "host"), 622 qemu_opt_get(opts, "port"), 623 optstr ? optstr : ""); 624 } else { 625 snprintf(ostr, olen, "%s:%s%s", 626 qemu_opt_get(opts, "host"), 627 qemu_opt_get(opts, "port"), 628 optstr ? optstr : ""); 629 } 630 } 631 qemu_opts_del(opts); 632 } 633 return sock; 634 } 635 636 /** 637 * Create a blocking socket and connect it to an address. 638 * 639 * @str: address string 640 * @errp: set in case of an error 641 * 642 * Returns -1 in case of error, file descriptor on success 643 **/ 644 int inet_connect(const char *str, Error **errp) 645 { 646 QemuOpts *opts; 647 int sock = -1; 648 InetSocketAddress *addr; 649 650 addr = inet_parse(str, errp); 651 if (addr != NULL) { 652 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 653 inet_addr_to_opts(opts, addr); 654 qapi_free_InetSocketAddress(addr); 655 sock = inet_connect_opts(opts, errp, NULL, NULL); 656 qemu_opts_del(opts); 657 } 658 return sock; 659 } 660 661 /** 662 * Create a non-blocking socket and connect it to an address. 663 * Calls the callback function with fd in case of success or -1 in case of 664 * error. 665 * 666 * @str: address string 667 * @callback: callback function that is called when connect completes, 668 * cannot be NULL. 669 * @opaque: opaque for callback function 670 * @errp: set in case of an error 671 * 672 * Returns: -1 on immediate error, file descriptor on success. 673 **/ 674 int inet_nonblocking_connect(const char *str, 675 NonBlockingConnectHandler *callback, 676 void *opaque, Error **errp) 677 { 678 QemuOpts *opts; 679 int sock = -1; 680 InetSocketAddress *addr; 681 682 g_assert(callback != NULL); 683 684 addr = inet_parse(str, errp); 685 if (addr != NULL) { 686 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 687 inet_addr_to_opts(opts, addr); 688 qapi_free_InetSocketAddress(addr); 689 sock = inet_connect_opts(opts, errp, callback, opaque); 690 qemu_opts_del(opts); 691 } 692 return sock; 693 } 694 695 #ifndef _WIN32 696 697 int unix_listen_opts(QemuOpts *opts, Error **errp) 698 { 699 struct sockaddr_un un; 700 const char *path = qemu_opt_get(opts, "path"); 701 int sock, fd; 702 703 sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0); 704 if (sock < 0) { 705 error_setg_errno(errp, errno, "Failed to create Unix socket"); 706 return -1; 707 } 708 709 memset(&un, 0, sizeof(un)); 710 un.sun_family = AF_UNIX; 711 if (path && strlen(path)) { 712 snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); 713 } else { 714 const char *tmpdir = getenv("TMPDIR"); 715 tmpdir = tmpdir ? tmpdir : "/tmp"; 716 if (snprintf(un.sun_path, sizeof(un.sun_path), "%s/qemu-socket-XXXXXX", 717 tmpdir) >= sizeof(un.sun_path)) { 718 error_setg_errno(errp, errno, 719 "TMPDIR environment variable (%s) too large", tmpdir); 720 goto err; 721 } 722 723 /* 724 * This dummy fd usage silences the mktemp() unsecure warning. 725 * Using mkstemp() doesn't make things more secure here 726 * though. bind() complains about existing files, so we have 727 * to unlink first and thus re-open the race window. The 728 * worst case possible is bind() failing, i.e. a DoS attack. 729 */ 730 fd = mkstemp(un.sun_path); 731 if (fd < 0) { 732 error_setg_errno(errp, errno, 733 "Failed to make a temporary socket name in %s", tmpdir); 734 goto err; 735 } 736 close(fd); 737 qemu_opt_set(opts, "path", un.sun_path, &error_abort); 738 } 739 740 if ((access(un.sun_path, F_OK) == 0) && 741 unlink(un.sun_path) < 0) { 742 error_setg_errno(errp, errno, 743 "Failed to unlink socket %s", un.sun_path); 744 goto err; 745 } 746 if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) { 747 error_setg_errno(errp, errno, "Failed to bind socket to %s", un.sun_path); 748 goto err; 749 } 750 if (listen(sock, 1) < 0) { 751 error_setg_errno(errp, errno, "Failed to listen on socket"); 752 goto err; 753 } 754 755 return sock; 756 757 err: 758 closesocket(sock); 759 return -1; 760 } 761 762 int unix_connect_opts(QemuOpts *opts, Error **errp, 763 NonBlockingConnectHandler *callback, void *opaque) 764 { 765 struct sockaddr_un un; 766 const char *path = qemu_opt_get(opts, "path"); 767 ConnectState *connect_state = NULL; 768 int sock, rc; 769 770 if (path == NULL) { 771 error_setg(errp, "unix connect: no path specified"); 772 return -1; 773 } 774 775 sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0); 776 if (sock < 0) { 777 error_setg_errno(errp, errno, "Failed to create socket"); 778 return -1; 779 } 780 if (callback != NULL) { 781 connect_state = g_malloc0(sizeof(*connect_state)); 782 connect_state->callback = callback; 783 connect_state->opaque = opaque; 784 qemu_set_nonblock(sock); 785 } 786 787 memset(&un, 0, sizeof(un)); 788 un.sun_family = AF_UNIX; 789 snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); 790 791 /* connect to peer */ 792 do { 793 rc = 0; 794 if (connect(sock, (struct sockaddr *) &un, sizeof(un)) < 0) { 795 rc = -socket_error(); 796 } 797 } while (rc == -EINTR); 798 799 if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) { 800 connect_state->fd = sock; 801 qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state); 802 return sock; 803 } else if (rc >= 0) { 804 /* non blocking socket immediate success, call callback */ 805 if (callback != NULL) { 806 callback(sock, NULL, opaque); 807 } 808 } 809 810 if (rc < 0) { 811 error_setg_errno(errp, -rc, "Failed to connect socket"); 812 close(sock); 813 sock = -1; 814 } 815 816 g_free(connect_state); 817 return sock; 818 } 819 820 #else 821 822 int unix_listen_opts(QemuOpts *opts, Error **errp) 823 { 824 error_setg(errp, "unix sockets are not available on windows"); 825 errno = ENOTSUP; 826 return -1; 827 } 828 829 int unix_connect_opts(QemuOpts *opts, Error **errp, 830 NonBlockingConnectHandler *callback, void *opaque) 831 { 832 error_setg(errp, "unix sockets are not available on windows"); 833 errno = ENOTSUP; 834 return -1; 835 } 836 #endif 837 838 /* compatibility wrapper */ 839 int unix_listen(const char *str, char *ostr, int olen, Error **errp) 840 { 841 QemuOpts *opts; 842 char *path, *optstr; 843 int sock, len; 844 845 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 846 847 optstr = strchr(str, ','); 848 if (optstr) { 849 len = optstr - str; 850 if (len) { 851 path = g_malloc(len+1); 852 snprintf(path, len+1, "%.*s", len, str); 853 qemu_opt_set(opts, "path", path, &error_abort); 854 g_free(path); 855 } 856 } else { 857 qemu_opt_set(opts, "path", str, &error_abort); 858 } 859 860 sock = unix_listen_opts(opts, errp); 861 862 if (sock != -1 && ostr) 863 snprintf(ostr, olen, "%s%s", qemu_opt_get(opts, "path"), optstr ? optstr : ""); 864 qemu_opts_del(opts); 865 return sock; 866 } 867 868 int unix_connect(const char *path, Error **errp) 869 { 870 QemuOpts *opts; 871 int sock; 872 873 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 874 qemu_opt_set(opts, "path", path, &error_abort); 875 sock = unix_connect_opts(opts, errp, NULL, NULL); 876 qemu_opts_del(opts); 877 return sock; 878 } 879 880 881 int unix_nonblocking_connect(const char *path, 882 NonBlockingConnectHandler *callback, 883 void *opaque, Error **errp) 884 { 885 QemuOpts *opts; 886 int sock = -1; 887 888 g_assert(callback != NULL); 889 890 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 891 qemu_opt_set(opts, "path", path, &error_abort); 892 sock = unix_connect_opts(opts, errp, callback, opaque); 893 qemu_opts_del(opts); 894 return sock; 895 } 896 897 SocketAddress *socket_parse(const char *str, Error **errp) 898 { 899 SocketAddress *addr; 900 901 addr = g_new0(SocketAddress, 1); 902 if (strstart(str, "unix:", NULL)) { 903 if (str[5] == '\0') { 904 error_setg(errp, "invalid Unix socket address"); 905 goto fail; 906 } else { 907 addr->kind = SOCKET_ADDRESS_KIND_UNIX; 908 addr->q_unix = g_new(UnixSocketAddress, 1); 909 addr->q_unix->path = g_strdup(str + 5); 910 } 911 } else if (strstart(str, "fd:", NULL)) { 912 if (str[3] == '\0') { 913 error_setg(errp, "invalid file descriptor address"); 914 goto fail; 915 } else { 916 addr->kind = SOCKET_ADDRESS_KIND_FD; 917 addr->fd = g_new(String, 1); 918 addr->fd->str = g_strdup(str + 3); 919 } 920 } else { 921 addr->kind = SOCKET_ADDRESS_KIND_INET; 922 addr->inet = inet_parse(str, errp); 923 if (addr->inet == NULL) { 924 goto fail; 925 } 926 } 927 return addr; 928 929 fail: 930 qapi_free_SocketAddress(addr); 931 return NULL; 932 } 933 934 int socket_connect(SocketAddress *addr, Error **errp, 935 NonBlockingConnectHandler *callback, void *opaque) 936 { 937 QemuOpts *opts; 938 int fd; 939 940 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 941 switch (addr->kind) { 942 case SOCKET_ADDRESS_KIND_INET: 943 inet_addr_to_opts(opts, addr->inet); 944 fd = inet_connect_opts(opts, errp, callback, opaque); 945 break; 946 947 case SOCKET_ADDRESS_KIND_UNIX: 948 qemu_opt_set(opts, "path", addr->q_unix->path, &error_abort); 949 fd = unix_connect_opts(opts, errp, callback, opaque); 950 break; 951 952 case SOCKET_ADDRESS_KIND_FD: 953 fd = monitor_get_fd(cur_mon, addr->fd->str, errp); 954 if (fd >= 0 && callback) { 955 qemu_set_nonblock(fd); 956 callback(fd, NULL, opaque); 957 } 958 break; 959 960 default: 961 abort(); 962 } 963 qemu_opts_del(opts); 964 return fd; 965 } 966 967 int socket_listen(SocketAddress *addr, Error **errp) 968 { 969 QemuOpts *opts; 970 int fd; 971 972 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 973 switch (addr->kind) { 974 case SOCKET_ADDRESS_KIND_INET: 975 inet_addr_to_opts(opts, addr->inet); 976 fd = inet_listen_opts(opts, 0, errp); 977 break; 978 979 case SOCKET_ADDRESS_KIND_UNIX: 980 qemu_opt_set(opts, "path", addr->q_unix->path, &error_abort); 981 fd = unix_listen_opts(opts, errp); 982 break; 983 984 case SOCKET_ADDRESS_KIND_FD: 985 fd = monitor_get_fd(cur_mon, addr->fd->str, errp); 986 break; 987 988 default: 989 abort(); 990 } 991 qemu_opts_del(opts); 992 return fd; 993 } 994 995 int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp) 996 { 997 QemuOpts *opts; 998 int fd; 999 1000 opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); 1001 switch (remote->kind) { 1002 case SOCKET_ADDRESS_KIND_INET: 1003 inet_addr_to_opts(opts, remote->inet); 1004 if (local) { 1005 qemu_opt_set(opts, "localaddr", local->inet->host, &error_abort); 1006 qemu_opt_set(opts, "localport", local->inet->port, &error_abort); 1007 } 1008 fd = inet_dgram_opts(opts, errp); 1009 break; 1010 1011 default: 1012 error_setg(errp, "socket type unsupported for datagram"); 1013 fd = -1; 1014 } 1015 qemu_opts_del(opts); 1016 return fd; 1017 } 1018