From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=47921 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PNnLs-0000Lo-C4 for qemu-devel@nongnu.org; Wed, 01 Dec 2010 09:08:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PNnLp-0006C7-Gi for qemu-devel@nongnu.org; Wed, 01 Dec 2010 09:08:08 -0500 Received: from mail-gx0-f173.google.com ([209.85.161.173]:62596) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PNnLp-0006Bj-CF for qemu-devel@nongnu.org; Wed, 01 Dec 2010 09:08:05 -0500 Received: by gxk24 with SMTP id 24so3673438gxk.4 for ; Wed, 01 Dec 2010 06:08:04 -0800 (PST) Message-ID: <4CF656BD.9070308@codemonkey.ws> Date: Wed, 01 Dec 2010 08:07:57 -0600 From: Anthony Liguori MIME-Version: 1.0 Subject: Re: [Qemu-devel] [PATCH 1/2] spice: connection events. References: <1291122714-2634-1-git-send-email-kraxel@redhat.com> <1291122714-2634-2-git-send-email-kraxel@redhat.com> In-Reply-To: <1291122714-2634-2-git-send-email-kraxel@redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Gerd Hoffmann Cc: qemu-devel@nongnu.org On 11/30/2010 07:11 AM, Gerd Hoffmann wrote: > This patch adds support for connection events to spice. The events are > quite simliar to the vnc events. Unlike vnc spice uses multiple tcp > channels though. qemu will report every single tcp connection (aka > spice channel). If you want track spice sessions only you can filter > for the main channel (channel-type == 1). > > Signed-off-by: Gerd Hoffmann > Reviewed-by: Anthony Liguori Regards, Anthony Liguori > --- > QMP/qmp-events.txt | 64 ++++++++++++++++++++++++++++++++++++++++++++ > monitor.c | 10 +++++++ > monitor.h | 3 ++ > ui/spice-core.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 152 insertions(+), 0 deletions(-) > > diff --git a/QMP/qmp-events.txt b/QMP/qmp-events.txt > index aa20210..0ce5d4e 100644 > --- a/QMP/qmp-events.txt > +++ b/QMP/qmp-events.txt > @@ -182,6 +182,70 @@ Example: > "host": "127.0.0.1", "sasl_username": "luiz" } }, > "timestamp": { "seconds": 1263475302, "microseconds": 150772 } } > > +SPICE_CONNECTED, SPICE_DISCONNECTED > +----------------------------------- > + > +Emitted when a SPICE client connects or disconnects. > + > +Data: > + > +- "server": Server information (json-object) > + - "host": IP address (json-string) > + - "port": port number (json-string) > + - "family": address family (json-string, "ipv4" or "ipv6") > +- "client": Client information (json-object) > + - "host": IP address (json-string) > + - "port": port number (json-string) > + - "family": address family (json-string, "ipv4" or "ipv6") > + > +Example: > + > +{ "timestamp": {"seconds": 1290688046, "microseconds": 388707}, > + "event": "SPICE_CONNECTED", > + "data": { > + "server": { "port": "5920", "family": "ipv4", "host": "127.0.0.1"}, > + "client": {"port": "52873", "family": "ipv4", "host": "127.0.0.1"} > +}} > + > + > +SPICE_INITIALIZED > +----------------- > + > +Emitted after initial handshake and authentication takes place (if any) > +and the SPICE channel is up'n'running > + > +Data: > + > +- "server": Server information (json-object) > + - "host": IP address (json-string) > + - "port": port number (json-string) > + - "family": address family (json-string, "ipv4" or "ipv6") > + - "auth": authentication method (json-string, optional) > +- "client": Client information (json-object) > + - "host": IP address (json-string) > + - "port": port number (json-string) > + - "family": address family (json-string, "ipv4" or "ipv6") > + - "connection-id": spice connection id. All channels with the same id > + belong to the same spice session (json-int) > + - "channel-type": channel type. "1" is the main control channel, filter for > + this one if you want track spice sessions only (json-int) > + - "channel-id": channel id. Usually "0", might be different needed when > + multiple channels of the same type exist, such as multiple > + display channels in a multihead setup (json-int) > + - "tls": whevener the channel is encrypted (json-bool) > + > +Example: > + > +{ "timestamp": {"seconds": 1290688046, "microseconds": 417172}, > + "event": "SPICE_INITIALIZED", > + "data": {"server": {"auth": "spice", "port": "5921", > + "family": "ipv4", "host": "127.0.0.1"}, > + "client": {"port": "49004", "family": "ipv4", "channel-type": 3, > + "connection-id": 1804289383, "host": "127.0.0.1", > + "channel-id": 0, "tls": true} > +}} > + > + > WATCHDOG > -------- > > diff --git a/monitor.c b/monitor.c > index 8cee35d..7eb8fca 100644 > --- a/monitor.c > +++ b/monitor.c > @@ -59,6 +59,7 @@ > #ifdef CONFIG_SIMPLE_TRACE > #include "trace.h" > #endif > +#include "ui/qemu-spice.h" > > //#define DEBUG > //#define DEBUG_COMPLETION > @@ -459,6 +460,15 @@ void monitor_protocol_event(MonitorEvent event, QObject *data) > case QEVENT_WATCHDOG: > event_name = "WATCHDOG"; > break; > + case QEVENT_SPICE_CONNECTED: > + event_name = "SPICE_CONNECTED"; > + break; > + case QEVENT_SPICE_INITIALIZED: > + event_name = "SPICE_INITIALIZED"; > + break; > + case QEVENT_SPICE_DISCONNECTED: > + event_name = "SPICE_DISCONNECTED"; > + break; > default: > abort(); > break; > diff --git a/monitor.h b/monitor.h > index 2d36bba..4f2d328 100644 > --- a/monitor.h > +++ b/monitor.h > @@ -32,6 +32,9 @@ typedef enum MonitorEvent { > QEVENT_BLOCK_IO_ERROR, > QEVENT_RTC_CHANGE, > QEVENT_WATCHDOG, > + QEVENT_SPICE_CONNECTED, > + QEVENT_SPICE_INITIALIZED, > + QEVENT_SPICE_DISCONNECTED, > QEVENT_MAX, > } MonitorEvent; > > diff --git a/ui/spice-core.c b/ui/spice-core.c > index b7fa031..93461c6 100644 > --- a/ui/spice-core.c > +++ b/ui/spice-core.c > @@ -18,16 +18,24 @@ > #include > #include > > +#include > + > #include "qemu-common.h" > #include "qemu-spice.h" > #include "qemu-timer.h" > #include "qemu-queue.h" > #include "qemu-x509.h" > +#include "qemu_socket.h" > +#include "qint.h" > +#include "qbool.h" > +#include "qstring.h" > +#include "qjson.h" > #include "monitor.h" > > /* core bits */ > > static SpiceServer *spice_server; > +static const char *auth = "spice"; > int using_spice = 0; > > struct SpiceTimer { > @@ -121,6 +129,68 @@ static void watch_remove(SpiceWatch *watch) > qemu_free(watch); > } > > +#if SPICE_INTERFACE_CORE_MINOR>= 3 > + > +static void add_addr_info(QDict *dict, struct sockaddr *addr, int len) > +{ > + char host[NI_MAXHOST], port[NI_MAXSERV]; > + const char *family; > + > + getnameinfo(addr, len, host, sizeof(host), port, sizeof(port), > + NI_NUMERICHOST | NI_NUMERICSERV); > + family = inet_strfamily(addr->sa_family); > + > + qdict_put(dict, "host", qstring_from_str(host)); > + qdict_put(dict, "port", qstring_from_str(port)); > + qdict_put(dict, "family", qstring_from_str(family)); > +} > + > +static void add_channel_info(QDict *dict, SpiceChannelEventInfo *info) > +{ > + int tls = info->flags& SPICE_CHANNEL_EVENT_FLAG_TLS; > + > + qdict_put(dict, "connection-id", qint_from_int(info->connection_id)); > + qdict_put(dict, "channel-type", qint_from_int(info->type)); > + qdict_put(dict, "channel-id", qint_from_int(info->id)); > + qdict_put(dict, "tls", qbool_from_int(tls)); > +} > + > +static void channel_event(int event, SpiceChannelEventInfo *info) > +{ > + static const int qevent[] = { > + [ SPICE_CHANNEL_EVENT_CONNECTED ] = QEVENT_SPICE_CONNECTED, > + [ SPICE_CHANNEL_EVENT_INITIALIZED ] = QEVENT_SPICE_INITIALIZED, > + [ SPICE_CHANNEL_EVENT_DISCONNECTED ] = QEVENT_SPICE_DISCONNECTED, > + }; > + QDict *server, *client; > + QObject *data; > + > + client = qdict_new(); > + add_addr_info(client,&info->paddr, info->plen); > + > + server = qdict_new(); > + add_addr_info(server,&info->laddr, info->llen); > + > + if (event == SPICE_CHANNEL_EVENT_INITIALIZED) { > + qdict_put(server, "auth", qstring_from_str(auth)); > + add_channel_info(client, info); > + } > + > + data = qobject_from_jsonf("{ 'client': %p, 'server': %p }", > + QOBJECT(client), QOBJECT(server)); > + monitor_protocol_event(qevent[event], data); > + qobject_decref(data); > +} > + > +#else /* SPICE_INTERFACE_CORE_MINOR>= 3 */ > + > +static QList *channel_list_get(void) > +{ > + return NULL; > +} > + > +#endif /* SPICE_INTERFACE_CORE_MINOR>= 3 */ > + > static SpiceCoreInterface core_interface = { > .base.type = SPICE_INTERFACE_CORE, > .base.description = "qemu core services", > @@ -135,6 +205,10 @@ static SpiceCoreInterface core_interface = { > .watch_add = watch_add, > .watch_update_mask = watch_update_mask, > .watch_remove = watch_remove, > + > +#if SPICE_INTERFACE_CORE_MINOR>= 3 > + .channel_event = channel_event, > +#endif > }; > > /* config string parsing */ > @@ -316,6 +390,7 @@ void qemu_spice_init(void) > spice_server_set_ticket(spice_server, password, 0, 0, 0); > } > if (qemu_opt_get_bool(opts, "disable-ticketing", 0)) { > + auth = "none"; > spice_server_set_noauth(spice_server); > } > >