Commit fb6ba0d5 authored by Wenchao Xia's avatar Wenchao Xia Committed by Luiz Capitulino
Browse files

qapi event: convert VNC events



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

Signed-off-by: default avatarWenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Signed-off-by: default avatarLuiz Capitulino <lcapitulino@redhat.com>
parent 06150279
Loading
Loading
Loading
Loading
+0 −90
Original line number Diff line number Diff line
@@ -142,93 +142,3 @@ Example:
                      "connection-id": 1804289383, "host": "127.0.0.1",
                      "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 } }
+49 −0
Original line number Diff line number Diff line
@@ -137,3 +137,52 @@
##
{ 'event': 'NIC_RX_FILTER_CHANGED',
  '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' } }
+57 −54
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include "qmp-commands.h"
#include "qemu/osdep.h"
#include "ui/input.h"
#include "qapi-event.h"

#define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
#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);
}

static int put_addr_qdict(QDict *qdict, struct sockaddr_storage *sa,
static VncBasicInfo *vnc_basic_info_get(struct sockaddr_storage *sa,
                                        socklen_t salen)
{
    VncBasicInfo *info;
    char host[NI_MAXHOST];
    char serv[NI_MAXSERV];
    int err;
@@ -137,40 +139,40 @@ static int put_addr_qdict(QDict *qdict, struct sockaddr_storage *sa,
                           NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
        VNC_DEBUG("Cannot resolve address %d: %s\n",
                  err, gai_strerror(err));
        return -1;
        return NULL;
    }

    qdict_put(qdict, "host", qstring_from_str(host));
    qdict_put(qdict, "service", qstring_from_str(serv));
    qdict_put(qdict, "family",qstring_from_str(inet_strfamily(sa->ss_family)));

    return 0;
    info = g_malloc0(sizeof(VncBasicInfo));
    info->host = g_strdup(host);
    info->service = g_strdup(serv);
    info->family = inet_netfamily(sa->ss_family);
    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;
    socklen_t salen;

    salen = sizeof(sa);
    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;
    socklen_t salen;

    salen = sizeof(sa);
    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) {
@@ -224,81 +226,82 @@ static const char *vnc_auth_name(VncDisplay *vd) {
    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) {
        return -1;
    VncServerInfo *info;
    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)));
    return 0;
    info = g_malloc(sizeof(*info));
    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)
{
#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
    QDict *qdict;
#endif

    if (!client->info) {
        return;
    }

#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
    qdict = qobject_to_qdict(client->info);
#endif

#ifdef CONFIG_VNC_TLS
    if (client->tls.session &&
        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
#ifdef CONFIG_VNC_SASL
    if (client->sasl.conn &&
        client->sasl.username) {
        qdict_put(qdict, "sasl_username",
                  qstring_from_str(client->sasl.username));
        client->info->has_sasl_username = true;
        client->info->sasl_username = g_strdup(client->sasl.username);
    }
#endif
}

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 (vnc_qdict_remote_addr(qdict, client->csock) < 0) {
        QDECREF(qdict);
        /* XXX: how to report the error? */
        return;
    if (bi) {
        client->info = g_malloc0(sizeof(*client->info));
        client->info->base = bi;
    }

    client->info = QOBJECT(qdict);
}

static void vnc_qmp_event(VncState *vs, MonitorEvent event)
static void vnc_qmp_event(VncState *vs, QAPIEvent event)
{
    QDict *server;
    QObject *data;
    VncServerInfo *si;

    if (!vs->info) {
        return;
    }
    g_assert(vs->info->base);

    server = qdict_new();
    if (vnc_server_info_put(server) < 0) {
        QDECREF(server);
    si = vnc_server_info_get();
    if (!si) {
        return;
    }

    data = qobject_from_jsonf("{ 'client': %p, 'server': %p }",
                              vs->info, QOBJECT(server));

    monitor_protocol_event(event, data);
    switch (event) {
    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;
    }

    qobject_incref(vs->info);
    qobject_decref(data);
    qapi_free_VncServerInfo(si);
}

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_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->output);
@@ -1049,7 +1052,7 @@ void vnc_disconnect_finish(VncState *vs)
    buffer_free(&vs->ws_output);
#endif /* CONFIG_VNC_WS */

    qobject_decref(vs->info);
    qapi_free_VncClientInfo(vs->info);

    vnc_zlib_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_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);

@@ -2847,7 +2850,7 @@ static void vnc_connect(VncDisplay *vd, int csock,
    }

    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);

    vs->vd = vd;
+2 −2
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@
#include "qemu/queue.h"
#include "qemu/thread.h"
#include "ui/console.h"
#include "monitor/monitor.h"
#include "audio/audio.h"
#include "qemu/bitmap.h"
#include <zlib.h>
@@ -40,6 +39,7 @@
#include "keymaps.h"
#include "vnc-palette.h"
#include "vnc-enc-zrle.h"
#include "qapi-types.h"

// #define _VNC_DEBUG 1

@@ -292,7 +292,7 @@ struct VncState
    bool websocket;
#endif /* CONFIG_VNC_WS */

    QObject *info;
    VncClientInfo *info;

    Buffer output;
    Buffer input;