[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 6/6] Implement vnc-event notifications (v2)



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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]