summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2010-10-11 16:30:58 +0200
committerGerd Hoffmann <kraxel@redhat.com>2010-10-12 11:11:26 +0200
commit97f33fa86aa6edd25111b173dc0d9599ac29f879 (patch)
tree66411081e1141b853de82195ecf06ec6a23998b0
parentf8c6e1c42a16d6b00f058389ee79baef7c0ff5d4 (diff)
server: add channel notifications.
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.
-rw-r--r--server/reds.c31
-rw-r--r--server/reds.h2
-rw-r--r--server/spice.h19
3 files changed, 48 insertions, 4 deletions
diff --git a/server/reds.c b/server/reds.c
index 5fafe400..fcdda798 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 6eed02be..e95aea5e 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 6f4c7820..e6304020 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 */