Hi all, the patch I have attached adds a 15 sec timeout for connection in gnome-remote-shell. Without the timeout, when you try to connect to a server with a firewall that drops the packets received in the ssh or telnet port, the syscall connection is kept blocked forever -- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Carlos Garcia Campos a.k.a. KaL elkalmail yahoo es carlosgc gnome org Grupo Linups Usuarios de SL/Linux de la UPSAM http://www.linups.org =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= PGP key: http://pgp.rediris.es:11371/pks/lookup?op=get&search=0x523E6462
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gnome-network/network-utilities/ChangeLog,v
retrieving revision 1.28
diff -u -u -r1.28 ChangeLog
--- ChangeLog 17 Dec 2003 23:00:12 -0000 1.28
+++ ChangeLog 27 Dec 2003 16:06:49 -0000
@@ -1,3 +1,8 @@
+2003-12-27 Carlos Garcia Campos <carlosgc gnome org>
+
+ * gnome-remote-shell.c (check_network_status): added connection
+ timeout
+
2003-12-17 Mason Kidd <mason_kidd mrkidd com>
* Makefile.am:
Index: gnome-remote-shell.c
===================================================================
RCS file: /cvs/gnome/gnome-network/network-utilities/gnome-remote-shell.c,v
retrieving revision 1.22
diff -u -u -r1.22 gnome-remote-shell.c
--- gnome-remote-shell.c 9 Dec 2003 23:24:32 -0000 1.22
+++ gnome-remote-shell.c 27 Dec 2003 16:06:49 -0000
@@ -27,6 +27,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <fcntl.h>
#include <gconf/gconf-client.h>
#include <gtk/gtkdialog.h>
#include <gtk/gtkentry.h>
@@ -180,69 +181,131 @@
{
struct sockaddr_in *addr;
struct sockaddr_in6 *addr6;
+ struct sockaddr *addr_ptr;
struct hostent *hostname;
- gint sd;
+ gint sd, err, ip_version, pf, size;
+ gint flags, len;
+ fd_set fd;
+ struct timeval *timeout;
gchar *msgerror;
- switch (get_ip_version (host))
+ switch (ip_version = get_ip_version (host))
{
case IPV4:
- hostname = gethostbyname2 (host, AF_INET);
+ pf = PF_INET;
+ break;
+ case IPV6:
+ pf = PF_INET6;
+ break;
+ case -1:
+ default:
+ g_print ("Error: Host unkown\n");
+ return FALSE;
+ }
+ hostname = gethostbyname2 (host, pf);
- addr = (struct sockaddr_in *) g_malloc (sizeof (struct sockaddr_in));
-
- sd = socket (AF_INET, SOCK_STREAM, 0);
- addr->sin_family = AF_INET;
- addr->sin_port = g_htons (port);
- addr->sin_addr = *(struct in_addr *) hostname->h_addr;
-
- errno = 0;
- if (connect (sd, (struct sockaddr *) addr, sizeof (struct sockaddr_in)) != 0) {
- msgerror = (gchar *) strerror (errno);
- msgerror = g_locale_to_utf8 (msgerror, strlen (msgerror), NULL, NULL, NULL);
-
- create_error (_("There is a connection error"), msgerror);
-
- g_free (msgerror);
- g_free (addr);
-
- return FALSE;
- }
- shutdown (sd, 2);
+ if ((sd = socket (pf, SOCK_STREAM, 0)) < 0) {
+ perror ("socket:");
+ return FALSE;
+ }
- g_free (addr);
+ flags = fcntl (sd, F_GETFL, 0);
- break;
- case IPV6:
- hostname = gethostbyname2 (host, PF_INET6);
+ if (fcntl (sd, F_SETFL, flags | O_NONBLOCK) < 0) {
+ perror ("fcntl:");
+ return FALSE;
+ }
+
+ if (ip_version == IPV4) {
+ addr = (struct sockaddr_in *) g_malloc (sizeof (struct sockaddr_in));
+ addr->sin_family = PF_INET;
+ addr->sin_port = g_htons (port);
+ addr->sin_addr = *(struct in_addr *) hostname->h_addr;
+ addr_ptr = (struct sockaddr *) addr;
+ size = sizeof (struct sockaddr_in);
+ } else {
addr6 = (struct sockaddr_in6 *) g_malloc (sizeof (struct sockaddr_in6));
- sd = socket (PF_INET6, SOCK_STREAM, 0);
addr6->sin6_family = PF_INET6;
addr6->sin6_port = g_htons (port);
addr6->sin6_addr = *(struct in6_addr *) hostname->h_addr;
+ addr_ptr = (struct sockaddr *) addr6;
+ size = sizeof (struct sockaddr_in6);
+ }
- errno = 0;
- if (connect (sd, (struct sockaddr *) addr6, sizeof (struct sockaddr_in6)) != 0) {
- msgerror = (gchar *) strerror (errno);
- msgerror = g_locale_to_utf8 (msgerror, strlen (msgerror), NULL, NULL, NULL);
+ errno = 0;
+ err = connect (sd, addr_ptr, size);
+
+ if (err < 0) {
+ if (errno != EINPROGRESS) {
+ msgerror = (gchar *) g_strerror (errno);
create_error (_("There is a connection error"), msgerror);
-
+
g_free (msgerror);
- g_free (addr6);
-
+ g_free (addr_ptr);
+
return FALSE;
}
- shutdown (sd, 2);
+ }
- g_free (addr6);
+ if (fcntl (sd, F_SETFL, flags) < 0) {
+ perror ("fcntl:");
+ return FALSE;
+ }
+
+ FD_ZERO (&fd);
+ FD_SET (sd, &fd);
+
+ timeout = (struct timeval *) g_malloc (sizeof (struct timeval));
+ timeout->tv_sec = 15;
+ timeout->tv_usec = 0;
+
+ errno = 0;
+ err = select (FD_SETSIZE, NULL, &fd, NULL, timeout);
+
+ if (err == 0) {
+ msgerror = g_strdup (_("Connection Timeout"));
+ msgerror = g_locale_to_utf8 (msgerror, strlen (msgerror), NULL, NULL, NULL);
- break;
- case -1:
+ create_error (_("There is a connection error"), msgerror);
+
+ g_free (msgerror);
+ g_free (addr_ptr);
+ g_free (timeout);
+
return FALSE;
}
+
+ len = sizeof (err);
+ if (getsockopt (sd, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
+ msgerror = g_strdup (_("Connection Timeout"));
+ msgerror = g_locale_to_utf8 (msgerror, strlen (msgerror), NULL, NULL, NULL);
+
+ create_error (_("There is a connection error"), msgerror);
+
+ g_free (msgerror);
+ g_free (addr_ptr);
+ g_free (timeout);
+
+ return FALSE;
+ } else if (err != 0) {
+ msgerror = (gchar *) g_strerror (err);
+
+ create_error (_("There is a connection error"), msgerror);
+
+ g_free (msgerror);
+ g_free (addr_ptr);
+ g_free (timeout);
+
+ return FALSE;
+ }
+
+ shutdown (sd, 2);
+
+ g_free (addr_ptr);
+ g_free (timeout);
return TRUE;
}
@@ -338,8 +401,9 @@
if (validate_host (host) == FALSE)
return;
- if (check_network_status (host, port) == FALSE)
+ if (check_network_status (host, port) == FALSE) {
return;
+ }
/*
* Get the terminal preferences from GConf.
Attachment:
signature.asc
Description: Esta parte del mensaje =?ISO-8859-1?Q?est=E1?= firmada digitalmente