[Gurlchecker-commits] r759 - in trunk: . src

esaracco at users.labs.libre-entreprise.org esaracco at users.labs.libre-entreprise.org
Thu Jan 28 13:28:33 CET 2010


Author: esaracco
Date: 2010-01-28 12:28:33 +0000 (Thu, 28 Jan 2010)
New Revision: 759

Modified:
   trunk/ChangeLog
   trunk/configure.in
   trunk/src/connection.c
Log:
Rewrote connect_thread function to avoid use of deprecated gethostbyname() function. By the way, it fixed a connection freeze problem when a lot of links were ignored by the end user.


Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2010-01-27 21:25:15 UTC (rev 758)
+++ trunk/ChangeLog	2010-01-28 12:28:33 UTC (rev 759)
@@ -1,3 +1,11 @@
+2010-01-28 Emmanuel Saracco <esaracco at users.labs.libre-entreprise.org>
+
+	* Network:
+
+	  - Rewrote connect_thread function to avoid use of deprecated
+	    gethostbyname() function. By the way, it fixed a connection freeze
+	    problem when a lot of links were ignored by the end user.
+
 2010-01-27 Emmanuel Saracco <esaracco at users.labs.libre-entreprise.org>
 
 	* GUI:

Modified: trunk/configure.in
===================================================================
--- trunk/configure.in	2010-01-27 21:25:15 UTC (rev 758)
+++ trunk/configure.in	2010-01-28 12:28:33 UTC (rev 759)
@@ -2,7 +2,7 @@
 AC_PREREQ(2.54)
 
 AC_INIT(configure.in)
-AM_INIT_AUTOMAKE(gurlchecker, 0.11.2svn2010012702)
+AM_INIT_AUTOMAKE(gurlchecker, 0.11.2svn2010012800)
 AM_CONFIG_HEADER(config.h)
 AC_CONFIG_MACRO_DIR([m4])
 

Modified: trunk/src/connection.c
===================================================================
--- trunk/src/connection.c	2010-01-27 21:25:15 UTC (rev 758)
+++ trunk/src/connection.c	2010-01-28 12:28:33 UTC (rev 759)
@@ -141,7 +141,8 @@
 			    gboolean header_request);
 static void uc_conn_disconnect (UCConn * conn);
 static void uc_conn_free (UCConn **conn);
-static UCTcpStatus connect_nonblock (const gint soc, struct sockaddr_in addr);
+static UCTcpStatus connect_nonblock (const gint soc, struct sockaddr *addr,
+                                     socklen_t addrlen);
 static gboolean uc_conn_timeout_cb (gpointer data);
 
 
@@ -613,6 +614,7 @@
   pthread_exit (NULL);
 }
 
+
 /**
  * connect_nonblock:
  * @soc: Socket to connect.
@@ -623,7 +625,7 @@
  * Returns: #UCTcpStatus of the operation.
  */
 static UCTcpStatus
-connect_nonblock (const gint soc, struct sockaddr_in addr)
+connect_nonblock (const gint soc, struct sockaddr *addr, socklen_t addrlen)
 {
   gint res;
   glong arg;
@@ -632,6 +634,7 @@
   gint valopt;
   socklen_t lon;
 
+
   if ((arg = fcntl (soc, F_GETFL, NULL)) < 0)
     {
       /* g_warning ("Error fcntl(..., F_GETFL) (%s)\n", strerror (errno)); */
@@ -645,7 +648,7 @@
       return UC_TCP_STATUS_ERROR;
     }
 
-  res = connect (soc, (struct sockaddr *) &addr, sizeof (addr));
+  res = connect (soc, addr, addrlen);
   if (res < 0)
     {
       if (errno == EINPROGRESS)
@@ -715,6 +718,7 @@
   return UC_TCP_STATUS_OK;
 }
 
+
 /**
  * connect_thread:
  * @data: a #UCConn object.
@@ -727,73 +731,76 @@
 connect_thread (void *data)
 {
   UCConn *conn = (UCConn *) data;
-  struct hostent *hostent;
-  struct sockaddr_in addr;
+  struct addrinfo hints; 
+  struct addrinfo *res = NULL; 
+  gint err = 0;
   gint *sock = NULL;
-  guint *port = NULL;
+  gchar *port = NULL;
 
+
   if (conn->ftp_passive)
-    {
-      sock = &conn->ftp_passive_socket;
-      port = &conn->ftp_passive_port;
-    }
+  {
+    sock = &conn->ftp_passive_socket;
+    port = g_strdup_printf ("%u", conn->ftp_passive_port);
+  }
   else
-    {
-      sock = &conn->socket;
-      port = &conn->port;
-    }
+  {
+    sock = &conn->socket;
+    port = g_strdup_printf ("%u", conn->port);
+  }
 
-  // FIXME use getaddrinfo here
-  /* resolve hostname (ok if IP) */
-  hostent = gethostbyname ((const char *) conn->hostname);
-  if (!hostent)
-    {
-      /* FIXME conn->tcp_status = UC_TCP_STATUS_BAD_HOSTNAME; */
-      g_warning ("Problem with gethostbyname: %s:%u", conn->hostname, *port);
-      conn->tcp_status = UC_TCP_STATUS_ERROR;
-    }
-  else
-    {
-      memset (&addr, 0, sizeof (struct sockaddr_in));
-      addr.sin_port = htons (*port);
-      addr.sin_family = AF_INET;
-      memcpy (&addr.sin_addr, hostent->h_addr_list[0], hostent->h_length);
+  // Free port at thread exit
+  pthread_cleanup_push (g_free, port);
 
-      /* create socket */
-      if ((*sock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
-	{
-	  g_warning ("Problem with socket creation: %s:%u", conn->hostname,
-		     *port);
-	  conn->tcp_status = UC_TCP_STATUS_ERROR;
-	}
+  memset (&hints, 0, sizeof (hints));
+  hints.ai_socktype = SOCK_STREAM;
+  hints.ai_family = PF_UNSPEC;
 
-      /* connect socket */
-      else if ((conn->tcp_status =
-		connect_nonblock (*sock, addr)) == UC_TCP_STATUS_OK)
-	{
+  if ((err = getaddrinfo (conn->hostname, port, &hints, &res)) != 0 ||
+      res == NULL)
+  {
+    /* FIXME conn->tcp_status = UC_TCP_STATUS_BAD_HOSTNAME; */
+    g_warning ("Problem with getaddrinfo(): %s:%s\n\t-> %s",
+               conn->hostname, port, gai_strerror (err));
+    conn->tcp_status = UC_TCP_STATUS_ERROR;
+  }
+  // TODO check all returned addresses for the hostname
+  else if ((*sock = socket (res->ai_family, res->ai_socktype,
+                            res->ai_protocol)) >= 0)
+  {
+    // Free getaddrinfo result at thread exit
+    pthread_cleanup_push ((void *) freeaddrinfo, res);
+
+    /* connect socket */
+    if ((conn->tcp_status =
+           connect_nonblock (*sock, res->ai_addr,
+                             res->ai_addrlen)) == UC_TCP_STATUS_OK)
+    {
 #ifdef ENABLE_GNUTLS
-	  if (conn->use_gnutls)
-	    {
-	      gint ret = 0;
+      if (conn->use_gnutls)
+      {
+        gint ret = 0;
 
-	      gnutls_transport_set_ptr (conn->session_gnutls,
-					(gnutls_transport_ptr) conn->socket);
-	      do
-		ret = gnutls_handshake (conn->session_gnutls);
-	      while ((ret == GNUTLS_E_AGAIN)
-		     || (ret == GNUTLS_E_INTERRUPTED));
 
-	      if (ret < 0)
-		{
-		  g_warning ("Problem with GNU TLS handshake: %s:%u",
-			     conn->hostname, *port);
-		  conn->tcp_status = UC_TCP_STATUS_ERROR;
-		}
-	    }
+        gnutls_transport_set_ptr (conn->session_gnutls,
+                                   (gnutls_transport_ptr) conn->socket);
+        do
+          ret = gnutls_handshake (conn->session_gnutls);
+        while ((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED));
+
+        if (ret < 0)
+        {
+          g_warning ("Problem with SSL handshake: %s:%s", conn->hostname, port);
+          conn->tcp_status = UC_TCP_STATUS_ERROR;
+        }
+      }
 #endif
-	}
     }
+    pthread_cleanup_pop (1); // freeaddrinfo (res)
+  }
 
+  pthread_cleanup_pop (1); // g_free (port)
+
   if (conn->ftp_passive)
     conn->thread_ftp_end = TRUE;
   else



More information about the Gurlchecker-commits mailing list