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:
parent
0615027903
commit
fb6ba0d525
|
@ -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 } }
|
|
||||||
|
|
|
@ -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' } }
|
||||||
|
|
109
ui/vnc.c
109
ui/vnc.c
|
@ -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;
|
||||||
|
|
4
ui/vnc.h
4
ui/vnc.h
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue