gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r16442 - in gnunet/src: arm transport util


From: gnunet
Subject: [GNUnet-SVN] r16442 - in gnunet/src: arm transport util
Date: Thu, 11 Aug 2011 13:05:35 +0200

Author: grothoff
Date: 2011-08-11 13:05:35 +0200 (Thu, 11 Aug 2011)
New Revision: 16442

Modified:
   gnunet/src/arm/arm_api.c
   gnunet/src/arm/gnunet-arm.c
   gnunet/src/transport/Makefile.am
   gnunet/src/util/client.c
   gnunet/src/util/network.c
Log:
use bind instead of connect to test if service is running to avoid long 
timeouts during startup

Modified: gnunet/src/arm/arm_api.c
===================================================================
--- gnunet/src/arm/arm_api.c    2011-08-11 09:43:35 UTC (rev 16441)
+++ gnunet/src/arm/arm_api.c    2011-08-11 11:05:35 UTC (rev 16442)
@@ -379,8 +379,6 @@
              "Looks like `%s' is not running, will start it.\n",
              "gnunet-service-arm");
 #endif
-  /* FIXME: should we check that HOSTNAME for 'arm' is localhost? */
-
  if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_string (pos->h->cfg,
                                             "arm", "PREFIX", &loprefix))
@@ -621,6 +619,7 @@
   struct RequestContext *sctx;
   struct GNUNET_CLIENT_Connection *client;
   size_t slen;
+
 #if DEBUG_ARM
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               _("Asked to start service `%s' within %llu ms\n"), service_name,

Modified: gnunet/src/arm/gnunet-arm.c
===================================================================
--- gnunet/src/arm/gnunet-arm.c 2011-08-11 09:43:35 UTC (rev 16441)
+++ gnunet/src/arm/gnunet-arm.c 2011-08-11 11:05:35 UTC (rev 16442)
@@ -46,7 +46,7 @@
  * (by checking if running before starting, so really this time is always 
waited on
  * startup (annoying)).
  */
-#define START_TIMEOUT GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_MILLISECONDS, 1000)
+#define START_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 
1)
 
 /**
  * Timeout for starting services, very short because of the strange way start 
works

Modified: gnunet/src/transport/Makefile.am
===================================================================
--- gnunet/src/transport/Makefile.am    2011-08-11 09:43:35 UTC (rev 16441)
+++ gnunet/src/transport/Makefile.am    2011-08-11 11:05:35 UTC (rev 16442)
@@ -333,6 +333,7 @@
  test_transport_api_disconnect.c
 test_transport_api_disconnect_LDADD = \
  $(top_builddir)/src/transport/libgnunettransport.la \
+ $(top_builddir)/src/hello/libgnunethello.la \
  $(top_builddir)/src/statistics/libgnunetstatistics.la \
  $(top_builddir)/src/testing/libgnunettesting.la \
  $(top_builddir)/src/util/libgnunetutil.la 

Modified: gnunet/src/util/client.c
===================================================================
--- gnunet/src/util/client.c    2011-08-11 09:43:35 UTC (rev 16441)
+++ gnunet/src/util/client.c    2011-08-11 11:05:35 UTC (rev 16442)
@@ -666,6 +666,15 @@
 }
 
 
+/**
+ * Send the 'TEST' message to the service.  If successful, prepare to
+ * receive the reply.
+ *
+ * @param cls the 'struct GNUNET_CLIENT_Connection' of the connection to test
+ * @param size number of bytes available in buf
+ * @param buf where to write the message
+ * @return number of bytes written to buf
+ */
 static size_t
 write_test (void *cls, size_t size, void *buf)
 {
@@ -698,11 +707,13 @@
 
 
 /**
- * Wait until the service is running.
+ * Test if the service is running.  If we are given a UNIXPATH or a local 
address,
+ * we do this NOT by trying to connect to the service, but by trying to BIND to
+ * the same port.  If the BIND fails, we know the service is running.
  *
  * @param service name of the service to wait for
  * @param cfg configuration to use
- * @param timeout how long to wait at most in ms
+ * @param timeout how long to wait at most 
  * @param task task to run if service is running
  *        (reason will be "PREREQ_DONE" (service running)
  *         or "TIMEOUT" (service not known to be running))
@@ -714,12 +725,171 @@
                             struct GNUNET_TIME_Relative timeout,
                             GNUNET_SCHEDULER_Task task, void *task_cls)
 {
+  char *hostname;
+  unsigned long long port;
+  struct GNUNET_NETWORK_Handle *sock;
   struct GNUNET_CLIENT_Connection *conn;
 
 #if DEBUG_CLIENT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Testing if service `%s' is running.\n", service);
 #endif
+#ifdef AF_UNIX
+  {
+    /* probe UNIX support */
+    struct sockaddr_un s_un;
+    size_t slen;
+    char *unixpath;
+    
+    unixpath = NULL;
+    if ( (GNUNET_OK ==
+         GNUNET_CONFIGURATION_get_value_string (cfg,
+                                                service,
+                                                "UNIXPATH", &unixpath)) &&
+        (0 < strlen (unixpath)) ) /* We have a non-NULL unixpath, does that 
mean it's valid? */
+      {
+       if (strlen(unixpath) >= sizeof(s_un.sun_path))
+         {
+           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                       _("UNIXPATH `%s' too long, maximum length is %llu\n"),
+                       unixpath, 
+                       sizeof(s_un.sun_path));
+         }
+       else
+         {
+           sock =  GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0);
+           if (sock != NULL)
+             {
+               memset (&s_un, 0, sizeof (s_un));
+               s_un.sun_family = AF_UNIX;
+               slen = strlen (unixpath) + 1;
+               if (slen >= sizeof (s_un.sun_path))
+                 slen = sizeof (s_un.sun_path) - 1;
+               memcpy (s_un.sun_path,
+                       unixpath,
+                       slen);
+               s_un.sun_path[slen] = '\0';
+               slen = sizeof (struct sockaddr_un);
+#if LINUX
+               s_un.sun_path[0] = '\0';
+#endif
+#if HAVE_SOCKADDR_IN_SIN_LEN
+               s_un.sun_len = (u_char) slen;
+#endif
+               if (GNUNET_OK !=
+                   GNUNET_NETWORK_socket_bind (sock,
+                                               (const struct sockaddr*) &s_un,
+                                               slen))
+                 {
+                   /* failed to bind => service must be running */
+                   GNUNET_free (unixpath);
+                   (void) GNUNET_NETWORK_socket_close (sock);
+                   GNUNET_SCHEDULER_add_continuation (task,
+                                                      task_cls,
+                                                      
GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+                   return;
+                 }
+               (void) GNUNET_NETWORK_socket_close (sock);
+             }
+           /* let's try IP */
+         }
+      }
+    GNUNET_free_non_null (unixpath);
+  }
+#endif
+
+  hostname = NULL;
+  if ((GNUNET_OK !=
+       GNUNET_CONFIGURATION_get_value_number (cfg,
+                                              service,
+                                              "PORT",
+                                              &port)) ||
+      (port > 65535) ||
+      (GNUNET_OK !=
+       GNUNET_CONFIGURATION_get_value_string (cfg,
+                                              service,
+                                              "HOSTNAME", &hostname)))
+    {
+      /* UNIXPATH failed (if possible) AND IP failed => error */
+      service_test_error (task, task_cls);
+      return;
+    }
+  
+  if (0 == strcmp ("localhost", hostname)) 
+    {
+      /* can test using 'bind' */
+      struct sockaddr_in s_in;
+      
+      memset (&s_in, 0, sizeof (s_in));
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      s_in.sin_len = saddrlens[1];
+#endif
+      s_in.sin_family = AF_INET;
+      s_in.sin_port = htons (port);
+
+      sock =  GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
+      if (sock != NULL)
+       {
+         if (GNUNET_OK !=
+             GNUNET_NETWORK_socket_bind (sock,
+                                         (const struct sockaddr*) &s_in,
+                                         sizeof (s_in)))
+           {
+             /* failed to bind => service must be running */
+             GNUNET_free (hostname);
+             (void) GNUNET_NETWORK_socket_close (sock);
+             GNUNET_SCHEDULER_add_continuation (task,
+                                                task_cls,
+                                                
GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+             return;
+           }
+         (void) GNUNET_NETWORK_socket_close (sock);
+       }        
+    }
+
+  if (0 == strcmp ("ip6-localhost", hostname)) 
+    {
+      /* can test using 'bind' */
+      struct sockaddr_in6 s_in6;
+      
+      memset (&s_in6, 0, sizeof (s_in6));
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      s_in6.sin6_len = saddrlens[1];
+#endif
+      s_in6.sin6_family = AF_INET6;
+      s_in6.sin6_port = htons (port);
+
+      sock =  GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0);
+      if (sock != NULL)
+       {
+         if (GNUNET_OK !=
+             GNUNET_NETWORK_socket_bind (sock,
+                                         (const struct sockaddr*) &s_in6,
+                                         sizeof (s_in6)))
+           {
+             /* failed to bind => service must be running */
+             GNUNET_free (hostname);
+             (void) GNUNET_NETWORK_socket_close (sock);
+             GNUNET_SCHEDULER_add_continuation (task,
+                                                task_cls,
+                                                
GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+             return;
+           }
+         (void) GNUNET_NETWORK_socket_close (sock);
+       }        
+    }
+
+  if ( (0 == strcmp ("localhost", hostname)) ||
+       (0 == strcmp ("ip6-localhost", hostname)) )
+    {
+      /* all binds succeeded => claim service not running right now */
+      GNUNET_free_non_null (hostname);
+      service_test_error (task, task_cls);
+      return;
+    }   
+  GNUNET_free_non_null (hostname);
+
+  /* non-localhost, try 'connect' method */
   conn = GNUNET_CLIENT_connect (service, cfg);
   if (conn == NULL)
     {

Modified: gnunet/src/util/network.c
===================================================================
--- gnunet/src/util/network.c   2011-08-11 09:43:35 UTC (rev 16441)
+++ gnunet/src/util/network.c   2011-08-11 11:05:35 UTC (rev 16442)
@@ -321,7 +321,7 @@
     SetErrnoFromWinsockError (WSAGetLastError ());
 #endif
   if (ret != 0)
-         return GNUNET_SYSERR;
+    return GNUNET_SYSERR;
 #ifndef MINGW
 #ifndef LINUX
   desc->addr = GNUNET_malloc (address_len);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]