gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [libmicrohttpd] branch master updated (1aaff725 -> bafd0789


From: gnunet
Subject: [GNUnet-SVN] [libmicrohttpd] branch master updated (1aaff725 -> bafd0789)
Date: Mon, 29 Jul 2019 20:05:01 +0200

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

grothoff pushed a change to branch master
in repository libmicrohttpd.

    from 1aaff725 is this year
     new 40bf201d indentation fixes, adding test_upgrade_large.c test for issue 
reported by Viet
     new 9c15b24f ensure event loop keeps going in test, and indentation fixes
     new bafd0789 fix hang reported by Viet on 24.6.2019 on the mailinglist: do 
not just consider nested epoll, but also already ready connections

The 3 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                                          |   5 +
 src/include/microhttpd.h                           |   2 +-
 src/microhttpd/.gitignore                          |   2 +
 src/microhttpd/Makefile.am                         |  34 ++-
 src/microhttpd/daemon.c                            | 281 +++++++++++----------
 src/microhttpd/response.c                          |  88 +++----
 .../{test_upgrade.c => test_upgrade_large.c}       |  79 ++++--
 7 files changed, 283 insertions(+), 208 deletions(-)
 copy src/microhttpd/{test_upgrade.c => test_upgrade_large.c} (93%)

diff --git a/ChangeLog b/ChangeLog
index c45326df..b4c065c8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Mon 29 Jul 2019 08:01:50 PM CEST
+    Fix hanging situation with large transmission over upgraded
+    (i.e. Web socket) connection with epoll() and HTTPS enabled
+    (as reported by Viet on the mailinglist). -CG
+
 Thu 25 Jul 2019 02:40:12 PM CEST
     Fixing regression introduced in cc5032b85 (bit mask matching
     of the header kinds in MHD_lookup_connection_value()), as
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 4c05ffac..f141967c 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -132,7 +132,7 @@ typedef intptr_t ssize_t;
  * Current version of the library.
  * 0x01093001 = 1.9.30-1.
  */
-#define MHD_VERSION 0x00096503
+#define MHD_VERSION 0x00096504
 
 /**
  * MHD-internal return code for "YES".
diff --git a/src/microhttpd/.gitignore b/src/microhttpd/.gitignore
index ec2e027d..611f88ec 100644
--- a/src/microhttpd/.gitignore
+++ b/src/microhttpd/.gitignore
@@ -57,3 +57,5 @@ test_shutdown_poll
 test_shutdown_select
 test_md5
 test_sha256
+test_upgrade_large
+test_upgrade_large_tls
diff --git a/src/microhttpd/Makefile.am b/src/microhttpd/Makefile.am
index 3fb65fe1..8bc60879 100644
--- a/src/microhttpd/Makefile.am
+++ b/src/microhttpd/Makefile.am
@@ -165,17 +165,17 @@ check_PROGRAMS = \
 if HAVE_POSIX_THREADS
 if ENABLE_UPGRADE
 if USE_POSIX_THREADS
-  check_PROGRAMS += test_upgrade
+  check_PROGRAMS += test_upgrade test_upgrade_large
 endif
 if USE_W32_THREADS
-  check_PROGRAMS += test_upgrade
+  check_PROGRAMS += test_upgrade test_upgrade_large
 endif
 if ENABLE_HTTPS
 if USE_POSIX_THREADS
-check_PROGRAMS += test_upgrade_tls
+check_PROGRAMS += test_upgrade_tls test_upgrade_large_tls
 endif
 if USE_W32_THREADS
-check_PROGRAMS += test_upgrade_tls
+check_PROGRAMS += test_upgrade_tls test_upgrade_large_tls
 endif
 endif
 endif
@@ -230,6 +230,19 @@ test_upgrade_LDADD = \
   $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) \
   $(PTHREAD_LIBS)
 
+test_upgrade_large_SOURCES = \
+  test_upgrade_large.c test_helpers.h mhd_sockets.h
+test_upgrade_large_CPPFLAGS = \
+  $(AM_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS)
+test_upgrade_large_CFLAGS = \
+  $(AM_CFLAGS) $(PTHREAD_CFLAGS) $(MHD_TLS_LIB_CFLAGS)
+test_upgrade_large_LDFLAGS = \
+  $(MHD_TLS_LIB_LDFLAGS)
+test_upgrade_large_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) \
+  $(PTHREAD_LIBS)
+
 test_upgrade_tls_SOURCES = \
   test_upgrade.c test_helpers.h mhd_sockets.h
 test_upgrade_tls_CPPFLAGS = \
@@ -243,6 +256,19 @@ test_upgrade_tls_LDADD = \
   $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) \
   $(PTHREAD_LIBS)
 
+test_upgrade_large_tls_SOURCES = \
+  test_upgrade_large.c test_helpers.h mhd_sockets.h
+test_upgrade_large_tls_CPPFLAGS = \
+  $(AM_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS)
+test_upgrade_large_tls_CFLAGS = \
+  $(AM_CFLAGS) $(PTHREAD_CFLAGS) $(MHD_TLS_LIB_CFLAGS)
+test_upgrade_large_tls_LDFLAGS = \
+  $(MHD_TLS_LIB_LDFLAGS)
+test_upgrade_large_tls_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(MHD_TLS_LIB_LDFLAGS) $(MHD_TLS_LIBDEPS) \
+  $(PTHREAD_LIBS)
+
 test_postprocessor_SOURCES = \
   test_postprocessor.c
 test_postprocessor_CPPFLAGS = \
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index b312c305..bf01ba9b 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -721,8 +721,8 @@ int
 MHD_get_fdset (struct MHD_Daemon *daemon,
                fd_set *read_fd_set,
                fd_set *write_fd_set,
-              fd_set *except_fd_set,
-              MHD_socket *max_fd)
+               fd_set *except_fd_set,
+               MHD_socket *max_fd)
 {
   return MHD_get_fdset2 (daemon,
                          read_fd_set,
@@ -2344,11 +2344,11 @@ psk_gnutls_adapter (gnutls_session_t session,
  */
 static int
 internal_add_connection (struct MHD_Daemon *daemon,
-                        MHD_socket client_socket,
-                        const struct sockaddr *addr,
-                        socklen_t addrlen,
-                        bool external_add,
-                        bool non_blck)
+                         MHD_socket client_socket,
+                         const struct sockaddr *addr,
+                         socklen_t addrlen,
+                         bool external_add,
+                         bool non_blck)
 {
   struct MHD_Connection *connection;
 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
@@ -2362,8 +2362,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
   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 */
+         socket as the initial offset into the pool for load
+         balancing */
       for (i = 0; i < daemon->worker_pool_size; ++i)
         {
           struct MHD_Daemon * const worker =
@@ -2448,7 +2448,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
   /* apply connection acceptance policy if present */
   if ( (NULL != daemon->apc) &&
        (MHD_NO == daemon->apc (daemon->apc_cls,
-                              addr,
+                               addr,
                                addrlen)) )
     {
 #if DEBUG_CLOSE
@@ -2472,8 +2472,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
       eno = errno;
 #ifdef HAVE_MESSAGES
       MHD_DLOG (daemon,
-               "Error allocating memory: %s\n",
-               MHD_strerror_ (errno));
+                "Error allocating memory: %s\n",
+                MHD_strerror_ (errno));
 #endif
       MHD_socket_close_chk_ (client_socket);
       MHD_ip_limit_del (daemon,
@@ -2487,8 +2487,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
     {
 #ifdef HAVE_MESSAGES
       MHD_DLOG (daemon,
-               _("Error allocating memory: %s\n"),
-               MHD_strerror_ (errno));
+                _("Error allocating memory: %s\n"),
+                MHD_strerror_ (errno));
 #endif
       MHD_socket_close_chk_ (client_socket);
       MHD_ip_limit_del (daemon,
@@ -2507,8 +2507,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
       eno = errno;
 #ifdef HAVE_MESSAGES
       MHD_DLOG (daemon,
-               _("Error allocating memory: %s\n"),
-               MHD_strerror_ (errno));
+                _("Error allocating memory: %s\n"),
+                MHD_strerror_ (errno));
 #endif
       MHD_socket_close_chk_ (client_socket);
       MHD_ip_limit_del (daemon,
@@ -2566,8 +2566,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
           /* set needed credentials for certificate authentication. */
         case GNUTLS_CRD_CERTIFICATE:
           gnutls_credentials_set (connection->tls_session,
-                                 GNUTLS_CRD_CERTIFICATE,
-                                 daemon->x509_cred);
+                                  GNUTLS_CRD_CERTIFICATE,
+                                  daemon->x509_cred);
          break;
         case GNUTLS_CRD_PSK:
           gnutls_credentials_set (connection->tls_session,
@@ -2596,18 +2596,18 @@ internal_add_connection (struct MHD_Daemon *daemon,
         }
 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64)
       gnutls_transport_set_int (connection->tls_session,
-                               (int)(client_socket));
+                                (int)(client_socket));
 #else  /* GnuTLS before 3.1.9 or Win x64 */
       gnutls_transport_set_ptr (connection->tls_session,
-                               
(gnutls_transport_ptr_t)(intptr_t)(client_socket));
+                                
(gnutls_transport_ptr_t)(intptr_t)(client_socket));
 #endif /* GnuTLS before 3.1.9 */
 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
       gnutls_transport_set_push_function (connection->tls_session,
-                                         MHD_tls_push_func_);
+                                          MHD_tls_push_func_);
 #endif /* MHD_TLSLIB_NEED_PUSH_FUNC */
       if (daemon->https_mem_trust)
          gnutls_certificate_server_set_request (connection->tls_session,
-                                                GNUTLS_CERT_REQUEST);
+                                             GNUTLS_CERT_REQUEST);
 #else  /* ! HTTPS_SUPPORT */
       eno = EINVAL;
       goto cleanup;
@@ -2641,8 +2641,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
                    connection);
     }
   DLL_insert (daemon->connections_head,
-             daemon->connections_tail,
-             connection);
+              daemon->connections_tail,
+              connection);
 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
 #endif
@@ -2661,13 +2661,13 @@ internal_add_connection (struct MHD_Daemon *daemon,
                                       &thread_main_handle_connection,
                                       connection))
         {
-         eno = errno;
+          eno = errno;
 #ifdef HAVE_MESSAGES
           MHD_DLOG (daemon,
                     "Failed to create a thread: %s\n",
                     MHD_strerror_ (eno));
 #endif
-         goto cleanup;
+          goto cleanup;
         }
     }
   else
@@ -2683,9 +2683,9 @@ internal_add_connection (struct MHD_Daemon *daemon,
          event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
          event.data.ptr = connection;
          if (0 != epoll_ctl (daemon->epoll_fd,
-                             EPOLL_CTL_ADD,
-                             client_socket,
-                             &event))
+                          EPOLL_CTL_ADD,
+                          client_socket,
+                          &event))
            {
              eno = errno;
 #ifdef HAVE_MESSAGES
@@ -2702,8 +2702,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
          connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | 
MHD_EPOLL_STATE_WRITE_READY
            | MHD_EPOLL_STATE_IN_EREADY_EDLL;
          EDLL_insert (daemon->eready_head,
-                      daemon->eready_tail,
-                      connection);
+                   daemon->eready_tail,
+                   connection);
        }
     }
   else /* This 'else' is combined with next 'if'. */
@@ -4178,28 +4178,29 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon)
   struct MHD_UpgradeResponseHandle * prev;
 
   num_events = MAX_EVENTS;
-  while (MAX_EVENTS == num_events)
+  while (0 != num_events)
     {
       unsigned int i;
       /* update event masks */
       num_events = epoll_wait (daemon->epoll_upgrade_fd,
-                              events,
+                               events,
                                MAX_EVENTS,
                                0);
       if (-1 == num_events)
-       {
+        {
           const int err = MHD_socket_get_error_ ();
+
           if (MHD_SCKT_ERR_IS_EINTR_ (err))
-           return MHD_YES;
+            return MHD_YES;
 #ifdef HAVE_MESSAGES
           MHD_DLOG (daemon,
                     _("Call to epoll_wait failed: %s\n"),
                     MHD_socket_strerr_ (err));
 #endif
-         return MHD_NO;
-       }
+          return MHD_NO;
+        }
       for (i = 0; i < (unsigned int) num_events; i++)
-       {
+        {
           struct UpgradeEpollHandle * const ueh = events[i].data.ptr;
           struct MHD_UpgradeResponseHandle * const urh = ueh->urh;
           bool new_err_state = false;
@@ -4217,24 +4218,24 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon)
 
           if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) &&
                (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
-           {
+            {
               /* Process new error state only one time
                * and avoid continuously marking this connection
                * as 'ready'. */
               ueh->celi |= MHD_EPOLL_STATE_ERROR;
               new_err_state = true;
-           }
+            }
 
           if (! urh->in_eready_list)
             {
               if (new_err_state ||
-                 is_urh_ready(urh))
-               {
-                 EDLL_insert (daemon->eready_urh_head,
-                              daemon->eready_urh_tail,
-                              urh);
-                 urh->in_eready_list = true;
-               }
+                  is_urh_ready(urh))
+                {
+                  EDLL_insert (daemon->eready_urh_head,
+                               daemon->eready_urh_tail,
+                               urh);
+                  urh->in_eready_list = true;
+                }
             }
         }
     }
@@ -4246,8 +4247,8 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon)
       if (! is_urh_ready(pos))
        {
          EDLL_remove (daemon->eready_urh_head,
-                      daemon->eready_urh_tail,
-                      pos);
+                       daemon->eready_urh_tail,
+                       pos);
          pos->in_eready_list = false;
        }
       /* Finished forwarding? */
@@ -4262,7 +4263,7 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon)
            * will be moved immediately to cleanup list. Otherwise
            * connection will stay in suspended list until 'pos' will
            * be marked with 'was_closed' by application. */
-          MHD_resume_connection(pos->connection);
+          MHD_resume_connection (pos->connection);
         }
     }
 
@@ -4287,7 +4288,7 @@ static const char * const epoll_itc_marker = "itc_marker";
  */
 static int
 MHD_epoll (struct MHD_Daemon *daemon,
-          int may_block)
+           int may_block)
 {
 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   static const char * const upgrade_marker = "upgrade_ptr";
@@ -4302,7 +4303,7 @@ MHD_epoll (struct MHD_Daemon *daemon,
   unsigned int i;
   MHD_socket ls;
 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
-  int run_upgraded = MHD_NO;
+  bool run_upgraded = false;
 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
 
   if (-1 == daemon->epoll_fd)
@@ -4318,50 +4319,50 @@ MHD_epoll (struct MHD_Daemon *daemon,
       event.events = EPOLLIN;
       event.data.ptr = daemon;
       if (0 != epoll_ctl (daemon->epoll_fd,
-                         EPOLL_CTL_ADD,
-                         ls,
-                         &event))
-       {
+                          EPOLL_CTL_ADD,
+                          ls,
+                          &event))
+        {
 #ifdef HAVE_MESSAGES
           MHD_DLOG (daemon,
                     _("Call to epoll_ctl failed: %s\n"),
                     MHD_socket_last_strerr_ ());
 #endif
-         return MHD_NO;
-       }
+          return MHD_NO;
+        }
       daemon->listen_socket_in_epoll = true;
     }
   if ( (daemon->was_quiesced) &&
        (daemon->listen_socket_in_epoll) )
-  {
-    if ( (0 != epoll_ctl (daemon->epoll_fd,
-                          EPOLL_CTL_DEL,
-                          ls,
-                          NULL)) &&
-         (ENOENT != errno) ) /* ENOENT can happen due to race with
-                                #MHD_quiesce_daemon() */
-      MHD_PANIC ("Failed to remove listen FD from epoll set\n");
-    daemon->listen_socket_in_epoll = false;
-  }
+    {
+      if ( (0 != epoll_ctl (daemon->epoll_fd,
+                            EPOLL_CTL_DEL,
+                            ls,
+                            NULL)) &&
+           (ENOENT != errno) ) /* ENOENT can happen due to race with
+                                  #MHD_quiesce_daemon() */
+        MHD_PANIC ("Failed to remove listen FD from epoll set\n");
+      daemon->listen_socket_in_epoll = false;
+    }
 
 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
-  if ( (! daemon->upgrade_fd_in_epoll) &&
-       (-1 != daemon->epoll_upgrade_fd) )
+  if ( ( (! daemon->upgrade_fd_in_epoll) &&
+         (-1 != daemon->epoll_upgrade_fd) ) )
     {
       event.events = EPOLLIN | EPOLLOUT;
       event.data.ptr = (void *) upgrade_marker;
       if (0 != epoll_ctl (daemon->epoll_fd,
-                         EPOLL_CTL_ADD,
-                         daemon->epoll_upgrade_fd,
-                         &event))
-       {
+                          EPOLL_CTL_ADD,
+                          daemon->epoll_upgrade_fd,
+                          &event))
+        {
 #ifdef HAVE_MESSAGES
           MHD_DLOG (daemon,
                     _("Call to epoll_ctl failed: %s\n"),
                     MHD_socket_last_strerr_ ());
 #endif
-         return MHD_NO;
-       }
+          return MHD_NO;
+        }
       daemon->upgrade_fd_in_epoll = true;
     }
 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
@@ -4373,10 +4374,10 @@ MHD_epoll (struct MHD_Daemon *daemon,
       /* we're at the connection limit, disable listen socket
         for event loop for now */
       if (0 != epoll_ctl (daemon->epoll_fd,
-                         EPOLL_CTL_DEL,
-                         ls,
-                         NULL))
-       MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
+                          EPOLL_CTL_DEL,
+                          ls,
+                          NULL))
+        MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
       daemon->listen_socket_in_epoll = false;
     }
 
@@ -4387,15 +4388,15 @@ MHD_epoll (struct MHD_Daemon *daemon,
   if (MHD_YES == may_block)
     {
       if (MHD_YES == MHD_get_timeout (daemon,
-                                     &timeout_ll))
-       {
-         if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
-           timeout_ms = INT_MAX;
-         else
-           timeout_ms = (int) timeout_ll;
-       }
+                                      &timeout_ll))
+        {
+          if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
+            timeout_ms = INT_MAX;
+          else
+            timeout_ms = (int) timeout_ll;
+        }
       else
-       timeout_ms = -1;
+        timeout_ms = -1;
     }
   else
     timeout_ms = 0;
@@ -4414,33 +4415,33 @@ MHD_epoll (struct MHD_Daemon *daemon,
     {
       /* update event masks */
       num_events = epoll_wait (daemon->epoll_fd,
-                              events,
+                               events,
                                MAX_EVENTS,
                                timeout_ms);
       if (-1 == num_events)
-       {
+        {
           const int err = MHD_socket_get_error_ ();
           if (MHD_SCKT_ERR_IS_EINTR_ (err))
-           return MHD_YES;
+            return MHD_YES;
 #ifdef HAVE_MESSAGES
           MHD_DLOG (daemon,
                     _("Call to epoll_wait failed: %s\n"),
                     MHD_socket_strerr_ (err));
 #endif
-         return MHD_NO;
-       }
+          return MHD_NO;
+        }
       for (i=0;i<(unsigned int) num_events;i++)
-       {
+        {
           /* First, check for the values of `ptr` that would indicate
              that this event is not about a normal connection. */
-         if (NULL == events[i].data.ptr)
-           continue; /* shutdown signal! */
+          if (NULL == events[i].data.ptr)
+            continue; /* shutdown signal! */
 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
           if (upgrade_marker == events[i].data.ptr)
             {
               /* activity on an upgraded connection, we process
                  those in a separate epoll() */
-              run_upgraded = MHD_YES;
+              run_upgraded = true;
               continue;
             }
 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
@@ -4451,8 +4452,8 @@ MHD_epoll (struct MHD_Daemon *daemon,
               MHD_itc_clear_ (daemon->itc);
               continue;
             }
-         if (daemon == events[i].data.ptr)
-           {
+          if (daemon == events[i].data.ptr)
+            {
               /* Check for error conditions on listen socket. */
               /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? 
*/
               if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
@@ -4467,9 +4468,9 @@ MHD_epoll (struct MHD_Daemon *daemon,
                           (daemon->connections < daemon->connection_limit) &&
                           (! daemon->at_limit) )
                     series_length++;
-               }
+                }
               continue;
-           }
+            }
           /* this is an event relating to a 'normal' connection,
              remember the event and if appropriate mark the
              connection as 'eready'. */
@@ -4518,7 +4519,7 @@ MHD_epoll (struct MHD_Daemon *daemon,
     }
 
 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
-  if (MHD_YES == run_upgraded)
+  if (run_upgraded || (NULL != daemon->eready_urh_head))
     run_epoll_for_upgrade (daemon);
 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
 
@@ -4606,22 +4607,22 @@ MHD_run (struct MHD_Daemon *daemon)
        (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) )
     return MHD_NO;
   if (0 != (daemon->options & MHD_USE_POLL))
-  {
-    MHD_poll (daemon, MHD_NO);
-    MHD_cleanup_connections (daemon);
-  }
+    {
+      MHD_poll (daemon, MHD_NO);
+      MHD_cleanup_connections (daemon);
+    }
 #ifdef EPOLL_SUPPORT
   else if (0 != (daemon->options & MHD_USE_EPOLL))
-  {
-    MHD_epoll (daemon, MHD_NO);
-    MHD_cleanup_connections (daemon);
-  }
+    {
+      MHD_epoll (daemon, MHD_NO);
+      MHD_cleanup_connections (daemon);
+    }
 #endif
   else
-  {
-    MHD_select (daemon, MHD_NO);
-    /* MHD_select does MHD_cleanup_connections already */
-  }
+    {
+      MHD_select (daemon, MHD_NO);
+      /* MHD_select does MHD_cleanup_connections already */
+    }
   return MHD_YES;
 }
 
@@ -4823,26 +4824,26 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon)
   if (NULL != daemon->worker_pool)
     for (i = 0; i < daemon->worker_pool_size; i++)
       {
-       daemon->worker_pool[i].was_quiesced = true;
+        daemon->worker_pool[i].was_quiesced = true;
 #ifdef EPOLL_SUPPORT
-       if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
-            (-1 != daemon->worker_pool[i].epoll_fd) &&
-            (daemon->worker_pool[i].listen_socket_in_epoll) )
-         {
-           if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
-                               EPOLL_CTL_DEL,
-                               ret,
-                               NULL))
-             MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
-           daemon->worker_pool[i].listen_socket_in_epoll = false;
-         }
-        else
-#endif
-        if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
+        if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
+             (-1 != daemon->worker_pool[i].epoll_fd) &&
+             (daemon->worker_pool[i].listen_socket_in_epoll) )
           {
-            if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q"))
-              MHD_PANIC (_("Failed to signal quiesce via inter-thread 
communication channel"));
+            if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
+                                EPOLL_CTL_DEL,
+                                ret,
+                                NULL))
+              MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
+            daemon->worker_pool[i].listen_socket_in_epoll = false;
           }
+        else
+#endif
+          if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
+            {
+              if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q"))
+                MHD_PANIC (_("Failed to signal quiesce via inter-thread 
communication channel"));
+            }
       }
 #endif
   daemon->was_quiesced = true;
@@ -4857,7 +4858,7 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon)
                             NULL)) &&
            (ENOENT != errno) ) /* ENOENT can happen due to race with
                                   #MHD_epoll() */
-       MHD_PANIC ("Failed to remove listen FD from epoll set\n");
+        MHD_PANIC ("Failed to remove listen FD from epoll set\n");
       daemon->listen_socket_in_epoll = false;
     }
 #endif
@@ -4891,8 +4892,8 @@ typedef void
  */
 static int
 parse_options_va (struct MHD_Daemon *daemon,
-                 const struct sockaddr **servaddr,
-                 va_list ap);
+                  const struct sockaddr **servaddr,
+                  va_list ap);
 
 
 /**
@@ -4930,8 +4931,8 @@ parse_options (struct MHD_Daemon *daemon,
  */
 static int
 parse_options_va (struct MHD_Daemon *daemon,
-                 const struct sockaddr **servaddr,
-                 va_list ap)
+                  const struct sockaddr **servaddr,
+                  va_list ap)
 {
   enum MHD_OPTION opt;
   struct MHD_OptionItem *oa;
@@ -6494,10 +6495,10 @@ thread_failed:
   if (daemon->upgrade_fd_in_epoll)
     {
       if (0 != epoll_ctl (daemon->epoll_fd,
-                         EPOLL_CTL_DEL,
-                         daemon->epoll_upgrade_fd,
-                         NULL))
-       MHD_PANIC (_("Failed to remove FD from epoll set\n"));
+                          EPOLL_CTL_DEL,
+                          daemon->epoll_upgrade_fd,
+                          NULL))
+        MHD_PANIC (_("Failed to remove FD from epoll set\n"));
       daemon->upgrade_fd_in_epoll = false;
     }
 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index 035e3054..3e9fb053 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -80,9 +80,9 @@
  */
 static int
 add_response_entry (struct MHD_Response *response,
-                   enum MHD_ValueKind kind,
-                   const char *header,
-                   const char *content)
+                    enum MHD_ValueKind kind,
+                    const char *header,
+                    const char *content)
 {
   struct MHD_HTTP_Header *hdr;
 
@@ -195,7 +195,7 @@ MHD_add_response_footer (struct MHD_Response *response,
 int
 MHD_del_response_header (struct MHD_Response *response,
                          const char *header,
-                        const char *content)
+                         const char *content)
 {
   struct MHD_HTTP_Header *pos;
   struct MHD_HTTP_Header *prev;
@@ -280,7 +280,7 @@ MHD_get_response_headers (struct MHD_Response *response,
  */
 const char *
 MHD_get_response_header (struct MHD_Response *response,
-                        const char *key)
+                         const char *key)
 {
   struct MHD_HTTP_Header *pos;
   size_t key_size;
@@ -558,8 +558,8 @@ free_callback (void *cls)
  */
 struct MHD_Response *
 MHD_create_response_from_fd_at_offset (size_t size,
-                                      int fd,
-                                      off_t offset)
+                                       int fd,
+                                       off_t offset)
 {
   return MHD_create_response_from_fd_at_offset64 (size,
                                                   fd,
@@ -627,7 +627,7 @@ MHD_create_response_from_fd_at_offset64 (uint64_t size,
  */
 struct MHD_Response *
 MHD_create_response_from_fd (size_t size,
-                            int fd)
+                             int fd)
 {
   return MHD_create_response_from_fd_at_offset64 (size,
                                                   fd,
@@ -732,8 +732,8 @@ MHD_create_response_from_data (size_t size,
  */
 struct MHD_Response *
 MHD_create_response_from_buffer (size_t size,
-                                void *buffer,
-                                enum MHD_ResponseMemoryMode mode)
+                                 void *buffer,
+                                 enum MHD_ResponseMemoryMode mode)
 {
   return MHD_create_response_from_data (size,
                                        buffer,
@@ -754,15 +754,15 @@ MHD_create_response_from_buffer (size_t size,
  */
 _MHD_EXTERN struct MHD_Response *
 MHD_create_response_from_buffer_with_free_callback (size_t size,
-                                                   void *buffer,
-                                                   
MHD_ContentReaderFreeCallback crfc)
+                                                    void *buffer,
+                                                    
MHD_ContentReaderFreeCallback crfc)
 {
   struct MHD_Response *r;
 
   r = MHD_create_response_from_data (size,
-                                    buffer,
-                                    MHD_YES,
-                                    MHD_NO);
+                                     buffer,
+                                     MHD_YES,
+                                     MHD_NO);
   if (NULL == r)
     return r;
   r->crfc = crfc;
@@ -997,17 +997,17 @@ MHD_response_execute_upgrade_ (struct MHD_Response 
*response,
                             EPOLL_CTL_ADD,
                             connection->socket_fd,
                             &event))
-       {
+          {
 #ifdef HAVE_MESSAGES
-          MHD_DLOG (daemon,
-                    _("Call to epoll_ctl failed: %s\n"),
-                    MHD_socket_last_strerr_ ());
+            MHD_DLOG (daemon,
+                      _("Call to epoll_ctl failed: %s\n"),
+                      MHD_socket_last_strerr_ ());
 #endif
-          MHD_socket_close_chk_ (sv[0]);
-          MHD_socket_close_chk_ (sv[1]);
-          free (urh);
-          return MHD_NO;
-       }
+            MHD_socket_close_chk_ (sv[0]);
+            MHD_socket_close_chk_ (sv[1]);
+            free (urh);
+            return MHD_NO;
+          }
 
         /* Second, add our end of the UNIX socketpair() */
         event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
@@ -1016,28 +1016,28 @@ MHD_response_execute_upgrade_ (struct MHD_Response 
*response,
                             EPOLL_CTL_ADD,
                             urh->mhd.socket,
                             &event))
-       {
-          event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
-          event.data.ptr = &urh->app;
-          if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
-                              EPOLL_CTL_DEL,
-                              connection->socket_fd,
-                              &event))
-            MHD_PANIC (_("Error cleaning up while handling epoll error"));
+          {
+            event.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
+            event.data.ptr = &urh->app;
+            if (0 != epoll_ctl (daemon->epoll_upgrade_fd,
+                                EPOLL_CTL_DEL,
+                                connection->socket_fd,
+                                &event))
+              MHD_PANIC (_("Error cleaning up while handling epoll error"));
 #ifdef HAVE_MESSAGES
-          MHD_DLOG (daemon,
-                    _("Call to epoll_ctl failed: %s\n"),
-                    MHD_socket_last_strerr_ ());
+            MHD_DLOG (daemon,
+                      _("Call to epoll_ctl failed: %s\n"),
+                      MHD_socket_last_strerr_ ());
 #endif
-          MHD_socket_close_chk_ (sv[0]);
-          MHD_socket_close_chk_ (sv[1]);
-          free (urh);
-          return MHD_NO;
-       }
-       EDLL_insert (daemon->eready_urh_head,
-                    daemon->eready_urh_tail,
-                    urh);
-       urh->in_eready_list = true;
+            MHD_socket_close_chk_ (sv[0]);
+            MHD_socket_close_chk_ (sv[1]);
+            free (urh);
+            return MHD_NO;
+          }
+        EDLL_insert (daemon->eready_urh_head,
+                     daemon->eready_urh_tail,
+                     urh);
+        urh->in_eready_list = true;
       }
 #endif /* EPOLL_SUPPORT */
     if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION) )
diff --git a/src/microhttpd/test_upgrade.c b/src/microhttpd/test_upgrade_large.c
similarity index 93%
copy from src/microhttpd/test_upgrade.c
copy to src/microhttpd/test_upgrade_large.c
index caf12e61..6f2a1b94 100644
--- a/src/microhttpd/test_upgrade.c
+++ b/src/microhttpd/test_upgrade_large.c
@@ -1,6 +1,6 @@
 /*
      This file is part of libmicrohttpd
-     Copyright (C) 2016 Christian Grothoff
+     Copyright (C) 2016, 2019 Christian Grothoff
 
      libmicrohttpd is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -19,8 +19,10 @@
 */
 
 /**
- * @file test_upgrade.c
- * @brief  Testcase for libmicrohttpd upgrading a connection
+ * @file test_upgrade_large.c
+ * @brief  Testcase for libmicrohttpd upgrading a connection,
+ *         modified to test the "large" corner case reported
+ *         by Viet on the mailinglist in 6'2019
  * @author Christian Grothoff
  * @author Karlson2k (Evgeny Grin)
  */
@@ -49,6 +51,10 @@
 
 #include "test_helpers.h"
 
+#define LARGE_STRING 
"HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello"
+
+#define LARGE_REPLY_STRING 
"WorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorldWorld"
+
 #ifdef HTTPS_SUPPORT
 #include <gnutls/gnutls.h>
 #include "../testcurl/https/tls_test_keys.h"
@@ -61,6 +67,8 @@
 
 static int verbose = 0;
 
+static int kicker[2] = {-1, -1} ;
+
 enum tls_tool
 {
   TLS_CLI_NO_TOOL = 0,
@@ -564,7 +572,17 @@ make_blocking (MHD_socket fd)
 
   ioctlsocket (fd, FIONBIO, &flags);
 #endif /* MHD_WINSOCK_SOCKETS */
+}
+
 
+static void
+kick_select ()
+{
+  if (-1 != kicker[1])
+  {
+    write (kicker[1], "K", 1);
+    fprintf (stderr, "KICKING\n");
+  }
 }
 
 
@@ -582,6 +600,7 @@ send_all (struct wr_socket *sock,
       ret = wr_send (sock,
                      &text[off],
                      len - off);
+      kick_select ();
       if (0 > ret)
         {
           if (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ()))
@@ -615,6 +634,7 @@ recv_hdr (struct wr_socket *sock)
       ret = wr_recv (sock,
                        &c,
                        1);
+      kick_select ();
       if (0 > ret)
         {
           if (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ()))
@@ -686,9 +706,9 @@ run_usock (void *cls)
   struct MHD_UpgradeResponseHandle *urh = cls;
 
   send_all (usock,
-            "Hello");
+            LARGE_STRING);
   recv_all (usock,
-            "World");
+            LARGE_REPLY_STRING);
   send_all (usock,
             "Finished");
   MHD_upgrade_action (urh,
@@ -714,9 +734,9 @@ run_usock_client (void *cls)
             "GET / HTTP/1.1\r\nConnection: Upgrade\r\n\r\n");
   recv_hdr (sock);
   recv_all (sock,
-            "Hello");
+            LARGE_STRING);
   send_all (sock,
-            "World");
+            LARGE_REPLY_STRING);
   recv_all (sock,
             "Finished");
   wr_close (sock);
@@ -883,7 +903,10 @@ run_mhd_select_loop (struct MHD_Daemon *daemon)
   MHD_socket max_fd;
   MHD_UNSIGNED_LONG_LONG to;
   struct timeval tv;
+  char drain[128];
 
+  if (0 != pipe (kicker))
+    abort ();
   while (! done)
     {
       FD_ZERO (&rs);
@@ -892,6 +915,7 @@ run_mhd_select_loop (struct MHD_Daemon *daemon)
       max_fd = -1;
       to = 1000;
 
+      FD_SET (kicker[0], &rs);
       if (MHD_YES !=
           MHD_get_fdset (daemon,
                          &rs,
@@ -911,11 +935,17 @@ run_mhd_select_loop (struct MHD_Daemon *daemon)
                                &es,
                                &tv))
         abort ();
+      if (FD_ISSET (kicker[0], &rs))
+        (void) read (kicker[0], drain, sizeof (drain));
       MHD_run_from_select (daemon,
                            &rs,
                            &ws,
                            &es);
     }
+  close (kicker[0]);
+  close (kicker[1]);
+  kicker[0] = -1;
+  kicker[1] = -1;
 }
 
 #ifdef HAVE_POLL
@@ -949,15 +979,18 @@ run_mhd_epoll_loop (struct MHD_Daemon *daemon)
   MHD_UNSIGNED_LONG_LONG to;
   struct timeval tv;
   int ret;
+  char drain[128];
 
   di = MHD_get_daemon_info (daemon,
                             MHD_DAEMON_INFO_EPOLL_FD);
   ep = di->listen_fd;
+  if (0 != pipe (kicker))
+    abort ();
   while (! done)
     {
       FD_ZERO (&rs);
       to = 1000;
-
+      FD_SET (kicker[0], &rs);
       FD_SET (ep, &rs);
       (void) MHD_get_timeout (daemon,
                               &to);
@@ -974,8 +1007,14 @@ run_mhd_epoll_loop (struct MHD_Daemon *daemon)
            (EAGAIN != errno) &&
            (EINTR != errno) )
         abort ();
+      if (FD_ISSET (kicker[0], &rs))
+        (void) read (kicker[0], drain, sizeof (drain));
       MHD_run (daemon);
     }
+  close (kicker[0]);
+  close (kicker[1]);
+  kicker[0] = -1;
+  kicker[1] = -1;
 }
 #endif /* EPOLL_SUPPORT */
 
@@ -1028,15 +1067,16 @@ test_upgrade (int flags,
 
   if (! test_tls)
     d = MHD_start_daemon (flags | MHD_USE_ERROR_LOG | MHD_ALLOW_UPGRADE,
-                         
MHD_is_feature_supported(MHD_FEATURE_AUTODETECT_BIND_PORT) ?
-                             0 : 1090,
-                         NULL, NULL,
-                         &ahc_upgrade, NULL,
-                         MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
-                         MHD_OPTION_NOTIFY_COMPLETED, &notify_completed_cb, 
NULL,
-                         MHD_OPTION_NOTIFY_CONNECTION, &notify_connection_cb, 
NULL,
-                         MHD_OPTION_THREAD_POOL_SIZE, pool,
-                         MHD_OPTION_END);
+                          
MHD_is_feature_supported(MHD_FEATURE_AUTODETECT_BIND_PORT) ?
+                          0 : 1090,
+                          NULL, NULL,
+                          &ahc_upgrade, NULL,
+                          MHD_OPTION_CONNECTION_MEMORY_LIMIT, 512,
+                          MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
+                          MHD_OPTION_NOTIFY_COMPLETED, &notify_completed_cb, 
NULL,
+                          MHD_OPTION_NOTIFY_CONNECTION, &notify_connection_cb, 
NULL,
+                          MHD_OPTION_THREAD_POOL_SIZE, pool,
+                          MHD_OPTION_END);
 #ifdef HTTPS_SUPPORT
   else
     d = MHD_start_daemon (flags | MHD_USE_ERROR_LOG | MHD_ALLOW_UPGRADE | 
MHD_USE_TLS,
@@ -1044,6 +1084,7 @@ test_upgrade (int flags,
                               0 : 1090,
                           NULL, NULL,
                           &ahc_upgrade, NULL,
+                          MHD_OPTION_CONNECTION_MEMORY_LIMIT, 512,
                           MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL,
                           MHD_OPTION_NOTIFY_COMPLETED, &notify_completed_cb, 
NULL,
                           MHD_OPTION_NOTIFY_CONNECTION, &notify_connection_cb, 
NULL,
@@ -1072,8 +1113,8 @@ test_upgrade (int flags,
       sa.sin_port = htons (dinfo->port);
       sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
       if (0 != wr_connect (sock,
-                        (struct sockaddr *) &sa,
-                        sizeof (sa)))
+                           (struct sockaddr *) &sa,
+                           sizeof (sa)))
         abort ();
     }
   else

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



reply via email to

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