@@ -230,14 +230,14 @@ static int vnc_server_info_put(QDict *qdict)
return 0;
}
-static QDict *do_info_vnc_client(Monitor *mon, VncState *client)
+static void vnc_client_cache_info(VncState *client)
{
QDict *qdict;
qdict = qdict_new();
if (vnc_qdict_remote_addr(qdict, client->csock) < 0) {
QDECREF(qdict);
- return NULL;
+ return;
}
#ifdef CONFIG_VNC_TLS
@@ -254,7 +254,7 @@ static QDict *do_info_vnc_client(Monitor *mon, VncState *client)
}
#endif
- return qdict;
+ client->info = QOBJECT(qdict);
}
static void info_vnc_iter(QObject *obj, void *opaque)
@@ -337,16 +337,17 @@ void do_info_vnc(Monitor *mon, QObject **ret_data)
if (vnc_display == NULL || vnc_display->display == NULL) {
*ret_data = qobject_from_jsonf("{ 'enabled': false }");
} else {
- QDict *qdict;
QList *clist;
clist = qlist_new();
if (vnc_display->clients) {
VncState *client = vnc_display->clients;
while (client) {
- qdict = do_info_vnc_client(mon, client);
- if (qdict)
- qlist_append(clist, qdict);
+ if (client->info) {
+ /* incref so that it's not freed by upper layers */
+ qobject_incref(client->info);
+ qlist_append_obj(clist, client->info);
+ }
client = client->next;
}
}
@@ -1099,6 +1100,8 @@ static void vnc_disconnect_finish(VncState *vs)
if (!vs->vd->clients)
dcl->idle = 1;
+ qobject_decref(vs->info);
+
vnc_remove_timer(vs->vd);
qemu_free(vs);
}
@@ -2053,6 +2056,8 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
char buf[1024];
int size;
+ vnc_client_cache_info(vs);
+
vnc_write_u16(vs, ds_get_width(vs->ds));
vnc_write_u16(vs, ds_get_height(vs->ds));
@@ -144,6 +144,8 @@ struct VncState
VncStateSASL sasl;
#endif
+ QObject *info;
+
Buffer output;
Buffer input;
/* current output mode information */
When a disconnection happens the client's socket on QEMU side may become invalid, this way it won't be possible to query it to get client information, which is going to be needed by the future VNC disconnect QMP event. To always have this information available we query the socket at connection time and cache the client info in struct VncState. Note that the caching occurs in protocol_client_init(), meaning that client information is only available _after_ the client has successfully authenticated if an authentication method is being used. This is also true for 'query-vnc' or 'info vnc'. If any kind of authentication is enabled and the client is connected but didn't authenticate yet, its info won't be available. Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> --- vnc.c | 19 ++++++++++++------- vnc.h | 2 ++ 2 files changed, 14 insertions(+), 7 deletions(-)