qemu/util/qemu-sockets.c
<<
>>
Prefs
   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 "qemu/osdep.h"
  19
  20#include "monitor/monitor.h"
  21#include "qapi/error.h"
  22#include "qemu/sockets.h"
  23#include "qemu/main-loop.h"
  24#include "qapi/qmp-input-visitor.h"
  25#include "qapi/qmp-output-visitor.h"
  26#include "qapi-visit.h"
  27#include "qemu/cutils.h"
  28
  29#ifndef AI_ADDRCONFIG
  30# define AI_ADDRCONFIG 0
  31#endif
  32
  33#ifndef AI_V4MAPPED
  34# define AI_V4MAPPED 0
  35#endif
  36
  37
  38static int inet_getport(struct addrinfo *e)
  39{
  40    struct sockaddr_in *i4;
  41    struct sockaddr_in6 *i6;
  42
  43    switch (e->ai_family) {
  44    case PF_INET6:
  45        i6 = (void*)e->ai_addr;
  46        return ntohs(i6->sin6_port);
  47    case PF_INET:
  48        i4 = (void*)e->ai_addr;
  49        return ntohs(i4->sin_port);
  50    default:
  51        return 0;
  52    }
  53}
  54
  55static void inet_setport(struct addrinfo *e, int port)
  56{
  57    struct sockaddr_in *i4;
  58    struct sockaddr_in6 *i6;
  59
  60    switch (e->ai_family) {
  61    case PF_INET6:
  62        i6 = (void*)e->ai_addr;
  63        i6->sin6_port = htons(port);
  64        break;
  65    case PF_INET:
  66        i4 = (void*)e->ai_addr;
  67        i4->sin_port = htons(port);
  68        break;
  69    }
  70}
  71
  72NetworkAddressFamily inet_netfamily(int family)
  73{
  74    switch (family) {
  75    case PF_INET6: return NETWORK_ADDRESS_FAMILY_IPV6;
  76    case PF_INET:  return NETWORK_ADDRESS_FAMILY_IPV4;
  77    case PF_UNIX:  return NETWORK_ADDRESS_FAMILY_UNIX;
  78    }
  79    return NETWORK_ADDRESS_FAMILY_UNKNOWN;
  80}
  81
  82/*
  83 * Matrix we're trying to apply
  84 *
  85 *  ipv4  ipv6   family
  86 *   -     -       PF_UNSPEC
  87 *   -     f       PF_INET
  88 *   -     t       PF_INET6
  89 *   f     -       PF_INET6
  90 *   f     f       <error>
  91 *   f     t       PF_INET6
  92 *   t     -       PF_INET
  93 *   t     f       PF_INET
  94 *   t     t       PF_INET6
  95 *
  96 * NB, this matrix is only about getting the neccessary results
  97 * from getaddrinfo(). Some of the cases require further work
  98 * after reading results from getaddrinfo in order to fully
  99 * apply the logic the end user wants. eg with the last case
 100 * ipv4=t + ipv6=t + PF_INET6, getaddrinfo alone can only
 101 * guarantee the ipv6=t part of the request - we need more
 102 * checks to provide ipv4=t part of the guarantee. This is
 103 * outside scope of this method and not currently handled by
 104 * callers at all.
 105 */
 106static int inet_ai_family_from_address(InetSocketAddress *addr,
 107                                       Error **errp)
 108{
 109    if (addr->has_ipv6 && addr->has_ipv4 &&
 110        !addr->ipv6 && !addr->ipv4) {
 111        error_setg(errp, "Cannot disable IPv4 and IPv6 at same time");
 112        return PF_UNSPEC;
 113    }
 114    if ((addr->has_ipv6 && addr->ipv6) || (addr->has_ipv4 && !addr->ipv4)) {
 115        return PF_INET6;
 116    }
 117    if ((addr->has_ipv4 && addr->ipv4) || (addr->has_ipv6 && !addr->ipv6)) {
 118        return PF_INET;
 119    }
 120    return PF_UNSPEC;
 121}
 122
 123static int inet_listen_saddr(InetSocketAddress *saddr,
 124                             int port_offset,
 125                             bool update_addr,
 126                             Error **errp)
 127{
 128    struct addrinfo ai,*res,*e;
 129    char port[33];
 130    char uaddr[INET6_ADDRSTRLEN+1];
 131    char uport[33];
 132    int slisten, rc, port_min, port_max, p;
 133    Error *err = NULL;
 134
 135    memset(&ai,0, sizeof(ai));
 136    ai.ai_flags = AI_PASSIVE;
 137    ai.ai_family = inet_ai_family_from_address(saddr, &err);
 138    ai.ai_socktype = SOCK_STREAM;
 139
 140    if (err) {
 141        error_propagate(errp, err);
 142        return -1;
 143    }
 144
 145    if (saddr->host == NULL) {
 146        error_setg(errp, "host not specified");
 147        return -1;
 148    }
 149    if (saddr->port != NULL) {
 150        pstrcpy(port, sizeof(port), saddr->port);
 151    } else {
 152        port[0] = '\0';
 153    }
 154
 155    /* lookup */
 156    if (port_offset) {
 157        unsigned long long baseport;
 158        if (strlen(port) == 0) {
 159            error_setg(errp, "port not specified");
 160            return -1;
 161        }
 162        if (parse_uint_full(port, &baseport, 10) < 0) {
 163            error_setg(errp, "can't convert to a number: %s", port);
 164            return -1;
 165        }
 166        if (baseport > 65535 ||
 167            baseport + port_offset > 65535) {
 168            error_setg(errp, "port %s out of range", port);
 169            return -1;
 170        }
 171        snprintf(port, sizeof(port), "%d", (int)baseport + port_offset);
 172    }
 173    rc = getaddrinfo(strlen(saddr->host) ? saddr->host : NULL,
 174                     strlen(port) ? port : NULL, &ai, &res);
 175    if (rc != 0) {
 176        error_setg(errp, "address resolution failed for %s:%s: %s",
 177                   saddr->host, port, gai_strerror(rc));
 178        return -1;
 179    }
 180
 181    /* create socket + bind */
 182    for (e = res; e != NULL; e = e->ai_next) {
 183        getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen,
 184                        uaddr,INET6_ADDRSTRLEN,uport,32,
 185                        NI_NUMERICHOST | NI_NUMERICSERV);
 186        slisten = qemu_socket(e->ai_family, e->ai_socktype, e->ai_protocol);
 187        if (slisten < 0) {
 188            if (!e->ai_next) {
 189                error_setg_errno(errp, errno, "Failed to create socket");
 190            }
 191            continue;
 192        }
 193
 194        socket_set_fast_reuse(slisten);
 195#ifdef IPV6_V6ONLY
 196        if (e->ai_family == PF_INET6) {
 197            /* listen on both ipv4 and ipv6 */
 198            const int off = 0;
 199            qemu_setsockopt(slisten, IPPROTO_IPV6, IPV6_V6ONLY, &off,
 200                            sizeof(off));
 201        }
 202#endif
 203
 204        port_min = inet_getport(e);
 205        port_max = saddr->has_to ? saddr->to + port_offset : port_min;
 206        for (p = port_min; p <= port_max; p++) {
 207            inet_setport(e, p);
 208            if (bind(slisten, e->ai_addr, e->ai_addrlen) == 0) {
 209                goto listen;
 210            }
 211            if (p == port_max) {
 212                if (!e->ai_next) {
 213                    error_setg_errno(errp, errno, "Failed to bind socket");
 214                }
 215            }
 216        }
 217        closesocket(slisten);
 218    }
 219    freeaddrinfo(res);
 220    return -1;
 221
 222listen:
 223    if (listen(slisten,1) != 0) {
 224        error_setg_errno(errp, errno, "Failed to listen on socket");
 225        closesocket(slisten);
 226        freeaddrinfo(res);
 227        return -1;
 228    }
 229    if (update_addr) {
 230        g_free(saddr->host);
 231        saddr->host = g_strdup(uaddr);
 232        g_free(saddr->port);
 233        saddr->port = g_strdup_printf("%d",
 234                                      inet_getport(e) - port_offset);
 235        saddr->has_ipv6 = saddr->ipv6 = e->ai_family == PF_INET6;
 236        saddr->has_ipv4 = saddr->ipv4 = e->ai_family != PF_INET6;
 237    }
 238    freeaddrinfo(res);
 239    return slisten;
 240}
 241
 242#ifdef _WIN32
 243#define QEMU_SOCKET_RC_INPROGRESS(rc) \
 244    ((rc) == -EINPROGRESS || (rc) == -EWOULDBLOCK || (rc) == -WSAEALREADY)
 245#else
 246#define QEMU_SOCKET_RC_INPROGRESS(rc) \
 247    ((rc) == -EINPROGRESS)
 248#endif
 249
 250/* Struct to store connect state for non blocking connect */
 251typedef struct ConnectState {
 252    int fd;
 253    struct addrinfo *addr_list;
 254    struct addrinfo *current_addr;
 255    NonBlockingConnectHandler *callback;
 256    void *opaque;
 257} ConnectState;
 258
 259static int inet_connect_addr(struct addrinfo *addr, bool *in_progress,
 260                             ConnectState *connect_state, Error **errp);
 261
 262static void wait_for_connect(void *opaque)
 263{
 264    ConnectState *s = opaque;
 265    int val = 0, rc = 0;
 266    socklen_t valsize = sizeof(val);
 267    bool in_progress;
 268    Error *err = NULL;
 269
 270    qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
 271
 272    do {
 273        rc = qemu_getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &val, &valsize);
 274    } while (rc == -1 && errno == EINTR);
 275
 276    /* update rc to contain error */
 277    if (!rc && val) {
 278        rc = -1;
 279        errno = val;
 280    }
 281
 282    /* connect error */
 283    if (rc < 0) {
 284        error_setg_errno(&err, errno, "Error connecting to socket");
 285        closesocket(s->fd);
 286        s->fd = rc;
 287    }
 288
 289    /* try to connect to the next address on the list */
 290    if (s->current_addr) {
 291        while (s->current_addr->ai_next != NULL && s->fd < 0) {
 292            s->current_addr = s->current_addr->ai_next;
 293            s->fd = inet_connect_addr(s->current_addr, &in_progress, s, NULL);
 294            if (s->fd < 0) {
 295                error_free(err);
 296                err = NULL;
 297                error_setg_errno(&err, errno, "Unable to start socket connect");
 298            }
 299            /* connect in progress */
 300            if (in_progress) {
 301                goto out;
 302            }
 303        }
 304
 305        freeaddrinfo(s->addr_list);
 306    }
 307
 308    if (s->callback) {
 309        s->callback(s->fd, err, s->opaque);
 310    }
 311    g_free(s);
 312out:
 313    error_free(err);
 314}
 315
 316static int inet_connect_addr(struct addrinfo *addr, bool *in_progress,
 317                             ConnectState *connect_state, Error **errp)
 318{
 319    int sock, rc;
 320
 321    *in_progress = false;
 322
 323    sock = qemu_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
 324    if (sock < 0) {
 325        error_setg_errno(errp, errno, "Failed to create socket");
 326        return -1;
 327    }
 328    socket_set_fast_reuse(sock);
 329    if (connect_state != NULL) {
 330        qemu_set_nonblock(sock);
 331    }
 332    /* connect to peer */
 333    do {
 334        rc = 0;
 335        if (connect(sock, addr->ai_addr, addr->ai_addrlen) < 0) {
 336            rc = -errno;
 337        }
 338    } while (rc == -EINTR);
 339
 340    if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) {
 341        connect_state->fd = sock;
 342        qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state);
 343        *in_progress = true;
 344    } else if (rc < 0) {
 345        error_setg_errno(errp, errno, "Failed to connect socket");
 346        closesocket(sock);
 347        return -1;
 348    }
 349    return sock;
 350}
 351
 352static struct addrinfo *inet_parse_connect_saddr(InetSocketAddress *saddr,
 353                                                 Error **errp)
 354{
 355    struct addrinfo ai, *res;
 356    int rc;
 357    Error *err = NULL;
 358    static int useV4Mapped = 1;
 359
 360    memset(&ai, 0, sizeof(ai));
 361
 362    ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
 363    if (atomic_read(&useV4Mapped)) {
 364        ai.ai_flags |= AI_V4MAPPED;
 365    }
 366    ai.ai_family = inet_ai_family_from_address(saddr, &err);
 367    ai.ai_socktype = SOCK_STREAM;
 368
 369    if (err) {
 370        error_propagate(errp, err);
 371        return NULL;
 372    }
 373
 374    if (saddr->host == NULL || saddr->port == NULL) {
 375        error_setg(errp, "host and/or port not specified");
 376        return NULL;
 377    }
 378
 379    /* lookup */
 380    rc = getaddrinfo(saddr->host, saddr->port, &ai, &res);
 381
 382    /* At least FreeBSD and OS-X 10.6 declare AI_V4MAPPED but
 383     * then don't implement it in their getaddrinfo(). Detect
 384     * this and retry without the flag since that's preferrable
 385     * to a fatal error
 386     */
 387    if (rc == EAI_BADFLAGS &&
 388        (ai.ai_flags & AI_V4MAPPED)) {
 389        atomic_set(&useV4Mapped, 0);
 390        ai.ai_flags &= ~AI_V4MAPPED;
 391        rc = getaddrinfo(saddr->host, saddr->port, &ai, &res);
 392    }
 393    if (rc != 0) {
 394        error_setg(errp, "address resolution failed for %s:%s: %s",
 395                   saddr->host, saddr->port, gai_strerror(rc));
 396        return NULL;
 397    }
 398    return res;
 399}
 400
 401/**
 402 * Create a socket and connect it to an address.
 403 *
 404 * @saddr: Inet socket address specification
 405 * @errp: set on error
 406 * @callback: callback function for non-blocking connect
 407 * @opaque: opaque for callback function
 408 *
 409 * Returns: -1 on error, file descriptor on success.
 410 *
 411 * If @callback is non-null, the connect is non-blocking.  If this
 412 * function succeeds, callback will be called when the connection
 413 * completes, with the file descriptor on success, or -1 on error.
 414 */
 415static int inet_connect_saddr(InetSocketAddress *saddr, Error **errp,
 416                              NonBlockingConnectHandler *callback, void *opaque)
 417{
 418    Error *local_err = NULL;
 419    struct addrinfo *res, *e;
 420    int sock = -1;
 421    bool in_progress;
 422    ConnectState *connect_state = NULL;
 423
 424    res = inet_parse_connect_saddr(saddr, errp);
 425    if (!res) {
 426        return -1;
 427    }
 428
 429    if (callback != NULL) {
 430        connect_state = g_malloc0(sizeof(*connect_state));
 431        connect_state->addr_list = res;
 432        connect_state->callback = callback;
 433        connect_state->opaque = opaque;
 434    }
 435
 436    for (e = res; e != NULL; e = e->ai_next) {
 437        error_free(local_err);
 438        local_err = NULL;
 439        if (connect_state != NULL) {
 440            connect_state->current_addr = e;
 441        }
 442        sock = inet_connect_addr(e, &in_progress, connect_state, &local_err);
 443        if (sock >= 0) {
 444            break;
 445        }
 446    }
 447
 448    if (sock < 0) {
 449        error_propagate(errp, local_err);
 450    } else if (in_progress) {
 451        /* wait_for_connect() will do the rest */
 452        return sock;
 453    } else {
 454        if (callback) {
 455            callback(sock, NULL, opaque);
 456        }
 457    }
 458    g_free(connect_state);
 459    freeaddrinfo(res);
 460    return sock;
 461}
 462
 463static int inet_dgram_saddr(InetSocketAddress *sraddr,
 464                            InetSocketAddress *sladdr,
 465                            Error **errp)
 466{
 467    struct addrinfo ai, *peer = NULL, *local = NULL;
 468    const char *addr;
 469    const char *port;
 470    int sock = -1, rc;
 471    Error *err = NULL;
 472
 473    /* lookup peer addr */
 474    memset(&ai,0, sizeof(ai));
 475    ai.ai_flags = AI_CANONNAME | AI_V4MAPPED | AI_ADDRCONFIG;
 476    ai.ai_family = inet_ai_family_from_address(sraddr, &err);
 477    ai.ai_socktype = SOCK_DGRAM;
 478
 479    if (err) {
 480        error_propagate(errp, err);
 481        goto err;
 482    }
 483
 484    addr = sraddr->host;
 485    port = sraddr->port;
 486    if (addr == NULL || strlen(addr) == 0) {
 487        addr = "localhost";
 488    }
 489    if (port == NULL || strlen(port) == 0) {
 490        error_setg(errp, "remote port not specified");
 491        goto err;
 492    }
 493
 494    if (0 != (rc = getaddrinfo(addr, port, &ai, &peer))) {
 495        error_setg(errp, "address resolution failed for %s:%s: %s", addr, port,
 496                   gai_strerror(rc));
 497        goto err;
 498    }
 499
 500    /* lookup local addr */
 501    memset(&ai,0, sizeof(ai));
 502    ai.ai_flags = AI_PASSIVE;
 503    ai.ai_family = peer->ai_family;
 504    ai.ai_socktype = SOCK_DGRAM;
 505
 506    if (sladdr) {
 507        addr = sladdr->host;
 508        port = sladdr->port;
 509        if (addr == NULL || strlen(addr) == 0) {
 510            addr = NULL;
 511        }
 512        if (!port || strlen(port) == 0) {
 513            port = "0";
 514        }
 515    } else {
 516        addr = NULL;
 517        port = "0";
 518    }
 519
 520    if (0 != (rc = getaddrinfo(addr, port, &ai, &local))) {
 521        error_setg(errp, "address resolution failed for %s:%s: %s", addr, port,
 522                   gai_strerror(rc));
 523        goto err;
 524    }
 525
 526    /* create socket */
 527    sock = qemu_socket(peer->ai_family, peer->ai_socktype, peer->ai_protocol);
 528    if (sock < 0) {
 529        error_setg_errno(errp, errno, "Failed to create socket");
 530        goto err;
 531    }
 532    socket_set_fast_reuse(sock);
 533
 534    /* bind socket */
 535    if (bind(sock, local->ai_addr, local->ai_addrlen) < 0) {
 536        error_setg_errno(errp, errno, "Failed to bind socket");
 537        goto err;
 538    }
 539
 540    /* connect to peer */
 541    if (connect(sock,peer->ai_addr,peer->ai_addrlen) < 0) {
 542        error_setg_errno(errp, errno, "Failed to connect socket");
 543        goto err;
 544    }
 545
 546    freeaddrinfo(local);
 547    freeaddrinfo(peer);
 548    return sock;
 549
 550err:
 551    if (-1 != sock)
 552        closesocket(sock);
 553    if (local)
 554        freeaddrinfo(local);
 555    if (peer)
 556        freeaddrinfo(peer);
 557    return -1;
 558}
 559
 560/* compatibility wrapper */
 561InetSocketAddress *inet_parse(const char *str, Error **errp)
 562{
 563    InetSocketAddress *addr;
 564    const char *optstr, *h;
 565    char host[65];
 566    char port[33];
 567    int to;
 568    int pos;
 569
 570    addr = g_new0(InetSocketAddress, 1);
 571
 572    /* parse address */
 573    if (str[0] == ':') {
 574        /* no host given */
 575        host[0] = '\0';
 576        if (1 != sscanf(str, ":%32[^,]%n", port, &pos)) {
 577            error_setg(errp, "error parsing port in address '%s'", str);
 578            goto fail;
 579        }
 580    } else if (str[0] == '[') {
 581        /* IPv6 addr */
 582        if (2 != sscanf(str, "[%64[^]]]:%32[^,]%n", host, port, &pos)) {
 583            error_setg(errp, "error parsing IPv6 address '%s'", str);
 584            goto fail;
 585        }
 586        addr->ipv6 = addr->has_ipv6 = true;
 587    } else {
 588        /* hostname or IPv4 addr */
 589        if (2 != sscanf(str, "%64[^:]:%32[^,]%n", host, port, &pos)) {
 590            error_setg(errp, "error parsing address '%s'", str);
 591            goto fail;
 592        }
 593        if (host[strspn(host, "0123456789.")] == '\0') {
 594            addr->ipv4 = addr->has_ipv4 = true;
 595        }
 596    }
 597
 598    addr->host = g_strdup(host);
 599    addr->port = g_strdup(port);
 600
 601    /* parse options */
 602    optstr = str + pos;
 603    h = strstr(optstr, ",to=");
 604    if (h) {
 605        h += 4;
 606        if (sscanf(h, "%d%n", &to, &pos) != 1 ||
 607            (h[pos] != '\0' && h[pos] != ',')) {
 608            error_setg(errp, "error parsing to= argument");
 609            goto fail;
 610        }
 611        addr->has_to = true;
 612        addr->to = to;
 613    }
 614    if (strstr(optstr, ",ipv4")) {
 615        addr->ipv4 = addr->has_ipv4 = true;
 616    }
 617    if (strstr(optstr, ",ipv6")) {
 618        addr->ipv6 = addr->has_ipv6 = true;
 619    }
 620    return addr;
 621
 622fail:
 623    qapi_free_InetSocketAddress(addr);
 624    return NULL;
 625}
 626
 627int inet_listen(const char *str, char *ostr, int olen,
 628                int socktype, int port_offset, Error **errp)
 629{
 630    char *optstr;
 631    int sock = -1;
 632    InetSocketAddress *addr;
 633
 634    addr = inet_parse(str, errp);
 635    if (addr != NULL) {
 636        sock = inet_listen_saddr(addr, port_offset, true, errp);
 637        if (sock != -1 && ostr) {
 638            optstr = strchr(str, ',');
 639            if (addr->ipv6) {
 640                snprintf(ostr, olen, "[%s]:%s%s",
 641                         addr->host,
 642                         addr->port,
 643                         optstr ? optstr : "");
 644            } else {
 645                snprintf(ostr, olen, "%s:%s%s",
 646                         addr->host,
 647                         addr->port,
 648                         optstr ? optstr : "");
 649            }
 650        }
 651        qapi_free_InetSocketAddress(addr);
 652    }
 653    return sock;
 654}
 655
 656/**
 657 * Create a blocking socket and connect it to an address.
 658 *
 659 * @str: address string
 660 * @errp: set in case of an error
 661 *
 662 * Returns -1 in case of error, file descriptor on success
 663 **/
 664int inet_connect(const char *str, Error **errp)
 665{
 666    int sock = -1;
 667    InetSocketAddress *addr;
 668
 669    addr = inet_parse(str, errp);
 670    if (addr != NULL) {
 671        sock = inet_connect_saddr(addr, errp, NULL, NULL);
 672        qapi_free_InetSocketAddress(addr);
 673    }
 674    return sock;
 675}
 676
 677/**
 678 * Create a non-blocking socket and connect it to an address.
 679 * Calls the callback function with fd in case of success or -1 in case of
 680 * error.
 681 *
 682 * @str: address string
 683 * @callback: callback function that is called when connect completes,
 684 *            cannot be NULL.
 685 * @opaque: opaque for callback function
 686 * @errp: set in case of an error
 687 *
 688 * Returns: -1 on immediate error, file descriptor on success.
 689 **/
 690int inet_nonblocking_connect(const char *str,
 691                             NonBlockingConnectHandler *callback,
 692                             void *opaque, Error **errp)
 693{
 694    int sock = -1;
 695    InetSocketAddress *addr;
 696
 697    g_assert(callback != NULL);
 698
 699    addr = inet_parse(str, errp);
 700    if (addr != NULL) {
 701        sock = inet_connect_saddr(addr, errp, callback, opaque);
 702        qapi_free_InetSocketAddress(addr);
 703    }
 704    return sock;
 705}
 706
 707#ifndef _WIN32
 708
 709static int unix_listen_saddr(UnixSocketAddress *saddr,
 710                             bool update_addr,
 711                             Error **errp)
 712{
 713    struct sockaddr_un un;
 714    int sock, fd;
 715
 716    sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
 717    if (sock < 0) {
 718        error_setg_errno(errp, errno, "Failed to create Unix socket");
 719        return -1;
 720    }
 721
 722    memset(&un, 0, sizeof(un));
 723    un.sun_family = AF_UNIX;
 724    if (saddr->path && strlen(saddr->path)) {
 725        snprintf(un.sun_path, sizeof(un.sun_path), "%s", saddr->path);
 726    } else {
 727        const char *tmpdir = getenv("TMPDIR");
 728        tmpdir = tmpdir ? tmpdir : "/tmp";
 729        if (snprintf(un.sun_path, sizeof(un.sun_path), "%s/qemu-socket-XXXXXX",
 730                     tmpdir) >= sizeof(un.sun_path)) {
 731            error_setg_errno(errp, errno,
 732                             "TMPDIR environment variable (%s) too large", tmpdir);
 733            goto err;
 734        }
 735
 736        /*
 737         * This dummy fd usage silences the mktemp() unsecure warning.
 738         * Using mkstemp() doesn't make things more secure here
 739         * though.  bind() complains about existing files, so we have
 740         * to unlink first and thus re-open the race window.  The
 741         * worst case possible is bind() failing, i.e. a DoS attack.
 742         */
 743        fd = mkstemp(un.sun_path);
 744        if (fd < 0) {
 745            error_setg_errno(errp, errno,
 746                             "Failed to make a temporary socket name in %s", tmpdir);
 747            goto err;
 748        }
 749        close(fd);
 750        if (update_addr) {
 751            g_free(saddr->path);
 752            saddr->path = g_strdup(un.sun_path);
 753        }
 754    }
 755
 756    if (unlink(un.sun_path) < 0 && errno != ENOENT) {
 757        error_setg_errno(errp, errno,
 758                         "Failed to unlink socket %s", un.sun_path);
 759        goto err;
 760    }
 761    if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) {
 762        error_setg_errno(errp, errno, "Failed to bind socket to %s", un.sun_path);
 763        goto err;
 764    }
 765    if (listen(sock, 1) < 0) {
 766        error_setg_errno(errp, errno, "Failed to listen on socket");
 767        goto err;
 768    }
 769
 770    return sock;
 771
 772err:
 773    closesocket(sock);
 774    return -1;
 775}
 776
 777static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp,
 778                              NonBlockingConnectHandler *callback, void *opaque)
 779{
 780    struct sockaddr_un un;
 781    ConnectState *connect_state = NULL;
 782    int sock, rc;
 783
 784    if (saddr->path == NULL) {
 785        error_setg(errp, "unix connect: no path specified");
 786        return -1;
 787    }
 788
 789    sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
 790    if (sock < 0) {
 791        error_setg_errno(errp, errno, "Failed to create socket");
 792        return -1;
 793    }
 794    if (callback != NULL) {
 795        connect_state = g_malloc0(sizeof(*connect_state));
 796        connect_state->callback = callback;
 797        connect_state->opaque = opaque;
 798        qemu_set_nonblock(sock);
 799    }
 800
 801    memset(&un, 0, sizeof(un));
 802    un.sun_family = AF_UNIX;
 803    snprintf(un.sun_path, sizeof(un.sun_path), "%s", saddr->path);
 804
 805    /* connect to peer */
 806    do {
 807        rc = 0;
 808        if (connect(sock, (struct sockaddr *) &un, sizeof(un)) < 0) {
 809            rc = -errno;
 810        }
 811    } while (rc == -EINTR);
 812
 813    if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) {
 814        connect_state->fd = sock;
 815        qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state);
 816        return sock;
 817    } else if (rc >= 0) {
 818        /* non blocking socket immediate success, call callback */
 819        if (callback != NULL) {
 820            callback(sock, NULL, opaque);
 821        }
 822    }
 823
 824    if (rc < 0) {
 825        error_setg_errno(errp, -rc, "Failed to connect socket");
 826        close(sock);
 827        sock = -1;
 828    }
 829
 830    g_free(connect_state);
 831    return sock;
 832}
 833
 834#else
 835
 836static int unix_listen_saddr(UnixSocketAddress *saddr,
 837                             bool update_addr,
 838                             Error **errp)
 839{
 840    error_setg(errp, "unix sockets are not available on windows");
 841    errno = ENOTSUP;
 842    return -1;
 843}
 844
 845static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp,
 846                              NonBlockingConnectHandler *callback, void *opaque)
 847{
 848    error_setg(errp, "unix sockets are not available on windows");
 849    errno = ENOTSUP;
 850    return -1;
 851}
 852#endif
 853
 854/* compatibility wrapper */
 855int unix_listen(const char *str, char *ostr, int olen, Error **errp)
 856{
 857    char *path, *optstr;
 858    int sock, len;
 859    UnixSocketAddress *saddr;
 860
 861    saddr = g_new0(UnixSocketAddress, 1);
 862
 863    optstr = strchr(str, ',');
 864    if (optstr) {
 865        len = optstr - str;
 866        if (len) {
 867            path = g_malloc(len+1);
 868            snprintf(path, len+1, "%.*s", len, str);
 869            saddr->path = path;
 870        }
 871    } else {
 872        saddr->path = g_strdup(str);
 873    }
 874
 875    sock = unix_listen_saddr(saddr, true, errp);
 876
 877    if (sock != -1 && ostr)
 878        snprintf(ostr, olen, "%s%s", saddr->path, optstr ? optstr : "");
 879    qapi_free_UnixSocketAddress(saddr);
 880    return sock;
 881}
 882
 883int unix_connect(const char *path, Error **errp)
 884{
 885    UnixSocketAddress *saddr;
 886    int sock;
 887
 888    saddr = g_new0(UnixSocketAddress, 1);
 889    saddr->path = g_strdup(path);
 890    sock = unix_connect_saddr(saddr, errp, NULL, NULL);
 891    qapi_free_UnixSocketAddress(saddr);
 892    return sock;
 893}
 894
 895
 896int unix_nonblocking_connect(const char *path,
 897                             NonBlockingConnectHandler *callback,
 898                             void *opaque, Error **errp)
 899{
 900    UnixSocketAddress *saddr;
 901    int sock = -1;
 902
 903    g_assert(callback != NULL);
 904
 905    saddr = g_new0(UnixSocketAddress, 1);
 906    saddr->path = g_strdup(path);
 907    sock = unix_connect_saddr(saddr, errp, callback, opaque);
 908    qapi_free_UnixSocketAddress(saddr);
 909    return sock;
 910}
 911
 912SocketAddress *socket_parse(const char *str, Error **errp)
 913{
 914    SocketAddress *addr;
 915
 916    addr = g_new0(SocketAddress, 1);
 917    if (strstart(str, "unix:", NULL)) {
 918        if (str[5] == '\0') {
 919            error_setg(errp, "invalid Unix socket address");
 920            goto fail;
 921        } else {
 922            addr->type = SOCKET_ADDRESS_KIND_UNIX;
 923            addr->u.q_unix.data = g_new(UnixSocketAddress, 1);
 924            addr->u.q_unix.data->path = g_strdup(str + 5);
 925        }
 926    } else if (strstart(str, "fd:", NULL)) {
 927        if (str[3] == '\0') {
 928            error_setg(errp, "invalid file descriptor address");
 929            goto fail;
 930        } else {
 931            addr->type = SOCKET_ADDRESS_KIND_FD;
 932            addr->u.fd.data = g_new(String, 1);
 933            addr->u.fd.data->str = g_strdup(str + 3);
 934        }
 935    } else {
 936        addr->type = SOCKET_ADDRESS_KIND_INET;
 937        addr->u.inet.data = inet_parse(str, errp);
 938        if (addr->u.inet.data == NULL) {
 939            goto fail;
 940        }
 941    }
 942    return addr;
 943
 944fail:
 945    qapi_free_SocketAddress(addr);
 946    return NULL;
 947}
 948
 949int socket_connect(SocketAddress *addr, Error **errp,
 950                   NonBlockingConnectHandler *callback, void *opaque)
 951{
 952    int fd;
 953
 954    switch (addr->type) {
 955    case SOCKET_ADDRESS_KIND_INET:
 956        fd = inet_connect_saddr(addr->u.inet.data, errp, callback, opaque);
 957        break;
 958
 959    case SOCKET_ADDRESS_KIND_UNIX:
 960        fd = unix_connect_saddr(addr->u.q_unix.data, errp, callback, opaque);
 961        break;
 962
 963    case SOCKET_ADDRESS_KIND_FD:
 964        fd = monitor_get_fd(cur_mon, addr->u.fd.data->str, errp);
 965        if (fd >= 0 && callback) {
 966            qemu_set_nonblock(fd);
 967            callback(fd, NULL, opaque);
 968        }
 969        break;
 970
 971    default:
 972        abort();
 973    }
 974    return fd;
 975}
 976
 977int socket_listen(SocketAddress *addr, Error **errp)
 978{
 979    int fd;
 980
 981    switch (addr->type) {
 982    case SOCKET_ADDRESS_KIND_INET:
 983        fd = inet_listen_saddr(addr->u.inet.data, 0, false, errp);
 984        break;
 985
 986    case SOCKET_ADDRESS_KIND_UNIX:
 987        fd = unix_listen_saddr(addr->u.q_unix.data, false, errp);
 988        break;
 989
 990    case SOCKET_ADDRESS_KIND_FD:
 991        fd = monitor_get_fd(cur_mon, addr->u.fd.data->str, errp);
 992        break;
 993
 994    default:
 995        abort();
 996    }
 997    return fd;
 998}
 999
1000int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp)
1001{
1002    int fd;
1003
1004    switch (remote->type) {
1005    case SOCKET_ADDRESS_KIND_INET:
1006        fd = inet_dgram_saddr(remote->u.inet.data,
1007                              local ? local->u.inet.data : NULL, errp);
1008        break;
1009
1010    default:
1011        error_setg(errp, "socket type unsupported for datagram");
1012        fd = -1;
1013    }
1014    return fd;
1015}
1016
1017
1018static SocketAddress *
1019socket_sockaddr_to_address_inet(struct sockaddr_storage *sa,
1020                                socklen_t salen,
1021                                Error **errp)
1022{
1023    char host[NI_MAXHOST];
1024    char serv[NI_MAXSERV];
1025    SocketAddress *addr;
1026    InetSocketAddress *inet;
1027    int ret;
1028
1029    ret = getnameinfo((struct sockaddr *)sa, salen,
1030                      host, sizeof(host),
1031                      serv, sizeof(serv),
1032                      NI_NUMERICHOST | NI_NUMERICSERV);
1033    if (ret != 0) {
1034        error_setg(errp, "Cannot format numeric socket address: %s",
1035                   gai_strerror(ret));
1036        return NULL;
1037    }
1038
1039    addr = g_new0(SocketAddress, 1);
1040    addr->type = SOCKET_ADDRESS_KIND_INET;
1041    inet = addr->u.inet.data = g_new0(InetSocketAddress, 1);
1042    inet->host = g_strdup(host);
1043    inet->port = g_strdup(serv);
1044    if (sa->ss_family == AF_INET) {
1045        inet->has_ipv4 = inet->ipv4 = true;
1046    } else {
1047        inet->has_ipv6 = inet->ipv6 = true;
1048    }
1049
1050    return addr;
1051}
1052
1053
1054#ifndef WIN32
1055static SocketAddress *
1056socket_sockaddr_to_address_unix(struct sockaddr_storage *sa,
1057                                socklen_t salen,
1058                                Error **errp)
1059{
1060    SocketAddress *addr;
1061    struct sockaddr_un *su = (struct sockaddr_un *)sa;
1062
1063    addr = g_new0(SocketAddress, 1);
1064    addr->type = SOCKET_ADDRESS_KIND_UNIX;
1065    addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
1066    if (su->sun_path[0]) {
1067        addr->u.q_unix.data->path = g_strndup(su->sun_path,
1068                                              sizeof(su->sun_path));
1069    }
1070
1071    return addr;
1072}
1073#endif /* WIN32 */
1074
1075SocketAddress *
1076socket_sockaddr_to_address(struct sockaddr_storage *sa,
1077                           socklen_t salen,
1078                           Error **errp)
1079{
1080    switch (sa->ss_family) {
1081    case AF_INET:
1082    case AF_INET6:
1083        return socket_sockaddr_to_address_inet(sa, salen, errp);
1084
1085#ifndef WIN32
1086    case AF_UNIX:
1087        return socket_sockaddr_to_address_unix(sa, salen, errp);
1088#endif /* WIN32 */
1089
1090    default:
1091        error_setg(errp, "socket family %d unsupported",
1092                   sa->ss_family);
1093        return NULL;
1094    }
1095    return 0;
1096}
1097
1098
1099SocketAddress *socket_local_address(int fd, Error **errp)
1100{
1101    struct sockaddr_storage ss;
1102    socklen_t sslen = sizeof(ss);
1103
1104    if (getsockname(fd, (struct sockaddr *)&ss, &sslen) < 0) {
1105        error_setg_errno(errp, errno, "%s",
1106                         "Unable to query local socket address");
1107        return NULL;
1108    }
1109
1110    return socket_sockaddr_to_address(&ss, sslen, errp);
1111}
1112
1113
1114SocketAddress *socket_remote_address(int fd, Error **errp)
1115{
1116    struct sockaddr_storage ss;
1117    socklen_t sslen = sizeof(ss);
1118
1119    if (getpeername(fd, (struct sockaddr *)&ss, &sslen) < 0) {
1120        error_setg_errno(errp, errno, "%s",
1121                         "Unable to query remote socket address");
1122        return NULL;
1123    }
1124
1125    return socket_sockaddr_to_address(&ss, sslen, errp);
1126}
1127
1128
1129void qapi_copy_SocketAddress(SocketAddress **p_dest,
1130                             SocketAddress *src)
1131{
1132    QmpOutputVisitor *qov;
1133    QmpInputVisitor *qiv;
1134    Visitor *ov, *iv;
1135    QObject *obj;
1136
1137    *p_dest = NULL;
1138
1139    qov = qmp_output_visitor_new();
1140    ov = qmp_output_get_visitor(qov);
1141    visit_type_SocketAddress(ov, NULL, &src, &error_abort);
1142    obj = qmp_output_get_qobject(qov);
1143    qmp_output_visitor_cleanup(qov);
1144    if (!obj) {
1145        return;
1146    }
1147
1148    qiv = qmp_input_visitor_new(obj);
1149    iv = qmp_input_get_visitor(qiv);
1150    visit_type_SocketAddress(iv, NULL, p_dest, &error_abort);
1151    qmp_input_visitor_cleanup(qiv);
1152    qobject_decref(obj);
1153}
1154