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