/*
* Copyright (C) 2010-2011 Robert Ancell.
* Author: Robert Ancell <robert.ancell@canonical.com>
- *
+ *
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
/* Port to listen on */
guint port;
+ /* Address to listen on */
+ gchar *listen_address;
+
/* Listening sockets */
GSocket *socket, *socket6;
};
return server->priv->port;
}
+void
+vnc_server_set_listen_address (VNCServer *server, const gchar *listen_address)
+{
+ g_return_if_fail (server != NULL);
+
+ g_free (server->priv->listen_address);
+ server->priv->listen_address = g_strdup (listen_address);
+}
+
+const gchar *
+vnc_server_get_listen_address (VNCServer *server)
+{
+ g_return_val_if_fail (server != NULL, NULL);
+ return server->priv->listen_address;
+}
+
static gboolean
read_cb (GSocket *socket, GIOCondition condition, VNCServer *server)
{
}
static GSocket *
-open_tcp_socket (GSocketFamily family, guint port, GError **error)
+open_tcp_socket (GSocketFamily family, guint port, const gchar *listen_address, GError **error)
{
GSocket *socket;
GSocketAddress *address;
-
+
socket = g_socket_new (family, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, error);
if (!socket)
return NULL;
- address = g_inet_socket_address_new (g_inet_address_new_any (family), port);
+ if (listen_address)
+ {
+ GList *addresses;
+
+ addresses = g_resolver_lookup_by_name (g_resolver_get_default (), listen_address, NULL, error);
+ if (!addresses)
+ {
+ g_object_unref (socket);
+ return NULL;
+ }
+ address = g_inet_socket_address_new (addresses->data, port);
+ g_resolver_free_addresses (addresses);
+ }
+ else
+ address = g_inet_socket_address_new (g_inet_address_new_any (family), port);
if (!g_socket_bind (socket, address, TRUE, error) ||
!g_socket_listen (socket, error))
{
GError *error = NULL;
g_return_val_if_fail (server != NULL, FALSE);
-
- server->priv->socket = open_tcp_socket (G_SOCKET_FAMILY_IPV4, server->priv->port, &error);
+
+ server->priv->socket = open_tcp_socket (G_SOCKET_FAMILY_IPV4, server->priv->port, server->priv->listen_address, &error);
if (error)
g_warning ("Failed to create IPv4 VNC socket: %s", error->message);
g_clear_error (&error);
-
+
if (server->priv->socket)
{
source = g_socket_create_source (server->priv->socket, G_IO_IN, NULL);
g_source_set_callback (source, (GSourceFunc) read_cb, server, NULL);
g_source_attach (source, NULL);
}
-
- server->priv->socket6 = open_tcp_socket (G_SOCKET_FAMILY_IPV6, server->priv->port, &error);
+
+ server->priv->socket6 = open_tcp_socket (G_SOCKET_FAMILY_IPV6, server->priv->port, server->priv->listen_address, &error);
if (error)
g_warning ("Failed to create IPv6 VNC socket: %s", error->message);
g_clear_error (&error);
static void
vnc_server_finalize (GObject *object)
{
- VNCServer *self;
-
- self = VNC_SERVER (object);
-
- if (self->priv->socket)
- g_object_unref (self->priv->socket);
- if (self->priv->socket6)
- g_object_unref (self->priv->socket6);
-
- G_OBJECT_CLASS (vnc_server_parent_class)->finalize (object);
+ VNCServer *self = VNC_SERVER (object);
+
+ g_free (self->priv->listen_address);
+ g_clear_object (&self->priv->socket);
+ g_clear_object (&self->priv->socket6);
+
+ G_OBJECT_CLASS (vnc_server_parent_class)->finalize (object);
}
static void
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = vnc_server_finalize;
+ object_class->finalize = vnc_server_finalize;
g_type_class_add_private (klass, sizeof (VNCServerPrivate));
signals[NEW_CONNECTION] =
- g_signal_new ("new-connection",
+ g_signal_new (VNC_SERVER_SIGNAL_NEW_CONNECTION,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (VNCServerClass, new_connection),