vino r1015 - in trunk: . capplet server server/libvncserver server/libvncserver/rfb
- From: jwendell svn gnome org
- To: svn-commits-list gnome org
- Subject: vino r1015 - in trunk: . capplet server server/libvncserver server/libvncserver/rfb
- Date: Fri, 12 Dec 2008 19:58:32 +0000 (UTC)
Author: jwendell
Date: Fri Dec 12 19:58:32 2008
New Revision: 1015
URL: http://svn.gnome.org/viewvc/vino?rev=1015&view=rev
Log:
2008-11-25 Jorge Pereira <jorge jorgepereira com br>
* capplet/vino-preferences.c:
(vino_preferences_dialog_update_for_allowed),
(vino_preferences_load_network_interfaces),
(vino_preferences_dialog_network_interface_update_combox),
(vino_preferences_dialog_network_interface_notify),
(vino_preferences_dialog_network_interface_changed),
(vino_preferences_dialog_setup_network_interface_combox),
(vino_preferences_dialog_init):
* capplet/vino-preferences.glade:
* configure.in:
* server/libvncserver/main.c: (rfbGetScreen):
* server/libvncserver/rfb/rfb.h:
* server/libvncserver/rfbserver.c: (rfbNewClient):
* server/libvncserver/sockets.c: (rfbInitListenSock),
(rfbSetAutoPort), (rfbSetPort), (rfbProcessNewConnection),
(rfbCheckFds), (ListenOnTCPPort), (NewSocketListenTCP),
(rfbSetNetworkInterface):
* server/vino-prefs.c: (vino_prefs_network_interface_changed),
(vino_prefs_create_server), (vino_prefs_init):
* server/vino-server.c: (vino_server_new_connection_pending),
(vino_server_init_from_screen), (vino_server_finalize),
(vino_server_set_property), (vino_server_get_property),
(vino_server_class_init), (vino_server_get_network_interface),
(vino_server_set_network_interface):
* server/vino-server.h:
* server/vino-server.schemas.in:
Removed the feature localOnly, added correct support for IPv4 mapped
IPv6, and added a new feature to able to set network interface for
accept connection. Closes #403183,#403192,#488354.
Modified:
trunk/ChangeLog
trunk/capplet/vino-preferences.c
trunk/capplet/vino-preferences.glade
trunk/configure.in
trunk/server/libvncserver/main.c
trunk/server/libvncserver/rfb/rfb.h
trunk/server/libvncserver/rfbserver.c
trunk/server/libvncserver/sockets.c
trunk/server/vino-prefs.c
trunk/server/vino-server.c
trunk/server/vino-server.h
trunk/server/vino-server.schemas.in
Modified: trunk/capplet/vino-preferences.c
==============================================================================
--- trunk/capplet/vino-preferences.c (original)
+++ trunk/capplet/vino-preferences.c Fri Dec 12 19:58:32 2008
@@ -30,6 +30,8 @@
#include <libintl.h>
#include <unistd.h>
#include <netdb.h>
+#include <net/if.h>
+#include <ifaddrs.h>
#include <gtk/gtk.h>
#include <glade/glade.h>
#include <gconf/gconf-client.h>
@@ -52,14 +54,14 @@
#define VINO_PREFS_VNC_PASSWORD VINO_PREFS_DIR "/vnc_password"
#define VINO_PREFS_MAILTO VINO_PREFS_DIR "/mailto"
#define VINO_PREFS_ICON_VISIBILITY VINO_PREFS_DIR "/icon_visibility"
-#define VINO_PREFS_LOCAL_ONLY VINO_PREFS_DIR "/local_only"
+#define VINO_PREFS_NETWORK_INTERFACE VINO_PREFS_DIR "/network_interface"
#define VINO_PREFS_ENCRYPTION VINO_PREFS_DIR "/require_encryption"
#define VINO_PREFS_USE_ALTERNATIVE_PORT VINO_PREFS_DIR "/use_alternative_port"
#define VINO_PREFS_ALTERNATIVE_PORT VINO_PREFS_DIR "/alternative_port"
#define VINO_PREFS_LOCK_SCREEN VINO_PREFS_DIR "/lock_screen_on_disconnect"
#define VINO_PREFS_DISABLE_BACKGROUND VINO_PREFS_DIR "/disable_background"
-#define N_LISTENERS 13
+#define N_LISTENERS 13
#define VINO_DBUS_BUS_NAME "org.gnome.Vino"
#define VINO_DBUS_INTERFACE "org.gnome.VinoScreen"
@@ -82,7 +84,8 @@
GtkWidget *icon_always_radio;
GtkWidget *icon_client_radio;
GtkWidget *icon_never_radio;
- GtkWidget *local_only_toggle;
+ GtkWidget *network_interface_combox;
+ GtkWidget *network_interface_label;
GtkWidget *encryption_toggle;
GtkWidget *use_alternative_port_toggle;
GtkWidget *alternative_port_entry;
@@ -180,7 +183,8 @@
gtk_widget_set_sensitive (dialog->icon_always_radio, allowed);
gtk_widget_set_sensitive (dialog->icon_client_radio, allowed);
gtk_widget_set_sensitive (dialog->icon_never_radio, allowed);
- gtk_widget_set_sensitive (dialog->local_only_toggle, allowed);
+ gtk_widget_set_sensitive (dialog->network_interface_combox, allowed);
+ gtk_widget_set_sensitive (dialog->network_interface_label, allowed);
gtk_widget_set_sensitive (dialog->encryption_toggle, allowed);
gtk_widget_set_sensitive (dialog->use_alternative_port_toggle, allowed);
gtk_widget_set_sensitive (dialog->alternative_port_entry, allowed &&
@@ -189,65 +193,133 @@
gtk_widget_set_sensitive (dialog->disable_background_toggle, allowed);
}
-static void
-vino_preferences_dialog_local_only_toggled (GtkToggleButton *toggle,
- VinoPreferencesDialog *dialog)
+static GSList *
+vino_preferences_load_network_interfaces (void)
{
- gboolean local_only;
+ struct ifaddrs *myaddrs, *ifa;
+ GSList *list = NULL;
+
+ /* Translators: 'All' means 'All network interfaces' */
+ list = g_slist_append (list, g_strdup (_("All")));
+
+ getifaddrs (&myaddrs);
+ for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
+ {
+ if (ifa->ifa_addr == NULL || ifa->ifa_name == NULL || (ifa->ifa_flags & IFF_UP) == 0)
+ continue;
- local_only = gtk_toggle_button_get_active (toggle);
+ if (ifa->ifa_addr->sa_family == AF_INET || ifa->ifa_addr->sa_family == AF_INET6)
+ {
+ if (g_slist_find_custom (list, ifa->ifa_name, (GCompareFunc)g_strcasecmp) == NULL)
+ {
+ list = g_slist_append (list, g_strdup (ifa->ifa_name));
+ }
+ }
+ }
- gconf_client_set_bool (dialog->client, VINO_PREFS_LOCAL_ONLY, local_only, NULL);
+ freeifaddrs (myaddrs);
+ return list;
}
static void
-vino_preferences_dialog_local_only_notify (GConfClient *client,
- guint cnx_id,
- GConfEntry *entry,
- VinoPreferencesDialog *dialog)
+vino_preferences_dialog_network_interface_update_combox (VinoPreferencesDialog *dialog,
+ const gchar *selected_iface,
+ gboolean first_time)
{
- gboolean local_only;
+ GSList *list;
+ gint i, sel;
+ gchar *iface_check;
- if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
- return;
+ list = vino_preferences_load_network_interfaces ();
- local_only = gconf_value_get_bool (entry->value) != FALSE;
+ if (selected_iface)
+ iface_check = g_strdup (selected_iface);
+ else
+ iface_check = gconf_client_get_string (dialog->client, VINO_PREFS_NETWORK_INTERFACE, NULL);
- if (local_only != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->local_only_toggle)))
+ sel = 0;
+ for(i = 0; list; list = list->next, i++)
{
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->local_only_toggle), local_only);
+ gchar *iface = list->data;
+
+ if (!iface)
+ continue;
+
+ if (first_time)
+ gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->network_interface_combox), iface);
+
+ if (iface_check && !g_strcasecmp (iface, iface_check))
+ sel = i;
+
+ g_free (iface);
}
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->network_interface_combox), sel);
+ g_slist_free (list);
+ g_free (iface_check);
}
-static gboolean
-vino_preferences_dialog_setup_local_only_toggle (VinoPreferencesDialog *dialog)
+static void
+vino_preferences_dialog_network_interface_notify (GConfClient *client,
+ guint cnx_id,
+ GConfEntry *entry,
+ VinoPreferencesDialog *dialog)
{
- gboolean local_only;
+ gchar *old_iface;
+ const gchar *new_iface;
- dialog->local_only_toggle = glade_xml_get_widget (dialog->xml, "local_only_toggle");
- g_assert (dialog->local_only_toggle != NULL);
+ if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
+ return;
+
+ new_iface = gconf_value_get_string (entry->value);
+ old_iface = gtk_combo_box_get_active_text (GTK_COMBO_BOX (dialog->network_interface_combox));
+
+ if (old_iface && new_iface && g_strcasecmp (old_iface, new_iface) != 0)
+ vino_preferences_dialog_network_interface_update_combox (dialog, new_iface, FALSE);
+
+ g_free (old_iface);
+}
+
+static void
+vino_preferences_dialog_network_interface_changed (gpointer unused,
+ VinoPreferencesDialog *dialog)
+{
+ gchar *iface;
- local_only = gconf_client_get_bool (dialog->client, VINO_PREFS_LOCAL_ONLY, NULL);
+ iface = gtk_combo_box_get_active_text (GTK_COMBO_BOX (dialog->network_interface_combox));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->local_only_toggle), local_only);
+ if (g_strcasecmp (iface, _("All")))
+ gconf_client_set_string (dialog->client, VINO_PREFS_NETWORK_INTERFACE, iface, NULL);
+ else
+ gconf_client_set_string (dialog->client, VINO_PREFS_NETWORK_INTERFACE, "", NULL);
+
+ g_free (iface);
+}
+
+static void
+vino_preferences_dialog_setup_network_interface_combox (VinoPreferencesDialog *dialog)
+{
+ dialog->network_interface_combox = glade_xml_get_widget (dialog->xml, "network_interface_combox");
+ dialog->network_interface_label = glade_xml_get_widget (dialog->xml, "network_interface_label");
+ g_assert (dialog->network_interface_combox != NULL);
+ vino_preferences_dialog_network_interface_update_combox (dialog, NULL, TRUE);
- g_signal_connect (dialog->local_only_toggle, "toggled",
- G_CALLBACK (vino_preferences_dialog_local_only_toggled), dialog);
+ g_signal_connect (dialog->network_interface_combox, "changed",
+ G_CALLBACK (vino_preferences_dialog_network_interface_changed), dialog);
- if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_LOCAL_ONLY, NULL))
+ if (!gconf_client_key_is_writable (dialog->client, VINO_PREFS_NETWORK_INTERFACE, NULL))
{
- gtk_widget_set_sensitive (dialog->local_only_toggle, FALSE);
+ gtk_widget_set_sensitive (dialog->network_interface_combox, FALSE);
+ gtk_widget_set_sensitive (dialog->network_interface_label, FALSE);
gtk_widget_show (dialog->writability_warning);
}
- dialog->listeners [dialog->n_listeners] =
- gconf_client_notify_add (dialog->client,
- VINO_PREFS_LOCAL_ONLY,
- (GConfClientNotifyFunc) vino_preferences_dialog_local_only_notify,
- dialog, NULL, NULL);
+ dialog->listeners [dialog->n_listeners] =
+ gconf_client_notify_add (dialog->client,
+ VINO_PREFS_NETWORK_INTERFACE,
+ (GConfClientNotifyFunc)vino_preferences_dialog_network_interface_notify,
+ dialog, NULL, NULL);
dialog->n_listeners++;
-
- return local_only;
}
static void
@@ -1450,13 +1522,13 @@
allowed = vino_preferences_dialog_setup_allowed_toggle (dialog);
- vino_preferences_dialog_setup_prompt_enabled_toggle (dialog);
- vino_preferences_dialog_setup_view_only_toggle (dialog);
- vino_preferences_dialog_setup_password_toggle (dialog);
- vino_preferences_dialog_setup_password_entry (dialog);
- vino_preferences_dialog_setup_icon_visibility (dialog);
- vino_preferences_dialog_setup_local_only_toggle (dialog);
- vino_preferences_dialog_setup_encryption_toggle (dialog);
+ vino_preferences_dialog_setup_prompt_enabled_toggle (dialog);
+ vino_preferences_dialog_setup_view_only_toggle (dialog);
+ vino_preferences_dialog_setup_password_toggle (dialog);
+ vino_preferences_dialog_setup_password_entry (dialog);
+ vino_preferences_dialog_setup_icon_visibility (dialog);
+ vino_preferences_dialog_setup_network_interface_combox (dialog);
+ vino_preferences_dialog_setup_encryption_toggle (dialog);
vino_preferences_dialog_setup_alternative_port_entry (dialog);
vino_preferences_dialog_setup_use_alternative_port_toggle (dialog);
vino_preferences_dialog_setup_lock_screen_toggle (dialog);
Modified: trunk/capplet/vino-preferences.glade
==============================================================================
--- trunk/capplet/vino-preferences.glade (original)
+++ trunk/capplet/vino-preferences.glade Fri Dec 12 19:58:32 2008
@@ -444,15 +444,39 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
<property name="spacing">6</property>
<child>
- <widget class="GtkCheckButton" id="local_only_toggle">
+ <widget class="GtkHBox" id="hbox3">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="has_tooltip">True</property>
- <property name="tooltip" translatable="yes">The server will only accept connections from localhost</property>
- <property name="label" translatable="yes">_Only allow local connections</property>
- <property name="use_underline">True</property>
- <property name="response_id">0</property>
- <property name="draw_indicator">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="network_interface_label">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Which network interface we should listen to.</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Listen this interface:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">network_interface_combox</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkComboBox" id="network_interface_combox">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tearoff_title">Click here to change the network interface!</property>
+ <property name="button_sensitivity">GTK_SENSITIVITY_ON</property>
+ <property name="items" translatable="yes"></property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">1</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="expand">False</property>
@@ -490,6 +514,7 @@
</widget>
<packing>
<property name="expand">False</property>
+ <property name="padding">1</property>
<property name="position">1</property>
</packing>
</child>
Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in (original)
+++ trunk/configure.in Fri Dec 12 19:58:32 2008
@@ -257,7 +257,7 @@
AC_SUBST(LIBZ)
AC_SUBST(LIBJPEG)
-AC_CHECK_HEADERS([netinet/in.h sys/time.h fcntl.h unistd.h sys/socket.h signal.h])
+AC_CHECK_HEADERS([netinet/in.h sys/time.h fcntl.h unistd.h sys/socket.h signal.h ifaddrs.h net/if.h])
AC_CHECK_FUNCS([gettimeofday])
dnl
Modified: trunk/server/libvncserver/main.c
==============================================================================
--- trunk/server/libvncserver/main.c (original)
+++ trunk/server/libvncserver/main.c Fri Dec 12 19:58:32 2008
@@ -320,7 +320,10 @@
rfbScreen->inetdSock=-1;
rfbScreen->maxFd=0;
- rfbScreen->rfbListenSock=-1;
+
+ rfbScreen->rfbListenSock[0] = -1;
+ rfbScreen->rfbListenSockTotal = 0;
+ rfbScreen->netIface = NULL;
rfbScreen->desktopName = strdup("LibVNCServer");
rfbScreen->rfbAlwaysShared = FALSE;
Modified: trunk/server/libvncserver/rfb/rfb.h
==============================================================================
--- trunk/server/libvncserver/rfb/rfb.h (original)
+++ trunk/server/libvncserver/rfb/rfb.h Fri Dec 12 19:58:32 2008
@@ -54,6 +54,8 @@
/* end of stuff for autoconf */
+#define RFB_MAX_SOCKETLISTEN 8 /* is the max listen by network interface */
+
struct _rfbClientRec;
struct _rfbScreenInfo;
struct rfbCursor;
@@ -114,7 +116,9 @@
rfbBool autoPort;
rfbBool localOnly;
int rfbPort;
- SOCKET rfbListenSock;
+ SOCKET rfbListenSock[RFB_MAX_SOCKETLISTEN];
+ int rfbListenSockTotal;
+ const char *netIface;
int maxSock;
int maxFd;
fd_set allFds;
@@ -394,9 +398,11 @@
extern int ReadExact(rfbClientPtr cl, char *buf, int len);
extern int ReadExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout);
extern int WriteExact(rfbClientPtr cl, const char *buf, int len);
-extern void rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen);
+extern void rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen, int insock);
extern void rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec);
-extern int ListenOnTCPPort(int port, rfbBool localOnly);
+extern rfbBool ListenOnTCPPort(rfbScreenInfoPtr rfbScreen, int port, const char *netIface);
+extern rfbBool rfbSetNetworkInterface(rfbScreenInfoPtr rfbScreen, const char *netIface);
+extern int NewSocketListenTCP(struct sockaddr *addr, socklen_t len);
/* rfbserver.c */
Modified: trunk/server/libvncserver/rfbserver.c
==============================================================================
--- trunk/server/libvncserver/rfbserver.c (original)
+++ trunk/server/libvncserver/rfbserver.c Fri Dec 12 19:58:32 2008
@@ -151,6 +151,7 @@
socklen_t addrlen = sizeof(addr);
int i;
char host[NI_MAXHOST];
+ const char *prt = "unknown";
cl = (rfbClientPtr)calloc(sizeof(rfbClientRec),1);
@@ -173,7 +174,12 @@
cl->host = strdup(host);
- rfbLog("Got connection from client %s\n", cl->host);
+ if (addr.ss_family == AF_INET)
+ prt = "IPv4";
+ else if (addr.ss_family == AF_INET6)
+ prt = "IPv6";
+
+ rfbLog("[%s] Got connection from client %s\n", prt, cl->host);
rfbLog(" other clients:\n");
iterator = rfbGetClientIterator(rfbScreen);
Modified: trunk/server/libvncserver/sockets.c
==============================================================================
--- trunk/server/libvncserver/sockets.c (original)
+++ trunk/server/libvncserver/sockets.c Fri Dec 12 19:58:32 2008
@@ -70,6 +70,9 @@
#endif
#endif
+#include <net/if.h> // IFF_UP
+#include <ifaddrs.h> // getifaddrs()
+
#if defined(__linux__) && defined(NEED_TIMEVAL)
struct timeval
{
@@ -135,38 +138,53 @@
static void
rfbInitListenSock(rfbScreenInfoPtr rfbScreen)
{
+ char *netIface = (char*)rfbScreen->netIface;
+ int i;
+
+ if(netIface == NULL || if_nametoindex(netIface) == 0) {
+ if(netIface != NULL)
+ rfbLog("WARNING: This (%s) a invalid network interface, set to all\n", netIface);
+ netIface = NULL;
+ }
+
if(rfbScreen->autoPort) {
- int i;
- rfbLog("Autoprobing TCP port \n");
+ rfbLog("Autoprobing TCP port in (%s) network interface\n",
+ netIface != NULL ? netIface : "all");
- for (i = 5900; i < 6000; i++) {
- if ((rfbScreen->rfbListenSock = ListenOnTCPPort(i, rfbScreen->localOnly)) >= 0) {
- rfbScreen->rfbPort = i;
- break;
- }
+ for (i = 5900; i < 6000; i++) {
+ if (ListenOnTCPPort(rfbScreen, i, netIface)) {
+ rfbScreen->rfbPort = i;
+ break;
}
+ }
- if (i >= 6000) {
- rfbLogPerror("Failure autoprobing");
- return;
- }
+ if (i >= 6000) {
+ rfbLogPerror("Failure autoprobing");
+ return;
+ }
+
+ rfbLog("Autoprobing selected port %d\n", rfbScreen->rfbPort);
- rfbLog("Autoprobing selected port %d\n", rfbScreen->rfbPort);
- FD_ZERO(&(rfbScreen->allFds));
- FD_SET(rfbScreen->rfbListenSock, &(rfbScreen->allFds));
- rfbScreen->maxFd = rfbScreen->rfbListenSock;
+ FD_ZERO(&rfbScreen->allFds);
+ for(i=0; i < rfbScreen->rfbListenSockTotal; i++) {
+ FD_SET(rfbScreen->rfbListenSock[i], &rfbScreen->allFds);
+ rfbScreen->maxFd = rfbScreen->rfbListenSock[i];
+ }
}
- else if(rfbScreen->rfbPort>0) {
- rfbLog("Listening for VNC connections on TCP port %d\n", rfbScreen->rfbPort);
+ else if(rfbScreen->rfbPort > 0) {
+ rfbLog("Listening for VNC connections on TCP port %d in (%s) network interface\n",
+ rfbScreen->rfbPort, netIface != NULL ? netIface : "all");
- if ((rfbScreen->rfbListenSock = ListenOnTCPPort(rfbScreen->rfbPort, rfbScreen->localOnly)) < 0) {
- rfbLogPerror("ListenOnTCPPort");
- return;
+ if (!ListenOnTCPPort(rfbScreen, rfbScreen->rfbPort, netIface)) {
+ rfbLogPerror("ListenOnTCPPort");
+ return;
}
- FD_ZERO(&(rfbScreen->allFds));
- FD_SET(rfbScreen->rfbListenSock, &(rfbScreen->allFds));
- rfbScreen->maxFd = rfbScreen->rfbListenSock;
+ FD_ZERO(&rfbScreen->allFds);
+ for(i=0; i < rfbScreen->rfbListenSockTotal; i++) {
+ FD_SET(rfbScreen->rfbListenSock[i], &rfbScreen->allFds);
+ rfbScreen->maxFd = rfbScreen->rfbListenSock[i];
+ }
}
}
@@ -181,10 +199,15 @@
if (!rfbScreen->socketInitDone)
return;
- if (rfbScreen->rfbListenSock > 0) {
- FD_CLR(rfbScreen->rfbListenSock, &(rfbScreen->allFds));
- close(rfbScreen->rfbListenSock);
- rfbScreen->rfbListenSock = -1;
+ if (rfbScreen->rfbListenSockTotal > 0) {
+ int i;
+
+ for(i=0; i < rfbScreen->rfbListenSockTotal; i++) {
+ FD_CLR(rfbScreen->rfbListenSock[i], &rfbScreen->allFds);
+ close(rfbScreen->rfbListenSock[i]);
+ rfbScreen->rfbListenSock[i] = -1;
+ }
+ rfbScreen->rfbListenSockTotal = 0;
}
rfbInitListenSock(rfbScreen);
@@ -201,53 +224,35 @@
if (!rfbScreen->socketInitDone || rfbScreen->autoPort)
return;
- if (rfbScreen->rfbListenSock > 0) {
- FD_CLR(rfbScreen->rfbListenSock, &(rfbScreen->allFds));
- close(rfbScreen->rfbListenSock);
- rfbScreen->rfbListenSock = -1;
- }
-
- rfbInitListenSock(rfbScreen);
-}
-
-void
-rfbSetLocalOnly(rfbScreenInfoPtr rfbScreen, rfbBool localOnly)
-{
- if (rfbScreen->localOnly == localOnly)
- return;
-
- rfbScreen->localOnly = localOnly;
-
- if (!rfbScreen->socketInitDone)
- return;
-
- if (rfbScreen->rfbListenSock > 0) {
- FD_CLR(rfbScreen->rfbListenSock, &(rfbScreen->allFds));
- close(rfbScreen->rfbListenSock);
- rfbScreen->rfbListenSock = -1;
- }
-
- rfbLog("Re-binding socket to listen for %s VNC connections on TCP port %d\n",
- rfbScreen->localOnly ? "local" : "all", rfbScreen->rfbPort);
+ if (rfbScreen->rfbListenSockTotal > 0) {
+ int i;
- if ((rfbScreen->rfbListenSock = ListenOnTCPPort(rfbScreen->rfbPort, rfbScreen->localOnly)) < 0) {
- rfbLogPerror("ListenOnTCPPort");
- return;
+ for(i=0; i < rfbScreen->rfbListenSockTotal; i++) {
+ FD_CLR(rfbScreen->rfbListenSock[i], &rfbScreen->allFds);
+ close(rfbScreen->rfbListenSock[i]);
+ rfbScreen->rfbListenSock[i] = -1;
+ }
+ rfbScreen->rfbListenSockTotal = 0;
}
- FD_SET(rfbScreen->rfbListenSock, &(rfbScreen->allFds));
- rfbScreen->maxFd = max(rfbScreen->rfbListenSock, rfbScreen->maxFd);
+ rfbInitListenSock(rfbScreen);
}
void
-rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen)
+rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen, int insock)
{
const int one = 1;
- int sock;
+ int sock = -1;
+ int i;
+
+ if((sock = accept(insock, NULL, NULL)) < 0) {
+ rfbLogPerror("rfbCheckFds: accept");
+ return;
+ }
- if ((sock = accept(rfbScreen->rfbListenSock, NULL, NULL)) < 0) {
- rfbLogPerror("rfbCheckFds: accept");
- return;
+ if(sock < 0) {
+ rfbLogPerror("rfbCheckFds: accept");
+ return;
}
#ifndef WIN32
@@ -258,8 +263,7 @@
}
#endif
- if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
- (char *)&one, sizeof(one)) < 0) {
+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) {
rfbLogPerror("rfbCheckFds: setsockopt");
close(sock);
return;
@@ -279,6 +283,7 @@
rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
{
int nfds;
+ int n;
fd_set fds;
struct timeval tv;
rfbClientIteratorPtr i;
@@ -289,7 +294,7 @@
rfbScreen->inetdInitDone = TRUE;
}
- memcpy((char *)&fds, (char *)&(rfbScreen->allFds), sizeof(fd_set));
+ memcpy(&fds, &rfbScreen->allFds, sizeof(fd_set));
tv.tv_sec = 0;
tv.tv_usec = usec;
nfds = select(rfbScreen->maxFd + 1, &fds, NULL, NULL /* &fds */, &tv);
@@ -304,12 +309,14 @@
rfbLogPerror("rfbCheckFds: select");
return;
}
-
- if (rfbScreen->rfbListenSock != -1 && FD_ISSET(rfbScreen->rfbListenSock, &fds)) {
- rfbProcessNewConnection(rfbScreen);
- FD_CLR(rfbScreen->rfbListenSock, &fds);
- if (--nfds == 0)
- return;
+ printf("DUMP: nfds = %d\n", nfds);
+ for(n=0; n < rfbScreen->rfbListenSockTotal; n++) {
+ if (rfbScreen->rfbListenSock[n] != -1 && FD_ISSET(rfbScreen->rfbListenSock[n], &fds)) {
+ rfbProcessNewConnection(rfbScreen, rfbScreen->rfbListenSock[n]);
+ FD_CLR(rfbScreen->rfbListenSock[n], &fds);
+ if (--nfds == 0)
+ return;
+ }
}
i = rfbGetClientIterator(rfbScreen);
@@ -547,57 +554,175 @@
return 1;
}
-int
-ListenOnTCPPort(port, localOnly)
- int port;
- rfbBool localOnly;
+rfbBool
+ListenOnTCPPort(rfbScreenInfoPtr rfbScreen, int port, const char *netIface)
{
- int sock = -1;
- int one = 1;
- struct sockaddr_in addr_in;
- struct sockaddr *addr;
- socklen_t addrlen;
+ int sock = -1;
+ int *psock = NULL;
+ int *ptot = NULL;
+ struct ifaddrs *myaddrs = NULL;
+ struct ifaddrs *ifa = NULL;
+
+ if(rfbScreen == NULL)
+ return FALSE;
+
+ psock = rfbScreen->rfbListenSock;
+ ptot = &rfbScreen->rfbListenSockTotal;
+ *ptot = 0;
+ if(netIface == NULL || strlen(netIface) == 0)
+ {
#ifdef ENABLE_IPV6
- struct sockaddr_in6 addr_in6;
+ struct sockaddr_in6 s6;
- memset(&addr_in6, 0, sizeof(addr_in6));
- addr_in6.sin6_family = AF_INET6;
- addr_in6.sin6_port = htons(port);
- addr_in6.sin6_addr = localOnly ? in6addr_loopback : in6addr_any;
+ memset(&s6, 0, sizeof(s6));
+ s6.sin6_family = AF_INET6;
+ s6.sin6_port = htons(port);
+ s6.sin6_addr = in6addr_any;
- addr = (struct sockaddr *)&addr_in6;
- addrlen = sizeof(addr_in6);
-
- sock = socket(AF_INET6, SOCK_STREAM, 0);
+ sock = NewSocketListenTCP ((struct sockaddr*)&s6, sizeof(s6));
+ rfbLog("Listening IPv{4,6}://*:%d\n", port);
#endif
+ if(sock < 0) {
+ struct sockaddr_in s4;
- if (sock < 0) {
- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- return -1;
+ memset(&s4, 0, sizeof(s4));
+ s4.sin_family = AF_INET;
+ s4.sin_port = htons(port);
+ s4.sin_addr.s_addr = htonl(INADDR_ANY);
- memset(&addr_in, 0, sizeof(addr_in));
- addr_in.sin_family = AF_INET;
- addr_in.sin_port = htons(port);
- addr_in.sin_addr.s_addr = localOnly ? htonl(INADDR_LOOPBACK) : htonl(INADDR_ANY);
+ sock = NewSocketListenTCP ((struct sockaddr*)&s4, sizeof(s4));
+ rfbLog("Listening IPv4://0.0.0.0:%d\n", port);
+ }
- addr = (struct sockaddr *)&addr_in;
- addrlen = sizeof(addr_in);
+ if(sock > 0) {
+ psock[0] = sock;
+ *ptot = 1;
+ return TRUE;
}
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
- (char *)&one, sizeof(one)) < 0) {
- close(sock);
- return -1;
+ rfbLog("Problems in NewSocketListenTCP(), sock=%d\n", sock);
+ return FALSE;
+ }
+
+ if(getifaddrs(&myaddrs) != 0) {
+ rfbLogPerror("getifaddrs\n");
+ return FALSE;
+ }
+
+ for (ifa = myaddrs; ifa != NULL && *ptot < RFB_MAX_SOCKETLISTEN; ifa = ifa->ifa_next) {
+ char buf[64] = { 0, };
+
+ if (ifa->ifa_addr == NULL || (ifa->ifa_flags & IFF_UP) == 0)
+ continue;
+
+ if (ifa->ifa_addr->sa_family == AF_INET) {
+ struct sockaddr_in *s4 = (struct sockaddr_in*)ifa->ifa_addr;
+ s4->sin_port = htons(port);
+
+ if (inet_ntop(s4->sin_family, (struct sockaddr*)&s4->sin_addr, buf, sizeof(buf)) == NULL) {
+ rfbLog("%s: inet_ntop failed!\n", ifa->ifa_name);
+ continue;
+ }
+ else if(!strcmp(ifa->ifa_name, netIface)) {
+ rfbLog("Listening IPv4://%s:%d\n", buf, port);
+ sock = NewSocketListenTCP((struct sockaddr*)s4, INET_ADDRSTRLEN);
+ }
}
- if (bind(sock, addr, addrlen) < 0) {
- close(sock);
- return -1;
+#ifdef ENABLE_IPV6
+ if (ifa->ifa_addr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *s6 = (struct sockaddr_in6*)ifa->ifa_addr;
+ s6->sin6_port = htons(port);
+
+ if (inet_ntop(ifa->ifa_addr->sa_family, (struct sockaddr*)&s6->sin6_addr, buf, sizeof(buf)) == NULL) {
+ rfbLog("%s: inet_ntop failed!\n", ifa->ifa_name);
+ continue;
+ }
+ else if(!strcmp(ifa->ifa_name, netIface)) {
+ rfbLog("Listening IPv6://%s:%d\n", buf, port);
+ sock = NewSocketListenTCP((struct sockaddr*)s6, INET6_ADDRSTRLEN);
+ }
+ }
+#endif
+
+ if(sock > 0) {
+ psock[*ptot] = sock;
+ *ptot += 1;
+ sock = -1;
}
+ }
+
+ freeifaddrs(myaddrs);
+
+ return TRUE;
+}
+
+int
+NewSocketListenTCP(struct sockaddr *addr, socklen_t len)
+{
+ int sock = -1;
+ int one = 1;
+
+ if ((sock = socket(addr->sa_family, SOCK_STREAM, 0)) < 0)
+ return -1;
+
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
+ close(sock);
+ return -1;
+ }
+
+ if (bind(sock, addr, len) < 0) {
+ close(sock);
+ return -1;
+ }
+
if (listen(sock, 5) < 0) {
- close(sock);
- return -1;
+ close(sock);
+ return -1;
}
return sock;
}
+
+rfbBool
+rfbSetNetworkInterface(rfbScreenInfoPtr rfbScreen, const char *netIface)
+{
+ int i;
+
+ if (!rfbScreen->socketInitDone || !rfbScreen->socketInitDone)
+ return FALSE;
+
+ if(rfbScreen->rfbListenSockTotal > 0) {
+ for(i=0; i < rfbScreen->rfbListenSockTotal; i++) {
+ FD_CLR(rfbScreen->rfbListenSock[i], &(rfbScreen->allFds));
+ close(rfbScreen->rfbListenSock[i]);
+ rfbScreen->rfbListenSock[i] = -1;
+ }
+ rfbScreen->rfbListenSockTotal = 0;
+ }
+
+ if(netIface != NULL && strlen(netIface) > 0 && if_nametoindex(netIface) > 0) {
+ rfbScreen->netIface = netIface;
+ }
+ else {
+ rfbScreen->netIface = NULL;
+ if(netIface != NULL)
+ rfbLog("WARNING: This (%s) a invalid network interface, set to all\n", netIface);
+ }
+
+ rfbLog("Re-binding socket to listen for VNC connections on TCP port %d in (%s) interface\n",
+ rfbScreen->rfbPort, rfbScreen->netIface != NULL ? rfbScreen->netIface : "all");
+
+ if (!ListenOnTCPPort(rfbScreen, rfbScreen->rfbPort, rfbScreen->netIface)) {
+ rfbLogPerror("ListenOnTCPPort");
+ return FALSE;
+ }
+
+ for(i=0; i < rfbScreen->rfbListenSockTotal; i++) {
+ FD_SET(rfbScreen->rfbListenSock[i], &(rfbScreen->allFds));
+ rfbScreen->maxFd = max(rfbScreen->rfbListenSock[i], rfbScreen->maxFd);
+ }
+
+ return TRUE;
+}
+
Modified: trunk/server/vino-prefs.c
==============================================================================
--- trunk/server/vino-prefs.c (original)
+++ trunk/server/vino-prefs.c Fri Dec 12 19:58:32 2008
@@ -37,6 +37,7 @@
#define VINO_PREFS_PROMPT_ENABLED VINO_PREFS_DIR "/prompt_enabled"
#define VINO_PREFS_VIEW_ONLY VINO_PREFS_DIR "/view_only"
#define VINO_PREFS_LOCAL_ONLY VINO_PREFS_DIR "/local_only"
+#define VINO_PREFS_NETWORK_INTERFACE VINO_PREFS_DIR "/network_interface"
#define VINO_PREFS_USE_ALTERNATIVE_PORT VINO_PREFS_DIR "/use_alternative_port"
#define VINO_PREFS_ALTERNATIVE_PORT VINO_PREFS_DIR "/alternative_port"
#define VINO_PREFS_REQUIRE_ENCRYPTION VINO_PREFS_DIR "/require_encryption"
@@ -46,7 +47,7 @@
#define VINO_PREFS_ICON_VISIBILITY VINO_PREFS_DIR "/icon_visibility"
#define VINO_PREFS_DISABLE_BACKGROUND VINO_PREFS_DIR "/disable_background"
-#define VINO_N_LISTENERS 12
+#define VINO_N_LISTENERS 12
static GConfClient *vino_client = NULL;
static GSList *vino_servers = NULL;
@@ -55,7 +56,7 @@
static gboolean vino_enabled = FALSE;
static gboolean vino_prompt_enabled = FALSE;
static gboolean vino_view_only = FALSE;
-static gboolean vino_local_only = FALSE;
+static char *vino_network_interface = NULL;
static gboolean vino_require_encryption = FALSE;
static VinoAuthMethod vino_auth_methods = VINO_AUTH_VNC;
static char *vino_vnc_password = NULL;
@@ -143,27 +144,35 @@
}
static void
-vino_prefs_local_only_changed (GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry)
+vino_prefs_network_interface_changed (GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry)
{
- gboolean local_only;
- GSList *l;
+ const char *network_interface;
+ GSList *l;
- if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
+ if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
return;
- local_only = gconf_value_get_bool (entry->value) != FALSE;
+ network_interface = gconf_value_get_string (entry->value);
- if (vino_local_only == local_only)
+ if (!network_interface && !vino_network_interface)
return;
- vino_local_only = local_only;
+ if (network_interface && vino_network_interface &&
+ !g_strcasecmp (network_interface, vino_network_interface))
+ return;
+
+ if (vino_network_interface)
+ g_free (vino_network_interface);
+
+ vino_network_interface = g_strdup (network_interface);
- dprintf (PREFS, "Local only changed: %s\n", vino_local_only ? "(true)" : "(false)");
+ dprintf (PREFS, "Network Interface for bind() changed: %s\n",
+ vino_network_interface ? vino_network_interface : "(null)");
for (l = vino_servers; l; l = l->next)
- vino_server_set_local_only (l->data, local_only);
+ vino_server_set_network_interface (l->data, network_interface);
}
static void
@@ -438,7 +447,7 @@
server = g_object_new (VINO_TYPE_SERVER,
"prompt-enabled", vino_prompt_enabled,
"view-only", vino_view_only,
- "local-only", vino_local_only,
+ "network-interface", vino_network_interface,
"use-alternative-port", vino_use_alternative_port,
"alternative-port", vino_alternative_port,
"auth-methods", vino_auth_methods,
@@ -446,8 +455,8 @@
"vnc-password", vino_vnc_password,
"on-hold", !vino_enabled,
"screen", screen,
- "lock-screen", vino_lock_screen,
- "disable-background", vino_disable_background,
+ "lock-screen", vino_lock_screen,
+ "disable-background", vino_disable_background,
NULL);
vino_servers = g_slist_prepend (vino_servers, server);
@@ -498,15 +507,23 @@
NULL);
}
dprintf (PREFS, "View only: %s\n", vino_view_only ? "(true)" : "(false)");
-
- vino_local_only = gconf_client_get_bool (vino_client,
- VINO_PREFS_LOCAL_ONLY,
- NULL);
- dprintf (PREFS, "Local only: %s\n", vino_local_only ? "(true)" : "(false)");
+
+ vino_network_interface = gconf_client_get_string (vino_client,
+ VINO_PREFS_NETWORK_INTERFACE,
+ NULL);
+ /* Check for old key, local_only, vino <= 2.24 */
+ if (!vino_network_interface && gconf_client_get_bool (vino_client, VINO_PREFS_LOCAL_ONLY, NULL))
+ {
+ gconf_client_set_string (vino_client, VINO_PREFS_NETWORK_INTERFACE, "lo", NULL);
+ vino_network_interface = g_strdup ("lo");
+ }
+ dprintf (PREFS, "Network interface: %s\n",
+ vino_network_interface ? vino_network_interface : "all");
vino_use_alternative_port = gconf_client_get_bool (vino_client,
VINO_PREFS_USE_ALTERNATIVE_PORT,
NULL);
+
dprintf (PREFS, "Use alternative port: %s\n",
vino_use_alternative_port ? "(true)" : "(false)");
@@ -584,8 +601,8 @@
vino_listeners [i] =
gconf_client_notify_add (vino_client,
- VINO_PREFS_LOCAL_ONLY,
- (GConfClientNotifyFunc) vino_prefs_local_only_changed,
+ VINO_PREFS_NETWORK_INTERFACE,
+ (GConfClientNotifyFunc) vino_prefs_network_interface_changed,
NULL, NULL, NULL);
i++;
@@ -666,7 +683,11 @@
if (vino_vnc_password)
g_free (vino_vnc_password);
vino_vnc_password = NULL;
-
+
+ if (vino_network_interface)
+ g_free (vino_network_interface);
+ vino_network_interface = NULL;
+
for (i = 0; i < VINO_N_LISTENERS; i++) {
if (vino_listeners [i])
gconf_client_notify_remove (vino_client, vino_listeners [i]);
Modified: trunk/server/vino-server.c
==============================================================================
--- trunk/server/vino-server.c (original)
+++ trunk/server/vino-server.c Fri Dec 12 19:58:32 2008
@@ -61,8 +61,8 @@
VinoStatusIcon *icon;
VinoDBusListener *listener;
- GIOChannel *io_channel;
- guint io_watch;
+ GIOChannel *io_channel[RFB_MAX_SOCKETLISTEN];
+ guint io_watch[RFB_MAX_SOCKETLISTEN];
GSList *clients;
@@ -76,7 +76,7 @@
int alternative_port;
guint on_hold : 1;
- guint local_only : 1;
+ char *network_interface;
guint prompt_enabled : 1;
guint view_only : 1;
guint require_encryption : 1;
@@ -106,7 +106,7 @@
PROP_ON_HOLD,
PROP_PROMPT_ENABLED,
PROP_VIEW_ONLY,
- PROP_LOCAL_ONLY,
+ PROP_NETWORK_INTERFACE,
PROP_USE_ALTERNATIVE_PORT,
PROP_ALTERNATIVE_PORT,
PROP_REQUIRE_ENCRYPTION,
@@ -250,8 +250,8 @@
g_source_remove (client->update_timeout);
client->update_timeout = 0;
- if (client->io_watch)
- g_source_remove (client->io_watch);
+ if (client->io_watch)
+ g_source_remove (client->io_watch);
client->io_watch = 0;
g_io_channel_unref (client->io_channel);
@@ -471,7 +471,7 @@
{
g_return_val_if_fail (VINO_IS_SERVER (server), FALSE);
- rfbProcessNewConnection (server->priv->rfb_screen);
+ rfbProcessNewConnection (server->priv->rfb_screen, g_io_channel_unix_get_fd(source));
return TRUE;
}
@@ -843,6 +843,7 @@
rfbScreenInfoPtr rfb_screen;
char *name;
GtkClipboard *cb;
+ int i;
g_return_if_fail (server->priv->screen == NULL);
g_return_if_fail (screen != NULL);
@@ -884,7 +885,7 @@
* 5900-6000
*/
rfb_screen->rfbDeferUpdateTime = 0;
- rfb_screen->localOnly = server->priv->local_only;
+ rfb_screen->netIface = server->priv->network_interface;
rfb_screen->autoPort = TRUE;
rfb_screen->rfbPort = VINO_SERVER_DEFAULT_PORT;
rfb_screen->rfbAlwaysShared = TRUE;
@@ -917,15 +918,18 @@
vino_server_update_security_types (server);
- dprintf (RFB, "Creating watch for listening socket %d - port %d\n",
- rfb_screen->rfbListenSock, rfb_screen->rfbPort);
+ dprintf (RFB, "Creating watch for listening socket [ ");
+ for (i=0; i < rfb_screen->rfbListenSockTotal; i++)
+ {
+ dprintf (RFB, "%d ", rfb_screen->rfbListenSock[i]);
- server->priv->io_channel = g_io_channel_unix_new (rfb_screen->rfbListenSock);
- server->priv->io_watch =
- g_io_add_watch (server->priv->io_channel,
- G_IO_IN|G_IO_PRI,
- (GIOFunc) vino_server_new_connection_pending,
- server);
+ server->priv->io_channel[i] = g_io_channel_unix_new (rfb_screen->rfbListenSock[i]);
+ server->priv->io_watch[i] = g_io_add_watch (server->priv->io_channel[i],
+ G_IO_IN|G_IO_PRI,
+ (GIOFunc) vino_server_new_connection_pending,
+ server);
+ }
+ dprintf(RFB,"]- port %d\n", rfb_screen->rfbPort);
#ifdef VINO_ENABLE_HTTP_SERVER
server->priv->http = vino_http_get (rfb_screen->rfbPort);
@@ -949,7 +953,8 @@
vino_server_finalize (GObject *object)
{
VinoServer *server = VINO_SERVER (object);
-
+ int i;
+
#ifdef VINO_ENABLE_HTTP_SERVER
if (server->priv->http)
{
@@ -960,13 +965,16 @@
server->priv->http = NULL;
#endif /* VINO_ENABLE_HTTP_SERVER */
- if (server->priv->io_watch)
- g_source_remove (server->priv->io_watch);
- server->priv->io_watch = 0;
-
- if (server->priv->io_channel)
- g_io_channel_unref (server->priv->io_channel);
- server->priv->io_channel = NULL;
+ for(i=0; i < server->priv->rfb_screen->rfbListenSockTotal; i++)
+ {
+ if (server->priv->io_watch[i])
+ g_source_remove (server->priv->io_watch[i]);
+ server->priv->io_watch[i] = 0;
+
+ if (server->priv->io_channel[i])
+ g_io_channel_unref (server->priv->io_channel[i]);
+ server->priv->io_channel[i] = NULL;
+ }
if (server->priv->rfb_screen)
rfbScreenCleanup (server->priv->rfb_screen);
@@ -981,6 +989,10 @@
g_free (server->priv->vnc_password);
server->priv->vnc_password = NULL;
+ if(server->priv->network_interface)
+ g_free (server->priv->network_interface);
+ server->priv->network_interface = NULL;
+
if (server->priv->prompt)
g_object_unref (server->priv->prompt);
server->priv->prompt = NULL;
@@ -1030,8 +1042,8 @@
case PROP_VIEW_ONLY:
vino_server_set_view_only (server, g_value_get_boolean (value));
break;
- case PROP_LOCAL_ONLY:
- vino_server_set_local_only (server, g_value_get_boolean (value));
+ case PROP_NETWORK_INTERFACE:
+ vino_server_set_network_interface (server, g_value_get_string (value));
break;
case PROP_REQUIRE_ENCRYPTION:
vino_server_set_require_encryption (server, g_value_get_boolean (value));
@@ -1082,8 +1094,8 @@
case PROP_VIEW_ONLY:
g_value_set_boolean (value, server->priv->view_only);
break;
- case PROP_LOCAL_ONLY:
- g_value_set_boolean (value, server->priv->local_only);
+ case PROP_NETWORK_INTERFACE:
+ g_value_set_string (value, server->priv->network_interface);
break;
case PROP_REQUIRE_ENCRYPTION:
g_value_set_boolean (value, server->priv->require_encryption);
@@ -1181,11 +1193,11 @@
G_PARAM_STATIC_BLURB));
g_object_class_install_property (gobject_class,
- PROP_LOCAL_ONLY,
- g_param_spec_boolean ("local-only",
- "Local Only",
- "Only allow local connections",
- FALSE,
+ PROP_NETWORK_INTERFACE,
+ g_param_spec_string ("network-interface",
+ "Network Interface",
+ "Network interface for accept connections",
+ NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_NAME |
@@ -1368,32 +1380,32 @@
}
}
-gboolean
-vino_server_get_local_only (VinoServer *server)
+G_CONST_RETURN char *
+vino_server_get_network_interface (VinoServer *server)
{
- g_return_val_if_fail (VINO_IS_SERVER (server), FALSE);
-
- return server->priv->local_only;
+ g_return_val_if_fail (VINO_IS_SERVER (server), NULL);
+
+ return server->priv->network_interface;
}
void
-vino_server_set_local_only (VinoServer *server,
- gboolean local_only)
+vino_server_set_network_interface (VinoServer *server,
+ const char *network_interface)
{
g_return_if_fail (VINO_IS_SERVER (server));
- local_only = local_only != FALSE;
+ if (server->priv->network_interface)
+ g_free (server->priv->network_interface);
- if (server->priv->local_only != local_only)
- {
- server->priv->local_only = local_only;
+ if(network_interface != NULL && strlen (network_interface) > 0)
+ server->priv->network_interface = g_strdup (network_interface);
+ else
+ server->priv->network_interface = NULL;
- if (server->priv->rfb_screen != NULL)
- rfbSetLocalOnly (server->priv->rfb_screen,
- server->priv->local_only);
+ if (server->priv->rfb_screen != NULL)
+ rfbSetNetworkInterface (server->priv->rfb_screen, server->priv->network_interface);
- g_object_notify (G_OBJECT (server), "local-only");
- }
+ g_object_notify (G_OBJECT (server), "network-interface");
}
gboolean
Modified: trunk/server/vino-server.h
==============================================================================
--- trunk/server/vino-server.h (original)
+++ trunk/server/vino-server.h Fri Dec 12 19:58:32 2008
@@ -85,9 +85,10 @@
void vino_server_set_alternative_port (VinoServer *server,
int alternative_port);
int vino_server_get_port (VinoServer *server);
-void vino_server_set_local_only (VinoServer *server,
- gboolean local_only);
-gboolean vino_server_get_local_only (VinoServer *server);
+
+void vino_server_set_network_interface (VinoServer *server,
+ const char *network_interface);
+G_CONST_RETURN char *vino_server_get_network_interface (VinoServer *server);
void vino_server_set_require_encryption (VinoServer *server,
gboolean require_encryption);
gboolean vino_server_get_require_encryption (VinoServer *server);
Modified: trunk/server/vino-server.schemas.in
==============================================================================
--- trunk/server/vino-server.schemas.in (original)
+++ trunk/server/vino-server.schemas.in Fri Dec 12 19:58:32 2008
@@ -51,19 +51,18 @@
</schema>
<schema>
- <key>/schemas/desktop/gnome/remote_access/local_only</key>
- <applyto>/desktop/gnome/remote_access/local_only</applyto>
+ <key>/schemas/desktop/gnome/remote_access/network_interface</key>
+ <applyto>/desktop/gnome/remote_access/network_interface</applyto>
<owner>gnome</owner>
- <type>bool</type>
- <default>false</default>
+ <type>string</type>
+ <default></default>
<locale name="C">
- <short>Only allow local connections</short>
+ <short>Settings of network interface using for accept connections</short>
<long>
- If true, the server will only accept connections from
- localhost and network connections will be rejected.
+ If set all, the server will listener in all network interfaces.
- Set this option to true if you wish to exclusively use
- a tunneling mechanism to access the server, such as ssh.
+ Set this if you want that accept connections only from specific
+ network interface. eg: eth0, wifi0, lo, ...
</long>
</locale>
</schema>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]