gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [libmicrohttpd] branch master updated (51b64e8b -> b7844230


From: gnunet
Subject: [GNUnet-SVN] [libmicrohttpd] branch master updated (51b64e8b -> b7844230)
Date: Sun, 04 Jun 2017 14:07:58 +0200

This is an automated email from the git hooks/post-receive script.

karlson2k pushed a change to branch master
in repository libmicrohttpd.

    from 51b64e8b MHD_connection_mark_closed_(): changed return type to 'bool'
     new 1ab764b2 internal_add_connection(): change one parameter type to 'bool'
     new b65a2210 internal_add_connection(): cosmetics
     new 47e648bd internal_add_connection(): minor refactoring for additional 
error check and minor optimization
     new b93ddc6b MHD_cleanup_connections(): improved thread safety
     new 44a92f9f internal_add_connection(): added missing TLS session deinit 
in case of failure
     new 5c28c2ff internal_add_connection(): improved thread safety in epoll 
mode with 'external' add
     new e720ad45 internal_add_connection(): cosmetics
     new 22c70e2a internal_add_connection(): check for connections limit in 
thread-safe way, thus allowing to really use MHD_add_connection() with 
'internal' polling mode
     new b7844230 MHD_add_connection(): updated doxy to reflect that 
per-IP-limit actually is NOT ignored. Skipping of per-IP-limit could be easily 
implemented by request.

The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 ChangeLog                |  4 +++
 src/include/microhttpd.h |  2 --
 src/microhttpd/daemon.c  | 91 ++++++++++++++++++++++++++++--------------------
 3 files changed, 58 insertions(+), 39 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 11eafd20..657dc286 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Sun Jun 04 15:02:00 MSK 2017
+       Improved thread-safety of MHD_add_connection() and
+       internal_add_connection(), minor optimisations. -EG
+
 Sun May 28 23:26:00 MSK 2017
        Releasing GNU libmicrohttpd 0.9.55. -EG
 
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 40a723d6..02a88d67 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -2189,8 +2189,6 @@ MHD_stop_daemon (struct MHD_Daemon *daemon);
  * this call and must no longer be used directly by the application
  * afterwards.
  *
- * Per-IP connection limits are ignored when using this API.
- *
  * @param daemon daemon that manages the connection
  * @param client_socket socket to manage (MHD will expect
  *        to receive an HTTP request from this socket next).
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 01af990c..455539a9 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -2328,11 +2328,6 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon);
  * this call and must no longer be used directly by the application
  * afterwards.
  *
- * Per-IP connection limits are ignored when using this API.
- *
- * @remark To be called only from thread that process
- * daemon's select()/poll()/etc.
- *
  * @param daemon daemon that manages the connection
  * @param client_socket socket to manage (MHD will expect
  *        to receive an HTTP request from this socket next).
@@ -2351,28 +2346,30 @@ internal_add_connection (struct MHD_Daemon *daemon,
                         MHD_socket client_socket,
                         const struct sockaddr *addr,
                         socklen_t addrlen,
-                        int external_add,
+                        bool external_add,
                         bool non_blck)
 {
   struct MHD_Connection *connection;
   unsigned int i;
-  int eno;
-  struct MHD_Daemon *worker;
+  int eno = 0;
 
-  if (NULL != daemon->worker_pool)
+  /* Direct add to master daemon could happen only with "external" add mode. */
+  EXTRA_CHECK ((NULL == daemon->worker_pool) || (external_add));
+  if ((external_add) && (NULL != daemon->worker_pool))
     {
       /* have a pool, try to find a pool with capacity; we use the
         socket as the initial offset into the pool for load
         balancing */
-      for (i=0;i<daemon->worker_pool_size;i++)
+      for (i = 0; i < daemon->worker_pool_size; ++i)
         {
-          worker = &daemon->worker_pool[(i + client_socket) % 
daemon->worker_pool_size];
+          struct MHD_Daemon * const worker =
+                &daemon->worker_pool[(i + client_socket) % 
daemon->worker_pool_size];
           if (worker->connections < worker->connection_limit)
             return internal_add_connection (worker,
                                             client_socket,
                                             addr,
                                             addrlen,
-                                            external_add,
+                                            true,
                                             non_blck);
         }
       /* all pools are at their connection limit, must refuse */
@@ -2588,12 +2585,27 @@ internal_add_connection (struct MHD_Daemon *daemon,
 
 
   MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+  /* Firm check under lock. */
+  if (daemon->connections >= daemon->connection_limit)
+    {
+      MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
+      /* above connection limit - reject */
+#ifdef HAVE_MESSAGES
+      MHD_DLOG (daemon,
+                _("Server reached connection limit. Closing inbound 
connection.\n"));
+#endif
+#if ENFILE
+      eno = ENFILE;
+#endif
+      goto cleanup;
+    }
+  daemon->connections++;
   if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
-  {
-    XDLL_insert (daemon->normal_timeout_head,
-                 daemon->normal_timeout_tail,
-                 connection);
-  }
+    {
+      XDLL_insert (daemon->normal_timeout_head,
+                   daemon->normal_timeout_tail,
+                   connection);
+    }
   DLL_insert (daemon->connections_head,
              daemon->connections_tail,
              connection);
@@ -2623,21 +2635,11 @@ internal_add_connection (struct MHD_Daemon *daemon,
          goto cleanup;
         }
     }
-  else
-    if ( (MHD_YES == external_add) &&
-        (MHD_ITC_IS_VALID_(daemon->itc)) &&
-        (! MHD_itc_activate_ (daemon->itc, "n")) )
-      {
-#ifdef HAVE_MESSAGES
-       MHD_DLOG (daemon,
-                 _("Failed to signal new connection via inter-thread 
communication channel."));
-#endif
-      }
 #ifdef EPOLL_SUPPORT
   if (0 != (daemon->options & MHD_USE_EPOLL))
     {
-      if (0 == (daemon->options & MHD_USE_TURBO))
-       {
+      if ((0 == (daemon->options & MHD_USE_TURBO)) || (external_add))
+       { /* Do not manipulate EReady DL-list in 'external_add' mode. */
          struct epoll_event event;
 
          event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
@@ -2666,8 +2668,18 @@ internal_add_connection (struct MHD_Daemon *daemon,
                       connection);
        }
     }
+  else /* This 'else' is combined with next 'if'. */
 #endif
-  daemon->connections++;
+  if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
+       (external_add) &&
+       (MHD_ITC_IS_VALID_(daemon->itc)) &&
+       (! MHD_itc_activate_ (daemon->itc, "n")) )
+    {
+#ifdef HAVE_MESSAGES
+      MHD_DLOG (daemon,
+                _("Failed to signal new connection via inter-thread 
communication channel."));
+#endif
+    }
   return MHD_YES;
  cleanup:
   if (NULL != daemon->notify_connection)
@@ -2675,6 +2687,10 @@ internal_add_connection (struct MHD_Daemon *daemon,
                                connection,
                                &connection->socket_context,
                                MHD_CONNECTION_NOTIFY_CLOSED);
+#ifdef HTTPS_SUPPORT
+ if (NULL != connection->tls_session)
+   gnutls_deinit (connection->tls_session);
+#endif /* HTTPS_SUPPORT */
   MHD_socket_close_chk_ (client_socket);
   MHD_ip_limit_del (daemon,
                     addr,
@@ -2693,7 +2709,10 @@ internal_add_connection (struct MHD_Daemon *daemon,
   MHD_pool_destroy (connection->pool);
   free (connection->addr);
   free (connection);
-  errno = eno;
+  if (0 != eno)
+    errno = eno;
+  else
+    errno  = EINVAL;
   return MHD_NO;
 }
 
@@ -2979,8 +2998,6 @@ resume_suspended_connections (struct MHD_Daemon *daemon)
  * this call and must no longer be used directly by the application
  * afterwards.
  *
- * Per-IP connection limits are ignored when using this API.
- *
  * @param daemon daemon that manages the connection
  * @param client_socket socket to manage (MHD will expect
  *        to receive an HTTP request from this socket next).
@@ -3023,7 +3040,7 @@ MHD_add_connection (struct MHD_Daemon *daemon,
                                  client_socket,
                                  addr,
                                   addrlen,
-                                 MHD_YES,
+                                 true,
                                  sk_nonbl);
 }
 
@@ -3153,7 +3170,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
                                   s,
                                  addr,
                                   addrlen,
-                                 MHD_NO,
+                                 false,
                                   sk_nonbl);
   return MHD_YES;
 }
@@ -3193,8 +3210,6 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
       if (NULL != pos->tls_session)
        gnutls_deinit (pos->tls_session);
 #endif /* HTTPS_SUPPORT */
-      daemon->connections--;
-      daemon->at_limit = false;
 
       /* clean up the connection */
       if (NULL != daemon->notify_connection)
@@ -3245,6 +3260,8 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
       free (pos);
 
       MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
+      daemon->connections--;
+      daemon->at_limit = false;
     }
   MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
 }

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

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