[gtk-vnc] Add support for connecting to GSocketAddress instances
- From: Daniel P. Berrange <dberrange src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk-vnc] Add support for connecting to GSocketAddress instances
- Date: Mon, 9 Jul 2012 10:51:21 +0000 (UTC)
commit 078e3cffaab939151aa6afc2df08f7444f6db9ec
Author: Daniel P. Berrange <berrange redhat com>
Date: Mon Jul 9 11:49:20 2012 +0100
Add support for connecting to GSocketAddress instances
To improve UNIX domain socket support, add the ability to open
a GSocketAddress instance. Pass the 'hostname' with the addr
for the purposes of SASL/TLS hostname verification. Also add
another method for opening a FD which accepts a hostname, again
for SASL/TLS hostname verification when using a tunnelled
socket
configure.ac | 8 +++++
examples/Makefile.am | 6 ++-
examples/gvncviewer.c | 46 ++++++++++++++++++++++--------
src/libgtk-vnc_sym.version | 2 +
src/libgvnc_sym.version | 2 +
src/vncconnection.c | 67 ++++++++++++++++++++++++++++++++++++++++++-
src/vncconnection.h | 3 ++
src/vncdisplay.c | 39 +++++++++++++++++++++++++
src/vncdisplay.h | 2 +
9 files changed, 159 insertions(+), 16 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 4d1283c..78bbb5f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -179,6 +179,14 @@ PKG_CHECK_MODULES(GIO, gio-2.0 >= $GIO_REQUIRED)
AC_SUBST(GIO_CFLAGS)
AC_SUBST(GIO_LIBS)
+PKG_CHECK_MODULES(GIOUNIX, gio-unix-2.0 >= $GIO_REQUIRED, [have_giounix=yes], [have_giounix=no])
+AC_SUBST(GIOUNIX_CFLAGS)
+AC_SUBST(GIOUNIX_LIBS)
+if test $have_giounix = "yes" ; then
+ AC_DEFINE_UNQUOTED([HAVE_GIOUNIX],[1], [Whether GIO UNIX is available])
+fi
+
+
PKG_CHECK_MODULES(GDK_PIXBUF, gdk-pixbuf-2.0 >= $GDK_PIXBUF_REQUIRED)
AC_SUBST(GDK_PIXBUF_CFLAGS)
AC_SUBST(GDK_PIXBUF_LIBS)
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 62d8445..ee98cb0 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -8,13 +8,15 @@ endif
gvncviewer_SOURCES = gvncviewer.c
gvncviewer_LDADD = ../src/libgtk-vnc-$(GTK_VNC_API_VERSION).la \
../src/libgvnc-1.0.la \
- $(GTK_CFLAGS) \
+ $(GIOUNIX_LIBS) \
$(GTK_LIBS) \
$(VIEW_LIBS)
if HAVE_PULSEAUDIO
gvncviewer_LDADD += ../src/libgvncpulse-1.0.la
endif
-gvncviewer_CFLAGS = $(GTK_CFLAGS) $(WARNING_CFLAGS) \
+gvncviewer_CFLAGS = $(GTK_CFLAGS) \
+ $(GIOUNIX_CFLAGS) \
+ $(WARNING_CFLAGS) \
$(VIEW_CFLAGS) -I$(top_srcdir)/src/
EXTRA_DIST = gvncviewer.py gvncviewer.js
diff --git a/examples/gvncviewer.c b/examples/gvncviewer.c
index 6d47d71..598d926 100644
--- a/examples/gvncviewer.c
+++ b/examples/gvncviewer.c
@@ -30,6 +30,9 @@
#include <stdlib.h>
#include <string.h>
#include <glib.h>
+#if HAVE_GIOUNIX
+#include <gio/gunixsocketaddress.h>
+#endif
#if WITH_LIBVIEW
#include <libview/autoDrawer.h>
@@ -565,8 +568,6 @@ int main(int argc, char **argv)
gchar *name;
GOptionContext *context;
GError *error = NULL;
- char port[1024], hostname[1024];
- char *display;
GtkWidget *window;
GtkWidget *layout;
GtkWidget *menubar;
@@ -687,18 +688,39 @@ int main(int argc, char **argv)
gtk_container_add(GTK_CONTAINER(window), layout);
gtk_widget_realize(vnc);
- snprintf(hostname, sizeof(hostname), "%s", args[0]);
- display = strchr(hostname, ':');
+#if HAVE_GIOUNIX
+ if (strchr(args[0], '/')) {
+ GSocketAddress *addr = g_unix_socket_address_new_with_type
+ (args[0], strlen(args[0]),
+ G_UNIX_SOCKET_ADDRESS_PATH);
- if (display) {
- *display = 0;
- snprintf(port, sizeof(port), "%d", 5900 + atoi(display + 1));
- } else
- snprintf(port, sizeof(port), "%d", 5900);
+ vnc_display_open_addr(VNC_DISPLAY(vnc), addr, NULL);
- if (!*hostname)
- snprintf(hostname, sizeof(hostname), "%s", "127.0.0.1");
- vnc_display_open_host(VNC_DISPLAY(vnc), hostname, port);
+ g_object_unref(addr);
+ } else {
+#endif
+ gchar *tmp;
+ gchar *hostname;
+ gchar *port;
+
+ if (g_str_equal(args[0], ""))
+ hostname = g_strdup("127.0.0.1");
+ else
+ hostname = g_strdup(args[0]);
+
+ tmp = strchr(hostname, ':');
+ if (tmp) {
+ *tmp = '\0';
+ port = g_strdup_printf("%d", 5900 + atoi(tmp + 1));
+ } else {
+ port = g_strdup("5900");
+ }
+ vnc_display_open_host(VNC_DISPLAY(vnc), hostname, port);
+ g_free(hostname);
+ g_free(port);
+#if HAVE_GIOUNIX
+ }
+#endif
vnc_display_set_keyboard_grab(VNC_DISPLAY(vnc), TRUE);
vnc_display_set_pointer_grab(VNC_DISPLAY(vnc), TRUE);
diff --git a/src/libgtk-vnc_sym.version b/src/libgtk-vnc_sym.version
index cdc69ab..d785eba 100644
--- a/src/libgtk-vnc_sym.version
+++ b/src/libgtk-vnc_sym.version
@@ -5,7 +5,9 @@
vnc_display_key_event_get_type;
vnc_display_new;
+ vnc_display_open_addr;
vnc_display_open_fd;
+ vnc_display_open_fd_with_hostname;
vnc_display_open_host;
vnc_display_is_open;
vnc_display_close;
diff --git a/src/libgvnc_sym.version b/src/libgvnc_sym.version
index 64a09dc..9adec25 100644
--- a/src/libgvnc_sym.version
+++ b/src/libgvnc_sym.version
@@ -51,7 +51,9 @@
vnc_connection_get_type;
vnc_connection_new;
+ vnc_connection_open_addr;
vnc_connection_open_fd;
+ vnc_connection_open_fd_with_hostname;
vnc_connection_open_host;
vnc_connection_is_open;
vnc_connection_shutdown;
diff --git a/src/vncconnection.c b/src/vncconnection.c
index f371f74..7bc481a 100644
--- a/src/vncconnection.c
+++ b/src/vncconnection.c
@@ -146,6 +146,7 @@ struct _VncConnectionPrivate
struct coroutine coroutine;
guint open_id;
GSocket *sock;
+ GSocketAddress *addr;
int fd;
char *host;
char *port;
@@ -4738,6 +4739,10 @@ static void vnc_connection_close(VncConnection *conn)
g_object_unref(priv->sock);
priv->sock = NULL;
}
+ if (priv->addr) {
+ g_object_unref(priv->addr);
+ priv->addr = NULL;
+ }
if (priv->fd != -1)
priv->fd = -1;
@@ -4849,6 +4854,8 @@ gboolean vnc_connection_is_open(VncConnection *conn)
return TRUE;
if (priv->host)
return TRUE;
+ if (priv->addr)
+ return TRUE;
return FALSE;
}
@@ -5015,6 +5022,24 @@ static GSocket *vnc_connection_connect_socket(GSocketAddress *sockaddr,
return sock;
}
+static gboolean vnc_connection_open_addr_internal(VncConnection *conn)
+{
+ VncConnectionPrivate *priv = conn->priv;
+ GError *conn_error = NULL;
+ GSocket *sock = NULL;
+
+ VNC_DEBUG("Connecting with addr %p", priv->addr);
+
+ sock = vnc_connection_connect_socket(priv->addr, &conn_error);
+ g_clear_error(&conn_error);
+ if (sock) {
+ priv->sock = sock;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
static gboolean vnc_connection_open_host_internal(VncConnection *conn)
{
VncConnectionPrivate *priv = conn->priv;
@@ -5081,6 +5106,9 @@ static void *vnc_connection_coroutine(void *opaque)
if (priv->fd != -1) {
if (!vnc_connection_open_fd_internal(conn))
goto cleanup;
+ } else if (priv->addr != NULL) {
+ if (!vnc_connection_open_addr_internal(conn))
+ goto cleanup;
} else {
if (!vnc_connection_open_host_internal(conn))
goto cleanup;
@@ -5131,6 +5159,12 @@ static gboolean do_vnc_connection_open(gpointer data)
gboolean vnc_connection_open_fd(VncConnection *conn, int fd)
{
+ return vnc_connection_open_fd_with_hostname(conn, fd, NULL);
+}
+
+
+gboolean vnc_connection_open_fd_with_hostname(VncConnection *conn, int fd, const char *hostname)
+{
VncConnectionPrivate *priv = conn->priv;
VNC_DEBUG("Open fd=%d", fd);
@@ -5139,8 +5173,9 @@ gboolean vnc_connection_open_fd(VncConnection *conn, int fd)
return FALSE;
priv->fd = fd;
- priv->host = NULL;
- priv->port = NULL;
+ priv->addr = NULL;
+ priv->host = g_strdup(hostname ? hostname : "localhost");
+ priv->port = g_strdup("");
g_object_ref(G_OBJECT(conn)); /* Unref'd when co-routine exits */
priv->open_id = g_idle_add(do_vnc_connection_open, conn);
@@ -5148,6 +5183,7 @@ gboolean vnc_connection_open_fd(VncConnection *conn, int fd)
return TRUE;
}
+
gboolean vnc_connection_open_host(VncConnection *conn, const char *host, const char *port)
{
VncConnectionPrivate *priv = conn->priv;
@@ -5158,6 +5194,7 @@ gboolean vnc_connection_open_host(VncConnection *conn, const char *host, const c
return FALSE;
priv->fd = -1;
+ priv->addr = NULL;
priv->host = g_strdup(host);
priv->port = g_strdup(port);
@@ -5167,6 +5204,32 @@ gboolean vnc_connection_open_host(VncConnection *conn, const char *host, const c
return TRUE;
}
+gboolean vnc_connection_open_addr(VncConnection *conn, GSocketAddress *addr, const char *hostname)
+{
+ VncConnectionPrivate *priv = conn->priv;
+
+ VNC_DEBUG("Open addr=%p", addr);
+
+ if (vnc_connection_is_open(conn))
+ return FALSE;
+
+ priv->fd = -1;
+ priv->addr = g_object_ref(addr);
+
+ priv->host = g_strdup(hostname ? hostname : "localhost");
+ if (G_IS_INET_SOCKET_ADDRESS(addr)) {
+ guint16 port = g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(addr));
+ priv->port = g_strdup_printf("%d", (int)port);
+ } else {
+ priv->port = g_strdup("");
+ }
+
+ g_object_ref(G_OBJECT(conn)); /* Unref'd when co-routine exits */
+ priv->open_id = g_idle_add(do_vnc_connection_open, conn);
+
+ return TRUE;
+}
+
gboolean vnc_connection_set_auth_type(VncConnection *conn, unsigned int type)
{
diff --git a/src/vncconnection.h b/src/vncconnection.h
index 764b857..cbfefd7 100644
--- a/src/vncconnection.h
+++ b/src/vncconnection.h
@@ -23,6 +23,7 @@
#define VNC_CONNECTION_H
#include <glib.h>
+#include <gio/gio.h>
#include <vncframebuffer.h>
#include <vnccursor.h>
@@ -153,7 +154,9 @@ GType vnc_connection_get_type(void) G_GNUC_CONST;
VncConnection *vnc_connection_new(void);
gboolean vnc_connection_open_fd(VncConnection *conn, int fd);
+gboolean vnc_connection_open_fd_with_hostname(VncConnection *conn, int fd, const char *hostname);
gboolean vnc_connection_open_host(VncConnection *conn, const char *host, const char *port);
+gboolean vnc_connection_open_addr(VncConnection *conn, GSocketAddress *addr, const char *hostname);
gboolean vnc_connection_is_open(VncConnection *conn);
void vnc_connection_shutdown(VncConnection *conn);
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
index c6354b5..5c0e994 100644
--- a/src/vncdisplay.c
+++ b/src/vncdisplay.c
@@ -1525,6 +1525,45 @@ gboolean vnc_display_open_fd(VncDisplay *obj, int fd)
return TRUE;
}
+
+gboolean vnc_display_open_fd_with_hostname(VncDisplay *obj, int fd, const char *hostname)
+{
+ VncDisplayPrivate *priv = obj->priv;
+
+ if (vnc_connection_is_open(priv->conn))
+ return FALSE;
+
+ if (!vnc_connection_set_shared(priv->conn, priv->shared_flag))
+ return FALSE;
+
+ if (!vnc_connection_open_fd_with_hostname(priv->conn, fd, hostname))
+ return FALSE;
+
+ g_object_ref(G_OBJECT(obj));
+
+ return TRUE;
+}
+
+
+gboolean vnc_display_open_addr(VncDisplay *obj, GSocketAddress *addr, const char *hostname)
+{
+ VncDisplayPrivate *priv = obj->priv;
+
+ if (vnc_connection_is_open(priv->conn))
+ return FALSE;
+
+ if (!vnc_connection_set_shared(priv->conn, priv->shared_flag))
+ return FALSE;
+
+ if (!vnc_connection_open_addr(priv->conn, addr, hostname))
+ return FALSE;
+
+ g_object_ref(G_OBJECT(obj));
+
+ return TRUE;
+}
+
+
gboolean vnc_display_open_host(VncDisplay *obj, const char *host, const char *port)
{
VncDisplayPrivate *priv = obj->priv;
diff --git a/src/vncdisplay.h b/src/vncdisplay.h
index b2c9a22..b53eee3 100644
--- a/src/vncdisplay.h
+++ b/src/vncdisplay.h
@@ -87,6 +87,8 @@ GType vnc_display_get_type(void);
GtkWidget *vnc_display_new(void);
gboolean vnc_display_open_fd(VncDisplay *obj, int fd);
+gboolean vnc_display_open_fd_with_hostname(VncDisplay *obj, int fd, const char *hostname);
+gboolean vnc_display_open_addr(VncDisplay *obj, GSocketAddress *addr, const char *hostname);
gboolean vnc_display_open_host(VncDisplay *obj, const char *host, const char *port);
gboolean vnc_display_is_open(VncDisplay *obj);
void vnc_display_close(VncDisplay *obj);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]