cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

socket.c (23038B)


      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 "qemu/osdep.h"
     25
     26#include "net/net.h"
     27#include "clients.h"
     28#include "monitor/monitor.h"
     29#include "qapi/error.h"
     30#include "qemu-common.h"
     31#include "qemu/error-report.h"
     32#include "qemu/option.h"
     33#include "qemu/sockets.h"
     34#include "qemu/iov.h"
     35#include "qemu/main-loop.h"
     36
     37typedef struct NetSocketState {
     38    NetClientState nc;
     39    int listen_fd;
     40    int fd;
     41    SocketReadState rs;
     42    unsigned int send_index;      /* number of bytes sent (only SOCK_STREAM) */
     43    struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
     44    IOHandler *send_fn;           /* differs between SOCK_STREAM/SOCK_DGRAM */
     45    bool read_poll;               /* waiting to receive data? */
     46    bool write_poll;              /* waiting to transmit data? */
     47} NetSocketState;
     48
     49static void net_socket_accept(void *opaque);
     50static void net_socket_writable(void *opaque);
     51
     52static void net_socket_update_fd_handler(NetSocketState *s)
     53{
     54    qemu_set_fd_handler(s->fd,
     55                        s->read_poll ? s->send_fn : NULL,
     56                        s->write_poll ? net_socket_writable : NULL,
     57                        s);
     58}
     59
     60static void net_socket_read_poll(NetSocketState *s, bool enable)
     61{
     62    s->read_poll = enable;
     63    net_socket_update_fd_handler(s);
     64}
     65
     66static void net_socket_write_poll(NetSocketState *s, bool enable)
     67{
     68    s->write_poll = enable;
     69    net_socket_update_fd_handler(s);
     70}
     71
     72static void net_socket_writable(void *opaque)
     73{
     74    NetSocketState *s = opaque;
     75
     76    net_socket_write_poll(s, false);
     77
     78    qemu_flush_queued_packets(&s->nc);
     79}
     80
     81static ssize_t net_socket_receive(NetClientState *nc, const uint8_t *buf, size_t size)
     82{
     83    NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
     84    uint32_t len = htonl(size);
     85    struct iovec iov[] = {
     86        {
     87            .iov_base = &len,
     88            .iov_len  = sizeof(len),
     89        }, {
     90            .iov_base = (void *)buf,
     91            .iov_len  = size,
     92        },
     93    };
     94    size_t remaining;
     95    ssize_t ret;
     96
     97    remaining = iov_size(iov, 2) - s->send_index;
     98    ret = iov_send(s->fd, iov, 2, s->send_index, remaining);
     99
    100    if (ret == -1 && errno == EAGAIN) {
    101        ret = 0; /* handled further down */
    102    }
    103    if (ret == -1) {
    104        s->send_index = 0;
    105        return -errno;
    106    }
    107    if (ret < (ssize_t)remaining) {
    108        s->send_index += ret;
    109        net_socket_write_poll(s, true);
    110        return 0;
    111    }
    112    s->send_index = 0;
    113    return size;
    114}
    115
    116static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t *buf, size_t size)
    117{
    118    NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
    119    ssize_t ret;
    120
    121    do {
    122        if (s->dgram_dst.sin_family != AF_UNIX) {
    123            ret = qemu_sendto(s->fd, buf, size, 0,
    124                              (struct sockaddr *)&s->dgram_dst,
    125                              sizeof(s->dgram_dst));
    126        } else {
    127            ret = send(s->fd, buf, size, 0);
    128        }
    129    } while (ret == -1 && errno == EINTR);
    130
    131    if (ret == -1 && errno == EAGAIN) {
    132        net_socket_write_poll(s, true);
    133        return 0;
    134    }
    135    return ret;
    136}
    137
    138static void net_socket_send_completed(NetClientState *nc, ssize_t len)
    139{
    140    NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
    141
    142    if (!s->read_poll) {
    143        net_socket_read_poll(s, true);
    144    }
    145}
    146
    147static void net_socket_rs_finalize(SocketReadState *rs)
    148{
    149    NetSocketState *s = container_of(rs, NetSocketState, rs);
    150
    151    if (qemu_send_packet_async(&s->nc, rs->buf,
    152                               rs->packet_len,
    153                               net_socket_send_completed) == 0) {
    154        net_socket_read_poll(s, false);
    155    }
    156}
    157
    158static void net_socket_send(void *opaque)
    159{
    160    NetSocketState *s = opaque;
    161    int size;
    162    int ret;
    163    uint8_t buf1[NET_BUFSIZE];
    164    const uint8_t *buf;
    165
    166    size = qemu_recv(s->fd, buf1, sizeof(buf1), 0);
    167    if (size < 0) {
    168        if (errno != EWOULDBLOCK)
    169            goto eoc;
    170    } else if (size == 0) {
    171        /* end of connection */
    172    eoc:
    173        net_socket_read_poll(s, false);
    174        net_socket_write_poll(s, false);
    175        if (s->listen_fd != -1) {
    176            qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
    177        }
    178        closesocket(s->fd);
    179
    180        s->fd = -1;
    181        net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
    182        s->nc.link_down = true;
    183        memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
    184
    185        return;
    186    }
    187    buf = buf1;
    188
    189    ret = net_fill_rstate(&s->rs, buf, size);
    190
    191    if (ret == -1) {
    192        goto eoc;
    193    }
    194}
    195
    196static void net_socket_send_dgram(void *opaque)
    197{
    198    NetSocketState *s = opaque;
    199    int size;
    200
    201    size = qemu_recv(s->fd, s->rs.buf, sizeof(s->rs.buf), 0);
    202    if (size < 0)
    203        return;
    204    if (size == 0) {
    205        /* end of connection */
    206        net_socket_read_poll(s, false);
    207        net_socket_write_poll(s, false);
    208        return;
    209    }
    210    if (qemu_send_packet_async(&s->nc, s->rs.buf, size,
    211                               net_socket_send_completed) == 0) {
    212        net_socket_read_poll(s, false);
    213    }
    214}
    215
    216static int net_socket_mcast_create(struct sockaddr_in *mcastaddr,
    217                                   struct in_addr *localaddr,
    218                                   Error **errp)
    219{
    220    struct ip_mreq imr;
    221    int fd;
    222    int val, ret;
    223#ifdef __OpenBSD__
    224    unsigned char loop;
    225#else
    226    int loop;
    227#endif
    228
    229    if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
    230        error_setg(errp, "specified mcastaddr %s (0x%08x) "
    231                   "does not contain a multicast address",
    232                   inet_ntoa(mcastaddr->sin_addr),
    233                   (int)ntohl(mcastaddr->sin_addr.s_addr));
    234        return -1;
    235    }
    236
    237    fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);
    238    if (fd < 0) {
    239        error_setg_errno(errp, errno, "can't create datagram socket");
    240        return -1;
    241    }
    242
    243    /* Allow multiple sockets to bind the same multicast ip and port by setting
    244     * SO_REUSEADDR. This is the only situation where SO_REUSEADDR should be set
    245     * on windows. Use socket_set_fast_reuse otherwise as it sets SO_REUSEADDR
    246     * only on posix systems.
    247     */
    248    val = 1;
    249    ret = qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
    250    if (ret < 0) {
    251        error_setg_errno(errp, errno,
    252                         "can't set socket option SO_REUSEADDR");
    253        goto fail;
    254    }
    255
    256    ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
    257    if (ret < 0) {
    258        error_setg_errno(errp, errno, "can't bind ip=%s to socket",
    259                         inet_ntoa(mcastaddr->sin_addr));
    260        goto fail;
    261    }
    262
    263    /* Add host to multicast group */
    264    imr.imr_multiaddr = mcastaddr->sin_addr;
    265    if (localaddr) {
    266        imr.imr_interface = *localaddr;
    267    } else {
    268        imr.imr_interface.s_addr = htonl(INADDR_ANY);
    269    }
    270
    271    ret = qemu_setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
    272                          &imr, sizeof(struct ip_mreq));
    273    if (ret < 0) {
    274        error_setg_errno(errp, errno,
    275                         "can't add socket to multicast group %s",
    276                         inet_ntoa(imr.imr_multiaddr));
    277        goto fail;
    278    }
    279
    280    /* Force mcast msgs to loopback (eg. several QEMUs in same host */
    281    loop = 1;
    282    ret = qemu_setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
    283                          &loop, sizeof(loop));
    284    if (ret < 0) {
    285        error_setg_errno(errp, errno,
    286                         "can't force multicast message to loopback");
    287        goto fail;
    288    }
    289
    290    /* If a bind address is given, only send packets from that address */
    291    if (localaddr != NULL) {
    292        ret = qemu_setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
    293                              localaddr, sizeof(*localaddr));
    294        if (ret < 0) {
    295            error_setg_errno(errp, errno,
    296                             "can't set the default network send interface");
    297            goto fail;
    298        }
    299    }
    300
    301    qemu_set_nonblock(fd);
    302    return fd;
    303fail:
    304    if (fd >= 0)
    305        closesocket(fd);
    306    return -1;
    307}
    308
    309static void net_socket_cleanup(NetClientState *nc)
    310{
    311    NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
    312    if (s->fd != -1) {
    313        net_socket_read_poll(s, false);
    314        net_socket_write_poll(s, false);
    315        close(s->fd);
    316        s->fd = -1;
    317    }
    318    if (s->listen_fd != -1) {
    319        qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
    320        closesocket(s->listen_fd);
    321        s->listen_fd = -1;
    322    }
    323}
    324
    325static NetClientInfo net_dgram_socket_info = {
    326    .type = NET_CLIENT_DRIVER_SOCKET,
    327    .size = sizeof(NetSocketState),
    328    .receive = net_socket_receive_dgram,
    329    .cleanup = net_socket_cleanup,
    330};
    331
    332static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
    333                                                const char *model,
    334                                                const char *name,
    335                                                int fd, int is_connected,
    336                                                const char *mcast,
    337                                                Error **errp)
    338{
    339    struct sockaddr_in saddr;
    340    int newfd;
    341    NetClientState *nc;
    342    NetSocketState *s;
    343    SocketAddress *sa;
    344    SocketAddressType sa_type;
    345
    346    sa = socket_local_address(fd, errp);
    347    if (!sa) {
    348        return NULL;
    349    }
    350    sa_type = sa->type;
    351    qapi_free_SocketAddress(sa);
    352
    353    /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
    354     * Because this may be "shared" socket from a "master" process, datagrams would be recv()
    355     * by ONLY ONE process: we must "clone" this dgram socket --jjo
    356     */
    357
    358    if (is_connected && mcast != NULL) {
    359            if (parse_host_port(&saddr, mcast, errp) < 0) {
    360                goto err;
    361            }
    362            /* must be bound */
    363            if (saddr.sin_addr.s_addr == 0) {
    364                error_setg(errp, "can't setup multicast destination address");
    365                goto err;
    366            }
    367            /* clone dgram socket */
    368            newfd = net_socket_mcast_create(&saddr, NULL, errp);
    369            if (newfd < 0) {
    370                goto err;
    371            }
    372            /* clone newfd to fd, close newfd */
    373            dup2(newfd, fd);
    374            close(newfd);
    375
    376    }
    377
    378    nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name);
    379
    380    s = DO_UPCAST(NetSocketState, nc, nc);
    381
    382    s->fd = fd;
    383    s->listen_fd = -1;
    384    s->send_fn = net_socket_send_dgram;
    385    net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
    386    net_socket_read_poll(s, true);
    387
    388    /* mcast: save bound address as dst */
    389    if (is_connected && mcast != NULL) {
    390        s->dgram_dst = saddr;
    391        snprintf(nc->info_str, sizeof(nc->info_str),
    392                 "socket: fd=%d (cloned mcast=%s:%d)",
    393                 fd, inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
    394    } else {
    395        if (sa_type == SOCKET_ADDRESS_TYPE_UNIX) {
    396            s->dgram_dst.sin_family = AF_UNIX;
    397        }
    398
    399        snprintf(nc->info_str, sizeof(nc->info_str),
    400                 "socket: fd=%d %s", fd, SocketAddressType_str(sa_type));
    401    }
    402
    403    return s;
    404
    405err:
    406    closesocket(fd);
    407    return NULL;
    408}
    409
    410static void net_socket_connect(void *opaque)
    411{
    412    NetSocketState *s = opaque;
    413    s->send_fn = net_socket_send;
    414    net_socket_read_poll(s, true);
    415}
    416
    417static NetClientInfo net_socket_info = {
    418    .type = NET_CLIENT_DRIVER_SOCKET,
    419    .size = sizeof(NetSocketState),
    420    .receive = net_socket_receive,
    421    .cleanup = net_socket_cleanup,
    422};
    423
    424static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
    425                                                 const char *model,
    426                                                 const char *name,
    427                                                 int fd, int is_connected)
    428{
    429    NetClientState *nc;
    430    NetSocketState *s;
    431
    432    nc = qemu_new_net_client(&net_socket_info, peer, model, name);
    433
    434    snprintf(nc->info_str, sizeof(nc->info_str), "socket: fd=%d", fd);
    435
    436    s = DO_UPCAST(NetSocketState, nc, nc);
    437
    438    s->fd = fd;
    439    s->listen_fd = -1;
    440    net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
    441
    442    /* Disable Nagle algorithm on TCP sockets to reduce latency */
    443    socket_set_nodelay(fd);
    444
    445    if (is_connected) {
    446        net_socket_connect(s);
    447    } else {
    448        qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
    449    }
    450    return s;
    451}
    452
    453static NetSocketState *net_socket_fd_init(NetClientState *peer,
    454                                          const char *model, const char *name,
    455                                          int fd, int is_connected,
    456                                          const char *mc, Error **errp)
    457{
    458    int so_type = -1, optlen=sizeof(so_type);
    459
    460    if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
    461        (socklen_t *)&optlen)< 0) {
    462        error_setg(errp, "can't get socket option SO_TYPE");
    463        closesocket(fd);
    464        return NULL;
    465    }
    466    switch(so_type) {
    467    case SOCK_DGRAM:
    468        return net_socket_fd_init_dgram(peer, model, name, fd, is_connected,
    469                                        mc, errp);
    470    case SOCK_STREAM:
    471        return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
    472    default:
    473        error_setg(errp, "socket type=%d for fd=%d must be either"
    474                   " SOCK_DGRAM or SOCK_STREAM", so_type, fd);
    475        closesocket(fd);
    476    }
    477    return NULL;
    478}
    479
    480static void net_socket_accept(void *opaque)
    481{
    482    NetSocketState *s = opaque;
    483    struct sockaddr_in saddr;
    484    socklen_t len;
    485    int fd;
    486
    487    for(;;) {
    488        len = sizeof(saddr);
    489        fd = qemu_accept(s->listen_fd, (struct sockaddr *)&saddr, &len);
    490        if (fd < 0 && errno != EINTR) {
    491            return;
    492        } else if (fd >= 0) {
    493            qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
    494            break;
    495        }
    496    }
    497
    498    s->fd = fd;
    499    s->nc.link_down = false;
    500    net_socket_connect(s);
    501    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
    502             "socket: connection from %s:%d",
    503             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
    504}
    505
    506static int net_socket_listen_init(NetClientState *peer,
    507                                  const char *model,
    508                                  const char *name,
    509                                  const char *host_str,
    510                                  Error **errp)
    511{
    512    NetClientState *nc;
    513    NetSocketState *s;
    514    struct sockaddr_in saddr;
    515    int fd, ret;
    516
    517    if (parse_host_port(&saddr, host_str, errp) < 0) {
    518        return -1;
    519    }
    520
    521    fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
    522    if (fd < 0) {
    523        error_setg_errno(errp, errno, "can't create stream socket");
    524        return -1;
    525    }
    526    qemu_set_nonblock(fd);
    527
    528    socket_set_fast_reuse(fd);
    529
    530    ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
    531    if (ret < 0) {
    532        error_setg_errno(errp, errno, "can't bind ip=%s to socket",
    533                         inet_ntoa(saddr.sin_addr));
    534        closesocket(fd);
    535        return -1;
    536    }
    537    ret = listen(fd, 0);
    538    if (ret < 0) {
    539        error_setg_errno(errp, errno, "can't listen on socket");
    540        closesocket(fd);
    541        return -1;
    542    }
    543
    544    nc = qemu_new_net_client(&net_socket_info, peer, model, name);
    545    s = DO_UPCAST(NetSocketState, nc, nc);
    546    s->fd = -1;
    547    s->listen_fd = fd;
    548    s->nc.link_down = true;
    549    net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
    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                                   Error **errp)
    560{
    561    NetSocketState *s;
    562    int fd, connected, ret;
    563    struct sockaddr_in saddr;
    564
    565    if (parse_host_port(&saddr, host_str, errp) < 0) {
    566        return -1;
    567    }
    568
    569    fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
    570    if (fd < 0) {
    571        error_setg_errno(errp, errno, "can't create stream socket");
    572        return -1;
    573    }
    574    qemu_set_nonblock(fd);
    575
    576    connected = 0;
    577    for(;;) {
    578        ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
    579        if (ret < 0) {
    580            if (errno == EINTR || errno == EWOULDBLOCK) {
    581                /* continue */
    582            } else if (errno == EINPROGRESS ||
    583                       errno == EALREADY ||
    584                       errno == EINVAL) {
    585                break;
    586            } else {
    587                error_setg_errno(errp, errno, "can't connect socket");
    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, NULL, errp);
    597    if (!s) {
    598        return -1;
    599    }
    600
    601    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
    602             "socket: connect to %s:%d",
    603             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
    604    return 0;
    605}
    606
    607static int net_socket_mcast_init(NetClientState *peer,
    608                                 const char *model,
    609                                 const char *name,
    610                                 const char *host_str,
    611                                 const char *localaddr_str,
    612                                 Error **errp)
    613{
    614    NetSocketState *s;
    615    int fd;
    616    struct sockaddr_in saddr;
    617    struct in_addr localaddr, *param_localaddr;
    618
    619    if (parse_host_port(&saddr, host_str, errp) < 0) {
    620        return -1;
    621    }
    622
    623    if (localaddr_str != NULL) {
    624        if (inet_aton(localaddr_str, &localaddr) == 0) {
    625            error_setg(errp, "localaddr '%s' is not a valid IPv4 address",
    626                       localaddr_str);
    627            return -1;
    628        }
    629        param_localaddr = &localaddr;
    630    } else {
    631        param_localaddr = NULL;
    632    }
    633
    634    fd = net_socket_mcast_create(&saddr, param_localaddr, errp);
    635    if (fd < 0) {
    636        return -1;
    637    }
    638
    639    s = net_socket_fd_init(peer, model, name, fd, 0, NULL, errp);
    640    if (!s) {
    641        return -1;
    642    }
    643
    644    s->dgram_dst = saddr;
    645
    646    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
    647             "socket: mcast=%s:%d",
    648             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
    649    return 0;
    650
    651}
    652
    653static int net_socket_udp_init(NetClientState *peer,
    654                                 const char *model,
    655                                 const char *name,
    656                                 const char *rhost,
    657                                 const char *lhost,
    658                                 Error **errp)
    659{
    660    NetSocketState *s;
    661    int fd, ret;
    662    struct sockaddr_in laddr, raddr;
    663
    664    if (parse_host_port(&laddr, lhost, errp) < 0) {
    665        return -1;
    666    }
    667
    668    if (parse_host_port(&raddr, rhost, errp) < 0) {
    669        return -1;
    670    }
    671
    672    fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);
    673    if (fd < 0) {
    674        error_setg_errno(errp, errno, "can't create datagram socket");
    675        return -1;
    676    }
    677
    678    ret = socket_set_fast_reuse(fd);
    679    if (ret < 0) {
    680        error_setg_errno(errp, errno,
    681                         "can't set socket option SO_REUSEADDR");
    682        closesocket(fd);
    683        return -1;
    684    }
    685    ret = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));
    686    if (ret < 0) {
    687        error_setg_errno(errp, errno, "can't bind ip=%s to socket",
    688                         inet_ntoa(laddr.sin_addr));
    689        closesocket(fd);
    690        return -1;
    691    }
    692    qemu_set_nonblock(fd);
    693
    694    s = net_socket_fd_init(peer, model, name, fd, 0, NULL, errp);
    695    if (!s) {
    696        return -1;
    697    }
    698
    699    s->dgram_dst = raddr;
    700
    701    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
    702             "socket: udp=%s:%d",
    703             inet_ntoa(raddr.sin_addr), ntohs(raddr.sin_port));
    704    return 0;
    705}
    706
    707int net_init_socket(const Netdev *netdev, const char *name,
    708                    NetClientState *peer, Error **errp)
    709{
    710    const NetdevSocketOptions *sock;
    711
    712    assert(netdev->type == NET_CLIENT_DRIVER_SOCKET);
    713    sock = &netdev->u.socket;
    714
    715    if (sock->has_fd + sock->has_listen + sock->has_connect + sock->has_mcast +
    716        sock->has_udp != 1) {
    717        error_setg(errp, "exactly one of listen=, connect=, mcast= or udp="
    718                   " is required");
    719        return -1;
    720    }
    721
    722    if (sock->has_localaddr && !sock->has_mcast && !sock->has_udp) {
    723        error_setg(errp, "localaddr= is only valid with mcast= or udp=");
    724        return -1;
    725    }
    726
    727    if (sock->has_fd) {
    728        int fd, ret;
    729
    730        fd = monitor_fd_param(monitor_cur(), sock->fd, errp);
    731        if (fd == -1) {
    732            return -1;
    733        }
    734        ret = qemu_try_set_nonblock(fd);
    735        if (ret < 0) {
    736            error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
    737                             name, fd);
    738            return -1;
    739        }
    740        if (!net_socket_fd_init(peer, "socket", name, fd, 1, sock->mcast,
    741                                errp)) {
    742            return -1;
    743        }
    744        return 0;
    745    }
    746
    747    if (sock->has_listen) {
    748        if (net_socket_listen_init(peer, "socket", name, sock->listen, errp)
    749            < 0) {
    750            return -1;
    751        }
    752        return 0;
    753    }
    754
    755    if (sock->has_connect) {
    756        if (net_socket_connect_init(peer, "socket", name, sock->connect, errp)
    757            < 0) {
    758            return -1;
    759        }
    760        return 0;
    761    }
    762
    763    if (sock->has_mcast) {
    764        /* if sock->localaddr is missing, it has been initialized to "all bits
    765         * zero" */
    766        if (net_socket_mcast_init(peer, "socket", name, sock->mcast,
    767                                  sock->localaddr, errp) < 0) {
    768            return -1;
    769        }
    770        return 0;
    771    }
    772
    773    assert(sock->has_udp);
    774    if (!sock->has_localaddr) {
    775        error_setg(errp, "localaddr= is mandatory with udp=");
    776        return -1;
    777    }
    778    if (net_socket_udp_init(peer, "socket", name, sock->udp, sock->localaddr,
    779                            errp) < 0) {
    780        return -1;
    781    }
    782    return 0;
    783}