From patchwork Tue Nov 2 13:29:02 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 69885 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id BFC13B6F11 for ; Wed, 3 Nov 2010 01:20:11 +1100 (EST) Received: from localhost ([127.0.0.1]:43320 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PDHgF-0003MN-R8 for incoming@patchwork.ozlabs.org; Tue, 02 Nov 2010 10:17:43 -0400 Received: from [140.186.70.92] (port=33875 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PDGvG-0003WU-T7 for qemu-devel@nongnu.org; Tue, 02 Nov 2010 09:29:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PDGvB-0002IQ-T0 for qemu-devel@nongnu.org; Tue, 02 Nov 2010 09:29:09 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42206) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PDGvB-0002IC-Lr for qemu-devel@nongnu.org; Tue, 02 Nov 2010 09:29:05 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id oA2DT40s003326 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 2 Nov 2010 09:29:05 -0400 Received: from rincewind.home.kraxel.org (vpn1-4-20.ams2.redhat.com [10.36.4.20]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id oA2DT3dc019029; Tue, 2 Nov 2010 09:29:03 -0400 Received: by rincewind.home.kraxel.org (Postfix, from userid 500) id 5CAC945211; Tue, 2 Nov 2010 14:29:02 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Tue, 2 Nov 2010 14:29:02 +0100 Message-Id: <1288704542-29864-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: Gerd Hoffmann Subject: [Qemu-devel] [PATCH] spice: connection events. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- monitor.c | 9 +++++++ monitor.h | 3 ++ ui/spice-core.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 0 deletions(-) diff --git a/monitor.c b/monitor.c index 61607c5..23f3b73 100644 --- a/monitor.c +++ b/monitor.c @@ -458,6 +458,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..a9f6d8f 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,56 @@ static void watch_remove(SpiceWatch *watch) qemu_free(watch); } +#if SPICE_INTERFACE_CORE_MINOR >= 3 +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, + }; + char lhost[NI_MAXHOST], lport[NI_MAXSERV]; + char phost[NI_MAXHOST], pport[NI_MAXSERV]; + QDict *server, *client; + QObject *data; + + getnameinfo(&info->laddr, info->llen, + lhost, sizeof(lhost), lport, sizeof(lport), + NI_NUMERICHOST | NI_NUMERICSERV); + getnameinfo(&info->paddr, info->plen, + phost, sizeof(phost), pport, sizeof(pport), + NI_NUMERICHOST | NI_NUMERICSERV); +#if 0 + fprintf(stderr, "%s: ev %d, flg %d, id %x, %d:%d, %s:%s <-> %s:%s\n", + __FUNCTION__, event, info->flags, info->connection_id, + info->type, info->id, lhost, lport, phost, pport); +#endif + + server = qdict_new(); + qdict_put(server, "host", qstring_from_str(lhost)); + qdict_put(server, "port", qstring_from_str(lport)); + qdict_put(server, "family", qstring_from_str(inet_strfamily(info->laddr.sa_family))); + if (event != SPICE_CHANNEL_EVENT_CONNECTED) { + int tls = info->flags & SPICE_CHANNEL_EVENT_FLAG_TLS; + qdict_put(server, "auth", qstring_from_str(auth)); + qdict_put(server, "connection-id", qint_from_int(info->connection_id)); + qdict_put(server, "channel-type", qint_from_int(info->type)); + qdict_put(server, "channel-id", qint_from_int(info->id)); + qdict_put(server, "tls", qbool_from_int(tls)); + } + + client = qdict_new(); + qdict_put(client, "host", qstring_from_str(phost)); + qdict_put(client, "port", qstring_from_str(pport)); + qdict_put(client, "family", qstring_from_str(inet_strfamily(info->paddr.sa_family))); + + data = qobject_from_jsonf("{ 'client': %p, 'server': %p }", + QOBJECT(client), QOBJECT(server)); + monitor_protocol_event(qevent[event], data); + qobject_decref(data); +} +#endif + static SpiceCoreInterface core_interface = { .base.type = SPICE_INTERFACE_CORE, .base.description = "qemu core services", @@ -135,6 +193,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 +378,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); }