qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 17/19] chardev: add udp support to qapi


From: Gerd Hoffmann
Subject: [Qemu-devel] [PATCH 17/19] chardev: add udp support to qapi
Date: Tue, 12 Mar 2013 09:56:27 +0100

This patch adds 'udp' support to qapi.

Signed-off-by: Gerd Hoffmann <address@hidden>
---
 include/qemu/sockets.h |    1 +
 qapi-schema.json       |   16 +++++++++++++++-
 qemu-char.c            |   44 ++++++++++++++++++++++++++------------------
 util/qemu-sockets.c    |   25 +++++++++++++++++++++++++
 4 files changed, 67 insertions(+), 19 deletions(-)

diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index 6125bf7..3dc6044 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -70,6 +70,7 @@ SocketAddress *socket_parse(const char *str, Error **errp);
 int socket_connect(SocketAddress *addr, Error **errp,
                    NonBlockingConnectHandler *callback, void *opaque);
 int socket_listen(SocketAddress *addr, Error **errp);
+int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp);
 
 /* Old, ipv4 only bits.  Don't use for new code. */
 int parse_host_port(struct sockaddr_in *saddr, const char *str);
diff --git a/qapi-schema.json b/qapi-schema.json
index 59c025f..ba023fb 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3166,7 +3166,7 @@
 ##
 # @ChardevSocket:
 #
-# Configuration info for socket chardevs.
+# Configuration info for (stream) socket chardevs.
 #
 # @addr: socket address to listen on (server=true)
 #        or connect to (server=false)
@@ -3185,6 +3185,19 @@
                                      '*telnet'  : 'bool' } }
 
 ##
+# @ChardevDgram:
+#
+# Configuration info for datagram socket chardevs.
+#
+# @remote: remote address
+# @local: #optional local address
+#
+# Since: 1.5
+##
+{ 'type': 'ChardevDgram', 'data': { 'remote' : 'SocketAddress',
+                                    '*local' : 'SocketAddress' } }
+
+##
 # @ChardevMux:
 #
 # Configuration info for mux chardevs.
@@ -3272,6 +3285,7 @@
                                        'parallel': 'ChardevHostdev',
                                        'pipe'   : 'ChardevHostdev',
                                        'socket' : 'ChardevSocket',
+                                       'dgram'  : 'ChardevDgram',
                                        'pty'    : 'ChardevDummy',
                                        'null'   : 'ChardevDummy',
                                        'mux'    : 'ChardevMux',
diff --git a/qemu-char.c b/qemu-char.c
index 0e7d46c..11f8ea5 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2237,21 +2237,14 @@ static void udp_chr_close(CharDriverState *chr)
     qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
 }
 
-static CharDriverState *qemu_chr_open_udp(QemuOpts *opts)
+static CharDriverState *qemu_chr_open_udp_fd(int fd)
 {
     CharDriverState *chr = NULL;
     NetCharDriver *s = NULL;
-    Error *local_err = NULL;
-    int fd = -1;
 
     chr = g_malloc0(sizeof(CharDriverState));
     s = g_malloc0(sizeof(NetCharDriver));
 
-    fd = inet_dgram_opts(opts, &local_err);
-    if (fd < 0) {
-        goto return_err;
-    }
-
     s->fd = fd;
     s->chan = io_channel_from_socket(s->fd);
     s->bufcnt = 0;
@@ -2261,18 +2254,18 @@ static CharDriverState *qemu_chr_open_udp(QemuOpts 
*opts)
     chr->chr_update_read_handler = udp_chr_update_read_handler;
     chr->chr_close = udp_chr_close;
     return chr;
+}
 
-return_err:
-    if (local_err) {
-        qerror_report_err(local_err);
-        error_free(local_err);
-    }
-    g_free(chr);
-    g_free(s);
-    if (fd >= 0) {
-        closesocket(fd);
+static CharDriverState *qemu_chr_open_udp(QemuOpts *opts)
+{
+    Error *local_err = NULL;
+    int fd = -1;
+
+    fd = inet_dgram_opts(opts, &local_err);
+    if (fd < 0) {
+        return NULL;
     }
-    return NULL;
+    return qemu_chr_open_udp_fd(fd);
 }
 
 /***********************************************************/
@@ -3655,6 +3648,18 @@ static CharDriverState 
*qmp_chardev_open_socket(ChardevSocket *sock,
                                    is_telnet, is_waitconnect, errp);
 }
 
+static CharDriverState *qmp_chardev_open_dgram(ChardevDgram *dgram,
+                                               Error **errp)
+{
+    int fd;
+
+    fd = socket_dgram(dgram->remote, dgram->local, errp);
+    if (error_is_set(errp)) {
+        return NULL;
+    }
+    return qemu_chr_open_udp_fd(fd);
+}
+
 ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
                                Error **errp)
 {
@@ -3684,6 +3689,9 @@ ChardevReturn *qmp_chardev_add(const char *id, 
ChardevBackend *backend,
     case CHARDEV_BACKEND_KIND_SOCKET:
         chr = qmp_chardev_open_socket(backend->socket, errp);
         break;
+    case CHARDEV_BACKEND_KIND_DGRAM:
+        chr = qmp_chardev_open_dgram(backend->dgram, errp);
+        break;
 #ifdef HAVE_CHARDEV_TTY
     case CHARDEV_BACKEND_KIND_PTY:
         chr = qemu_chr_open_pty(id, ret);
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 3f12296..83e4e08 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -949,6 +949,31 @@ int socket_listen(SocketAddress *addr, Error **errp)
     return fd;
 }
 
+int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp)
+{
+    QemuOpts *opts;
+    int fd;
+
+    opts = qemu_opts_create_nofail(&dummy_opts);
+    switch (remote->kind) {
+    case SOCKET_ADDRESS_KIND_INET:
+        qemu_opt_set(opts, "host", remote->inet->host);
+        qemu_opt_set(opts, "port", remote->inet->port);
+        if (local) {
+            qemu_opt_set(opts, "localaddr", local->inet->host);
+            qemu_opt_set(opts, "localport", local->inet->port);
+        }
+        fd = inet_dgram_opts(opts, errp);
+        break;
+
+    default:
+        error_setg(errp, "socket type unsupported for datagram");
+        return -1;
+    }
+    qemu_opts_del(opts);
+    return fd;
+}
+
 #ifdef _WIN32
 static void socket_cleanup(void)
 {
-- 
1.7.9.7




reply via email to

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