qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

dgram.c (19106B)


      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 
     39 typedef 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 
     50 static void net_dgram_send(void *opaque);
     51 static void net_dgram_writable(void *opaque);
     52 
     53 static 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 
     61 static void net_dgram_read_poll(NetDgramState *s, bool enable)
     62 {
     63     s->read_poll = enable;
     64     net_dgram_update_fd_handler(s);
     65 }
     66 
     67 static void net_dgram_write_poll(NetDgramState *s, bool enable)
     68 {
     69     s->write_poll = enable;
     70     net_dgram_update_fd_handler(s);
     71 }
     72 
     73 static 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 
     82 static 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 
    103 static 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 
    112 static 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 
    123 static 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 
    144 static 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;
    231 fail:
    232     if (fd >= 0) {
    233         closesocket(fd);
    234     }
    235     return -1;
    236 }
    237 
    238 static 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 
    252 static 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 
    259 static 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 
    279 static 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                 closesocket(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                 closesocket(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                 closesocket(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 
    421 int 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             closesocket(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             closesocket(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             closesocket(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 }