qemu/net/dgram.c
<<
>>
Prefs
   1/*
   2 * QEMU System Emulator
   3 *
   4 * Copyright (c) 2003-2008 Fabrice Bellard
   5 * Copyright (c) 2022 Red Hat, Inc.
   6 *
   7 * Permission is hereby granted, free of charge, to any person obtaining a copy
   8 * of this software and associated documentation files (the "Software"), to deal
   9 * in the Software without restriction, including without limitation the rights
  10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 * copies of the Software, and to permit persons to whom the Software is
  12 * furnished to do so, subject to the following conditions:
  13 *
  14 * The above copyright notice and this permission notice shall be included in
  15 * all copies or substantial portions of the Software.
  16 *
  17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 * THE SOFTWARE.
  24 */
  25
  26#include "qemu/osdep.h"
  27
  28#include "net/net.h"
  29#include "clients.h"
  30#include "monitor/monitor.h"
  31#include "qapi/error.h"
  32#include "qemu/error-report.h"
  33#include "qemu/option.h"
  34#include "qemu/sockets.h"
  35#include "qemu/iov.h"
  36#include "qemu/main-loop.h"
  37#include "qemu/cutils.h"
  38
  39typedef struct NetDgramState {
  40    NetClientState nc;
  41    int fd;
  42    SocketReadState rs;
  43    bool read_poll;               /* waiting to receive data? */
  44    bool write_poll;              /* waiting to transmit data? */
  45    /* contains destination iff connectionless */
  46    struct sockaddr *dest_addr;
  47    socklen_t dest_len;
  48} NetDgramState;
  49
  50static void net_dgram_send(void *opaque);
  51static void net_dgram_writable(void *opaque);
  52
  53static void net_dgram_update_fd_handler(NetDgramState *s)
  54{
  55    qemu_set_fd_handler(s->fd,
  56                        s->read_poll ? net_dgram_send : NULL,
  57                        s->write_poll ? net_dgram_writable : NULL,
  58                        s);
  59}
  60
  61static void net_dgram_read_poll(NetDgramState *s, bool enable)
  62{
  63    s->read_poll = enable;
  64    net_dgram_update_fd_handler(s);
  65}
  66
  67static void net_dgram_write_poll(NetDgramState *s, bool enable)
  68{
  69    s->write_poll = enable;
  70    net_dgram_update_fd_handler(s);
  71}
  72
  73static void net_dgram_writable(void *opaque)
  74{
  75    NetDgramState *s = opaque;
  76
  77    net_dgram_write_poll(s, false);
  78
  79    qemu_flush_queued_packets(&s->nc);
  80}
  81
  82static ssize_t net_dgram_receive(NetClientState *nc,
  83                                 const uint8_t *buf, size_t size)
  84{
  85    NetDgramState *s = DO_UPCAST(NetDgramState, nc, nc);
  86    ssize_t ret;
  87
  88    do {
  89        if (s->dest_addr) {
  90            ret = sendto(s->fd, buf, size, 0, s->dest_addr, s->dest_len);
  91        } else {
  92            ret = send(s->fd, buf, size, 0);
  93        }
  94    } while (ret == -1 && errno == EINTR);
  95
  96    if (ret == -1 && errno == EAGAIN) {
  97        net_dgram_write_poll(s, true);
  98        return 0;
  99    }
 100    return ret;
 101}
 102
 103static void net_dgram_send_completed(NetClientState *nc, ssize_t len)
 104{
 105    NetDgramState *s = DO_UPCAST(NetDgramState, nc, nc);
 106
 107    if (!s->read_poll) {
 108        net_dgram_read_poll(s, true);
 109    }
 110}
 111
 112static void net_dgram_rs_finalize(SocketReadState *rs)
 113{
 114    NetDgramState *s = container_of(rs, NetDgramState, rs);
 115
 116    if (qemu_send_packet_async(&s->nc, rs->buf,
 117                               rs->packet_len,
 118                               net_dgram_send_completed) == 0) {
 119        net_dgram_read_poll(s, false);
 120    }
 121}
 122
 123static void net_dgram_send(void *opaque)
 124{
 125    NetDgramState *s = opaque;
 126    int size;
 127
 128    size = recv(s->fd, s->rs.buf, sizeof(s->rs.buf), 0);
 129    if (size < 0) {
 130        return;
 131    }
 132    if (size == 0) {
 133        /* end of connection */
 134        net_dgram_read_poll(s, false);
 135        net_dgram_write_poll(s, false);
 136        return;
 137    }
 138    if (qemu_send_packet_async(&s->nc, s->rs.buf, size,
 139                               net_dgram_send_completed) == 0) {
 140        net_dgram_read_poll(s, false);
 141    }
 142}
 143
 144static int net_dgram_mcast_create(struct sockaddr_in *mcastaddr,
 145                                  struct in_addr *localaddr,
 146                                  Error **errp)
 147{
 148    struct ip_mreq imr;
 149    int fd;
 150    int val, ret;
 151#ifdef __OpenBSD__
 152    unsigned char loop;
 153#else
 154    int loop;
 155#endif
 156
 157    if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
 158        error_setg(errp, "specified mcastaddr %s (0x%08x) "
 159                   "does not contain a multicast address",
 160                   inet_ntoa(mcastaddr->sin_addr),
 161                   (int)ntohl(mcastaddr->sin_addr.s_addr));
 162        return -1;
 163    }
 164
 165    fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);
 166    if (fd < 0) {
 167        error_setg_errno(errp, errno, "can't create datagram socket");
 168        return -1;
 169    }
 170
 171    /*
 172     * Allow multiple sockets to bind the same multicast ip and port by setting
 173     * SO_REUSEADDR. This is the only situation where SO_REUSEADDR should be set
 174     * on windows. Use socket_set_fast_reuse otherwise as it sets SO_REUSEADDR
 175     * only on posix systems.
 176     */
 177    val = 1;
 178    ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
 179    if (ret < 0) {
 180        error_setg_errno(errp, errno, "can't set socket option SO_REUSEADDR");
 181        goto fail;
 182    }
 183
 184    ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
 185    if (ret < 0) {
 186        error_setg_errno(errp, errno, "can't bind ip=%s to socket",
 187                         inet_ntoa(mcastaddr->sin_addr));
 188        goto fail;
 189    }
 190
 191    /* Add host to multicast group */
 192    imr.imr_multiaddr = mcastaddr->sin_addr;
 193    if (localaddr) {
 194        imr.imr_interface = *localaddr;
 195    } else {
 196        imr.imr_interface.s_addr = htonl(INADDR_ANY);
 197    }
 198
 199    ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
 200                     &imr, sizeof(struct ip_mreq));
 201    if (ret < 0) {
 202        error_setg_errno(errp, errno,
 203                         "can't add socket to multicast group %s",
 204                         inet_ntoa(imr.imr_multiaddr));
 205        goto fail;
 206    }
 207
 208    /* Force mcast msgs to loopback (eg. several QEMUs in same host */
 209    loop = 1;
 210    ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
 211                     &loop, sizeof(loop));
 212    if (ret < 0) {
 213        error_setg_errno(errp, errno,
 214                         "can't force multicast message to loopback");
 215        goto fail;
 216    }
 217
 218    /* If a bind address is given, only send packets from that address */
 219    if (localaddr != NULL) {
 220        ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
 221                         localaddr, sizeof(*localaddr));
 222        if (ret < 0) {
 223            error_setg_errno(errp, errno,
 224                             "can't set the default network send interface");
 225            goto fail;
 226        }
 227    }
 228
 229    qemu_socket_set_nonblock(fd);
 230    return fd;
 231fail:
 232    if (fd >= 0) {
 233        close(fd);
 234    }
 235    return -1;
 236}
 237
 238static void net_dgram_cleanup(NetClientState *nc)
 239{
 240    NetDgramState *s = DO_UPCAST(NetDgramState, nc, nc);
 241    if (s->fd != -1) {
 242        net_dgram_read_poll(s, false);
 243        net_dgram_write_poll(s, false);
 244        close(s->fd);
 245        s->fd = -1;
 246    }
 247    g_free(s->dest_addr);
 248    s->dest_addr = NULL;
 249    s->dest_len = 0;
 250}
 251
 252static NetClientInfo net_dgram_socket_info = {
 253    .type = NET_CLIENT_DRIVER_DGRAM,
 254    .size = sizeof(NetDgramState),
 255    .receive = net_dgram_receive,
 256    .cleanup = net_dgram_cleanup,
 257};
 258
 259static NetDgramState *net_dgram_fd_init(NetClientState *peer,
 260                                        const char *model,
 261                                        const char *name,
 262                                        int fd,
 263                                        Error **errp)
 264{
 265    NetClientState *nc;
 266    NetDgramState *s;
 267
 268    nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name);
 269
 270    s = DO_UPCAST(NetDgramState, nc, nc);
 271
 272    s->fd = fd;
 273    net_socket_rs_init(&s->rs, net_dgram_rs_finalize, false);
 274    net_dgram_read_poll(s, true);
 275
 276    return s;
 277}
 278
 279static int net_dgram_mcast_init(NetClientState *peer,
 280                                const char *model,
 281                                const char *name,
 282                                SocketAddress *remote,
 283                                SocketAddress *local,
 284                                Error **errp)
 285{
 286    NetDgramState *s;
 287    int fd, ret;
 288    struct sockaddr_in *saddr;
 289
 290    if (remote->type != SOCKET_ADDRESS_TYPE_INET) {
 291        error_setg(errp, "multicast only support inet type");
 292        return -1;
 293    }
 294
 295    saddr = g_new(struct sockaddr_in, 1);
 296    if (convert_host_port(saddr, remote->u.inet.host, remote->u.inet.port,
 297                          errp) < 0) {
 298        g_free(saddr);
 299        return -1;
 300    }
 301
 302    if (!local) {
 303        fd = net_dgram_mcast_create(saddr, NULL, errp);
 304        if (fd < 0) {
 305            g_free(saddr);
 306            return -1;
 307        }
 308    } else {
 309        switch (local->type) {
 310        case SOCKET_ADDRESS_TYPE_INET: {
 311            struct in_addr localaddr;
 312
 313            if (inet_aton(local->u.inet.host, &localaddr) == 0) {
 314                g_free(saddr);
 315                error_setg(errp, "localaddr '%s' is not a valid IPv4 address",
 316                           local->u.inet.host);
 317                return -1;
 318            }
 319
 320            fd = net_dgram_mcast_create(saddr, &localaddr, errp);
 321            if (fd < 0) {
 322                g_free(saddr);
 323                return -1;
 324            }
 325            break;
 326        }
 327        case SOCKET_ADDRESS_TYPE_FD: {
 328            int newfd;
 329
 330            fd = monitor_fd_param(monitor_cur(), local->u.fd.str, errp);
 331            if (fd == -1) {
 332                g_free(saddr);
 333                return -1;
 334            }
 335            ret = qemu_socket_try_set_nonblock(fd);
 336            if (ret < 0) {
 337                g_free(saddr);
 338                error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
 339                                 name, fd);
 340                return -1;
 341            }
 342
 343            /*
 344             * fd passed: multicast: "learn" dest_addr address from bound
 345             * address and save it. Because this may be "shared" socket from a
 346             * "master" process, datagrams would be recv() by ONLY ONE process:
 347             * we must "clone" this dgram socket --jjo
 348             */
 349
 350            saddr = g_new(struct sockaddr_in, 1);
 351
 352            if (convert_host_port(saddr, local->u.inet.host, local->u.inet.port,
 353                                  errp) < 0) {
 354                g_free(saddr);
 355                close(fd);
 356                return -1;
 357            }
 358
 359            /* must be bound */
 360            if (saddr->sin_addr.s_addr == 0) {
 361                error_setg(errp, "can't setup multicast destination address");
 362                g_free(saddr);
 363                close(fd);
 364                return -1;
 365            }
 366            /* clone dgram socket */
 367            newfd = net_dgram_mcast_create(saddr, NULL, errp);
 368            if (newfd < 0) {
 369                g_free(saddr);
 370                close(fd);
 371                return -1;
 372            }
 373            /* clone newfd to fd, close newfd */
 374            dup2(newfd, fd);
 375            close(newfd);
 376            break;
 377        }
 378        default:
 379            g_free(saddr);
 380            error_setg(errp, "only support inet or fd type for local");
 381            return -1;
 382        }
 383    }
 384
 385    s = net_dgram_fd_init(peer, model, name, fd, errp);
 386    if (!s) {
 387        g_free(saddr);
 388        return -1;
 389    }
 390
 391    g_assert(s->dest_addr == NULL);
 392    s->dest_addr = (struct sockaddr *)saddr;
 393    s->dest_len = sizeof(*saddr);
 394
 395    if (!local) {
 396        qemu_set_info_str(&s->nc, "mcast=%s:%d",
 397                          inet_ntoa(saddr->sin_addr),
 398                          ntohs(saddr->sin_port));
 399    } else {
 400        switch (local->type) {
 401        case SOCKET_ADDRESS_TYPE_INET:
 402            qemu_set_info_str(&s->nc, "mcast=%s:%d",
 403                              inet_ntoa(saddr->sin_addr),
 404                              ntohs(saddr->sin_port));
 405            break;
 406        case SOCKET_ADDRESS_TYPE_FD:
 407            qemu_set_info_str(&s->nc, "fd=%d (cloned mcast=%s:%d)",
 408                              fd, inet_ntoa(saddr->sin_addr),
 409                              ntohs(saddr->sin_port));
 410            break;
 411        default:
 412            g_assert_not_reached();
 413        }
 414    }
 415
 416    return 0;
 417
 418}
 419
 420
 421int net_init_dgram(const Netdev *netdev, const char *name,
 422                   NetClientState *peer, Error **errp)
 423{
 424    NetDgramState *s;
 425    int fd, ret;
 426    SocketAddress *remote, *local;
 427    struct sockaddr *dest_addr;
 428    struct sockaddr_in laddr_in, raddr_in;
 429    struct sockaddr_un laddr_un, raddr_un;
 430    socklen_t dest_len;
 431
 432    assert(netdev->type == NET_CLIENT_DRIVER_DGRAM);
 433
 434    remote = netdev->u.dgram.remote;
 435    local = netdev->u.dgram.local;
 436
 437    /* detect multicast address */
 438    if (remote && remote->type == SOCKET_ADDRESS_TYPE_INET) {
 439        struct sockaddr_in mcastaddr;
 440
 441        if (convert_host_port(&mcastaddr, remote->u.inet.host,
 442                              remote->u.inet.port, errp) < 0) {
 443            return -1;
 444        }
 445
 446        if (IN_MULTICAST(ntohl(mcastaddr.sin_addr.s_addr))) {
 447            return net_dgram_mcast_init(peer, "dram", name, remote, local,
 448                                           errp);
 449        }
 450    }
 451
 452    /* unicast address */
 453    if (!local) {
 454        error_setg(errp, "dgram requires local= parameter");
 455        return -1;
 456    }
 457
 458    if (remote) {
 459        if (local->type == SOCKET_ADDRESS_TYPE_FD) {
 460            error_setg(errp, "don't set remote with local.fd");
 461            return -1;
 462        }
 463        if (remote->type != local->type) {
 464            error_setg(errp, "remote and local types must be the same");
 465            return -1;
 466        }
 467    } else {
 468        if (local->type != SOCKET_ADDRESS_TYPE_FD) {
 469            error_setg(errp,
 470                       "type=inet or type=unix requires remote parameter");
 471            return -1;
 472        }
 473    }
 474
 475    switch (local->type) {
 476    case SOCKET_ADDRESS_TYPE_INET:
 477        if (convert_host_port(&laddr_in, local->u.inet.host, local->u.inet.port,
 478                              errp) < 0) {
 479            return -1;
 480        }
 481
 482        if (convert_host_port(&raddr_in, remote->u.inet.host,
 483                              remote->u.inet.port, errp) < 0) {
 484            return -1;
 485        }
 486
 487        fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);
 488        if (fd < 0) {
 489            error_setg_errno(errp, errno, "can't create datagram socket");
 490            return -1;
 491        }
 492
 493        ret = socket_set_fast_reuse(fd);
 494        if (ret < 0) {
 495            error_setg_errno(errp, errno,
 496                             "can't set socket option SO_REUSEADDR");
 497            close(fd);
 498            return -1;
 499        }
 500        ret = bind(fd, (struct sockaddr *)&laddr_in, sizeof(laddr_in));
 501        if (ret < 0) {
 502            error_setg_errno(errp, errno, "can't bind ip=%s to socket",
 503                             inet_ntoa(laddr_in.sin_addr));
 504            close(fd);
 505            return -1;
 506        }
 507        qemu_socket_set_nonblock(fd);
 508
 509        dest_len = sizeof(raddr_in);
 510        dest_addr = g_malloc(dest_len);
 511        memcpy(dest_addr, &raddr_in, dest_len);
 512        break;
 513    case SOCKET_ADDRESS_TYPE_UNIX:
 514        ret = unlink(local->u.q_unix.path);
 515        if (ret < 0 && errno != ENOENT) {
 516            error_setg_errno(errp, errno, "failed to unlink socket %s",
 517                             local->u.q_unix.path);
 518            return -1;
 519        }
 520
 521        laddr_un.sun_family = PF_UNIX;
 522        ret = snprintf(laddr_un.sun_path, sizeof(laddr_un.sun_path), "%s",
 523                       local->u.q_unix.path);
 524        if (ret < 0 || ret >= sizeof(laddr_un.sun_path)) {
 525            error_setg(errp, "UNIX socket path '%s' is too long",
 526                       local->u.q_unix.path);
 527            error_append_hint(errp, "Path must be less than %zu bytes\n",
 528                              sizeof(laddr_un.sun_path));
 529        }
 530
 531        raddr_un.sun_family = PF_UNIX;
 532        ret = snprintf(raddr_un.sun_path, sizeof(raddr_un.sun_path), "%s",
 533                       remote->u.q_unix.path);
 534        if (ret < 0 || ret >= sizeof(raddr_un.sun_path)) {
 535            error_setg(errp, "UNIX socket path '%s' is too long",
 536                       remote->u.q_unix.path);
 537            error_append_hint(errp, "Path must be less than %zu bytes\n",
 538                              sizeof(raddr_un.sun_path));
 539        }
 540
 541        fd = qemu_socket(PF_UNIX, SOCK_DGRAM, 0);
 542        if (fd < 0) {
 543            error_setg_errno(errp, errno, "can't create datagram socket");
 544            return -1;
 545        }
 546
 547        ret = bind(fd, (struct sockaddr *)&laddr_un, sizeof(laddr_un));
 548        if (ret < 0) {
 549            error_setg_errno(errp, errno, "can't bind unix=%s to socket",
 550                             laddr_un.sun_path);
 551            close(fd);
 552            return -1;
 553        }
 554        qemu_socket_set_nonblock(fd);
 555
 556        dest_len = sizeof(raddr_un);
 557        dest_addr = g_malloc(dest_len);
 558        memcpy(dest_addr, &raddr_un, dest_len);
 559        break;
 560    case SOCKET_ADDRESS_TYPE_FD:
 561        fd = monitor_fd_param(monitor_cur(), local->u.fd.str, errp);
 562        if (fd == -1) {
 563            return -1;
 564        }
 565        ret = qemu_socket_try_set_nonblock(fd);
 566        if (ret < 0) {
 567            error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
 568                             name, fd);
 569            return -1;
 570        }
 571        dest_addr = NULL;
 572        dest_len = 0;
 573        break;
 574    default:
 575        error_setg(errp, "only support inet or fd type for local");
 576        return -1;
 577    }
 578
 579    s = net_dgram_fd_init(peer, "dgram", name, fd, errp);
 580    if (!s) {
 581        return -1;
 582    }
 583
 584    if (remote) {
 585        g_assert(s->dest_addr == NULL);
 586        s->dest_addr = dest_addr;
 587        s->dest_len = dest_len;
 588    }
 589
 590    switch (local->type) {
 591    case SOCKET_ADDRESS_TYPE_INET:
 592        qemu_set_info_str(&s->nc, "udp=%s:%d/%s:%d",
 593                          inet_ntoa(laddr_in.sin_addr),
 594                          ntohs(laddr_in.sin_port),
 595                          inet_ntoa(raddr_in.sin_addr),
 596                          ntohs(raddr_in.sin_port));
 597        break;
 598    case SOCKET_ADDRESS_TYPE_UNIX:
 599        qemu_set_info_str(&s->nc, "udp=%s:%s",
 600                          laddr_un.sun_path, raddr_un.sun_path);
 601        break;
 602    case SOCKET_ADDRESS_TYPE_FD: {
 603        SocketAddress *sa;
 604        SocketAddressType sa_type;
 605
 606        sa = socket_local_address(fd, errp);
 607        if (sa) {
 608            sa_type = sa->type;
 609            qapi_free_SocketAddress(sa);
 610
 611            qemu_set_info_str(&s->nc, "fd=%d %s", fd,
 612                              SocketAddressType_str(sa_type));
 613        } else {
 614            qemu_set_info_str(&s->nc, "fd=%d", fd);
 615        }
 616        break;
 617    }
 618    default:
 619        g_assert_not_reached();
 620    }
 621
 622    return 0;
 623}
 624