gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r11900 - in gnunet/src: include util


From: gnunet
Subject: [GNUnet-SVN] r11900 - in gnunet/src: include util
Date: Wed, 23 Jun 2010 13:58:33 +0200

Author: grothoff
Date: 2010-06-23 13:58:33 +0200 (Wed, 23 Jun 2010)
New Revision: 11900

Modified:
   gnunet/src/include/gnunet_network_lib.h
   gnunet/src/include/gnunet_server_lib.h
   gnunet/src/util/network.c
   gnunet/src/util/server.c
   gnunet/src/util/service.c
Log:
support for systemd style listen fd passing

Modified: gnunet/src/include/gnunet_network_lib.h
===================================================================
--- gnunet/src/include/gnunet_network_lib.h     2010-06-23 11:41:46 UTC (rev 
11899)
+++ gnunet/src/include/gnunet_network_lib.h     2010-06-23 11:58:33 UTC (rev 
11900)
@@ -72,6 +72,16 @@
 
 
 /**
+ * Box a native socket (and check that it is a socket).
+ *
+ * @param fd socket to box
+ * @return NULL on error (including not supported on target platform)
+ */
+struct GNUNET_NETWORK_Handle *
+GNUNET_NETWORK_socket_box_native (int fd);
+
+
+/**
  * Bind to a connected socket
  *
  * @param desc socket to bind

Modified: gnunet/src/include/gnunet_server_lib.h
===================================================================
--- gnunet/src/include/gnunet_server_lib.h      2010-06-23 11:41:46 UTC (rev 
11899)
+++ gnunet/src/include/gnunet_server_lib.h      2010-06-23 11:58:33 UTC (rev 
11900)
@@ -114,6 +114,29 @@
  * @param sched scheduler to use
  * @param access function for access control
  * @param access_cls closure for access
+ * @param lsocks NULL-terminated array of listen sockets
+ * @param maxbuf maximum write buffer size for accepted sockets
+ * @param idle_timeout after how long should we timeout idle connections?
+ * @param require_found if YES, connections sending messages of unknown type
+ *        will be closed
+ * @return handle for the new server, NULL on error
+ *         (typically, "port" already in use)
+ */
+struct GNUNET_SERVER_Handle *
+GNUNET_SERVER_create_with_sockets (struct GNUNET_SCHEDULER_Handle *sched,
+                                  GNUNET_CONNECTION_AccessCheck access, void 
*access_cls,
+                                  struct GNUNET_NETWORK_Handle **lsocks,
+                                  size_t maxbuf,
+                                  struct GNUNET_TIME_Relative
+                                  idle_timeout,
+                                  int require_found);
+
+/**
+ * Create a new server.
+ *
+ * @param sched scheduler to use
+ * @param access function for access control
+ * @param access_cls closure for access
  * @param serverAddr address toes listen on (including port), NULL terminated 
array
  * @param socklen lengths of respective serverAddr 
  * @param maxbuf maximum write buffer size for accepted sockets

Modified: gnunet/src/util/network.c
===================================================================
--- gnunet/src/util/network.c   2010-06-23 11:41:46 UTC (rev 11899)
+++ gnunet/src/util/network.c   2010-06-23 11:58:33 UTC (rev 11900)
@@ -308,6 +308,29 @@
 
 
 /**
+ * Box a native socket (and check that it is a socket).
+ *
+ * @param fd socket to box
+ * @return NULL on error (including not supported on target platform)
+ */
+struct GNUNET_NETWORK_Handle *
+GNUNET_NETWORK_socket_box_native (int fd)
+{
+#if MINGW
+  return NULL;
+#else
+  struct GNUNET_NETWORK_Handle *ret;
+
+  if (fcntl (fd, F_GETFD) < 0)
+    return NULL; /* invalid FD */
+  ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle)); 
+  ret->fd = fd;
+  return ret;
+#endif
+}
+
+
+/**
  * Connect a socket
  * @param desc socket
  * @param address peer address

Modified: gnunet/src/util/server.c
===================================================================
--- gnunet/src/util/server.c    2010-06-23 11:41:46 UTC (rev 11899)
+++ gnunet/src/util/server.c    2010-06-23 11:58:33 UTC (rev 11900)
@@ -395,6 +395,60 @@
  * @param sched scheduler to use
  * @param access function for access control
  * @param access_cls closure for access
+ * @param lsocks NULL-terminated array of listen sockets
+ * @param maxbuf maximum write buffer size for accepted sockets
+ * @param idle_timeout after how long should we timeout idle connections?
+ * @param require_found if YES, connections sending messages of unknown type
+ *        will be closed
+ * @return handle for the new server, NULL on error
+ *         (typically, "port" already in use)
+ */
+struct GNUNET_SERVER_Handle *
+GNUNET_SERVER_create_with_sockets (struct GNUNET_SCHEDULER_Handle *sched,
+                                  GNUNET_CONNECTION_AccessCheck access, void 
*access_cls,
+                                  struct GNUNET_NETWORK_Handle **lsocks,
+                                  size_t maxbuf,
+                                  struct GNUNET_TIME_Relative
+                                  idle_timeout,
+                                  int require_found)
+{
+  struct GNUNET_SERVER_Handle *ret;
+  struct GNUNET_NETWORK_FDSet *r;
+  int i;
+
+  ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle));
+  ret->sched = sched;
+  ret->maxbuf = maxbuf;
+  ret->idle_timeout = idle_timeout;
+  ret->listen_sockets = lsocks;
+  ret->access = access;
+  ret->access_cls = access_cls;
+  ret->require_found = require_found;
+  if (lsocks != NULL)
+    {
+      r = GNUNET_NETWORK_fdset_create ();
+      i = 0;
+      while (NULL != ret->listen_sockets[i])
+        GNUNET_NETWORK_fdset_set (r, ret->listen_sockets[i++]);
+      ret->listen_task = GNUNET_SCHEDULER_add_select (sched,
+                                                      
GNUNET_SCHEDULER_PRIORITY_HIGH,
+                                                      GNUNET_SCHEDULER_NO_TASK,
+                                                      
GNUNET_TIME_UNIT_FOREVER_REL,
+                                                      r, NULL,
+                                                      &process_listen_socket,
+                                                      ret);
+      GNUNET_NETWORK_fdset_destroy (r);
+    }
+  return ret;
+}
+
+
+/**
+ * Create a new server.
+ *
+ * @param sched scheduler to use
+ * @param access function for access control
+ * @param access_cls closure for access
  * @param serverAddr address to listen on (including port), NULL terminated 
array
  * @param socklen length of serverAddr
  * @param maxbuf maximum write buffer size for accepted sockets
@@ -414,9 +468,7 @@
                       struct GNUNET_TIME_Relative
                       idle_timeout, int require_found)
 {
-  struct GNUNET_SERVER_Handle *ret;
   struct GNUNET_NETWORK_Handle **lsocks;
-  struct GNUNET_NETWORK_FDSet *r;
   unsigned int i;
   unsigned int j;
 
@@ -448,30 +500,12 @@
     {
       lsocks = NULL;
     }
-  ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle));
-  ret->sched = sched;
-  ret->maxbuf = maxbuf;
-  ret->idle_timeout = idle_timeout;
-  ret->listen_sockets = lsocks;
-  ret->access = access;
-  ret->access_cls = access_cls;
-  ret->require_found = require_found;
-  if (lsocks != NULL)
-    {
-      r = GNUNET_NETWORK_fdset_create ();
-      i = 0;
-      while (NULL != ret->listen_sockets[i])
-        GNUNET_NETWORK_fdset_set (r, ret->listen_sockets[i++]);
-      ret->listen_task = GNUNET_SCHEDULER_add_select (sched,
-                                                      
GNUNET_SCHEDULER_PRIORITY_HIGH,
-                                                      GNUNET_SCHEDULER_NO_TASK,
-                                                      
GNUNET_TIME_UNIT_FOREVER_REL,
-                                                      r, NULL,
-                                                      &process_listen_socket,
-                                                      ret);
-      GNUNET_NETWORK_fdset_destroy (r);
-    }
-  return ret;
+  return GNUNET_SERVER_create_with_sockets (sched,
+                                           access, access_cls,
+                                           lsocks,
+                                           maxbuf, 
+                                           idle_timeout,
+                                           require_found);
 }
 
 

Modified: gnunet/src/util/service.c
===================================================================
--- gnunet/src/util/service.c   2010-06-23 11:41:46 UTC (rev 11899)
+++ gnunet/src/util/service.c   2010-06-23 11:58:33 UTC (rev 11900)
@@ -435,7 +435,8 @@
   struct GNUNET_SCHEDULER_Handle *sched;
 
   /**
-   * NULL-terminated array of addresses to bind to.
+   * NULL-terminated array of addresses to bind to, NULL if we got pre-bound
+   * listen sockets.
    */
   struct sockaddr **addrs;
 
@@ -483,6 +484,16 @@
   struct GNUNET_SERVER_MessageHandler *my_handlers;
 
   /**
+   * Array of the lengths of the entries in addrs.
+   */
+  socklen_t * addrlens;
+
+  /**
+   * NULL-terminated array of listen sockets we should take over.
+   */
+  struct GNUNET_NETWORK_Handle **lsocks;
+
+  /**
    * Idle timeout for server.
    */
   struct GNUNET_TIME_Relative timeout;
@@ -515,11 +526,6 @@
    */
   enum GNUNET_SERVICE_Options options;
 
-  /**
-   * Array of the lengths of the entries in addrs.
-   */
-  socklen_t * addrlens;
-
 };
 
 
@@ -1085,6 +1091,11 @@
   unsigned long long maxbuf;
   struct GNUNET_TIME_Relative idleout;
   int tolerant;
+  const char *lpid;
+  unsigned int pid;
+  const char *nfds;
+  unsigned int cnt;
+  int flags;
 
   if (GNUNET_CONFIGURATION_have_value (sctx->cfg,
                                        sctx->serviceName, "TIMEOUT"))
@@ -1140,11 +1151,45 @@
   else
     tolerant = GNUNET_NO;
 
-  if (GNUNET_SYSERR ==
-      GNUNET_SERVICE_get_server_addresses (sctx->serviceName,
-                                          sctx->cfg,
-                                          &sctx->addrs,
-                                          &sctx->addrlens))
+#ifndef MINGW
+  errno = 0;
+  if ( (NULL != (lpid = getenv ("LISTEN_PID"))) &&
+       (1 == sscanf ("%u", lpid, &pid)) &&
+       (getpid () == (pid_t) pid) &&
+       (NULL != (nfds = getenv ("LISTEN_FDS"))) &&
+       (1 == sscanf ("%u", nfds, &cnt)) &&
+       (cnt > 0) )
+    {
+      sctx->lsocks = GNUNET_malloc (sizeof(struct GNUNET_NETWORK_Handle*) * 
(cnt+1));
+      while (0 < cnt--)
+       {
+         flags = fcntl (3 + cnt, F_GETFD);      
+         if ( (flags < 0) ||
+              (0 != (flags & FD_CLOEXEC)) ||
+              (NULL == (sctx->lsocks[cnt] = GNUNET_NETWORK_socket_box_native 
(3 + cnt))) )
+           {
+             GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                         _("Could not access pre-bound socket %u, will try to 
bind myself\n"),
+                         (unsigned int) 3 +cnt);
+             cnt++;
+             while (sctx->lsocks[cnt] != NULL)
+               GNUNET_NETWORK_socket_close (sctx->lsocks[cnt++]);
+             GNUNET_free (sctx->lsocks);
+             sctx->lsocks = NULL;
+             break;
+           }
+       }
+      unsetenv ("LISTEN_PID");
+      unsetenv ("LISTEN_FDS");
+    }
+#endif
+
+  if ( (sctx->lsocks == NULL) &&
+       (GNUNET_SYSERR ==
+       GNUNET_SERVICE_get_server_addresses (sctx->serviceName,
+                                            sctx->cfg,
+                                            &sctx->addrs,
+                                            &sctx->addrlens)) )
     return GNUNET_SYSERR;
   sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
   sctx->maxbuf = (size_t) maxbuf;
@@ -1265,23 +1310,34 @@
   unsigned int i;
 
   sctx->sched = tc->sched;
-  sctx->server = GNUNET_SERVER_create (tc->sched,
-                                       &check_access,
-                                       sctx,
-                                       sctx->addrs,
-                                       sctx->addrlens,
-                                       sctx->maxbuf,
-                                       sctx->timeout, sctx->require_found);
+  if (sctx->lsocks != NULL)
+    sctx->server = GNUNET_SERVER_create_with_sockets (tc->sched,
+                                                     &check_access,
+                                                     sctx,
+                                                     sctx->lsocks,
+                                                     sctx->maxbuf,
+                                                     sctx->timeout, 
sctx->require_found);
+  else
+    sctx->server = GNUNET_SERVER_create (tc->sched,
+                                        &check_access,
+                                        sctx,
+                                        sctx->addrs,
+                                        sctx->addrlens,
+                                        sctx->maxbuf,
+                                        sctx->timeout, sctx->require_found);
   if (sctx->server == NULL)
     {
-      i = 0;
-      while (sctx->addrs[i] != NULL)
+      if (sctx->addrs != NULL)
        {
-         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                     _("Failed to start `%s' at `%s'\n"),
-                     sctx->serviceName, 
-                     GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
-         i++;
+         i = 0;
+         while (sctx->addrs[i] != NULL)
+           {
+             GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                         _("Failed to start `%s' at `%s'\n"),
+                         sctx->serviceName, 
+                         GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
+             i++;
+           }
        }
       sctx->ret = GNUNET_SYSERR;
       return;
@@ -1307,14 +1363,17 @@
       sctx->ready_confirm_fd = -1;
       write_pid_file (sctx, getpid ());
     }
-  i = 0;
-  while (sctx->addrs[i] != NULL)
+  if (sctx->addrs != NULL)
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                 _("Service `%s' runs at %s\n"),
-                 sctx->serviceName, 
-                 GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
-      i++;
+      i = 0;
+      while (sctx->addrs[i] != NULL)
+       {
+         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                     _("Service `%s' runs at %s\n"),
+                     sctx->serviceName, 
+                     GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
+         i++;
+       }
     }
   sctx->task (sctx->task_cls, tc->sched, sctx->server, sctx->cfg);
 }
@@ -1594,19 +1653,33 @@
   sctx->sched = sched;
 
   /* setup subsystems */
-  if ((GNUNET_OK != setup_service (sctx)) ||
-      (NULL == (sctx->server = GNUNET_SERVER_create (sched,
-                                                     &check_access,
-                                                     sctx,
-                                                     sctx->addrs,
-                                                     sctx->addrlens,
-                                                     sctx->maxbuf,
-                                                     sctx->timeout,
-                                                     sctx->require_found))))
+  if (GNUNET_OK != setup_service (sctx))
     {
       GNUNET_SERVICE_stop (sctx);
       return NULL;
     }
+  if (sctx->lsocks != NULL)
+    sctx->server = GNUNET_SERVER_create_with_sockets (sched,
+                                                     &check_access,
+                                                     sctx,
+                                                     sctx->lsocks,
+                                                     sctx->maxbuf,
+                                                     sctx->timeout, 
sctx->require_found);
+  else
+    sctx->server = GNUNET_SERVER_create (sched,
+                                        &check_access,
+                                        sctx,
+                                        sctx->addrs,
+                                        sctx->addrlens,
+                                        sctx->maxbuf,
+                                        sctx->timeout,
+                                        sctx->require_found);
+                                        
+  if (NULL == sctx->server)
+    {
+      GNUNET_SERVICE_stop (sctx);
+      return NULL;
+    }
   sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
   memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
   i = 0;
@@ -1642,10 +1715,13 @@
   if (NULL != sctx->server)
     GNUNET_SERVER_destroy (sctx->server);
   GNUNET_free_non_null (sctx->my_handlers);
-  i = 0;
-  while (sctx->addrs[i] != NULL)    
-    GNUNET_free (sctx->addrs[i++]);    
-  GNUNET_free (sctx->addrs);
+  if (sctx->addrs != NULL)
+    {
+      i = 0;
+      while (sctx->addrs[i] != NULL)    
+       GNUNET_free (sctx->addrs[i++]);    
+      GNUNET_free (sctx->addrs);
+    }
   GNUNET_free_non_null (sctx->addrlens);
   GNUNET_free_non_null (sctx->v4_denied);
   GNUNET_free_non_null (sctx->v6_denied);




reply via email to

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