qapi event: convert VNC events

Since VNC_CONNECTED, VNC_DISCONNECTED, VNC_INITIALIZED share some
common functions, convert them in one patch.

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
This commit is contained in:
Wenchao Xia 2014-06-18 08:43:49 +02:00 committed by Luiz Capitulino
parent 0615027903
commit fb6ba0d525
4 changed files with 108 additions and 146 deletions

View File

@ -142,93 +142,3 @@ Example:
"connection-id": 1804289383, "host": "127.0.0.1", "connection-id": 1804289383, "host": "127.0.0.1",
"channel-id": 0, "tls": true} "channel-id": 0, "tls": true}
}} }}
VNC_CONNECTED
-------------
Emitted when a VNC client establishes a connection.
Data:
- "server": Server information (json-object)
- "host": IP address (json-string)
- "service": 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)
- "service": port number (json-string)
- "family": address family (json-string, "ipv4" or "ipv6")
Example:
{ "event": "VNC_CONNECTED",
"data": {
"server": { "auth": "sasl", "family": "ipv4",
"service": "5901", "host": "0.0.0.0" },
"client": { "family": "ipv4", "service": "58425",
"host": "127.0.0.1" } },
"timestamp": { "seconds": 1262976601, "microseconds": 975795 } }
Note: This event is emitted before any authentication takes place, thus
the authentication ID is not provided.
VNC_DISCONNECTED
----------------
Emitted when the connection is closed.
Data:
- "server": Server information (json-object)
- "host": IP address (json-string)
- "service": 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)
- "service": port number (json-string)
- "family": address family (json-string, "ipv4" or "ipv6")
- "x509_dname": TLS dname (json-string, optional)
- "sasl_username": SASL username (json-string, optional)
Example:
{ "event": "VNC_DISCONNECTED",
"data": {
"server": { "auth": "sasl", "family": "ipv4",
"service": "5901", "host": "0.0.0.0" },
"client": { "family": "ipv4", "service": "58425",
"host": "127.0.0.1", "sasl_username": "luiz" } },
"timestamp": { "seconds": 1262976601, "microseconds": 975795 } }
VNC_INITIALIZED
---------------
Emitted after authentication takes place (if any) and the VNC session is
made active.
Data:
- "server": Server information (json-object)
- "host": IP address (json-string)
- "service": 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)
- "service": port number (json-string)
- "family": address family (json-string, "ipv4" or "ipv6")
- "x509_dname": TLS dname (json-string, optional)
- "sasl_username": SASL username (json-string, optional)
Example:
{ "event": "VNC_INITIALIZED",
"data": {
"server": { "auth": "sasl", "family": "ipv4",
"service": "5901", "host": "0.0.0.0"},
"client": { "family": "ipv4", "service": "46089",
"host": "127.0.0.1", "sasl_username": "luiz" } },
"timestamp": { "seconds": 1263475302, "microseconds": 150772 } }

View File

@ -137,3 +137,52 @@
## ##
{ 'event': 'NIC_RX_FILTER_CHANGED', { 'event': 'NIC_RX_FILTER_CHANGED',
'data': { '*name': 'str', 'path': 'str' } } 'data': { '*name': 'str', 'path': 'str' } }
##
# @VNC_CONNECTED
#
# Emitted when a VNC client establishes a connection
#
# @server: server information
#
# @client: client information
#
# Note: This event is emitted before any authentication takes place, thus
# the authentication ID is not provided
#
# Since: 0.13.0
##
{ 'event': 'VNC_CONNECTED',
'data': { 'server': 'VncServerInfo',
'client': 'VncBasicInfo' } }
##
# @VNC_INITIALIZED
#
# Emitted after authentication takes place (if any) and the VNC session is
# made active
#
# @server: server information
#
# @client: client information
#
# Since: 0.13.0
##
{ 'event': 'VNC_INITIALIZED',
'data': { 'server': 'VncServerInfo',
'client': 'VncClientInfo' } }
##
# @VNC_DISCONNECTED
#
# Emitted when the connection is closed
#
# @server: server information
#
# @client: client information
#
# Since: 0.13.0
##
{ 'event': 'VNC_DISCONNECTED',
'data': { 'server': 'VncServerInfo',
'client': 'VncClientInfo' } }

111
ui/vnc.c
View File

@ -35,6 +35,7 @@
#include "qmp-commands.h" #include "qmp-commands.h"
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "ui/input.h" #include "ui/input.h"
#include "qapi-event.h"
#define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
#define VNC_REFRESH_INTERVAL_INC 50 #define VNC_REFRESH_INTERVAL_INC 50
@ -124,9 +125,10 @@ char *vnc_socket_remote_addr(const char *format, int fd) {
return addr_to_string(format, &sa, salen); return addr_to_string(format, &sa, salen);
} }
static int put_addr_qdict(QDict *qdict, struct sockaddr_storage *sa, static VncBasicInfo *vnc_basic_info_get(struct sockaddr_storage *sa,
socklen_t salen) socklen_t salen)
{ {
VncBasicInfo *info;
char host[NI_MAXHOST]; char host[NI_MAXHOST];
char serv[NI_MAXSERV]; char serv[NI_MAXSERV];
int err; int err;
@ -137,40 +139,40 @@ static int put_addr_qdict(QDict *qdict, struct sockaddr_storage *sa,
NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
VNC_DEBUG("Cannot resolve address %d: %s\n", VNC_DEBUG("Cannot resolve address %d: %s\n",
err, gai_strerror(err)); err, gai_strerror(err));
return -1; return NULL;
} }
qdict_put(qdict, "host", qstring_from_str(host)); info = g_malloc0(sizeof(VncBasicInfo));
qdict_put(qdict, "service", qstring_from_str(serv)); info->host = g_strdup(host);
qdict_put(qdict, "family",qstring_from_str(inet_strfamily(sa->ss_family))); info->service = g_strdup(serv);
info->family = inet_netfamily(sa->ss_family);
return 0; return info;
} }
static int vnc_server_addr_put(QDict *qdict, int fd) static VncBasicInfo *vnc_basic_info_get_from_server_addr(int fd)
{ {
struct sockaddr_storage sa; struct sockaddr_storage sa;
socklen_t salen; socklen_t salen;
salen = sizeof(sa); salen = sizeof(sa);
if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0) { if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0) {
return -1; return NULL;
} }
return put_addr_qdict(qdict, &sa, salen); return vnc_basic_info_get(&sa, salen);
} }
static int vnc_qdict_remote_addr(QDict *qdict, int fd) static VncBasicInfo *vnc_basic_info_get_from_remote_addr(int fd)
{ {
struct sockaddr_storage sa; struct sockaddr_storage sa;
socklen_t salen; socklen_t salen;
salen = sizeof(sa); salen = sizeof(sa);
if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0) { if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0) {
return -1; return NULL;
} }
return put_addr_qdict(qdict, &sa, salen); return vnc_basic_info_get(&sa, salen);
} }
static const char *vnc_auth_name(VncDisplay *vd) { static const char *vnc_auth_name(VncDisplay *vd) {
@ -224,81 +226,82 @@ static const char *vnc_auth_name(VncDisplay *vd) {
return "unknown"; return "unknown";
} }
static int vnc_server_info_put(QDict *qdict) static VncServerInfo *vnc_server_info_get(void)
{ {
if (vnc_server_addr_put(qdict, vnc_display->lsock) < 0) { VncServerInfo *info;
return -1; VncBasicInfo *bi = vnc_basic_info_get_from_server_addr(vnc_display->lsock);
if (!bi) {
return NULL;
} }
qdict_put(qdict, "auth", qstring_from_str(vnc_auth_name(vnc_display))); info = g_malloc(sizeof(*info));
return 0; info->base = bi;
info->has_auth = true;
info->auth = g_strdup(vnc_auth_name(vnc_display));
return info;
} }
static void vnc_client_cache_auth(VncState *client) static void vnc_client_cache_auth(VncState *client)
{ {
#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
QDict *qdict;
#endif
if (!client->info) { if (!client->info) {
return; return;
} }
#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
qdict = qobject_to_qdict(client->info);
#endif
#ifdef CONFIG_VNC_TLS #ifdef CONFIG_VNC_TLS
if (client->tls.session && if (client->tls.session &&
client->tls.dname) { client->tls.dname) {
qdict_put(qdict, "x509_dname", qstring_from_str(client->tls.dname)); client->info->has_x509_dname = true;
client->info->x509_dname = g_strdup(client->tls.dname);
} }
#endif #endif
#ifdef CONFIG_VNC_SASL #ifdef CONFIG_VNC_SASL
if (client->sasl.conn && if (client->sasl.conn &&
client->sasl.username) { client->sasl.username) {
qdict_put(qdict, "sasl_username", client->info->has_sasl_username = true;
qstring_from_str(client->sasl.username)); client->info->sasl_username = g_strdup(client->sasl.username);
} }
#endif #endif
} }
static void vnc_client_cache_addr(VncState *client) static void vnc_client_cache_addr(VncState *client)
{ {
QDict *qdict; VncBasicInfo *bi = vnc_basic_info_get_from_remote_addr(client->csock);
qdict = qdict_new(); if (bi) {
if (vnc_qdict_remote_addr(qdict, client->csock) < 0) { client->info = g_malloc0(sizeof(*client->info));
QDECREF(qdict); client->info->base = bi;
/* XXX: how to report the error? */
return;
} }
client->info = QOBJECT(qdict);
} }
static void vnc_qmp_event(VncState *vs, MonitorEvent event) static void vnc_qmp_event(VncState *vs, QAPIEvent event)
{ {
QDict *server; VncServerInfo *si;
QObject *data;
if (!vs->info) { if (!vs->info) {
return; return;
} }
g_assert(vs->info->base);
server = qdict_new(); si = vnc_server_info_get();
if (vnc_server_info_put(server) < 0) { if (!si) {
QDECREF(server);
return; return;
} }
data = qobject_from_jsonf("{ 'client': %p, 'server': %p }", switch (event) {
vs->info, QOBJECT(server)); case QAPI_EVENT_VNC_CONNECTED:
qapi_event_send_vnc_connected(si, vs->info->base, &error_abort);
break;
case QAPI_EVENT_VNC_INITIALIZED:
qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
break;
case QAPI_EVENT_VNC_DISCONNECTED:
qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
break;
default:
break;
}
monitor_protocol_event(event, data); qapi_free_VncServerInfo(si);
qobject_incref(vs->info);
qobject_decref(data);
} }
static VncClientInfo *qmp_query_vnc_client(const VncState *client) static VncClientInfo *qmp_query_vnc_client(const VncState *client)
@ -1040,7 +1043,7 @@ void vnc_disconnect_finish(VncState *vs)
vnc_jobs_join(vs); /* Wait encoding jobs */ vnc_jobs_join(vs); /* Wait encoding jobs */
vnc_lock_output(vs); vnc_lock_output(vs);
vnc_qmp_event(vs, QEVENT_VNC_DISCONNECTED); vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
buffer_free(&vs->input); buffer_free(&vs->input);
buffer_free(&vs->output); buffer_free(&vs->output);
@ -1049,7 +1052,7 @@ void vnc_disconnect_finish(VncState *vs)
buffer_free(&vs->ws_output); buffer_free(&vs->ws_output);
#endif /* CONFIG_VNC_WS */ #endif /* CONFIG_VNC_WS */
qobject_decref(vs->info); qapi_free_VncClientInfo(vs->info);
vnc_zlib_clear(vs); vnc_zlib_clear(vs);
vnc_tight_clear(vs); vnc_tight_clear(vs);
@ -2324,7 +2327,7 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
vnc_flush(vs); vnc_flush(vs);
vnc_client_cache_auth(vs); vnc_client_cache_auth(vs);
vnc_qmp_event(vs, QEVENT_VNC_INITIALIZED); vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
vnc_read_when(vs, protocol_client_msg, 1); vnc_read_when(vs, protocol_client_msg, 1);
@ -2847,7 +2850,7 @@ static void vnc_connect(VncDisplay *vd, int csock,
} }
vnc_client_cache_addr(vs); vnc_client_cache_addr(vs);
vnc_qmp_event(vs, QEVENT_VNC_CONNECTED); vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING); vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
vs->vd = vd; vs->vd = vd;

View File

@ -31,7 +31,6 @@
#include "qemu/queue.h" #include "qemu/queue.h"
#include "qemu/thread.h" #include "qemu/thread.h"
#include "ui/console.h" #include "ui/console.h"
#include "monitor/monitor.h"
#include "audio/audio.h" #include "audio/audio.h"
#include "qemu/bitmap.h" #include "qemu/bitmap.h"
#include <zlib.h> #include <zlib.h>
@ -40,6 +39,7 @@
#include "keymaps.h" #include "keymaps.h"
#include "vnc-palette.h" #include "vnc-palette.h"
#include "vnc-enc-zrle.h" #include "vnc-enc-zrle.h"
#include "qapi-types.h"
// #define _VNC_DEBUG 1 // #define _VNC_DEBUG 1
@ -292,7 +292,7 @@ struct VncState
bool websocket; bool websocket;
#endif /* CONFIG_VNC_WS */ #endif /* CONFIG_VNC_WS */
QObject *info; VncClientInfo *info;
Buffer output; Buffer output;
Buffer input; Buffer input;