qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 5/5] Migrate Datagram operation in socket transpo


From: anton . ivanov
Subject: [Qemu-devel] [PATCH v2 5/5] Migrate Datagram operation in socket transport to UDST
Date: Thu, 20 Jul 2017 20:12:28 +0100

From: Anton Ivanov <address@hidden>

Migrate datagram operation to UDST if UDST is available.

Signed-off-by: Anton Ivanov <address@hidden>
---
 net/socket.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 118 insertions(+), 5 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index f85ef7d61b..0523fe9ac1 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -33,6 +33,9 @@
 #include "qemu/sockets.h"
 #include "qemu/iov.h"
 #include "qemu/main-loop.h"
+#ifdef CONFIG_UDST
+#include "udst.h"
+#endif
 
 typedef struct NetSocketState {
     NetClientState nc;
@@ -49,6 +52,14 @@ typedef struct NetSocketState {
 static void net_socket_accept(void *opaque);
 static void net_socket_writable(void *opaque);
 
+#ifdef CONFIG_UDST
+static int noop(void *us, uint8_t *buf)
+{
+    return 0;
+}
+#endif
+
+
 static void net_socket_update_fd_handler(NetSocketState *s)
 {
     qemu_set_fd_handler(s->fd,
@@ -113,6 +124,8 @@ static ssize_t net_socket_receive(NetClientState *nc, const 
uint8_t *buf, size_t
     return size;
 }
 
+#ifndef CONFIG_UDST
+
 static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t 
*buf, size_t size)
 {
     NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
@@ -130,6 +143,7 @@ static ssize_t net_socket_receive_dgram(NetClientState *nc, 
const uint8_t *buf,
     }
     return ret;
 }
+#endif
 
 static void net_socket_send_completed(NetClientState *nc, ssize_t len)
 {
@@ -189,6 +203,8 @@ static void net_socket_send(void *opaque)
     }
 }
 
+#ifndef CONFIG_UDST
+
 static void net_socket_send_dgram(void *opaque)
 {
     NetSocketState *s = opaque;
@@ -208,6 +224,7 @@ static void net_socket_send_dgram(void *opaque)
         net_socket_read_poll(s, false);
     }
 }
+#endif
 
 static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct 
in_addr *localaddr)
 {
@@ -309,7 +326,85 @@ static void net_socket_cleanup(NetClientState *nc)
         s->listen_fd = -1;
     }
 }
+#ifdef CONFIG_UDST
+static NetUdstState *net_socket_fd_init_dgram(NetClientState *peer,
+                                                const char *model,
+                                                const char *name,
+                                                int fd, int is_connected)
+{
+    struct sockaddr_in saddr;
+    int newfd;
+    socklen_t saddr_len = sizeof(saddr);
+    NetClientState *nc;
+    NetUdstState *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) {
+        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);
+                goto err;
+            }
+            /* clone dgram socket */
+            newfd = net_socket_mcast_create(&saddr, NULL);
+            if (newfd < 0) {
+                /* error already reported by net_socket_mcast_create() */
+                goto err;
+            }
+            /* 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));
+            goto err;
+        }
+    }
+
+    fprintf(stderr,
+            "qemu: init udst for fd=%d\n",
+            fd);
+    nc = qemu_new_udst_net_client(name, peer);
+
+    s = DO_UPCAST(NetUdstState, nc, nc);
+
+    s->offset = 0;
+
+    qemu_net_finalize_udst_init(s,
+        &noop,
+        NULL,
+        fd);
+
+    /* mcast: save bound address as dst */
+    if (is_connected) {
+        s->dgram_dst = g_memdup(&saddr, sizeof(struct sockaddr_in));
+        s->dst_size = sizeof(struct sockaddr_in);
+        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 {
+        /* This will be overwritten later if we have a dst */
+        s->dgram_dst = NULL;
+        s->dst_size = 0;
+        snprintf(nc->info_str, sizeof(nc->info_str),
+                 "socket: fd=%d", fd);
+    }
+
+    return s;
+
+err:
+    closesocket(fd);
+    return NULL;
+}
+#else
 static NetClientInfo net_dgram_socket_info = {
     .type = NET_CLIENT_DRIVER_SOCKET,
     .size = sizeof(NetSocketState),
@@ -386,6 +481,7 @@ err:
     closesocket(fd);
     return NULL;
 }
+#endif
 
 static void net_socket_connect(void *opaque)
 {
@@ -430,7 +526,7 @@ static NetSocketState 
*net_socket_fd_init_stream(NetClientState *peer,
     return s;
 }
 
-static NetSocketState *net_socket_fd_init(NetClientState *peer,
+static void *net_socket_fd_init(NetClientState *peer,
                                           const char *model, const char *name,
                                           int fd, int is_connected)
 {
@@ -567,7 +663,7 @@ static int net_socket_connect_init(NetClientState *peer,
             break;
         }
     }
-    s = net_socket_fd_init(peer, model, name, fd, connected);
+    s = net_socket_fd_init_stream(peer, model, name, fd, connected);
     if (!s)
         return -1;
     snprintf(s->nc.info_str, sizeof(s->nc.info_str),
@@ -582,7 +678,11 @@ static int net_socket_mcast_init(NetClientState *peer,
                                  const char *host_str,
                                  const char *localaddr_str)
 {
+#ifdef CONFIG_UDST
+    NetUdstState *s;
+#else
     NetSocketState *s;
+#endif
     int fd;
     struct sockaddr_in saddr;
     struct in_addr localaddr, *param_localaddr;
@@ -602,11 +702,15 @@ static int net_socket_mcast_init(NetClientState *peer,
     if (fd < 0)
         return -1;
 
-    s = net_socket_fd_init(peer, model, name, fd, 0);
+    s = net_socket_fd_init_dgram(peer, model, name, fd, 0);
     if (!s)
         return -1;
-
+#ifdef CONFIG_UDST
+    s->dgram_dst = g_memdup(&saddr, sizeof(struct sockaddr_in));
+    s->dst_size = sizeof(struct sockaddr_in);
+#else
     s->dgram_dst = saddr;
+#endif
 
     snprintf(s->nc.info_str, sizeof(s->nc.info_str),
              "socket: mcast=%s:%d",
@@ -621,7 +725,11 @@ static int net_socket_udp_init(NetClientState *peer,
                                  const char *rhost,
                                  const char *lhost)
 {
+#ifdef CONFIG_UDST
+    NetUdstState *s;
+#else
     NetSocketState *s;
+#endif
     int fd, ret;
     struct sockaddr_in laddr, raddr;
 
@@ -652,12 +760,17 @@ static int net_socket_udp_init(NetClientState *peer,
     }
     qemu_set_nonblock(fd);
 
-    s = net_socket_fd_init(peer, model, name, fd, 0);
+    s = net_socket_fd_init_dgram(peer, model, name, fd, 0);
     if (!s) {
         return -1;
     }
 
+#ifdef CONFIG_UDST
+    s->dgram_dst = g_memdup(&raddr, sizeof(struct sockaddr_in));
+    s->dst_size = sizeof(struct sockaddr_in);
+#else
     s->dgram_dst = raddr;
+#endif
 
     snprintf(s->nc.info_str, sizeof(s->nc.info_str),
              "socket: udp=%s:%d",
-- 
2.11.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]