This patch adds notification whenever a client connects or disconnects via VNC.
I'd like to add a lot more events especially ones that are auth related but this
is at least a start.
Signed-off-by: Anthony Liguori <aliguori(a)us.ibm.com>
diff --git a/vnc.c b/vnc.c
index 6d93215..abe6bdf 100644
--- a/vnc.c
+++ b/vnc.c
@@ -29,6 +29,7 @@
#include "qemu_socket.h"
#include "qemu-timer.h"
#include "acl.h"
+#include "wait.h"
#define VNC_REFRESH_INTERVAL (1000 / 30)
@@ -872,6 +873,15 @@ static void audio_del(VncState *vs)
}
}
+static void vnc_send_connect_event(VncState *vs)
+{
+ qemu_notify_event("vnc-event", "connect", vs->peer_address);
+}
+
+static void vnc_send_disconnect_event(VncState *vs)
+{
+ qemu_notify_event("vnc-event", "disconnect",
vs->peer_address);
+}
int vnc_client_io_error(VncState *vs, int ret, int last_errno)
{
@@ -889,6 +899,8 @@ int vnc_client_io_error(VncState *vs, int ret, int last_errno)
}
}
+ vnc_send_disconnect_event(vs);
+ qemu_free(vs->peer_address);
VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ?
last_errno : 0);
qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
closesocket(vs->csock);
@@ -2008,6 +2020,9 @@ static void vnc_connect(VncDisplay *vd, int csock)
vs->next = vd->clients;
vd->clients = vs;
+
+ vs->peer_address = vnc_socket_remote_addr("client-address=%s:%s",
vs->csock);
+ vnc_send_connect_event(vs);
}
static void vnc_listen_read(void *opaque)
@@ -2055,7 +2070,6 @@ void vnc_display_init(DisplayState *ds)
register_displaychangelistener(ds, dcl);
}
-
void vnc_display_close(DisplayState *ds)
{
VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
diff --git a/vnc.h b/vnc.h
index 3ae95f3..745d655 100644
--- a/vnc.h
+++ b/vnc.h
@@ -161,6 +161,8 @@ struct VncState
Buffer zlib_tmp;
z_stream zlib_stream[4];
+ char *peer_address;
+
VncState *next;
};
diff --git a/wait-events.c b/wait-events.c
index ecd26d2..8a2af85 100644
--- a/wait-events.c
+++ b/wait-events.c
@@ -45,10 +45,24 @@ static const EventDesc vm_state_events[] = {
{ 0 },
};
+static const EventDesc vnc_events[] = {
+ { "connect", "a client has connected",
+ "This event occurs whenever a client connects to the builtin VNC
server.",
+ "address=host:service", },
+ { "disconnect", "a client has disconnected",
+ "This event occurs whenever a client disconnects to the builtin VNC
server.",
+ "client-address=host:service", },
+ { 0 },
+};
+
static const EventClassDesc vm_event_classes[] = {
{ "vm-state", "the VM start/stop state has changed",
"These events occur whenever a VM's state changes.",
vm_state_events, },
+ { "vnc-event", "events from the builtin VNC server",
+ "These events are generated by the builtin VNC server. They include\n"
+ "connection information, authentication information, etc.",
+ vnc_events, },
{ 0 },
};
diff --git a/wait.c b/wait.c
index a976a72..33fb702 100644
--- a/wait.c
+++ b/wait.c
@@ -114,7 +114,7 @@ static int event_in_mask(PendingWaiter *w, WaitEvent *e)
{
int ret;
- if (e->class == NULL)
+ if (w->mask == NULL)
ret = 1;
else
ret = find_string(w->mask, e->class);
@@ -128,20 +128,18 @@ static int event_in_mask(PendingWaiter *w, WaitEvent *e)
static int try_to_process_events(void)
{
int processed_events = 0;
+ WaitEvent *e, *ne;
- while (!TAILQ_EMPTY(&pending_events) &&
!TAILQ_EMPTY(&pending_waiters)) {
- WaitEvent *e;
+ TAILQ_FOREACH_SAFE(e, &pending_events, node, ne) {
PendingWaiter *w;
- e = TAILQ_FIRST(&pending_events);
- TAILQ_REMOVE(&pending_events, e, node);
-
TAILQ_FOREACH(w, &pending_waiters, node) {
if (event_in_mask(w, e))
break;
}
if (w) {
+ TAILQ_REMOVE(&pending_events, e, node);
TAILQ_REMOVE(&pending_waiters, w, node);
dispatch_event(w, e);