socket.c 21.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*
 * QEMU System Emulator
 *
 * Copyright (c) 2003-2008 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "config-host.h"

P
Paolo Bonzini 已提交
26
#include "net/net.h"
27
#include "clients.h"
28
#include "monitor/monitor.h"
29
#include "qemu-common.h"
30 31 32 33
#include "qemu/error-report.h"
#include "qemu/option.h"
#include "qemu/sockets.h"
#include "qemu/iov.h"
34
#include "qemu/main-loop.h"
35 36

typedef struct NetSocketState {
37
    NetClientState nc;
38
    int listen_fd;
39 40 41 42
    int fd;
    int state; /* 0 = getting length, 1 = getting data */
    unsigned int index;
    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 47 48
    IOHandler *send_fn;           /* differs between SOCK_STREAM/SOCK_DGRAM */
    bool read_poll;               /* waiting to receive data? */
    bool write_poll;              /* waiting to transmit data? */
49 50
} NetSocketState;

51
static void net_socket_accept(void *opaque);
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
static void net_socket_writable(void *opaque);

/* Only read packets from socket when peer can receive them */
static int net_socket_can_send(void *opaque)
{
    NetSocketState *s = opaque;

    return qemu_can_send_packet(&s->nc);
}

static void net_socket_update_fd_handler(NetSocketState *s)
{
    qemu_set_fd_handler2(s->fd,
                         s->read_poll  ? net_socket_can_send : NULL,
                         s->read_poll  ? s->send_fn : NULL,
                         s->write_poll ? net_socket_writable : NULL,
                         s);
}

static void net_socket_read_poll(NetSocketState *s, bool enable)
{
    s->read_poll = enable;
    net_socket_update_fd_handler(s);
}

static void net_socket_write_poll(NetSocketState *s, bool enable)
{
    s->write_poll = enable;
    net_socket_update_fd_handler(s);
}

static void net_socket_writable(void *opaque)
{
    NetSocketState *s = opaque;

    net_socket_write_poll(s, false);

    qemu_flush_queued_packets(&s->nc);
}
91

92
static ssize_t net_socket_receive(NetClientState *nc, const uint8_t *buf, size_t size)
93
{
94
    NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
95 96 97 98 99 100 101 102 103 104 105 106
    uint32_t len = htonl(size);
    struct iovec iov[] = {
        {
            .iov_base = &len,
            .iov_len  = sizeof(len),
        }, {
            .iov_base = (void *)buf,
            .iov_len  = size,
        },
    };
    size_t remaining;
    ssize_t ret;
107

108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
    remaining = iov_size(iov, 2) - s->send_index;
    ret = iov_send(s->fd, iov, 2, s->send_index, remaining);

    if (ret == -1 && errno == EAGAIN) {
        ret = 0; /* handled further down */
    }
    if (ret == -1) {
        s->send_index = 0;
        return -errno;
    }
    if (ret < (ssize_t)remaining) {
        s->send_index += ret;
        net_socket_write_poll(s, true);
        return 0;
    }
    s->send_index = 0;
    return size;
125 126
}

127
static 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 131 132
    ssize_t ret;

    do {
133 134 135
        ret = qemu_sendto(s->fd, buf, size, 0,
                          (struct sockaddr *)&s->dgram_dst,
                          sizeof(s->dgram_dst));
136 137 138 139 140 141 142
    } while (ret == -1 && errno == EINTR);

    if (ret == -1 && errno == EAGAIN) {
        net_socket_write_poll(s, true);
        return 0;
    }
    return ret;
143 144 145 146 147 148 149
}

static void net_socket_send(void *opaque)
{
    NetSocketState *s = opaque;
    int size, err;
    unsigned l;
150
    uint8_t buf1[NET_BUFSIZE];
151 152
    const uint8_t *buf;

B
Blue Swirl 已提交
153
    size = qemu_recv(s->fd, buf1, sizeof(buf1), 0);
154 155 156 157 158 159 160
    if (size < 0) {
        err = socket_error();
        if (err != EWOULDBLOCK)
            goto eoc;
    } else if (size == 0) {
        /* end of connection */
    eoc:
161 162
        net_socket_read_poll(s, false);
        net_socket_write_poll(s, false);
163 164 165
        if (s->listen_fd != -1) {
            qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
        }
166
        closesocket(s->fd);
167 168 169 170 171 172 173 174 175

        s->fd = -1;
        s->state = 0;
        s->index = 0;
        s->packet_len = 0;
        s->nc.link_down = true;
        memset(s->buf, 0, sizeof(s->buf));
        memset(s->nc.info_str, 0, sizeof(s->nc.info_str));

176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
        return;
    }
    buf = buf1;
    while (size > 0) {
        /* reassemble a packet from the network */
        switch(s->state) {
        case 0:
            l = 4 - s->index;
            if (l > size)
                l = size;
            memcpy(s->buf + s->index, buf, l);
            buf += l;
            size -= l;
            s->index += l;
            if (s->index == 4) {
                /* got length */
                s->packet_len = ntohl(*(uint32_t *)s->buf);
                s->index = 0;
                s->state = 1;
            }
            break;
        case 1:
            l = s->packet_len - s->index;
            if (l > size)
                l = size;
            if (s->index + l <= sizeof(s->buf)) {
                memcpy(s->buf + s->index, buf, l);
            } else {
                fprintf(stderr, "serious error: oversized packet received,"
                    "connection terminated.\n");
                s->state = 0;
                goto eoc;
            }

            s->index += l;
            buf += l;
            size -= l;
            if (s->index >= s->packet_len) {
214
                qemu_send_packet(&s->nc, s->buf, s->packet_len);
215 216 217 218 219 220 221 222 223 224 225 226 227
                s->index = 0;
                s->state = 0;
            }
            break;
        }
    }
}

static void net_socket_send_dgram(void *opaque)
{
    NetSocketState *s = opaque;
    int size;

B
Blue Swirl 已提交
228
    size = qemu_recv(s->fd, s->buf, sizeof(s->buf), 0);
229 230 231 232
    if (size < 0)
        return;
    if (size == 0) {
        /* end of connection */
233 234
        net_socket_read_poll(s, false);
        net_socket_write_poll(s, false);
235 236
        return;
    }
237
    qemu_send_packet(&s->nc, s->buf, size);
238 239
}

240
static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr *localaddr)
241 242 243 244
{
    struct ip_mreq imr;
    int fd;
    int val, ret;
245 246 247 248 249 250
#ifdef __OpenBSD__
    unsigned char loop;
#else
    int loop;
#endif

251
    if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
S
Stefan Hajnoczi 已提交
252 253 254
        fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) "
                "does not contain a multicast address\n",
                inet_ntoa(mcastaddr->sin_addr),
255
                (int)ntohl(mcastaddr->sin_addr.s_addr));
S
Stefan Hajnoczi 已提交
256
        return -1;
257 258

    }
K
Kevin Wolf 已提交
259
    fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);
260 261 262 263 264
    if (fd < 0) {
        perror("socket(PF_INET, SOCK_DGRAM)");
        return -1;
    }

265 266 267 268 269
    /* Allow multiple sockets to bind the same multicast ip and port by setting
     * SO_REUSEADDR. This is the only situation where SO_REUSEADDR should be set
     * on windows. Use socket_set_fast_reuse otherwise as it sets SO_REUSEADDR
     * only on posix systems.
     */
270
    val = 1;
271
    ret = qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
272
    if (ret < 0) {
S
Stefan Hajnoczi 已提交
273 274
        perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
        goto fail;
275 276 277 278 279 280 281 282 283 284
    }

    ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
    if (ret < 0) {
        perror("bind");
        goto fail;
    }

    /* Add host to multicast group */
    imr.imr_multiaddr = mcastaddr->sin_addr;
285 286 287 288 289
    if (localaddr) {
        imr.imr_interface = *localaddr;
    } else {
        imr.imr_interface.s_addr = htonl(INADDR_ANY);
    }
290

291 292
    ret = qemu_setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                          &imr, sizeof(struct ip_mreq));
293
    if (ret < 0) {
S
Stefan Hajnoczi 已提交
294 295
        perror("setsockopt(IP_ADD_MEMBERSHIP)");
        goto fail;
296 297 298
    }

    /* Force mcast msgs to loopback (eg. several QEMUs in same host */
299
    loop = 1;
300 301
    ret = qemu_setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
                          &loop, sizeof(loop));
302
    if (ret < 0) {
S
Stefan Hajnoczi 已提交
303 304
        perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
        goto fail;
305 306
    }

307 308
    /* If a bind address is given, only send packets from that address */
    if (localaddr != NULL) {
309 310
        ret = qemu_setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
                              localaddr, sizeof(*localaddr));
311 312 313 314 315 316
        if (ret < 0) {
            perror("setsockopt(IP_MULTICAST_IF)");
            goto fail;
        }
    }

317
    qemu_set_nonblock(fd);
318 319 320 321 322 323 324
    return fd;
fail:
    if (fd >= 0)
        closesocket(fd);
    return -1;
}

325
static void net_socket_cleanup(NetClientState *nc)
326
{
327
    NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
328
    if (s->fd != -1) {
329 330
        net_socket_read_poll(s, false);
        net_socket_write_poll(s, false);
331 332 333 334 335 336 337 338
        close(s->fd);
        s->fd = -1;
    }
    if (s->listen_fd != -1) {
        qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
        closesocket(s->listen_fd);
        s->listen_fd = -1;
    }
339 340
}

341
static NetClientInfo net_dgram_socket_info = {
342
    .type = NET_CLIENT_OPTIONS_KIND_SOCKET,
343 344 345 346 347
    .size = sizeof(NetSocketState),
    .receive = net_socket_receive_dgram,
    .cleanup = net_socket_cleanup,
};

348
static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
349 350 351 352 353 354
                                                const char *model,
                                                const char *name,
                                                int fd, int is_connected)
{
    struct sockaddr_in saddr;
    int newfd;
355
    socklen_t saddr_len = sizeof(saddr);
356
    NetClientState *nc;
357 358 359 360 361 362 363 364
    NetSocketState *s;

    /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
     * Because this may be "shared" socket from a "master" process, datagrams would be recv()
     * by ONLY ONE process: we must "clone" this dgram socket --jjo
     */

    if (is_connected) {
S
Stefan Hajnoczi 已提交
365 366 367 368 369
        if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
            /* must be bound */
            if (saddr.sin_addr.s_addr == 0) {
                fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, "
                        "cannot setup multicast dst addr\n", fd);
370
                goto err;
S
Stefan Hajnoczi 已提交
371 372 373 374 375
            }
            /* clone dgram socket */
            newfd = net_socket_mcast_create(&saddr, NULL);
            if (newfd < 0) {
                /* error already reported by net_socket_mcast_create() */
376
                goto err;
S
Stefan Hajnoczi 已提交
377 378 379 380 381 382 383 384 385
            }
            /* clone newfd to fd, close newfd */
            dup2(newfd, fd);
            close(newfd);

        } else {
            fprintf(stderr,
                    "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
                    fd, strerror(errno));
386
            goto err;
S
Stefan Hajnoczi 已提交
387
        }
388 389
    }

390
    nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name);
391 392 393

    s = DO_UPCAST(NetSocketState, nc, nc);

394
    s->fd = fd;
395
    s->listen_fd = -1;
396 397
    s->send_fn = net_socket_send_dgram;
    net_socket_read_poll(s, true);
398 399

    /* mcast: save bound address as dst */
Z
Zhi Yong Wu 已提交
400 401
    if (is_connected) {
        s->dgram_dst = saddr;
402 403 404 405 406 407
        snprintf(nc->info_str, sizeof(nc->info_str),
                 "socket: fd=%d (cloned mcast=%s:%d)",
                 fd, inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
    } else {
        snprintf(nc->info_str, sizeof(nc->info_str),
                 "socket: fd=%d", fd);
Z
Zhi Yong Wu 已提交
408
    }
409 410

    return s;
411 412 413 414

err:
    closesocket(fd);
    return NULL;
415 416 417 418 419
}

static void net_socket_connect(void *opaque)
{
    NetSocketState *s = opaque;
420 421
    s->send_fn = net_socket_send;
    net_socket_read_poll(s, true);
422 423
}

424
static NetClientInfo net_socket_info = {
425
    .type = NET_CLIENT_OPTIONS_KIND_SOCKET,
426 427 428 429 430
    .size = sizeof(NetSocketState),
    .receive = net_socket_receive,
    .cleanup = net_socket_cleanup,
};

431
static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
432 433 434 435
                                                 const char *model,
                                                 const char *name,
                                                 int fd, int is_connected)
{
436
    NetClientState *nc;
437
    NetSocketState *s;
438

439
    nc = qemu_new_net_client(&net_socket_info, peer, model, name);
440 441 442 443 444

    snprintf(nc->info_str, sizeof(nc->info_str), "socket: fd=%d", fd);

    s = DO_UPCAST(NetSocketState, nc, nc);

445
    s->fd = fd;
446
    s->listen_fd = -1;
447

448 449 450
    /* Disable Nagle algorithm on TCP sockets to reduce latency */
    socket_set_nodelay(fd);

451 452 453 454 455 456 457 458
    if (is_connected) {
        net_socket_connect(s);
    } else {
        qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
    }
    return s;
}

459
static NetSocketState *net_socket_fd_init(NetClientState *peer,
460 461 462 463 464 465 466
                                          const char *model, const char *name,
                                          int fd, int is_connected)
{
    int so_type = -1, optlen=sizeof(so_type);

    if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
        (socklen_t *)&optlen)< 0) {
S
Stefan Hajnoczi 已提交
467 468
        fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n",
                fd);
469
        closesocket(fd);
S
Stefan Hajnoczi 已提交
470
        return NULL;
471 472 473
    }
    switch(so_type) {
    case SOCK_DGRAM:
474
        return net_socket_fd_init_dgram(peer, model, name, fd, is_connected);
475
    case SOCK_STREAM:
476
        return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
477 478 479
    default:
        /* who knows ... this could be a eg. a pty, do warn and continue as stream */
        fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
480
        return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
481 482 483 484 485 486
    }
    return NULL;
}

static void net_socket_accept(void *opaque)
{
487
    NetSocketState *s = opaque;
488 489 490 491 492 493
    struct sockaddr_in saddr;
    socklen_t len;
    int fd;

    for(;;) {
        len = sizeof(saddr);
494
        fd = qemu_accept(s->listen_fd, (struct sockaddr *)&saddr, &len);
495 496 497
        if (fd < 0 && errno != EINTR) {
            return;
        } else if (fd >= 0) {
498
            qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
499 500 501
            break;
        }
    }
502 503 504 505 506 507 508

    s->fd = fd;
    s->nc.link_down = false;
    net_socket_connect(s);
    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
             "socket: connection from %s:%d",
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
509 510
}

511
static int net_socket_listen_init(NetClientState *peer,
512 513 514 515
                                  const char *model,
                                  const char *name,
                                  const char *host_str)
{
516 517
    NetClientState *nc;
    NetSocketState *s;
518
    struct sockaddr_in saddr;
519
    int fd, ret;
520 521 522 523

    if (parse_host_port(&saddr, host_str) < 0)
        return -1;

K
Kevin Wolf 已提交
524
    fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
525 526 527 528
    if (fd < 0) {
        perror("socket");
        return -1;
    }
529
    qemu_set_nonblock(fd);
530

531
    socket_set_fast_reuse(fd);
532 533 534 535

    ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
    if (ret < 0) {
        perror("bind");
536
        closesocket(fd);
537 538 539 540 541
        return -1;
    }
    ret = listen(fd, 0);
    if (ret < 0) {
        perror("listen");
542
        closesocket(fd);
543 544
        return -1;
    }
545 546 547 548 549 550 551 552

    nc = qemu_new_net_client(&net_socket_info, peer, model, name);
    s = DO_UPCAST(NetSocketState, nc, nc);
    s->fd = -1;
    s->listen_fd = fd;
    s->nc.link_down = true;

    qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
553 554 555
    return 0;
}

556
static int net_socket_connect_init(NetClientState *peer,
557 558 559 560 561 562 563 564 565 566 567
                                   const char *model,
                                   const char *name,
                                   const char *host_str)
{
    NetSocketState *s;
    int fd, connected, ret, err;
    struct sockaddr_in saddr;

    if (parse_host_port(&saddr, host_str) < 0)
        return -1;

K
Kevin Wolf 已提交
568
    fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
569 570 571 572
    if (fd < 0) {
        perror("socket");
        return -1;
    }
573
    qemu_set_nonblock(fd);
574 575 576 577 578 579 580 581 582 583

    connected = 0;
    for(;;) {
        ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
        if (ret < 0) {
            err = socket_error();
            if (err == EINTR || err == EWOULDBLOCK) {
            } else if (err == EINPROGRESS) {
                break;
#ifdef _WIN32
584
            } else if (err == WSAEALREADY || err == WSAEINVAL) {
585 586 587 588 589 590 591 592 593 594 595 596
                break;
#endif
            } else {
                perror("connect");
                closesocket(fd);
                return -1;
            }
        } else {
            connected = 1;
            break;
        }
    }
597
    s = net_socket_fd_init(peer, model, name, fd, connected);
598 599
    if (!s)
        return -1;
600
    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
601 602 603 604 605
             "socket: connect to %s:%d",
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
    return 0;
}

606
static int net_socket_mcast_init(NetClientState *peer,
607 608
                                 const char *model,
                                 const char *name,
609 610
                                 const char *host_str,
                                 const char *localaddr_str)
611 612 613 614
{
    NetSocketState *s;
    int fd;
    struct sockaddr_in saddr;
615
    struct in_addr localaddr, *param_localaddr;
616 617 618 619

    if (parse_host_port(&saddr, host_str) < 0)
        return -1;

620 621 622 623 624 625 626
    if (localaddr_str != NULL) {
        if (inet_aton(localaddr_str, &localaddr) == 0)
            return -1;
        param_localaddr = &localaddr;
    } else {
        param_localaddr = NULL;
    }
627

628
    fd = net_socket_mcast_create(&saddr, param_localaddr);
629
    if (fd < 0)
S
Stefan Hajnoczi 已提交
630
        return -1;
631

632
    s = net_socket_fd_init(peer, model, name, fd, 0);
633 634 635 636 637
    if (!s)
        return -1;

    s->dgram_dst = saddr;

638
    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
639 640 641 642 643 644
             "socket: mcast=%s:%d",
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
    return 0;

}

645
static int net_socket_udp_init(NetClientState *peer,
646 647 648 649 650 651
                                 const char *model,
                                 const char *name,
                                 const char *rhost,
                                 const char *lhost)
{
    NetSocketState *s;
652
    int fd, ret;
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667
    struct sockaddr_in laddr, raddr;

    if (parse_host_port(&laddr, lhost) < 0) {
        return -1;
    }

    if (parse_host_port(&raddr, rhost) < 0) {
        return -1;
    }

    fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);
    if (fd < 0) {
        perror("socket(PF_INET, SOCK_DGRAM)");
        return -1;
    }
668 669

    ret = socket_set_fast_reuse(fd);
670 671 672 673 674 675 676 677 678 679
    if (ret < 0) {
        closesocket(fd);
        return -1;
    }
    ret = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));
    if (ret < 0) {
        perror("bind");
        closesocket(fd);
        return -1;
    }
680
    qemu_set_nonblock(fd);
681

682
    s = net_socket_fd_init(peer, model, name, fd, 0);
683 684 685 686 687 688 689 690 691 692 693 694
    if (!s) {
        return -1;
    }

    s->dgram_dst = raddr;

    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
             "socket: udp=%s:%d",
             inet_ntoa(raddr.sin_addr), ntohs(raddr.sin_port));
    return 0;
}

695
int net_init_socket(const NetClientOptions *opts, const char *name,
696
                    NetClientState *peer)
697
{
698
    const NetdevSocketOptions *sock;
699

700 701
    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_SOCKET);
    sock = opts->socket;
702

703 704 705 706 707 708
    if (sock->has_fd + sock->has_listen + sock->has_connect + sock->has_mcast +
        sock->has_udp != 1) {
        error_report("exactly one of fd=, listen=, connect=, mcast= or udp="
                     " is required");
        return -1;
    }
709

710 711 712 713
    if (sock->has_localaddr && !sock->has_mcast && !sock->has_udp) {
        error_report("localaddr= is only valid with mcast= or udp=");
        return -1;
    }
714

715 716
    if (sock->has_fd) {
        int fd;
717

718
        fd = monitor_handle_fd_param(cur_mon, sock->fd);
719 720 721 722 723
        if (fd == -1) {
            return -1;
        }
        qemu_set_nonblock(fd);
        if (!net_socket_fd_init(peer, "socket", name, fd, 1)) {
724 725
            return -1;
        }
726 727
        return 0;
    }
728

729
    if (sock->has_listen) {
730
        if (net_socket_listen_init(peer, "socket", name, sock->listen) == -1) {
731 732
            return -1;
        }
733 734
        return 0;
    }
735

736
    if (sock->has_connect) {
737
        if (net_socket_connect_init(peer, "socket", name, sock->connect) ==
738
            -1) {
739 740
            return -1;
        }
741 742
        return 0;
    }
743

744 745 746
    if (sock->has_mcast) {
        /* if sock->localaddr is missing, it has been initialized to "all bits
         * zero" */
747
        if (net_socket_mcast_init(peer, "socket", name, sock->mcast,
748
            sock->localaddr) == -1) {
749 750
            return -1;
        }
751 752
        return 0;
    }
753

754 755 756 757 758
    assert(sock->has_udp);
    if (!sock->has_localaddr) {
        error_report("localaddr= is mandatory with udp=");
        return -1;
    }
759
    if (net_socket_udp_init(peer, "socket", name, sock->udp, sock->localaddr) ==
760
        -1) {
761 762 763 764
        return -1;
    }
    return 0;
}