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#ifdef CONFIG_AF_VSOCK
  21#include <linux/vm_sockets.h>
  22#endif /* CONFIG_AF_VSOCK */
  23
  24#include "qemu-common.h"
  25#include "monitor/monitor.h"
  26#include "qapi/clone-visitor.h"
  27#include "qapi/error.h"
  28#include "qapi/qapi-visit-sockets.h"
  29#include "qemu/sockets.h"
  30#include "qemu/main-loop.h"
  31#include "qapi/qobject-input-visitor.h"
  32#include "qapi/qobject-output-visitor.h"
  33#include "qemu/cutils.h"
  34#include "trace.h"
  35
  36#ifndef AI_ADDRCONFIG
  37# define AI_ADDRCONFIG 0
  38#endif
  39
  40#ifndef AI_V4MAPPED
  41# define AI_V4MAPPED 0
  42#endif
  43
  44#ifndef AI_NUMERICSERV
  45# define AI_NUMERICSERV 0
  46#endif
  47
  48
  49static int inet_getport(struct addrinfo *e)
  50{
  51    struct sockaddr_in *i4;
  52    struct sockaddr_in6 *i6;
  53
  54    switch (e->ai_family) {
  55    case PF_INET6:
  56        i6 = (void*)e->ai_addr;
  57        return ntohs(i6->sin6_port);
  58    case PF_INET:
  59        i4 = (void*)e->ai_addr;
  60        return ntohs(i4->sin_port);
  61    default:
  62        return 0;
  63    }
  64}
  65
  66static void inet_setport(struct addrinfo *e, int port)
  67{
  68    struct sockaddr_in *i4;
  69    struct sockaddr_in6 *i6;
  70
  71    switch (e->ai_family) {
  72    case PF_INET6:
  73        i6 = (void*)e->ai_addr;
  74        i6->sin6_port = htons(port);
  75        break;
  76    case PF_INET:
  77        i4 = (void*)e->ai_addr;
  78        i4->sin_port = htons(port);
  79        break;
  80    }
  81}
  82
  83NetworkAddressFamily inet_netfamily(int family)
  84{
  85    switch (family) {
  86    case PF_INET6: return NETWORK_ADDRESS_FAMILY_IPV6;
  87    case PF_INET:  return NETWORK_ADDRESS_FAMILY_IPV4;
  88    case PF_UNIX:  return NETWORK_ADDRESS_FAMILY_UNIX;
  89#ifdef CONFIG_AF_VSOCK
  90    case PF_VSOCK: return NETWORK_ADDRESS_FAMILY_VSOCK;
  91#endif /* CONFIG_AF_VSOCK */
  92    }
  93    return NETWORK_ADDRESS_FAMILY_UNKNOWN;
  94}
  95
  96bool fd_is_socket(int fd)
  97{
  98    int optval;
  99    socklen_t optlen = sizeof(optval);
 100    return !qemu_getsockopt(fd, SOL_SOCKET, SO_TYPE, &optval, &optlen);
 101}
 102
 103
 104/*
 105 * Matrix we're trying to apply
 106 *
 107 *  ipv4  ipv6   family
 108 *   -     -       PF_UNSPEC
 109 *   -     f       PF_INET
 110 *   -     t       PF_INET6
 111 *   f     -       PF_INET6
 112 *   f     f       <error>
 113 *   f     t       PF_INET6
 114 *   t     -       PF_INET
 115 *   t     f       PF_INET
 116 *   t     t       PF_INET6/PF_UNSPEC
 117 *
 118 * NB, this matrix is only about getting the necessary results
 119 * from getaddrinfo(). Some of the cases require further work
 120 * after reading results from getaddrinfo in order to fully
 121 * apply the logic the end user wants.
 122 *
 123 * In the first and last cases, we must set IPV6_V6ONLY=0
 124 * when binding, to allow a single listener to potentially
 125 * accept both IPv4+6 addresses.
 126 */
 127int inet_ai_family_from_address(InetSocketAddress *addr,
 128                                Error **errp)
 129{
 130    if (addr->has_ipv6 && addr->has_ipv4 &&
 131        !addr->ipv6 && !addr->ipv4) {
 132        error_setg(errp, "Cannot disable IPv4 and IPv6 at same time");
 133        return PF_UNSPEC;
 134    }
 135    if ((addr->has_ipv6 && addr->ipv6) && (addr->has_ipv4 && addr->ipv4)) {
 136        /*
 137         * Some backends can only do a single listener. In that case
 138         * we want empty hostname to resolve to "::" and then use the
 139         * flag IPV6_V6ONLY==0 to get both protocols on 1 socket. This
 140         * doesn't work for addresses other than "", so they're just
 141         * inevitably broken until multiple listeners can be used,
 142         * and thus we honour getaddrinfo automatic protocol detection
 143         * Once all backends do multi-listener, remove the PF_INET6
 144         * branch entirely.
 145         */
 146        if (!addr->host || g_str_equal(addr->host, "")) {
 147            return PF_INET6;
 148        } else {
 149            return PF_UNSPEC;
 150        }
 151    }
 152    if ((addr->has_ipv6 && addr->ipv6) || (addr->has_ipv4 && !addr->ipv4)) {
 153        return PF_INET6;
 154    }
 155    if ((addr->has_ipv4 && addr->ipv4) || (addr->has_ipv6 && !addr->ipv6)) {
 156        return PF_INET;
 157    }
 158    return PF_UNSPEC;
 159}
 160
 161static int create_fast_reuse_socket(struct addrinfo *e)
 162{
 163    int slisten = qemu_socket(e->ai_family, e->ai_socktype, e->ai_protocol);
 164    if (slisten < 0) {
 165        return -1;
 166    }
 167    socket_set_fast_reuse(slisten);
 168    return slisten;
 169}
 170
 171static int try_bind(int socket, InetSocketAddress *saddr, struct addrinfo *e)
 172{
 173#ifndef IPV6_V6ONLY
 174    return bind(socket, e->ai_addr, e->ai_addrlen);
 175#else
 176    /*
 177     * Deals with first & last cases in matrix in comment
 178     * for inet_ai_family_from_address().
 179     */
 180    int v6only =
 181        ((!saddr->has_ipv4 && !saddr->has_ipv6) ||
 182         (saddr->has_ipv4 && saddr->ipv4 &&
 183          saddr->has_ipv6 && saddr->ipv6)) ? 0 : 1;
 184    int stat;
 185
 186 rebind:
 187    if (e->ai_family == PF_INET6) {
 188        qemu_setsockopt(socket, IPPROTO_IPV6, IPV6_V6ONLY, &v6only,
 189                        sizeof(v6only));
 190    }
 191
 192    stat = bind(socket, e->ai_addr, e->ai_addrlen);
 193    if (!stat) {
 194        return 0;
 195    }
 196
 197    /* If we got EADDRINUSE from an IPv6 bind & v6only is unset,
 198     * it could be that the IPv4 port is already claimed, so retry
 199     * with v6only set
 200     */
 201    if (e->ai_family == PF_INET6 && errno == EADDRINUSE && !v6only) {
 202        v6only = 1;
 203        goto rebind;
 204    }
 205    return stat;
 206#endif
 207}
 208
 209static int inet_listen_saddr(InetSocketAddress *saddr,
 210                             int port_offset,
 211                             int num,
 212                             Error **errp)
 213{
 214    struct addrinfo ai,*res,*e;
 215    char port[33];
 216    char uaddr[INET6_ADDRSTRLEN+1];
 217    char uport[33];
 218    int rc, port_min, port_max, p;
 219    int slisten = -1;
 220    int saved_errno = 0;
 221    bool socket_created = false;
 222    Error *err = NULL;
 223
 224    if (saddr->keep_alive) {
 225        error_setg(errp, "keep-alive option is not supported for passive "
 226                   "sockets");
 227        return -1;
 228    }
 229
 230    memset(&ai,0, sizeof(ai));
 231    ai.ai_flags = AI_PASSIVE;
 232    if (saddr->has_numeric && saddr->numeric) {
 233        ai.ai_flags |= AI_NUMERICHOST | AI_NUMERICSERV;
 234    }
 235    ai.ai_family = inet_ai_family_from_address(saddr, &err);
 236    ai.ai_socktype = SOCK_STREAM;
 237
 238    if (err) {
 239        error_propagate(errp, err);
 240        return -1;
 241    }
 242
 243    if (saddr->host == NULL) {
 244        error_setg(errp, "host not specified");
 245        return -1;
 246    }
 247    if (saddr->port != NULL) {
 248        pstrcpy(port, sizeof(port), saddr->port);
 249    } else {
 250        port[0] = '\0';
 251    }
 252
 253    /* lookup */
 254    if (port_offset) {
 255        unsigned long long baseport;
 256        if (strlen(port) == 0) {
 257            error_setg(errp, "port not specified");
 258            return -1;
 259        }
 260        if (parse_uint_full(port, &baseport, 10) < 0) {
 261            error_setg(errp, "can't convert to a number: %s", port);
 262            return -1;
 263        }
 264        if (baseport > 65535 ||
 265            baseport + port_offset > 65535) {
 266            error_setg(errp, "port %s out of range", port);
 267            return -1;
 268        }
 269        snprintf(port, sizeof(port), "%d", (int)baseport + port_offset);
 270    }
 271    rc = getaddrinfo(strlen(saddr->host) ? saddr->host : NULL,
 272                     strlen(port) ? port : NULL, &ai, &res);
 273    if (rc != 0) {
 274        error_setg(errp, "address resolution failed for %s:%s: %s",
 275                   saddr->host, port, gai_strerror(rc));
 276        return -1;
 277    }
 278
 279    /* create socket + bind/listen */
 280    for (e = res; e != NULL; e = e->ai_next) {
 281#ifdef HAVE_IPPROTO_MPTCP
 282        if (saddr->has_mptcp && saddr->mptcp) {
 283            e->ai_protocol = IPPROTO_MPTCP;
 284        }
 285#endif
 286        getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen,
 287                        uaddr,INET6_ADDRSTRLEN,uport,32,
 288                        NI_NUMERICHOST | NI_NUMERICSERV);
 289
 290        port_min = inet_getport(e);
 291        port_max = saddr->has_to ? saddr->to + port_offset : port_min;
 292        for (p = port_min; p <= port_max; p++) {
 293            inet_setport(e, p);
 294
 295            slisten = create_fast_reuse_socket(e);
 296            if (slisten < 0) {
 297                /* First time we expect we might fail to create the socket
 298                 * eg if 'e' has AF_INET6 but ipv6 kmod is not loaded.
 299                 * Later iterations should always succeed if first iteration
 300                 * worked though, so treat that as fatal.
 301                 */
 302                if (p == port_min) {
 303                    continue;
 304                } else {
 305                    error_setg_errno(errp, errno,
 306                                     "Failed to recreate failed listening socket");
 307                    goto listen_failed;
 308                }
 309            }
 310            socket_created = true;
 311
 312            rc = try_bind(slisten, saddr, e);
 313            if (rc < 0) {
 314                if (errno != EADDRINUSE) {
 315                    error_setg_errno(errp, errno, "Failed to bind socket");
 316                    goto listen_failed;
 317                }
 318            } else {
 319                if (!listen(slisten, num)) {
 320                    goto listen_ok;
 321                }
 322                if (errno != EADDRINUSE) {
 323                    error_setg_errno(errp, errno, "Failed to listen on socket");
 324                    goto listen_failed;
 325                }
 326            }
 327            /* Someone else managed to bind to the same port and beat us
 328             * to listen on it! Socket semantics does not allow us to
 329             * recover from this situation, so we need to recreate the
 330             * socket to allow bind attempts for subsequent ports:
 331             */
 332            closesocket(slisten);
 333            slisten = -1;
 334        }
 335    }
 336    error_setg_errno(errp, errno,
 337                     socket_created ?
 338                     "Failed to find an available port" :
 339                     "Failed to create a socket");
 340listen_failed:
 341    saved_errno = errno;
 342    if (slisten >= 0) {
 343        closesocket(slisten);
 344    }
 345    freeaddrinfo(res);
 346    errno = saved_errno;
 347    return -1;
 348
 349listen_ok:
 350    freeaddrinfo(res);
 351    return slisten;
 352}
 353
 354#ifdef _WIN32
 355#define QEMU_SOCKET_RC_INPROGRESS(rc) \
 356    ((rc) == -EINPROGRESS || (rc) == -EWOULDBLOCK || (rc) == -WSAEALREADY)
 357#else
 358#define QEMU_SOCKET_RC_INPROGRESS(rc) \
 359    ((rc) == -EINPROGRESS)
 360#endif
 361
 362static int inet_connect_addr(const InetSocketAddress *saddr,
 363                             struct addrinfo *addr, Error **errp)
 364{
 365    int sock, rc;
 366
 367    sock = qemu_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
 368    if (sock < 0) {
 369        error_setg_errno(errp, errno, "Failed to create socket family %d",
 370                         addr->ai_family);
 371        return -1;
 372    }
 373    socket_set_fast_reuse(sock);
 374
 375    /* connect to peer */
 376    do {
 377        rc = 0;
 378        if (connect(sock, addr->ai_addr, addr->ai_addrlen) < 0) {
 379            rc = -errno;
 380        }
 381    } while (rc == -EINTR);
 382
 383    if (rc < 0) {
 384        error_setg_errno(errp, errno, "Failed to connect to '%s:%s'",
 385                         saddr->host, saddr->port);
 386        closesocket(sock);
 387        return -1;
 388    }
 389
 390    return sock;
 391}
 392
 393static struct addrinfo *inet_parse_connect_saddr(InetSocketAddress *saddr,
 394                                                 Error **errp)
 395{
 396    struct addrinfo ai, *res;
 397    int rc;
 398    Error *err = NULL;
 399    static int useV4Mapped = 1;
 400
 401    memset(&ai, 0, sizeof(ai));
 402
 403    ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
 404    if (qatomic_read(&useV4Mapped)) {
 405        ai.ai_flags |= AI_V4MAPPED;
 406    }
 407    ai.ai_family = inet_ai_family_from_address(saddr, &err);
 408    ai.ai_socktype = SOCK_STREAM;
 409
 410    if (err) {
 411        error_propagate(errp, err);
 412        return NULL;
 413    }
 414
 415    if (saddr->host == NULL || saddr->port == NULL) {
 416        error_setg(errp, "host and/or port not specified");
 417        return NULL;
 418    }
 419
 420    /* lookup */
 421    rc = getaddrinfo(saddr->host, saddr->port, &ai, &res);
 422
 423    /* At least FreeBSD and OS-X 10.6 declare AI_V4MAPPED but
 424     * then don't implement it in their getaddrinfo(). Detect
 425     * this and retry without the flag since that's preferable
 426     * to a fatal error
 427     */
 428    if (rc == EAI_BADFLAGS &&
 429        (ai.ai_flags & AI_V4MAPPED)) {
 430        qatomic_set(&useV4Mapped, 0);
 431        ai.ai_flags &= ~AI_V4MAPPED;
 432        rc = getaddrinfo(saddr->host, saddr->port, &ai, &res);
 433    }
 434    if (rc != 0) {
 435        error_setg(errp, "address resolution failed for %s:%s: %s",
 436                   saddr->host, saddr->port, gai_strerror(rc));
 437        return NULL;
 438    }
 439    return res;
 440}
 441
 442/**
 443 * Create a socket and connect it to an address.
 444 *
 445 * @saddr: Inet socket address specification
 446 * @errp: set on error
 447 *
 448 * Returns: -1 on error, file descriptor on success.
 449 */
 450int inet_connect_saddr(InetSocketAddress *saddr, Error **errp)
 451{
 452    Error *local_err = NULL;
 453    struct addrinfo *res, *e;
 454    int sock = -1;
 455
 456    res = inet_parse_connect_saddr(saddr, errp);
 457    if (!res) {
 458        return -1;
 459    }
 460
 461    for (e = res; e != NULL; e = e->ai_next) {
 462        error_free(local_err);
 463        local_err = NULL;
 464
 465#ifdef HAVE_IPPROTO_MPTCP
 466        if (saddr->has_mptcp && saddr->mptcp) {
 467            e->ai_protocol = IPPROTO_MPTCP;
 468        }
 469#endif
 470
 471        sock = inet_connect_addr(saddr, e, &local_err);
 472        if (sock >= 0) {
 473            break;
 474        }
 475    }
 476
 477    freeaddrinfo(res);
 478
 479    if (sock < 0) {
 480        error_propagate(errp, local_err);
 481        return sock;
 482    }
 483
 484    if (saddr->keep_alive) {
 485        int val = 1;
 486        int ret = qemu_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
 487                                  &val, sizeof(val));
 488
 489        if (ret < 0) {
 490            error_setg_errno(errp, errno, "Unable to set KEEPALIVE");
 491            close(sock);
 492            return -1;
 493        }
 494    }
 495
 496    return sock;
 497}
 498
 499static int inet_dgram_saddr(InetSocketAddress *sraddr,
 500                            InetSocketAddress *sladdr,
 501                            Error **errp)
 502{
 503    struct addrinfo ai, *peer = NULL, *local = NULL;
 504    const char *addr;
 505    const char *port;
 506    int sock = -1, rc;
 507    Error *err = NULL;
 508
 509    /* lookup peer addr */
 510    memset(&ai,0, sizeof(ai));
 511    ai.ai_flags = AI_CANONNAME | AI_V4MAPPED | AI_ADDRCONFIG;
 512    ai.ai_family = inet_ai_family_from_address(sraddr, &err);
 513    ai.ai_socktype = SOCK_DGRAM;
 514
 515    if (err) {
 516        error_propagate(errp, err);
 517        goto err;
 518    }
 519
 520    addr = sraddr->host;
 521    port = sraddr->port;
 522    if (addr == NULL || strlen(addr) == 0) {
 523        addr = "localhost";
 524    }
 525    if (port == NULL || strlen(port) == 0) {
 526        error_setg(errp, "remote port not specified");
 527        goto err;
 528    }
 529
 530    if ((rc = getaddrinfo(addr, port, &ai, &peer)) != 0) {
 531        error_setg(errp, "address resolution failed for %s:%s: %s", addr, port,
 532                   gai_strerror(rc));
 533        goto err;
 534    }
 535
 536    /* lookup local addr */
 537    memset(&ai,0, sizeof(ai));
 538    ai.ai_flags = AI_PASSIVE;
 539    ai.ai_family = peer->ai_family;
 540    ai.ai_socktype = SOCK_DGRAM;
 541
 542    if (sladdr) {
 543        addr = sladdr->host;
 544        port = sladdr->port;
 545        if (addr == NULL || strlen(addr) == 0) {
 546            addr = NULL;
 547        }
 548        if (!port || strlen(port) == 0) {
 549            port = "0";
 550        }
 551    } else {
 552        addr = NULL;
 553        port = "0";
 554    }
 555
 556    if ((rc = getaddrinfo(addr, port, &ai, &local)) != 0) {
 557        error_setg(errp, "address resolution failed for %s:%s: %s", addr, port,
 558                   gai_strerror(rc));
 559        goto err;
 560    }
 561
 562    /* create socket */
 563    sock = qemu_socket(peer->ai_family, peer->ai_socktype, peer->ai_protocol);
 564    if (sock < 0) {
 565        error_setg_errno(errp, errno, "Failed to create socket family %d",
 566                         peer->ai_family);
 567        goto err;
 568    }
 569    socket_set_fast_reuse(sock);
 570
 571    /* bind socket */
 572    if (bind(sock, local->ai_addr, local->ai_addrlen) < 0) {
 573        error_setg_errno(errp, errno, "Failed to bind socket");
 574        goto err;
 575    }
 576
 577    /* connect to peer */
 578    if (connect(sock,peer->ai_addr,peer->ai_addrlen) < 0) {
 579        error_setg_errno(errp, errno, "Failed to connect to '%s:%s'",
 580                         addr, port);
 581        goto err;
 582    }
 583
 584    freeaddrinfo(local);
 585    freeaddrinfo(peer);
 586    return sock;
 587
 588err:
 589    if (sock != -1) {
 590        closesocket(sock);
 591    }
 592    if (local) {
 593        freeaddrinfo(local);
 594    }
 595    if (peer) {
 596        freeaddrinfo(peer);
 597    }
 598
 599    return -1;
 600}
 601
 602/* compatibility wrapper */
 603static int inet_parse_flag(const char *flagname, const char *optstr, bool *val,
 604                           Error **errp)
 605{
 606    char *end;
 607    size_t len;
 608
 609    end = strstr(optstr, ",");
 610    if (end) {
 611        if (end[1] == ',') { /* Reject 'ipv6=on,,foo' */
 612            error_setg(errp, "error parsing '%s' flag '%s'", flagname, optstr);
 613            return -1;
 614        }
 615        len = end - optstr;
 616    } else {
 617        len = strlen(optstr);
 618    }
 619    if (len == 0 || (len == 3 && strncmp(optstr, "=on", len) == 0)) {
 620        *val = true;
 621    } else if (len == 4 && strncmp(optstr, "=off", len) == 0) {
 622        *val = false;
 623    } else {
 624        error_setg(errp, "error parsing '%s' flag '%s'", flagname, optstr);
 625        return -1;
 626    }
 627    return 0;
 628}
 629
 630int inet_parse(InetSocketAddress *addr, const char *str, Error **errp)
 631{
 632    const char *optstr, *h;
 633    char host[65];
 634    char port[33];
 635    int to;
 636    int pos;
 637    char *begin;
 638
 639    memset(addr, 0, sizeof(*addr));
 640
 641    /* parse address */
 642    if (str[0] == ':') {
 643        /* no host given */
 644        host[0] = '\0';
 645        if (sscanf(str, ":%32[^,]%n", port, &pos) != 1) {
 646            error_setg(errp, "error parsing port in address '%s'", str);
 647            return -1;
 648        }
 649    } else if (str[0] == '[') {
 650        /* IPv6 addr */
 651        if (sscanf(str, "[%64[^]]]:%32[^,]%n", host, port, &pos) != 2) {
 652            error_setg(errp, "error parsing IPv6 address '%s'", str);
 653            return -1;
 654        }
 655    } else {
 656        /* hostname or IPv4 addr */
 657        if (sscanf(str, "%64[^:]:%32[^,]%n", host, port, &pos) != 2) {
 658            error_setg(errp, "error parsing address '%s'", str);
 659            return -1;
 660        }
 661    }
 662
 663    addr->host = g_strdup(host);
 664    addr->port = g_strdup(port);
 665
 666    /* parse options */
 667    optstr = str + pos;
 668    h = strstr(optstr, ",to=");
 669    if (h) {
 670        h += 4;
 671        if (sscanf(h, "%d%n", &to, &pos) != 1 ||
 672            (h[pos] != '\0' && h[pos] != ',')) {
 673            error_setg(errp, "error parsing to= argument");
 674            return -1;
 675        }
 676        addr->has_to = true;
 677        addr->to = to;
 678    }
 679    begin = strstr(optstr, ",ipv4");
 680    if (begin) {
 681        if (inet_parse_flag("ipv4", begin + 5, &addr->ipv4, errp) < 0) {
 682            return -1;
 683        }
 684        addr->has_ipv4 = true;
 685    }
 686    begin = strstr(optstr, ",ipv6");
 687    if (begin) {
 688        if (inet_parse_flag("ipv6", begin + 5, &addr->ipv6, errp) < 0) {
 689            return -1;
 690        }
 691        addr->has_ipv6 = true;
 692    }
 693    begin = strstr(optstr, ",keep-alive");
 694    if (begin) {
 695        if (inet_parse_flag("keep-alive", begin + strlen(",keep-alive"),
 696                            &addr->keep_alive, errp) < 0)
 697        {
 698            return -1;
 699        }
 700        addr->has_keep_alive = true;
 701    }
 702#ifdef HAVE_IPPROTO_MPTCP
 703    begin = strstr(optstr, ",mptcp");
 704    if (begin) {
 705        if (inet_parse_flag("mptcp", begin + strlen(",mptcp"),
 706                            &addr->mptcp, errp) < 0)
 707        {
 708            return -1;
 709        }
 710        addr->has_mptcp = true;
 711    }
 712#endif
 713    return 0;
 714}
 715
 716
 717/**
 718 * Create a blocking socket and connect it to an address.
 719 *
 720 * @str: address string
 721 * @errp: set in case of an error
 722 *
 723 * Returns -1 in case of error, file descriptor on success
 724 **/
 725int inet_connect(const char *str, Error **errp)
 726{
 727    int sock = -1;
 728    InetSocketAddress *addr = g_new(InetSocketAddress, 1);
 729
 730    if (!inet_parse(addr, str, errp)) {
 731        sock = inet_connect_saddr(addr, errp);
 732    }
 733    qapi_free_InetSocketAddress(addr);
 734    return sock;
 735}
 736
 737#ifdef CONFIG_AF_VSOCK
 738static bool vsock_parse_vaddr_to_sockaddr(const VsockSocketAddress *vaddr,
 739                                          struct sockaddr_vm *svm,
 740                                          Error **errp)
 741{
 742    unsigned long long val;
 743
 744    memset(svm, 0, sizeof(*svm));
 745    svm->svm_family = AF_VSOCK;
 746
 747    if (parse_uint_full(vaddr->cid, &val, 10) < 0 ||
 748        val > UINT32_MAX) {
 749        error_setg(errp, "Failed to parse cid '%s'", vaddr->cid);
 750        return false;
 751    }
 752    svm->svm_cid = val;
 753
 754    if (parse_uint_full(vaddr->port, &val, 10) < 0 ||
 755        val > UINT32_MAX) {
 756        error_setg(errp, "Failed to parse port '%s'", vaddr->port);
 757        return false;
 758    }
 759    svm->svm_port = val;
 760
 761    return true;
 762}
 763
 764static int vsock_connect_addr(const VsockSocketAddress *vaddr,
 765                              const struct sockaddr_vm *svm, Error **errp)
 766{
 767    int sock, rc;
 768
 769    sock = qemu_socket(AF_VSOCK, SOCK_STREAM, 0);
 770    if (sock < 0) {
 771        error_setg_errno(errp, errno, "Failed to create socket family %d",
 772                         AF_VSOCK);
 773        return -1;
 774    }
 775
 776    /* connect to peer */
 777    do {
 778        rc = 0;
 779        if (connect(sock, (const struct sockaddr *)svm, sizeof(*svm)) < 0) {
 780            rc = -errno;
 781        }
 782    } while (rc == -EINTR);
 783
 784    if (rc < 0) {
 785        error_setg_errno(errp, errno, "Failed to connect to '%s:%s'",
 786                         vaddr->cid, vaddr->port);
 787        closesocket(sock);
 788        return -1;
 789    }
 790
 791    return sock;
 792}
 793
 794static int vsock_connect_saddr(VsockSocketAddress *vaddr, Error **errp)
 795{
 796    struct sockaddr_vm svm;
 797
 798    if (!vsock_parse_vaddr_to_sockaddr(vaddr, &svm, errp)) {
 799        return -1;
 800    }
 801
 802    return vsock_connect_addr(vaddr, &svm, errp);
 803}
 804
 805static int vsock_listen_saddr(VsockSocketAddress *vaddr,
 806                              int num,
 807                              Error **errp)
 808{
 809    struct sockaddr_vm svm;
 810    int slisten;
 811
 812    if (!vsock_parse_vaddr_to_sockaddr(vaddr, &svm, errp)) {
 813        return -1;
 814    }
 815
 816    slisten = qemu_socket(AF_VSOCK, SOCK_STREAM, 0);
 817    if (slisten < 0) {
 818        error_setg_errno(errp, errno, "Failed to create socket");
 819        return -1;
 820    }
 821
 822    if (bind(slisten, (const struct sockaddr *)&svm, sizeof(svm)) != 0) {
 823        error_setg_errno(errp, errno, "Failed to bind socket");
 824        closesocket(slisten);
 825        return -1;
 826    }
 827
 828    if (listen(slisten, num) != 0) {
 829        error_setg_errno(errp, errno, "Failed to listen on socket");
 830        closesocket(slisten);
 831        return -1;
 832    }
 833    return slisten;
 834}
 835
 836static int vsock_parse(VsockSocketAddress *addr, const char *str,
 837                       Error **errp)
 838{
 839    char cid[33];
 840    char port[33];
 841    int n;
 842
 843    if (sscanf(str, "%32[^:]:%32[^,]%n", cid, port, &n) != 2) {
 844        error_setg(errp, "error parsing address '%s'", str);
 845        return -1;
 846    }
 847    if (str[n] != '\0') {
 848        error_setg(errp, "trailing characters in address '%s'", str);
 849        return -1;
 850    }
 851
 852    addr->cid = g_strdup(cid);
 853    addr->port = g_strdup(port);
 854    return 0;
 855}
 856#else
 857static void vsock_unsupported(Error **errp)
 858{
 859    error_setg(errp, "socket family AF_VSOCK unsupported");
 860}
 861
 862static int vsock_connect_saddr(VsockSocketAddress *vaddr, Error **errp)
 863{
 864    vsock_unsupported(errp);
 865    return -1;
 866}
 867
 868static int vsock_listen_saddr(VsockSocketAddress *vaddr,
 869                              int num,
 870                              Error **errp)
 871{
 872    vsock_unsupported(errp);
 873    return -1;
 874}
 875
 876static int vsock_parse(VsockSocketAddress *addr, const char *str,
 877                        Error **errp)
 878{
 879    vsock_unsupported(errp);
 880    return -1;
 881}
 882#endif /* CONFIG_AF_VSOCK */
 883
 884#ifndef _WIN32
 885
 886static bool saddr_is_abstract(UnixSocketAddress *saddr)
 887{
 888#ifdef CONFIG_LINUX
 889    return saddr->abstract;
 890#else
 891    return false;
 892#endif
 893}
 894
 895static bool saddr_is_tight(UnixSocketAddress *saddr)
 896{
 897#ifdef CONFIG_LINUX
 898    return !saddr->has_tight || saddr->tight;
 899#else
 900    return false;
 901#endif
 902}
 903
 904static int unix_listen_saddr(UnixSocketAddress *saddr,
 905                             int num,
 906                             Error **errp)
 907{
 908    bool abstract = saddr_is_abstract(saddr);
 909    struct sockaddr_un un;
 910    int sock, fd;
 911    char *pathbuf = NULL;
 912    const char *path;
 913    size_t pathlen;
 914    size_t addrlen;
 915
 916    sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
 917    if (sock < 0) {
 918        error_setg_errno(errp, errno, "Failed to create Unix socket");
 919        return -1;
 920    }
 921
 922    if (saddr->path[0] || abstract) {
 923        path = saddr->path;
 924    } else {
 925        const char *tmpdir = getenv("TMPDIR");
 926        tmpdir = tmpdir ? tmpdir : "/tmp";
 927        path = pathbuf = g_strdup_printf("%s/qemu-socket-XXXXXX", tmpdir);
 928    }
 929
 930    pathlen = strlen(path);
 931    if (pathlen > sizeof(un.sun_path) ||
 932        (abstract && pathlen > (sizeof(un.sun_path) - 1))) {
 933        error_setg(errp, "UNIX socket path '%s' is too long", path);
 934        error_append_hint(errp, "Path must be less than %zu bytes\n",
 935                          abstract ? sizeof(un.sun_path) - 1 :
 936                          sizeof(un.sun_path));
 937        goto err;
 938    }
 939
 940    if (pathbuf != NULL) {
 941        /*
 942         * This dummy fd usage silences the mktemp() unsecure warning.
 943         * Using mkstemp() doesn't make things more secure here
 944         * though.  bind() complains about existing files, so we have
 945         * to unlink first and thus re-open the race window.  The
 946         * worst case possible is bind() failing, i.e. a DoS attack.
 947         */
 948        fd = mkstemp(pathbuf);
 949        if (fd < 0) {
 950            error_setg_errno(errp, errno,
 951                             "Failed to make a temporary socket %s", pathbuf);
 952            goto err;
 953        }
 954        close(fd);
 955    }
 956
 957    if (!abstract && unlink(path) < 0 && errno != ENOENT) {
 958        error_setg_errno(errp, errno,
 959                         "Failed to unlink socket %s", path);
 960        goto err;
 961    }
 962
 963    memset(&un, 0, sizeof(un));
 964    un.sun_family = AF_UNIX;
 965    addrlen = sizeof(un);
 966
 967    if (abstract) {
 968        un.sun_path[0] = '\0';
 969        memcpy(&un.sun_path[1], path, pathlen);
 970        if (saddr_is_tight(saddr)) {
 971            addrlen = offsetof(struct sockaddr_un, sun_path) + 1 + pathlen;
 972        }
 973    } else {
 974        memcpy(un.sun_path, path, pathlen);
 975    }
 976
 977    if (bind(sock, (struct sockaddr *) &un, addrlen) < 0) {
 978        error_setg_errno(errp, errno, "Failed to bind socket to %s", path);
 979        goto err;
 980    }
 981    if (listen(sock, num) < 0) {
 982        error_setg_errno(errp, errno, "Failed to listen on socket");
 983        goto err;
 984    }
 985
 986    g_free(pathbuf);
 987    return sock;
 988
 989err:
 990    g_free(pathbuf);
 991    closesocket(sock);
 992    return -1;
 993}
 994
 995static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp)
 996{
 997    bool abstract = saddr_is_abstract(saddr);
 998    struct sockaddr_un un;
 999    int sock, rc;
1000    size_t pathlen;
1001    size_t addrlen;
1002
1003    if (saddr->path == NULL) {
1004        error_setg(errp, "unix connect: no path specified");
1005        return -1;
1006    }
1007
1008    sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
1009    if (sock < 0) {
1010        error_setg_errno(errp, errno, "Failed to create socket");
1011        return -1;
1012    }
1013
1014    pathlen = strlen(saddr->path);
1015    if (pathlen > sizeof(un.sun_path) ||
1016        (abstract && pathlen > (sizeof(un.sun_path) - 1))) {
1017        error_setg(errp, "UNIX socket path '%s' is too long", saddr->path);
1018        error_append_hint(errp, "Path must be less than %zu bytes\n",
1019                          abstract ? sizeof(un.sun_path) - 1 :
1020                          sizeof(un.sun_path));
1021        goto err;
1022    }
1023
1024    memset(&un, 0, sizeof(un));
1025    un.sun_family = AF_UNIX;
1026    addrlen = sizeof(un);
1027
1028    if (abstract) {
1029        un.sun_path[0] = '\0';
1030        memcpy(&un.sun_path[1], saddr->path, pathlen);
1031        if (saddr_is_tight(saddr)) {
1032            addrlen = offsetof(struct sockaddr_un, sun_path) + 1 + pathlen;
1033        }
1034    } else {
1035        memcpy(un.sun_path, saddr->path, pathlen);
1036    }
1037    /* connect to peer */
1038    do {
1039        rc = 0;
1040        if (connect(sock, (struct sockaddr *) &un, addrlen) < 0) {
1041            rc = -errno;
1042        }
1043    } while (rc == -EINTR);
1044
1045    if (rc < 0) {
1046        error_setg_errno(errp, -rc, "Failed to connect to '%s'",
1047                         saddr->path);
1048        goto err;
1049    }
1050
1051    return sock;
1052
1053 err:
1054    close(sock);
1055    return -1;
1056}
1057
1058#else
1059
1060static int unix_listen_saddr(UnixSocketAddress *saddr,
1061                             int num,
1062                             Error **errp)
1063{
1064    error_setg(errp, "unix sockets are not available on windows");
1065    errno = ENOTSUP;
1066    return -1;
1067}
1068
1069static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp)
1070{
1071    error_setg(errp, "unix sockets are not available on windows");
1072    errno = ENOTSUP;
1073    return -1;
1074}
1075#endif
1076
1077/* compatibility wrapper */
1078int unix_listen(const char *str, Error **errp)
1079{
1080    UnixSocketAddress *saddr;
1081    int sock;
1082
1083    saddr = g_new0(UnixSocketAddress, 1);
1084    saddr->path = g_strdup(str);
1085    sock = unix_listen_saddr(saddr, 1, errp);
1086    qapi_free_UnixSocketAddress(saddr);
1087    return sock;
1088}
1089
1090int unix_connect(const char *path, Error **errp)
1091{
1092    UnixSocketAddress *saddr;
1093    int sock;
1094
1095    saddr = g_new0(UnixSocketAddress, 1);
1096    saddr->path = g_strdup(path);
1097    sock = unix_connect_saddr(saddr, errp);
1098    qapi_free_UnixSocketAddress(saddr);
1099    return sock;
1100}
1101
1102
1103SocketAddress *socket_parse(const char *str, Error **errp)
1104{
1105    SocketAddress *addr;
1106
1107    addr = g_new0(SocketAddress, 1);
1108    if (strstart(str, "unix:", NULL)) {
1109        if (str[5] == '\0') {
1110            error_setg(errp, "invalid Unix socket address");
1111            goto fail;
1112        } else {
1113            addr->type = SOCKET_ADDRESS_TYPE_UNIX;
1114            addr->u.q_unix.path = g_strdup(str + 5);
1115        }
1116    } else if (strstart(str, "fd:", NULL)) {
1117        if (str[3] == '\0') {
1118            error_setg(errp, "invalid file descriptor address");
1119            goto fail;
1120        } else {
1121            addr->type = SOCKET_ADDRESS_TYPE_FD;
1122            addr->u.fd.str = g_strdup(str + 3);
1123        }
1124    } else if (strstart(str, "vsock:", NULL)) {
1125        addr->type = SOCKET_ADDRESS_TYPE_VSOCK;
1126        if (vsock_parse(&addr->u.vsock, str + strlen("vsock:"), errp)) {
1127            goto fail;
1128        }
1129    } else {
1130        addr->type = SOCKET_ADDRESS_TYPE_INET;
1131        if (inet_parse(&addr->u.inet, str, errp)) {
1132            goto fail;
1133        }
1134    }
1135    return addr;
1136
1137fail:
1138    qapi_free_SocketAddress(addr);
1139    return NULL;
1140}
1141
1142static int socket_get_fd(const char *fdstr, Error **errp)
1143{
1144    Monitor *cur_mon = monitor_cur();
1145    int fd;
1146    if (cur_mon) {
1147        fd = monitor_get_fd(cur_mon, fdstr, errp);
1148        if (fd < 0) {
1149            return -1;
1150        }
1151    } else {
1152        if (qemu_strtoi(fdstr, NULL, 10, &fd) < 0) {
1153            error_setg_errno(errp, errno,
1154                             "Unable to parse FD number %s",
1155                             fdstr);
1156            return -1;
1157        }
1158    }
1159    if (!fd_is_socket(fd)) {
1160        error_setg(errp, "File descriptor '%s' is not a socket", fdstr);
1161        close(fd);
1162        return -1;
1163    }
1164    return fd;
1165}
1166
1167int socket_address_parse_named_fd(SocketAddress *addr, Error **errp)
1168{
1169    int fd;
1170
1171    if (addr->type != SOCKET_ADDRESS_TYPE_FD) {
1172        return 0;
1173    }
1174
1175    fd = socket_get_fd(addr->u.fd.str, errp);
1176    if (fd < 0) {
1177        return fd;
1178    }
1179
1180    g_free(addr->u.fd.str);
1181    addr->u.fd.str = g_strdup_printf("%d", fd);
1182
1183    return 0;
1184}
1185
1186int socket_connect(SocketAddress *addr, Error **errp)
1187{
1188    int fd;
1189
1190    switch (addr->type) {
1191    case SOCKET_ADDRESS_TYPE_INET:
1192        fd = inet_connect_saddr(&addr->u.inet, errp);
1193        break;
1194
1195    case SOCKET_ADDRESS_TYPE_UNIX:
1196        fd = unix_connect_saddr(&addr->u.q_unix, errp);
1197        break;
1198
1199    case SOCKET_ADDRESS_TYPE_FD:
1200        fd = socket_get_fd(addr->u.fd.str, errp);
1201        break;
1202
1203    case SOCKET_ADDRESS_TYPE_VSOCK:
1204        fd = vsock_connect_saddr(&addr->u.vsock, errp);
1205        break;
1206
1207    default:
1208        abort();
1209    }
1210    return fd;
1211}
1212
1213int socket_listen(SocketAddress *addr, int num, Error **errp)
1214{
1215    int fd;
1216
1217    trace_socket_listen(num);
1218    switch (addr->type) {
1219    case SOCKET_ADDRESS_TYPE_INET:
1220        fd = inet_listen_saddr(&addr->u.inet, 0, num, errp);
1221        break;
1222
1223    case SOCKET_ADDRESS_TYPE_UNIX:
1224        fd = unix_listen_saddr(&addr->u.q_unix, num, errp);
1225        break;
1226
1227    case SOCKET_ADDRESS_TYPE_FD:
1228        fd = socket_get_fd(addr->u.fd.str, errp);
1229        if (fd < 0) {
1230            return -1;
1231        }
1232
1233        /*
1234         * If the socket is not yet in the listen state, then transition it to
1235         * the listen state now.
1236         *
1237         * If it's already listening then this updates the backlog value as
1238         * requested.
1239         *
1240         * If this socket cannot listen because it's already in another state
1241         * (e.g. unbound or connected) then we'll catch the error here.
1242         */
1243        if (listen(fd, num) != 0) {
1244            error_setg_errno(errp, errno, "Failed to listen on fd socket");
1245            closesocket(fd);
1246            return -1;
1247        }
1248        break;
1249
1250    case SOCKET_ADDRESS_TYPE_VSOCK:
1251        fd = vsock_listen_saddr(&addr->u.vsock, num, errp);
1252        break;
1253
1254    default:
1255        abort();
1256    }
1257    return fd;
1258}
1259
1260void socket_listen_cleanup(int fd, Error **errp)
1261{
1262    SocketAddress *addr;
1263
1264    addr = socket_local_address(fd, errp);
1265    if (!addr) {
1266        return;
1267    }
1268
1269    if (addr->type == SOCKET_ADDRESS_TYPE_UNIX
1270        && addr->u.q_unix.path) {
1271        if (unlink(addr->u.q_unix.path) < 0 && errno != ENOENT) {
1272            error_setg_errno(errp, errno,
1273                             "Failed to unlink socket %s",
1274                             addr->u.q_unix.path);
1275        }
1276    }
1277
1278    qapi_free_SocketAddress(addr);
1279}
1280
1281int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp)
1282{
1283    int fd;
1284
1285    /*
1286     * TODO SOCKET_ADDRESS_TYPE_FD when fd is AF_INET or AF_INET6
1287     * (although other address families can do SOCK_DGRAM, too)
1288     */
1289    switch (remote->type) {
1290    case SOCKET_ADDRESS_TYPE_INET:
1291        fd = inet_dgram_saddr(&remote->u.inet,
1292                              local ? &local->u.inet : NULL, errp);
1293        break;
1294
1295    default:
1296        error_setg(errp, "socket type unsupported for datagram");
1297        fd = -1;
1298    }
1299    return fd;
1300}
1301
1302
1303static SocketAddress *
1304socket_sockaddr_to_address_inet(struct sockaddr_storage *sa,
1305                                socklen_t salen,
1306                                Error **errp)
1307{
1308    char host[NI_MAXHOST];
1309    char serv[NI_MAXSERV];
1310    SocketAddress *addr;
1311    InetSocketAddress *inet;
1312    int ret;
1313
1314    ret = getnameinfo((struct sockaddr *)sa, salen,
1315                      host, sizeof(host),
1316                      serv, sizeof(serv),
1317                      NI_NUMERICHOST | NI_NUMERICSERV);
1318    if (ret != 0) {
1319        error_setg(errp, "Cannot format numeric socket address: %s",
1320                   gai_strerror(ret));
1321        return NULL;
1322    }
1323
1324    addr = g_new0(SocketAddress, 1);
1325    addr->type = SOCKET_ADDRESS_TYPE_INET;
1326    inet = &addr->u.inet;
1327    inet->host = g_strdup(host);
1328    inet->port = g_strdup(serv);
1329    if (sa->ss_family == AF_INET) {
1330        inet->has_ipv4 = inet->ipv4 = true;
1331    } else {
1332        inet->has_ipv6 = inet->ipv6 = true;
1333    }
1334
1335    return addr;
1336}
1337
1338
1339#ifndef WIN32
1340static SocketAddress *
1341socket_sockaddr_to_address_unix(struct sockaddr_storage *sa,
1342                                socklen_t salen,
1343                                Error **errp)
1344{
1345    SocketAddress *addr;
1346    struct sockaddr_un *su = (struct sockaddr_un *)sa;
1347
1348    addr = g_new0(SocketAddress, 1);
1349    addr->type = SOCKET_ADDRESS_TYPE_UNIX;
1350    salen -= offsetof(struct sockaddr_un, sun_path);
1351#ifdef CONFIG_LINUX
1352    if (salen > 0 && !su->sun_path[0]) {
1353        /* Linux abstract socket */
1354        addr->u.q_unix.path = g_strndup(su->sun_path + 1, salen - 1);
1355        addr->u.q_unix.has_abstract = true;
1356        addr->u.q_unix.abstract = true;
1357        addr->u.q_unix.has_tight = true;
1358        addr->u.q_unix.tight = salen < sizeof(su->sun_path);
1359        return addr;
1360    }
1361#endif
1362
1363    addr->u.q_unix.path = g_strndup(su->sun_path, salen);
1364    return addr;
1365}
1366#endif /* WIN32 */
1367
1368#ifdef CONFIG_AF_VSOCK
1369static SocketAddress *
1370socket_sockaddr_to_address_vsock(struct sockaddr_storage *sa,
1371                                 socklen_t salen,
1372                                 Error **errp)
1373{
1374    SocketAddress *addr;
1375    VsockSocketAddress *vaddr;
1376    struct sockaddr_vm *svm = (struct sockaddr_vm *)sa;
1377
1378    addr = g_new0(SocketAddress, 1);
1379    addr->type = SOCKET_ADDRESS_TYPE_VSOCK;
1380    vaddr = &addr->u.vsock;
1381    vaddr->cid = g_strdup_printf("%u", svm->svm_cid);
1382    vaddr->port = g_strdup_printf("%u", svm->svm_port);
1383
1384    return addr;
1385}
1386#endif /* CONFIG_AF_VSOCK */
1387
1388SocketAddress *
1389socket_sockaddr_to_address(struct sockaddr_storage *sa,
1390                           socklen_t salen,
1391                           Error **errp)
1392{
1393    switch (sa->ss_family) {
1394    case AF_INET:
1395    case AF_INET6:
1396        return socket_sockaddr_to_address_inet(sa, salen, errp);
1397
1398#ifndef WIN32
1399    case AF_UNIX:
1400        return socket_sockaddr_to_address_unix(sa, salen, errp);
1401#endif /* WIN32 */
1402
1403#ifdef CONFIG_AF_VSOCK
1404    case AF_VSOCK:
1405        return socket_sockaddr_to_address_vsock(sa, salen, errp);
1406#endif
1407
1408    default:
1409        error_setg(errp, "socket family %d unsupported",
1410                   sa->ss_family);
1411        return NULL;
1412    }
1413    return 0;
1414}
1415
1416
1417SocketAddress *socket_local_address(int fd, Error **errp)
1418{
1419    struct sockaddr_storage ss;
1420    socklen_t sslen = sizeof(ss);
1421
1422    if (getsockname(fd, (struct sockaddr *)&ss, &sslen) < 0) {
1423        error_setg_errno(errp, errno, "%s",
1424                         "Unable to query local socket address");
1425        return NULL;
1426    }
1427
1428    return socket_sockaddr_to_address(&ss, sslen, errp);
1429}
1430
1431
1432SocketAddress *socket_remote_address(int fd, Error **errp)
1433{
1434    struct sockaddr_storage ss;
1435    socklen_t sslen = sizeof(ss);
1436
1437    if (getpeername(fd, (struct sockaddr *)&ss, &sslen) < 0) {
1438        error_setg_errno(errp, errno, "%s",
1439                         "Unable to query remote socket address");
1440        return NULL;
1441    }
1442
1443    return socket_sockaddr_to_address(&ss, sslen, errp);
1444}
1445
1446
1447SocketAddress *socket_address_flatten(SocketAddressLegacy *addr_legacy)
1448{
1449    SocketAddress *addr;
1450
1451    if (!addr_legacy) {
1452        return NULL;
1453    }
1454
1455    addr = g_new(SocketAddress, 1);
1456
1457    switch (addr_legacy->type) {
1458    case SOCKET_ADDRESS_TYPE_INET:
1459        addr->type = SOCKET_ADDRESS_TYPE_INET;
1460        QAPI_CLONE_MEMBERS(InetSocketAddress, &addr->u.inet,
1461                           addr_legacy->u.inet.data);
1462        break;
1463    case SOCKET_ADDRESS_TYPE_UNIX:
1464        addr->type = SOCKET_ADDRESS_TYPE_UNIX;
1465        QAPI_CLONE_MEMBERS(UnixSocketAddress, &addr->u.q_unix,
1466                           addr_legacy->u.q_unix.data);
1467        break;
1468    case SOCKET_ADDRESS_TYPE_VSOCK:
1469        addr->type = SOCKET_ADDRESS_TYPE_VSOCK;
1470        QAPI_CLONE_MEMBERS(VsockSocketAddress, &addr->u.vsock,
1471                           addr_legacy->u.vsock.data);
1472        break;
1473    case SOCKET_ADDRESS_TYPE_FD:
1474        addr->type = SOCKET_ADDRESS_TYPE_FD;
1475        QAPI_CLONE_MEMBERS(String, &addr->u.fd, addr_legacy->u.fd.data);
1476        break;
1477    default:
1478        abort();
1479    }
1480
1481    return addr;
1482}
1483