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