qemu/net/socket.c
<<
>>
Prefs
   1/*
   2 * QEMU System Emulator
   3 *
   4 * Copyright (c) 2003-2008 Fabrice Bellard
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a copy
   7 * of this software and associated documentation files (the "Software"), to deal
   8 * in the Software without restriction, including without limitation the rights
   9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 * copies of the Software, and to permit persons to whom the Software is
  11 * furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 * THE SOFTWARE.
  23 */
  24#include "config-host.h"
  25
  26#include "net/net.h"
  27#include "clients.h"
  28#include "monitor/monitor.h"
  29#include "qemu-common.h"
  30#include "qemu/error-report.h"
  31#include "qemu/option.h"
  32#include "qemu/sockets.h"
  33#include "qemu/iov.h"
  34#include "qemu/main-loop.h"
  35
  36typedef struct NetSocketState {
  37    NetClientState nc;
  38    int listen_fd;
  39    int fd;
  40    int state; /* 0 = getting length, 1 = getting data */
  41    unsigned int index;
  42    unsigned int packet_len;
  43    unsigned int send_index;      /* number of bytes sent (only SOCK_STREAM) */
  44    uint8_t buf[NET_BUFSIZE];
  45    struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
  46    IOHandler *send_fn;           /* differs between SOCK_STREAM/SOCK_DGRAM */
  47    bool read_poll;               /* waiting to receive data? */
  48    bool write_poll;              /* waiting to transmit data? */
  49} NetSocketState;
  50
  51static void net_socket_accept(void *opaque);
  52static void net_socket_writable(void *opaque);
  53
  54/* Only read packets from socket when peer can receive them */
  55static int net_socket_can_send(void *opaque)
  56{
  57    NetSocketState *s = opaque;
  58
  59    return qemu_can_send_packet(&s->nc);
  60}
  61
  62static void net_socket_update_fd_handler(NetSocketState *s)
  63{
  64    qemu_set_fd_handler2(s->fd,
  65                         s->read_poll  ? net_socket_can_send : NULL,
  66                         s->read_poll  ? s->send_fn : NULL,
  67                         s->write_poll ? net_socket_writable : NULL,
  68                         s);
  69}
  70
  71static void net_socket_read_poll(NetSocketState *s, bool enable)
  72{
  73    s->read_poll = enable;
  74    net_socket_update_fd_handler(s);
  75}
  76
  77static void net_socket_write_poll(NetSocketState *s, bool enable)
  78{
  79    s->write_poll = enable;
  80    net_socket_update_fd_handler(s);
  81}
  82
  83static void net_socket_writable(void *opaque)
  84{
  85    NetSocketState *s = opaque;
  86
  87    net_socket_write_poll(s, false);
  88
  89    qemu_flush_queued_packets(&s->nc);
  90}
  91
  92static ssize_t net_socket_receive(NetClientState *nc, const uint8_t *buf, size_t size)
  93{
  94    NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
  95    uint32_t len = htonl(size);
  96    struct iovec iov[] = {
  97        {
  98            .iov_base = &len,
  99            .iov_len  = sizeof(len),
 100        }, {
 101            .iov_base = (void *)buf,
 102            .iov_len  = size,
 103        },
 104    };
 105    size_t remaining;
 106    ssize_t ret;
 107
 108    remaining = iov_size(iov, 2) - s->send_index;
 109    ret = iov_send(s->fd, iov, 2, s->send_index, remaining);
 110
 111    if (ret == -1 && errno == EAGAIN) {
 112        ret = 0; /* handled further down */
 113    }
 114    if (ret == -1) {
 115        s->send_index = 0;
 116        return -errno;
 117    }
 118    if (ret < (ssize_t)remaining) {
 119        s->send_index += ret;
 120        net_socket_write_poll(s, true);
 121        return 0;
 122    }
 123    s->send_index = 0;
 124    return size;
 125}
 126
 127static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t *buf, size_t size)
 128{
 129    NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
 130    ssize_t ret;
 131
 132    do {
 133        ret = qemu_sendto(s->fd, buf, size, 0,
 134                          (struct sockaddr *)&s->dgram_dst,
 135                          sizeof(s->dgram_dst));
 136    } while (ret == -1 && errno == EINTR);
 137
 138    if (ret == -1 && errno == EAGAIN) {
 139        net_socket_write_poll(s, true);
 140        return 0;
 141    }
 142    return ret;
 143}
 144
 145static void net_socket_send(void *opaque)
 146{
 147    NetSocketState *s = opaque;
 148    int size, err;
 149    unsigned l;
 150    uint8_t buf1[NET_BUFSIZE];
 151    const uint8_t *buf;
 152
 153    size = qemu_recv(s->fd, buf1, sizeof(buf1), 0);
 154    if (size < 0) {
 155        err = socket_error();
 156        if (err != EWOULDBLOCK)
 157            goto eoc;
 158    } else if (size == 0) {
 159        /* end of connection */
 160    eoc:
 161        net_socket_read_poll(s, false);
 162        net_socket_write_poll(s, false);
 163        if (s->listen_fd != -1) {
 164            qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
 165        }
 166        closesocket(s->fd);
 167
 168        s->fd = -1;
 169        s->state = 0;
 170        s->index = 0;
 171        s->packet_len = 0;
 172        s->nc.link_down = true;
 173        memset(s->buf, 0, sizeof(s->buf));
 174        memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
 175
 176        return;
 177    }
 178    buf = buf1;
 179    while (size > 0) {
 180        /* reassemble a packet from the network */
 181        switch(s->state) {
 182        case 0:
 183            l = 4 - s->index;
 184            if (l > size)
 185                l = size;
 186            memcpy(s->buf + s->index, buf, l);
 187            buf += l;
 188            size -= l;
 189            s->index += l;
 190            if (s->index == 4) {
 191                /* got length */
 192                s->packet_len = ntohl(*(uint32_t *)s->buf);
 193                s->index = 0;
 194                s->state = 1;
 195            }
 196            break;
 197        case 1:
 198            l = s->packet_len - s->index;
 199            if (l > size)
 200                l = size;
 201            if (s->index + l <= sizeof(s->buf)) {
 202                memcpy(s->buf + s->index, buf, l);
 203            } else {
 204                fprintf(stderr, "serious error: oversized packet received,"
 205                    "connection terminated.\n");
 206                s->state = 0;
 207                goto eoc;
 208            }
 209
 210            s->index += l;
 211            buf += l;
 212            size -= l;
 213            if (s->index >= s->packet_len) {
 214                qemu_send_packet(&s->nc, s->buf, s->packet_len);
 215                s->index = 0;
 216                s->state = 0;
 217            }
 218            break;
 219        }
 220    }
 221}
 222
 223static void net_socket_send_dgram(void *opaque)
 224{
 225    NetSocketState *s = opaque;
 226    int size;
 227
 228    size = qemu_recv(s->fd, s->buf, sizeof(s->buf), 0);
 229    if (size < 0)
 230        return;
 231    if (size == 0) {
 232        /* end of connection */
 233        net_socket_read_poll(s, false);
 234        net_socket_write_poll(s, false);
 235        return;
 236    }
 237    qemu_send_packet(&s->nc, s->buf, size);
 238}
 239
 240static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr *localaddr)
 241{
 242    struct ip_mreq imr;
 243    int fd;
 244    int val, ret;
 245#ifdef __OpenBSD__
 246    unsigned char loop;
 247#else
 248    int loop;
 249#endif
 250
 251    if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
 252        fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) "
 253                "does not contain a multicast address\n",
 254                inet_ntoa(mcastaddr->sin_addr),
 255                (int)ntohl(mcastaddr->sin_addr.s_addr));
 256        return -1;
 257
 258    }
 259    fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);
 260    if (fd < 0) {
 261        perror("socket(PF_INET, SOCK_DGRAM)");
 262        return -1;
 263    }
 264
 265    /* Allow multiple sockets to bind the same multicast ip and port by setting
 266     * SO_REUSEADDR. This is the only situation where SO_REUSEADDR should be set
 267     * on windows. Use socket_set_fast_reuse otherwise as it sets SO_REUSEADDR
 268     * only on posix systems.
 269     */
 270    val = 1;
 271    ret = qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
 272    if (ret < 0) {
 273        perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
 274        goto fail;
 275    }
 276
 277    ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
 278    if (ret < 0) {
 279        perror("bind");
 280        goto fail;
 281    }
 282
 283    /* Add host to multicast group */
 284    imr.imr_multiaddr = mcastaddr->sin_addr;
 285    if (localaddr) {
 286        imr.imr_interface = *localaddr;
 287    } else {
 288        imr.imr_interface.s_addr = htonl(INADDR_ANY);
 289    }
 290
 291    ret = qemu_setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
 292                          &imr, sizeof(struct ip_mreq));
 293    if (ret < 0) {
 294        perror("setsockopt(IP_ADD_MEMBERSHIP)");
 295        goto fail;
 296    }
 297
 298    /* Force mcast msgs to loopback (eg. several QEMUs in same host */
 299    loop = 1;
 300    ret = qemu_setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
 301                          &loop, sizeof(loop));
 302    if (ret < 0) {
 303        perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
 304        goto fail;
 305    }
 306
 307    /* If a bind address is given, only send packets from that address */
 308    if (localaddr != NULL) {
 309        ret = qemu_setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
 310                              localaddr, sizeof(*localaddr));
 311        if (ret < 0) {
 312            perror("setsockopt(IP_MULTICAST_IF)");
 313            goto fail;
 314        }
 315    }
 316
 317    qemu_set_nonblock(fd);
 318    return fd;
 319fail:
 320    if (fd >= 0)
 321        closesocket(fd);
 322    return -1;
 323}
 324
 325static void net_socket_cleanup(NetClientState *nc)
 326{
 327    NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
 328    if (s->fd != -1) {
 329        net_socket_read_poll(s, false);
 330        net_socket_write_poll(s, false);
 331        close(s->fd);
 332        s->fd = -1;
 333    }
 334    if (s->listen_fd != -1) {
 335        qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
 336        closesocket(s->listen_fd);
 337        s->listen_fd = -1;
 338    }
 339}
 340
 341static NetClientInfo net_dgram_socket_info = {
 342    .type = NET_CLIENT_OPTIONS_KIND_SOCKET,
 343    .size = sizeof(NetSocketState),
 344    .receive = net_socket_receive_dgram,
 345    .cleanup = net_socket_cleanup,
 346};
 347
 348static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
 349                                                const char *model,
 350                                                const char *name,
 351                                                int fd, int is_connected)
 352{
 353    struct sockaddr_in saddr;
 354    int newfd;
 355    socklen_t saddr_len;
 356    NetClientState *nc;
 357    NetSocketState *s;
 358
 359    /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
 360     * Because this may be "shared" socket from a "master" process, datagrams would be recv()
 361     * by ONLY ONE process: we must "clone" this dgram socket --jjo
 362     */
 363
 364    if (is_connected) {
 365        if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
 366            /* must be bound */
 367            if (saddr.sin_addr.s_addr == 0) {
 368                fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, "
 369                        "cannot setup multicast dst addr\n", fd);
 370                goto err;
 371            }
 372            /* clone dgram socket */
 373            newfd = net_socket_mcast_create(&saddr, NULL);
 374            if (newfd < 0) {
 375                /* error already reported by net_socket_mcast_create() */
 376                goto err;
 377            }
 378            /* clone newfd to fd, close newfd */
 379            dup2(newfd, fd);
 380            close(newfd);
 381
 382        } else {
 383            fprintf(stderr,
 384                    "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
 385                    fd, strerror(errno));
 386            goto err;
 387        }
 388    }
 389
 390    nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name);
 391
 392    snprintf(nc->info_str, sizeof(nc->info_str),
 393            "socket: fd=%d (%s mcast=%s:%d)",
 394            fd, is_connected ? "cloned" : "",
 395            inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
 396
 397    s = DO_UPCAST(NetSocketState, nc, nc);
 398
 399    s->fd = fd;
 400    s->listen_fd = -1;
 401    s->send_fn = net_socket_send_dgram;
 402    net_socket_read_poll(s, true);
 403
 404    /* mcast: save bound address as dst */
 405    if (is_connected) {
 406        s->dgram_dst = saddr;
 407    }
 408
 409    return s;
 410
 411err:
 412    closesocket(fd);
 413    return NULL;
 414}
 415
 416static void net_socket_connect(void *opaque)
 417{
 418    NetSocketState *s = opaque;
 419    s->send_fn = net_socket_send;
 420    net_socket_read_poll(s, true);
 421}
 422
 423static NetClientInfo net_socket_info = {
 424    .type = NET_CLIENT_OPTIONS_KIND_SOCKET,
 425    .size = sizeof(NetSocketState),
 426    .receive = net_socket_receive,
 427    .cleanup = net_socket_cleanup,
 428};
 429
 430static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
 431                                                 const char *model,
 432                                                 const char *name,
 433                                                 int fd, int is_connected)
 434{
 435    NetClientState *nc;
 436    NetSocketState *s;
 437
 438    nc = qemu_new_net_client(&net_socket_info, peer, model, name);
 439
 440    snprintf(nc->info_str, sizeof(nc->info_str), "socket: fd=%d", fd);
 441
 442    s = DO_UPCAST(NetSocketState, nc, nc);
 443
 444    s->fd = fd;
 445    s->listen_fd = -1;
 446
 447    /* Disable Nagle algorithm on TCP sockets to reduce latency */
 448    socket_set_nodelay(fd);
 449
 450    if (is_connected) {
 451        net_socket_connect(s);
 452    } else {
 453        qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
 454    }
 455    return s;
 456}
 457
 458static NetSocketState *net_socket_fd_init(NetClientState *peer,
 459                                          const char *model, const char *name,
 460                                          int fd, int is_connected)
 461{
 462    int so_type = -1, optlen=sizeof(so_type);
 463
 464    if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
 465        (socklen_t *)&optlen)< 0) {
 466        fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n",
 467                fd);
 468        closesocket(fd);
 469        return NULL;
 470    }
 471    switch(so_type) {
 472    case SOCK_DGRAM:
 473        return net_socket_fd_init_dgram(peer, model, name, fd, is_connected);
 474    case SOCK_STREAM:
 475        return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
 476    default:
 477        /* who knows ... this could be a eg. a pty, do warn and continue as stream */
 478        fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
 479        return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
 480    }
 481    return NULL;
 482}
 483
 484static void net_socket_accept(void *opaque)
 485{
 486    NetSocketState *s = opaque;
 487    struct sockaddr_in saddr;
 488    socklen_t len;
 489    int fd;
 490
 491    for(;;) {
 492        len = sizeof(saddr);
 493        fd = qemu_accept(s->listen_fd, (struct sockaddr *)&saddr, &len);
 494        if (fd < 0 && errno != EINTR) {
 495            return;
 496        } else if (fd >= 0) {
 497            qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
 498            break;
 499        }
 500    }
 501
 502    s->fd = fd;
 503    s->nc.link_down = false;
 504    net_socket_connect(s);
 505    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
 506             "socket: connection from %s:%d",
 507             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
 508}
 509
 510static int net_socket_listen_init(NetClientState *peer,
 511                                  const char *model,
 512                                  const char *name,
 513                                  const char *host_str)
 514{
 515    NetClientState *nc;
 516    NetSocketState *s;
 517    struct sockaddr_in saddr;
 518    int fd, ret;
 519
 520    if (parse_host_port(&saddr, host_str) < 0)
 521        return -1;
 522
 523    fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
 524    if (fd < 0) {
 525        perror("socket");
 526        return -1;
 527    }
 528    qemu_set_nonblock(fd);
 529
 530    socket_set_fast_reuse(fd);
 531
 532    ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
 533    if (ret < 0) {
 534        perror("bind");
 535        closesocket(fd);
 536        return -1;
 537    }
 538    ret = listen(fd, 0);
 539    if (ret < 0) {
 540        perror("listen");
 541        closesocket(fd);
 542        return -1;
 543    }
 544
 545    nc = qemu_new_net_client(&net_socket_info, peer, model, name);
 546    s = DO_UPCAST(NetSocketState, nc, nc);
 547    s->fd = -1;
 548    s->listen_fd = fd;
 549    s->nc.link_down = true;
 550
 551    qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
 552    return 0;
 553}
 554
 555static int net_socket_connect_init(NetClientState *peer,
 556                                   const char *model,
 557                                   const char *name,
 558                                   const char *host_str)
 559{
 560    NetSocketState *s;
 561    int fd, connected, ret, err;
 562    struct sockaddr_in saddr;
 563
 564    if (parse_host_port(&saddr, host_str) < 0)
 565        return -1;
 566
 567    fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
 568    if (fd < 0) {
 569        perror("socket");
 570        return -1;
 571    }
 572    qemu_set_nonblock(fd);
 573
 574    connected = 0;
 575    for(;;) {
 576        ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
 577        if (ret < 0) {
 578            err = socket_error();
 579            if (err == EINTR || err == EWOULDBLOCK) {
 580            } else if (err == EINPROGRESS) {
 581                break;
 582#ifdef _WIN32
 583            } else if (err == WSAEALREADY || err == WSAEINVAL) {
 584                break;
 585#endif
 586            } else {
 587                perror("connect");
 588                closesocket(fd);
 589                return -1;
 590            }
 591        } else {
 592            connected = 1;
 593            break;
 594        }
 595    }
 596    s = net_socket_fd_init(peer, model, name, fd, connected);
 597    if (!s)
 598        return -1;
 599    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
 600             "socket: connect to %s:%d",
 601             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
 602    return 0;
 603}
 604
 605static int net_socket_mcast_init(NetClientState *peer,
 606                                 const char *model,
 607                                 const char *name,
 608                                 const char *host_str,
 609                                 const char *localaddr_str)
 610{
 611    NetSocketState *s;
 612    int fd;
 613    struct sockaddr_in saddr;
 614    struct in_addr localaddr, *param_localaddr;
 615
 616    if (parse_host_port(&saddr, host_str) < 0)
 617        return -1;
 618
 619    if (localaddr_str != NULL) {
 620        if (inet_aton(localaddr_str, &localaddr) == 0)
 621            return -1;
 622        param_localaddr = &localaddr;
 623    } else {
 624        param_localaddr = NULL;
 625    }
 626
 627    fd = net_socket_mcast_create(&saddr, param_localaddr);
 628    if (fd < 0)
 629        return -1;
 630
 631    s = net_socket_fd_init(peer, model, name, fd, 0);
 632    if (!s)
 633        return -1;
 634
 635    s->dgram_dst = saddr;
 636
 637    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
 638             "socket: mcast=%s:%d",
 639             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
 640    return 0;
 641
 642}
 643
 644static int net_socket_udp_init(NetClientState *peer,
 645                                 const char *model,
 646                                 const char *name,
 647                                 const char *rhost,
 648                                 const char *lhost)
 649{
 650    NetSocketState *s;
 651    int fd, ret;
 652    struct sockaddr_in laddr, raddr;
 653
 654    if (parse_host_port(&laddr, lhost) < 0) {
 655        return -1;
 656    }
 657
 658    if (parse_host_port(&raddr, rhost) < 0) {
 659        return -1;
 660    }
 661
 662    fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);
 663    if (fd < 0) {
 664        perror("socket(PF_INET, SOCK_DGRAM)");
 665        return -1;
 666    }
 667
 668    ret = socket_set_fast_reuse(fd);
 669    if (ret < 0) {
 670        closesocket(fd);
 671        return -1;
 672    }
 673    ret = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));
 674    if (ret < 0) {
 675        perror("bind");
 676        closesocket(fd);
 677        return -1;
 678    }
 679    qemu_set_nonblock(fd);
 680
 681    s = net_socket_fd_init(peer, model, name, fd, 0);
 682    if (!s) {
 683        return -1;
 684    }
 685
 686    s->dgram_dst = raddr;
 687
 688    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
 689             "socket: udp=%s:%d",
 690             inet_ntoa(raddr.sin_addr), ntohs(raddr.sin_port));
 691    return 0;
 692}
 693
 694int net_init_socket(const NetClientOptions *opts, const char *name,
 695                    NetClientState *peer)
 696{
 697    const NetdevSocketOptions *sock;
 698
 699    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_SOCKET);
 700    sock = opts->socket;
 701
 702    if (sock->has_fd + sock->has_listen + sock->has_connect + sock->has_mcast +
 703        sock->has_udp != 1) {
 704        error_report("exactly one of fd=, listen=, connect=, mcast= or udp="
 705                     " is required");
 706        return -1;
 707    }
 708
 709    if (sock->has_localaddr && !sock->has_mcast && !sock->has_udp) {
 710        error_report("localaddr= is only valid with mcast= or udp=");
 711        return -1;
 712    }
 713
 714    if (sock->has_fd) {
 715        int fd;
 716
 717        fd = monitor_handle_fd_param(cur_mon, sock->fd);
 718        if (fd == -1) {
 719            return -1;
 720        }
 721        qemu_set_nonblock(fd);
 722        if (!net_socket_fd_init(peer, "socket", name, fd, 1)) {
 723            return -1;
 724        }
 725        return 0;
 726    }
 727
 728    if (sock->has_listen) {
 729        if (net_socket_listen_init(peer, "socket", name, sock->listen) == -1) {
 730            return -1;
 731        }
 732        return 0;
 733    }
 734
 735    if (sock->has_connect) {
 736        if (net_socket_connect_init(peer, "socket", name, sock->connect) ==
 737            -1) {
 738            return -1;
 739        }
 740        return 0;
 741    }
 742
 743    if (sock->has_mcast) {
 744        /* if sock->localaddr is missing, it has been initialized to "all bits
 745         * zero" */
 746        if (net_socket_mcast_init(peer, "socket", name, sock->mcast,
 747            sock->localaddr) == -1) {
 748            return -1;
 749        }
 750        return 0;
 751    }
 752
 753    assert(sock->has_udp);
 754    if (!sock->has_localaddr) {
 755        error_report("localaddr= is mandatory with udp=");
 756        return -1;
 757    }
 758    if (net_socket_udp_init(peer, "socket", name, sock->udp, sock->localaddr) ==
 759        -1) {
 760        return -1;
 761    }
 762    return 0;
 763}
 764