[Spice-devel] [PATCH] server: add channel notifications.

Gerd Hoffmann kraxel at redhat.com
Tue Oct 12 01:58:55 PDT 2010


This patch adds a channel event callback to the spice core interface.
This new callback will be called for three events:

  (1) A new connection has been established.
  (2) The channel is ready (i.e. authentication is done,
      link message verification passed all tests, channel
      is ready to use).
  (3) Channel was disconnected.

Qemu will use this to send notifications to the management app.

Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
---
 server/reds.c  |   31 ++++++++++++++++++++++++++++---
 server/reds.h  |    2 ++
 server/spice.h |   19 ++++++++++++++++++-
 3 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/server/reds.c b/server/reds.c
index 5fafe40..fcdda79 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -385,6 +385,13 @@ static ChannelSecurityOptions *find_channel_security(int id)
     return now;
 }
 
+static void reds_channel_event(RedsStreamContext *peer, int event)
+{
+    if (core->base.minor_version < 3 || core->channel_event == NULL)
+        return;
+    core->channel_event(event, &peer->info);
+}
+
 static int reds_write(void *ctx, void *buf, size_t size)
 {
     int return_code;
@@ -409,6 +416,7 @@ static int reds_read(void *ctx, void *buf, size_t size)
 
 static int reds_free(RedsStreamContext *peer)
 {
+    reds_channel_event(peer, SPICE_CHANNEL_EVENT_DISCONNECTED);
     close(peer->socket);
     free(peer);
     return 0;
@@ -471,6 +479,7 @@ static int reds_ssl_writev(void *ctx, const struct iovec *vector, int count)
 
 static int reds_ssl_free(RedsStreamContext *peer)
 {
+    reds_channel_event(peer, SPICE_CHANNEL_EVENT_DISCONNECTED);
     SSL_free(peer->ssl);
     close(peer->socket);
     free(peer);
@@ -1980,12 +1989,20 @@ static int reds_send_link_error(RedLinkInfo *link, uint32_t error)
                                                                          sizeof(reply));
 }
 
-static void reds_show_new_channel(RedLinkInfo *link)
+static void reds_show_new_channel(RedLinkInfo *link, int connection_id)
 {
     red_printf("channel %d:%d, connected successfully, over %s link",
                link->link_mess->channel_type,
                link->link_mess->channel_id,
                link->peer->ssl == NULL ? "Non Secure" : "Secure");
+    /* add info + send event */
+    if (link->peer->ssl) {
+        link->peer->info.flags |= SPICE_CHANNEL_EVENT_FLAG_TLS;
+    }
+    link->peer->info.connection_id = connection_id;
+    link->peer->info.type = link->link_mess->channel_type;
+    link->peer->info.id   = link->link_mess->channel_id;
+    reds_channel_event(link->peer, SPICE_CHANNEL_EVENT_INITIALIZED);
 }
 
 static void reds_send_link_result(RedLinkInfo *link, uint32_t error)
@@ -2038,7 +2055,7 @@ static void reds_handle_main_link(RedLinkInfo *link)
     reds->peer = link->peer;
     reds->in_handler.shut = FALSE;
 
-    reds_show_new_channel(link);
+    reds_show_new_channel(link, connection_id);
     __reds_release_link(link);
     if (vdagent) {
         SpiceCharDeviceInterface *sif;
@@ -2530,7 +2547,7 @@ static void reds_handle_other_links(RedLinkInfo *link)
     }
 
     reds_send_link_result(link, SPICE_LINK_ERR_OK);
-    reds_show_new_channel(link);
+    reds_show_new_channel(link, reds->link_id);
     if (link_mess->channel_type == SPICE_CHANNEL_INPUTS && !link->peer->ssl) {
         RedsOutItem *item;
         SpiceMsgNotify notify;
@@ -2813,6 +2830,14 @@ static RedLinkInfo *__reds_accept_connection(int listen_socket)
     peer = spice_new0(RedsStreamContext, 1);
     link->peer = peer;
     peer->socket = socket;
+
+    /* gather info + send event */
+    peer->info.llen = sizeof(peer->info.laddr);
+    peer->info.plen = sizeof(peer->info.paddr);
+    getsockname(peer->socket, (struct sockaddr*)(&peer->info.laddr), &peer->info.llen);
+    getpeername(peer->socket, (struct sockaddr*)(&peer->info.paddr), &peer->info.plen);
+    reds_channel_event(peer, SPICE_CHANNEL_EVENT_CONNECTED);
+
     openssl_init(link);
 
     return link;
diff --git a/server/reds.h b/server/reds.h
index 6eed02b..e95aea5 100644
--- a/server/reds.h
+++ b/server/reds.h
@@ -35,6 +35,8 @@ typedef struct RedsStreamContext {
     int shutdown;
     SSL *ssl;
 
+    SpiceChannelEventInfo info;
+
     int (*cb_write)(void *, void *, int);
     int (*cb_read)(void *, void *, int);
 
diff --git a/server/spice.h b/server/spice.h
index 6f4c782..e630402 100644
--- a/server/spice.h
+++ b/server/spice.h
@@ -42,18 +42,34 @@ struct SpiceBaseInstance {
 
 #define SPICE_INTERFACE_CORE "core"
 #define SPICE_INTERFACE_CORE_MAJOR 1
-#define SPICE_INTERFACE_CORE_MINOR 2
+#define SPICE_INTERFACE_CORE_MINOR 3
 typedef struct SpiceCoreInterface SpiceCoreInterface;
 
 #define SPICE_WATCH_EVENT_READ  (1 << 0)
 #define SPICE_WATCH_EVENT_WRITE (1 << 1)
 
+#define SPICE_CHANNEL_EVENT_CONNECTED     1
+#define SPICE_CHANNEL_EVENT_INITIALIZED   2
+#define SPICE_CHANNEL_EVENT_DISCONNECTED  3
+
+#define SPICE_CHANNEL_EVENT_FLAG_TLS      (1 << 0)
+
 typedef struct SpiceWatch SpiceWatch;
 typedef void (*SpiceWatchFunc)(int fd, int event, void *opaque);
 
 typedef struct SpiceTimer SpiceTimer;
 typedef void (*SpiceTimerFunc)(void *opaque);
 
+typedef struct SpiceChannelEventInfo {
+    int connection_id;
+    int type;
+    int id;
+    int flags;
+    struct sockaddr laddr;
+    struct sockaddr paddr;
+    socklen_t llen, plen;
+} SpiceChannelEventInfo;
+
 struct SpiceCoreInterface {
     SpiceBaseInterface base;
 
@@ -66,6 +82,7 @@ struct SpiceCoreInterface {
     void (*watch_update_mask)(SpiceWatch *watch, int event_mask);
     void (*watch_remove)(SpiceWatch *watch);
 
+    void (*channel_event)(int event, SpiceChannelEventInfo *info);
 };
 
 /* qxl interface */
-- 
1.7.1



More information about the Spice-devel mailing list