libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

daemon.c (320555B)


      1 /*
      2   This file is part of libmicrohttpd
      3   Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
      4   Copyright (C) 2015-2024 Evgeny Grin (Karlson2k)
      5 
      6   This library is free software; you can redistribute it and/or
      7   modify it under the terms of the GNU Lesser General Public
      8   License as published by the Free Software Foundation; either
      9   version 2.1 of the License, or (at your option) any later version.
     10 
     11   This library is distributed in the hope that it will be useful,
     12   but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14   Lesser General Public License for more details.
     15 
     16   You should have received a copy of the GNU Lesser General Public
     17   License along with this library; if not, write to the Free Software
     18   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     19 
     20 */
     21 
     22 /**
     23  * @file microhttpd/daemon.c
     24  * @brief  A minimal-HTTP server library
     25  * @author Daniel Pittman
     26  * @author Christian Grothoff
     27  * @author Karlson2k (Evgeny Grin)
     28  */
     29 #include "platform.h"
     30 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
     31 #include "mhd_threads.h"
     32 #endif
     33 #include "internal.h"
     34 #include "response.h"
     35 #include "connection.h"
     36 #include "memorypool.h"
     37 #include "mhd_limits.h"
     38 #include "autoinit_funcs.h"
     39 #include "mhd_mono_clock.h"
     40 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
     41 #include "mhd_locks.h"
     42 #endif
     43 #include "mhd_sockets.h"
     44 #include "mhd_itc.h"
     45 #include "mhd_compat.h"
     46 #include "mhd_send.h"
     47 #include "mhd_align.h"
     48 #include "mhd_str.h"
     49 
     50 #ifdef MHD_USE_SYS_TSEARCH
     51 #include <search.h>
     52 #else  /* ! MHD_USE_SYS_TSEARCH */
     53 #include "tsearch.h"
     54 #endif /* ! MHD_USE_SYS_TSEARCH */
     55 
     56 #ifdef HTTPS_SUPPORT
     57 #include "connection_https.h"
     58 #ifdef MHD_HTTPS_REQUIRE_GCRYPT
     59 #include <gcrypt.h>
     60 #endif /* MHD_HTTPS_REQUIRE_GCRYPT */
     61 #endif /* HTTPS_SUPPORT */
     62 
     63 #if defined(_WIN32) && ! defined(__CYGWIN__)
     64 #ifndef WIN32_LEAN_AND_MEAN
     65 #define WIN32_LEAN_AND_MEAN 1
     66 #endif /* !WIN32_LEAN_AND_MEAN */
     67 #include <windows.h>
     68 #endif
     69 
     70 #ifdef MHD_USE_POSIX_THREADS
     71 #ifdef HAVE_SIGNAL_H
     72 #include <signal.h>
     73 #endif /* HAVE_SIGNAL_H */
     74 #endif /* MHD_USE_POSIX_THREADS */
     75 
     76 /**
     77  * Default connection limit.
     78  */
     79 #ifdef MHD_POSIX_SOCKETS
     80 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 3 - 1 - MHD_ITC_NUM_FDS_)
     81 #else
     82 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 2)
     83 #endif
     84 
     85 /**
     86  * Default memory allowed per connection.
     87  */
     88 #define MHD_POOL_SIZE_DEFAULT (32 * 1024)
     89 
     90 
     91 /* Forward declarations. */
     92 
     93 
     94 /**
     95  * Global initialisation function.
     96  */
     97 void
     98 MHD_init (void);
     99 
    100 /**
    101  * Global deinitialisation function.
    102  */
    103 void
    104 MHD_fini (void);
    105 
    106 /**
    107  * Close all connections for the daemon.
    108  * Must only be called when MHD_Daemon::shutdown was set to true.
    109  * @remark To be called only from thread that process
    110  * daemon's select()/poll()/etc.
    111  *
    112  * @param daemon daemon to close down
    113  */
    114 static void
    115 close_all_connections (struct MHD_Daemon *daemon);
    116 
    117 #ifdef EPOLL_SUPPORT
    118 
    119 /**
    120  * Do epoll()-based processing.
    121  *
    122  * @param daemon daemon to run poll loop for
    123  * @param millisec the maximum time in milliseconds to wait for events,
    124  *                 set to '0' for non-blocking processing,
    125  *                 set to '-1' to wait indefinitely.
    126  * @return #MHD_NO on serious errors, #MHD_YES on success
    127  */
    128 static enum MHD_Result
    129 MHD_epoll (struct MHD_Daemon *daemon,
    130            int32_t millisec);
    131 
    132 #endif /* EPOLL_SUPPORT */
    133 
    134 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
    135 /**
    136  * Do nothing - global initialisation is
    137  * performed by library constructor.
    138  */
    139 #define MHD_check_global_init_() (void) 0
    140 #else  /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
    141 /**
    142  * Track global initialisation
    143  */
    144 volatile int global_init_count = 0;
    145 
    146 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
    147 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
    148 /**
    149  * Global initialisation mutex
    150  */
    151 MHD_MUTEX_STATIC_DEFN_INIT_ (global_init_mutex_);
    152 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
    153 #endif
    154 
    155 
    156 /**
    157  * Check whether global initialisation was performed
    158  * and call initialiser if necessary.
    159  */
    160 void
    161 MHD_check_global_init_ (void)
    162 {
    163 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
    164 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
    165   MHD_mutex_lock_chk_ (&global_init_mutex_);
    166 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
    167 #endif
    168   if (0 == global_init_count++)
    169     MHD_init ();
    170 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
    171 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
    172   MHD_mutex_unlock_chk_ (&global_init_mutex_);
    173 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
    174 #endif
    175 }
    176 
    177 
    178 #endif /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
    179 
    180 #ifdef HAVE_MESSAGES
    181 /**
    182  * Default logger function
    183  */
    184 static void
    185 MHD_default_logger_ (void *cls,
    186                      const char *fm,
    187                      va_list ap)
    188 {
    189   vfprintf ((FILE *) cls, fm, ap);
    190 #ifdef _DEBUG
    191   fflush ((FILE *) cls);
    192 #endif /* _DEBUG */
    193 }
    194 
    195 
    196 #endif /* HAVE_MESSAGES */
    197 
    198 
    199 /**
    200  * Free the memory allocated by MHD.
    201  *
    202  * If any MHD function explicitly mentions that returned pointer must be
    203  * freed by this function, then no other method must be used to free
    204  * the memory.
    205  *
    206  * @param ptr the pointer to free.
    207  * @sa #MHD_digest_auth_get_username(), #MHD_basic_auth_get_username_password3()
    208  * @sa #MHD_basic_auth_get_username_password()
    209  * @note Available since #MHD_VERSION 0x00095600
    210  * @ingroup specialized
    211  */
    212 _MHD_EXTERN void
    213 MHD_free (void *ptr)
    214 {
    215   free (ptr);
    216 }
    217 
    218 
    219 /**
    220  * Maintain connection count for single address.
    221  */
    222 struct MHD_IPCount
    223 {
    224   /**
    225    * Address family. AF_INET or AF_INET6 for now.
    226    */
    227   int family;
    228 
    229   /**
    230    * Actual address.
    231    */
    232   union
    233   {
    234     /**
    235      * IPv4 address.
    236      */
    237     struct in_addr ipv4;
    238 #ifdef HAVE_INET6
    239     /**
    240      * IPv6 address.
    241      */
    242     struct in6_addr ipv6;
    243 #endif
    244   } addr;
    245 
    246   /**
    247    * Counter.
    248    */
    249   unsigned int count;
    250 };
    251 
    252 
    253 /**
    254  * Lock shared structure for IP connection counts and connection DLLs.
    255  *
    256  * @param daemon handle to daemon where lock is
    257  */
    258 static void
    259 MHD_ip_count_lock (struct MHD_Daemon *daemon)
    260 {
    261   mhd_assert (NULL == daemon->master);
    262 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
    263   MHD_mutex_lock_chk_ (&daemon->per_ip_connection_mutex);
    264 #else
    265   (void) daemon;
    266 #endif
    267 }
    268 
    269 
    270 /**
    271  * Unlock shared structure for IP connection counts and connection DLLs.
    272  *
    273  * @param daemon handle to daemon where lock is
    274  */
    275 static void
    276 MHD_ip_count_unlock (struct MHD_Daemon *daemon)
    277 {
    278   mhd_assert (NULL == daemon->master);
    279 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
    280   MHD_mutex_unlock_chk_ (&daemon->per_ip_connection_mutex);
    281 #else
    282   (void) daemon;
    283 #endif
    284 }
    285 
    286 
    287 /**
    288  * Tree comparison function for IP addresses (supplied to tsearch() family).
    289  * We compare everything in the struct up through the beginning of the
    290  * 'count' field.
    291  *
    292  * @param a1 first address to compare
    293  * @param a2 second address to compare
    294  * @return -1, 0 or 1 depending on result of compare
    295  */
    296 static int
    297 MHD_ip_addr_compare (const void *a1,
    298                      const void *a2)
    299 {
    300   return memcmp (a1,
    301                  a2,
    302                  offsetof (struct MHD_IPCount,
    303                            count));
    304 }
    305 
    306 
    307 /**
    308  * Parse address and initialize @a key using the address.
    309  *
    310  * @param addr address to parse
    311  * @param addrlen number of bytes in @a addr
    312  * @param key where to store the parsed address
    313  * @return #MHD_YES on success and #MHD_NO otherwise (e.g., invalid address type)
    314  */
    315 static enum MHD_Result
    316 MHD_ip_addr_to_key (const struct sockaddr_storage *addr,
    317                     socklen_t addrlen,
    318                     struct MHD_IPCount *key)
    319 {
    320   memset (key,
    321           0,
    322           sizeof(*key));
    323 
    324   /* IPv4 addresses */
    325   if (sizeof (struct sockaddr_in) <= (size_t) addrlen)
    326   {
    327     if (AF_INET == addr->ss_family)
    328     {
    329       key->family = AF_INET;
    330       memcpy (&key->addr.ipv4,
    331               &((const struct sockaddr_in *) addr)->sin_addr,
    332               sizeof(((const struct sockaddr_in *) NULL)->sin_addr));
    333       return MHD_YES;
    334     }
    335   }
    336 
    337 #ifdef HAVE_INET6
    338   if (sizeof (struct sockaddr_in6) <= (size_t) addrlen)
    339   {
    340     /* IPv6 addresses */
    341     if (AF_INET6 == addr->ss_family)
    342     {
    343       key->family = AF_INET6;
    344       memcpy (&key->addr.ipv6,
    345               &((const struct sockaddr_in6 *) addr)->sin6_addr,
    346               sizeof(((const struct sockaddr_in6 *) NULL)->sin6_addr));
    347       return MHD_YES;
    348     }
    349   }
    350 #endif
    351 
    352   /* Some other address */
    353   return MHD_NO;
    354 }
    355 
    356 
    357 /**
    358  * Check if IP address is over its limit in terms of the number
    359  * of allowed concurrent connections.  If the IP is still allowed,
    360  * increments the connection counter.
    361  *
    362  * @param daemon handle to daemon where connection counts are tracked
    363  * @param addr address to add (or increment counter)
    364  * @param addrlen number of bytes in @a addr
    365  * @return Return #MHD_YES if IP below limit, #MHD_NO if IP has surpassed limit.
    366  *   Also returns #MHD_NO if fails to allocate memory.
    367  */
    368 static enum MHD_Result
    369 MHD_ip_limit_add (struct MHD_Daemon *daemon,
    370                   const struct sockaddr_storage *addr,
    371                   socklen_t addrlen)
    372 {
    373   struct MHD_IPCount *newkeyp;
    374   struct MHD_IPCount *keyp;
    375   struct MHD_IPCount **nodep;
    376   enum MHD_Result result;
    377 
    378   daemon = MHD_get_master (daemon);
    379   /* Ignore if no connection limit assigned */
    380   if (0 == daemon->per_ip_connection_limit)
    381     return MHD_YES;
    382 
    383   newkeyp = (struct MHD_IPCount *) malloc (sizeof(struct MHD_IPCount));
    384   if (NULL == newkeyp)
    385     return MHD_NO;
    386 
    387   /* Initialize key */
    388   if (MHD_NO == MHD_ip_addr_to_key (addr,
    389                                     addrlen,
    390                                     newkeyp))
    391   {
    392     free (newkeyp);
    393     return MHD_YES; /* Allow unhandled address types through */
    394   }
    395 
    396   MHD_ip_count_lock (daemon);
    397 
    398   /* Search for the IP address */
    399   nodep = (struct MHD_IPCount **) tsearch (newkeyp,
    400                                            &daemon->per_ip_connection_count,
    401                                            &MHD_ip_addr_compare);
    402   if (NULL == nodep)
    403   {
    404     MHD_ip_count_unlock (daemon);
    405     free (newkeyp);
    406 #ifdef HAVE_MESSAGES
    407     MHD_DLOG (daemon,
    408               _ ("Failed to add IP connection count node.\n"));
    409 #endif
    410     return MHD_NO;
    411   }
    412   keyp = *nodep;
    413   /* Test if there is room for another connection; if so,
    414    * increment count */
    415   result = (keyp->count < daemon->per_ip_connection_limit) ? MHD_YES : MHD_NO;
    416   if (MHD_NO != result)
    417     ++keyp->count;
    418   MHD_ip_count_unlock (daemon);
    419 
    420   /* If we got an existing node back, free the one we created */
    421   if (keyp != newkeyp)
    422     free (newkeyp);
    423 
    424   return result;
    425 }
    426 
    427 
    428 /**
    429  * Decrement connection count for IP address, removing from table
    430  * count reaches 0.
    431  *
    432  * @param daemon handle to daemon where connection counts are tracked
    433  * @param addr address to remove (or decrement counter)
    434  * @param addrlen number of bytes in @a addr
    435  */
    436 static void
    437 MHD_ip_limit_del (struct MHD_Daemon *daemon,
    438                   const struct sockaddr_storage *addr,
    439                   socklen_t addrlen)
    440 {
    441   struct MHD_IPCount search_key;
    442   struct MHD_IPCount *found_key;
    443   void **nodep;
    444 
    445   daemon = MHD_get_master (daemon);
    446   /* Ignore if no connection limit assigned */
    447   if (0 == daemon->per_ip_connection_limit)
    448     return;
    449   /* Initialize search key */
    450   if (MHD_NO == MHD_ip_addr_to_key (addr,
    451                                     addrlen,
    452                                     &search_key))
    453     return;
    454 
    455   MHD_ip_count_lock (daemon);
    456 
    457   /* Search for the IP address */
    458   if (NULL == (nodep = tfind (&search_key,
    459                               &daemon->per_ip_connection_count,
    460                               &MHD_ip_addr_compare)))
    461   {
    462     /* Something's wrong if we couldn't find an IP address
    463      * that was previously added */
    464     MHD_PANIC (_ ("Failed to find previously-added IP address.\n"));
    465   }
    466   found_key = (struct MHD_IPCount *) *nodep;
    467   /* Validate existing count for IP address */
    468   if (0 == found_key->count)
    469   {
    470     MHD_PANIC (_ ("Previously-added IP address had counter of zero.\n"));
    471   }
    472   /* Remove the node entirely if count reduces to 0 */
    473   if (0 == --found_key->count)
    474   {
    475     tdelete (found_key,
    476              &daemon->per_ip_connection_count,
    477              &MHD_ip_addr_compare);
    478     MHD_ip_count_unlock (daemon);
    479     free (found_key);
    480   }
    481   else
    482     MHD_ip_count_unlock (daemon);
    483 }
    484 
    485 
    486 #ifdef HTTPS_SUPPORT
    487 /**
    488  * Read and setup our certificate and key.
    489  *
    490  * @param daemon handle to daemon to initialize
    491  * @return 0 on success
    492  */
    493 static int
    494 MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
    495 {
    496   gnutls_datum_t key;
    497   gnutls_datum_t cert;
    498   int ret;
    499 
    500 #if GNUTLS_VERSION_MAJOR >= 3
    501   if (NULL != daemon->cert_callback)
    502   {
    503     gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
    504                                                daemon->cert_callback);
    505   }
    506 #endif
    507 #if GNUTLS_VERSION_NUMBER >= 0x030603
    508   else if (NULL != daemon->cert_callback2)
    509   {
    510     gnutls_certificate_set_retrieve_function3 (daemon->x509_cred,
    511                                                daemon->cert_callback2);
    512   }
    513 #endif
    514 
    515   if (NULL != daemon->https_mem_trust)
    516   {
    517     size_t paramlen;
    518     paramlen = strlen (daemon->https_mem_trust);
    519     if (UINT_MAX < paramlen)
    520     {
    521 #ifdef HAVE_MESSAGES
    522       MHD_DLOG (daemon,
    523                 _ ("Too long trust certificate.\n"));
    524 #endif
    525       return -1;
    526     }
    527     cert.data = (unsigned char *) _MHD_DROP_CONST (daemon->https_mem_trust);
    528     cert.size = (unsigned int) paramlen;
    529     if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred,
    530                                                &cert,
    531                                                GNUTLS_X509_FMT_PEM) < 0)
    532     {
    533 #ifdef HAVE_MESSAGES
    534       MHD_DLOG (daemon,
    535                 _ ("Bad trust certificate format.\n"));
    536 #endif
    537       return -1;
    538     }
    539   }
    540 
    541   if (daemon->have_dhparams)
    542   {
    543     gnutls_certificate_set_dh_params (daemon->x509_cred,
    544                                       daemon->https_mem_dhparams);
    545   }
    546   /* certificate & key loaded from memory */
    547   if ( (NULL != daemon->https_mem_cert) &&
    548        (NULL != daemon->https_mem_key) )
    549   {
    550     size_t param1len;
    551     size_t param2len;
    552 
    553     param1len = strlen (daemon->https_mem_key);
    554     param2len = strlen (daemon->https_mem_cert);
    555     if ( (UINT_MAX < param1len) ||
    556          (UINT_MAX < param2len) )
    557     {
    558 #ifdef HAVE_MESSAGES
    559       MHD_DLOG (daemon,
    560                 _ ("Too long key or certificate.\n"));
    561 #endif
    562       return -1;
    563     }
    564     key.data = (unsigned char *) _MHD_DROP_CONST (daemon->https_mem_key);
    565     key.size = (unsigned int) param1len;
    566     cert.data = (unsigned char *) _MHD_DROP_CONST (daemon->https_mem_cert);
    567     cert.size = (unsigned int) param2len;
    568 
    569     if (NULL != daemon->https_key_password)
    570     {
    571 #if GNUTLS_VERSION_NUMBER >= 0x030111
    572       ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
    573                                                   &cert,
    574                                                   &key,
    575                                                   GNUTLS_X509_FMT_PEM,
    576                                                   daemon->https_key_password,
    577                                                   0);
    578 #else
    579 #ifdef HAVE_MESSAGES
    580       MHD_DLOG (daemon,
    581                 _ ("Failed to setup x509 certificate/key: pre 3.X.X version " \
    582                    "of GnuTLS does not support setting key password.\n"));
    583 #endif
    584       return -1;
    585 #endif
    586     }
    587     else
    588       ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
    589                                                  &cert,
    590                                                  &key,
    591                                                  GNUTLS_X509_FMT_PEM);
    592 #ifdef HAVE_MESSAGES
    593     if (0 != ret)
    594       MHD_DLOG (daemon,
    595                 _ ("GnuTLS failed to setup x509 certificate/key: %s\n"),
    596                 gnutls_strerror (ret));
    597 #endif
    598     return ret;
    599   }
    600 #if GNUTLS_VERSION_MAJOR >= 3
    601   if (NULL != daemon->cert_callback)
    602     return 0;
    603 #endif
    604 #if GNUTLS_VERSION_NUMBER >= 0x030603
    605   else if (NULL != daemon->cert_callback2)
    606     return 0;
    607 #endif
    608 #ifdef HAVE_MESSAGES
    609   MHD_DLOG (daemon,
    610             _ ("You need to specify a certificate and key location.\n"));
    611 #endif
    612   return -1;
    613 }
    614 
    615 
    616 /**
    617  * Initialize security aspects of the HTTPS daemon
    618  *
    619  * @param daemon handle to daemon to initialize
    620  * @return 0 on success
    621  */
    622 static int
    623 MHD_TLS_init (struct MHD_Daemon *daemon)
    624 {
    625   switch (daemon->cred_type)
    626   {
    627   case GNUTLS_CRD_CERTIFICATE:
    628     if (0 !=
    629         gnutls_certificate_allocate_credentials (&daemon->x509_cred))
    630       return GNUTLS_E_MEMORY_ERROR;
    631     return MHD_init_daemon_certificate (daemon);
    632   case GNUTLS_CRD_PSK:
    633     if (0 !=
    634         gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
    635       return GNUTLS_E_MEMORY_ERROR;
    636     return 0;
    637   case GNUTLS_CRD_ANON:
    638   case GNUTLS_CRD_SRP:
    639   case GNUTLS_CRD_IA:
    640   default:
    641 #ifdef HAVE_MESSAGES
    642     MHD_DLOG (daemon,
    643               _ ("Error: invalid credentials type %d specified.\n"),
    644               daemon->cred_type);
    645 #endif
    646     return -1;
    647   }
    648 }
    649 
    650 
    651 #endif /* HTTPS_SUPPORT */
    652 
    653 
    654 #undef MHD_get_fdset
    655 
    656 /**
    657  * Obtain the `select()` sets for this daemon.
    658  * Daemon's FDs will be added to fd_sets. To get only
    659  * daemon FDs in fd_sets, call FD_ZERO for each fd_set
    660  * before calling this function. FD_SETSIZE is assumed
    661  * to be platform's default.
    662  *
    663  * This function should be called only when MHD is configured to
    664  * use "external" sockets polling with 'select()' or with 'epoll'.
    665  * In the latter case, it will only add the single 'epoll' file
    666  * descriptor used by MHD to the sets.
    667  * It's necessary to use #MHD_get_timeout() to get maximum timeout
    668  * value for `select()`. Usage of `select()` with indefinite timeout
    669  * (or timeout larger than returned by #MHD_get_timeout()) will
    670  * violate MHD API and may results in pending unprocessed data.
    671  *
    672  * This function must be called only for daemon started
    673  * without #MHD_USE_INTERNAL_POLLING_THREAD flag.
    674  *
    675  * @param daemon daemon to get sets from
    676  * @param read_fd_set read set
    677  * @param write_fd_set write set
    678  * @param except_fd_set except set
    679  * @param max_fd increased to largest FD added (if larger
    680  *               than existing value); can be NULL
    681  * @return #MHD_YES on success, #MHD_NO if this
    682  *         daemon was not started with the right
    683  *         options for this call or any FD didn't
    684  *         fit fd_set.
    685  * @ingroup event
    686  */
    687 _MHD_EXTERN enum MHD_Result
    688 MHD_get_fdset (struct MHD_Daemon *daemon,
    689                fd_set *read_fd_set,
    690                fd_set *write_fd_set,
    691                fd_set *except_fd_set,
    692                MHD_socket *max_fd)
    693 {
    694   return MHD_get_fdset2 (daemon,
    695                          read_fd_set,
    696                          write_fd_set,
    697                          except_fd_set,
    698                          max_fd,
    699 #ifdef HAS_FD_SETSIZE_OVERRIDABLE
    700                          daemon->fdset_size_set_by_app ?
    701                          ((unsigned int) daemon->fdset_size) :
    702                          ((unsigned int) _MHD_SYS_DEFAULT_FD_SETSIZE)
    703 #else  /* ! HAS_FD_SETSIZE_OVERRIDABLE */
    704                          ((unsigned int) _MHD_SYS_DEFAULT_FD_SETSIZE)
    705 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
    706                          );
    707 }
    708 
    709 
    710 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
    711 /**
    712  * Obtain the select() file descriptor sets for the
    713  * given @a urh.
    714  *
    715  * @param urh upgrade handle to wait for
    716  * @param[out] rs read set to initialize
    717  * @param[out] ws write set to initialize
    718  * @param[out] es except set to initialize
    719  * @param[out] max_fd maximum FD to update
    720  * @param fd_setsize value of FD_SETSIZE
    721  * @return true on success, false on error
    722  */
    723 static bool
    724 urh_to_fdset (struct MHD_UpgradeResponseHandle *urh,
    725               fd_set *rs,
    726               fd_set *ws,
    727               fd_set *es,
    728               MHD_socket *max_fd,
    729               int fd_setsize)
    730 {
    731   const MHD_socket conn_sckt = urh->connection->socket_fd;
    732   const MHD_socket mhd_sckt = urh->mhd.socket;
    733   bool res = true;
    734 
    735 #ifndef HAS_FD_SETSIZE_OVERRIDABLE
    736   (void) fd_setsize;  /* Mute compiler warning */
    737   fd_setsize = (int) FD_SETSIZE; /* Help compiler to optimise */
    738 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
    739 
    740   /* Do not add to 'es' only if socket is closed
    741    * or not used anymore. */
    742   if (MHD_INVALID_SOCKET != conn_sckt)
    743   {
    744     if ( (urh->in_buffer_used < urh->in_buffer_size) &&
    745          (! MHD_add_to_fd_set_ (conn_sckt,
    746                                 rs,
    747                                 max_fd,
    748                                 fd_setsize)) )
    749       res = false;
    750     if ( (0 != urh->out_buffer_used) &&
    751          (! MHD_add_to_fd_set_ (conn_sckt,
    752                                 ws,
    753                                 max_fd,
    754                                 fd_setsize)) )
    755       res = false;
    756     /* Do not monitor again for errors if error was detected before as
    757      * error state is remembered. */
    758     if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
    759         ((0 != urh->in_buffer_size) ||
    760          (0 != urh->out_buffer_size) ||
    761          (0 != urh->out_buffer_used))
    762         && (NULL != es))
    763       (void) MHD_add_to_fd_set_ (conn_sckt,
    764                                  es,
    765                                  max_fd,
    766                                  fd_setsize);
    767   }
    768   if (MHD_INVALID_SOCKET != mhd_sckt)
    769   {
    770     if ( (urh->out_buffer_used < urh->out_buffer_size) &&
    771          (! MHD_add_to_fd_set_ (mhd_sckt,
    772                                 rs,
    773                                 max_fd,
    774                                 fd_setsize)) )
    775       res = false;
    776     if ( (0 != urh->in_buffer_used) &&
    777          (! MHD_add_to_fd_set_ (mhd_sckt,
    778                                 ws,
    779                                 max_fd,
    780                                 fd_setsize)) )
    781       res = false;
    782     /* Do not monitor again for errors if error was detected before as
    783      * error state is remembered. */
    784     if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
    785         ((0 != urh->out_buffer_size) ||
    786          (0 != urh->in_buffer_size) ||
    787          (0 != urh->in_buffer_used))
    788         && (NULL != es))
    789       MHD_add_to_fd_set_ (mhd_sckt,
    790                           es,
    791                           max_fd,
    792                           fd_setsize);
    793   }
    794 
    795   return res;
    796 }
    797 
    798 
    799 /**
    800  * Update the @a urh based on the ready FDs in
    801  * the @a rs, @a ws, and @a es.
    802  *
    803  * @param urh upgrade handle to update
    804  * @param rs read result from select()
    805  * @param ws write result from select()
    806  * @param es except result from select()
    807  * @param fd_setsize value of FD_SETSIZE used when fd_sets were created
    808  */
    809 static void
    810 urh_from_fdset (struct MHD_UpgradeResponseHandle *urh,
    811                 const fd_set *rs,
    812                 const fd_set *ws,
    813                 const fd_set *es,
    814                 int fd_setsize)
    815 {
    816   const MHD_socket conn_sckt = urh->connection->socket_fd;
    817   const MHD_socket mhd_sckt = urh->mhd.socket;
    818 
    819   /* Reset read/write ready, preserve error state. */
    820   urh->app.celi &= (~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY)
    821                     & ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY));
    822   urh->mhd.celi &= (~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY)
    823                     & ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY));
    824 
    825   mhd_assert (urh->connection->sk_nonblck);
    826 
    827 #ifndef HAS_FD_SETSIZE_OVERRIDABLE
    828   (void) fd_setsize; /* Mute compiler warning */
    829   mhd_assert (((int) FD_SETSIZE) <= fd_setsize);
    830   fd_setsize = FD_SETSIZE; /* Help compiler to optimise */
    831 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
    832 
    833   if (MHD_INVALID_SOCKET != conn_sckt)
    834   {
    835     if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (conn_sckt, NULL, fd_setsize))
    836     {
    837       if (FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (rs)))
    838         urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
    839       if (FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (ws)))
    840         urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
    841       if ((NULL != es) &&
    842           FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (es)))
    843         urh->app.celi |= MHD_EPOLL_STATE_ERROR;
    844     }
    845     else
    846     { /* Cannot check readiness. Force ready state is safe as socket is non-blocking */
    847       urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
    848       urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
    849     }
    850   }
    851   if ((MHD_INVALID_SOCKET != mhd_sckt))
    852   {
    853     if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (mhd_sckt, NULL, fd_setsize))
    854     {
    855       if (FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (rs)))
    856         urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
    857       if (FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (ws)))
    858         urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
    859       if ((NULL != es) &&
    860           FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (es)))
    861         urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
    862     }
    863     else
    864     { /* Cannot check readiness. Force ready state is safe as socket is non-blocking */
    865       urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
    866       urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
    867     }
    868   }
    869 }
    870 
    871 
    872 #ifdef HAVE_POLL
    873 
    874 /**
    875  * Set required 'event' members in 'pollfd' elements,
    876  * assuming that @a p[0].fd is MHD side of socketpair
    877  * and @a p[1].fd is TLS connected socket.
    878  *
    879  * @param urh upgrade handle to watch for
    880  * @param p pollfd array to update
    881  */
    882 static void
    883 urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh,
    884                    struct pollfd p[2])
    885 {
    886   p[0].events = 0;
    887   p[1].events = 0;
    888 
    889   if (urh->in_buffer_used < urh->in_buffer_size)
    890     p[0].events |= POLLIN;
    891   if (0 != urh->out_buffer_used)
    892     p[0].events |= POLLOUT;
    893 
    894   /* Do not monitor again for errors if error was detected before as
    895    * error state is remembered. */
    896   if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
    897       ((0 != urh->in_buffer_size) ||
    898        (0 != urh->out_buffer_size) ||
    899        (0 != urh->out_buffer_used)))
    900     p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
    901 
    902   if (urh->out_buffer_used < urh->out_buffer_size)
    903     p[1].events |= POLLIN;
    904   if (0 != urh->in_buffer_used)
    905     p[1].events |= POLLOUT;
    906 
    907   /* Do not monitor again for errors if error was detected before as
    908    * error state is remembered. */
    909   if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
    910       ((0 != urh->out_buffer_size) ||
    911        (0 != urh->in_buffer_size) ||
    912        (0 != urh->in_buffer_used)))
    913     p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
    914 }
    915 
    916 
    917 /**
    918  * Set @a p to watch for @a urh.
    919  *
    920  * @param urh upgrade handle to watch for
    921  * @param p pollfd array to set
    922  */
    923 static void
    924 urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh,
    925                struct pollfd p[2])
    926 {
    927   p[0].fd = urh->connection->socket_fd;
    928   p[1].fd = urh->mhd.socket;
    929   urh_update_pollfd (urh,
    930                      p);
    931 }
    932 
    933 
    934 /**
    935  * Update ready state in @a urh based on pollfd.
    936  * @param urh upgrade handle to update
    937  * @param p 'poll()' processed pollfd.
    938  */
    939 static void
    940 urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh,
    941                  struct pollfd p[2])
    942 {
    943   /* Reset read/write ready, preserve error state. */
    944   urh->app.celi &= (~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY)
    945                     & ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY));
    946   urh->mhd.celi &= (~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY)
    947                     & ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY));
    948 
    949   if (0 != (p[0].revents & POLLIN))
    950     urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
    951   if (0 != (p[0].revents & POLLOUT))
    952     urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
    953   if (0 != (p[0].revents & POLLHUP))
    954     urh->app.celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
    955   if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
    956     urh->app.celi |= MHD_EPOLL_STATE_ERROR;
    957   if (0 != (p[1].revents & POLLIN))
    958     urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
    959   if (0 != (p[1].revents & POLLOUT))
    960     urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
    961   if (0 != (p[1].revents & POLLHUP))
    962     urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
    963   if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
    964     urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
    965 }
    966 
    967 
    968 #endif /* HAVE_POLL */
    969 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
    970 
    971 
    972 /**
    973  * Internal version of #MHD_get_fdset2().
    974  *
    975  * @param daemon daemon to get sets from
    976  * @param read_fd_set read set
    977  * @param write_fd_set write set
    978  * @param except_fd_set except set
    979  * @param max_fd increased to largest FD added (if larger
    980  *               than existing value); can be NULL
    981  * @param fd_setsize value of FD_SETSIZE
    982  * @return #MHD_YES on success, #MHD_NO if any FD didn't
    983  *         fit fd_set.
    984  * @ingroup event
    985  */
    986 static enum MHD_Result
    987 internal_get_fdset2 (struct MHD_Daemon *daemon,
    988                      fd_set *read_fd_set,
    989                      fd_set *write_fd_set,
    990                      fd_set *except_fd_set,
    991                      MHD_socket *max_fd,
    992                      int fd_setsize)
    993 {
    994   struct MHD_Connection *pos;
    995   struct MHD_Connection *posn;
    996   enum MHD_Result result = MHD_YES;
    997   MHD_socket ls;
    998   bool itc_added;
    999 
   1000 #ifndef HAS_FD_SETSIZE_OVERRIDABLE
   1001   (void) fd_setsize;  /* Mute compiler warning */
   1002   fd_setsize = (int) FD_SETSIZE; /* Help compiler to optimise */
   1003 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   1004 
   1005   if (daemon->shutdown)
   1006     return MHD_YES;
   1007 
   1008   /* The order of FDs added is important for W32 sockets as W32 fd_set has
   1009      limits for number of added FDs instead of the limit for the higher
   1010      FD value. */
   1011 
   1012   /* Add ITC FD first. The daemon must be able to respond on application
   1013      commands issued in other threads. */
   1014   itc_added = false;
   1015   if (MHD_ITC_IS_VALID_ (daemon->itc))
   1016   {
   1017     itc_added = MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
   1018                                     read_fd_set,
   1019                                     max_fd,
   1020                                     fd_setsize);
   1021     if (! itc_added)
   1022       result = MHD_NO;
   1023   }
   1024 
   1025   ls = daemon->was_quiesced ? MHD_INVALID_SOCKET : daemon->listen_fd;
   1026   if (! itc_added &&
   1027       (MHD_INVALID_SOCKET != ls))
   1028   {
   1029     /* Add listen FD if ITC was not added. Listen FD could be used to signal
   1030        the daemon shutdown. */
   1031     if (MHD_add_to_fd_set_ (ls,
   1032                             read_fd_set,
   1033                             max_fd,
   1034                             fd_setsize))
   1035       ls = MHD_INVALID_SOCKET;   /* Already added */
   1036     else
   1037       result = MHD_NO;
   1038   }
   1039 
   1040   /* Add all sockets to 'except_fd_set' as well to watch for
   1041    * out-of-band data. However, ignore errors if INFO_READ
   1042    * or INFO_WRITE sockets will not fit 'except_fd_set'. */
   1043   /* Start from oldest connections. Make sense for W32 FDSETs. */
   1044   for (pos = daemon->connections_tail; NULL != pos; pos = posn)
   1045   {
   1046     posn = pos->prev;
   1047 
   1048     switch (pos->event_loop_info)
   1049     {
   1050     case MHD_EVENT_LOOP_INFO_READ:
   1051     case MHD_EVENT_LOOP_INFO_PROCESS_READ:
   1052       if (! MHD_add_to_fd_set_ (pos->socket_fd,
   1053                                 read_fd_set,
   1054                                 max_fd,
   1055                                 fd_setsize))
   1056         result = MHD_NO;
   1057 #ifdef MHD_POSIX_SOCKETS
   1058       if (NULL != except_fd_set)
   1059         (void) MHD_add_to_fd_set_ (pos->socket_fd,
   1060                                    except_fd_set,
   1061                                    max_fd,
   1062                                    fd_setsize);
   1063 #endif /* MHD_POSIX_SOCKETS */
   1064       break;
   1065     case MHD_EVENT_LOOP_INFO_WRITE:
   1066       if (! MHD_add_to_fd_set_ (pos->socket_fd,
   1067                                 write_fd_set,
   1068                                 max_fd,
   1069                                 fd_setsize))
   1070         result = MHD_NO;
   1071 #ifdef MHD_POSIX_SOCKETS
   1072       if (NULL != except_fd_set)
   1073         (void) MHD_add_to_fd_set_ (pos->socket_fd,
   1074                                    except_fd_set,
   1075                                    max_fd,
   1076                                    fd_setsize);
   1077 #endif /* MHD_POSIX_SOCKETS */
   1078       break;
   1079     case MHD_EVENT_LOOP_INFO_PROCESS:
   1080       if ( (NULL == except_fd_set) ||
   1081            ! MHD_add_to_fd_set_ (pos->socket_fd,
   1082                                  except_fd_set,
   1083                                  max_fd,
   1084                                  fd_setsize))
   1085         result = MHD_NO;
   1086       break;
   1087     case MHD_EVENT_LOOP_INFO_CLEANUP:
   1088       /* this should never happen */
   1089       break;
   1090     }
   1091   }
   1092 #ifdef MHD_WINSOCK_SOCKETS
   1093   /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets
   1094    * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will
   1095    * not be pushed out. */
   1096   if (NULL != except_fd_set)
   1097   {
   1098     for (pos = daemon->connections_tail; NULL != pos; pos = posn)
   1099     {
   1100       posn = pos->prev;
   1101       MHD_add_to_fd_set_ (pos->socket_fd,
   1102                           except_fd_set,
   1103                           max_fd,
   1104                           fd_setsize);
   1105     }
   1106   }
   1107 #endif /* MHD_WINSOCK_SOCKETS */
   1108 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   1109   if (1)
   1110   {
   1111     struct MHD_UpgradeResponseHandle *urh;
   1112 
   1113     for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
   1114     {
   1115       if (MHD_NO ==
   1116           urh_to_fdset (urh,
   1117                         read_fd_set,
   1118                         write_fd_set,
   1119                         except_fd_set,
   1120                         max_fd,
   1121                         fd_setsize))
   1122         result = MHD_NO;
   1123     }
   1124   }
   1125 #endif
   1126 
   1127   if (MHD_INVALID_SOCKET != ls)
   1128   {
   1129     /* The listen socket is present and hasn't been added */
   1130     if ((daemon->connections < daemon->connection_limit) &&
   1131         ! daemon->at_limit)
   1132     {
   1133       if (! MHD_add_to_fd_set_ (ls,
   1134                                 read_fd_set,
   1135                                 max_fd,
   1136                                 fd_setsize))
   1137         result = MHD_NO;
   1138     }
   1139   }
   1140 
   1141 #if _MHD_DEBUG_CONNECT
   1142 #ifdef HAVE_MESSAGES
   1143   if (NULL != max_fd)
   1144     MHD_DLOG (daemon,
   1145               _ ("Maximum socket in select set: %d\n"),
   1146               *max_fd);
   1147 #endif
   1148 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   1149   return result;
   1150 }
   1151 
   1152 
   1153 /**
   1154  * Obtain the `select()` sets for this daemon.
   1155  * Daemon's FDs will be added to fd_sets. To get only
   1156  * daemon FDs in fd_sets, call FD_ZERO for each fd_set
   1157  * before calling this function.
   1158  *
   1159  * Passing custom FD_SETSIZE as @a fd_setsize allow usage of
   1160  * larger/smaller than platform's default fd_sets.
   1161  *
   1162  * This function should be called only when MHD is configured to
   1163  * use "external" sockets polling with 'select()' or with 'epoll'.
   1164  * In the latter case, it will only add the single 'epoll' file
   1165  * descriptor used by MHD to the sets.
   1166  * It's necessary to use #MHD_get_timeout() to get maximum timeout
   1167  * value for `select()`. Usage of `select()` with indefinite timeout
   1168  * (or timeout larger than returned by #MHD_get_timeout()) will
   1169  * violate MHD API and may results in pending unprocessed data.
   1170  *
   1171  * This function must be called only for daemon started
   1172  * without #MHD_USE_INTERNAL_POLLING_THREAD flag.
   1173  *
   1174  * @param daemon daemon to get sets from
   1175  * @param read_fd_set read set
   1176  * @param write_fd_set write set
   1177  * @param except_fd_set except set
   1178  * @param max_fd increased to largest FD added (if larger
   1179  *               than existing value); can be NULL
   1180  * @param fd_setsize value of FD_SETSIZE
   1181  * @return #MHD_YES on success, #MHD_NO if this
   1182  *         daemon was not started with the right
   1183  *         options for this call or any FD didn't
   1184  *         fit fd_set.
   1185  * @ingroup event
   1186  */
   1187 _MHD_EXTERN enum MHD_Result
   1188 MHD_get_fdset2 (struct MHD_Daemon *daemon,
   1189                 fd_set *read_fd_set,
   1190                 fd_set *write_fd_set,
   1191                 fd_set *except_fd_set,
   1192                 MHD_socket *max_fd,
   1193                 unsigned int fd_setsize)
   1194 {
   1195   if ( (NULL == daemon) ||
   1196        (NULL == read_fd_set) ||
   1197        (NULL == write_fd_set) ||
   1198        MHD_D_IS_USING_THREADS_ (daemon) ||
   1199        MHD_D_IS_USING_POLL_ (daemon))
   1200     return MHD_NO;
   1201 
   1202 #ifdef HAVE_MESSAGES
   1203   if (NULL == except_fd_set)
   1204   {
   1205     MHD_DLOG (daemon,
   1206               _ ("MHD_get_fdset2() called with except_fd_set "
   1207                  "set to NULL. Such behavior is unsupported.\n"));
   1208   }
   1209 #endif
   1210 
   1211 #ifdef HAS_FD_SETSIZE_OVERRIDABLE
   1212   if (0 == fd_setsize)
   1213     return MHD_NO;
   1214   else if (((unsigned int) INT_MAX) < fd_setsize)
   1215     fd_setsize = (unsigned int) INT_MAX;
   1216 #ifdef HAVE_MESSAGES
   1217   else if (daemon->fdset_size > ((int) fd_setsize))
   1218   {
   1219     if (daemon->fdset_size_set_by_app)
   1220     {
   1221       MHD_DLOG (daemon,
   1222                 _ ("%s() called with fd_setsize (%u) " \
   1223                    "less than value set by MHD_OPTION_APP_FD_SETSIZE (%d). " \
   1224                    "Some socket FDs may be not processed. " \
   1225                    "Use MHD_OPTION_APP_FD_SETSIZE with the correct value.\n"),
   1226                 "MHD_get_fdset2", fd_setsize, daemon->fdset_size);
   1227     }
   1228     else
   1229     {
   1230       MHD_DLOG (daemon,
   1231                 _ ("%s() called with fd_setsize (%u) " \
   1232                    "less than FD_SETSIZE used by MHD (%d). " \
   1233                    "Some socket FDs may be not processed. " \
   1234                    "Consider using MHD_OPTION_APP_FD_SETSIZE option.\n"),
   1235                 "MHD_get_fdset2", fd_setsize, daemon->fdset_size);
   1236     }
   1237   }
   1238 #endif /* HAVE_MESSAGES */
   1239 #else  /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   1240   if (((unsigned int) FD_SETSIZE) > fd_setsize)
   1241   {
   1242 #ifdef HAVE_MESSAGES
   1243     MHD_DLOG (daemon,
   1244               _ ("%s() called with fd_setsize (%u) " \
   1245                  "less than fixed FD_SETSIZE value (%d) used on the " \
   1246                  "platform.\n"),
   1247               "MHD_get_fdset2", fd_setsize, (int) FD_SETSIZE);
   1248 #endif /* HAVE_MESSAGES */
   1249     return MHD_NO;
   1250   }
   1251   fd_setsize = (int) FD_SETSIZE; /* Help compiler to optimise */
   1252 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   1253 
   1254 #ifdef EPOLL_SUPPORT
   1255   if (MHD_D_IS_USING_EPOLL_ (daemon))
   1256   {
   1257     if (daemon->shutdown)
   1258       return MHD_YES;
   1259 
   1260     /* we're in epoll mode, use the epoll FD as a stand-in for
   1261        the entire event set */
   1262 
   1263     return MHD_add_to_fd_set_ (daemon->epoll_fd,
   1264                                read_fd_set,
   1265                                max_fd,
   1266                                (int) fd_setsize) ? MHD_YES : MHD_NO;
   1267   }
   1268 #endif
   1269 
   1270   return internal_get_fdset2 (daemon,
   1271                               read_fd_set,
   1272                               write_fd_set,
   1273                               except_fd_set,
   1274                               max_fd,
   1275                               (int) fd_setsize);
   1276 }
   1277 
   1278 
   1279 /**
   1280  * Call the handlers for a connection in the appropriate order based
   1281  * on the readiness as detected by the event loop.
   1282  *
   1283  * @param con connection to handle
   1284  * @param read_ready set if the socket is ready for reading
   1285  * @param write_ready set if the socket is ready for writing
   1286  * @param force_close set if a hard error was detected on the socket;
   1287  *        if this information is not available, simply pass #MHD_NO
   1288  * @return #MHD_YES to continue normally,
   1289  *         #MHD_NO if a serious error was encountered and the
   1290  *         connection is to be closed.
   1291  */
   1292 static enum MHD_Result
   1293 call_handlers (struct MHD_Connection *con,
   1294                bool read_ready,
   1295                bool write_ready,
   1296                bool force_close)
   1297 {
   1298   enum MHD_Result ret;
   1299   bool states_info_processed = false;
   1300   /* Fast track flag */
   1301   bool on_fasttrack = (con->state == MHD_CONNECTION_INIT);
   1302   ret = MHD_YES;
   1303 
   1304   mhd_assert ((0 == (con->daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   1305               (MHD_thread_handle_ID_is_valid_ID_ (con->tid)));
   1306   mhd_assert ((0 != (con->daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   1307               (! MHD_thread_handle_ID_is_valid_ID_ (con->tid)));
   1308   mhd_assert ((0 == (con->daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   1309               (MHD_thread_handle_ID_is_current_thread_ (con->tid)));
   1310 
   1311 #ifdef HTTPS_SUPPORT
   1312   if (con->tls_read_ready)
   1313     read_ready = true;
   1314 #endif /* HTTPS_SUPPORT */
   1315   if ( (0 != (MHD_EVENT_LOOP_INFO_READ & con->event_loop_info)) &&
   1316        (read_ready || (force_close && con->sk_nonblck)) )
   1317   {
   1318     MHD_connection_handle_read (con, force_close);
   1319     mhd_assert (! force_close || MHD_CONNECTION_CLOSED == con->state);
   1320     ret = MHD_connection_handle_idle (con);
   1321     if (force_close)
   1322       return ret;
   1323     states_info_processed = true;
   1324   }
   1325   if (! force_close)
   1326   {
   1327     /* No need to check value of 'ret' here as closed connection
   1328      * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */
   1329     if ( (MHD_EVENT_LOOP_INFO_WRITE == con->event_loop_info) &&
   1330          write_ready)
   1331     {
   1332       MHD_connection_handle_write (con);
   1333       ret = MHD_connection_handle_idle (con);
   1334       states_info_processed = true;
   1335     }
   1336   }
   1337   else
   1338   {
   1339     MHD_connection_close_ (con,
   1340                            MHD_REQUEST_TERMINATED_WITH_ERROR);
   1341     return MHD_connection_handle_idle (con);
   1342   }
   1343 
   1344   if (! states_info_processed)
   1345   {   /* Connection is not read or write ready, but external conditions
   1346        * may be changed and need to be processed. */
   1347     ret = MHD_connection_handle_idle (con);
   1348   }
   1349   /* Fast track for fast connections. */
   1350   /* If full request was read by single read_handler() invocation
   1351      and headers were completely prepared by single MHD_connection_handle_idle()
   1352      then try not to wait for next sockets polling and send response
   1353      immediately.
   1354      As writeability of socket was not checked and it may have
   1355      some data pending in system buffers, use this optimization
   1356      only for non-blocking sockets. */
   1357   /* No need to check 'ret' as connection is always in
   1358    * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */
   1359   else if (on_fasttrack && con->sk_nonblck)
   1360   {
   1361     if (MHD_CONNECTION_HEADERS_SENDING == con->state)
   1362     {
   1363       MHD_connection_handle_write (con);
   1364       /* Always call 'MHD_connection_handle_idle()' after each read/write. */
   1365       ret = MHD_connection_handle_idle (con);
   1366     }
   1367     /* If all headers were sent by single write_handler() and
   1368      * response body is prepared by single MHD_connection_handle_idle()
   1369      * call - continue. */
   1370     if ((MHD_CONNECTION_NORMAL_BODY_READY == con->state) ||
   1371         (MHD_CONNECTION_CHUNKED_BODY_READY == con->state))
   1372     {
   1373       MHD_connection_handle_write (con);
   1374       ret = MHD_connection_handle_idle (con);
   1375     }
   1376   }
   1377 
   1378   /* All connection's data and states are processed for this turn.
   1379    * If connection already has more data to be processed - use
   1380    * zero timeout for next select()/poll(). */
   1381   /* Thread-per-connection do not need global zero timeout as
   1382    * connections are processed individually. */
   1383   /* Note: no need to check for read buffer availability for
   1384    * TLS read-ready connection in 'read info' state as connection
   1385    * without space in read buffer will be marked as 'info block'. */
   1386   if ( (! con->daemon->data_already_pending) &&
   1387        (! MHD_D_IS_USING_THREAD_PER_CONN_ (con->daemon)) )
   1388   {
   1389     if (0 != (MHD_EVENT_LOOP_INFO_PROCESS & con->event_loop_info))
   1390       con->daemon->data_already_pending = true;
   1391 #ifdef HTTPS_SUPPORT
   1392     else if ( (con->tls_read_ready) &&
   1393               (0 != (MHD_EVENT_LOOP_INFO_READ & con->event_loop_info)) )
   1394       con->daemon->data_already_pending = true;
   1395 #endif /* HTTPS_SUPPORT */
   1396   }
   1397   return ret;
   1398 }
   1399 
   1400 
   1401 #ifdef UPGRADE_SUPPORT
   1402 /**
   1403  * Finally cleanup upgrade-related resources. It should
   1404  * be called when TLS buffers have been drained and
   1405  * application signaled MHD by #MHD_UPGRADE_ACTION_CLOSE.
   1406  *
   1407  * @param connection handle to the upgraded connection to clean
   1408  */
   1409 static void
   1410 cleanup_upgraded_connection (struct MHD_Connection *connection)
   1411 {
   1412   struct MHD_UpgradeResponseHandle *urh = connection->urh;
   1413 
   1414   if (NULL == urh)
   1415     return;
   1416 #ifdef HTTPS_SUPPORT
   1417   /* Signal remote client the end of TLS connection by
   1418    * gracefully closing TLS session. */
   1419   if (0 != (connection->daemon->options & MHD_USE_TLS))
   1420     gnutls_bye (connection->tls_session,
   1421                 GNUTLS_SHUT_WR);
   1422 
   1423   if (MHD_INVALID_SOCKET != urh->mhd.socket)
   1424     MHD_socket_close_chk_ (urh->mhd.socket);
   1425 
   1426   if (MHD_INVALID_SOCKET != urh->app.socket)
   1427     MHD_socket_close_chk_ (urh->app.socket);
   1428 #endif /* HTTPS_SUPPORT */
   1429   connection->urh = NULL;
   1430   free (urh);
   1431 }
   1432 
   1433 
   1434 #endif /* UPGRADE_SUPPORT */
   1435 
   1436 
   1437 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   1438 /**
   1439  * Performs bi-directional forwarding on upgraded HTTPS connections
   1440  * based on the readiness state stored in the @a urh handle.
   1441  * @remark To be called only from thread that processes
   1442  * connection's recv(), send() and response.
   1443  *
   1444  * @param urh handle to process
   1445  */
   1446 static void
   1447 process_urh (struct MHD_UpgradeResponseHandle *urh)
   1448 {
   1449   /* Help compiler to optimize:
   1450    * pointers to 'connection' and 'daemon' are not changed
   1451    * during this processing, so no need to chain dereference
   1452    * each time. */
   1453   struct MHD_Connection *const connection = urh->connection;
   1454   struct MHD_Daemon *const daemon = connection->daemon;
   1455   /* Prevent data races: use same value of 'was_closed' throughout
   1456    * this function. If 'was_closed' changed externally in the middle
   1457    * of processing - it will be processed on next iteration. */
   1458   bool was_closed;
   1459 
   1460 #ifdef MHD_USE_THREADS
   1461   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   1462                MHD_thread_handle_ID_is_current_thread_ (connection->tid) );
   1463 #endif /* MHD_USE_THREADS */
   1464 
   1465   mhd_assert (0 != (daemon->options & MHD_USE_TLS));
   1466 
   1467   if (daemon->shutdown)
   1468   {
   1469     /* Daemon shutting down, application will not receive any more data. */
   1470 #ifdef HAVE_MESSAGES
   1471     if (! urh->was_closed)
   1472     {
   1473       MHD_DLOG (daemon,
   1474                 _ ("Initiated daemon shutdown while \"upgraded\" " \
   1475                    "connection was not closed.\n"));
   1476     }
   1477 #endif
   1478     urh->was_closed = true;
   1479   }
   1480   was_closed = urh->was_closed;
   1481   if (was_closed)
   1482   {
   1483     /* Application was closed connections: no more data
   1484      * can be forwarded to application socket. */
   1485     if (0 < urh->in_buffer_used)
   1486     {
   1487 #ifdef HAVE_MESSAGES
   1488       MHD_DLOG (daemon,
   1489                 _ ("Failed to forward to application %" PRIu64 \
   1490                    " bytes of data received from remote side: " \
   1491                    "application closed data forwarding.\n"),
   1492                 (uint64_t) urh->in_buffer_used);
   1493 #endif
   1494 
   1495     }
   1496     /* Discard any data received form remote. */
   1497     urh->in_buffer_used = 0;
   1498     /* Do not try to push data to application. */
   1499     urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY);
   1500     /* Reading from remote client is not required anymore. */
   1501     urh->in_buffer_size = 0;
   1502     urh->app.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY);
   1503     connection->tls_read_ready = false;
   1504   }
   1505 
   1506   /* On some platforms (W32, possibly Darwin) failed send() (send() will
   1507    * always fail after remote disconnect was detected) may discard data in
   1508    * system buffers received by system but not yet read by recv().  So, before
   1509    * trying send() on any socket, recv() must be performed at first otherwise
   1510    * last part of incoming data may be lost.  If disconnect or error was
   1511    * detected - try to read from socket to dry data possibly pending is system
   1512    * buffers. */
   1513 
   1514   /*
   1515    * handle reading from remote TLS client
   1516    */
   1517   if (((0 != ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY)
   1518               & urh->app.celi)) ||
   1519        (connection->tls_read_ready)) &&
   1520       (urh->in_buffer_used < urh->in_buffer_size))
   1521   {
   1522     ssize_t res;
   1523     size_t buf_size;
   1524 
   1525     buf_size = urh->in_buffer_size - urh->in_buffer_used;
   1526     if (buf_size > SSIZE_MAX)
   1527       buf_size = SSIZE_MAX;
   1528 
   1529     res = gnutls_record_recv (connection->tls_session,
   1530                               &urh->in_buffer[urh->in_buffer_used],
   1531                               buf_size);
   1532     if (0 >= res)
   1533     {
   1534       connection->tls_read_ready = false;
   1535       if (GNUTLS_E_INTERRUPTED != res)
   1536       {
   1537         urh->app.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY);
   1538         if ((GNUTLS_E_AGAIN != res) ||
   1539             (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)))
   1540         {
   1541           /* TLS unrecoverable error has been detected,
   1542              socket error was detected and all data has been read,
   1543              or socket was disconnected/shut down. */
   1544           /* Stop trying to read from this TLS socket. */
   1545           urh->in_buffer_size = 0;
   1546         }
   1547       }
   1548     }
   1549     else   /* 0 < res */
   1550     {
   1551       urh->in_buffer_used += (size_t) res;
   1552       connection->tls_read_ready =
   1553         (0 < gnutls_record_check_pending (connection->tls_session));
   1554     }
   1555   }
   1556 
   1557   /*
   1558    * handle reading from application
   1559    */
   1560   /* If application signalled MHD about socket closure then
   1561    * check for any pending data even if socket is not marked
   1562    * as 'ready' (signal may arrive after poll()/select()).
   1563    * Socketpair for forwarding is always in non-blocking mode
   1564    * so no risk that recv() will block the thread. */
   1565   if (((0 != ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY)
   1566               & urh->mhd.celi))
   1567        || was_closed) /* Force last reading from app if app has closed the connection */
   1568       && (urh->out_buffer_used < urh->out_buffer_size))
   1569   {
   1570     ssize_t res;
   1571     size_t buf_size;
   1572 
   1573     buf_size = urh->out_buffer_size - urh->out_buffer_used;
   1574     if (buf_size > MHD_SCKT_SEND_MAX_SIZE_)
   1575       buf_size = MHD_SCKT_SEND_MAX_SIZE_;
   1576 
   1577     res = MHD_recv_ (urh->mhd.socket,
   1578                      &urh->out_buffer[urh->out_buffer_used],
   1579                      buf_size);
   1580     if (0 >= res)
   1581     {
   1582       const int err = MHD_socket_get_error_ ();
   1583       if ((0 == res) ||
   1584           ((! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
   1585            (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err))))
   1586       {
   1587         urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY);
   1588         if ((0 == res) ||
   1589             (was_closed) ||
   1590             (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
   1591             (! MHD_SCKT_ERR_IS_EAGAIN_ (err)))
   1592         {
   1593           /* Socket disconnect/shutdown was detected;
   1594            * Application signalled about closure of 'upgraded' socket and
   1595            * all data has been read from application;
   1596            * or persistent / unrecoverable error. */
   1597           /* Do not try to pull more data from application. */
   1598           urh->out_buffer_size = 0;
   1599         }
   1600       }
   1601     }
   1602     else   /* 0 < res */
   1603     {
   1604       urh->out_buffer_used += (size_t) res;
   1605       if (buf_size > (size_t) res)
   1606         urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY);
   1607     }
   1608   }
   1609 
   1610   /*
   1611    * handle writing to remote HTTPS client
   1612    */
   1613   if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
   1614        (urh->out_buffer_used > 0) )
   1615   {
   1616     ssize_t res;
   1617     size_t data_size;
   1618 
   1619     data_size = urh->out_buffer_used;
   1620     if (data_size > SSIZE_MAX)
   1621       data_size = SSIZE_MAX;
   1622 
   1623     res = gnutls_record_send (connection->tls_session,
   1624                               urh->out_buffer,
   1625                               data_size);
   1626     if (0 >= res)
   1627     {
   1628       if (GNUTLS_E_INTERRUPTED != res)
   1629       {
   1630         urh->app.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY);
   1631         if (GNUTLS_E_AGAIN != res)
   1632         {
   1633           /* TLS connection shut down or
   1634            * persistent / unrecoverable error. */
   1635 #ifdef HAVE_MESSAGES
   1636           MHD_DLOG (daemon,
   1637                     _ ("Failed to forward to remote client %" PRIu64 \
   1638                        " bytes of data received from application: %s\n"),
   1639                     (uint64_t) urh->out_buffer_used,
   1640                     gnutls_strerror ((int) res));
   1641 #endif
   1642           /* Discard any data unsent to remote. */
   1643           urh->out_buffer_used = 0;
   1644           /* Do not try to pull more data from application. */
   1645           urh->out_buffer_size = 0;
   1646           urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY);
   1647         }
   1648       }
   1649     }
   1650     else   /* 0 < res */
   1651     {
   1652       const size_t next_out_buffer_used = urh->out_buffer_used - (size_t) res;
   1653       if (0 != next_out_buffer_used)
   1654       {
   1655         memmove (urh->out_buffer,
   1656                  &urh->out_buffer[res],
   1657                  next_out_buffer_used);
   1658       }
   1659       urh->out_buffer_used = next_out_buffer_used;
   1660     }
   1661     if ( (0 == urh->out_buffer_used) &&
   1662          (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) )
   1663     {
   1664       /* Unrecoverable error on socket was detected and all
   1665        * pending data was sent to remote. */
   1666       /* Do not try to send to remote anymore. */
   1667       urh->app.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY);
   1668       /* Do not try to pull more data from application. */
   1669       urh->out_buffer_size = 0;
   1670       urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY);
   1671     }
   1672   }
   1673 
   1674   /*
   1675    * handle writing to application
   1676    */
   1677   if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
   1678        (urh->in_buffer_used > 0) )
   1679   {
   1680     ssize_t res;
   1681     size_t data_size;
   1682 
   1683     data_size = urh->in_buffer_used;
   1684     if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
   1685       data_size = MHD_SCKT_SEND_MAX_SIZE_;
   1686 
   1687     res = MHD_send_ (urh->mhd.socket,
   1688                      urh->in_buffer,
   1689                      data_size);
   1690     if (0 >= res)
   1691     {
   1692       const int err = MHD_socket_get_error_ ();
   1693       if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
   1694            (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err)) )
   1695       {
   1696         urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY);
   1697         if (! MHD_SCKT_ERR_IS_EAGAIN_ (err))
   1698         {
   1699           /* Socketpair connection shut down or
   1700            * persistent / unrecoverable error. */
   1701 #ifdef HAVE_MESSAGES
   1702           MHD_DLOG (daemon,
   1703                     _ ("Failed to forward to application %" PRIu64 \
   1704                        " bytes of data received from remote side: %s\n"),
   1705                     (uint64_t) urh->in_buffer_used,
   1706                     MHD_socket_strerr_ (err));
   1707 #endif
   1708           /* Discard any data received from remote. */
   1709           urh->in_buffer_used = 0;
   1710           /* Reading from remote client is not required anymore. */
   1711           urh->in_buffer_size = 0;
   1712           urh->app.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY);
   1713           connection->tls_read_ready = false;
   1714         }
   1715       }
   1716     }
   1717     else   /* 0 < res */
   1718     {
   1719       const size_t next_in_buffer_used = urh->in_buffer_used - (size_t) res;
   1720       if (0 != next_in_buffer_used)
   1721       {
   1722         memmove (urh->in_buffer,
   1723                  &urh->in_buffer[res],
   1724                  next_in_buffer_used);
   1725         if (data_size > (size_t) res)
   1726           urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY);
   1727       }
   1728       urh->in_buffer_used = next_in_buffer_used;
   1729     }
   1730     if ( (0 == urh->in_buffer_used) &&
   1731          (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) )
   1732     {
   1733       /* Do not try to push data to application. */
   1734       urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY);
   1735       /* Reading from remote client is not required anymore. */
   1736       urh->in_buffer_size = 0;
   1737       urh->app.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY);
   1738       connection->tls_read_ready = false;
   1739     }
   1740   }
   1741 
   1742   /* Check whether data is present in TLS buffers
   1743    * and incoming forward buffer have some space. */
   1744   if ( (connection->tls_read_ready) &&
   1745        (urh->in_buffer_used < urh->in_buffer_size) &&
   1746        (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) )
   1747     daemon->data_already_pending = true;
   1748 
   1749   if ( (daemon->shutdown) &&
   1750        ( (0 != urh->out_buffer_size) ||
   1751          (0 != urh->out_buffer_used) ) )
   1752   {
   1753     /* Daemon shutting down, discard any remaining forward data. */
   1754 #ifdef HAVE_MESSAGES
   1755     if (0 < urh->out_buffer_used)
   1756       MHD_DLOG (daemon,
   1757                 _ ("Failed to forward to remote client %" PRIu64 \
   1758                    " bytes of data received from application: daemon shut down.\n"),
   1759                 (uint64_t) urh->out_buffer_used);
   1760 #endif
   1761     /* Discard any data unsent to remote. */
   1762     urh->out_buffer_used = 0;
   1763     /* Do not try to sent to remote anymore. */
   1764     urh->app.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY);
   1765     /* Do not try to pull more data from application. */
   1766     urh->out_buffer_size = 0;
   1767     urh->mhd.celi &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY);
   1768   }
   1769 
   1770   if (! was_closed && urh->was_closed)
   1771     daemon->data_already_pending = true; /* Force processing again */
   1772 }
   1773 
   1774 
   1775 #endif /* HTTPS_SUPPORT  && UPGRADE_SUPPORT */
   1776 
   1777 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   1778 #ifdef UPGRADE_SUPPORT
   1779 /**
   1780  * Main function of the thread that handles an individual connection
   1781  * after it was "upgraded" when #MHD_USE_THREAD_PER_CONNECTION is set.
   1782  * @remark To be called only from thread that process
   1783  * connection's recv(), send() and response.
   1784  *
   1785  * @param con the connection this thread will handle
   1786  */
   1787 static void
   1788 thread_main_connection_upgrade (struct MHD_Connection *con)
   1789 {
   1790 #ifdef HTTPS_SUPPORT
   1791   struct MHD_UpgradeResponseHandle *urh = con->urh;
   1792   struct MHD_Daemon *daemon = con->daemon;
   1793 
   1794   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   1795                MHD_thread_handle_ID_is_current_thread_ (con->tid) );
   1796   /* Here, we need to bi-directionally forward
   1797      until the application tells us that it is done
   1798      with the socket; */
   1799   if ( (0 != (daemon->options & MHD_USE_TLS)) &&
   1800        MHD_D_IS_USING_SELECT_ (daemon))
   1801   {
   1802     while ( (0 != urh->in_buffer_size) ||
   1803             (0 != urh->out_buffer_size) ||
   1804             (0 != urh->in_buffer_used) ||
   1805             (0 != urh->out_buffer_used) )
   1806     {
   1807       /* use select */
   1808       fd_set rs;
   1809       fd_set ws;
   1810       fd_set es;
   1811       MHD_socket max_fd;
   1812       int num_ready;
   1813       bool result;
   1814 
   1815       FD_ZERO (&rs);
   1816       FD_ZERO (&ws);
   1817       FD_ZERO (&es);
   1818       max_fd = MHD_INVALID_SOCKET;
   1819       result = urh_to_fdset (urh,
   1820                              &rs,
   1821                              &ws,
   1822                              &es,
   1823                              &max_fd,
   1824                              FD_SETSIZE);
   1825       if (! result)
   1826       {
   1827 #ifdef HAVE_MESSAGES
   1828         MHD_DLOG (con->daemon,
   1829                   _ ("Error preparing select.\n"));
   1830 #endif
   1831         break;
   1832       }
   1833       /* FIXME: does this check really needed? */
   1834       if (MHD_INVALID_SOCKET != max_fd)
   1835       {
   1836         struct timeval *tvp;
   1837         struct timeval tv;
   1838         if (((con->tls_read_ready) &&
   1839              (urh->in_buffer_used < urh->in_buffer_size)) ||
   1840             (daemon->shutdown))
   1841         {         /* No need to wait if incoming data is already pending in TLS buffers. */
   1842           tv.tv_sec = 0;
   1843           tv.tv_usec = 0;
   1844           tvp = &tv;
   1845         }
   1846         else
   1847           tvp = NULL;
   1848         num_ready = MHD_SYS_select_ (max_fd + 1,
   1849                                      &rs,
   1850                                      &ws,
   1851                                      &es,
   1852                                      tvp);
   1853       }
   1854       else
   1855         num_ready = 0;
   1856       if (num_ready < 0)
   1857       {
   1858         const int err = MHD_socket_get_error_ ();
   1859 
   1860         if (MHD_SCKT_ERR_IS_EINTR_ (err))
   1861           continue;
   1862 #ifdef HAVE_MESSAGES
   1863         MHD_DLOG (con->daemon,
   1864                   _ ("Error during select (%d): `%s'\n"),
   1865                   err,
   1866                   MHD_socket_strerr_ (err));
   1867 #endif
   1868         break;
   1869       }
   1870       urh_from_fdset (urh,
   1871                       &rs,
   1872                       &ws,
   1873                       &es,
   1874                       (int) FD_SETSIZE);
   1875       process_urh (urh);
   1876     }
   1877   }
   1878 #ifdef HAVE_POLL
   1879   else if (0 != (daemon->options & MHD_USE_TLS))
   1880   {
   1881     /* use poll() */
   1882     struct pollfd p[2];
   1883     memset (p,
   1884             0,
   1885             sizeof (p));
   1886     p[0].fd = urh->connection->socket_fd;
   1887     p[1].fd = urh->mhd.socket;
   1888 
   1889     while ( (0 != urh->in_buffer_size) ||
   1890             (0 != urh->out_buffer_size) ||
   1891             (0 != urh->in_buffer_used) ||
   1892             (0 != urh->out_buffer_used) )
   1893     {
   1894       int timeout;
   1895 
   1896       urh_update_pollfd (urh, p);
   1897 
   1898       if (((con->tls_read_ready) &&
   1899            (urh->in_buffer_used < urh->in_buffer_size)) ||
   1900           (daemon->shutdown))
   1901         timeout = 0;     /* No need to wait if incoming data is already pending in TLS buffers. */
   1902       else
   1903         timeout = -1;
   1904 
   1905       if (MHD_sys_poll_ (p,
   1906                          2,
   1907                          timeout) < 0)
   1908       {
   1909         const int err = MHD_socket_get_error_ ();
   1910 
   1911         if (MHD_SCKT_ERR_IS_EINTR_ (err))
   1912           continue;
   1913 #ifdef HAVE_MESSAGES
   1914         MHD_DLOG (con->daemon,
   1915                   _ ("Error during poll: `%s'\n"),
   1916                   MHD_socket_strerr_ (err));
   1917 #endif
   1918         break;
   1919       }
   1920       urh_from_pollfd (urh,
   1921                        p);
   1922       process_urh (urh);
   1923     }
   1924   }
   1925   /* end POLL */
   1926 #endif
   1927   /* end HTTPS */
   1928 #endif /* HTTPS_SUPPORT */
   1929   /* TLS forwarding was finished. Cleanup socketpair. */
   1930   MHD_connection_finish_forward_ (con);
   1931   /* Do not set 'urh->clean_ready' yet as 'urh' will be used
   1932    * in connection thread for a little while. */
   1933 }
   1934 
   1935 
   1936 #endif /* UPGRADE_SUPPORT */
   1937 
   1938 
   1939 /**
   1940  * Get maximum wait period for the connection (the amount of time left before
   1941  * connection time out)
   1942  * @param c the connection to check
   1943  * @return the maximum number of millisecond before the connection must be
   1944  *         processed again.
   1945  */
   1946 static uint64_t
   1947 connection_get_wait (struct MHD_Connection *c)
   1948 {
   1949   const uint64_t now = MHD_monotonic_msec_counter ();
   1950   const uint64_t since_actv = now - c->last_activity;
   1951   const uint64_t timeout = c->connection_timeout_ms;
   1952   uint64_t mseconds_left;
   1953 
   1954   mhd_assert (0 != timeout);
   1955   /* Keep the next lines in sync with #connection_check_timedout() to avoid
   1956    * undesired side-effects like busy-waiting. */
   1957   if (timeout < since_actv)
   1958   {
   1959     if (UINT64_MAX / 2 < since_actv)
   1960     {
   1961       const uint64_t jump_back = c->last_activity - now;
   1962       /* Very unlikely that it is more than quarter-million years pause.
   1963        * More likely that system clock jumps back. */
   1964       if (5000 >= jump_back)
   1965       { /* Jump back is less than 5 seconds, try to recover. */
   1966         return 100; /* Set wait time to 0.1 seconds */
   1967       }
   1968       /* Too large jump back */
   1969     }
   1970     return 0; /* Connection has timed out */
   1971   }
   1972   else if (since_actv == timeout)
   1973   {
   1974     /* Exact match for timeout and time from last activity.
   1975      * Maybe this is just a precise match or this happens because the timer
   1976      * resolution is too low.
   1977      * Set wait time to 0.1 seconds to avoid busy-waiting with low
   1978      * timer resolution as connection is not timed-out yet. */
   1979     return 100;
   1980   }
   1981   mseconds_left = timeout - since_actv;
   1982 
   1983   return mseconds_left;
   1984 }
   1985 
   1986 
   1987 /**
   1988  * Main function of the thread that handles an individual
   1989  * connection when #MHD_USE_THREAD_PER_CONNECTION is set.
   1990  *
   1991  * @param data the `struct MHD_Connection` this thread will handle
   1992  * @return always 0
   1993  */
   1994 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
   1995 thread_main_handle_connection (void *data)
   1996 {
   1997   struct MHD_Connection *con = data;
   1998   struct MHD_Daemon *daemon = con->daemon;
   1999   int num_ready;
   2000   fd_set rs;
   2001   fd_set ws;
   2002   fd_set es;
   2003   MHD_socket maxsock;
   2004 #ifdef WINDOWS
   2005 #ifdef HAVE_POLL
   2006   unsigned int extra_slot;
   2007 #endif /* HAVE_POLL */
   2008 #define EXTRA_SLOTS 1
   2009 #else  /* !WINDOWS */
   2010 #define EXTRA_SLOTS 0
   2011 #endif /* !WINDOWS */
   2012 #ifdef HAVE_POLL
   2013   struct pollfd p[1 + EXTRA_SLOTS];
   2014 #endif
   2015 #undef EXTRA_SLOTS
   2016 #ifdef HAVE_POLL
   2017   const bool use_poll = MHD_D_IS_USING_POLL_ (daemon);
   2018 #else  /* ! HAVE_POLL */
   2019   const bool use_poll = 0;
   2020 #endif /* ! HAVE_POLL */
   2021   bool was_suspended = false;
   2022   MHD_thread_handle_ID_set_current_thread_ID_ (&(con->tid));
   2023 
   2024   while ( (! daemon->shutdown) &&
   2025           (MHD_CONNECTION_CLOSED != con->state) )
   2026   {
   2027     bool use_zero_timeout;
   2028 #ifdef UPGRADE_SUPPORT
   2029     struct MHD_UpgradeResponseHandle *const urh = con->urh;
   2030 #else  /* ! UPGRADE_SUPPORT */
   2031     static const void *const urh = NULL;
   2032 #endif /* ! UPGRADE_SUPPORT */
   2033 
   2034     if ( (con->suspended) &&
   2035          (NULL == urh) )
   2036     {
   2037       /* Connection was suspended, wait for resume. */
   2038       was_suspended = true;
   2039       if (! use_poll)
   2040       {
   2041         FD_ZERO (&rs);
   2042         if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
   2043                                   &rs,
   2044                                   NULL,
   2045                                   FD_SETSIZE))
   2046         {
   2047   #ifdef HAVE_MESSAGES
   2048           MHD_DLOG (con->daemon,
   2049                     _ ("Failed to add FD to fd_set.\n"));
   2050   #endif
   2051           goto exit;
   2052         }
   2053         if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1,
   2054                                  &rs,
   2055                                  NULL,
   2056                                  NULL,
   2057                                  NULL))
   2058         {
   2059           const int err = MHD_socket_get_error_ ();
   2060 
   2061           if (MHD_SCKT_ERR_IS_EINTR_ (err))
   2062             continue;
   2063 #ifdef HAVE_MESSAGES
   2064           MHD_DLOG (con->daemon,
   2065                     _ ("Error during select (%d): `%s'\n"),
   2066                     err,
   2067                     MHD_socket_strerr_ (err));
   2068 #endif
   2069           break;
   2070         }
   2071       }
   2072 #ifdef HAVE_POLL
   2073       else     /* use_poll */
   2074       {
   2075         p[0].events = POLLIN;
   2076         p[0].fd = MHD_itc_r_fd_ (daemon->itc);
   2077         p[0].revents = 0;
   2078         if (0 > MHD_sys_poll_ (p,
   2079                                1,
   2080                                -1))
   2081         {
   2082           if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_))
   2083             continue;
   2084 #ifdef HAVE_MESSAGES
   2085           MHD_DLOG (con->daemon,
   2086                     _ ("Error during poll: `%s'\n"),
   2087                     MHD_socket_last_strerr_ ());
   2088 #endif
   2089           break;
   2090         }
   2091       }
   2092 #endif /* HAVE_POLL */
   2093       MHD_itc_clear_ (daemon->itc);
   2094       continue; /* Check again for resume. */
   2095     }           /* End of "suspended" branch. */
   2096 
   2097     if (was_suspended)
   2098     {
   2099       MHD_update_last_activity_ (con);     /* Reset timeout timer. */
   2100       /* Process response queued during suspend and update states. */
   2101       MHD_connection_handle_idle (con);
   2102       was_suspended = false;
   2103     }
   2104 
   2105     use_zero_timeout =
   2106       (0 != (MHD_EVENT_LOOP_INFO_PROCESS & con->event_loop_info)
   2107 #ifdef HTTPS_SUPPORT
   2108        || ( (con->tls_read_ready) &&
   2109             (0 != (MHD_EVENT_LOOP_INFO_READ & con->event_loop_info)) )
   2110 #endif /* HTTPS_SUPPORT */
   2111       );
   2112     if (! use_poll)
   2113     {
   2114       /* use select */
   2115       bool err_state = false;
   2116       struct timeval tv;
   2117       struct timeval *tvp;
   2118       if (use_zero_timeout)
   2119       {
   2120         tv.tv_sec = 0;
   2121         tv.tv_usec = 0;
   2122         tvp = &tv;
   2123       }
   2124       else if (con->connection_timeout_ms > 0)
   2125       {
   2126         const uint64_t mseconds_left = connection_get_wait (con);
   2127 #if (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC
   2128         if (mseconds_left / 1000 > TIMEVAL_TV_SEC_MAX)
   2129           tv.tv_sec = TIMEVAL_TV_SEC_MAX;
   2130         else
   2131 #endif /* (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC */
   2132         tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) mseconds_left / 1000;
   2133 
   2134         tv.tv_usec = ((uint16_t) (mseconds_left % 1000)) * ((int32_t) 1000);
   2135         tvp = &tv;
   2136       }
   2137       else
   2138         tvp = NULL;
   2139 
   2140       FD_ZERO (&rs);
   2141       FD_ZERO (&ws);
   2142       FD_ZERO (&es);
   2143       maxsock = MHD_INVALID_SOCKET;
   2144       switch (con->event_loop_info)
   2145       {
   2146       case MHD_EVENT_LOOP_INFO_READ:
   2147       case MHD_EVENT_LOOP_INFO_PROCESS_READ:
   2148         if (! MHD_add_to_fd_set_ (con->socket_fd,
   2149                                   &rs,
   2150                                   &maxsock,
   2151                                   FD_SETSIZE))
   2152           err_state = true;
   2153         break;
   2154       case MHD_EVENT_LOOP_INFO_WRITE:
   2155         if (! MHD_add_to_fd_set_ (con->socket_fd,
   2156                                   &ws,
   2157                                   &maxsock,
   2158                                   FD_SETSIZE))
   2159           err_state = true;
   2160         break;
   2161       case MHD_EVENT_LOOP_INFO_PROCESS:
   2162         if (! MHD_add_to_fd_set_ (con->socket_fd,
   2163                                   &es,
   2164                                   &maxsock,
   2165                                   FD_SETSIZE))
   2166           err_state = true;
   2167         break;
   2168       case MHD_EVENT_LOOP_INFO_CLEANUP:
   2169         /* how did we get here!? */
   2170         goto exit;
   2171       }
   2172 #ifdef WINDOWS
   2173       if (MHD_ITC_IS_VALID_ (daemon->itc) )
   2174       {
   2175         if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
   2176                                   &rs,
   2177                                   &maxsock,
   2178                                   FD_SETSIZE))
   2179           err_state = 1;
   2180       }
   2181 #endif
   2182       if (err_state)
   2183       {
   2184 #ifdef HAVE_MESSAGES
   2185         MHD_DLOG (con->daemon,
   2186                   _ ("Failed to add FD to fd_set.\n"));
   2187 #endif
   2188         goto exit;
   2189       }
   2190 
   2191       num_ready = MHD_SYS_select_ (maxsock + 1,
   2192                                    &rs,
   2193                                    &ws,
   2194                                    &es,
   2195                                    tvp);
   2196       if (num_ready < 0)
   2197       {
   2198         const int err = MHD_socket_get_error_ ();
   2199 
   2200         if (MHD_SCKT_ERR_IS_EINTR_ (err))
   2201           continue;
   2202 #ifdef HAVE_MESSAGES
   2203         MHD_DLOG (con->daemon,
   2204                   _ ("Error during select (%d): `%s'\n"),
   2205                   err,
   2206                   MHD_socket_strerr_ (err));
   2207 #endif
   2208         break;
   2209       }
   2210 #ifdef WINDOWS
   2211       /* Clear ITC before other processing so additional
   2212        * signals will trigger select() again */
   2213       if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
   2214            (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
   2215                       &rs)) )
   2216         MHD_itc_clear_ (daemon->itc);
   2217 #endif
   2218       if (MHD_NO ==
   2219           call_handlers (con,
   2220                          FD_ISSET (con->socket_fd,
   2221                                    &rs),
   2222                          FD_ISSET (con->socket_fd,
   2223                                    &ws),
   2224                          FD_ISSET (con->socket_fd,
   2225                                    &es)) )
   2226         goto exit;
   2227     }
   2228 #ifdef HAVE_POLL
   2229     else
   2230     {
   2231       int timeout_val;
   2232       /* use poll */
   2233       if (use_zero_timeout)
   2234         timeout_val = 0;
   2235       else if (con->connection_timeout_ms > 0)
   2236       {
   2237         const uint64_t mseconds_left = connection_get_wait (con);
   2238 #if SIZEOF_UINT64_T >= SIZEOF_INT
   2239         if (mseconds_left >= INT_MAX)
   2240           timeout_val = INT_MAX;
   2241         else
   2242 #endif /* SIZEOF_UINT64_T >= SIZEOF_INT */
   2243         timeout_val = (int) mseconds_left;
   2244       }
   2245       else
   2246         timeout_val = -1;
   2247       memset (&p,
   2248               0,
   2249               sizeof (p));
   2250       p[0].fd = con->socket_fd;
   2251       switch (con->event_loop_info)
   2252       {
   2253       case MHD_EVENT_LOOP_INFO_READ:
   2254       case MHD_EVENT_LOOP_INFO_PROCESS_READ:
   2255         p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
   2256         break;
   2257       case MHD_EVENT_LOOP_INFO_WRITE:
   2258         p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
   2259         break;
   2260       case MHD_EVENT_LOOP_INFO_PROCESS:
   2261         p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
   2262         break;
   2263       case MHD_EVENT_LOOP_INFO_CLEANUP:
   2264         /* how did we get here!? */
   2265         goto exit;
   2266       }
   2267 #ifdef WINDOWS
   2268       extra_slot = 0;
   2269       if (MHD_ITC_IS_VALID_ (daemon->itc))
   2270       {
   2271         p[1].events |= POLLIN;
   2272         p[1].fd = MHD_itc_r_fd_ (daemon->itc);
   2273         p[1].revents = 0;
   2274         extra_slot = 1;
   2275       }
   2276 #endif
   2277       if (MHD_sys_poll_ (p,
   2278 #ifdef WINDOWS
   2279                          1 + extra_slot,
   2280 #else
   2281                          1,
   2282 #endif
   2283                          timeout_val) < 0)
   2284       {
   2285         if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_))
   2286           continue;
   2287 #ifdef HAVE_MESSAGES
   2288         MHD_DLOG (con->daemon,
   2289                   _ ("Error during poll: `%s'\n"),
   2290                   MHD_socket_last_strerr_ ());
   2291 #endif
   2292         break;
   2293       }
   2294 #ifdef WINDOWS
   2295       /* Clear ITC before other processing so additional
   2296        * signals will trigger poll() again */
   2297       if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
   2298            (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
   2299         MHD_itc_clear_ (daemon->itc);
   2300 #endif
   2301       if (MHD_NO ==
   2302           call_handlers (con,
   2303                          (0 != (p[0].revents & POLLIN)),
   2304                          (0 != (p[0].revents & POLLOUT)),
   2305                          (0 != (p[0].revents & MHD_POLL_REVENTS_ERR_DISC)) ))
   2306         goto exit;
   2307     }
   2308 #endif
   2309 #ifdef UPGRADE_SUPPORT
   2310     if (MHD_CONNECTION_UPGRADE == con->state)
   2311     {
   2312       /* Normal HTTP processing is finished,
   2313        * notify application. */
   2314       if ( (NULL != daemon->notify_completed) &&
   2315            (con->rq.client_aware) )
   2316         daemon->notify_completed (daemon->notify_completed_cls,
   2317                                   con,
   2318                                   &con->rq.client_context,
   2319                                   MHD_REQUEST_TERMINATED_COMPLETED_OK);
   2320       con->rq.client_aware = false;
   2321 
   2322       thread_main_connection_upgrade (con);
   2323       /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */
   2324 
   2325       /* "Upgraded" data will not be used in this thread from this point. */
   2326       con->urh->clean_ready = true;
   2327       /* If 'urh->was_closed' set to true, connection will be
   2328        * moved immediately to cleanup list. Otherwise connection
   2329        * will stay in suspended list until 'urh' will be marked
   2330        * with 'was_closed' by application. */
   2331       MHD_resume_connection (con);
   2332 
   2333       /* skip usual clean up  */
   2334       return (MHD_THRD_RTRN_TYPE_) 0;
   2335     }
   2336 #endif /* UPGRADE_SUPPORT */
   2337   }
   2338 #if _MHD_DEBUG_CLOSE
   2339 #ifdef HAVE_MESSAGES
   2340   MHD_DLOG (con->daemon,
   2341             _ ("Processing thread terminating. Closing connection.\n"));
   2342 #endif
   2343 #endif
   2344   if (MHD_CONNECTION_CLOSED != con->state)
   2345     MHD_connection_close_ (con,
   2346                            (daemon->shutdown) ?
   2347                            MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN :
   2348                            MHD_REQUEST_TERMINATED_WITH_ERROR);
   2349   MHD_connection_handle_idle (con);
   2350 exit:
   2351   if (NULL != con->rp.response)
   2352   {
   2353     MHD_destroy_response (con->rp.response);
   2354     con->rp.response = NULL;
   2355   }
   2356 
   2357   if (MHD_INVALID_SOCKET != con->socket_fd)
   2358   {
   2359     shutdown (con->socket_fd,
   2360               SHUT_WR);
   2361     /* 'socket_fd' can be used in other thread to signal shutdown.
   2362      * To avoid data races, do not close socket here. Daemon will
   2363      * use more connections only after cleanup anyway. */
   2364   }
   2365   if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
   2366        (! MHD_itc_activate_ (daemon->itc, "t")) )
   2367   {
   2368 #ifdef HAVE_MESSAGES
   2369     MHD_DLOG (daemon,
   2370               _ ("Failed to signal thread termination via inter-thread " \
   2371                  "communication channel.\n"));
   2372 #endif
   2373   }
   2374   return (MHD_THRD_RTRN_TYPE_) 0;
   2375 }
   2376 
   2377 
   2378 #endif
   2379 
   2380 
   2381 /**
   2382  * Free resources associated with all closed connections.
   2383  * (destroy responses, free buffers, etc.).  All closed
   2384  * connections are kept in the "cleanup" doubly-linked list.
   2385  *
   2386  * @param daemon daemon to clean up
   2387  */
   2388 static void
   2389 MHD_cleanup_connections (struct MHD_Daemon *daemon);
   2390 
   2391 #if defined(HTTPS_SUPPORT)
   2392 #if defined(MHD_SEND_SPIPE_SUPPRESS_NEEDED) && \
   2393   defined(MHD_SEND_SPIPE_SUPPRESS_POSSIBLE) && \
   2394   ! defined(MHD_socket_nosignal_) && \
   2395   (GNUTLS_VERSION_NUMBER + 0 < 0x030402) && defined(MSG_NOSIGNAL)
   2396 /**
   2397  * Older version of GnuTLS do not support suppressing of SIGPIPE signal.
   2398  * Use push function replacement with suppressing SIGPIPE signal where necessary
   2399  * and if possible.
   2400  */
   2401 #define MHD_TLSLIB_NEED_PUSH_FUNC 1
   2402 #endif /* MHD_SEND_SPIPE_SUPPRESS_NEEDED &&
   2403           MHD_SEND_SPIPE_SUPPRESS_POSSIBLE &&
   2404           ! MHD_socket_nosignal_ && (GNUTLS_VERSION_NUMBER+0 < 0x030402) &&
   2405           MSG_NOSIGNAL */
   2406 
   2407 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
   2408 /**
   2409  * Data push function replacement with suppressing SIGPIPE signal
   2410  * for TLS library.
   2411  */
   2412 static ssize_t
   2413 MHD_tls_push_func_ (gnutls_transport_ptr_t trnsp,
   2414                     const void *data,
   2415                     size_t data_size)
   2416 {
   2417 #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX)
   2418   if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
   2419     data_size = MHD_SCKT_SEND_MAX_SIZE_;
   2420 #endif /* (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) */
   2421   return MHD_send_ ((MHD_socket) (intptr_t) (trnsp), data, data_size);
   2422 }
   2423 
   2424 
   2425 #endif /* MHD_TLSLIB_DONT_SUPPRESS_SIGPIPE */
   2426 
   2427 
   2428 /**
   2429  * Function called by GNUtls to obtain the PSK for a given session.
   2430  *
   2431  * @param session the session to lookup PSK for
   2432  * @param username username to lookup PSK for
   2433  * @param[out] key where to write PSK
   2434  * @return 0 on success, -1 on error
   2435  */
   2436 static int
   2437 psk_gnutls_adapter (gnutls_session_t session,
   2438                     const char *username,
   2439                     gnutls_datum_t *key)
   2440 {
   2441   struct MHD_Connection *connection;
   2442   struct MHD_Daemon *daemon;
   2443 #if GNUTLS_VERSION_MAJOR >= 3
   2444   void *app_psk;
   2445   size_t app_psk_size;
   2446 #endif /* GNUTLS_VERSION_MAJOR >= 3 */
   2447 
   2448   connection = gnutls_session_get_ptr (session);
   2449   if (NULL == connection)
   2450   {
   2451 #ifdef HAVE_MESSAGES
   2452     /* Cannot use our logger, we don't even have "daemon" */
   2453     MHD_PANIC (_ ("Internal server error. This should be impossible.\n"));
   2454 #endif
   2455     return -1;
   2456   }
   2457   daemon = connection->daemon;
   2458 #if GNUTLS_VERSION_MAJOR >= 3
   2459   if (NULL == daemon->cred_callback)
   2460   {
   2461 #ifdef HAVE_MESSAGES
   2462     MHD_DLOG (daemon,
   2463               _ ("PSK not supported by this server.\n"));
   2464 #endif
   2465     return -1;
   2466   }
   2467   if (0 != daemon->cred_callback (daemon->cred_callback_cls,
   2468                                   connection,
   2469                                   username,
   2470                                   &app_psk,
   2471                                   &app_psk_size))
   2472     return -1;
   2473   if (NULL == (key->data = gnutls_malloc (app_psk_size)))
   2474   {
   2475 #ifdef HAVE_MESSAGES
   2476     MHD_DLOG (daemon,
   2477               _ ("PSK authentication failed: gnutls_malloc failed to " \
   2478                  "allocate memory.\n"));
   2479 #endif
   2480     free (app_psk);
   2481     return -1;
   2482   }
   2483   if (UINT_MAX < app_psk_size)
   2484   {
   2485 #ifdef HAVE_MESSAGES
   2486     MHD_DLOG (daemon,
   2487               _ ("PSK authentication failed: PSK too long.\n"));
   2488 #endif
   2489     free (app_psk);
   2490     return -1;
   2491   }
   2492   key->size = (unsigned int) app_psk_size;
   2493   memcpy (key->data,
   2494           app_psk,
   2495           app_psk_size);
   2496   free (app_psk);
   2497   return 0;
   2498 #else
   2499   (void) username; (void) key; /* Mute compiler warning */
   2500 #ifdef HAVE_MESSAGES
   2501   MHD_DLOG (daemon,
   2502             _ ("PSK not supported by this server.\n"));
   2503 #endif
   2504   return -1;
   2505 #endif
   2506 }
   2507 
   2508 
   2509 #endif /* HTTPS_SUPPORT */
   2510 
   2511 
   2512 /**
   2513  * Do basic preparation work on the new incoming connection.
   2514  *
   2515  * This function do all preparation that is possible outside main daemon
   2516  * thread.
   2517  * @remark Could be called from any thread.
   2518  *
   2519  * @param daemon daemon that manages the connection
   2520  * @param client_socket socket to manage (MHD will expect
   2521  *        to receive an HTTP request from this socket next).
   2522  * @param addr IP address of the client
   2523  * @param addrlen number of bytes in @a addr
   2524  * @param external_add indicate that socket has been added externally
   2525  * @param non_blck indicate that socket in non-blocking mode
   2526  * @param sk_spipe_supprs indicate that the @a client_socket has
   2527  *                         set SIGPIPE suppression
   2528  * @param sk_is_nonip _MHD_YES if this is not a TCP/IP socket
   2529  * @return pointer to the connection on success, NULL if this daemon could
   2530  *        not handle the connection (i.e. malloc failed, etc).
   2531  *        The socket will be closed in case of error; 'errno' is
   2532  *        set to indicate further details about the error.
   2533  */
   2534 static struct MHD_Connection *
   2535 new_connection_prepare_ (struct MHD_Daemon *daemon,
   2536                          MHD_socket client_socket,
   2537                          const struct sockaddr_storage *addr,
   2538                          socklen_t addrlen,
   2539                          bool external_add,
   2540                          bool non_blck,
   2541                          bool sk_spipe_supprs,
   2542                          enum MHD_tristate sk_is_nonip)
   2543 {
   2544   struct MHD_Connection *connection;
   2545   int eno = 0;
   2546 
   2547 #ifdef HAVE_MESSAGES
   2548 #if _MHD_DEBUG_CONNECT
   2549   MHD_DLOG (daemon,
   2550             _ ("Accepted connection on socket %d.\n"),
   2551             client_socket);
   2552 #endif
   2553 #endif
   2554   if ( (daemon->connections == daemon->connection_limit) ||
   2555        (MHD_NO == MHD_ip_limit_add (daemon,
   2556                                     addr,
   2557                                     addrlen)) )
   2558   {
   2559     /* above connection limit - reject */
   2560 #ifdef HAVE_MESSAGES
   2561     MHD_DLOG (daemon,
   2562               _ ("Server reached connection limit. " \
   2563                  "Closing inbound connection.\n"));
   2564 #endif
   2565     MHD_socket_close_chk_ (client_socket);
   2566 #if defined(ENFILE) && (ENFILE + 0 != 0)
   2567     errno = ENFILE;
   2568 #endif
   2569     return NULL;
   2570   }
   2571 
   2572   /* apply connection acceptance policy if present */
   2573   if ( (NULL != daemon->apc) &&
   2574        (MHD_NO == daemon->apc (daemon->apc_cls,
   2575                                (const struct sockaddr *) addr,
   2576                                addrlen)) )
   2577   {
   2578 #if _MHD_DEBUG_CLOSE
   2579 #ifdef HAVE_MESSAGES
   2580     MHD_DLOG (daemon,
   2581               _ ("Connection rejected by application. Closing connection.\n"));
   2582 #endif
   2583 #endif
   2584     MHD_socket_close_chk_ (client_socket);
   2585     MHD_ip_limit_del (daemon,
   2586                       addr,
   2587                       addrlen);
   2588 #if defined(EACCESS) && (EACCESS + 0 != 0)
   2589     errno = EACCESS;
   2590 #endif
   2591     return NULL;
   2592   }
   2593 
   2594   if (NULL == (connection = MHD_calloc_ (1, sizeof (struct MHD_Connection))))
   2595   {
   2596     eno = errno;
   2597 #ifdef HAVE_MESSAGES
   2598     MHD_DLOG (daemon,
   2599               _ ("Error allocating memory: %s\n"),
   2600               MHD_strerror_ (errno));
   2601 #endif
   2602     MHD_socket_close_chk_ (client_socket);
   2603     MHD_ip_limit_del (daemon,
   2604                       addr,
   2605                       addrlen);
   2606     errno = eno;
   2607     return NULL;
   2608   }
   2609 
   2610   if (! external_add)
   2611   {
   2612     connection->sk_corked = _MHD_OFF;
   2613     connection->sk_nodelay = _MHD_OFF;
   2614   }
   2615   else
   2616   {
   2617     connection->sk_corked = _MHD_UNKNOWN;
   2618     connection->sk_nodelay = _MHD_UNKNOWN;
   2619   }
   2620 
   2621   if (0 < addrlen)
   2622   {
   2623     if (NULL == (connection->addr = malloc ((size_t) addrlen)))
   2624     {
   2625       eno = errno;
   2626 #ifdef HAVE_MESSAGES
   2627       MHD_DLOG (daemon,
   2628                 _ ("Error allocating memory: %s\n"),
   2629                 MHD_strerror_ (errno));
   2630 #endif
   2631       MHD_socket_close_chk_ (client_socket);
   2632       MHD_ip_limit_del (daemon,
   2633                         addr,
   2634                         addrlen);
   2635       free (connection);
   2636       errno = eno;
   2637       return NULL;
   2638     }
   2639     memcpy (connection->addr,
   2640             addr,
   2641             (size_t) addrlen);
   2642   }
   2643   else
   2644     connection->addr = NULL;
   2645   connection->addr_len = addrlen;
   2646   connection->socket_fd = client_socket;
   2647   connection->sk_nonblck = non_blck;
   2648   connection->is_nonip = sk_is_nonip;
   2649   connection->sk_spipe_suppress = sk_spipe_supprs;
   2650 #ifdef MHD_USE_THREADS
   2651   MHD_thread_handle_ID_set_invalid_ (&connection->tid);
   2652 #endif /* MHD_USE_THREADS */
   2653   connection->daemon = daemon;
   2654   connection->connection_timeout_ms = daemon->connection_timeout_ms;
   2655   connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
   2656   if (0 != connection->connection_timeout_ms)
   2657     connection->last_activity = MHD_monotonic_msec_counter ();
   2658 
   2659   if (0 == (daemon->options & MHD_USE_TLS))
   2660   {
   2661     /* set default connection handlers  */
   2662     MHD_set_http_callbacks_ (connection);
   2663   }
   2664   else
   2665   {
   2666 #ifdef HTTPS_SUPPORT
   2667 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030500)
   2668     gnutls_init_flags_t
   2669 #else
   2670     unsigned int
   2671 #endif
   2672     flags;
   2673 
   2674     flags = GNUTLS_SERVER;
   2675 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030402)
   2676     flags |= GNUTLS_NO_SIGNAL;
   2677 #endif /* GNUTLS_VERSION_NUMBER >= 0x030402 */
   2678 #if GNUTLS_VERSION_MAJOR >= 3
   2679     flags |= GNUTLS_NONBLOCK;
   2680 #endif /* GNUTLS_VERSION_MAJOR >= 3*/
   2681 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030603)
   2682     if (0 != (daemon->options & MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT))
   2683       flags |= GNUTLS_POST_HANDSHAKE_AUTH;
   2684 #endif
   2685 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030605)
   2686     if (0 != (daemon->options & MHD_USE_INSECURE_TLS_EARLY_DATA))
   2687       flags |= GNUTLS_ENABLE_EARLY_DATA;
   2688 #endif
   2689     connection->tls_state = MHD_TLS_CONN_INIT;
   2690     MHD_set_https_callbacks (connection);
   2691     if ((GNUTLS_E_SUCCESS != gnutls_init (&connection->tls_session, flags)) ||
   2692         (GNUTLS_E_SUCCESS != gnutls_priority_set (connection->tls_session,
   2693                                                   daemon->priority_cache)))
   2694     {
   2695       if (NULL != connection->tls_session)
   2696         gnutls_deinit (connection->tls_session);
   2697       MHD_socket_close_chk_ (client_socket);
   2698       MHD_ip_limit_del (daemon,
   2699                         addr,
   2700                         addrlen);
   2701       if (NULL != connection->addr)
   2702         free (connection->addr);
   2703       free (connection);
   2704 #ifdef HAVE_MESSAGES
   2705       MHD_DLOG (daemon,
   2706                 _ ("Failed to initialise TLS session.\n"));
   2707 #endif
   2708 #if defined(EPROTO) && (EPROTO + 0 != 0)
   2709       errno = EPROTO;
   2710 #endif
   2711       return NULL;
   2712     }
   2713 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030200)
   2714     if (! daemon->disable_alpn)
   2715     {
   2716       static const char prt1[] = "http/1.1"; /* Registered code for HTTP/1.1 */
   2717       static const char prt2[] = "http/1.0"; /* Registered code for HTTP/1.0 */
   2718       static const gnutls_datum_t prts[2] =
   2719       { {_MHD_DROP_CONST (prt1), MHD_STATICSTR_LEN_ (prt1)},
   2720         {_MHD_DROP_CONST (prt2), MHD_STATICSTR_LEN_ (prt2)} };
   2721 
   2722       if (GNUTLS_E_SUCCESS !=
   2723           gnutls_alpn_set_protocols (connection->tls_session,
   2724                                      prts,
   2725                                      sizeof(prts) / sizeof(prts[0]),
   2726                                      0 /* | GNUTLS_ALPN_SERVER_PRECEDENCE */))
   2727       {
   2728 #ifdef HAVE_MESSAGES
   2729         MHD_DLOG (daemon,
   2730                   _ ("Failed to set ALPN protocols.\n"));
   2731 #else  /* ! HAVE_MESSAGES */
   2732         (void) 0; /* Mute compiler warning */
   2733 #endif /* ! HAVE_MESSAGES */
   2734       }
   2735     }
   2736 #endif /* GNUTLS_VERSION_NUMBER >= 0x030200 */
   2737     gnutls_session_set_ptr (connection->tls_session,
   2738                             connection);
   2739     switch (daemon->cred_type)
   2740     {
   2741     /* set needed credentials for certificate authentication. */
   2742     case GNUTLS_CRD_CERTIFICATE:
   2743       gnutls_credentials_set (connection->tls_session,
   2744                               GNUTLS_CRD_CERTIFICATE,
   2745                               daemon->x509_cred);
   2746       break;
   2747     case GNUTLS_CRD_PSK:
   2748       gnutls_credentials_set (connection->tls_session,
   2749                               GNUTLS_CRD_PSK,
   2750                               daemon->psk_cred);
   2751       gnutls_psk_set_server_credentials_function (daemon->psk_cred,
   2752                                                   &psk_gnutls_adapter);
   2753       break;
   2754     case GNUTLS_CRD_ANON:
   2755     case GNUTLS_CRD_SRP:
   2756     case GNUTLS_CRD_IA:
   2757     default:
   2758 #ifdef HAVE_MESSAGES
   2759       MHD_DLOG (daemon,
   2760                 _ ("Failed to setup TLS credentials: " \
   2761                    "unknown credential type %d.\n"),
   2762                 daemon->cred_type);
   2763 #endif
   2764       gnutls_deinit (connection->tls_session);
   2765       MHD_socket_close_chk_ (client_socket);
   2766       MHD_ip_limit_del (daemon,
   2767                         addr,
   2768                         addrlen);
   2769       if (NULL != connection->addr)
   2770         free (connection->addr);
   2771       free (connection);
   2772       MHD_PANIC (_ ("Unknown credential type.\n"));
   2773 #if defined(EINVAL) && (EINVAL + 0 != 0)
   2774       errno = EINVAL;
   2775 #endif
   2776       return NULL;
   2777     }
   2778 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030109) && ! defined(_WIN64)
   2779     gnutls_transport_set_int (connection->tls_session,
   2780                               (int) (client_socket));
   2781 #else  /* GnuTLS before 3.1.9 or Win x64 */
   2782     gnutls_transport_set_ptr (connection->tls_session,
   2783                               (gnutls_transport_ptr_t) \
   2784                               (intptr_t) client_socket);
   2785 #endif /* GnuTLS before 3.1.9 or Win x64 */
   2786 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
   2787     gnutls_transport_set_push_function (connection->tls_session,
   2788                                         MHD_tls_push_func_);
   2789 #endif /* MHD_TLSLIB_NEED_PUSH_FUNC */
   2790     if (daemon->https_mem_trust)
   2791       gnutls_certificate_server_set_request (connection->tls_session,
   2792                                              GNUTLS_CERT_REQUEST);
   2793 #else  /* ! HTTPS_SUPPORT */
   2794     MHD_socket_close_chk_ (client_socket);
   2795     MHD_ip_limit_del (daemon,
   2796                       addr,
   2797                       addrlen);
   2798     free (connection->addr);
   2799     free (connection);
   2800     MHD_PANIC (_ ("TLS connection on non-TLS daemon.\n"));
   2801 #if 0
   2802     /* Unreachable code */
   2803     eno = EINVAL;
   2804     return NULL;
   2805 #endif
   2806 #endif /* ! HTTPS_SUPPORT */
   2807   }
   2808 
   2809   return connection;
   2810 }
   2811 
   2812 
   2813 #ifdef MHD_USE_THREADS
   2814 /**
   2815  * Close prepared, but not yet processed connection.
   2816  * @param daemon     the daemon
   2817  * @param connection the connection to close
   2818  */
   2819 static void
   2820 new_connection_close_ (struct MHD_Daemon *daemon,
   2821                        struct MHD_Connection *connection)
   2822 {
   2823   mhd_assert (connection->daemon == daemon);
   2824   mhd_assert (! connection->in_cleanup);
   2825   mhd_assert (NULL == connection->next);
   2826   mhd_assert (NULL == connection->nextX);
   2827 #ifdef EPOLL_SUPPORT
   2828   mhd_assert (NULL == connection->nextE);
   2829 #endif /* EPOLL_SUPPORT */
   2830 
   2831 #ifdef HTTPS_SUPPORT
   2832   if (NULL != connection->tls_session)
   2833   {
   2834     mhd_assert (0 != (daemon->options & MHD_USE_TLS));
   2835     gnutls_deinit (connection->tls_session);
   2836   }
   2837 #endif /* HTTPS_SUPPORT */
   2838   MHD_socket_close_chk_ (connection->socket_fd);
   2839   MHD_ip_limit_del (daemon,
   2840                     connection->addr,
   2841                     connection->addr_len);
   2842   if (NULL != connection->addr)
   2843     free (connection->addr);
   2844   free (connection);
   2845 }
   2846 
   2847 
   2848 #endif /* MHD_USE_THREADS */
   2849 
   2850 
   2851 /**
   2852  * Finally insert the new connection to the list of connections
   2853  * served by the daemon and start processing.
   2854  * @remark To be called only from thread that process
   2855  * daemon's select()/poll()/etc.
   2856  *
   2857  * @param daemon daemon that manages the connection
   2858  * @param connection the newly created connection
   2859  * @return #MHD_YES on success, #MHD_NO on error
   2860  */
   2861 static enum MHD_Result
   2862 new_connection_process_ (struct MHD_Daemon *daemon,
   2863                          struct MHD_Connection *connection)
   2864 {
   2865   int eno = 0;
   2866 
   2867   mhd_assert (connection->daemon == daemon);
   2868 
   2869 #ifdef MHD_USE_THREADS
   2870   /* Function manipulate connection and timeout DL-lists,
   2871    * must be called only within daemon thread. */
   2872   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   2873                MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   2874   mhd_assert (NULL == daemon->worker_pool);
   2875 #endif /* MHD_USE_THREADS */
   2876 
   2877   /* Allocate memory pool in the processing thread so
   2878    * intensively used memory area is allocated in "good"
   2879    * (for the thread) memory region. It is important with
   2880    * NUMA and/or complex cache hierarchy. */
   2881   connection->pool = MHD_pool_create (daemon->pool_size);
   2882   if (NULL == connection->pool)
   2883   { /* 'pool' creation failed */
   2884 #ifdef HAVE_MESSAGES
   2885     MHD_DLOG (daemon,
   2886               _ ("Error allocating memory: %s\n"),
   2887               MHD_strerror_ (errno));
   2888 #endif
   2889 #if defined(ENOMEM) && (ENOMEM + 0 != 0)
   2890     eno = ENOMEM;
   2891 #endif
   2892     (void) 0; /* Mute possible compiler warning */
   2893   }
   2894   else
   2895   { /* 'pool' creation succeed */
   2896     MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   2897     /* Firm check under lock. */
   2898     if (daemon->connections >= daemon->connection_limit)
   2899     { /* Connections limit */
   2900       MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   2901 #ifdef HAVE_MESSAGES
   2902       MHD_DLOG (daemon,
   2903                 _ ("Server reached connection limit. "
   2904                    "Closing inbound connection.\n"));
   2905 #endif
   2906 #if defined(ENFILE) && (ENFILE + 0 != 0)
   2907       eno = ENFILE;
   2908 #endif
   2909       (void) 0; /* Mute possible compiler warning */
   2910     }
   2911     else
   2912     { /* Have space for new connection */
   2913       daemon->connections++;
   2914       DLL_insert (daemon->connections_head,
   2915                   daemon->connections_tail,
   2916                   connection);
   2917       if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   2918       {
   2919         XDLL_insert (daemon->normal_timeout_head,
   2920                      daemon->normal_timeout_tail,
   2921                      connection);
   2922       }
   2923       MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   2924 
   2925       MHD_connection_set_initial_state_ (connection);
   2926 
   2927       if (NULL != daemon->notify_connection)
   2928         daemon->notify_connection (daemon->notify_connection_cls,
   2929                                    connection,
   2930                                    &connection->socket_context,
   2931                                    MHD_CONNECTION_NOTIFY_STARTED);
   2932 #ifdef MHD_USE_THREADS
   2933       if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   2934       {
   2935         mhd_assert (! MHD_D_IS_USING_EPOLL_ (daemon));
   2936         if (! MHD_create_named_thread_ (&connection->tid,
   2937                                         "MHD-connection",
   2938                                         daemon->thread_stack_size,
   2939                                         &thread_main_handle_connection,
   2940                                         connection))
   2941         {
   2942           eno = errno;
   2943 #ifdef HAVE_MESSAGES
   2944 #ifdef EAGAIN
   2945           if (EAGAIN == eno)
   2946             MHD_DLOG (daemon,
   2947                       _ ("Failed to create a new thread because it would "
   2948                          "have exceeded the system limit on the number of "
   2949                          "threads or no system resources available.\n"));
   2950           else
   2951 #endif /* EAGAIN */
   2952           MHD_DLOG (daemon,
   2953                     _ ("Failed to create a thread: %s\n"),
   2954                     MHD_strerror_ (eno));
   2955 #endif /* HAVE_MESSAGES */
   2956         }
   2957         else               /* New thread has been created successfully */
   2958           return MHD_YES;  /* *** Function success exit point *** */
   2959       }
   2960       else
   2961 #else  /* ! MHD_USE_THREADS */
   2962       if (1)
   2963 #endif /* ! MHD_USE_THREADS */
   2964       { /* No 'thread-per-connection' */
   2965 #ifdef MHD_USE_THREADS
   2966         connection->tid = daemon->tid;
   2967 #endif /* MHD_USE_THREADS */
   2968 #ifdef EPOLL_SUPPORT
   2969         if (MHD_D_IS_USING_EPOLL_ (daemon))
   2970         {
   2971           if (0 == (daemon->options & MHD_USE_TURBO))
   2972           {
   2973             struct epoll_event event;
   2974 
   2975             event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET | EPOLLRDHUP;
   2976             event.data.ptr = connection;
   2977             if (0 != epoll_ctl (daemon->epoll_fd,
   2978                                 EPOLL_CTL_ADD,
   2979                                 connection->socket_fd,
   2980                                 &event))
   2981             {
   2982               eno = errno;
   2983 #ifdef HAVE_MESSAGES
   2984               MHD_DLOG (daemon,
   2985                         _ ("Call to epoll_ctl failed: %s\n"),
   2986                         MHD_socket_last_strerr_ ());
   2987 #endif
   2988             }
   2989             else
   2990             { /* 'socket_fd' has been added to 'epool' */
   2991               connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
   2992 
   2993               return MHD_YES;  /* *** Function success exit point *** */
   2994             }
   2995           }
   2996           else
   2997           {
   2998             connection->epoll_state |= MHD_EPOLL_STATE_READ_READY
   2999                                        | MHD_EPOLL_STATE_WRITE_READY
   3000                                        | MHD_EPOLL_STATE_IN_EREADY_EDLL;
   3001             EDLL_insert (daemon->eready_head,
   3002                          daemon->eready_tail,
   3003                          connection);
   3004 
   3005             return MHD_YES;  /* *** Function success exit point *** */
   3006           }
   3007         }
   3008         else /* No 'epoll' */
   3009 #endif /* EPOLL_SUPPORT */
   3010         return MHD_YES;    /* *** Function success exit point *** */
   3011       }
   3012 
   3013       /* ** Below is a cleanup path ** */
   3014       if (NULL != daemon->notify_connection)
   3015         daemon->notify_connection (daemon->notify_connection_cls,
   3016                                    connection,
   3017                                    &connection->socket_context,
   3018                                    MHD_CONNECTION_NOTIFY_CLOSED);
   3019       MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   3020       if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   3021       {
   3022         XDLL_remove (daemon->normal_timeout_head,
   3023                      daemon->normal_timeout_tail,
   3024                      connection);
   3025       }
   3026       DLL_remove (daemon->connections_head,
   3027                   daemon->connections_tail,
   3028                   connection);
   3029       daemon->connections--;
   3030       MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   3031     }
   3032     MHD_pool_destroy (connection->pool);
   3033   }
   3034   /* Free resources allocated before the call of this functions */
   3035 #ifdef HTTPS_SUPPORT
   3036   if (NULL != connection->tls_session)
   3037     gnutls_deinit (connection->tls_session);
   3038 #endif /* HTTPS_SUPPORT */
   3039   MHD_ip_limit_del (daemon,
   3040                     connection->addr,
   3041                     connection->addr_len);
   3042   if (NULL != connection->addr)
   3043     free (connection->addr);
   3044   MHD_socket_close_chk_ (connection->socket_fd);
   3045   free (connection);
   3046   if (0 != eno)
   3047     errno = eno;
   3048 #ifdef EINVAL
   3049   else
   3050     errno = EINVAL;
   3051 #endif /* EINVAL */
   3052   return MHD_NO;  /* *** Function failure exit point *** */
   3053 }
   3054 
   3055 
   3056 /**
   3057  * Add another client connection to the set of connections
   3058  * managed by MHD.  This API is usually not needed (since
   3059  * MHD will accept inbound connections on the server socket).
   3060  * Use this API in special cases, for example if your HTTP
   3061  * server is behind NAT and needs to connect out to the
   3062  * HTTP client.
   3063  *
   3064  * The given client socket will be managed (and closed!) by MHD after
   3065  * this call and must no longer be used directly by the application
   3066  * afterwards.
   3067  *
   3068  * @param daemon daemon that manages the connection
   3069  * @param client_socket socket to manage (MHD will expect
   3070  *        to receive an HTTP request from this socket next).
   3071  * @param addr IP address of the client
   3072  * @param addrlen number of bytes in @a addr
   3073  * @param external_add perform additional operations needed due
   3074  *        to the application calling us directly
   3075  * @param non_blck indicate that socket in non-blocking mode
   3076  * @param sk_spipe_supprs indicate that the @a client_socket has
   3077  *                         set SIGPIPE suppression
   3078  * @param sk_is_nonip _MHD_YES if this is not a TCP/IP socket
   3079  * @return #MHD_YES on success, #MHD_NO if this daemon could
   3080  *        not handle the connection (i.e. malloc failed, etc).
   3081  *        The socket will be closed in any case; 'errno' is
   3082  *        set to indicate further details about the error.
   3083  */
   3084 static enum MHD_Result
   3085 internal_add_connection (struct MHD_Daemon *daemon,
   3086                          MHD_socket client_socket,
   3087                          const struct sockaddr_storage *addr,
   3088                          socklen_t addrlen,
   3089                          bool external_add,
   3090                          bool non_blck,
   3091                          bool sk_spipe_supprs,
   3092                          enum MHD_tristate sk_is_nonip)
   3093 {
   3094   struct MHD_Connection *connection;
   3095 
   3096 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   3097   /* Direct add to master daemon could never happen. */
   3098   mhd_assert (NULL == daemon->worker_pool);
   3099 #endif
   3100 
   3101   if (MHD_D_IS_USING_SELECT_ (daemon) &&
   3102       (! MHD_D_DOES_SCKT_FIT_FDSET_ (client_socket, daemon)) )
   3103   {
   3104 #ifdef HAVE_MESSAGES
   3105     MHD_DLOG (daemon,
   3106               _ ("New connection socket descriptor (%d) is not less " \
   3107                  "than FD_SETSIZE (%d).\n"),
   3108               (int) client_socket,
   3109               (int) MHD_D_GET_FD_SETSIZE_ (daemon));
   3110 #endif
   3111     MHD_socket_close_chk_ (client_socket);
   3112 #if defined(ENFILE) && (ENFILE + 0 != 0)
   3113     errno = ENFILE;
   3114 #endif
   3115     return MHD_NO;
   3116   }
   3117 
   3118   if (MHD_D_IS_USING_EPOLL_ (daemon) &&
   3119       (! non_blck) )
   3120   {
   3121 #ifdef HAVE_MESSAGES
   3122     MHD_DLOG (daemon,
   3123               _ ("Epoll mode supports only non-blocking sockets\n"));
   3124 #endif
   3125     MHD_socket_close_chk_ (client_socket);
   3126 #if defined(EINVAL) && (EINVAL + 0 != 0)
   3127     errno = EINVAL;
   3128 #endif
   3129     return MHD_NO;
   3130   }
   3131 
   3132   connection = new_connection_prepare_ (daemon,
   3133                                         client_socket,
   3134                                         addr, addrlen,
   3135                                         external_add,
   3136                                         non_blck,
   3137                                         sk_spipe_supprs,
   3138                                         sk_is_nonip);
   3139   if (NULL == connection)
   3140     return MHD_NO;
   3141 
   3142   if ((external_add) &&
   3143       MHD_D_IS_THREAD_SAFE_ (daemon))
   3144   {
   3145     /* Connection is added externally and MHD is thread safe mode. */
   3146     MHD_mutex_lock_chk_ (&daemon->new_connections_mutex);
   3147     DLL_insert (daemon->new_connections_head,
   3148                 daemon->new_connections_tail,
   3149                 connection);
   3150     daemon->have_new = true;
   3151     MHD_mutex_unlock_chk_ (&daemon->new_connections_mutex);
   3152 
   3153     /* The rest of connection processing must be handled in
   3154      * the daemon thread. */
   3155     if ((MHD_ITC_IS_VALID_ (daemon->itc)) &&
   3156         (! MHD_itc_activate_ (daemon->itc, "n")))
   3157     {
   3158 #ifdef HAVE_MESSAGES
   3159       MHD_DLOG (daemon,
   3160                 _ ("Failed to signal new connection via inter-thread " \
   3161                    "communication channel.\n"));
   3162 #endif
   3163     }
   3164     return MHD_YES;
   3165   }
   3166 
   3167   return new_connection_process_ (daemon, connection);
   3168 }
   3169 
   3170 
   3171 static void
   3172 new_connections_list_process_ (struct MHD_Daemon *daemon)
   3173 {
   3174   struct MHD_Connection *local_head;
   3175   struct MHD_Connection *local_tail;
   3176   mhd_assert (daemon->have_new);
   3177   mhd_assert (MHD_D_IS_THREAD_SAFE_ (daemon));
   3178 
   3179   /* Detach DL-list of new connections from the daemon for
   3180    * following local processing. */
   3181   MHD_mutex_lock_chk_ (&daemon->new_connections_mutex);
   3182   mhd_assert (NULL != daemon->new_connections_head);
   3183   local_head = daemon->new_connections_head;
   3184   local_tail = daemon->new_connections_tail;
   3185   daemon->new_connections_head = NULL;
   3186   daemon->new_connections_tail = NULL;
   3187   daemon->have_new = false;
   3188   MHD_mutex_unlock_chk_ (&daemon->new_connections_mutex);
   3189   (void) local_head; /* Mute compiler warning */
   3190 
   3191   /* Process new connections in FIFO order. */
   3192   do
   3193   {
   3194     struct MHD_Connection *c;   /**< Currently processed connection */
   3195 
   3196     c = local_tail;
   3197     DLL_remove (local_head,
   3198                 local_tail,
   3199                 c);
   3200     mhd_assert (daemon == c->daemon);
   3201     if (MHD_NO == new_connection_process_ (daemon, c))
   3202     {
   3203 #ifdef HAVE_MESSAGES
   3204       MHD_DLOG (daemon,
   3205                 _ ("Failed to start serving new connection.\n"));
   3206 #endif
   3207       (void) 0;
   3208     }
   3209   } while (NULL != local_tail);
   3210 
   3211 }
   3212 
   3213 
   3214 /**
   3215  * Internal version of ::MHD_suspend_connection().
   3216  *
   3217  * @remark In thread-per-connection mode: can be called from any thread,
   3218  * in any other mode: to be called only from thread that process
   3219  * daemon's select()/poll()/etc.
   3220  *
   3221  * @param connection the connection to suspend
   3222  */
   3223 void
   3224 internal_suspend_connection_ (struct MHD_Connection *connection)
   3225 {
   3226   struct MHD_Daemon *daemon = connection->daemon;
   3227   mhd_assert (NULL == daemon->worker_pool);
   3228 
   3229 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   3230   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   3231                MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) || \
   3232                MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   3233   MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   3234 #endif
   3235   if (connection->resuming)
   3236   {
   3237     /* suspending again while we didn't even complete resuming yet */
   3238     connection->resuming = false;
   3239 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   3240     MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   3241 #endif
   3242     return;
   3243   }
   3244   if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   3245   {
   3246     if (connection->connection_timeout_ms == daemon->connection_timeout_ms)
   3247       XDLL_remove (daemon->normal_timeout_head,
   3248                    daemon->normal_timeout_tail,
   3249                    connection);
   3250     else
   3251       XDLL_remove (daemon->manual_timeout_head,
   3252                    daemon->manual_timeout_tail,
   3253                    connection);
   3254   }
   3255   DLL_remove (daemon->connections_head,
   3256               daemon->connections_tail,
   3257               connection);
   3258   mhd_assert (! connection->suspended);
   3259   DLL_insert (daemon->suspended_connections_head,
   3260               daemon->suspended_connections_tail,
   3261               connection);
   3262   connection->suspended = true;
   3263 #ifdef EPOLL_SUPPORT
   3264   if (MHD_D_IS_USING_EPOLL_ (daemon))
   3265   {
   3266     if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
   3267     {
   3268       EDLL_remove (daemon->eready_head,
   3269                    daemon->eready_tail,
   3270                    connection);
   3271       connection->epoll_state &=
   3272         ~((enum MHD_EpollState) MHD_EPOLL_STATE_IN_EREADY_EDLL);
   3273     }
   3274     if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
   3275     {
   3276       if (0 != epoll_ctl (daemon->epoll_fd,
   3277                           EPOLL_CTL_DEL,
   3278                           connection->socket_fd,
   3279                           NULL))
   3280         MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
   3281       connection->epoll_state &=
   3282         ~((enum MHD_EpollState) MHD_EPOLL_STATE_IN_EPOLL_SET);
   3283     }
   3284     connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
   3285   }
   3286 #endif
   3287 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   3288   MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   3289 #endif
   3290 }
   3291 
   3292 
   3293 /**
   3294  * Suspend handling of network data for a given connection.
   3295  * This can be used to dequeue a connection from MHD's event loop
   3296  * (not applicable to thread-per-connection!) for a while.
   3297  *
   3298  * If you use this API in conjunction with an "internal" socket polling,
   3299  * you must set the option #MHD_USE_ITC to ensure that a resumed
   3300  * connection is immediately processed by MHD.
   3301  *
   3302  * Suspended connections continue to count against the total number of
   3303  * connections allowed (per daemon, as well as per IP, if such limits
   3304  * are set).  Suspended connections will NOT time out; timeouts will
   3305  * restart when the connection handling is resumed.  While a
   3306  * connection is suspended, MHD will not detect disconnects by the
   3307  * client.
   3308  *
   3309  * The only safe way to call this function is to call it from the
   3310  * #MHD_AccessHandlerCallback or #MHD_ContentReaderCallback.
   3311  *
   3312  * Finally, it is an API violation to call #MHD_stop_daemon while
   3313  * having suspended connections (this will at least create memory and
   3314  * socket leaks or lead to undefined behavior).  You must explicitly
   3315  * resume all connections before stopping the daemon.
   3316  *
   3317  * @param connection the connection to suspend
   3318  *
   3319  * @sa #MHD_AccessHandlerCallback
   3320  */
   3321 _MHD_EXTERN void
   3322 MHD_suspend_connection (struct MHD_Connection *connection)
   3323 {
   3324   struct MHD_Daemon *const daemon = connection->daemon;
   3325 
   3326 #ifdef MHD_USE_THREADS
   3327   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   3328                MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) || \
   3329                MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   3330 #endif /* MHD_USE_THREADS */
   3331 
   3332   if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
   3333     MHD_PANIC (_ ("Cannot suspend connections without " \
   3334                   "enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
   3335 #ifdef UPGRADE_SUPPORT
   3336   if (NULL != connection->urh)
   3337   {
   3338 #ifdef HAVE_MESSAGES
   3339     MHD_DLOG (daemon,
   3340               _ ("Error: connection scheduled for \"upgrade\" cannot " \
   3341                  "be suspended.\n"));
   3342 #endif /* HAVE_MESSAGES */
   3343     return;
   3344   }
   3345 #endif /* UPGRADE_SUPPORT */
   3346   internal_suspend_connection_ (connection);
   3347 }
   3348 
   3349 
   3350 /**
   3351  * Resume handling of network data for suspended connection.  It is
   3352  * safe to resume a suspended connection at any time.  Calling this
   3353  * function on a connection that was not previously suspended will
   3354  * result in undefined behavior.
   3355  *
   3356  * If you are using this function in "external" sockets polling mode, you must
   3357  * make sure to run #MHD_run() and #MHD_get_timeout() afterwards (before
   3358  * again calling #MHD_get_fdset()), as otherwise the change may not be
   3359  * reflected in the set returned by #MHD_get_fdset() and you may end up
   3360  * with a connection that is stuck until the next network activity.
   3361  *
   3362  * @param connection the connection to resume
   3363  */
   3364 _MHD_EXTERN void
   3365 MHD_resume_connection (struct MHD_Connection *connection)
   3366 {
   3367   struct MHD_Daemon *daemon = connection->daemon;
   3368 #if defined(MHD_USE_THREADS)
   3369   mhd_assert (NULL == daemon->worker_pool);
   3370 #endif /* MHD_USE_THREADS */
   3371 
   3372   if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
   3373     MHD_PANIC (_ ("Cannot resume connections without enabling " \
   3374                   "MHD_ALLOW_SUSPEND_RESUME!\n"));
   3375 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   3376   MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   3377 #endif
   3378   connection->resuming = true;
   3379   daemon->resuming = true;
   3380 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   3381   MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   3382 #endif
   3383   if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
   3384        (! MHD_itc_activate_ (daemon->itc, "r")) )
   3385   {
   3386 #ifdef HAVE_MESSAGES
   3387     MHD_DLOG (daemon,
   3388               _ ("Failed to signal resume via inter-thread " \
   3389                  "communication channel.\n"));
   3390 #endif
   3391   }
   3392 }
   3393 
   3394 
   3395 #ifdef UPGRADE_SUPPORT
   3396 /**
   3397  * Mark upgraded connection as closed by application.
   3398  *
   3399  * The @a connection pointer must not be used after call of this function
   3400  * as it may be freed in other thread immediately.
   3401  * @param connection the upgraded connection to mark as closed by application
   3402  */
   3403 void
   3404 MHD_upgraded_connection_mark_app_closed_ (struct MHD_Connection *connection)
   3405 {
   3406   /* Cache 'daemon' here to avoid data races */
   3407   struct MHD_Daemon *const daemon = connection->daemon;
   3408 #if defined(MHD_USE_THREADS)
   3409   mhd_assert (NULL == daemon->worker_pool);
   3410 #endif /* MHD_USE_THREADS */
   3411   mhd_assert (NULL != connection->urh);
   3412   mhd_assert (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME));
   3413 
   3414   MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   3415   connection->urh->was_closed = true;
   3416   connection->resuming = true;
   3417   daemon->resuming = true;
   3418   MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   3419   if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
   3420        (! MHD_itc_activate_ (daemon->itc, "r")) )
   3421   {
   3422 #ifdef HAVE_MESSAGES
   3423     MHD_DLOG (daemon,
   3424               _ ("Failed to signal resume via " \
   3425                  "inter-thread communication channel.\n"));
   3426 #endif
   3427   }
   3428 }
   3429 
   3430 
   3431 #endif /* UPGRADE_SUPPORT */
   3432 
   3433 /**
   3434  * Run through the suspended connections and move any that are no
   3435  * longer suspended back to the active state.
   3436  * @remark To be called only from thread that process
   3437  * daemon's select()/poll()/etc.
   3438  *
   3439  * @param daemon daemon context
   3440  * @return #MHD_YES if a connection was actually resumed
   3441  */
   3442 static enum MHD_Result
   3443 resume_suspended_connections (struct MHD_Daemon *daemon)
   3444 {
   3445   struct MHD_Connection *pos;
   3446   struct MHD_Connection *prev = NULL;
   3447   enum MHD_Result ret;
   3448   const bool used_thr_p_c = (0 != (daemon->options
   3449                                    & MHD_USE_THREAD_PER_CONNECTION));
   3450 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   3451   mhd_assert (NULL == daemon->worker_pool);
   3452   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   3453                MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   3454 #endif
   3455 
   3456   ret = MHD_NO;
   3457 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   3458   MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   3459 #endif
   3460 
   3461   if (daemon->resuming)
   3462   {
   3463     prev = daemon->suspended_connections_tail;
   3464     /* During shutdown check for resuming is forced. */
   3465     mhd_assert ((NULL != prev) || (daemon->shutdown) || \
   3466                 (0 != (daemon->options & MHD_ALLOW_UPGRADE)));
   3467   }
   3468 
   3469   daemon->resuming = false;
   3470 
   3471   while (NULL != (pos = prev))
   3472   {
   3473 #ifdef UPGRADE_SUPPORT
   3474     struct MHD_UpgradeResponseHandle *const urh = pos->urh;
   3475 #else  /* ! UPGRADE_SUPPORT */
   3476     static const void *const urh = NULL;
   3477 #endif /* ! UPGRADE_SUPPORT */
   3478     prev = pos->prev;
   3479     if ( (! pos->resuming)
   3480 #ifdef UPGRADE_SUPPORT
   3481          || ( (NULL != urh) &&
   3482               ( (! urh->was_closed) ||
   3483                 (! urh->clean_ready) ) )
   3484 #endif /* UPGRADE_SUPPORT */
   3485          )
   3486       continue;
   3487     ret = MHD_YES;
   3488     mhd_assert (pos->suspended);
   3489     DLL_remove (daemon->suspended_connections_head,
   3490                 daemon->suspended_connections_tail,
   3491                 pos);
   3492     pos->suspended = false;
   3493     if (NULL == urh)
   3494     {
   3495       DLL_insert (daemon->connections_head,
   3496                   daemon->connections_tail,
   3497                   pos);
   3498       if (! used_thr_p_c)
   3499       {
   3500         /* Reset timeout timer on resume. */
   3501         if (0 != pos->connection_timeout_ms)
   3502           pos->last_activity = MHD_monotonic_msec_counter ();
   3503 
   3504         if (pos->connection_timeout_ms == daemon->connection_timeout_ms)
   3505           XDLL_insert (daemon->normal_timeout_head,
   3506                        daemon->normal_timeout_tail,
   3507                        pos);
   3508         else
   3509           XDLL_insert (daemon->manual_timeout_head,
   3510                        daemon->manual_timeout_tail,
   3511                        pos);
   3512       }
   3513 #ifdef EPOLL_SUPPORT
   3514       if (MHD_D_IS_USING_EPOLL_ (daemon))
   3515       {
   3516         if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
   3517           MHD_PANIC ("Resumed connection was already in EREADY set.\n");
   3518         /* we always mark resumed connections as ready, as we
   3519            might have missed the edge poll event during suspension */
   3520         EDLL_insert (daemon->eready_head,
   3521                      daemon->eready_tail,
   3522                      pos);
   3523         pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL   \
   3524                             | MHD_EPOLL_STATE_READ_READY
   3525                             | MHD_EPOLL_STATE_WRITE_READY;
   3526         pos->epoll_state &= ~((enum MHD_EpollState) MHD_EPOLL_STATE_SUSPENDED);
   3527       }
   3528 #endif
   3529     }
   3530 #ifdef UPGRADE_SUPPORT
   3531     else
   3532     {
   3533       /* Data forwarding was finished (for TLS connections) AND
   3534        * application was closed upgraded connection.
   3535        * Insert connection into cleanup list. */
   3536 
   3537       if ( (NULL != daemon->notify_completed) &&
   3538            (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) &&
   3539            (pos->rq.client_aware) )
   3540       {
   3541         daemon->notify_completed (daemon->notify_completed_cls,
   3542                                   pos,
   3543                                   &pos->rq.client_context,
   3544                                   MHD_REQUEST_TERMINATED_COMPLETED_OK);
   3545         pos->rq.client_aware = false;
   3546       }
   3547       DLL_insert (daemon->cleanup_head,
   3548                   daemon->cleanup_tail,
   3549                   pos);
   3550       daemon->data_already_pending = true;
   3551     }
   3552 #endif /* UPGRADE_SUPPORT */
   3553     pos->resuming = false;
   3554   }
   3555 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   3556   MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   3557 #endif
   3558   if ( (used_thr_p_c) &&
   3559        (MHD_NO != ret) )
   3560   {   /* Wake up suspended connections. */
   3561     if (! MHD_itc_activate_ (daemon->itc,
   3562                              "w"))
   3563     {
   3564 #ifdef HAVE_MESSAGES
   3565       MHD_DLOG (daemon,
   3566                 _ ("Failed to signal resume of connection via " \
   3567                    "inter-thread communication channel.\n"));
   3568 #endif
   3569     }
   3570   }
   3571   return ret;
   3572 }
   3573 
   3574 
   3575 /**
   3576  * Add another client connection to the set of connections managed by
   3577  * MHD.  This API is usually not needed (since MHD will accept inbound
   3578  * connections on the server socket).  Use this API in special cases,
   3579  * for example if your HTTP server is behind NAT and needs to connect
   3580  * out to the HTTP client, or if you are building a proxy.
   3581  *
   3582  * If you use this API in conjunction with a internal select or a
   3583  * thread pool, you must set the option
   3584  * #MHD_USE_ITC to ensure that the freshly added
   3585  * connection is immediately processed by MHD.
   3586  *
   3587  * The given client socket will be managed (and closed!) by MHD after
   3588  * this call and must no longer be used directly by the application
   3589  * afterwards.
   3590  *
   3591  * @param daemon daemon that manages the connection
   3592  * @param client_socket socket to manage (MHD will expect
   3593  *        to receive an HTTP request from this socket next).
   3594  * @param addr IP address of the client
   3595  * @param addrlen number of bytes in @a addr
   3596  * @return #MHD_YES on success, #MHD_NO if this daemon could
   3597  *        not handle the connection (i.e. malloc() failed, etc).
   3598  *        The socket will be closed in any case; `errno` is
   3599  *        set to indicate further details about the error.
   3600  * @ingroup specialized
   3601  */
   3602 _MHD_EXTERN enum MHD_Result
   3603 MHD_add_connection (struct MHD_Daemon *daemon,
   3604                     MHD_socket client_socket,
   3605                     const struct sockaddr *addr,
   3606                     socklen_t addrlen)
   3607 {
   3608   bool sk_nonbl;
   3609   bool sk_spipe_supprs;
   3610   struct sockaddr_storage addrstorage;
   3611 
   3612   /* TODO: fix atomic value reading */
   3613   if ((! MHD_D_IS_THREAD_SAFE_ (daemon)) &&
   3614       (daemon->connection_limit <= daemon->connections))
   3615     MHD_cleanup_connections (daemon);
   3616 
   3617 #ifdef HAVE_MESSAGES
   3618   if (MHD_D_IS_USING_THREADS_ (daemon) &&
   3619       (0 == (daemon->options & MHD_USE_ITC)))
   3620   {
   3621     MHD_DLOG (daemon,
   3622               _ ("MHD_add_connection() has been called for daemon started"
   3623                  " without MHD_USE_ITC flag.\nDaemon will not process newly"
   3624                  " added connection until any activity occurs in already"
   3625                  " added sockets.\n"));
   3626   }
   3627 #endif /* HAVE_MESSAGES */
   3628   if (0 != addrlen)
   3629   {
   3630     if (AF_INET == addr->sa_family)
   3631     {
   3632       if (sizeof(struct sockaddr_in) > (size_t) addrlen)
   3633       {
   3634 #ifdef HAVE_MESSAGES
   3635         MHD_DLOG (daemon,
   3636                   _ ("MHD_add_connection() has been called with "
   3637                      "incorrect 'addrlen' value.\n"));
   3638 #endif /* HAVE_MESSAGES */
   3639         return MHD_NO;
   3640       }
   3641 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
   3642       if ((0 != addr->sa_len) &&
   3643           (sizeof(struct sockaddr_in) > (size_t) addr->sa_len) )
   3644       {
   3645 #ifdef HAVE_MESSAGES
   3646         MHD_DLOG (daemon,
   3647                   _ ("MHD_add_connection() has been called with " \
   3648                      "non-zero value of 'sa_len' member of " \
   3649                      "'struct sockaddr' which does not match 'sa_family'.\n"));
   3650 #endif /* HAVE_MESSAGES */
   3651         return MHD_NO;
   3652       }
   3653 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
   3654     }
   3655 #ifdef HAVE_INET6
   3656     if (AF_INET6 == addr->sa_family)
   3657     {
   3658       if (sizeof(struct sockaddr_in6) > (size_t) addrlen)
   3659       {
   3660 #ifdef HAVE_MESSAGES
   3661         MHD_DLOG (daemon,
   3662                   _ ("MHD_add_connection() has been called with "
   3663                      "incorrect 'addrlen' value.\n"));
   3664 #endif /* HAVE_MESSAGES */
   3665         return MHD_NO;
   3666       }
   3667 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
   3668       if ((0 != addr->sa_len) &&
   3669           (sizeof(struct sockaddr_in6) > (size_t) addr->sa_len) )
   3670       {
   3671 #ifdef HAVE_MESSAGES
   3672         MHD_DLOG (daemon,
   3673                   _ ("MHD_add_connection() has been called with " \
   3674                      "non-zero value of 'sa_len' member of " \
   3675                      "'struct sockaddr' which does not match 'sa_family'.\n"));
   3676 #endif /* HAVE_MESSAGES */
   3677         return MHD_NO;
   3678       }
   3679 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
   3680     }
   3681 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
   3682     if ((0 != addr->sa_len) &&
   3683         (addrlen > addr->sa_len))
   3684       addrlen = (socklen_t) addr->sa_len;   /* Use safest value */
   3685 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
   3686 #endif /* HAVE_INET6 */
   3687   }
   3688 
   3689   if (! MHD_socket_nonblocking_ (client_socket))
   3690   {
   3691 #ifdef HAVE_MESSAGES
   3692     MHD_DLOG (daemon,
   3693               _ ("Failed to set nonblocking mode on new client socket: %s\n"),
   3694               MHD_socket_last_strerr_ ());
   3695 #endif
   3696     sk_nonbl = false;
   3697   }
   3698   else
   3699     sk_nonbl = true;
   3700 
   3701 #ifndef MHD_WINSOCK_SOCKETS
   3702   sk_spipe_supprs = false;
   3703 #else  /* MHD_WINSOCK_SOCKETS */
   3704   sk_spipe_supprs = true; /* Nothing to suppress on W32 */
   3705 #endif /* MHD_WINSOCK_SOCKETS */
   3706 #if defined(MHD_socket_nosignal_)
   3707   if (! sk_spipe_supprs)
   3708     sk_spipe_supprs = MHD_socket_nosignal_ (client_socket);
   3709   if (! sk_spipe_supprs)
   3710   {
   3711 #ifdef HAVE_MESSAGES
   3712     MHD_DLOG (daemon,
   3713               _ ("Failed to suppress SIGPIPE on new client socket: %s\n"),
   3714               MHD_socket_last_strerr_ ());
   3715 #else  /* ! HAVE_MESSAGES */
   3716     (void) 0; /* Mute compiler warning */
   3717 #endif /* ! HAVE_MESSAGES */
   3718 #ifndef MSG_NOSIGNAL
   3719     /* Application expects that SIGPIPE will be suppressed,
   3720      * but suppression failed and SIGPIPE cannot be suppressed with send(). */
   3721     if (! daemon->sigpipe_blocked)
   3722     {
   3723       int err = MHD_socket_get_error_ ();
   3724       MHD_socket_close_ (client_socket);
   3725       MHD_socket_fset_error_ (err);
   3726       return MHD_NO;
   3727     }
   3728 #endif /* MSG_NOSIGNAL */
   3729   }
   3730 #endif /* MHD_socket_nosignal_ */
   3731 
   3732   if ( (0 != (daemon->options & MHD_USE_TURBO)) &&
   3733        (! MHD_socket_noninheritable_ (client_socket)) )
   3734   {
   3735 #ifdef HAVE_MESSAGES
   3736     MHD_DLOG (daemon,
   3737               _ ("Failed to set noninheritable mode on new client socket.\n"));
   3738 #endif
   3739   }
   3740 
   3741   /* Copy to sockaddr_storage structure to avoid alignment problems */
   3742   if (0 < addrlen)
   3743     memcpy (&addrstorage, addr, (size_t) addrlen);
   3744 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
   3745   addrstorage.ss_len = addrlen; /* Force set the right length */
   3746 #endif /* HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN */
   3747 
   3748 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   3749   if (NULL != daemon->worker_pool)
   3750   {
   3751     unsigned int i;
   3752     /* have a pool, try to find a pool with capacity; we use the
   3753        socket as the initial offset into the pool for load
   3754        balancing */
   3755     for (i = 0; i < daemon->worker_pool_size; ++i)
   3756     {
   3757       struct MHD_Daemon *const worker =
   3758         &daemon->worker_pool[(i + (unsigned int) client_socket)
   3759                              % daemon->worker_pool_size];
   3760       if (worker->connections < worker->connection_limit)
   3761         return internal_add_connection (worker,
   3762                                         client_socket,
   3763                                         &addrstorage,
   3764                                         addrlen,
   3765                                         true,
   3766                                         sk_nonbl,
   3767                                         sk_spipe_supprs,
   3768                                         _MHD_UNKNOWN);
   3769     }
   3770     /* all pools are at their connection limit, must refuse */
   3771     MHD_socket_close_chk_ (client_socket);
   3772 #if defined(ENFILE) && (ENFILE + 0 != 0)
   3773     errno = ENFILE;
   3774 #endif
   3775     return MHD_NO;
   3776   }
   3777 #endif /* MHD_USE_POSIX_THREADS || MHD_USE_W32_THREADS */
   3778 
   3779   return internal_add_connection (daemon,
   3780                                   client_socket,
   3781                                   &addrstorage,
   3782                                   addrlen,
   3783                                   true,
   3784                                   sk_nonbl,
   3785                                   sk_spipe_supprs,
   3786                                   _MHD_UNKNOWN);
   3787 }
   3788 
   3789 
   3790 /**
   3791  * Accept an incoming connection and create the MHD_Connection object for
   3792  * it.  This function also enforces policy by way of checking with the
   3793  * accept policy callback.
   3794  * @remark To be called only from thread that process
   3795  * daemon's select()/poll()/etc.
   3796  *
   3797  * @param daemon handle with the listen socket
   3798  * @return #MHD_YES on success (connections denied by policy or due
   3799  *         to 'out of memory' and similar errors) are still considered
   3800  *         successful as far as #MHD_accept_connection() is concerned);
   3801  *         a return code of #MHD_NO only refers to the actual
   3802  *         accept() system call.
   3803  */
   3804 static enum MHD_Result
   3805 MHD_accept_connection (struct MHD_Daemon *daemon)
   3806 {
   3807   struct sockaddr_storage addrstorage;
   3808   socklen_t addrlen;
   3809   MHD_socket s;
   3810   MHD_socket fd;
   3811   bool sk_nonbl;
   3812   bool sk_spipe_supprs;
   3813   bool sk_cloexec;
   3814   enum MHD_tristate sk_non_ip;
   3815 #if defined(_DEBUG) && defined (USE_ACCEPT4)
   3816   const bool use_accept4 = ! daemon->avoid_accept4;
   3817 #elif defined (USE_ACCEPT4)
   3818   static const bool use_accept4 = true;
   3819 #else  /* ! USE_ACCEPT4 && ! _DEBUG */
   3820   static const bool use_accept4 = false;
   3821 #endif /* ! USE_ACCEPT4 && ! _DEBUG */
   3822 
   3823 #ifdef MHD_USE_THREADS
   3824   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   3825                MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   3826   mhd_assert (NULL == daemon->worker_pool);
   3827 #endif /* MHD_USE_THREADS */
   3828 
   3829   if ( (MHD_INVALID_SOCKET == (fd = daemon->listen_fd)) ||
   3830        (daemon->was_quiesced) )
   3831     return MHD_NO;
   3832 
   3833   addrlen = (socklen_t) sizeof (addrstorage);
   3834   memset (&addrstorage,
   3835           0,
   3836           (size_t) addrlen);
   3837 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
   3838   addrstorage.ss_len = addrlen;
   3839 #endif /* HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN */
   3840 
   3841   /* Initialise with default values to avoid compiler warnings */
   3842   sk_nonbl = false;
   3843   sk_spipe_supprs = false;
   3844   sk_cloexec = false;
   3845   s = MHD_INVALID_SOCKET;
   3846 
   3847 #ifdef USE_ACCEPT4
   3848   if (use_accept4 &&
   3849       (MHD_INVALID_SOCKET !=
   3850        (s = accept4 (fd,
   3851                      (struct sockaddr *) &addrstorage,
   3852                      &addrlen,
   3853                      SOCK_CLOEXEC_OR_ZERO | SOCK_NONBLOCK_OR_ZERO
   3854                      | SOCK_NOSIGPIPE_OR_ZERO))))
   3855   {
   3856     sk_nonbl = (SOCK_NONBLOCK_OR_ZERO != 0);
   3857 #ifndef MHD_WINSOCK_SOCKETS
   3858     sk_spipe_supprs = (SOCK_NOSIGPIPE_OR_ZERO != 0);
   3859 #else  /* MHD_WINSOCK_SOCKETS */
   3860     sk_spipe_supprs = true; /* Nothing to suppress on W32 */
   3861 #endif /* MHD_WINSOCK_SOCKETS */
   3862     sk_cloexec = (SOCK_CLOEXEC_OR_ZERO != 0);
   3863   }
   3864 #endif /* USE_ACCEPT4 */
   3865 #if defined(_DEBUG) || ! defined(USE_ACCEPT4)
   3866   if (! use_accept4 &&
   3867       (MHD_INVALID_SOCKET !=
   3868        (s = accept (fd,
   3869                     (struct sockaddr *) &addrstorage,
   3870                     &addrlen))))
   3871   {
   3872 #ifdef MHD_ACCEPT_INHERIT_NONBLOCK
   3873     sk_nonbl = daemon->listen_nonblk;
   3874 #else  /* ! MHD_ACCEPT_INHERIT_NONBLOCK */
   3875     sk_nonbl = false;
   3876 #endif /* ! MHD_ACCEPT_INHERIT_NONBLOCK */
   3877 #ifndef MHD_WINSOCK_SOCKETS
   3878     sk_spipe_supprs = false;
   3879 #else  /* MHD_WINSOCK_SOCKETS */
   3880     sk_spipe_supprs = true; /* Nothing to suppress on W32 */
   3881 #endif /* MHD_WINSOCK_SOCKETS */
   3882     sk_cloexec = false;
   3883   }
   3884 #endif /* _DEBUG || !USE_ACCEPT4 */
   3885 
   3886   if (MHD_INVALID_SOCKET == s)
   3887   {
   3888     const int err = MHD_socket_get_error_ ();
   3889 
   3890     /* This could be a common occurrence with multiple worker threads */
   3891     if (MHD_SCKT_ERR_IS_ (err,
   3892                           MHD_SCKT_EINVAL_))
   3893       return MHD_NO;   /* can happen during shutdown */
   3894     if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_ (err))
   3895       return MHD_NO;   /* do not print error if client just disconnected early */
   3896 #ifdef HAVE_MESSAGES
   3897     if (! MHD_SCKT_ERR_IS_EAGAIN_ (err) )
   3898       MHD_DLOG (daemon,
   3899                 _ ("Error accepting connection: %s\n"),
   3900                 MHD_socket_strerr_ (err));
   3901 #endif
   3902     if (MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) )
   3903     {
   3904       /* system/process out of resources */
   3905       if (0 == daemon->connections)
   3906       {
   3907 #ifdef HAVE_MESSAGES
   3908         /* Not setting 'at_limit' flag, as there is no way it
   3909            would ever be cleared.  Instead trying to produce
   3910            bit fat ugly warning. */
   3911         MHD_DLOG (daemon,
   3912                   _ ("Hit process or system resource limit at FIRST " \
   3913                      "connection. This is really bad as there is no sane " \
   3914                      "way to proceed. Will try busy waiting for system " \
   3915                      "resources to become magically available.\n"));
   3916 #endif
   3917       }
   3918       else
   3919       {
   3920 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   3921         MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   3922 #endif
   3923         daemon->at_limit = true;
   3924 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   3925         MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   3926 #endif
   3927 #ifdef HAVE_MESSAGES
   3928         MHD_DLOG (daemon,
   3929                   _ ("Hit process or system resource limit at %u " \
   3930                      "connections, temporarily suspending accept(). " \
   3931                      "Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
   3932                   (unsigned int) daemon->connections);
   3933 #endif
   3934       }
   3935     }
   3936     return MHD_NO;
   3937   }
   3938 
   3939   sk_non_ip = daemon->listen_is_unix;
   3940   if (0 >= addrlen)
   3941   {
   3942 #ifdef HAVE_MESSAGES
   3943     if (_MHD_NO != daemon->listen_is_unix)
   3944       MHD_DLOG (daemon,
   3945                 _ ("Accepted socket has zero-length address. "
   3946                    "Processing the new socket as a socket with " \
   3947                    "unknown type.\n"));
   3948 #endif
   3949     addrlen = 0;
   3950     sk_non_ip = _MHD_YES; /* IP-type addresses have non-zero length */
   3951   }
   3952   if (((socklen_t) sizeof (addrstorage)) < addrlen)
   3953   {
   3954     /* Should not happen as 'sockaddr_storage' must be large enough to
   3955      * store any address supported by the system. */
   3956 #ifdef HAVE_MESSAGES
   3957     MHD_DLOG (daemon,
   3958               _ ("Accepted socket address is larger than expected by " \
   3959                  "system headers. Processing the new socket as a socket with " \
   3960                  "unknown type.\n"));
   3961 #endif
   3962     addrlen = 0;
   3963     sk_non_ip = _MHD_YES; /* IP-type addresses must fit */
   3964   }
   3965 
   3966   if (! sk_nonbl && ! MHD_socket_nonblocking_ (s))
   3967   {
   3968 #ifdef HAVE_MESSAGES
   3969     MHD_DLOG (daemon,
   3970               _ ("Failed to set nonblocking mode on incoming connection " \
   3971                  "socket: %s\n"),
   3972               MHD_socket_last_strerr_ ());
   3973 #else  /* ! HAVE_MESSAGES */
   3974     (void) 0; /* Mute compiler warning */
   3975 #endif /* ! HAVE_MESSAGES */
   3976   }
   3977   else
   3978     sk_nonbl = true;
   3979 
   3980   if (! sk_cloexec && ! MHD_socket_noninheritable_ (s))
   3981   {
   3982 #ifdef HAVE_MESSAGES
   3983     MHD_DLOG (daemon,
   3984               _ ("Failed to set noninheritable mode on incoming connection " \
   3985                  "socket.\n"));
   3986 #else  /* ! HAVE_MESSAGES */
   3987     (void) 0; /* Mute compiler warning */
   3988 #endif /* ! HAVE_MESSAGES */
   3989   }
   3990 
   3991 #if defined(MHD_socket_nosignal_)
   3992   if (! sk_spipe_supprs && ! MHD_socket_nosignal_ (s))
   3993   {
   3994 #ifdef HAVE_MESSAGES
   3995     MHD_DLOG (daemon,
   3996               _ ("Failed to suppress SIGPIPE on incoming connection " \
   3997                  "socket: %s\n"),
   3998               MHD_socket_last_strerr_ ());
   3999 #else  /* ! HAVE_MESSAGES */
   4000     (void) 0; /* Mute compiler warning */
   4001 #endif /* ! HAVE_MESSAGES */
   4002 #ifndef MSG_NOSIGNAL
   4003     /* Application expects that SIGPIPE will be suppressed,
   4004      * but suppression failed and SIGPIPE cannot be suppressed with send(). */
   4005     if (! daemon->sigpipe_blocked)
   4006     {
   4007       (void) MHD_socket_close_ (s);
   4008       return MHD_NO;
   4009     }
   4010 #endif /* MSG_NOSIGNAL */
   4011   }
   4012   else
   4013     sk_spipe_supprs = true;
   4014 #endif /* MHD_socket_nosignal_ */
   4015 #ifdef HAVE_MESSAGES
   4016 #if _MHD_DEBUG_CONNECT
   4017   MHD_DLOG (daemon,
   4018             _ ("Accepted connection on socket %d\n"),
   4019             s);
   4020 #endif
   4021 #endif
   4022   (void) internal_add_connection (daemon,
   4023                                   s,
   4024                                   &addrstorage,
   4025                                   addrlen,
   4026                                   false,
   4027                                   sk_nonbl,
   4028                                   sk_spipe_supprs,
   4029                                   sk_non_ip);
   4030   return MHD_YES;
   4031 }
   4032 
   4033 
   4034 /**
   4035  * Free resources associated with all closed connections.
   4036  * (destroy responses, free buffers, etc.).  All closed
   4037  * connections are kept in the "cleanup" doubly-linked list.
   4038  * @remark To be called only from thread that
   4039  * process daemon's select()/poll()/etc.
   4040  *
   4041  * @param daemon daemon to clean up
   4042  */
   4043 static void
   4044 MHD_cleanup_connections (struct MHD_Daemon *daemon)
   4045 {
   4046   struct MHD_Connection *pos;
   4047 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   4048   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   4049                MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   4050   mhd_assert (NULL == daemon->worker_pool);
   4051 
   4052   MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   4053 #endif
   4054   while (NULL != (pos = daemon->cleanup_tail))
   4055   {
   4056     DLL_remove (daemon->cleanup_head,
   4057                 daemon->cleanup_tail,
   4058                 pos);
   4059 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   4060     MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   4061     if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) &&
   4062         (! pos->thread_joined) &&
   4063         (! MHD_thread_handle_ID_join_thread_ (pos->tid)) )
   4064       MHD_PANIC (_ ("Failed to join a thread.\n"));
   4065 #endif
   4066 #ifdef UPGRADE_SUPPORT
   4067     cleanup_upgraded_connection (pos);
   4068 #endif /* UPGRADE_SUPPORT */
   4069     MHD_pool_destroy (pos->pool);
   4070 #ifdef HTTPS_SUPPORT
   4071     if (NULL != pos->tls_session)
   4072       gnutls_deinit (pos->tls_session);
   4073 #endif /* HTTPS_SUPPORT */
   4074 
   4075     /* clean up the connection */
   4076     if (NULL != daemon->notify_connection)
   4077       daemon->notify_connection (daemon->notify_connection_cls,
   4078                                  pos,
   4079                                  &pos->socket_context,
   4080                                  MHD_CONNECTION_NOTIFY_CLOSED);
   4081     MHD_ip_limit_del (daemon,
   4082                       pos->addr,
   4083                       pos->addr_len);
   4084 #ifdef EPOLL_SUPPORT
   4085     if (MHD_D_IS_USING_EPOLL_ (daemon))
   4086     {
   4087       if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
   4088       {
   4089         EDLL_remove (daemon->eready_head,
   4090                      daemon->eready_tail,
   4091                      pos);
   4092         pos->epoll_state &=
   4093           ~((enum MHD_EpollState) MHD_EPOLL_STATE_IN_EREADY_EDLL);
   4094       }
   4095       if ( (-1 != daemon->epoll_fd) &&
   4096            (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
   4097       {
   4098         /* epoll documentation suggests that closing a FD
   4099            automatically removes it from the epoll set; however,
   4100            this is not true as if we fail to do manually remove it,
   4101            we are still seeing an event for this fd in epoll,
   4102            causing grief (use-after-free...) --- at least on my
   4103            system. */
   4104         if (0 != epoll_ctl (daemon->epoll_fd,
   4105                             EPOLL_CTL_DEL,
   4106                             pos->socket_fd,
   4107                             NULL))
   4108           MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
   4109         pos->epoll_state &=
   4110           ~((enum MHD_EpollState)
   4111             MHD_EPOLL_STATE_IN_EPOLL_SET);
   4112       }
   4113     }
   4114 #endif
   4115     if (NULL != pos->rp.response)
   4116     {
   4117       MHD_destroy_response (pos->rp.response);
   4118       pos->rp.response = NULL;
   4119     }
   4120     if (MHD_INVALID_SOCKET != pos->socket_fd)
   4121       MHD_socket_close_chk_ (pos->socket_fd);
   4122     if (NULL != pos->addr)
   4123       free (pos->addr);
   4124     free (pos);
   4125 
   4126 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   4127     MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   4128 #endif
   4129     daemon->connections--;
   4130     daemon->at_limit = false;
   4131   }
   4132 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   4133   MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   4134 #endif
   4135 }
   4136 
   4137 
   4138 /**
   4139  * Obtain timeout value for polling function for this daemon.
   4140  *
   4141  * This function set value to the amount of milliseconds for which polling
   4142  * function (`select()`, `poll()` or epoll) should at most block, not the
   4143  * timeout value set for connections.
   4144  *
   4145  * Any "external" sockets polling function must be called with the timeout
   4146  * value provided by this function. Smaller timeout values can be used for
   4147  * polling function if it is required for any reason, but using larger
   4148  * timeout value or no timeout (indefinite timeout) when this function
   4149  * return #MHD_YES will break MHD processing logic and result in "hung"
   4150  * connections with data pending in network buffers and other problems.
   4151  *
   4152  * It is important to always use this function (or #MHD_get_timeout64(),
   4153  * #MHD_get_timeout64s(), #MHD_get_timeout_i() functions) when "external"
   4154  * polling is used.
   4155  * If this function returns #MHD_YES then #MHD_run() (or #MHD_run_from_select())
   4156  * must be called right after return from polling function, regardless of
   4157  * the states of MHD FDs.
   4158  *
   4159  * In practice, if #MHD_YES is returned then #MHD_run() (or
   4160  * #MHD_run_from_select()) must be called not later than @a timeout
   4161  * millisecond even if no activity is detected on sockets by sockets
   4162  * polling function.
   4163  * @remark To be called only from thread that process
   4164  * daemon's select()/poll()/etc.
   4165  *
   4166  * @param daemon daemon to query for timeout
   4167  * @param[out] timeout set to the timeout (in milliseconds)
   4168  * @return #MHD_YES on success, #MHD_NO if timeouts are
   4169  *         not used and no data processing is pending.
   4170  * @ingroup event
   4171  */
   4172 _MHD_EXTERN enum MHD_Result
   4173 MHD_get_timeout (struct MHD_Daemon *daemon,
   4174                  MHD_UNSIGNED_LONG_LONG *timeout)
   4175 {
   4176   uint64_t t64;
   4177   if (MHD_NO == MHD_get_timeout64 (daemon, &t64))
   4178     return MHD_NO;
   4179 
   4180 #if SIZEOF_UINT64_T > SIZEOF_UNSIGNED_LONG_LONG
   4181   if (ULLONG_MAX <= t64)
   4182     *timeout = ULLONG_MAX;
   4183   else
   4184 #endif /* SIZEOF_UINT64_T > SIZEOF_UNSIGNED_LONG_LONG */
   4185   *timeout = (MHD_UNSIGNED_LONG_LONG) t64;
   4186   return MHD_YES;
   4187 }
   4188 
   4189 
   4190 /**
   4191  * Obtain timeout value for external polling function for this daemon.
   4192  *
   4193  * This function set value to the amount of milliseconds for which polling
   4194  * function (`select()`, `poll()` or epoll) should at most block, not the
   4195  * timeout value set for connections.
   4196  *
   4197  * Any "external" sockets polling function must be called with the timeout
   4198  * value provided by this function. Smaller timeout values can be used for
   4199  * polling function if it is required for any reason, but using larger
   4200  * timeout value or no timeout (indefinite timeout) when this function
   4201  * return #MHD_YES will break MHD processing logic and result in "hung"
   4202  * connections with data pending in network buffers and other problems.
   4203  *
   4204  * It is important to always use this function (or #MHD_get_timeout(),
   4205  * #MHD_get_timeout64s(), #MHD_get_timeout_i() functions) when "external"
   4206  * polling is used.
   4207  * If this function returns #MHD_YES then #MHD_run() (or #MHD_run_from_select())
   4208  * must be called right after return from polling function, regardless of
   4209  * the states of MHD FDs.
   4210  *
   4211  * In practice, if #MHD_YES is returned then #MHD_run() (or
   4212  * #MHD_run_from_select()) must be called not later than @a timeout
   4213  * millisecond even if no activity is detected on sockets by sockets
   4214  * polling function.
   4215  * @remark To be called only from thread that process
   4216  * daemon's select()/poll()/etc.
   4217  *
   4218  * @param daemon daemon to query for timeout
   4219  * @param[out] timeout64 the pointer to the variable to be set to the
   4220  *                  timeout (in milliseconds)
   4221  * @return #MHD_YES if timeout value has been set,
   4222  *         #MHD_NO if timeouts are not used and no data processing is pending.
   4223  * @note Available since #MHD_VERSION 0x00097701
   4224  * @ingroup event
   4225  */
   4226 _MHD_EXTERN enum MHD_Result
   4227 MHD_get_timeout64 (struct MHD_Daemon *daemon,
   4228                    uint64_t *timeout64)
   4229 {
   4230   uint64_t earliest_deadline;
   4231   struct MHD_Connection *pos;
   4232   struct MHD_Connection *earliest_tmot_conn; /**< the connection with earliest timeout */
   4233 
   4234 #ifdef MHD_USE_THREADS
   4235   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   4236                MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   4237 #endif /* MHD_USE_THREADS */
   4238 
   4239   if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   4240   {
   4241 #ifdef HAVE_MESSAGES
   4242     MHD_DLOG (daemon,
   4243               _ ("Illegal call to MHD_get_timeout.\n"));
   4244 #endif
   4245     return MHD_NO;
   4246   }
   4247   if (daemon->data_already_pending
   4248       || (NULL != daemon->cleanup_head)
   4249       || daemon->resuming
   4250       || daemon->have_new
   4251       || daemon->shutdown)
   4252   {
   4253     /* Some data or connection statuses already waiting to be processed. */
   4254     *timeout64 = 0;
   4255     return MHD_YES;
   4256   }
   4257 #ifdef EPOLL_SUPPORT
   4258   if (MHD_D_IS_USING_EPOLL_ (daemon) &&
   4259       ((NULL != daemon->eready_head)
   4260 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
   4261        || (NULL != daemon->eready_urh_head)
   4262 #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */
   4263       ) )
   4264   {
   4265     /* Some connection(s) already have some data pending. */
   4266     *timeout64 = 0;
   4267     return MHD_YES;
   4268   }
   4269 #endif /* EPOLL_SUPPORT */
   4270 
   4271   earliest_tmot_conn = NULL;
   4272   earliest_deadline = 0; /* mute compiler warning */
   4273   /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */
   4274   pos = daemon->normal_timeout_tail;
   4275   if ( (NULL != pos) &&
   4276        (0 != pos->connection_timeout_ms) )
   4277   {
   4278     earliest_tmot_conn = pos;
   4279     earliest_deadline = pos->last_activity + pos->connection_timeout_ms;
   4280   }
   4281 
   4282   for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX)
   4283   {
   4284     if (0 != pos->connection_timeout_ms)
   4285     {
   4286       if ( (NULL == earliest_tmot_conn) ||
   4287            (earliest_deadline - pos->last_activity >
   4288             pos->connection_timeout_ms) )
   4289       {
   4290         earliest_tmot_conn = pos;
   4291         earliest_deadline = pos->last_activity + pos->connection_timeout_ms;
   4292       }
   4293     }
   4294   }
   4295 
   4296   if (NULL != earliest_tmot_conn)
   4297   {
   4298     *timeout64 = connection_get_wait (earliest_tmot_conn);
   4299     return MHD_YES;
   4300   }
   4301   return MHD_NO;
   4302 }
   4303 
   4304 
   4305 #if defined(HAVE_POLL) || defined(EPOLL_SUPPORT)
   4306 /**
   4307  * Obtain timeout value for external polling function for this daemon.
   4308  *
   4309  * This function set value to the amount of milliseconds for which polling
   4310  * function (`select()`, `poll()` or epoll) should at most block, not the
   4311  * timeout value set for connections.
   4312  *
   4313  * Any "external" sockets polling function must be called with the timeout
   4314  * value provided by this function (if returned value is non-negative).
   4315  * Smaller timeout values can be used for polling function if it is required
   4316  * for any reason, but using larger timeout value or no timeout (indefinite
   4317  * timeout) when this function returns non-negative value will break MHD
   4318  * processing logic and result in "hung" connections with data pending in
   4319  * network buffers and other problems.
   4320  *
   4321  * It is important to always use this function (or #MHD_get_timeout(),
   4322  * #MHD_get_timeout64(), #MHD_get_timeout_i() functions) when "external"
   4323  * polling is used.
   4324  * If this function returns non-negative value then #MHD_run() (or
   4325  * #MHD_run_from_select()) must be called right after return from polling
   4326  * function, regardless of the states of MHD FDs.
   4327  *
   4328  * In practice, if zero or positive value is returned then #MHD_run() (or
   4329  * #MHD_run_from_select()) must be called not later than returned amount of
   4330  * millisecond even if no activity is detected on sockets by sockets
   4331  * polling function.
   4332  * @remark To be called only from thread that process
   4333  * daemon's select()/poll()/etc.
   4334  *
   4335  * @param daemon the daemon to query for timeout
   4336  * @return -1 if connections' timeouts are not set and no data processing
   4337  *         is pending, so external polling function may wait for sockets
   4338  *         activity for indefinite amount of time,
   4339  *         otherwise returned value is the the maximum amount of millisecond
   4340  *         that external polling function must wait for the activity of FDs.
   4341  * @note Available since #MHD_VERSION 0x00097701
   4342  * @ingroup event
   4343  */
   4344 _MHD_EXTERN int64_t
   4345 MHD_get_timeout64s (struct MHD_Daemon *daemon)
   4346 {
   4347   uint64_t utimeout;
   4348   if (MHD_NO == MHD_get_timeout64 (daemon, &utimeout))
   4349     return -1;
   4350   if (INT64_MAX < utimeout)
   4351     return INT64_MAX;
   4352 
   4353   return (int64_t) utimeout;
   4354 }
   4355 
   4356 
   4357 /**
   4358  * Obtain timeout value for external polling function for this daemon.
   4359  *
   4360  * This function set value to the amount of milliseconds for which polling
   4361  * function (`select()`, `poll()` or epoll) should at most block, not the
   4362  * timeout value set for connections.
   4363  *
   4364  * Any "external" sockets polling function must be called with the timeout
   4365  * value provided by this function (if returned value is non-negative).
   4366  * Smaller timeout values can be used for polling function if it is required
   4367  * for any reason, but using larger timeout value or no timeout (indefinite
   4368  * timeout) when this function returns non-negative value will break MHD
   4369  * processing logic and result in "hung" connections with data pending in
   4370  * network buffers and other problems.
   4371  *
   4372  * It is important to always use this function (or #MHD_get_timeout(),
   4373  * #MHD_get_timeout64(), #MHD_get_timeout64s() functions) when "external"
   4374  * polling is used.
   4375  * If this function returns non-negative value then #MHD_run() (or
   4376  * #MHD_run_from_select()) must be called right after return from polling
   4377  * function, regardless of the states of MHD FDs.
   4378  *
   4379  * In practice, if zero or positive value is returned then #MHD_run() (or
   4380  * #MHD_run_from_select()) must be called not later than returned amount of
   4381  * millisecond even if no activity is detected on sockets by sockets
   4382  * polling function.
   4383  * @remark To be called only from thread that process
   4384  * daemon's select()/poll()/etc.
   4385  *
   4386  * @param daemon the daemon to query for timeout
   4387  * @return -1 if connections' timeouts are not set and no data processing
   4388  *         is pending, so external polling function may wait for sockets
   4389  *         activity for indefinite amount of time,
   4390  *         otherwise returned value is the the maximum amount of millisecond
   4391  *         (capped at INT_MAX) that external polling function must wait
   4392  *         for the activity of FDs.
   4393  * @note Available since #MHD_VERSION 0x00097701
   4394  * @ingroup event
   4395  */
   4396 _MHD_EXTERN int
   4397 MHD_get_timeout_i (struct MHD_Daemon *daemon)
   4398 {
   4399 #if SIZEOF_INT >= SIZEOF_INT64_T
   4400   return MHD_get_timeout64s (daemon);
   4401 #else  /* SIZEOF_INT < SIZEOF_INT64_T */
   4402   const int64_t to64 = MHD_get_timeout64s (daemon);
   4403   if (INT_MAX >= to64)
   4404     return (int) to64;
   4405   return INT_MAX;
   4406 #endif /* SIZEOF_INT < SIZEOF_INT64_T */
   4407 }
   4408 
   4409 
   4410 /**
   4411  * Obtain timeout value for polling function for this daemon.
   4412  * @remark To be called only from the thread that processes
   4413  * daemon's select()/poll()/etc.
   4414  *
   4415  * @param daemon the daemon to query for timeout
   4416  * @param max_timeout the maximum return value (in milliseconds),
   4417  *                    ignored if set to '-1'
   4418  * @return timeout value in milliseconds or -1 if no timeout is expected.
   4419  */
   4420 static int64_t
   4421 get_timeout_millisec_ (struct MHD_Daemon *daemon,
   4422                        int32_t max_timeout)
   4423 {
   4424   uint64_t d_timeout;
   4425   mhd_assert (0 <= max_timeout || -1 == max_timeout);
   4426   if (0 == max_timeout)
   4427     return 0;
   4428 
   4429   if (MHD_NO == MHD_get_timeout64 (daemon, &d_timeout))
   4430     return max_timeout;
   4431 
   4432   if ((0 < max_timeout) && ((uint64_t) max_timeout < d_timeout))
   4433     return max_timeout;
   4434 
   4435   if (INT64_MAX <= d_timeout)
   4436     return INT64_MAX;
   4437 
   4438   return (int64_t) d_timeout;
   4439 }
   4440 
   4441 
   4442 /**
   4443  * Obtain timeout value for polling function for this daemon.
   4444  * @remark To be called only from the thread that processes
   4445  * daemon's select()/poll()/etc.
   4446  *
   4447  * @param daemon the daemon to query for timeout
   4448  * @param max_timeout the maximum return value (in milliseconds),
   4449  *                    ignored if set to '-1'
   4450  * @return timeout value in milliseconds, capped to INT_MAX, or
   4451  *         -1 if no timeout is expected.
   4452  */
   4453 static int
   4454 get_timeout_millisec_int (struct MHD_Daemon *daemon,
   4455                           int32_t max_timeout)
   4456 {
   4457   int64_t res;
   4458 
   4459   res = get_timeout_millisec_ (daemon, max_timeout);
   4460 #if SIZEOF_INT < SIZEOF_INT64_T
   4461   if (INT_MAX <= res)
   4462     return INT_MAX;
   4463 #endif /* SIZEOF_INT < SIZEOF_INT64_T */
   4464   return (int) res;
   4465 }
   4466 
   4467 
   4468 #endif /* HAVE_POLL || EPOLL_SUPPORT */
   4469 
   4470 /**
   4471  * Internal version of #MHD_run_from_select().
   4472  *
   4473  * @param daemon daemon to run select loop for
   4474  * @param read_fd_set read set
   4475  * @param write_fd_set write set
   4476  * @param except_fd_set except set
   4477  * @param fd_setsize value of FD_SETSIZE used when fd_sets were created
   4478  * @return #MHD_NO on serious errors, #MHD_YES on success
   4479  * @ingroup event
   4480  */
   4481 static enum MHD_Result
   4482 internal_run_from_select (struct MHD_Daemon *daemon,
   4483                           const fd_set *read_fd_set,
   4484                           const fd_set *write_fd_set,
   4485                           const fd_set *except_fd_set,
   4486                           int fd_setsize)
   4487 {
   4488   MHD_socket ds;
   4489 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   4490   struct MHD_UpgradeResponseHandle *urh;
   4491   struct MHD_UpgradeResponseHandle *urhn;
   4492 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   4493 
   4494   mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   4495               (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid)));
   4496   mhd_assert ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   4497               (! MHD_thread_handle_ID_is_valid_ID_ (daemon->tid)));
   4498   mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   4499               (MHD_thread_handle_ID_is_current_thread_ (daemon->tid)));
   4500 
   4501   mhd_assert (0 < fd_setsize);
   4502   (void) fd_setsize; /* Mute compiler warning */
   4503 #ifndef HAS_FD_SETSIZE_OVERRIDABLE
   4504   (void) fd_setsize; /* Mute compiler warning */
   4505   mhd_assert (((int) FD_SETSIZE) <= fd_setsize);
   4506   fd_setsize = FD_SETSIZE; /* Help compiler to optimise */
   4507 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   4508 
   4509   /* Clear ITC to avoid spinning select */
   4510   /* Do it before any other processing so new signals
   4511      will trigger select again and will be processed */
   4512   if (MHD_ITC_IS_VALID_ (daemon->itc))
   4513   { /* Have ITC */
   4514     bool need_to_clear_itc = true; /* ITC is always non-blocking, it is safe to clear even if ITC not activated */
   4515     if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (MHD_itc_r_fd_ (daemon->itc),
   4516                                          NULL, fd_setsize))
   4517       need_to_clear_itc = FD_ISSET (MHD_itc_r_fd_ (daemon->itc), \
   4518                                     (fd_set *) _MHD_DROP_CONST (read_fd_set)); /* Skip clearing, if not needed */
   4519     if (need_to_clear_itc)
   4520       MHD_itc_clear_ (daemon->itc);
   4521   }
   4522 
   4523   /* Reset. New value will be set when connections are processed. */
   4524   /* Note: no-op for thread-per-connection as it is always false in that mode. */
   4525   daemon->data_already_pending = false;
   4526 
   4527   /* Process externally added connection if any */
   4528   if (daemon->have_new)
   4529     new_connections_list_process_ (daemon);
   4530 
   4531   /* select connection thread handling type */
   4532   ds = daemon->listen_fd;
   4533   if ( (MHD_INVALID_SOCKET != ds) &&
   4534        (! daemon->was_quiesced) )
   4535   {
   4536     bool need_to_accept;
   4537     if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (ds, NULL, fd_setsize))
   4538       need_to_accept = FD_ISSET (ds,
   4539                                  (fd_set *) _MHD_DROP_CONST (read_fd_set));
   4540     else                                       /* Cannot check whether new connection are pending */
   4541       need_to_accept = daemon->listen_nonblk;  /* Try to accept if non-blocking */
   4542 
   4543     if (need_to_accept)
   4544       (void) MHD_accept_connection (daemon);
   4545   }
   4546 
   4547   if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   4548   {
   4549     /* do not have a thread per connection, process all connections now */
   4550     struct MHD_Connection *pos;
   4551     for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
   4552     {
   4553       MHD_socket cs;
   4554       bool r_ready;
   4555       bool w_ready;
   4556       bool has_err;
   4557 
   4558       cs = pos->socket_fd;
   4559       if (MHD_INVALID_SOCKET == cs)
   4560         continue;
   4561 
   4562       if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (cs, NULL, fd_setsize))
   4563       {
   4564         r_ready = FD_ISSET (cs,
   4565                             (fd_set *) _MHD_DROP_CONST (read_fd_set));
   4566         w_ready = FD_ISSET (cs,
   4567                             (fd_set *) _MHD_DROP_CONST (write_fd_set));
   4568         has_err = (NULL != except_fd_set) &&
   4569                   FD_ISSET (cs,
   4570                             (fd_set *) _MHD_DROP_CONST (except_fd_set));
   4571       }
   4572       else
   4573       { /* Cannot check the real readiness */
   4574         r_ready = pos->sk_nonblck;
   4575         w_ready = r_ready;
   4576         has_err = false;
   4577       }
   4578       call_handlers (pos,
   4579                      r_ready,
   4580                      w_ready,
   4581                      has_err);
   4582     }
   4583   }
   4584 
   4585 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   4586   /* handle upgraded HTTPS connections */
   4587   for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
   4588   {
   4589     urhn = urh->prev;
   4590     /* update urh state based on select() output */
   4591     urh_from_fdset (urh,
   4592                     read_fd_set,
   4593                     write_fd_set,
   4594                     except_fd_set,
   4595                     fd_setsize);
   4596     /* call generic forwarding function for passing data */
   4597     process_urh (urh);
   4598     /* Finished forwarding? */
   4599     if ( (0 == urh->in_buffer_size) &&
   4600          (0 == urh->out_buffer_size) &&
   4601          (0 == urh->in_buffer_used) &&
   4602          (0 == urh->out_buffer_used) )
   4603     {
   4604       MHD_connection_finish_forward_ (urh->connection);
   4605       urh->clean_ready = true;
   4606       /* Resuming will move connection to cleanup list. */
   4607       MHD_resume_connection (urh->connection);
   4608     }
   4609   }
   4610 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   4611   MHD_cleanup_connections (daemon);
   4612   return MHD_YES;
   4613 }
   4614 
   4615 
   4616 #undef MHD_run_from_select
   4617 
   4618 /**
   4619  * Run webserver operations. This method should be called by clients
   4620  * in combination with #MHD_get_fdset and #MHD_get_timeout() if the
   4621  * client-controlled select method is used.
   4622  * This function specifies FD_SETSIZE used when provided fd_sets were
   4623  * created. It is important on platforms where FD_SETSIZE can be
   4624  * overridden.
   4625  *
   4626  * You can use this function instead of #MHD_run if you called
   4627  * 'select()' on the result from #MHD_get_fdset2().  File descriptors in
   4628  * the sets that are not controlled by MHD will be ignored.  Calling
   4629  * this function instead of #MHD_run() is more efficient as MHD will
   4630  * not have to call 'select()' again to determine which operations are
   4631  * ready.
   4632  *
   4633  * If #MHD_get_timeout() returned #MHD_YES, than this function must be
   4634  * called right after 'select()' returns regardless of detected activity
   4635  * on the daemon's FDs.
   4636  *
   4637  * This function cannot be used with daemon started with
   4638  * #MHD_USE_INTERNAL_POLLING_THREAD flag.
   4639  *
   4640  * @param daemon the daemon to run select loop for
   4641  * @param read_fd_set the read set
   4642  * @param write_fd_set the write set
   4643  * @param except_fd_set the except set
   4644  * @param fd_setsize the value of FD_SETSIZE
   4645  * @return #MHD_NO on serious errors, #MHD_YES on success
   4646  * @sa #MHD_get_fdset2(), #MHD_OPTION_APP_FD_SETSIZE
   4647  * @ingroup event
   4648  */
   4649 _MHD_EXTERN enum MHD_Result
   4650 MHD_run_from_select2 (struct MHD_Daemon *daemon,
   4651                       const fd_set *read_fd_set,
   4652                       const fd_set *write_fd_set,
   4653                       const fd_set *except_fd_set,
   4654                       unsigned int fd_setsize)
   4655 {
   4656   if (MHD_D_IS_USING_POLL_ (daemon) ||
   4657       MHD_D_IS_USING_THREADS_ (daemon))
   4658     return MHD_NO;
   4659   if ((NULL == read_fd_set) || (NULL == write_fd_set))
   4660     return MHD_NO;
   4661 #ifdef HAVE_MESSAGES
   4662   if (NULL == except_fd_set)
   4663   {
   4664     MHD_DLOG (daemon,
   4665               _ ("MHD_run_from_select() called with except_fd_set "
   4666                  "set to NULL. Such behavior is deprecated.\n"));
   4667   }
   4668 #endif /* HAVE_MESSAGES */
   4669 
   4670 #ifdef HAS_FD_SETSIZE_OVERRIDABLE
   4671   if (0 == fd_setsize)
   4672     return MHD_NO;
   4673   else if (((unsigned int) INT_MAX) < fd_setsize)
   4674     fd_setsize = (unsigned int) INT_MAX;
   4675 #ifdef HAVE_MESSAGES
   4676   else if (daemon->fdset_size > ((int) fd_setsize))
   4677   {
   4678     if (daemon->fdset_size_set_by_app)
   4679     {
   4680       MHD_DLOG (daemon,
   4681                 _ ("%s() called with fd_setsize (%u) " \
   4682                    "less than value set by MHD_OPTION_APP_FD_SETSIZE (%d). " \
   4683                    "Some socket FDs may be not processed. " \
   4684                    "Use MHD_OPTION_APP_FD_SETSIZE with the correct value.\n"),
   4685                 "MHD_run_from_select2", fd_setsize, daemon->fdset_size);
   4686     }
   4687     else
   4688     {
   4689       MHD_DLOG (daemon,
   4690                 _ ("%s() called with fd_setsize (%u) " \
   4691                    "less than FD_SETSIZE used by MHD (%d). " \
   4692                    "Some socket FDs may be not processed. " \
   4693                    "Consider using MHD_OPTION_APP_FD_SETSIZE option.\n"),
   4694                 "MHD_run_from_select2", fd_setsize, daemon->fdset_size);
   4695     }
   4696   }
   4697 #endif /* HAVE_MESSAGES */
   4698 #else  /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   4699   if (((unsigned int) FD_SETSIZE) > fd_setsize)
   4700   {
   4701 #ifdef HAVE_MESSAGES
   4702     MHD_DLOG (daemon,
   4703               _ ("%s() called with fd_setsize (%u) " \
   4704                  "less than fixed FD_SETSIZE value (%d) used on the " \
   4705                  "platform.\n"),
   4706               "MHD_run_from_select2", fd_setsize, (int) FD_SETSIZE);
   4707 #endif /* HAVE_MESSAGES */
   4708     return MHD_NO;
   4709   }
   4710 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   4711 
   4712   if (MHD_D_IS_USING_EPOLL_ (daemon))
   4713   {
   4714 #ifdef EPOLL_SUPPORT
   4715     enum MHD_Result ret = MHD_epoll (daemon,
   4716                                      0);
   4717 
   4718     MHD_cleanup_connections (daemon);
   4719     return ret;
   4720 #else  /* ! EPOLL_SUPPORT */
   4721     return MHD_NO;
   4722 #endif /* ! EPOLL_SUPPORT */
   4723   }
   4724 
   4725   /* Resuming external connections when using an extern mainloop  */
   4726   if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
   4727     resume_suspended_connections (daemon);
   4728 
   4729   return internal_run_from_select (daemon,
   4730                                    read_fd_set,
   4731                                    write_fd_set,
   4732                                    except_fd_set,
   4733                                    (int) fd_setsize);
   4734 }
   4735 
   4736 
   4737 /**
   4738  * Run webserver operations. This method should be called by clients
   4739  * in combination with #MHD_get_fdset and #MHD_get_timeout() if the
   4740  * client-controlled select method is used.
   4741  *
   4742  * You can use this function instead of #MHD_run if you called
   4743  * `select()` on the result from #MHD_get_fdset.  File descriptors in
   4744  * the sets that are not controlled by MHD will be ignored.  Calling
   4745  * this function instead of #MHD_run is more efficient as MHD will
   4746  * not have to call `select()` again to determine which operations are
   4747  * ready.
   4748  *
   4749  * If #MHD_get_timeout() returned #MHD_YES, than this function must be
   4750  * called right after `select()` returns regardless of detected activity
   4751  * on the daemon's FDs.
   4752  *
   4753  * This function cannot be used with daemon started with
   4754  * #MHD_USE_INTERNAL_POLLING_THREAD flag.
   4755  *
   4756  * @param daemon daemon to run select loop for
   4757  * @param read_fd_set read set
   4758  * @param write_fd_set write set
   4759  * @param except_fd_set except set
   4760  * @return #MHD_NO on serious errors, #MHD_YES on success
   4761  * @ingroup event
   4762  */
   4763 _MHD_EXTERN enum MHD_Result
   4764 MHD_run_from_select (struct MHD_Daemon *daemon,
   4765                      const fd_set *read_fd_set,
   4766                      const fd_set *write_fd_set,
   4767                      const fd_set *except_fd_set)
   4768 {
   4769   return MHD_run_from_select2 (daemon,
   4770                                read_fd_set,
   4771                                write_fd_set,
   4772                                except_fd_set,
   4773 #ifdef HAS_FD_SETSIZE_OVERRIDABLE
   4774                                daemon->fdset_size_set_by_app ?
   4775                                ((unsigned int) daemon->fdset_size) :
   4776                                ((unsigned int) _MHD_SYS_DEFAULT_FD_SETSIZE)
   4777 #else  /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   4778                                ((unsigned int) _MHD_SYS_DEFAULT_FD_SETSIZE)
   4779 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   4780                                );
   4781 }
   4782 
   4783 
   4784 /**
   4785  * Main internal select() call.  Will compute select sets, call select()
   4786  * and then #internal_run_from_select with the result.
   4787  *
   4788  * @param daemon daemon to run select() loop for
   4789  * @param millisec the maximum time in milliseconds to wait for events,
   4790  *                 set to '0' for non-blocking processing,
   4791  *                 set to '-1' to wait indefinitely.
   4792  * @return #MHD_NO on serious errors, #MHD_YES on success
   4793  */
   4794 static enum MHD_Result
   4795 MHD_select (struct MHD_Daemon *daemon,
   4796             int32_t millisec)
   4797 {
   4798   int num_ready;
   4799   fd_set rs;
   4800   fd_set ws;
   4801   fd_set es;
   4802   MHD_socket maxsock;
   4803   struct timeval timeout;
   4804   struct timeval *tv;
   4805   int err_state;
   4806   MHD_socket ls;
   4807 
   4808   timeout.tv_sec = 0;
   4809   timeout.tv_usec = 0;
   4810   if (daemon->shutdown)
   4811     return MHD_NO;
   4812   FD_ZERO (&rs);
   4813   FD_ZERO (&ws);
   4814   FD_ZERO (&es);
   4815   maxsock = MHD_INVALID_SOCKET;
   4816   err_state = MHD_NO;
   4817   if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
   4818        (MHD_NO != resume_suspended_connections (daemon)) &&
   4819        (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) )
   4820     millisec = 0;
   4821 
   4822   if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   4823   {
   4824     /* single-threaded, go over everything */
   4825     if (MHD_NO ==
   4826         internal_get_fdset2 (daemon,
   4827                              &rs,
   4828                              &ws,
   4829                              &es,
   4830                              &maxsock,
   4831                              (int) FD_SETSIZE))
   4832     {
   4833 #ifdef HAVE_MESSAGES
   4834       MHD_DLOG (daemon,
   4835                 _ ("Could not obtain daemon fdsets.\n"));
   4836 #endif
   4837       err_state = MHD_YES;
   4838     }
   4839   }
   4840   else
   4841   {
   4842     bool itc_added;
   4843     /* accept only, have one thread per connection */
   4844     itc_added = false;
   4845     if (MHD_ITC_IS_VALID_ (daemon->itc))
   4846     {
   4847       itc_added = MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
   4848                                       &rs,
   4849                                       &maxsock,
   4850                                       (int) FD_SETSIZE);
   4851       if (! itc_added)
   4852       {
   4853 #ifdef HAVE_MESSAGES
   4854         MHD_DLOG (daemon, _ ("Could not add control inter-thread " \
   4855                              "communication channel FD to fdset.\n"));
   4856 #endif
   4857         err_state = MHD_YES;
   4858       }
   4859     }
   4860     if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
   4861          (! daemon->was_quiesced) )
   4862     {
   4863       /* Stop listening if we are at the configured connection limit */
   4864       /* If we're at the connection limit, no point in really
   4865          accepting new connections; however, make sure we do not miss
   4866          the shutdown OR the termination of an existing connection; so
   4867          only do this optimisation if we have a signaling ITC in
   4868          place. */
   4869       if (! itc_added ||
   4870           ((daemon->connections < daemon->connection_limit) &&
   4871            ! daemon->at_limit))
   4872       {
   4873         if (! MHD_add_to_fd_set_ (ls,
   4874                                   &rs,
   4875                                   &maxsock,
   4876                                   (int) FD_SETSIZE))
   4877         {
   4878 #ifdef HAVE_MESSAGES
   4879           MHD_DLOG (daemon,
   4880                     _ ("Could not add listen socket to fdset.\n"));
   4881 #endif
   4882           err_state = MHD_YES;
   4883         }
   4884       }
   4885     }
   4886   }
   4887 
   4888   if (MHD_NO != err_state)
   4889     millisec = 0;
   4890   if (0 == millisec)
   4891   {
   4892     timeout.tv_usec = 0;
   4893     timeout.tv_sec = 0;
   4894     tv = &timeout;
   4895   }
   4896   else
   4897   {
   4898     uint64_t mhd_tmo;
   4899     uint64_t select_tmo;
   4900 
   4901     if ( (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) &&
   4902          (MHD_NO != MHD_get_timeout64 (daemon, &mhd_tmo)) )
   4903     {
   4904       if ( (0 < millisec) &&
   4905            (mhd_tmo > (uint64_t) millisec) )
   4906         select_tmo = (uint64_t) millisec;
   4907       else
   4908         select_tmo = mhd_tmo;
   4909       tv = &timeout; /* have timeout value */
   4910     }
   4911     else if (0 < millisec)
   4912     {
   4913       select_tmo = (uint64_t) millisec;
   4914       tv = &timeout; /* have timeout value */
   4915     }
   4916     else
   4917     {
   4918       select_tmo = 0; /* Not actually used, silent compiler warning */
   4919       tv = NULL;
   4920     }
   4921 
   4922     if (NULL != tv)
   4923     { /* have timeout value */
   4924 #if (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC
   4925       if (select_tmo / 1000 > TIMEVAL_TV_SEC_MAX)
   4926         timeout.tv_sec = TIMEVAL_TV_SEC_MAX;
   4927       else
   4928 #endif /* (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC */
   4929       timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) (select_tmo / 1000);
   4930 
   4931       timeout.tv_usec = ((uint16_t) (select_tmo % 1000)) * ((int32_t) 1000);
   4932     }
   4933   }
   4934   num_ready = MHD_SYS_select_ (maxsock + 1,
   4935                                &rs,
   4936                                &ws,
   4937                                &es,
   4938                                tv);
   4939   if (daemon->shutdown)
   4940     return MHD_NO;
   4941   if (num_ready < 0)
   4942   {
   4943     const int err = MHD_socket_get_error_ ();
   4944     if (MHD_SCKT_ERR_IS_EINTR_ (err))
   4945       return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
   4946 #ifdef HAVE_MESSAGES
   4947     MHD_DLOG (daemon,
   4948               _ ("select failed: %s\n"),
   4949               MHD_socket_strerr_ (err));
   4950 #endif
   4951     return MHD_NO;
   4952   }
   4953   if (MHD_NO != internal_run_from_select (daemon,
   4954                                           &rs,
   4955                                           &ws,
   4956                                           &es,
   4957                                           (int) FD_SETSIZE))
   4958     return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
   4959   return MHD_NO;
   4960 }
   4961 
   4962 
   4963 #ifdef HAVE_POLL
   4964 /**
   4965  * Process all of our connections and possibly the server
   4966  * socket using poll().
   4967  *
   4968  * @param daemon daemon to run poll loop for
   4969  * @param millisec the maximum time in milliseconds to wait for events,
   4970  *                 set to '0' for non-blocking processing,
   4971  *                 set to '-1' to wait indefinitely.
   4972  * @return #MHD_NO on serious errors, #MHD_YES on success
   4973  */
   4974 static enum MHD_Result
   4975 MHD_poll_all (struct MHD_Daemon *daemon,
   4976               int32_t millisec)
   4977 {
   4978   unsigned int num_connections;
   4979   struct MHD_Connection *pos;
   4980   struct MHD_Connection *prev;
   4981 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   4982   struct MHD_UpgradeResponseHandle *urh;
   4983   struct MHD_UpgradeResponseHandle *urhn;
   4984 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   4985 
   4986   mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   4987               (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid)));
   4988   mhd_assert ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   4989               (! MHD_thread_handle_ID_is_valid_ID_ (daemon->tid)));
   4990   mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   4991               (MHD_thread_handle_ID_is_current_thread_ (daemon->tid)));
   4992 
   4993   if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
   4994        (MHD_NO != resume_suspended_connections (daemon)) )
   4995     millisec = 0;
   4996 
   4997   /* count number of connections and thus determine poll set size */
   4998   num_connections = 0;
   4999   for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
   5000     num_connections++;
   5001 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5002   for (urh = daemon->urh_head; NULL != urh; urh = urh->next)
   5003     num_connections += 2;
   5004 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5005   {
   5006     unsigned int i;
   5007     int timeout;
   5008     unsigned int poll_server;
   5009     int poll_listen;
   5010     int poll_itc_idx;
   5011     struct pollfd *p;
   5012     MHD_socket ls;
   5013 
   5014     p = MHD_calloc_ ((2 + (size_t) num_connections),
   5015                      sizeof (struct pollfd));
   5016     if (NULL == p)
   5017     {
   5018 #ifdef HAVE_MESSAGES
   5019       MHD_DLOG (daemon,
   5020                 _ ("Error allocating memory: %s\n"),
   5021                 MHD_strerror_ (errno));
   5022 #endif
   5023       return MHD_NO;
   5024     }
   5025     poll_server = 0;
   5026     poll_listen = -1;
   5027     if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
   5028          (! daemon->was_quiesced) &&
   5029          (daemon->connections < daemon->connection_limit) &&
   5030          (! daemon->at_limit) )
   5031     {
   5032       /* only listen if we are not at the connection limit */
   5033       p[poll_server].fd = ls;
   5034       p[poll_server].events = POLLIN;
   5035       p[poll_server].revents = 0;
   5036       poll_listen = (int) poll_server;
   5037       poll_server++;
   5038     }
   5039     poll_itc_idx = -1;
   5040     if (MHD_ITC_IS_VALID_ (daemon->itc))
   5041     {
   5042       p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc);
   5043       p[poll_server].events = POLLIN;
   5044       p[poll_server].revents = 0;
   5045       poll_itc_idx = (int) poll_server;
   5046       poll_server++;
   5047     }
   5048 
   5049     timeout = get_timeout_millisec_int (daemon, millisec);
   5050 
   5051     i = 0;
   5052     for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
   5053     {
   5054       p[poll_server + i].fd = pos->socket_fd;
   5055       switch (pos->event_loop_info)
   5056       {
   5057       case MHD_EVENT_LOOP_INFO_READ:
   5058       case MHD_EVENT_LOOP_INFO_PROCESS_READ:
   5059         p[poll_server + i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
   5060         break;
   5061       case MHD_EVENT_LOOP_INFO_WRITE:
   5062         p[poll_server + i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
   5063         break;
   5064       case MHD_EVENT_LOOP_INFO_PROCESS:
   5065         p[poll_server + i].events |=  MHD_POLL_EVENTS_ERR_DISC;
   5066         break;
   5067       case MHD_EVENT_LOOP_INFO_CLEANUP:
   5068         timeout = 0; /* clean up "pos" immediately */
   5069         break;
   5070       }
   5071       i++;
   5072     }
   5073 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5074     for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
   5075     {
   5076       urh_to_pollfd (urh, &(p[poll_server + i]));
   5077       i += 2;
   5078     }
   5079 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5080     if (0 == poll_server + num_connections)
   5081     {
   5082       free (p);
   5083       return MHD_YES;
   5084     }
   5085     if (MHD_sys_poll_ (p,
   5086                        poll_server + num_connections,
   5087                        timeout) < 0)
   5088     {
   5089       const int err = MHD_socket_get_error_ ();
   5090       if (MHD_SCKT_ERR_IS_EINTR_ (err))
   5091       {
   5092         free (p);
   5093         return MHD_YES;
   5094       }
   5095 #ifdef HAVE_MESSAGES
   5096       MHD_DLOG (daemon,
   5097                 _ ("poll failed: %s\n"),
   5098                 MHD_socket_strerr_ (err));
   5099 #endif
   5100       free (p);
   5101       return MHD_NO;
   5102     }
   5103 
   5104     /* handle ITC FD */
   5105     /* do it before any other processing so
   5106        new signals will be processed in next loop */
   5107     if ( (-1 != poll_itc_idx) &&
   5108          (0 != (p[poll_itc_idx].revents & POLLIN)) )
   5109       MHD_itc_clear_ (daemon->itc);
   5110 
   5111     /* handle shutdown */
   5112     if (daemon->shutdown)
   5113     {
   5114       free (p);
   5115       return MHD_NO;
   5116     }
   5117 
   5118     /* Process externally added connection if any */
   5119     if (daemon->have_new)
   5120       new_connections_list_process_ (daemon);
   5121 
   5122     /* handle 'listen' FD */
   5123     if ( (-1 != poll_listen) &&
   5124          (0 != (p[poll_listen].revents & POLLIN)) )
   5125       (void) MHD_accept_connection (daemon);
   5126 
   5127     /* Reset. New value will be set when connections are processed. */
   5128     daemon->data_already_pending = false;
   5129 
   5130     i = 0;
   5131     prev = daemon->connections_tail;
   5132     while (NULL != (pos = prev))
   5133     {
   5134       prev = pos->prev;
   5135       /* first, sanity checks */
   5136       if (i >= num_connections)
   5137         break;     /* connection list changed somehow, retry later ... */
   5138       if (p[poll_server + i].fd != pos->socket_fd)
   5139         continue;  /* fd mismatch, something else happened, retry later ... */
   5140       call_handlers (pos,
   5141                      0 != (p[poll_server + i].revents & POLLIN),
   5142                      0 != (p[poll_server + i].revents & POLLOUT),
   5143                      0 != (p[poll_server + i].revents
   5144                            & MHD_POLL_REVENTS_ERR_DISC));
   5145       i++;
   5146     }
   5147 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5148     for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
   5149     {
   5150       if (i >= num_connections)
   5151         break;   /* connection list changed somehow, retry later ... */
   5152 
   5153       /* Get next connection here as connection can be removed
   5154        * from 'daemon->urh_head' list. */
   5155       urhn = urh->prev;
   5156       /* Check for fd mismatch. FIXME: required for safety? */
   5157       if ((p[poll_server + i].fd != urh->connection->socket_fd) ||
   5158           (p[poll_server + i + 1].fd != urh->mhd.socket))
   5159         break;
   5160       urh_from_pollfd (urh,
   5161                        &p[poll_server + i]);
   5162       i += 2;
   5163       process_urh (urh);
   5164       /* Finished forwarding? */
   5165       if ( (0 == urh->in_buffer_size) &&
   5166            (0 == urh->out_buffer_size) &&
   5167            (0 == urh->in_buffer_used) &&
   5168            (0 == urh->out_buffer_used) )
   5169       {
   5170         /* MHD_connection_finish_forward_() will remove connection from
   5171          * 'daemon->urh_head' list. */
   5172         MHD_connection_finish_forward_ (urh->connection);
   5173         urh->clean_ready = true;
   5174         /* If 'urh->was_closed' already was set to true, connection will be
   5175          * moved immediately to cleanup list. Otherwise connection
   5176          * will stay in suspended list until 'urh' will be marked
   5177          * with 'was_closed' by application. */
   5178         MHD_resume_connection (urh->connection);
   5179       }
   5180     }
   5181 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5182 
   5183     free (p);
   5184   }
   5185   return MHD_YES;
   5186 }
   5187 
   5188 
   5189 /**
   5190  * Process only the listen socket using poll().
   5191  *
   5192  * @param daemon daemon to run poll loop for
   5193  * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
   5194  * @return #MHD_NO on serious errors, #MHD_YES on success
   5195  */
   5196 static enum MHD_Result
   5197 MHD_poll_listen_socket (struct MHD_Daemon *daemon,
   5198                         int may_block)
   5199 {
   5200   struct pollfd p[2];
   5201   int timeout;
   5202   unsigned int poll_count;
   5203   int poll_listen;
   5204   int poll_itc_idx;
   5205   MHD_socket ls;
   5206 
   5207   mhd_assert (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid));
   5208   mhd_assert (MHD_thread_handle_ID_is_current_thread_ (daemon->tid));
   5209 
   5210   memset (&p,
   5211           0,
   5212           sizeof (p));
   5213   poll_count = 0;
   5214   poll_listen = -1;
   5215   poll_itc_idx = -1;
   5216   if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
   5217        (! daemon->was_quiesced) )
   5218 
   5219   {
   5220     p[poll_count].fd = ls;
   5221     p[poll_count].events = POLLIN;
   5222     p[poll_count].revents = 0;
   5223     poll_listen = (int) poll_count;
   5224     poll_count++;
   5225   }
   5226   if (MHD_ITC_IS_VALID_ (daemon->itc))
   5227   {
   5228     p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc);
   5229     p[poll_count].events = POLLIN;
   5230     p[poll_count].revents = 0;
   5231     poll_itc_idx = (int) poll_count;
   5232     poll_count++;
   5233   }
   5234 
   5235   if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
   5236     (void) resume_suspended_connections (daemon);
   5237 
   5238   if (MHD_NO == may_block)
   5239     timeout = 0;
   5240   else
   5241     timeout = -1;
   5242   if (0 == poll_count)
   5243     return MHD_YES;
   5244   if (MHD_sys_poll_ (p,
   5245                      poll_count,
   5246                      timeout) < 0)
   5247   {
   5248     const int err = MHD_socket_get_error_ ();
   5249 
   5250     if (MHD_SCKT_ERR_IS_EINTR_ (err))
   5251       return MHD_YES;
   5252 #ifdef HAVE_MESSAGES
   5253     MHD_DLOG (daemon,
   5254               _ ("poll failed: %s\n"),
   5255               MHD_socket_strerr_ (err));
   5256 #endif
   5257     return MHD_NO;
   5258   }
   5259   if ( (0 <= poll_itc_idx) &&
   5260        (0 != (p[poll_itc_idx].revents & POLLIN)) )
   5261     MHD_itc_clear_ (daemon->itc);
   5262 
   5263   /* handle shutdown */
   5264   if (daemon->shutdown)
   5265     return MHD_NO;
   5266 
   5267   /* Process externally added connection if any */
   5268   if (daemon->have_new)
   5269     new_connections_list_process_ (daemon);
   5270 
   5271   if ( (0 <= poll_listen) &&
   5272        (0 != (p[poll_listen].revents & POLLIN)) )
   5273     (void) MHD_accept_connection (daemon);
   5274   return MHD_YES;
   5275 }
   5276 
   5277 
   5278 #endif
   5279 
   5280 #ifdef HAVE_POLL
   5281 
   5282 /**
   5283  * Do poll()-based processing.
   5284  *
   5285  * @param daemon daemon to run poll()-loop for
   5286  * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
   5287  * @return #MHD_NO on serious errors, #MHD_YES on success
   5288  */
   5289 static enum MHD_Result
   5290 MHD_poll (struct MHD_Daemon *daemon,
   5291           int may_block)
   5292 {
   5293   if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   5294     return MHD_poll_all (daemon,
   5295                          may_block ? -1 : 0);
   5296   return MHD_poll_listen_socket (daemon,
   5297                                  may_block);
   5298 }
   5299 
   5300 
   5301 #endif /* HAVE_POLL */
   5302 
   5303 
   5304 #ifdef EPOLL_SUPPORT
   5305 
   5306 /**
   5307  * How many events to we process at most per epoll() call?  Trade-off
   5308  * between required stack-size and number of system calls we have to
   5309  * make; 128 should be way enough to avoid more than one system call
   5310  * for most scenarios, and still be moderate in stack size
   5311  * consumption.  Embedded systems might want to choose a smaller value
   5312  * --- but why use epoll() on such a system in the first place?
   5313  */
   5314 #define MAX_EVENTS 128
   5315 
   5316 
   5317 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5318 
   5319 /**
   5320  * Checks whether @a urh has some data to process.
   5321  *
   5322  * @param urh upgrade handler to analyse
   5323  * @return 'true' if @a urh has some data to process,
   5324  *         'false' otherwise
   5325  */
   5326 static bool
   5327 is_urh_ready (struct MHD_UpgradeResponseHandle *const urh)
   5328 {
   5329   const struct MHD_Connection *const connection = urh->connection;
   5330 
   5331   if ( (0 == urh->in_buffer_size) &&
   5332        (0 == urh->out_buffer_size) &&
   5333        (0 == urh->in_buffer_used) &&
   5334        (0 == urh->out_buffer_used) )
   5335     return false;
   5336   if (connection->daemon->shutdown)
   5337     return true;
   5338   if ( ( (0 != ((MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_ERROR)
   5339                 & urh->app.celi)) ||
   5340          (connection->tls_read_ready) ) &&
   5341        (urh->in_buffer_used < urh->in_buffer_size) )
   5342     return true;
   5343   if ( ( (0 != ((MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_ERROR)
   5344                 & urh->mhd.celi)) ||
   5345          urh->was_closed) &&
   5346        (urh->out_buffer_used < urh->out_buffer_size) )
   5347     return true;
   5348   if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
   5349        (urh->out_buffer_used > 0) )
   5350     return true;
   5351   if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
   5352        (urh->in_buffer_used > 0) )
   5353     return true;
   5354   return false;
   5355 }
   5356 
   5357 
   5358 /**
   5359  * Do epoll()-based processing for TLS connections that have been
   5360  * upgraded.  This requires a separate epoll() invocation as we
   5361  * cannot use the `struct MHD_Connection` data structures for
   5362  * the `union epoll_data` in this case.
   5363  * @remark To be called only from thread that process
   5364  * daemon's select()/poll()/etc.
   5365  */
   5366 static enum MHD_Result
   5367 run_epoll_for_upgrade (struct MHD_Daemon *daemon)
   5368 {
   5369   struct epoll_event events[MAX_EVENTS];
   5370   int num_events;
   5371   struct MHD_UpgradeResponseHandle *pos;
   5372   struct MHD_UpgradeResponseHandle *prev;
   5373 
   5374 #ifdef MHD_USE_THREADS
   5375   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   5376                MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   5377 #endif /* MHD_USE_THREADS */
   5378 
   5379   num_events = MAX_EVENTS;
   5380   while (0 != num_events)
   5381   {
   5382     unsigned int i;
   5383     /* update event masks */
   5384     num_events = epoll_wait (daemon->epoll_upgrade_fd,
   5385                              events,
   5386                              MAX_EVENTS,
   5387                              0);
   5388     if (-1 == num_events)
   5389     {
   5390       const int err = MHD_socket_get_error_ ();
   5391 
   5392       if (MHD_SCKT_ERR_IS_EINTR_ (err))
   5393         return MHD_YES;
   5394 #ifdef HAVE_MESSAGES
   5395       MHD_DLOG (daemon,
   5396                 _ ("Call to epoll_wait failed: %s\n"),
   5397                 MHD_socket_strerr_ (err));
   5398 #endif
   5399       return MHD_NO;
   5400     }
   5401     for (i = 0; i < (unsigned int) num_events; i++)
   5402     {
   5403       struct UpgradeEpollHandle *const ueh = events[i].data.ptr;
   5404       struct MHD_UpgradeResponseHandle *const urh = ueh->urh;
   5405       bool new_err_state = false;
   5406 
   5407       if (urh->clean_ready)
   5408         continue;
   5409 
   5410       /* Update ueh state based on what is ready according to epoll() */
   5411       if (0 != (events[i].events & EPOLLIN))
   5412       {
   5413         ueh->celi |= MHD_EPOLL_STATE_READ_READY;
   5414       }
   5415       if (0 != (events[i].events & EPOLLOUT))
   5416       {
   5417         ueh->celi |= MHD_EPOLL_STATE_WRITE_READY;
   5418       }
   5419       if (0 != (events[i].events & EPOLLHUP))
   5420       {
   5421         ueh->celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
   5422       }
   5423 
   5424       if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) &&
   5425            (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
   5426       {
   5427         /* Process new error state only one time and avoid continuously
   5428          * marking this connection as 'ready'. */
   5429         ueh->celi |= MHD_EPOLL_STATE_ERROR;
   5430         new_err_state = true;
   5431       }
   5432       if (! urh->in_eready_list)
   5433       {
   5434         if (new_err_state ||
   5435             is_urh_ready (urh))
   5436         {
   5437           EDLL_insert (daemon->eready_urh_head,
   5438                        daemon->eready_urh_tail,
   5439                        urh);
   5440           urh->in_eready_list = true;
   5441         }
   5442       }
   5443     }
   5444   }
   5445   prev = daemon->eready_urh_tail;
   5446   while (NULL != (pos = prev))
   5447   {
   5448     prev = pos->prevE;
   5449     process_urh (pos);
   5450     if (! is_urh_ready (pos))
   5451     {
   5452       EDLL_remove (daemon->eready_urh_head,
   5453                    daemon->eready_urh_tail,
   5454                    pos);
   5455       pos->in_eready_list = false;
   5456     }
   5457     /* Finished forwarding? */
   5458     if ( (0 == pos->in_buffer_size) &&
   5459          (0 == pos->out_buffer_size) &&
   5460          (0 == pos->in_buffer_used) &&
   5461          (0 == pos->out_buffer_used) )
   5462     {
   5463       MHD_connection_finish_forward_ (pos->connection);
   5464       pos->clean_ready = true;
   5465       /* If 'pos->was_closed' already was set to true, connection
   5466        * will be moved immediately to cleanup list. Otherwise
   5467        * connection will stay in suspended list until 'pos' will
   5468        * be marked with 'was_closed' by application. */
   5469       MHD_resume_connection (pos->connection);
   5470     }
   5471   }
   5472 
   5473   return MHD_YES;
   5474 }
   5475 
   5476 
   5477 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5478 
   5479 
   5480 /**
   5481  * Pointer-marker to distinguish ITC slot in epoll sets.
   5482  */
   5483 static const char *const epoll_itc_marker = "itc_marker";
   5484 
   5485 
   5486 /**
   5487  * Do epoll()-based processing.
   5488  *
   5489  * @param daemon daemon to run poll loop for
   5490  * @param millisec the maximum time in milliseconds to wait for events,
   5491  *                 set to '0' for non-blocking processing,
   5492  *                 set to '-1' to wait indefinitely.
   5493  * @return #MHD_NO on serious errors, #MHD_YES on success
   5494  */
   5495 static enum MHD_Result
   5496 MHD_epoll (struct MHD_Daemon *daemon,
   5497            int32_t millisec)
   5498 {
   5499 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5500   static const char *const upgrade_marker = "upgrade_ptr";
   5501 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5502   struct MHD_Connection *pos;
   5503   struct MHD_Connection *prev;
   5504   struct epoll_event events[MAX_EVENTS];
   5505   struct epoll_event event;
   5506   int timeout_ms;
   5507   int num_events;
   5508   unsigned int i;
   5509   MHD_socket ls;
   5510 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5511   bool run_upgraded = false;
   5512 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5513   bool need_to_accept;
   5514 
   5515   mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   5516               (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid)));
   5517   mhd_assert ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   5518               (! MHD_thread_handle_ID_is_valid_ID_ (daemon->tid)));
   5519   mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   5520               (MHD_thread_handle_ID_is_current_thread_ (daemon->tid)));
   5521 
   5522   if (-1 == daemon->epoll_fd)
   5523     return MHD_NO; /* we're down! */
   5524   if (daemon->shutdown)
   5525     return MHD_NO;
   5526   if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
   5527        (! daemon->was_quiesced) &&
   5528        (daemon->connections < daemon->connection_limit) &&
   5529        (! daemon->listen_socket_in_epoll) &&
   5530        (! daemon->at_limit) )
   5531   {
   5532     event.events = EPOLLIN | EPOLLRDHUP;
   5533     event.data.ptr = daemon;
   5534     if (0 != epoll_ctl (daemon->epoll_fd,
   5535                         EPOLL_CTL_ADD,
   5536                         ls,
   5537                         &event))
   5538     {
   5539 #ifdef HAVE_MESSAGES
   5540       MHD_DLOG (daemon,
   5541                 _ ("Call to epoll_ctl failed: %s\n"),
   5542                 MHD_socket_last_strerr_ ());
   5543 #endif
   5544       return MHD_NO;
   5545     }
   5546     daemon->listen_socket_in_epoll = true;
   5547   }
   5548   if ( (daemon->was_quiesced) &&
   5549        (daemon->listen_socket_in_epoll) )
   5550   {
   5551     if ( (0 != epoll_ctl (daemon->epoll_fd,
   5552                           EPOLL_CTL_DEL,
   5553                           ls,
   5554                           NULL)) &&
   5555          (ENOENT != errno) )   /* ENOENT can happen due to race with
   5556                                   #MHD_quiesce_daemon() */
   5557       MHD_PANIC ("Failed to remove listen FD from epoll set.\n");
   5558     daemon->listen_socket_in_epoll = false;
   5559   }
   5560 
   5561 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5562   if ( ( (! daemon->upgrade_fd_in_epoll) &&
   5563          (-1 != daemon->epoll_upgrade_fd) ) )
   5564   {
   5565     event.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP;
   5566     event.data.ptr = _MHD_DROP_CONST (upgrade_marker);
   5567     if (0 != epoll_ctl (daemon->epoll_fd,
   5568                         EPOLL_CTL_ADD,
   5569                         daemon->epoll_upgrade_fd,
   5570                         &event))
   5571     {
   5572 #ifdef HAVE_MESSAGES
   5573       MHD_DLOG (daemon,
   5574                 _ ("Call to epoll_ctl failed: %s\n"),
   5575                 MHD_socket_last_strerr_ ());
   5576 #endif
   5577       return MHD_NO;
   5578     }
   5579     daemon->upgrade_fd_in_epoll = true;
   5580   }
   5581 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5582   if ( (daemon->listen_socket_in_epoll) &&
   5583        ( (daemon->connections == daemon->connection_limit) ||
   5584          (daemon->at_limit) ||
   5585          (daemon->was_quiesced) ) )
   5586   {
   5587     /* we're at the connection limit, disable listen socket
   5588  for event loop for now */
   5589     if (0 != epoll_ctl (daemon->epoll_fd,
   5590                         EPOLL_CTL_DEL,
   5591                         ls,
   5592                         NULL))
   5593       MHD_PANIC (_ ("Failed to remove listen FD from epoll set.\n"));
   5594     daemon->listen_socket_in_epoll = false;
   5595   }
   5596 
   5597   if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
   5598        (MHD_NO != resume_suspended_connections (daemon)) )
   5599     millisec = 0;
   5600 
   5601   timeout_ms = get_timeout_millisec_int (daemon, millisec);
   5602 
   5603   /* Reset. New value will be set when connections are processed. */
   5604   /* Note: Used mostly for uniformity here as same situation is
   5605    * signaled in epoll mode by non-empty eready DLL. */
   5606   daemon->data_already_pending = false;
   5607 
   5608   need_to_accept = false;
   5609   /* drain 'epoll' event queue; need to iterate as we get at most
   5610      MAX_EVENTS in one system call here; in practice this should
   5611      pretty much mean only one round, but better an extra loop here
   5612      than unfair behavior... */
   5613   num_events = MAX_EVENTS;
   5614   while (MAX_EVENTS == num_events)
   5615   {
   5616     /* update event masks */
   5617     num_events = epoll_wait (daemon->epoll_fd,
   5618                              events,
   5619                              MAX_EVENTS,
   5620                              timeout_ms);
   5621     if (-1 == num_events)
   5622     {
   5623       const int err = MHD_socket_get_error_ ();
   5624       if (MHD_SCKT_ERR_IS_EINTR_ (err))
   5625         return MHD_YES;
   5626 #ifdef HAVE_MESSAGES
   5627       MHD_DLOG (daemon,
   5628                 _ ("Call to epoll_wait failed: %s\n"),
   5629                 MHD_socket_strerr_ (err));
   5630 #endif
   5631       return MHD_NO;
   5632     }
   5633     for (i = 0; i < (unsigned int) num_events; i++)
   5634     {
   5635       /* First, check for the values of `ptr` that would indicate
   5636          that this event is not about a normal connection. */
   5637       if (NULL == events[i].data.ptr)
   5638         continue;     /* shutdown signal! */
   5639 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5640       if (upgrade_marker == events[i].data.ptr)
   5641       {
   5642         /* activity on an upgraded connection, we process
   5643            those in a separate epoll() */
   5644         run_upgraded = true;
   5645         continue;
   5646       }
   5647 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5648       if (epoll_itc_marker == events[i].data.ptr)
   5649       {
   5650         /* It's OK to clear ITC here as all external
   5651            conditions will be processed later. */
   5652         MHD_itc_clear_ (daemon->itc);
   5653         continue;
   5654       }
   5655       if (daemon == events[i].data.ptr)
   5656       {
   5657         /* Check for error conditions on listen socket. */
   5658         /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */
   5659         if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
   5660           need_to_accept = true;
   5661         continue;
   5662       }
   5663       /* this is an event relating to a 'normal' connection,
   5664          remember the event and if appropriate mark the
   5665          connection as 'eready'. */
   5666       pos = events[i].data.ptr;
   5667       /* normal processing: update read/write data */
   5668       if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
   5669       {
   5670         pos->epoll_state |= MHD_EPOLL_STATE_ERROR;
   5671         if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
   5672         {
   5673           EDLL_insert (daemon->eready_head,
   5674                        daemon->eready_tail,
   5675                        pos);
   5676           pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
   5677         }
   5678       }
   5679       else
   5680       {
   5681         if (0 != (events[i].events & EPOLLIN))
   5682         {
   5683           pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
   5684           if ( ( (0 != (MHD_EVENT_LOOP_INFO_READ & pos->event_loop_info)) ||
   5685                  (pos->read_buffer_size > pos->read_buffer_offset) ) &&
   5686                (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
   5687           {
   5688             EDLL_insert (daemon->eready_head,
   5689                          daemon->eready_tail,
   5690                          pos);
   5691             pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
   5692           }
   5693         }
   5694         if (0 != (events[i].events & EPOLLOUT))
   5695         {
   5696           pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
   5697           if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
   5698                (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
   5699           {
   5700             EDLL_insert (daemon->eready_head,
   5701                          daemon->eready_tail,
   5702                          pos);
   5703             pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
   5704           }
   5705         }
   5706       }
   5707     }
   5708   }
   5709 
   5710   /* Process externally added connection if any */
   5711   if (daemon->have_new)
   5712     new_connections_list_process_ (daemon);
   5713 
   5714   if (need_to_accept)
   5715   {
   5716     unsigned int series_length = 0;
   5717 
   5718     /* Run 'accept' until it fails or daemon at limit of connections.
   5719      * Do not accept more then 10 connections at once. The rest will
   5720      * be accepted on next turn (level trigger is used for listen
   5721      * socket). */
   5722     while ( (MHD_NO != MHD_accept_connection (daemon)) &&
   5723             (series_length < 10) &&
   5724             (daemon->connections < daemon->connection_limit) &&
   5725             (! daemon->at_limit) )
   5726       series_length++;
   5727   }
   5728 
   5729   /* Handle timed-out connections; we need to do this here
   5730      as the epoll mechanism won't call the 'MHD_connection_handle_idle()' on everything,
   5731      as the other event loops do.  As timeouts do not get an explicit
   5732      event, we need to find those connections that might have timed out
   5733      here.
   5734 
   5735      Connections with custom timeouts must all be looked at, as we
   5736      do not bother to sort that (presumably very short) list. */
   5737   prev = daemon->manual_timeout_tail;
   5738   while (NULL != (pos = prev))
   5739   {
   5740     prev = pos->prevX;
   5741     MHD_connection_handle_idle (pos);
   5742   }
   5743   /* Connections with the default timeout are sorted by prepending
   5744      them to the head of the list whenever we touch the connection;
   5745      thus it suffices to iterate from the tail until the first
   5746      connection is NOT timed out */
   5747   prev = daemon->normal_timeout_tail;
   5748   while (NULL != (pos = prev))
   5749   {
   5750     prev = pos->prevX;
   5751     MHD_connection_handle_idle (pos);
   5752     if (MHD_CONNECTION_CLOSED != pos->state)
   5753       break; /* sorted by timeout, no need to visit the rest! */
   5754   }
   5755 
   5756 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5757   if (run_upgraded || (NULL != daemon->eready_urh_head))
   5758     run_epoll_for_upgrade (daemon);
   5759 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5760 
   5761   /* process events for connections */
   5762   prev = daemon->eready_tail;
   5763   while (NULL != (pos = prev))
   5764   {
   5765     prev = pos->prevE;
   5766     call_handlers (pos,
   5767                    0 != (pos->epoll_state & MHD_EPOLL_STATE_READ_READY),
   5768                    0 != (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY),
   5769                    0 != (pos->epoll_state & MHD_EPOLL_STATE_ERROR));
   5770     if (MHD_EPOLL_STATE_IN_EREADY_EDLL ==
   5771         (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED
   5772                              | MHD_EPOLL_STATE_IN_EREADY_EDLL)))
   5773     {
   5774       if ( ((MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) &&
   5775             (0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) ||
   5776            ((MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
   5777             (0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ) ||
   5778            (MHD_EVENT_LOOP_INFO_CLEANUP == pos->event_loop_info) )
   5779       {
   5780         EDLL_remove (daemon->eready_head,
   5781                      daemon->eready_tail,
   5782                      pos);
   5783         pos->epoll_state &=
   5784           ~((enum MHD_EpollState) MHD_EPOLL_STATE_IN_EREADY_EDLL);
   5785       }
   5786     }
   5787   }
   5788 
   5789   return MHD_YES;
   5790 }
   5791 
   5792 
   5793 #endif
   5794 
   5795 
   5796 /**
   5797  * Run webserver operations (without blocking unless in client callbacks).
   5798  *
   5799  * This method should be called by clients in combination with
   5800  * #MHD_get_fdset() (or #MHD_get_daemon_info() with MHD_DAEMON_INFO_EPOLL_FD
   5801  * if epoll is used) and #MHD_get_timeout() if the client-controlled
   5802  * connection polling method is used (i.e. daemon was started without
   5803  * #MHD_USE_INTERNAL_POLLING_THREAD flag).
   5804  *
   5805  * This function is a convenience method, which is useful if the
   5806  * fd_sets from #MHD_get_fdset were not directly passed to `select()`;
   5807  * with this function, MHD will internally do the appropriate `select()`
   5808  * call itself again.  While it is acceptable to call #MHD_run (if
   5809  * #MHD_USE_INTERNAL_POLLING_THREAD is not set) at any moment, you should
   5810  * call #MHD_run_from_select() if performance is important (as it saves an
   5811  * expensive call to `select()`).
   5812  *
   5813  * If #MHD_get_timeout() returned #MHD_YES, than this function must be called
   5814  * right after polling function returns regardless of detected activity on
   5815  * the daemon's FDs.
   5816  *
   5817  * @param daemon daemon to run
   5818  * @return #MHD_YES on success, #MHD_NO if this
   5819  *         daemon was not started with the right
   5820  *         options for this call.
   5821  * @ingroup event
   5822  */
   5823 _MHD_EXTERN enum MHD_Result
   5824 MHD_run (struct MHD_Daemon *daemon)
   5825 {
   5826   if ( (daemon->shutdown) ||
   5827        MHD_D_IS_USING_THREADS_ (daemon) )
   5828     return MHD_NO;
   5829 
   5830   (void) MHD_run_wait (daemon, 0);
   5831   return MHD_YES;
   5832 }
   5833 
   5834 
   5835 /**
   5836  * Run webserver operation with possible blocking.
   5837  *
   5838  * This function does the following: waits for any network event not more than
   5839  * specified number of milliseconds, processes all incoming and outgoing data,
   5840  * processes new connections, processes any timed-out connection, and does
   5841  * other things required to run webserver.
   5842  * Once all connections are processed, function returns.
   5843  *
   5844  * This function is useful for quick and simple (lazy) webserver implementation
   5845  * if application needs to run a single thread only and does not have any other
   5846  * network activity.
   5847  *
   5848  * This function calls MHD_get_timeout() internally and use returned value as
   5849  * maximum wait time if it less than value of @a millisec parameter.
   5850  *
   5851  * It is expected that the "external" socket polling function is not used in
   5852  * conjunction with this function unless the @a millisec is set to zero.
   5853  *
   5854  * @param daemon the daemon to run
   5855  * @param millisec the maximum time in milliseconds to wait for network and
   5856  *                 other events. Note: there is no guarantee that function
   5857  *                 blocks for the specified amount of time. The real processing
   5858  *                 time can be shorter (if some data or connection timeout
   5859  *                 comes earlier) or longer (if data processing requires more
   5860  *                 time, especially in user callbacks).
   5861  *                 If set to '0' then function does not block and processes
   5862  *                 only already available data (if any).
   5863  *                 If set to '-1' then function waits for events
   5864  *                 indefinitely (blocks until next network activity or
   5865  *                 connection timeout).
   5866  * @return #MHD_YES on success, #MHD_NO if this
   5867  *         daemon was not started with the right
   5868  *         options for this call or some serious
   5869  *         unrecoverable error occurs.
   5870  * @note Available since #MHD_VERSION 0x00097206
   5871  * @ingroup event
   5872  */
   5873 _MHD_EXTERN enum MHD_Result
   5874 MHD_run_wait (struct MHD_Daemon *daemon,
   5875               int32_t millisec)
   5876 {
   5877   enum MHD_Result res;
   5878   if ( (daemon->shutdown) ||
   5879        MHD_D_IS_USING_THREADS_ (daemon) )
   5880     return MHD_NO;
   5881 
   5882   mhd_assert (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid));
   5883 
   5884   if (0 > millisec)
   5885     millisec = -1;
   5886 #ifdef HAVE_POLL
   5887   if (MHD_D_IS_USING_POLL_ (daemon))
   5888   {
   5889     res = MHD_poll_all (daemon, millisec);
   5890     MHD_cleanup_connections (daemon);
   5891   }
   5892   else
   5893 #endif /* HAVE_POLL */
   5894 #ifdef EPOLL_SUPPORT
   5895   if (MHD_D_IS_USING_EPOLL_ (daemon))
   5896   {
   5897     res = MHD_epoll (daemon, millisec);
   5898     MHD_cleanup_connections (daemon);
   5899   }
   5900   else
   5901 #endif
   5902   if (1)
   5903   {
   5904     mhd_assert (MHD_D_IS_USING_SELECT_ (daemon));
   5905 #ifdef HAS_FD_SETSIZE_OVERRIDABLE
   5906 #ifdef HAVE_MESSAGES
   5907     if (daemon->fdset_size_set_by_app
   5908         && (((int) FD_SETSIZE) < daemon->fdset_size))
   5909     {
   5910       MHD_DLOG (daemon,
   5911                 _ ("MHD_run()/MHD_run_wait() called for daemon started with " \
   5912                    "MHD_OPTION_APP_FD_SETSIZE option (%d). " \
   5913                    "The library was compiled with smaller FD_SETSIZE (%d). " \
   5914                    "Some socket FDs may be not processed. " \
   5915                    "Use MHD_run_from_select2() instead of MHD_run() or " \
   5916                    "do not use MHD_OPTION_APP_FD_SETSIZE option.\n"),
   5917                 daemon->fdset_size, (int) FD_SETSIZE);
   5918     }
   5919 #endif /* HAVE_MESSAGES */
   5920 #endif /* HAS_FD_SETSIZE_OVERRIDABLE */
   5921 
   5922     res = MHD_select (daemon, millisec);
   5923     /* MHD_select does MHD_cleanup_connections already */
   5924   }
   5925   return res;
   5926 }
   5927 
   5928 
   5929 /**
   5930  * Close the given connection, remove it from all of its
   5931  * DLLs and move it into the cleanup queue.
   5932  * @remark To be called only from thread that
   5933  * process daemon's select()/poll()/etc.
   5934  *
   5935  * @param pos connection to move to cleanup
   5936  */
   5937 static void
   5938 close_connection (struct MHD_Connection *pos)
   5939 {
   5940   struct MHD_Daemon *daemon = pos->daemon;
   5941 
   5942 #ifdef MHD_USE_THREADS
   5943   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   5944                MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   5945   mhd_assert (NULL == daemon->worker_pool);
   5946 #endif /* MHD_USE_THREADS */
   5947 
   5948   if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   5949   {
   5950     MHD_connection_mark_closed_ (pos);
   5951     return;   /* must let thread to do the rest */
   5952   }
   5953   MHD_connection_close_ (pos,
   5954                          MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN);
   5955 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   5956   MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   5957 #endif
   5958   mhd_assert (! pos->suspended);
   5959   mhd_assert (! pos->resuming);
   5960   if (pos->connection_timeout_ms == daemon->connection_timeout_ms)
   5961     XDLL_remove (daemon->normal_timeout_head,
   5962                  daemon->normal_timeout_tail,
   5963                  pos);
   5964   else
   5965     XDLL_remove (daemon->manual_timeout_head,
   5966                  daemon->manual_timeout_tail,
   5967                  pos);
   5968   DLL_remove (daemon->connections_head,
   5969               daemon->connections_tail,
   5970               pos);
   5971   DLL_insert (daemon->cleanup_head,
   5972               daemon->cleanup_tail,
   5973               pos);
   5974   daemon->data_already_pending = true;
   5975 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   5976   MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   5977 #endif
   5978 }
   5979 
   5980 
   5981 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   5982 /**
   5983  * Thread that runs the polling loop until the daemon
   5984  * is explicitly shut down.
   5985  *
   5986  * @param cls `struct MHD_Deamon` to run select loop in a thread for
   5987  * @return always 0 (on shutdown)
   5988  */
   5989 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
   5990 MHD_polling_thread (void *cls)
   5991 {
   5992   struct MHD_Daemon *daemon = cls;
   5993 #ifdef HAVE_PTHREAD_SIGMASK
   5994   sigset_t s_mask;
   5995   int err;
   5996 #endif /* HAVE_PTHREAD_SIGMASK */
   5997 
   5998   MHD_thread_handle_ID_set_current_thread_ID_ (&(daemon->tid));
   5999 #ifdef HAVE_PTHREAD_SIGMASK
   6000   if ((0 == sigemptyset (&s_mask)) &&
   6001       (0 == sigaddset (&s_mask, SIGPIPE)))
   6002   {
   6003     err = pthread_sigmask (SIG_BLOCK, &s_mask, NULL);
   6004   }
   6005   else
   6006     err = errno;
   6007   if (0 == err)
   6008     daemon->sigpipe_blocked = true;
   6009 #ifdef HAVE_MESSAGES
   6010   else
   6011     MHD_DLOG (daemon,
   6012               _ ("Failed to block SIGPIPE on daemon thread: %s\n"),
   6013               MHD_strerror_ (errno));
   6014 #endif /* HAVE_MESSAGES */
   6015 #endif /* HAVE_PTHREAD_SIGMASK */
   6016   while (! daemon->shutdown)
   6017   {
   6018 #ifdef HAVE_POLL
   6019     if (MHD_D_IS_USING_POLL_ (daemon))
   6020       MHD_poll (daemon, MHD_YES);
   6021     else
   6022 #endif /* HAVE_POLL */
   6023 #ifdef EPOLL_SUPPORT
   6024     if (MHD_D_IS_USING_EPOLL_ (daemon))
   6025       MHD_epoll (daemon, -1);
   6026     else
   6027 #endif
   6028     MHD_select (daemon, -1);
   6029     MHD_cleanup_connections (daemon);
   6030   }
   6031 
   6032   /* Resume any pending for resume connections, join
   6033    * all connection's threads (if any) and finally cleanup
   6034    * everything. */
   6035   if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
   6036     resume_suspended_connections (daemon);
   6037   close_all_connections (daemon);
   6038 
   6039   return (MHD_THRD_RTRN_TYPE_) 0;
   6040 }
   6041 
   6042 
   6043 #endif
   6044 
   6045 
   6046 /**
   6047  * Process escape sequences ('%HH') Updates val in place; the
   6048  * result cannot be larger than the input.
   6049  * The result must also still be 0-terminated.
   6050  *
   6051  * @param cls closure (use NULL)
   6052  * @param connection handle to connection, not used
   6053  * @param val value to unescape (modified in the process)
   6054  * @return length of the resulting val (strlen(val) maybe
   6055  *  shorter afterwards due to elimination of escape sequences)
   6056  */
   6057 static size_t
   6058 unescape_wrapper (void *cls,
   6059                   struct MHD_Connection *connection,
   6060                   char *val)
   6061 {
   6062   bool broken;
   6063   size_t res;
   6064   (void) cls; /* Mute compiler warning. */
   6065 
   6066   /* TODO: add individual parameter */
   6067   if (0 <= connection->daemon->client_discipline)
   6068     return MHD_str_pct_decode_in_place_strict_ (val);
   6069 
   6070   res = MHD_str_pct_decode_in_place_lenient_ (val, &broken);
   6071 #ifdef HAVE_MESSAGES
   6072   if (broken)
   6073   {
   6074     MHD_DLOG (connection->daemon,
   6075               _ ("The URL encoding is broken.\n"));
   6076   }
   6077 #endif /* HAVE_MESSAGES */
   6078   return res;
   6079 }
   6080 
   6081 
   6082 /**
   6083  * Start a webserver on the given port.  Variadic version of
   6084  * #MHD_start_daemon_va.
   6085  *
   6086  * @param flags combination of `enum MHD_FLAG` values
   6087  * @param port port to bind to (in host byte order),
   6088  *        use '0' to bind to random free port,
   6089  *        ignored if #MHD_OPTION_SOCK_ADDR or
   6090  *        #MHD_OPTION_LISTEN_SOCKET is provided
   6091  *        or #MHD_USE_NO_LISTEN_SOCKET is specified
   6092  * @param apc callback to call to check which clients
   6093  *        will be allowed to connect; you can pass NULL
   6094  *        in which case connections from any IP will be
   6095  *        accepted
   6096  * @param apc_cls extra argument to @a apc
   6097  * @param dh handler called for all requests (repeatedly)
   6098  * @param dh_cls extra argument to @a dh
   6099  * @return NULL on error, handle to daemon on success
   6100  * @ingroup event
   6101  */
   6102 _MHD_EXTERN struct MHD_Daemon *
   6103 MHD_start_daemon (unsigned int flags,
   6104                   uint16_t port,
   6105                   MHD_AcceptPolicyCallback apc,
   6106                   void *apc_cls,
   6107                   MHD_AccessHandlerCallback dh,
   6108                   void *dh_cls,
   6109                   ...)
   6110 {
   6111   struct MHD_Daemon *daemon;
   6112   va_list ap;
   6113 
   6114   va_start (ap,
   6115             dh_cls);
   6116   daemon = MHD_start_daemon_va (flags,
   6117                                 port,
   6118                                 apc,
   6119                                 apc_cls,
   6120                                 dh,
   6121                                 dh_cls,
   6122                                 ap);
   6123   va_end (ap);
   6124   return daemon;
   6125 }
   6126 
   6127 
   6128 /**
   6129  * Stop accepting connections from the listening socket.  Allows
   6130  * clients to continue processing, but stops accepting new
   6131  * connections.  Note that the caller is responsible for closing the
   6132  * returned socket; however, if MHD is run using threads (anything but
   6133  * external select mode), socket will be removed from existing threads
   6134  * with some delay and it must not be closed while it's in use. To make
   6135  * sure that the socket is not used anymore, call #MHD_stop_daemon.
   6136  *
   6137  * Note that some thread modes require the caller to have passed
   6138  * #MHD_USE_ITC when using this API.  If this daemon is
   6139  * in one of those modes and this option was not given to
   6140  * #MHD_start_daemon, this function will return #MHD_INVALID_SOCKET.
   6141  *
   6142  * @param daemon daemon to stop accepting new connections for
   6143  * @return old listen socket on success, #MHD_INVALID_SOCKET if
   6144  *         the daemon was already not listening anymore
   6145  * @ingroup specialized
   6146  */
   6147 _MHD_EXTERN MHD_socket
   6148 MHD_quiesce_daemon (struct MHD_Daemon *daemon)
   6149 {
   6150 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   6151   unsigned int i;
   6152 #endif
   6153   MHD_socket ret;
   6154 
   6155   ret = daemon->listen_fd;
   6156   if ((MHD_INVALID_SOCKET == ret)
   6157       || daemon->was_quiesced)
   6158     return MHD_INVALID_SOCKET;
   6159   if ( (0 == (daemon->options & (MHD_USE_ITC))) &&
   6160        MHD_D_IS_USING_THREADS_ (daemon) )
   6161   {
   6162 #ifdef HAVE_MESSAGES
   6163     MHD_DLOG (daemon,
   6164               _ ("Using MHD_quiesce_daemon in this mode " \
   6165                  "requires MHD_USE_ITC.\n"));
   6166 #endif
   6167     return MHD_INVALID_SOCKET;
   6168   }
   6169 
   6170 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   6171   if (NULL != daemon->worker_pool)
   6172     for (i = 0; i < daemon->worker_pool_size; i++)
   6173     {
   6174       daemon->worker_pool[i].was_quiesced = true;
   6175 #ifdef EPOLL_SUPPORT
   6176       if (MHD_D_IS_USING_EPOLL_ (daemon) &&
   6177           (-1 != daemon->worker_pool[i].epoll_fd) &&
   6178           (daemon->worker_pool[i].listen_socket_in_epoll) )
   6179       {
   6180         if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
   6181                             EPOLL_CTL_DEL,
   6182                             ret,
   6183                             NULL))
   6184           MHD_PANIC (_ ("Failed to remove listen FD from epoll set.\n"));
   6185         daemon->worker_pool[i].listen_socket_in_epoll = false;
   6186       }
   6187       else
   6188 #endif
   6189       if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc))
   6190       {
   6191         if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q"))
   6192           MHD_PANIC (_ ("Failed to signal quiesce via inter-thread " \
   6193                         "communication channel.\n"));
   6194       }
   6195     }
   6196 #endif
   6197   daemon->was_quiesced = true;
   6198 #ifdef EPOLL_SUPPORT
   6199   if (MHD_D_IS_USING_EPOLL_ (daemon) &&
   6200       (-1 != daemon->epoll_fd) &&
   6201       (daemon->listen_socket_in_epoll) )
   6202   {
   6203     if ( (0 != epoll_ctl (daemon->epoll_fd,
   6204                           EPOLL_CTL_DEL,
   6205                           ret,
   6206                           NULL)) &&
   6207          (ENOENT != errno) )   /* ENOENT can happen due to race with
   6208                                   #MHD_epoll() */
   6209       MHD_PANIC ("Failed to remove listen FD from epoll set.\n");
   6210     daemon->listen_socket_in_epoll = false;
   6211   }
   6212 #endif
   6213   if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
   6214        (! MHD_itc_activate_ (daemon->itc, "q")) )
   6215     MHD_PANIC (_ ("failed to signal quiesce via inter-thread " \
   6216                   "communication channel.\n"));
   6217   return ret;
   6218 }
   6219 
   6220 
   6221 /**
   6222  * Temporal location of the application-provided parameters/options.
   6223  * Used when options are decoded from #MHD_start_deamon() parameters, but
   6224  * not yet processed/applied.
   6225  */
   6226 struct MHD_InterimParams_
   6227 {
   6228   /**
   6229    * The total number of all user options used.
   6230    *
   6231    * Contains number only of meaningful options, i.e. #MHD_OPTION_END and
   6232    * #MHD_OPTION_ARRAY themselves are not counted, while options inside
   6233    * #MHD_OPTION_ARRAY are counted.
   6234    */
   6235   size_t num_opts;
   6236   /**
   6237    * Set to 'true' if @a fdset_size is set by application.
   6238    */
   6239   bool fdset_size_set;
   6240   /**
   6241    * The value for #MHD_OPTION_APP_FD_SETSIZE set by application.
   6242    */
   6243   int fdset_size;
   6244   /**
   6245    * Set to 'true' if @a listen_fd is set by application.
   6246    */
   6247   bool listen_fd_set;
   6248   /**
   6249    * Application-provided listen socket.
   6250    */
   6251   MHD_socket listen_fd;
   6252   /**
   6253    * Set to 'true' if @a server_addr is set by application.
   6254    */
   6255   bool pserver_addr_set;
   6256   /**
   6257    * Application-provided struct sockaddr to bind server to.
   6258    */
   6259   const struct sockaddr *pserver_addr;
   6260   /**
   6261    * Set to 'true' if @a server_addr_len is set by application.
   6262    */
   6263   bool server_addr_len_set;
   6264   /**
   6265    * Applicaiton-provided the size of the memory pointed by @a server_addr.
   6266    */
   6267   socklen_t server_addr_len;
   6268 };
   6269 
   6270 /**
   6271  * Signature of the MHD custom logger function.
   6272  *
   6273  * @param cls closure
   6274  * @param format format string
   6275  * @param va arguments to the format string (fprintf-style)
   6276  */
   6277 typedef void
   6278 (*VfprintfFunctionPointerType)(void *cls,
   6279                                const char *format,
   6280                                va_list va);
   6281 
   6282 
   6283 /**
   6284  * Parse a list of options given as varargs.
   6285  *
   6286  * @param daemon the daemon to initialize
   6287  * @param servaddr where to store the server's listen address
   6288  * @param params the interim parameters to be assigned to
   6289  * @param ap the options
   6290  * @return #MHD_YES on success, #MHD_NO on error
   6291  */
   6292 static enum MHD_Result
   6293 parse_options_va (struct MHD_Daemon *daemon,
   6294                   struct MHD_InterimParams_ *params,
   6295                   va_list ap);
   6296 
   6297 
   6298 /**
   6299  * Parse a list of options given as varargs.
   6300  *
   6301  * @param daemon the daemon to initialize
   6302  * @param servaddr where to store the server's listen address
   6303  * @param params the interim parameters to be assigned to
   6304  * @param ... the options
   6305  * @return #MHD_YES on success, #MHD_NO on error
   6306  */
   6307 static enum MHD_Result
   6308 parse_options (struct MHD_Daemon *daemon,
   6309                struct MHD_InterimParams_ *params,
   6310                ...)
   6311 {
   6312   va_list ap;
   6313   enum MHD_Result ret;
   6314 
   6315   va_start (ap, params);
   6316   ret = parse_options_va (daemon,
   6317                           params,
   6318                           ap);
   6319   va_end (ap);
   6320   return ret;
   6321 }
   6322 
   6323 
   6324 #ifdef HTTPS_SUPPORT
   6325 /**
   6326  * Type of GnuTLS priorities base string
   6327  */
   6328 enum MHD_TlsPrioritiesBaseType
   6329 {
   6330   MHD_TLS_PRIO_BASE_LIBMHD = 0, /**< @c "@LIBMICROHTTPD" */
   6331   MHD_TLS_PRIO_BASE_SYSTEM = 1, /**< @c "@SYSTEM" */
   6332 #if GNUTLS_VERSION_NUMBER >= 0x030300
   6333   MHD_TLS_PRIO_BASE_DEFAULT,    /**< Default priorities string */
   6334 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */
   6335   MHD_TLS_PRIO_BASE_NORMAL      /**< @c "NORMAL */
   6336 };
   6337 
   6338 static const struct _MHD_cstr_w_len MHD_TlsBasePriotities[] = {
   6339   _MHD_S_STR_W_LEN ("@LIBMICROHTTPD"),
   6340   _MHD_S_STR_W_LEN ("@SYSTEM"),
   6341 #if GNUTLS_VERSION_NUMBER >= 0x030300
   6342   {NULL, 0},
   6343 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */
   6344   _MHD_S_STR_W_LEN ("NORMAL")
   6345 };
   6346 
   6347 /**
   6348  * Initialise TLS priorities with default settings
   6349  * @param daemon the daemon to initialise TLS priorities
   6350  * @return true on success, false on error
   6351  */
   6352 static bool
   6353 daemon_tls_priorities_init_default (struct MHD_Daemon *daemon)
   6354 {
   6355   unsigned int p;
   6356   int res;
   6357 
   6358   mhd_assert (0 != (((unsigned int) daemon->options) & MHD_USE_TLS));
   6359   mhd_assert (NULL == daemon->priority_cache);
   6360   mhd_assert (MHD_TLS_PRIO_BASE_NORMAL + 1 == \
   6361               sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0]));
   6362 
   6363   res = GNUTLS_E_SUCCESS; /* Mute compiler warning */
   6364 
   6365   for (p = 0;
   6366        p < sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0]);
   6367        ++p)
   6368   {
   6369     res = gnutls_priority_init (&daemon->priority_cache,
   6370                                 MHD_TlsBasePriotities[p].str, NULL);
   6371     if (GNUTLS_E_SUCCESS == res)
   6372     {
   6373 #ifdef _DEBUG
   6374 #ifdef HAVE_MESSAGES
   6375       switch ((enum MHD_TlsPrioritiesBaseType) p)
   6376       {
   6377       case MHD_TLS_PRIO_BASE_LIBMHD:
   6378         MHD_DLOG (daemon,
   6379                   _ ("GnuTLS priorities have been initialised with " \
   6380                      "@LIBMICROHTTPD application-specific system-wide " \
   6381                      "configuration.\n") );
   6382         break;
   6383       case MHD_TLS_PRIO_BASE_SYSTEM:
   6384         MHD_DLOG (daemon,
   6385                   _ ("GnuTLS priorities have been initialised with " \
   6386                      "@SYSTEM system-wide configuration.\n") );
   6387         break;
   6388 #if GNUTLS_VERSION_NUMBER >= 0x030300
   6389       case MHD_TLS_PRIO_BASE_DEFAULT:
   6390         MHD_DLOG (daemon,
   6391                   _ ("GnuTLS priorities have been initialised with " \
   6392                      "GnuTLS default configuration.\n") );
   6393         break;
   6394 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */
   6395       case MHD_TLS_PRIO_BASE_NORMAL:
   6396         MHD_DLOG (daemon,
   6397                   _ ("GnuTLS priorities have been initialised with " \
   6398                      "NORMAL configuration.\n") );
   6399         break;
   6400       default:
   6401         mhd_assert (0);
   6402       }
   6403 #endif /* HAVE_MESSAGES */
   6404 #endif /* _DEBUG */
   6405       return true;
   6406     }
   6407   }
   6408 #ifdef HAVE_MESSAGES
   6409   MHD_DLOG (daemon,
   6410             _ ("Failed to set GnuTLS priorities. Last error: %s\n"),
   6411             gnutls_strerror (res));
   6412 #endif /* HAVE_MESSAGES */
   6413   return false;
   6414 }
   6415 
   6416 
   6417 /**
   6418  * The inner helper function for #daemon_tls_priorities_init_app().
   6419  * @param daemon the daemon to use
   6420  * @param prio   the appication-specified appendix for default priorities
   6421  * @param prio_len the length of @a prio
   6422  * @param buf    the temporal buffer for string manipulations
   6423  * @param buf_size the size of the @a buf
   6424  * @return true on success, false on error
   6425  */
   6426 static bool
   6427 daemon_tls_priorities_init_append_inner_ (struct MHD_Daemon *daemon,
   6428                                           const char *prio,
   6429                                           size_t prio_len,
   6430                                           char *buf,
   6431                                           const size_t buf_size)
   6432 {
   6433   unsigned int p;
   6434   int res;
   6435   const char *err_pos;
   6436 
   6437   (void) buf_size; /* Mute compiler warning for non-Debug builds */
   6438   mhd_assert (0 != (((unsigned int) daemon->options) & MHD_USE_TLS));
   6439   mhd_assert (NULL == daemon->priority_cache);
   6440   mhd_assert (MHD_TLS_PRIO_BASE_NORMAL + 1 == \
   6441               sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0]));
   6442 
   6443   res = GNUTLS_E_SUCCESS; /* Mute compiler warning */
   6444 
   6445   for (p = 0;
   6446        p < sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0]);
   6447        ++p)
   6448   {
   6449 
   6450 #if GNUTLS_VERSION_NUMBER >= 0x030300
   6451 #if GNUTLS_VERSION_NUMBER >= 0x030603
   6452     if (NULL == MHD_TlsBasePriotities[p].str)
   6453       res = gnutls_priority_init2 (&daemon->priority_cache, prio, &err_pos,
   6454                                    GNUTLS_PRIORITY_INIT_DEF_APPEND);
   6455     else
   6456 #else /* 0x030300 <= GNUTLS_VERSION_NUMBER
   6457          && GNUTLS_VERSION_NUMBER < 0x030603 */
   6458     if (NULL == MHD_TlsBasePriotities[p].str)
   6459       continue; /* Skip the value, no way to append priorities to the default string */
   6460     else
   6461 #endif /* GNUTLS_VERSION_NUMBER < 0x030603 */
   6462 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */
   6463     if (1)
   6464     {
   6465       size_t buf_pos;
   6466 
   6467       mhd_assert (NULL != MHD_TlsBasePriotities[p].str);
   6468       buf_pos = 0;
   6469       memcpy (buf + buf_pos, MHD_TlsBasePriotities[p].str,
   6470               MHD_TlsBasePriotities[p].len);
   6471       buf_pos += MHD_TlsBasePriotities[p].len;
   6472       buf[buf_pos++] = ':';
   6473       memcpy (buf + buf_pos, prio, prio_len + 1);
   6474 #ifdef _DEBUG
   6475       buf_pos += prio_len + 1;
   6476       mhd_assert (buf_size >= buf_pos);
   6477 #endif /* _DEBUG */
   6478       res = gnutls_priority_init (&daemon->priority_cache, buf, &err_pos);
   6479     }
   6480     if (GNUTLS_E_SUCCESS == res)
   6481     {
   6482 #ifdef _DEBUG
   6483 #ifdef HAVE_MESSAGES
   6484       switch ((enum MHD_TlsPrioritiesBaseType) p)
   6485       {
   6486       case MHD_TLS_PRIO_BASE_LIBMHD:
   6487         MHD_DLOG (daemon,
   6488                   _ ("GnuTLS priorities have been initialised with " \
   6489                      "priorities specified by application appended to " \
   6490                      "@LIBMICROHTTPD application-specific system-wide " \
   6491                      "configuration.\n") );
   6492         break;
   6493       case MHD_TLS_PRIO_BASE_SYSTEM:
   6494         MHD_DLOG (daemon,
   6495                   _ ("GnuTLS priorities have been initialised with " \
   6496                      "priorities specified by application appended to " \
   6497                      "@SYSTEM system-wide configuration.\n") );
   6498         break;
   6499 #if GNUTLS_VERSION_NUMBER >= 0x030300
   6500       case MHD_TLS_PRIO_BASE_DEFAULT:
   6501         MHD_DLOG (daemon,
   6502                   _ ("GnuTLS priorities have been initialised with " \
   6503                      "priorities specified by application appended to " \
   6504                      "GnuTLS default configuration.\n") );
   6505         break;
   6506 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */
   6507       case MHD_TLS_PRIO_BASE_NORMAL:
   6508         MHD_DLOG (daemon,
   6509                   _ ("GnuTLS priorities have been initialised with " \
   6510                      "priorities specified by application appended to " \
   6511                      "NORMAL configuration.\n") );
   6512         break;
   6513       default:
   6514         mhd_assert (0);
   6515       }
   6516 #endif /* HAVE_MESSAGES */
   6517 #endif /* _DEBUG */
   6518       return true;
   6519     }
   6520   }
   6521 #ifdef HAVE_MESSAGES
   6522   MHD_DLOG (daemon,
   6523             _ ("Failed to set GnuTLS priorities. Last error: %s. " \
   6524                "The problematic part starts at: %s\n"),
   6525             gnutls_strerror (res), err_pos);
   6526 #endif /* HAVE_MESSAGES */
   6527   return false;
   6528 }
   6529 
   6530 
   6531 #define LOCAL_BUFF_SIZE 128
   6532 
   6533 /**
   6534  * Initialise TLS priorities with default settings with application-specified
   6535  * appended string.
   6536  * @param daemon the daemon to initialise TLS priorities
   6537  * @param prio the application specified priorities to be appended to
   6538  *             the GnuTLS standard priorities string
   6539  * @return true on success, false on error
   6540  */
   6541 static bool
   6542 daemon_tls_priorities_init_append (struct MHD_Daemon *daemon, const char *prio)
   6543 {
   6544   static const size_t longest_base_prio = MHD_STATICSTR_LEN_ ("@LIBMICROHTTPD");
   6545   bool ret;
   6546   size_t prio_len;
   6547   size_t buf_size_needed;
   6548 
   6549   if (NULL == prio)
   6550     return daemon_tls_priorities_init_default (daemon);
   6551 
   6552   if (':' == prio[0])
   6553     ++prio;
   6554 
   6555   prio_len = strlen (prio);
   6556 
   6557   buf_size_needed = longest_base_prio + 1 + prio_len + 1;
   6558 
   6559   if (LOCAL_BUFF_SIZE >= buf_size_needed)
   6560   {
   6561     char local_buffer[LOCAL_BUFF_SIZE];
   6562     ret = daemon_tls_priorities_init_append_inner_ (daemon, prio, prio_len,
   6563                                                     local_buffer,
   6564                                                     LOCAL_BUFF_SIZE);
   6565   }
   6566   else
   6567   {
   6568     char *allocated_buffer;
   6569     allocated_buffer = (char *) malloc (buf_size_needed);
   6570     if (NULL == allocated_buffer)
   6571     {
   6572 #ifdef HAVE_MESSAGES
   6573       MHD_DLOG (daemon,
   6574                 _ ("Error allocating memory: %s\n"),
   6575                 MHD_strerror_ (errno));
   6576 #endif
   6577       return false;
   6578     }
   6579     ret = daemon_tls_priorities_init_append_inner_ (daemon, prio, prio_len,
   6580                                                     allocated_buffer,
   6581                                                     buf_size_needed);
   6582     free (allocated_buffer);
   6583   }
   6584   return ret;
   6585 }
   6586 
   6587 
   6588 #endif /* HTTPS_SUPPORT */
   6589 
   6590 
   6591 /**
   6592  * Parse a list of options given as varargs.
   6593  *
   6594  * @param[in,out] daemon the daemon to initialize
   6595  * @param[out] params the interim parameters to be assigned to
   6596  * @param ap the options
   6597  * @return #MHD_YES on success, #MHD_NO on error
   6598  */
   6599 static enum MHD_Result
   6600 parse_options_va (struct MHD_Daemon *daemon,
   6601                   struct MHD_InterimParams_ *params,
   6602                   va_list ap)
   6603 {
   6604   enum MHD_OPTION opt;
   6605   struct MHD_OptionItem *oa;
   6606   unsigned int i;
   6607   unsigned int uv;
   6608 #ifdef HTTPS_SUPPORT
   6609   const char *pstr;
   6610 #if GNUTLS_VERSION_MAJOR >= 3
   6611   gnutls_certificate_retrieve_function2 * pgcrf;
   6612 #endif
   6613 #if GNUTLS_VERSION_NUMBER >= 0x030603
   6614   gnutls_certificate_retrieve_function3 * pgcrf2;
   6615 #endif
   6616 #endif /* HTTPS_SUPPORT */
   6617 
   6618   while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int)))
   6619   {
   6620     /* Increase counter at start, so resulting value is number of
   6621      * processed options, including any failed ones. */
   6622     params->num_opts++;
   6623     switch (opt)
   6624     {
   6625     case MHD_OPTION_CONNECTION_MEMORY_LIMIT:
   6626       if (1)
   6627       {
   6628         size_t val;
   6629 
   6630         val = va_arg (ap,
   6631                       size_t);
   6632         if (0 != val)
   6633         {
   6634           daemon->pool_size = val;
   6635           if (64 > daemon->pool_size)
   6636           {
   6637 #ifdef HAVE_MESSAGES
   6638             MHD_DLOG (daemon,
   6639                       _ ("Warning: specified " \
   6640                          "MHD_OPTION_CONNECTION_MEMORY_LIMIT " \
   6641                          "value is too small and rounded up to 64.\n"));
   6642 #endif /* HAVE_MESSAGES */
   6643             daemon->pool_size = 64;
   6644           }
   6645           if (daemon->pool_size / 4 < daemon->pool_increment)
   6646             daemon->pool_increment = daemon->pool_size / 4;
   6647         }
   6648       }
   6649       break;
   6650     case MHD_OPTION_CONNECTION_MEMORY_INCREMENT:
   6651       if (1)
   6652       {
   6653         size_t val;
   6654 
   6655         val = va_arg (ap,
   6656                       size_t);
   6657 
   6658         if (0 != val)
   6659         {
   6660           daemon->pool_increment = val;
   6661           if (daemon->pool_size / 4 < daemon->pool_increment)
   6662           {
   6663 #ifdef HAVE_MESSAGES
   6664             MHD_DLOG (daemon,
   6665                       _ ("Warning: specified " \
   6666                          "MHD_OPTION_CONNECTION_MEMORY_INCREMENT value is " \
   6667                          "too large and rounded down to 1/4 of " \
   6668                          "MHD_OPTION_CONNECTION_MEMORY_LIMIT.\n"));
   6669 #endif /* HAVE_MESSAGES */
   6670             daemon->pool_increment = daemon->pool_size / 4;
   6671           }
   6672         }
   6673       }
   6674       break;
   6675     case MHD_OPTION_CONNECTION_LIMIT:
   6676       daemon->connection_limit = va_arg (ap,
   6677                                          unsigned int);
   6678       break;
   6679     case MHD_OPTION_CONNECTION_TIMEOUT:
   6680       uv = va_arg (ap,
   6681                    unsigned int);
   6682 #if (SIZEOF_UINT64_T - 2) <= SIZEOF_UNSIGNED_INT
   6683       if ((UINT64_MAX / 4000 - 1) < uv)
   6684       {
   6685 #ifdef HAVE_MESSAGES
   6686         MHD_DLOG (daemon,
   6687                   _ ("The specified connection timeout (%u) is too large. " \
   6688                      "Maximum allowed value (%" PRIu64 ") will be used " \
   6689                      "instead.\n"),
   6690                   uv,
   6691                   (UINT64_MAX / 4000 - 1));
   6692 #endif
   6693         uv = UINT64_MAX / 4000 - 1;
   6694       }
   6695 #endif /* (SIZEOF_UINT64_T - 2) <= SIZEOF_UNSIGNED_INT */
   6696       daemon->connection_timeout_ms = ((uint64_t) uv) * 1000;
   6697       break;
   6698     case MHD_OPTION_NOTIFY_COMPLETED:
   6699       daemon->notify_completed = va_arg (ap,
   6700                                          MHD_RequestCompletedCallback);
   6701       daemon->notify_completed_cls = va_arg (ap,
   6702                                              void *);
   6703       break;
   6704     case MHD_OPTION_NOTIFY_CONNECTION:
   6705       daemon->notify_connection = va_arg (ap,
   6706                                           MHD_NotifyConnectionCallback);
   6707       daemon->notify_connection_cls = va_arg (ap,
   6708                                               void *);
   6709       break;
   6710     case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
   6711       daemon->per_ip_connection_limit = va_arg (ap,
   6712                                                 unsigned int);
   6713       break;
   6714     case MHD_OPTION_SOCK_ADDR_LEN:
   6715       params->server_addr_len = va_arg (ap,
   6716                                         socklen_t);
   6717       params->server_addr_len_set = true;
   6718       params->pserver_addr = va_arg (ap,
   6719                                      const struct sockaddr *);
   6720       params->pserver_addr_set = true;
   6721       break;
   6722     case MHD_OPTION_SOCK_ADDR:
   6723       params->server_addr_len_set = false;
   6724       params->pserver_addr = va_arg (ap,
   6725                                      const struct sockaddr *);
   6726       params->pserver_addr_set = true;
   6727       break;
   6728     case MHD_OPTION_URI_LOG_CALLBACK:
   6729       daemon->uri_log_callback = va_arg (ap,
   6730                                          LogCallback);
   6731       daemon->uri_log_callback_cls = va_arg (ap,
   6732                                              void *);
   6733       break;
   6734     case MHD_OPTION_SERVER_INSANITY:
   6735       daemon->insanity_level = (enum MHD_DisableSanityCheck)
   6736                                va_arg (ap,
   6737                                        unsigned int);
   6738       break;
   6739 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   6740     case MHD_OPTION_THREAD_POOL_SIZE:
   6741       daemon->worker_pool_size = va_arg (ap,
   6742                                          unsigned int);
   6743       if (0 == daemon->worker_pool_size)
   6744       {
   6745         (void) 0; /* MHD_OPTION_THREAD_POOL_SIZE ignored, do nothing */
   6746       }
   6747       else if (1 == daemon->worker_pool_size)
   6748       {
   6749 #ifdef HAVE_MESSAGES
   6750         MHD_DLOG (daemon,
   6751                   _ ("Warning: value \"1\", specified as the thread pool " \
   6752                      "size, is ignored. Thread pool is not used.\n"));
   6753 #endif
   6754         daemon->worker_pool_size = 0;
   6755       }
   6756 #if SIZEOF_UNSIGNED_INT >= (SIZEOF_SIZE_T - 2)
   6757       /* Next comparison could be always false on some platforms and whole branch will
   6758        * be optimized out on these platforms. On others it will be compiled into real
   6759        * check. */
   6760       else if (daemon->worker_pool_size >=
   6761                (SIZE_MAX / sizeof (struct MHD_Daemon)))            /* Compiler may warn on some platforms, ignore warning. */
   6762       {
   6763 #ifdef HAVE_MESSAGES
   6764         MHD_DLOG (daemon,
   6765                   _ ("Specified thread pool size (%u) too big.\n"),
   6766                   daemon->worker_pool_size);
   6767 #endif
   6768         return MHD_NO;
   6769       }
   6770 #endif /* SIZEOF_UNSIGNED_INT >= (SIZEOF_SIZE_T - 2) */
   6771       else
   6772       {
   6773         if (! MHD_D_IS_USING_THREADS_ (daemon))
   6774         {
   6775 #ifdef HAVE_MESSAGES
   6776           MHD_DLOG (daemon,
   6777                     _ ("MHD_OPTION_THREAD_POOL_SIZE option is specified but "
   6778                        "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
   6779 #endif
   6780           return MHD_NO;
   6781         }
   6782         if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   6783         {
   6784 #ifdef HAVE_MESSAGES
   6785           MHD_DLOG (daemon,
   6786                     _ ("Both MHD_OPTION_THREAD_POOL_SIZE option and "
   6787                        "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
   6788 #endif
   6789           return MHD_NO;
   6790         }
   6791       }
   6792       break;
   6793 #endif
   6794 #ifdef HTTPS_SUPPORT
   6795     case MHD_OPTION_HTTPS_MEM_KEY:
   6796       pstr = va_arg (ap,
   6797                      const char *);
   6798       if (0 != (daemon->options & MHD_USE_TLS))
   6799         daemon->https_mem_key = pstr;
   6800 #ifdef HAVE_MESSAGES
   6801       else
   6802         MHD_DLOG (daemon,
   6803                   _ ("MHD HTTPS option %d passed to MHD but " \
   6804                      "MHD_USE_TLS not set.\n"),
   6805                   opt);
   6806 #endif
   6807       break;
   6808     case MHD_OPTION_HTTPS_KEY_PASSWORD:
   6809       pstr = va_arg (ap,
   6810                      const char *);
   6811       if (0 != (daemon->options & MHD_USE_TLS))
   6812         daemon->https_key_password = pstr;
   6813 #ifdef HAVE_MESSAGES
   6814       else
   6815         MHD_DLOG (daemon,
   6816                   _ ("MHD HTTPS option %d passed to MHD but " \
   6817                      "MHD_USE_TLS not set.\n"),
   6818                   opt);
   6819 #endif
   6820       break;
   6821     case MHD_OPTION_HTTPS_MEM_CERT:
   6822       pstr = va_arg (ap,
   6823                      const char *);
   6824       if (0 != (daemon->options & MHD_USE_TLS))
   6825         daemon->https_mem_cert = pstr;
   6826 #ifdef HAVE_MESSAGES
   6827       else
   6828         MHD_DLOG (daemon,
   6829                   _ ("MHD HTTPS option %d passed to MHD but " \
   6830                      "MHD_USE_TLS not set.\n"),
   6831                   opt);
   6832 #endif
   6833       break;
   6834     case MHD_OPTION_HTTPS_MEM_TRUST:
   6835       pstr = va_arg (ap,
   6836                      const char *);
   6837       if (0 != (daemon->options & MHD_USE_TLS))
   6838         daemon->https_mem_trust = pstr;
   6839 #ifdef HAVE_MESSAGES
   6840       else
   6841         MHD_DLOG (daemon,
   6842                   _ ("MHD HTTPS option %d passed to MHD but " \
   6843                      "MHD_USE_TLS not set.\n"),
   6844                   opt);
   6845 #endif
   6846       break;
   6847     case MHD_OPTION_HTTPS_CRED_TYPE:
   6848       daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
   6849                                                               int);
   6850       break;
   6851     case MHD_OPTION_HTTPS_MEM_DHPARAMS:
   6852       pstr = va_arg (ap,
   6853                      const char *);
   6854       if (0 != (daemon->options & MHD_USE_TLS))
   6855       {
   6856         gnutls_datum_t dhpar;
   6857         size_t pstr_len;
   6858 
   6859         if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
   6860         {
   6861 #ifdef HAVE_MESSAGES
   6862           MHD_DLOG (daemon,
   6863                     _ ("Error initializing DH parameters.\n"));
   6864 #endif
   6865           return MHD_NO;
   6866         }
   6867         dhpar.data = (unsigned char *) _MHD_DROP_CONST (pstr);
   6868         pstr_len = strlen (pstr);
   6869         if (UINT_MAX < pstr_len)
   6870         {
   6871 #ifdef HAVE_MESSAGES
   6872           MHD_DLOG (daemon,
   6873                     _ ("Diffie-Hellman parameters string too long.\n"));
   6874 #endif
   6875           return MHD_NO;
   6876         }
   6877         dhpar.size = (unsigned int) pstr_len;
   6878         if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
   6879                                            &dhpar,
   6880                                            GNUTLS_X509_FMT_PEM) < 0)
   6881         {
   6882 #ifdef HAVE_MESSAGES
   6883           MHD_DLOG (daemon,
   6884                     _ ("Bad Diffie-Hellman parameters format.\n"));
   6885 #endif
   6886           gnutls_dh_params_deinit (daemon->https_mem_dhparams);
   6887           return MHD_NO;
   6888         }
   6889         daemon->have_dhparams = true;
   6890       }
   6891 #ifdef HAVE_MESSAGES
   6892       else
   6893         MHD_DLOG (daemon,
   6894                   _ ("MHD HTTPS option %d passed to MHD but " \
   6895                      "MHD_USE_TLS not set.\n"),
   6896                   opt);
   6897 #endif
   6898       break;
   6899     case MHD_OPTION_HTTPS_PRIORITIES:
   6900     case MHD_OPTION_HTTPS_PRIORITIES_APPEND:
   6901       pstr = va_arg (ap,
   6902                      const char *);
   6903       if (0 != (daemon->options & MHD_USE_TLS))
   6904       {
   6905         if (NULL != daemon->priority_cache)
   6906           gnutls_priority_deinit (daemon->priority_cache);
   6907 
   6908         if (MHD_OPTION_HTTPS_PRIORITIES == opt)
   6909         {
   6910           int init_res;
   6911           const char *err_pos;
   6912           init_res = gnutls_priority_init (&daemon->priority_cache,
   6913                                            pstr,
   6914                                            &err_pos);
   6915           if (GNUTLS_E_SUCCESS != init_res)
   6916           {
   6917 #ifdef HAVE_MESSAGES
   6918             MHD_DLOG (daemon,
   6919                       _ ("Setting priorities to '%s' failed: %s " \
   6920                          "The problematic part starts at: %s\n"),
   6921                       pstr,
   6922                       gnutls_strerror (init_res),
   6923                       err_pos);
   6924 #endif
   6925             daemon->priority_cache = NULL;
   6926             return MHD_NO;
   6927           }
   6928         }
   6929         else
   6930         {
   6931           /* The cache has been deinited */
   6932           daemon->priority_cache = NULL;
   6933           if (! daemon_tls_priorities_init_append (daemon, pstr))
   6934             return MHD_NO;
   6935         }
   6936       }
   6937 #ifdef HAVE_MESSAGES
   6938       else
   6939         MHD_DLOG (daemon,
   6940                   _ ("MHD HTTPS option %d passed to MHD but " \
   6941                      "MHD_USE_TLS not set.\n"),
   6942                   opt);
   6943 #endif
   6944       break;
   6945     case MHD_OPTION_HTTPS_CERT_CALLBACK:
   6946 #if GNUTLS_VERSION_MAJOR < 3
   6947 #ifdef HAVE_MESSAGES
   6948       MHD_DLOG (daemon,
   6949                 _ ("MHD_OPTION_HTTPS_CERT_CALLBACK requires building " \
   6950                    "MHD with GnuTLS >= 3.0.\n"));
   6951 #endif
   6952       return MHD_NO;
   6953 #else
   6954       pgcrf = va_arg (ap,
   6955                       gnutls_certificate_retrieve_function2 *);
   6956       if (0 != (daemon->options & MHD_USE_TLS))
   6957         daemon->cert_callback = pgcrf;
   6958 #ifdef HAVE_MESSAGES
   6959       else
   6960         MHD_DLOG (daemon,
   6961                   _ ("MHD HTTPS option %d passed to MHD but " \
   6962                      "MHD_USE_TLS not set.\n"),
   6963                   opt);
   6964 #endif /*  HAVE_MESSAGES */
   6965       break;
   6966 #endif
   6967     case MHD_OPTION_HTTPS_CERT_CALLBACK2:
   6968 #if GNUTLS_VERSION_NUMBER < 0x030603
   6969 #ifdef HAVE_MESSAGES
   6970       MHD_DLOG (daemon,
   6971                 _ ("MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building " \
   6972                    "MHD with GnuTLS >= 3.6.3.\n"));
   6973 #endif
   6974       return MHD_NO;
   6975 #else
   6976       pgcrf2 = va_arg (ap,
   6977                        gnutls_certificate_retrieve_function3 *);
   6978       if (0 != (daemon->options & MHD_USE_TLS))
   6979         daemon->cert_callback2 = pgcrf2;
   6980 #ifdef HAVE_MESSAGES
   6981       else
   6982         MHD_DLOG (daemon,
   6983                   _ ("MHD HTTPS option %d passed to MHD but " \
   6984                      "MHD_USE_TLS not set.\n"),
   6985                   opt);
   6986 #endif /* HAVE_MESSAGES */
   6987       break;
   6988 #endif
   6989 #endif /* HTTPS_SUPPORT */
   6990 #ifdef DAUTH_SUPPORT
   6991     case MHD_OPTION_DIGEST_AUTH_RANDOM:
   6992     case MHD_OPTION_DIGEST_AUTH_RANDOM_COPY:
   6993       daemon->digest_auth_rand_size = va_arg (ap,
   6994                                               size_t);
   6995       daemon->digest_auth_random = va_arg (ap,
   6996                                            const char *);
   6997       if (MHD_OPTION_DIGEST_AUTH_RANDOM_COPY == opt)
   6998         /* Set to some non-NULL value just to indicate that copy is required. */
   6999         daemon->digest_auth_random_copy = daemon;
   7000       else
   7001         daemon->digest_auth_random_copy = NULL;
   7002       break;
   7003     case MHD_OPTION_NONCE_NC_SIZE:
   7004       daemon->nonce_nc_size = va_arg (ap,
   7005                                       unsigned int);
   7006       break;
   7007     case MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE:
   7008       daemon->dauth_bind_type = va_arg (ap,
   7009                                         unsigned int);
   7010       if (0 != (daemon->dauth_bind_type & MHD_DAUTH_BIND_NONCE_URI_PARAMS))
   7011         daemon->dauth_bind_type |= MHD_DAUTH_BIND_NONCE_URI;
   7012       break;
   7013     case MHD_OPTION_DIGEST_AUTH_DEFAULT_NONCE_TIMEOUT:
   7014       if (1)
   7015       {
   7016         unsigned int val;
   7017         val = va_arg (ap,
   7018                       unsigned int);
   7019         if (0 != val)
   7020           daemon->dauth_def_nonce_timeout = val;
   7021       }
   7022       break;
   7023     case MHD_OPTION_DIGEST_AUTH_DEFAULT_MAX_NC:
   7024       if (1)
   7025       {
   7026         uint32_t val;
   7027         val = va_arg (ap,
   7028                       uint32_t);
   7029         if (0 != val)
   7030           daemon->dauth_def_max_nc = val;
   7031       }
   7032       break;
   7033 #else  /* ! DAUTH_SUPPORT */
   7034     case MHD_OPTION_DIGEST_AUTH_RANDOM:
   7035     case MHD_OPTION_DIGEST_AUTH_RANDOM_COPY:
   7036     case MHD_OPTION_NONCE_NC_SIZE:
   7037     case MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE:
   7038     case MHD_OPTION_DIGEST_AUTH_DEFAULT_NONCE_TIMEOUT:
   7039     case MHD_OPTION_DIGEST_AUTH_DEFAULT_MAX_NC:
   7040 #ifdef HAVE_MESSAGES
   7041       MHD_DLOG (daemon,
   7042                 _ ("Digest Auth is disabled for this build " \
   7043                    "of GNU libmicrohttpd.\n"));
   7044 #endif /* HAVE_MESSAGES */
   7045       return MHD_NO;
   7046 #endif /* ! DAUTH_SUPPORT */
   7047     case MHD_OPTION_LISTEN_SOCKET:
   7048       params->listen_fd = va_arg (ap,
   7049                                   MHD_socket);
   7050       params->listen_fd_set = true;
   7051       break;
   7052     case MHD_OPTION_EXTERNAL_LOGGER:
   7053 #ifdef HAVE_MESSAGES
   7054       daemon->custom_error_log = va_arg (ap,
   7055                                          VfprintfFunctionPointerType);
   7056       daemon->custom_error_log_cls = va_arg (ap,
   7057                                              void *);
   7058       if (1 != params->num_opts)
   7059         MHD_DLOG (daemon,
   7060                   _ ("MHD_OPTION_EXTERNAL_LOGGER is not the first option "
   7061                      "specified for the daemon. Some messages may be "
   7062                      "printed by the standard MHD logger.\n"));
   7063 
   7064 #else
   7065       (void) va_arg (ap,
   7066                      VfprintfFunctionPointerType);
   7067       (void) va_arg (ap,
   7068                      void *);
   7069 #endif
   7070       break;
   7071 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   7072     case MHD_OPTION_THREAD_STACK_SIZE:
   7073       daemon->thread_stack_size = va_arg (ap,
   7074                                           size_t);
   7075       break;
   7076 #endif
   7077     case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE:
   7078 #ifdef TCP_FASTOPEN
   7079       daemon->fastopen_queue_size = va_arg (ap,
   7080                                             unsigned int);
   7081       break;
   7082 #else  /* ! TCP_FASTOPEN */
   7083 #ifdef HAVE_MESSAGES
   7084       MHD_DLOG (daemon,
   7085                 _ ("TCP fastopen is not supported on this platform.\n"));
   7086 #endif /* HAVE_MESSAGES */
   7087       return MHD_NO;
   7088 #endif /* ! TCP_FASTOPEN */
   7089     case MHD_OPTION_LISTENING_ADDRESS_REUSE:
   7090       daemon->listening_address_reuse = va_arg (ap,
   7091                                                 unsigned int) ? 1 : -1;
   7092       break;
   7093     case MHD_OPTION_LISTEN_BACKLOG_SIZE:
   7094       daemon->listen_backlog_size = va_arg (ap,
   7095                                             unsigned int);
   7096       break;
   7097     case MHD_OPTION_STRICT_FOR_CLIENT:
   7098       daemon->client_discipline = va_arg (ap, int); /* Temporal assignment */
   7099       /* Map to correct value */
   7100       if (-1 >= daemon->client_discipline)
   7101         daemon->client_discipline = -3;
   7102       else if (1 <= daemon->client_discipline)
   7103         daemon->client_discipline = 1;
   7104 #ifdef HAVE_MESSAGES
   7105       if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) &&
   7106            (1 != daemon->client_discipline) )
   7107       {
   7108         MHD_DLOG (daemon,
   7109                   _ ("Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
   7110                      "another behaviour is specified by "
   7111                      "MHD_OPTION_STRICT_CLIENT.\n"));
   7112       }
   7113 #endif /* HAVE_MESSAGES */
   7114       break;
   7115     case MHD_OPTION_CLIENT_DISCIPLINE_LVL:
   7116       daemon->client_discipline = va_arg (ap, int);
   7117 #ifdef HAVE_MESSAGES
   7118       if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) &&
   7119            (1 != daemon->client_discipline) )
   7120       {
   7121         MHD_DLOG (daemon,
   7122                   _ ("Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
   7123                      "another behaviour is specified by "
   7124                      "MHD_OPTION_CLIENT_DISCIPLINE_LVL.\n"));
   7125       }
   7126 #endif /* HAVE_MESSAGES */
   7127       break;
   7128     case MHD_OPTION_ARRAY:
   7129       params->num_opts--; /* Do not count MHD_OPTION_ARRAY */
   7130       oa = va_arg (ap, struct MHD_OptionItem *);
   7131       i = 0;
   7132       while (MHD_OPTION_END != (opt = oa[i].option))
   7133       {
   7134         switch (opt)
   7135         {
   7136         /* all options taking 'size_t' */
   7137         case MHD_OPTION_CONNECTION_MEMORY_LIMIT:
   7138         case MHD_OPTION_CONNECTION_MEMORY_INCREMENT:
   7139         case MHD_OPTION_THREAD_STACK_SIZE:
   7140           if (MHD_NO == parse_options (daemon,
   7141                                        params,
   7142                                        opt,
   7143                                        (size_t) oa[i].value,
   7144                                        MHD_OPTION_END))
   7145             return MHD_NO;
   7146           break;
   7147         /* all options taking 'unsigned int' */
   7148         case MHD_OPTION_NONCE_NC_SIZE:
   7149         case MHD_OPTION_CONNECTION_LIMIT:
   7150         case MHD_OPTION_CONNECTION_TIMEOUT:
   7151         case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
   7152         case MHD_OPTION_THREAD_POOL_SIZE:
   7153         case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE:
   7154         case MHD_OPTION_LISTENING_ADDRESS_REUSE:
   7155         case MHD_OPTION_LISTEN_BACKLOG_SIZE:
   7156         case MHD_OPTION_SERVER_INSANITY:
   7157         case MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE:
   7158         case MHD_OPTION_DIGEST_AUTH_DEFAULT_NONCE_TIMEOUT:
   7159           if (MHD_NO == parse_options (daemon,
   7160                                        params,
   7161                                        opt,
   7162                                        (unsigned int) oa[i].value,
   7163                                        MHD_OPTION_END))
   7164             return MHD_NO;
   7165           break;
   7166         /* all options taking 'enum' */
   7167         case MHD_OPTION_HTTPS_CRED_TYPE:
   7168 #ifdef HTTPS_SUPPORT
   7169           if (MHD_NO == parse_options (daemon,
   7170                                        params,
   7171                                        opt,
   7172                                        (gnutls_credentials_type_t) oa[i].value,
   7173                                        MHD_OPTION_END))
   7174 #endif /* HTTPS_SUPPORT */
   7175           return MHD_NO;
   7176           break;
   7177         /* all options taking 'MHD_socket' */
   7178         case MHD_OPTION_LISTEN_SOCKET:
   7179           if (MHD_NO == parse_options (daemon,
   7180                                        params,
   7181                                        opt,
   7182                                        (MHD_socket) oa[i].value,
   7183                                        MHD_OPTION_END))
   7184             return MHD_NO;
   7185           break;
   7186         /* all options taking 'int' */
   7187         case MHD_OPTION_STRICT_FOR_CLIENT:
   7188         case MHD_OPTION_CLIENT_DISCIPLINE_LVL:
   7189         case MHD_OPTION_SIGPIPE_HANDLED_BY_APP:
   7190         case MHD_OPTION_TLS_NO_ALPN:
   7191         case MHD_OPTION_APP_FD_SETSIZE:
   7192           if (MHD_NO == parse_options (daemon,
   7193                                        params,
   7194                                        opt,
   7195                                        (int) oa[i].value,
   7196                                        MHD_OPTION_END))
   7197             return MHD_NO;
   7198           break;
   7199         /* all options taking 'uint32_t' */
   7200         case MHD_OPTION_DIGEST_AUTH_DEFAULT_MAX_NC:
   7201           if (MHD_NO == parse_options (daemon,
   7202                                        params,
   7203                                        opt,
   7204                                        (uint32_t) oa[i].value,
   7205                                        MHD_OPTION_END))
   7206             return MHD_NO;
   7207           break;
   7208         /* all options taking one pointer */
   7209         case MHD_OPTION_SOCK_ADDR:
   7210         case MHD_OPTION_HTTPS_MEM_KEY:
   7211         case MHD_OPTION_HTTPS_KEY_PASSWORD:
   7212         case MHD_OPTION_HTTPS_MEM_CERT:
   7213         case MHD_OPTION_HTTPS_MEM_TRUST:
   7214         case MHD_OPTION_HTTPS_MEM_DHPARAMS:
   7215         case MHD_OPTION_HTTPS_PRIORITIES:
   7216         case MHD_OPTION_HTTPS_PRIORITIES_APPEND:
   7217         case MHD_OPTION_ARRAY:
   7218         case MHD_OPTION_HTTPS_CERT_CALLBACK:
   7219         case MHD_OPTION_HTTPS_CERT_CALLBACK2:
   7220           if (MHD_NO == parse_options (daemon,
   7221                                        params,
   7222                                        opt,
   7223                                        oa[i].ptr_value,
   7224                                        MHD_OPTION_END))
   7225             return MHD_NO;
   7226           break;
   7227         /* all options taking two pointers */
   7228         case MHD_OPTION_NOTIFY_COMPLETED:
   7229         case MHD_OPTION_NOTIFY_CONNECTION:
   7230         case MHD_OPTION_URI_LOG_CALLBACK:
   7231         case MHD_OPTION_EXTERNAL_LOGGER:
   7232         case MHD_OPTION_UNESCAPE_CALLBACK:
   7233         case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER:
   7234           if (MHD_NO == parse_options (daemon,
   7235                                        params,
   7236                                        opt,
   7237                                        (void *) oa[i].value,
   7238                                        oa[i].ptr_value,
   7239                                        MHD_OPTION_END))
   7240             return MHD_NO;
   7241           break;
   7242         /* options taking size_t-number followed by pointer */
   7243         case MHD_OPTION_DIGEST_AUTH_RANDOM:
   7244         case MHD_OPTION_DIGEST_AUTH_RANDOM_COPY:
   7245           if (MHD_NO == parse_options (daemon,
   7246                                        params,
   7247                                        opt,
   7248                                        (size_t) oa[i].value,
   7249                                        oa[i].ptr_value,
   7250                                        MHD_OPTION_END))
   7251             return MHD_NO;
   7252           break;
   7253         /* options taking socklen_t-number followed by pointer */
   7254         case MHD_OPTION_SOCK_ADDR_LEN:
   7255           if (MHD_NO == parse_options (daemon,
   7256                                        params,
   7257                                        opt,
   7258                                        (socklen_t) oa[i].value,
   7259                                        oa[i].ptr_value,
   7260                                        MHD_OPTION_END))
   7261             return MHD_NO;
   7262           break;
   7263         case MHD_OPTION_END: /* Not possible */
   7264         default:
   7265           return MHD_NO;
   7266         }
   7267         i++;
   7268       }
   7269       break;
   7270     case MHD_OPTION_UNESCAPE_CALLBACK:
   7271       daemon->unescape_callback = va_arg (ap,
   7272                                           UnescapeCallback);
   7273       daemon->unescape_callback_cls = va_arg (ap,
   7274                                               void *);
   7275       break;
   7276 #ifdef HTTPS_SUPPORT
   7277     case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER:
   7278 #if GNUTLS_VERSION_MAJOR >= 3
   7279       daemon->cred_callback = va_arg (ap,
   7280                                       MHD_PskServerCredentialsCallback);
   7281       daemon->cred_callback_cls = va_arg (ap,
   7282                                           void *);
   7283       break;
   7284 #else
   7285       MHD_DLOG (daemon,
   7286                 _ ("MHD HTTPS option %d passed to MHD compiled " \
   7287                    "without GNUtls >= 3.\n"),
   7288                 opt);
   7289       return MHD_NO;
   7290 #endif
   7291 #endif /* HTTPS_SUPPORT */
   7292     case MHD_OPTION_SIGPIPE_HANDLED_BY_APP:
   7293       if (! MHD_D_IS_USING_THREADS_ (daemon))
   7294         daemon->sigpipe_blocked = ( (va_arg (ap,
   7295                                              int)) != 0);
   7296       else
   7297       {
   7298         (void) va_arg (ap,
   7299                        int);
   7300       }
   7301       break;
   7302     case MHD_OPTION_TLS_NO_ALPN:
   7303 #ifdef HTTPS_SUPPORT
   7304       daemon->disable_alpn = (va_arg (ap,
   7305                                       int) != 0);
   7306 #else  /* ! HTTPS_SUPPORT */
   7307       (void) va_arg (ap, int);
   7308 #endif /* ! HTTPS_SUPPORT */
   7309 #ifdef HAVE_MESSAGES
   7310       if (0 == (daemon->options & MHD_USE_TLS))
   7311         MHD_DLOG (daemon,
   7312                   _ ("MHD HTTPS option %d passed to MHD " \
   7313                      "but MHD_USE_TLS not set.\n"),
   7314                   (int) opt);
   7315 #endif /* HAVE_MESSAGES */
   7316       break;
   7317     case MHD_OPTION_APP_FD_SETSIZE:
   7318       params->fdset_size_set = true;
   7319       params->fdset_size = va_arg (ap,
   7320                                    int);
   7321       break;
   7322 #ifndef HTTPS_SUPPORT
   7323     case MHD_OPTION_HTTPS_MEM_KEY:
   7324     case MHD_OPTION_HTTPS_MEM_CERT:
   7325     case MHD_OPTION_HTTPS_CRED_TYPE:
   7326     case MHD_OPTION_HTTPS_PRIORITIES:
   7327     case MHD_OPTION_HTTPS_PRIORITIES_APPEND:
   7328     case MHD_OPTION_HTTPS_MEM_TRUST:
   7329     case MHD_OPTION_HTTPS_CERT_CALLBACK:
   7330     case MHD_OPTION_HTTPS_MEM_DHPARAMS:
   7331     case MHD_OPTION_HTTPS_KEY_PASSWORD:
   7332     case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER:
   7333     case MHD_OPTION_HTTPS_CERT_CALLBACK2:
   7334 #ifdef HAVE_MESSAGES
   7335       MHD_DLOG (daemon,
   7336                 _ ("MHD HTTPS option %d passed to MHD "
   7337                    "compiled without HTTPS support.\n"),
   7338                 opt);
   7339 #endif
   7340       return MHD_NO;
   7341 #endif /* HTTPS_SUPPORT */
   7342     case MHD_OPTION_END: /* Not possible */
   7343     default:
   7344 #ifdef HAVE_MESSAGES
   7345       MHD_DLOG (daemon,
   7346                 _ ("Invalid option %d! (Did you terminate "
   7347                    "the list with MHD_OPTION_END?).\n"),
   7348                 opt);
   7349 #endif
   7350       return MHD_NO;
   7351     }
   7352   }
   7353   return MHD_YES;
   7354 }
   7355 
   7356 
   7357 #ifdef EPOLL_SUPPORT
   7358 static int
   7359 setup_epoll_fd (struct MHD_Daemon *daemon)
   7360 {
   7361   int fd;
   7362 
   7363 #ifndef HAVE_MESSAGES
   7364   (void) daemon; /* Mute compiler warning. */
   7365 #endif /* ! HAVE_MESSAGES */
   7366 
   7367 #ifdef USE_EPOLL_CREATE1
   7368   fd = epoll_create1 (EPOLL_CLOEXEC);
   7369 #else  /* ! USE_EPOLL_CREATE1 */
   7370   fd = epoll_create (MAX_EVENTS);
   7371 #endif /* ! USE_EPOLL_CREATE1 */
   7372   if (MHD_INVALID_SOCKET == fd)
   7373   {
   7374 #ifdef HAVE_MESSAGES
   7375     MHD_DLOG (daemon,
   7376               _ ("Call to epoll_create1 failed: %s\n"),
   7377               MHD_socket_last_strerr_ ());
   7378 #endif
   7379     return MHD_INVALID_SOCKET;
   7380   }
   7381 #if ! defined(USE_EPOLL_CREATE1)
   7382   if (! MHD_socket_noninheritable_ (fd))
   7383   {
   7384 #ifdef HAVE_MESSAGES
   7385     MHD_DLOG (daemon,
   7386               _ ("Failed to set noninheritable mode on epoll FD.\n"));
   7387 #endif
   7388   }
   7389 #endif /* ! USE_EPOLL_CREATE1 */
   7390   return fd;
   7391 }
   7392 
   7393 
   7394 /**
   7395  * Setup epoll() FD for the daemon and initialize it to listen
   7396  * on the listen FD.
   7397  * @remark To be called only from MHD_start_daemon_va()
   7398  *
   7399  * @param daemon daemon to initialize for epoll()
   7400  * @return #MHD_YES on success, #MHD_NO on failure
   7401  */
   7402 static enum MHD_Result
   7403 setup_epoll_to_listen (struct MHD_Daemon *daemon)
   7404 {
   7405   struct epoll_event event;
   7406   MHD_socket ls;
   7407 
   7408   mhd_assert (MHD_D_IS_USING_EPOLL_ (daemon));
   7409   mhd_assert (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION));
   7410   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   7411                (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) || \
   7412                MHD_ITC_IS_VALID_ (daemon->itc) );
   7413   daemon->epoll_fd = setup_epoll_fd (daemon);
   7414   if (! MHD_D_IS_USING_THREADS_ (daemon)
   7415       && (0 != (daemon->options & MHD_USE_AUTO)))
   7416   {
   7417     /* Application requested "MHD_USE_AUTO", probably MHD_get_fdset() will be
   7418        used.
   7419        Make sure that epoll FD is suitable for fd_set.
   7420        Actually, MHD_get_fdset() is allowed for MHD_USE_EPOLL direct,
   7421        but most probably direct requirement for MHD_USE_EPOLL means that
   7422        epoll FD will be used directly. This logic is fuzzy, but better
   7423        than nothing with current MHD API. */
   7424     if (! MHD_D_DOES_SCKT_FIT_FDSET_ (daemon->epoll_fd, daemon))
   7425     {
   7426 #ifdef HAVE_MESSAGES
   7427       MHD_DLOG (daemon,
   7428                 _ ("The epoll FD is too large to be used with fd_set.\n"));
   7429 #endif /* HAVE_MESSAGES */
   7430       return MHD_NO;
   7431     }
   7432   }
   7433   if (-1 == daemon->epoll_fd)
   7434     return MHD_NO;
   7435 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   7436   if (0 != (MHD_ALLOW_UPGRADE & daemon->options))
   7437   {
   7438     daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
   7439     if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd)
   7440       return MHD_NO;
   7441   }
   7442 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   7443   if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
   7444        (! daemon->was_quiesced) )
   7445   {
   7446     event.events = EPOLLIN | EPOLLRDHUP;
   7447     event.data.ptr = daemon;
   7448     if (0 != epoll_ctl (daemon->epoll_fd,
   7449                         EPOLL_CTL_ADD,
   7450                         ls,
   7451                         &event))
   7452     {
   7453 #ifdef HAVE_MESSAGES
   7454       MHD_DLOG (daemon,
   7455                 _ ("Call to epoll_ctl failed: %s\n"),
   7456                 MHD_socket_last_strerr_ ());
   7457 #endif
   7458       return MHD_NO;
   7459     }
   7460     daemon->listen_socket_in_epoll = true;
   7461   }
   7462 
   7463   if (MHD_ITC_IS_VALID_ (daemon->itc))
   7464   {
   7465     event.events = EPOLLIN | EPOLLRDHUP;
   7466     event.data.ptr = _MHD_DROP_CONST (epoll_itc_marker);
   7467     if (0 != epoll_ctl (daemon->epoll_fd,
   7468                         EPOLL_CTL_ADD,
   7469                         MHD_itc_r_fd_ (daemon->itc),
   7470                         &event))
   7471     {
   7472 #ifdef HAVE_MESSAGES
   7473       MHD_DLOG (daemon,
   7474                 _ ("Call to epoll_ctl failed: %s\n"),
   7475                 MHD_socket_last_strerr_ ());
   7476 #endif
   7477       return MHD_NO;
   7478     }
   7479   }
   7480   return MHD_YES;
   7481 }
   7482 
   7483 
   7484 #endif
   7485 
   7486 
   7487 /**
   7488  * Apply interim parameters
   7489  * @param[in,out] d the daemon to use
   7490  * @param[out] ppsockaddr the pointer to store the pointer to 'struct sockaddr'
   7491  *                        if provided by application
   7492  * @param[out] psockaddr_len the size memory area pointed by 'struct sockaddr'
   7493  *                           if provided by application
   7494  * @param[in,out] params the interim parameters to process
   7495  * @return true in case of success,
   7496  *         false in case of critical error (the daemon must be closed).
   7497  */
   7498 static bool
   7499 process_interim_params (struct MHD_Daemon *d,
   7500                         const struct sockaddr **ppsockaddr,
   7501                         socklen_t *psockaddr_len,
   7502                         struct MHD_InterimParams_ *params)
   7503 {
   7504   if (params->fdset_size_set)
   7505   {
   7506     if (0 >= params->fdset_size)
   7507     {
   7508 #ifdef HAVE_MESSAGES
   7509       MHD_DLOG (d,
   7510                 _ ("MHD_OPTION_APP_FD_SETSIZE value (%d) is not positive.\n"),
   7511                 params->fdset_size);
   7512 #endif /* HAVE_MESSAGES */
   7513       return false;
   7514     }
   7515     if (MHD_D_IS_USING_THREADS_ (d))
   7516     {
   7517 #ifdef HAVE_MESSAGES
   7518       MHD_DLOG (d,
   7519                 _ ("MHD_OPTION_APP_FD_SETSIZE is ignored for daemon started " \
   7520                    "with MHD_USE_INTERNAL_POLLING_THREAD.\n"));
   7521 #endif /* HAVE_MESSAGES */
   7522       (void) 0;
   7523     }
   7524     else if (MHD_D_IS_USING_POLL_ (d))
   7525     {
   7526 #ifdef HAVE_MESSAGES
   7527       MHD_DLOG (d,
   7528                 _ ("MHD_OPTION_APP_FD_SETSIZE is ignored for daemon started " \
   7529                    "with MHD_USE_POLL.\n"));
   7530 #endif /* HAVE_MESSAGES */
   7531       (void) 0;
   7532     }
   7533     else
   7534     { /* The daemon without internal threads, external sockets polling */
   7535 #ifndef HAS_FD_SETSIZE_OVERRIDABLE
   7536       if (((int) FD_SETSIZE) != params->fdset_size)
   7537       {
   7538 #ifdef HAVE_MESSAGES
   7539         MHD_DLOG (d,
   7540                   _ ("MHD_OPTION_APP_FD_SETSIZE value (%d) does not match " \
   7541                      "the platform FD_SETSIZE value (%d) and this platform " \
   7542                      "does not support overriding of FD_SETSIZE.\n"),
   7543                   params->fdset_size, (int) FD_SETSIZE);
   7544 #endif /* HAVE_MESSAGES */
   7545         return false;
   7546       }
   7547 #else  /* HAS_FD_SETSIZE_OVERRIDABLE */
   7548       d->fdset_size = params->fdset_size;
   7549       d->fdset_size_set_by_app = true;
   7550 #endif /* HAS_FD_SETSIZE_OVERRIDABLE */
   7551     }
   7552   }
   7553 
   7554   if (params->listen_fd_set)
   7555   {
   7556     if (MHD_INVALID_SOCKET == params->listen_fd)
   7557     {
   7558       (void) 0; /* Use MHD-created socket */
   7559     }
   7560 #ifdef HAS_SIGNED_SOCKET
   7561     else if (0 > params->listen_fd)
   7562     {
   7563 #ifdef HAVE_MESSAGES
   7564       MHD_DLOG (d,
   7565                 _ ("The value provided for MHD_OPTION_LISTEN_SOCKET " \
   7566                    "is invalid.\n"));
   7567 #endif /* HAVE_MESSAGES */
   7568       return false;
   7569     }
   7570 #endif /* HAS_SIGNED_SOCKET */
   7571     else if (0 != (d->options & MHD_USE_NO_LISTEN_SOCKET))
   7572     {
   7573 #ifdef HAVE_MESSAGES
   7574       MHD_DLOG (d,
   7575                 _ ("MHD_OPTION_LISTEN_SOCKET specified for daemon "
   7576                    "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
   7577 #endif /* HAVE_MESSAGES */
   7578       (void) MHD_socket_close_ (params->listen_fd);
   7579       return false;
   7580     }
   7581     else
   7582     {
   7583       d->listen_fd = params->listen_fd;
   7584       d->listen_is_unix = _MHD_UNKNOWN;
   7585 #ifdef MHD_USE_GETSOCKNAME
   7586       d->port = 0;  /* Force use of autodetection */
   7587 #endif /* MHD_USE_GETSOCKNAME */
   7588     }
   7589   }
   7590 
   7591   mhd_assert (! params->server_addr_len_set || params->pserver_addr_set);
   7592   if (params->pserver_addr_set)
   7593   {
   7594     if (NULL == params->pserver_addr)
   7595     {
   7596       /* The size must be zero if set */
   7597       if (params->server_addr_len_set && (0 != params->server_addr_len))
   7598         return false;
   7599       /* Ignore parameter if it is NULL */
   7600     }
   7601     else if (MHD_INVALID_SOCKET != d->listen_fd)
   7602     {
   7603 #ifdef HAVE_MESSAGES
   7604       MHD_DLOG (d,
   7605                 _ ("MHD_OPTION_LISTEN_SOCKET cannot be used together with " \
   7606                    "MHD_OPTION_SOCK_ADDR_LEN or MHD_OPTION_SOCK_ADDR.\n"));
   7607 #endif /* HAVE_MESSAGES */
   7608       return false;
   7609     }
   7610     else if (0 != (d->options & MHD_USE_NO_LISTEN_SOCKET))
   7611     {
   7612 #ifdef HAVE_MESSAGES
   7613       MHD_DLOG (d,
   7614                 _ ("MHD_OPTION_SOCK_ADDR_LEN or MHD_OPTION_SOCK_ADDR " \
   7615                    "specified for daemon with MHD_USE_NO_LISTEN_SOCKET " \
   7616                    "flag set.\n"));
   7617 #endif /* HAVE_MESSAGES */
   7618       if (MHD_INVALID_SOCKET != d->listen_fd)
   7619       {
   7620         (void) MHD_socket_close_ (params->listen_fd);
   7621         params->listen_fd = MHD_INVALID_SOCKET;
   7622       }
   7623       return false;
   7624     }
   7625     else
   7626     {
   7627       *ppsockaddr = params->pserver_addr;
   7628       if (params->server_addr_len_set)
   7629       {
   7630         /* The size must be non-zero if set */
   7631         if (0 == params->server_addr_len)
   7632           return false;
   7633         *psockaddr_len = params->server_addr_len;
   7634       }
   7635       else
   7636         *psockaddr_len = 0;
   7637     }
   7638   }
   7639   return true;
   7640 }
   7641 
   7642 
   7643 /**
   7644  * Start a webserver on the given port.
   7645  *
   7646  * @param flags combination of `enum MHD_FLAG` values
   7647  * @param port port to bind to (in host byte order),
   7648  *        use '0' to bind to random free port,
   7649  *        ignored if #MHD_OPTION_SOCK_ADDR or
   7650  *        #MHD_OPTION_LISTEN_SOCKET is provided
   7651  *        or #MHD_USE_NO_LISTEN_SOCKET is specified
   7652  * @param apc callback to call to check which clients
   7653  *        will be allowed to connect; you can pass NULL
   7654  *        in which case connections from any IP will be
   7655  *        accepted
   7656  * @param apc_cls extra argument to @a apc
   7657  * @param dh handler called for all requests (repeatedly)
   7658  * @param dh_cls extra argument to @a dh
   7659  * @param ap list of options (type-value pairs,
   7660  *        terminated with #MHD_OPTION_END).
   7661  * @return NULL on error, handle to daemon on success
   7662  * @ingroup event
   7663  */
   7664 _MHD_EXTERN struct MHD_Daemon *
   7665 MHD_start_daemon_va (unsigned int flags,
   7666                      uint16_t port,
   7667                      MHD_AcceptPolicyCallback apc,
   7668                      void *apc_cls,
   7669                      MHD_AccessHandlerCallback dh,
   7670                      void *dh_cls,
   7671                      va_list ap)
   7672 {
   7673   const MHD_SCKT_OPT_BOOL_ on = 1;
   7674   struct MHD_Daemon *daemon;
   7675   const struct sockaddr *pservaddr = NULL;
   7676   socklen_t addrlen;
   7677 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   7678   unsigned int i;
   7679 #endif
   7680   enum MHD_FLAG eflags; /* same type as in MHD_Daemon */
   7681   enum MHD_FLAG *pflags;
   7682   struct MHD_InterimParams_ *interim_params;
   7683 
   7684   MHD_check_global_init_ ();
   7685   eflags = (enum MHD_FLAG) flags;
   7686   pflags = &eflags;
   7687 
   7688   if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
   7689     *pflags |= MHD_USE_INTERNAL_POLLING_THREAD; /* Force enable, log warning later if needed */
   7690 
   7691 #ifndef HAVE_INET6
   7692   if (0 != (*pflags & MHD_USE_IPv6))
   7693     return NULL;
   7694 #endif
   7695 #ifndef HAVE_POLL
   7696   if (0 != (*pflags & MHD_USE_POLL))
   7697     return NULL;
   7698 #endif
   7699 #ifndef EPOLL_SUPPORT
   7700   if (0 != (*pflags & MHD_USE_EPOLL))
   7701     return NULL;
   7702 #endif /* ! EPOLL_SUPPORT */
   7703 #ifndef HTTPS_SUPPORT
   7704   if (0 != (*pflags & MHD_USE_TLS))
   7705     return NULL;
   7706 #endif /* ! HTTPS_SUPPORT */
   7707 #ifndef TCP_FASTOPEN
   7708   if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
   7709     return NULL;
   7710 #endif
   7711   if (0 != (*pflags & MHD_ALLOW_UPGRADE))
   7712   {
   7713 #ifdef UPGRADE_SUPPORT
   7714     *pflags |= MHD_ALLOW_SUSPEND_RESUME;
   7715 #else  /* ! UPGRADE_SUPPORT */
   7716     return NULL;
   7717 #endif /* ! UPGRADE_SUPPORT */
   7718   }
   7719 #ifdef MHD_USE_THREADS
   7720   if ((MHD_USE_NO_THREAD_SAFETY | MHD_USE_INTERNAL_POLLING_THREAD) ==
   7721       ((MHD_USE_NO_THREAD_SAFETY | MHD_USE_INTERNAL_POLLING_THREAD)
   7722        & *pflags))
   7723     return NULL; /* Cannot be thread-unsafe with multiple threads */
   7724 #else  /* ! MHD_USE_THREADS */
   7725   if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
   7726     return NULL;
   7727 #endif /* ! MHD_USE_THREADS */
   7728 
   7729   if (NULL == dh)
   7730     return NULL;
   7731 
   7732   /* Check for invalid combinations of flags. */
   7733   if ((0 != (*pflags & MHD_USE_POLL)) && (0 != (*pflags & MHD_USE_EPOLL)))
   7734     return NULL;
   7735   if ((0 != (*pflags & MHD_USE_EPOLL)) &&
   7736       (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)))
   7737     return NULL;
   7738   if ((0 != (*pflags & MHD_USE_POLL)) &&
   7739       (0 == (*pflags & (MHD_USE_INTERNAL_POLLING_THREAD
   7740                         | MHD_USE_THREAD_PER_CONNECTION))))
   7741     return NULL;
   7742   if ((0 != (*pflags & MHD_USE_AUTO)) &&
   7743       (0 != (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))))
   7744     return NULL;
   7745 
   7746   if (0 != (*pflags & MHD_USE_AUTO))
   7747   {
   7748 #if defined(EPOLL_SUPPORT) && defined(HAVE_POLL)
   7749     if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
   7750       *pflags |= MHD_USE_POLL;
   7751     else
   7752       *pflags |= MHD_USE_EPOLL; /* Including "external select" mode */
   7753 #elif defined(HAVE_POLL)
   7754     if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
   7755       *pflags |= MHD_USE_POLL; /* Including thread-per-connection */
   7756 #elif defined(EPOLL_SUPPORT)
   7757     if (0 == (*pflags & MHD_USE_THREAD_PER_CONNECTION))
   7758       *pflags |= MHD_USE_EPOLL; /* Including "external select" mode */
   7759 #else
   7760     /* No choice: use select() for any mode - do not modify flags */
   7761 #endif
   7762   }
   7763 
   7764   if (0 != (*pflags & MHD_USE_NO_THREAD_SAFETY))
   7765     *pflags = (*pflags & ~((enum MHD_FLAG) MHD_USE_ITC)); /* useless in single-threaded environment */
   7766   else if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
   7767   {
   7768 #ifdef HAVE_LISTEN_SHUTDOWN
   7769     if (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET))
   7770 #endif
   7771     *pflags |= MHD_USE_ITC;       /* yes, must use ITC to signal thread */
   7772   }
   7773 
   7774   if (NULL == (daemon = MHD_calloc_ (1, sizeof (struct MHD_Daemon))))
   7775     return NULL;
   7776   interim_params = (struct MHD_InterimParams_ *) \
   7777                    MHD_calloc_ (1, sizeof (struct MHD_InterimParams_));
   7778   if (NULL == interim_params)
   7779   {
   7780     int err_num = errno;
   7781     free (daemon);
   7782     errno = err_num;
   7783     return NULL;
   7784   }
   7785 #ifdef EPOLL_SUPPORT
   7786   daemon->epoll_fd = -1;
   7787 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   7788   daemon->epoll_upgrade_fd = -1;
   7789 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   7790 #endif
   7791   /* try to open listen socket */
   7792 #ifdef HTTPS_SUPPORT
   7793   daemon->priority_cache = NULL;
   7794 #endif /* HTTPS_SUPPORT */
   7795   daemon->listen_fd = MHD_INVALID_SOCKET;
   7796   daemon->listen_is_unix = _MHD_NO;
   7797   daemon->listening_address_reuse = 0;
   7798   daemon->options = *pflags;
   7799   pflags = &daemon->options;
   7800   daemon->client_discipline = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ?
   7801                               1 : 0;
   7802   daemon->port = port;
   7803   daemon->apc = apc;
   7804   daemon->apc_cls = apc_cls;
   7805   daemon->default_handler = dh;
   7806   daemon->default_handler_cls = dh_cls;
   7807   daemon->connections = 0;
   7808   daemon->connection_limit = MHD_MAX_CONNECTIONS_DEFAULT;
   7809   daemon->pool_size = MHD_POOL_SIZE_DEFAULT;
   7810   daemon->pool_increment = MHD_BUF_INC_SIZE;
   7811   daemon->unescape_callback = &unescape_wrapper;
   7812   daemon->connection_timeout_ms = 0;       /* no timeout */
   7813   MHD_itc_set_invalid_ (daemon->itc);
   7814 #ifdef MHD_USE_THREADS
   7815   MHD_thread_handle_ID_set_invalid_ (&daemon->tid);
   7816 #endif /* MHD_USE_THREADS */
   7817 #ifdef SOMAXCONN
   7818   daemon->listen_backlog_size = SOMAXCONN;
   7819 #else  /* !SOMAXCONN */
   7820   daemon->listen_backlog_size = 511; /* should be safe value */
   7821 #endif /* !SOMAXCONN */
   7822 #ifdef HAVE_MESSAGES
   7823   daemon->custom_error_log = &MHD_default_logger_;
   7824   daemon->custom_error_log_cls = stderr;
   7825 #endif
   7826 #ifndef MHD_WINSOCK_SOCKETS
   7827   daemon->sigpipe_blocked = false;
   7828 #else  /* MHD_WINSOCK_SOCKETS */
   7829   /* There is no SIGPIPE on W32, nothing to block. */
   7830   daemon->sigpipe_blocked = true;
   7831 #endif /* _WIN32 && ! __CYGWIN__ */
   7832 #if defined(_DEBUG) && defined(HAVE_ACCEPT4)
   7833   daemon->avoid_accept4 = false;
   7834 #endif /* _DEBUG */
   7835 #ifdef HAS_FD_SETSIZE_OVERRIDABLE
   7836   daemon->fdset_size = (int) FD_SETSIZE;
   7837   daemon->fdset_size_set_by_app = false;
   7838 #endif /* HAS_FD_SETSIZE_OVERRIDABLE */
   7839 
   7840 #ifdef DAUTH_SUPPORT
   7841   daemon->digest_auth_rand_size = 0;
   7842   daemon->digest_auth_random = NULL;
   7843   daemon->nonce_nc_size = 4; /* tiny */
   7844   daemon->dauth_def_nonce_timeout = MHD_DAUTH_DEF_TIMEOUT_;
   7845   daemon->dauth_def_max_nc = MHD_DAUTH_DEF_MAX_NC_;
   7846 #endif
   7847 #ifdef HTTPS_SUPPORT
   7848   if (0 != (*pflags & MHD_USE_TLS))
   7849   {
   7850     daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
   7851   }
   7852 #endif /* HTTPS_SUPPORT */
   7853 
   7854   interim_params->num_opts = 0;
   7855   interim_params->fdset_size_set = false;
   7856   interim_params->fdset_size = 0;
   7857   interim_params->listen_fd_set = false;
   7858   interim_params->listen_fd = MHD_INVALID_SOCKET;
   7859   interim_params->pserver_addr_set = false;
   7860   interim_params->pserver_addr = NULL;
   7861   interim_params->server_addr_len_set = false;
   7862   interim_params->server_addr_len = 0;
   7863 
   7864   if (MHD_NO == parse_options_va (daemon,
   7865                                   interim_params,
   7866                                   ap))
   7867   {
   7868 #ifdef HTTPS_SUPPORT
   7869     if ( (0 != (*pflags & MHD_USE_TLS)) &&
   7870          (NULL != daemon->priority_cache) )
   7871       gnutls_priority_deinit (daemon->priority_cache);
   7872 #endif /* HTTPS_SUPPORT */
   7873     free (interim_params);
   7874     free (daemon);
   7875     return NULL;
   7876   }
   7877   if (! process_interim_params (daemon,
   7878                                 &pservaddr,
   7879                                 &addrlen,
   7880                                 interim_params))
   7881   {
   7882     free (interim_params);
   7883     free (daemon);
   7884     return NULL;
   7885   }
   7886   free (interim_params);
   7887   interim_params = NULL;
   7888 #ifdef HTTPS_SUPPORT
   7889   if ((0 != (*pflags & MHD_USE_TLS))
   7890       && (NULL == daemon->priority_cache)
   7891       && ! daemon_tls_priorities_init_default (daemon))
   7892   {
   7893 #ifdef HAVE_MESSAGES
   7894     MHD_DLOG (daemon,
   7895               _ ("Failed to initialise GnuTLS priorities.\n"));
   7896 #endif /* HAVE_MESSAGES */
   7897     free (daemon);
   7898     return NULL;
   7899   }
   7900 #endif /* HTTPS_SUPPORT */
   7901 
   7902 #ifdef HAVE_MESSAGES
   7903   if ( (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) &&
   7904        (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD)) )
   7905   {
   7906     MHD_DLOG (daemon,
   7907               _ ("Warning: MHD_USE_THREAD_PER_CONNECTION must be used " \
   7908                  "only with MHD_USE_INTERNAL_POLLING_THREAD. " \
   7909                  "Flag MHD_USE_INTERNAL_POLLING_THREAD was added. " \
   7910                  "Consider setting MHD_USE_INTERNAL_POLLING_THREAD " \
   7911                  "explicitly.\n"));
   7912   }
   7913 #endif
   7914 
   7915   if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)
   7916       && ((NULL != daemon->notify_completed)
   7917           || (NULL != daemon->notify_connection)) )
   7918     *pflags |= MHD_USE_ITC; /* requires ITC */
   7919 
   7920 #ifdef _DEBUG
   7921 #ifdef HAVE_MESSAGES
   7922   MHD_DLOG (daemon,
   7923             _ ("Using debug build of libmicrohttpd.\n") );
   7924 #endif /* HAVE_MESSAGES */
   7925 #endif /* _DEBUG */
   7926 
   7927   if ( (0 != (*pflags & MHD_USE_ITC))
   7928 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   7929        && (0 == daemon->worker_pool_size)
   7930 #endif
   7931        )
   7932   {
   7933     if (! MHD_itc_init_ (daemon->itc))
   7934     {
   7935 #ifdef HAVE_MESSAGES
   7936       MHD_DLOG (daemon,
   7937                 _ ("Failed to create inter-thread communication channel: %s\n"),
   7938                 MHD_itc_last_strerror_ ());
   7939 #endif
   7940 #ifdef HTTPS_SUPPORT
   7941       if (NULL != daemon->priority_cache)
   7942         gnutls_priority_deinit (daemon->priority_cache);
   7943 #endif /* HTTPS_SUPPORT */
   7944       free (daemon);
   7945       return NULL;
   7946     }
   7947     if (MHD_D_IS_USING_SELECT_ (daemon) &&
   7948         (! MHD_D_DOES_SCKT_FIT_FDSET_ (MHD_itc_r_fd_ (daemon->itc), daemon)) )
   7949     {
   7950 #ifdef HAVE_MESSAGES
   7951       MHD_DLOG (daemon,
   7952                 _ ("file descriptor for inter-thread communication " \
   7953                    "channel exceeds maximum value.\n"));
   7954 #endif
   7955       MHD_itc_destroy_chk_ (daemon->itc);
   7956 #ifdef HTTPS_SUPPORT
   7957       if (NULL != daemon->priority_cache)
   7958         gnutls_priority_deinit (daemon->priority_cache);
   7959 #endif /* HTTPS_SUPPORT */
   7960       free (daemon);
   7961       return NULL;
   7962     }
   7963   }
   7964 
   7965 #ifdef DAUTH_SUPPORT
   7966   if (NULL != daemon->digest_auth_random_copy)
   7967   {
   7968     mhd_assert (daemon == daemon->digest_auth_random_copy);
   7969     daemon->digest_auth_random_copy = malloc (daemon->digest_auth_rand_size);
   7970     if (NULL == daemon->digest_auth_random_copy)
   7971     {
   7972 #ifdef HTTPS_SUPPORT
   7973       if (0 != (*pflags & MHD_USE_TLS))
   7974         gnutls_priority_deinit (daemon->priority_cache);
   7975 #endif /* HTTPS_SUPPORT */
   7976       free (daemon);
   7977       return NULL;
   7978     }
   7979     memcpy (daemon->digest_auth_random_copy,
   7980             daemon->digest_auth_random,
   7981             daemon->digest_auth_rand_size);
   7982     daemon->digest_auth_random = daemon->digest_auth_random_copy;
   7983   }
   7984   if (daemon->nonce_nc_size > 0)
   7985   {
   7986     if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc)))
   7987          / sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size)
   7988     {
   7989 #ifdef HAVE_MESSAGES
   7990       MHD_DLOG (daemon,
   7991                 _ ("Specified value for NC_SIZE too large.\n"));
   7992 #endif
   7993 #ifdef HTTPS_SUPPORT
   7994       if (0 != (*pflags & MHD_USE_TLS))
   7995         gnutls_priority_deinit (daemon->priority_cache);
   7996 #endif /* HTTPS_SUPPORT */
   7997       free (daemon->digest_auth_random_copy);
   7998       free (daemon);
   7999       return NULL;
   8000     }
   8001     daemon->nnc = MHD_calloc_ (daemon->nonce_nc_size,
   8002                                sizeof (struct MHD_NonceNc));
   8003     if (NULL == daemon->nnc)
   8004     {
   8005 #ifdef HAVE_MESSAGES
   8006       MHD_DLOG (daemon,
   8007                 _ ("Failed to allocate memory for nonce-nc map: %s\n"),
   8008                 MHD_strerror_ (errno));
   8009 #endif
   8010 #ifdef HTTPS_SUPPORT
   8011       if (0 != (*pflags & MHD_USE_TLS))
   8012         gnutls_priority_deinit (daemon->priority_cache);
   8013 #endif /* HTTPS_SUPPORT */
   8014       free (daemon->digest_auth_random_copy);
   8015       free (daemon);
   8016       return NULL;
   8017     }
   8018   }
   8019 
   8020 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8021   if (! MHD_mutex_init_ (&daemon->nnc_lock))
   8022   {
   8023 #ifdef HAVE_MESSAGES
   8024     MHD_DLOG (daemon,
   8025               _ ("MHD failed to initialize nonce-nc mutex.\n"));
   8026 #endif
   8027 #ifdef HTTPS_SUPPORT
   8028     if (0 != (*pflags & MHD_USE_TLS))
   8029       gnutls_priority_deinit (daemon->priority_cache);
   8030 #endif /* HTTPS_SUPPORT */
   8031     free (daemon->digest_auth_random_copy);
   8032     free (daemon->nnc);
   8033     free (daemon);
   8034     return NULL;
   8035   }
   8036 #endif
   8037 #endif
   8038 
   8039   /* Thread polling currently works only with internal select thread mode */
   8040 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8041   if ( (! MHD_D_IS_USING_THREADS_ (daemon)) &&
   8042        (daemon->worker_pool_size > 0) )
   8043   {
   8044 #ifdef HAVE_MESSAGES
   8045     MHD_DLOG (daemon,
   8046               _ ("MHD thread polling only works with " \
   8047                  "MHD_USE_INTERNAL_POLLING_THREAD.\n"));
   8048 #endif
   8049     goto free_and_fail;
   8050   }
   8051 #endif
   8052 
   8053   if ( (MHD_INVALID_SOCKET == daemon->listen_fd) &&
   8054        (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
   8055   {
   8056     /* try to open listen socket */
   8057     struct sockaddr_in servaddr4;
   8058 #ifdef HAVE_INET6
   8059     struct sockaddr_in6 servaddr6;
   8060     const bool use_ipv6 = (0 != (*pflags & MHD_USE_IPv6));
   8061 #else  /* ! HAVE_INET6 */
   8062     const bool use_ipv6 = false;
   8063 #endif /* ! HAVE_INET6 */
   8064     int domain;
   8065 
   8066     if (NULL != pservaddr)
   8067     {
   8068 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
   8069       const socklen_t sa_len = pservaddr->sa_len;
   8070 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
   8071 #ifdef HAVE_INET6
   8072       if (use_ipv6 && (AF_INET6 != pservaddr->sa_family))
   8073       {
   8074 #ifdef HAVE_MESSAGES
   8075         MHD_DLOG (daemon,
   8076                   _ ("MHD_USE_IPv6 is enabled, but 'struct sockaddr *' " \
   8077                      "specified for MHD_OPTION_SOCK_ADDR_LEN or " \
   8078                      "MHD_OPTION_SOCK_ADDR is not IPv6 address.\n"));
   8079 #endif /* HAVE_MESSAGES */
   8080         goto free_and_fail;
   8081       }
   8082 #endif /* HAVE_INET6 */
   8083       switch (pservaddr->sa_family)
   8084       {
   8085       case AF_INET:
   8086         if (1)
   8087         {
   8088           struct sockaddr_in sa4;
   8089           uint16_t sa4_port;
   8090           if ((0 != addrlen)
   8091               && (((socklen_t) sizeof(sa4)) > addrlen))
   8092           {
   8093 #ifdef HAVE_MESSAGES
   8094             MHD_DLOG (daemon,
   8095                       _ ("The size specified for MHD_OPTION_SOCK_ADDR_LEN " \
   8096                          "option is wrong.\n"));
   8097 #endif /* HAVE_MESSAGES */
   8098             goto free_and_fail;
   8099           }
   8100 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
   8101           if (0 != sa_len)
   8102           {
   8103             if (((socklen_t) sizeof(sa4)) > sa_len)
   8104             {
   8105 #ifdef HAVE_MESSAGES
   8106               MHD_DLOG (daemon,
   8107                         _ ("The value of 'struct sockaddr.sa_len' provided " \
   8108                            "via MHD_OPTION_SOCK_ADDR_LEN option is not zero " \
   8109                            "and does not match 'sa_family' value of the " \
   8110                            "same structure.\n"));
   8111 #endif /* HAVE_MESSAGES */
   8112               goto free_and_fail;
   8113             }
   8114             if ((0 == addrlen) || (sa_len < addrlen))
   8115               addrlen = sa_len; /* Use smaller value for safety */
   8116           }
   8117 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
   8118           if (0 == addrlen)
   8119             addrlen = sizeof(sa4);
   8120           memcpy (&sa4, pservaddr, sizeof(sa4));  /* Required due to stronger alignment */
   8121           sa4_port = (uint16_t) ntohs (sa4.sin_port);
   8122 #ifndef MHD_USE_GETSOCKNAME
   8123           if (0 != sa4_port)
   8124 #endif /* ! MHD_USE_GETSOCKNAME */
   8125           daemon->port = sa4_port;
   8126           domain = PF_INET;
   8127         }
   8128         break;
   8129 #ifdef HAVE_INET6
   8130       case AF_INET6:
   8131         if (1)
   8132         {
   8133           struct sockaddr_in6 sa6;
   8134           uint16_t sa6_port;
   8135           if ((0 != addrlen)
   8136               && (((socklen_t) sizeof(sa6)) > addrlen))
   8137           {
   8138 #ifdef HAVE_MESSAGES
   8139             MHD_DLOG (daemon,
   8140                       _ ("The size specified for MHD_OPTION_SOCK_ADDR_LEN " \
   8141                          "option is wrong.\n"));
   8142 #endif /* HAVE_MESSAGES */
   8143             goto free_and_fail;
   8144           }
   8145 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
   8146           if (0 != sa_len)
   8147           {
   8148             if (((socklen_t) sizeof(sa6)) > sa_len)
   8149             {
   8150 #ifdef HAVE_MESSAGES
   8151               MHD_DLOG (daemon,
   8152                         _ ("The value of 'struct sockaddr.sa_len' provided " \
   8153                            "via MHD_OPTION_SOCK_ADDR_LEN option is not zero " \
   8154                            "and does not match 'sa_family' value of the " \
   8155                            "same structure.\n"));
   8156 #endif /* HAVE_MESSAGES */
   8157               goto free_and_fail;
   8158             }
   8159             if ((0 == addrlen) || (sa_len < addrlen))
   8160               addrlen = sa_len; /* Use smaller value for safety */
   8161           }
   8162 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
   8163           if (0 == addrlen)
   8164             addrlen = sizeof(sa6);
   8165           memcpy (&sa6, pservaddr, sizeof(sa6));  /* Required due to stronger alignment */
   8166           sa6_port = (uint16_t) ntohs (sa6.sin6_port);
   8167 #ifndef MHD_USE_GETSOCKNAME
   8168           if (0 != sa6_port)
   8169 #endif /* ! MHD_USE_GETSOCKNAME */
   8170           daemon->port = sa6_port;
   8171           domain = PF_INET6;
   8172           *pflags |= ((enum MHD_FLAG) MHD_USE_IPv6);
   8173         }
   8174         break;
   8175 #endif /* HAVE_INET6 */
   8176 #ifdef AF_UNIX
   8177       case AF_UNIX:
   8178 #endif /* AF_UNIX */
   8179       default:
   8180 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
   8181         if (0 == addrlen)
   8182           addrlen = sa_len;
   8183         else if ((0 != sa_len) && (sa_len < addrlen))
   8184           addrlen = sa_len; /* Use smaller value for safety */
   8185 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
   8186         if (0 >= addrlen)
   8187         {
   8188 #ifdef HAVE_MESSAGES
   8189           MHD_DLOG (daemon,
   8190                     _ ("The 'sa_family' of the 'struct sockaddr' provided " \
   8191                        "via MHD_OPTION_SOCK_ADDR option is not supported.\n"));
   8192 #endif /* HAVE_MESSAGES */
   8193           goto free_and_fail;
   8194         }
   8195 #ifdef AF_UNIX
   8196         if (AF_UNIX == pservaddr->sa_family)
   8197         {
   8198           daemon->port = 0;     /* special value for UNIX domain sockets */
   8199           daemon->listen_is_unix = _MHD_YES;
   8200 #ifdef PF_UNIX
   8201           domain = PF_UNIX;
   8202 #else /* ! PF_UNIX */
   8203           domain = AF_UNIX;
   8204 #endif /* ! PF_UNIX */
   8205         }
   8206         else /* combined with the next 'if' */
   8207 #endif /* AF_UNIX */
   8208         if (1)
   8209         {
   8210           daemon->port = 0;     /* ugh */
   8211           daemon->listen_is_unix = _MHD_UNKNOWN;
   8212           /* Assumed the same values for AF_* and PF_* */
   8213           domain = pservaddr->sa_family;
   8214         }
   8215         break;
   8216       }
   8217     }
   8218     else
   8219     {
   8220       if (! use_ipv6)
   8221       {
   8222         memset (&servaddr4,
   8223                 0,
   8224                 sizeof (struct sockaddr_in));
   8225         servaddr4.sin_family = AF_INET;
   8226         servaddr4.sin_port = htons (port);
   8227         if (0 != INADDR_ANY)
   8228           servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
   8229 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
   8230         servaddr4.sin_len = sizeof (struct sockaddr_in);
   8231 #endif
   8232         pservaddr = (struct sockaddr *) &servaddr4;
   8233         addrlen = (socklen_t) sizeof(servaddr4);
   8234         daemon->listen_is_unix = _MHD_NO;
   8235         domain = PF_INET;
   8236       }
   8237 #ifdef HAVE_INET6
   8238       else
   8239       {
   8240 #ifdef IN6ADDR_ANY_INIT
   8241         static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
   8242 #endif
   8243         memset (&servaddr6,
   8244                 0,
   8245                 sizeof (struct sockaddr_in6));
   8246         servaddr6.sin6_family = AF_INET6;
   8247         servaddr6.sin6_port = htons (port);
   8248 #ifdef IN6ADDR_ANY_INIT
   8249         servaddr6.sin6_addr = static_in6any;
   8250 #endif
   8251 #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
   8252         servaddr6.sin6_len = sizeof (struct sockaddr_in6);
   8253 #endif
   8254         pservaddr = (struct sockaddr *) &servaddr6;
   8255         addrlen = (socklen_t) sizeof (servaddr6);
   8256         daemon->listen_is_unix = _MHD_NO;
   8257         domain = PF_INET6;
   8258       }
   8259 #endif /* HAVE_INET6 */
   8260     }
   8261 
   8262     daemon->listen_fd = MHD_socket_create_listen_ (domain);
   8263     if (MHD_INVALID_SOCKET == daemon->listen_fd)
   8264     {
   8265 #ifdef HAVE_MESSAGES
   8266       MHD_DLOG (daemon,
   8267                 _ ("Failed to create socket for listening: %s\n"),
   8268                 MHD_socket_last_strerr_ ());
   8269 #endif
   8270       goto free_and_fail;
   8271     }
   8272     if (MHD_D_IS_USING_SELECT_ (daemon) &&
   8273         (! MHD_D_DOES_SCKT_FIT_FDSET_ (daemon->listen_fd,
   8274                                        daemon)) )
   8275     {
   8276 #ifdef HAVE_MESSAGES
   8277       MHD_DLOG (daemon,
   8278                 _ ("Listen socket descriptor (%d) is not " \
   8279                    "less than daemon FD_SETSIZE value (%d).\n"),
   8280                 (int) daemon->listen_fd,
   8281                 (int) MHD_D_GET_FD_SETSIZE_ (daemon));
   8282 #endif
   8283       goto free_and_fail;
   8284     }
   8285 
   8286     /* Apply the socket options according to listening_address_reuse. */
   8287     if (0 == daemon->listening_address_reuse)
   8288     {
   8289 #ifndef MHD_WINSOCK_SOCKETS
   8290       /* No user requirement, use "traditional" default SO_REUSEADDR
   8291        * on non-W32 platforms, and do not fail if it doesn't work.
   8292        * Don't use it on W32, because on W32 it will allow multiple
   8293        * bind to the same address:port, like SO_REUSEPORT on others. */
   8294       if (0 > setsockopt (daemon->listen_fd,
   8295                           SOL_SOCKET,
   8296                           SO_REUSEADDR,
   8297                           (const void *) &on, sizeof (on)))
   8298       {
   8299 #ifdef HAVE_MESSAGES
   8300         MHD_DLOG (daemon,
   8301                   _ ("setsockopt failed: %s\n"),
   8302                   MHD_socket_last_strerr_ ());
   8303 #endif
   8304       }
   8305 #endif /* ! MHD_WINSOCK_SOCKETS */
   8306     }
   8307     else if (daemon->listening_address_reuse > 0)
   8308     {
   8309       /* User requested to allow reusing listening address:port. */
   8310 #ifndef MHD_WINSOCK_SOCKETS
   8311       /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if
   8312        * it doesn't work. */
   8313       if (0 > setsockopt (daemon->listen_fd,
   8314                           SOL_SOCKET,
   8315                           SO_REUSEADDR,
   8316                           (const void *) &on, sizeof (on)))
   8317       {
   8318 #ifdef HAVE_MESSAGES
   8319         MHD_DLOG (daemon,
   8320                   _ ("setsockopt failed: %s\n"),
   8321                   MHD_socket_last_strerr_ ());
   8322 #endif
   8323       }
   8324 #endif /* ! MHD_WINSOCK_SOCKETS */
   8325       /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
   8326        * Fail if SO_REUSEPORT is not defined or setsockopt fails.
   8327        */
   8328       /* SO_REUSEADDR on W32 has the same semantics
   8329          as SO_REUSEPORT on BSD/Linux */
   8330 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
   8331       if (0 > setsockopt (daemon->listen_fd,
   8332                           SOL_SOCKET,
   8333 #ifndef MHD_WINSOCK_SOCKETS
   8334                           SO_REUSEPORT,
   8335 #else  /* MHD_WINSOCK_SOCKETS */
   8336                           SO_REUSEADDR,
   8337 #endif /* MHD_WINSOCK_SOCKETS */
   8338                           (const void *) &on,
   8339                           sizeof (on)))
   8340       {
   8341 #ifdef HAVE_MESSAGES
   8342         MHD_DLOG (daemon,
   8343                   _ ("setsockopt failed: %s\n"),
   8344                   MHD_socket_last_strerr_ ());
   8345 #endif
   8346         goto free_and_fail;
   8347       }
   8348 #else  /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
   8349       /* we're supposed to allow address:port re-use, but
   8350          on this platform we cannot; fail hard */
   8351 #ifdef HAVE_MESSAGES
   8352       MHD_DLOG (daemon,
   8353                 _ ("Cannot allow listening address reuse: " \
   8354                    "SO_REUSEPORT not defined.\n"));
   8355 #endif
   8356       goto free_and_fail;
   8357 #endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
   8358     }
   8359     else   /* if (daemon->listening_address_reuse < 0) */
   8360     {
   8361       /* User requested to disallow reusing listening address:port.
   8362        * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
   8363        * is used and Solaris with SO_EXCLBIND.
   8364        * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE
   8365        * or setsockopt fails.
   8366        */
   8367 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \
   8368       (defined(__sun) && defined(SO_EXCLBIND))
   8369       if (0 > setsockopt (daemon->listen_fd,
   8370                           SOL_SOCKET,
   8371 #ifdef SO_EXCLUSIVEADDRUSE
   8372                           SO_EXCLUSIVEADDRUSE,
   8373 #else  /* SO_EXCLBIND */
   8374                           SO_EXCLBIND,
   8375 #endif /* SO_EXCLBIND */
   8376                           (const void *) &on,
   8377                           sizeof (on)))
   8378       {
   8379 #ifdef HAVE_MESSAGES
   8380         MHD_DLOG (daemon,
   8381                   _ ("setsockopt failed: %s\n"),
   8382                   MHD_socket_last_strerr_ ());
   8383 #endif
   8384         goto free_and_fail;
   8385       }
   8386 #elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */
   8387 #ifdef HAVE_MESSAGES
   8388       MHD_DLOG (daemon,
   8389                 _ ("Cannot disallow listening address reuse: " \
   8390                    "SO_EXCLUSIVEADDRUSE not defined.\n"));
   8391 #endif
   8392       goto free_and_fail;
   8393 #endif /* MHD_WINSOCK_SOCKETS */
   8394     }
   8395 
   8396     /* check for user supplied sockaddr */
   8397     if (0 != (*pflags & MHD_USE_IPv6))
   8398     {
   8399 #ifdef IPPROTO_IPV6
   8400 #ifdef IPV6_V6ONLY
   8401       /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
   8402          (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
   8403          and may also be missing on older POSIX systems; good luck if you have any of those,
   8404          your IPv6 socket may then also bind against IPv4 anyway... */
   8405       const MHD_SCKT_OPT_BOOL_ v6_only =
   8406         (MHD_USE_DUAL_STACK != (*pflags & MHD_USE_DUAL_STACK));
   8407       if (0 > setsockopt (daemon->listen_fd,
   8408                           IPPROTO_IPV6, IPV6_V6ONLY,
   8409                           (const void *) &v6_only,
   8410                           sizeof (v6_only)))
   8411       {
   8412 #ifdef HAVE_MESSAGES
   8413         MHD_DLOG (daemon,
   8414                   _ ("setsockopt failed: %s\n"),
   8415                   MHD_socket_last_strerr_ ());
   8416 #endif
   8417       }
   8418 #endif
   8419 #endif
   8420     }
   8421     if (0 != bind (daemon->listen_fd,
   8422                    pservaddr,
   8423                    addrlen))
   8424     {
   8425 #ifdef HAVE_MESSAGES
   8426       MHD_DLOG (daemon,
   8427                 _ ("Failed to bind to port %u: %s\n"),
   8428                 (unsigned int) port,
   8429                 MHD_socket_last_strerr_ ());
   8430 #endif
   8431       goto free_and_fail;
   8432     }
   8433 #ifdef TCP_FASTOPEN
   8434     if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
   8435     {
   8436       if (0 == daemon->fastopen_queue_size)
   8437         daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
   8438       if (0 != setsockopt (daemon->listen_fd,
   8439                            IPPROTO_TCP,
   8440                            TCP_FASTOPEN,
   8441                            (const void *) &daemon->fastopen_queue_size,
   8442                            sizeof (daemon->fastopen_queue_size)))
   8443       {
   8444 #ifdef HAVE_MESSAGES
   8445         MHD_DLOG (daemon,
   8446                   _ ("setsockopt failed: %s\n"),
   8447                   MHD_socket_last_strerr_ ());
   8448 #endif
   8449       }
   8450     }
   8451 #endif
   8452     if (0 != listen (daemon->listen_fd,
   8453                      (int) daemon->listen_backlog_size))
   8454     {
   8455 #ifdef HAVE_MESSAGES
   8456       MHD_DLOG (daemon,
   8457                 _ ("Failed to listen for connections: %s\n"),
   8458                 MHD_socket_last_strerr_ ());
   8459 #endif
   8460       goto free_and_fail;
   8461     }
   8462   }
   8463   else
   8464   {
   8465     if (MHD_D_IS_USING_SELECT_ (daemon) &&
   8466         (! MHD_D_DOES_SCKT_FIT_FDSET_ (daemon->listen_fd,
   8467                                        daemon)) )
   8468     {
   8469 #ifdef HAVE_MESSAGES
   8470       MHD_DLOG (daemon,
   8471                 _ ("Listen socket descriptor (%d) is not " \
   8472                    "less than daemon FD_SETSIZE value (%d).\n"),
   8473                 (int) daemon->listen_fd,
   8474                 (int) MHD_D_GET_FD_SETSIZE_ (daemon));
   8475 #endif
   8476       goto free_and_fail;
   8477     }
   8478     else
   8479     {
   8480 #if defined(SOL_SOCKET) && (defined(SO_DOMAIN) || defined(SO_PROTOCOL_INFOW))
   8481       int af;
   8482       int opt_name;
   8483       void *poptval;
   8484       socklen_t optval_size;
   8485 #ifdef SO_DOMAIN
   8486       opt_name = SO_DOMAIN;
   8487       poptval = &af;
   8488       optval_size = (socklen_t) sizeof (af);
   8489 #else  /* SO_PROTOCOL_INFOW */
   8490       WSAPROTOCOL_INFOW prot_info;
   8491       opt_name = SO_PROTOCOL_INFOW;
   8492       poptval = &prot_info;
   8493       optval_size = (socklen_t) sizeof (prot_info);
   8494 #endif /* SO_PROTOCOL_INFOW */
   8495 
   8496       if (0 == getsockopt (daemon->listen_fd,
   8497                            SOL_SOCKET,
   8498                            opt_name,
   8499                            poptval,
   8500                            &optval_size))
   8501       {
   8502 #ifndef SO_DOMAIN
   8503         af = prot_info.iAddressFamily;
   8504 #endif /* SO_DOMAIN */
   8505         switch (af)
   8506         {
   8507         case AF_INET:
   8508           daemon->listen_is_unix = _MHD_NO;
   8509           break;
   8510 #ifdef HAVE_INET6
   8511         case AF_INET6:
   8512           *pflags |= MHD_USE_IPv6;
   8513           daemon->listen_is_unix = _MHD_NO;
   8514           break;
   8515 #endif /* HAVE_INET6 */
   8516 #ifdef AF_UNIX
   8517         case AF_UNIX:
   8518           daemon->port = 0;     /* special value for UNIX domain sockets */
   8519           daemon->listen_is_unix = _MHD_YES;
   8520           break;
   8521 #endif /* AF_UNIX */
   8522         default:
   8523           daemon->port = 0;     /* ugh */
   8524           daemon->listen_is_unix = _MHD_UNKNOWN;
   8525           break;
   8526         }
   8527       }
   8528       else
   8529 #endif /* SOL_SOCKET && (SO_DOMAIN || SO_PROTOCOL_INFOW)) */
   8530       daemon->listen_is_unix = _MHD_UNKNOWN;
   8531     }
   8532 
   8533 #ifdef MHD_USE_GETSOCKNAME
   8534     daemon->port = 0;  /* Force use of autodetection */
   8535 #endif /* MHD_USE_GETSOCKNAME */
   8536   }
   8537 
   8538 #ifdef MHD_USE_GETSOCKNAME
   8539   if ( (0 == daemon->port) &&
   8540        (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) &&
   8541        (_MHD_YES != daemon->listen_is_unix) )
   8542   {   /* Get port number. */
   8543     struct sockaddr_storage bindaddr;
   8544 
   8545     memset (&bindaddr,
   8546             0,
   8547             sizeof (struct sockaddr_storage));
   8548     addrlen = sizeof (struct sockaddr_storage);
   8549 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
   8550     bindaddr.ss_len = (socklen_t) addrlen;
   8551 #endif
   8552     if (0 != getsockname (daemon->listen_fd,
   8553                           (struct sockaddr *) &bindaddr,
   8554                           &addrlen))
   8555     {
   8556 #ifdef HAVE_MESSAGES
   8557       MHD_DLOG (daemon,
   8558                 _ ("Failed to get listen port number: %s\n"),
   8559                 MHD_socket_last_strerr_ ());
   8560 #endif /* HAVE_MESSAGES */
   8561     }
   8562 #ifdef MHD_POSIX_SOCKETS
   8563     else if (sizeof (bindaddr) < addrlen)
   8564     {
   8565       /* should be impossible with `struct sockaddr_storage` */
   8566 #ifdef HAVE_MESSAGES
   8567       MHD_DLOG (daemon,
   8568                 _ ("Failed to get listen port number " \
   8569                    "(`struct sockaddr_storage` too small!?).\n"));
   8570 #endif /* HAVE_MESSAGES */
   8571     }
   8572 #ifndef __linux__
   8573     else if (0 == addrlen)
   8574     {
   8575       /* Many non-Linux-based platforms return zero addrlen
   8576        * for AF_UNIX sockets */
   8577       daemon->port = 0;     /* special value for UNIX domain sockets */
   8578       if (_MHD_UNKNOWN == daemon->listen_is_unix)
   8579         daemon->listen_is_unix = _MHD_YES;
   8580     }
   8581 #endif /* __linux__ */
   8582 #endif /* MHD_POSIX_SOCKETS */
   8583     else
   8584     {
   8585       switch (bindaddr.ss_family)
   8586       {
   8587       case AF_INET:
   8588         {
   8589           struct sockaddr_in *s4 = (struct sockaddr_in *) &bindaddr;
   8590 
   8591           daemon->port = ntohs (s4->sin_port);
   8592           daemon->listen_is_unix = _MHD_NO;
   8593           break;
   8594         }
   8595 #ifdef HAVE_INET6
   8596       case AF_INET6:
   8597         {
   8598           struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &bindaddr;
   8599 
   8600           daemon->port = ntohs (s6->sin6_port);
   8601           daemon->listen_is_unix = _MHD_NO;
   8602           mhd_assert (0 != (*pflags & MHD_USE_IPv6));
   8603           break;
   8604         }
   8605 #endif /* HAVE_INET6 */
   8606 #ifdef AF_UNIX
   8607       case AF_UNIX:
   8608         daemon->port = 0;     /* special value for UNIX domain sockets */
   8609         daemon->listen_is_unix = _MHD_YES;
   8610         break;
   8611 #endif
   8612       default:
   8613 #ifdef HAVE_MESSAGES
   8614         MHD_DLOG (daemon,
   8615                   _ ("Listen socket has unknown address family!\n"));
   8616 #endif
   8617         daemon->port = 0;     /* ugh */
   8618         daemon->listen_is_unix = _MHD_UNKNOWN;
   8619         break;
   8620       }
   8621     }
   8622   }
   8623 #endif /* MHD_USE_GETSOCKNAME */
   8624 
   8625   if (MHD_INVALID_SOCKET != daemon->listen_fd)
   8626   {
   8627     mhd_assert (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET));
   8628     if (! MHD_socket_nonblocking_ (daemon->listen_fd))
   8629     {
   8630 #ifdef HAVE_MESSAGES
   8631       MHD_DLOG (daemon,
   8632                 _ ("Failed to set nonblocking mode on listening socket: %s\n"),
   8633                 MHD_socket_last_strerr_ ());
   8634 #endif
   8635       if (MHD_D_IS_USING_EPOLL_ (daemon)
   8636 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8637           || (daemon->worker_pool_size > 0)
   8638 #endif
   8639           )
   8640       {
   8641         /* Accept must be non-blocking. Multiple children may wake up
   8642          * to handle a new connection, but only one will win the race.
   8643          * The others must immediately return. */
   8644         goto free_and_fail;
   8645       }
   8646       daemon->listen_nonblk = false;
   8647     }
   8648     else
   8649       daemon->listen_nonblk = true;
   8650   }
   8651   else
   8652   {
   8653     mhd_assert (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET));
   8654     daemon->listen_nonblk = false; /* Actually listen socket does not exist */
   8655   }
   8656 
   8657 #ifdef EPOLL_SUPPORT
   8658   if (MHD_D_IS_USING_EPOLL_ (daemon)
   8659 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8660       && (0 == daemon->worker_pool_size)
   8661 #endif
   8662       )
   8663   {
   8664     if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   8665     {
   8666 #ifdef HAVE_MESSAGES
   8667       MHD_DLOG (daemon,
   8668                 _ ("Combining MHD_USE_THREAD_PER_CONNECTION and " \
   8669                    "MHD_USE_EPOLL is not supported.\n"));
   8670 #endif
   8671       goto free_and_fail;
   8672     }
   8673     if (MHD_NO == setup_epoll_to_listen (daemon))
   8674       goto free_and_fail;
   8675   }
   8676 #endif /* EPOLL_SUPPORT */
   8677 
   8678 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8679   if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex))
   8680   {
   8681 #ifdef HAVE_MESSAGES
   8682     MHD_DLOG (daemon,
   8683               _ ("MHD failed to initialize IP connection limit mutex.\n"));
   8684 #endif
   8685     goto free_and_fail;
   8686   }
   8687 #endif
   8688 
   8689 #ifdef HTTPS_SUPPORT
   8690   /* initialize HTTPS daemon certificate aspects & send / recv functions */
   8691   if ( (0 != (*pflags & MHD_USE_TLS)) &&
   8692        (0 != MHD_TLS_init (daemon)) )
   8693   {
   8694 #ifdef HAVE_MESSAGES
   8695     MHD_DLOG (daemon,
   8696               _ ("Failed to initialize TLS support.\n"));
   8697 #endif
   8698 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8699     MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
   8700 #endif
   8701     goto free_and_fail;
   8702   }
   8703 #endif /* HTTPS_SUPPORT */
   8704 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8705   /* Start threads if requested by parameters */
   8706   if (MHD_D_IS_USING_THREADS_ (daemon))
   8707   {
   8708     /* Internal thread (or threads) is used.
   8709      * Make sure that MHD will be able to communicate with threads. */
   8710     /* If using a thread pool ITC will be initialised later
   8711      * for each individual worker thread. */
   8712 #ifdef HAVE_LISTEN_SHUTDOWN
   8713     mhd_assert ((1 < daemon->worker_pool_size) || \
   8714                 (MHD_ITC_IS_VALID_ (daemon->itc)) || \
   8715                 (MHD_INVALID_SOCKET != daemon->listen_fd));
   8716 #else  /* ! HAVE_LISTEN_SHUTDOWN */
   8717     mhd_assert ((1 < daemon->worker_pool_size) || \
   8718                 (MHD_ITC_IS_VALID_ (daemon->itc)));
   8719 #endif /* ! HAVE_LISTEN_SHUTDOWN */
   8720     if (0 == daemon->worker_pool_size)
   8721     {
   8722       if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex))
   8723       {
   8724 #ifdef HAVE_MESSAGES
   8725         MHD_DLOG (daemon,
   8726                   _ ("Failed to initialise internal lists mutex.\n"));
   8727 #endif
   8728         MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
   8729         goto free_and_fail;
   8730       }
   8731       if (! MHD_mutex_init_ (&daemon->new_connections_mutex))
   8732       {
   8733 #ifdef HAVE_MESSAGES
   8734         MHD_DLOG (daemon,
   8735                   _ ("Failed to initialise mutex.\n"));
   8736 #endif
   8737         MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
   8738         MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
   8739         goto free_and_fail;
   8740       }
   8741       if (! MHD_create_named_thread_ (&daemon->tid,
   8742                                       MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) ?
   8743                                       "MHD-listen" : "MHD-single",
   8744                                       daemon->thread_stack_size,
   8745                                       &MHD_polling_thread,
   8746                                       daemon) )
   8747       {
   8748 #ifdef HAVE_MESSAGES
   8749 #ifdef EAGAIN
   8750         if (EAGAIN == errno)
   8751           MHD_DLOG (daemon,
   8752                     _ ("Failed to create a new thread because it would have " \
   8753                        "exceeded the system limit on the number of threads or " \
   8754                        "no system resources available.\n"));
   8755         else
   8756 #endif /* EAGAIN */
   8757         MHD_DLOG (daemon,
   8758                   _ ("Failed to create listen thread: %s\n"),
   8759                   MHD_strerror_ (errno));
   8760 #endif /* HAVE_MESSAGES */
   8761         MHD_mutex_destroy_chk_ (&daemon->new_connections_mutex);
   8762         MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
   8763         MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
   8764         goto free_and_fail;
   8765       }
   8766     }
   8767     else   /* 0 < daemon->worker_pool_size */
   8768     {
   8769       /* Coarse-grained count of connections per thread (note error
   8770        * due to integer division). Also keep track of how many
   8771        * connections are leftover after an equal split. */
   8772       unsigned int conns_per_thread = daemon->connection_limit
   8773                                       / daemon->worker_pool_size;
   8774       unsigned int leftover_conns = daemon->connection_limit
   8775                                     % daemon->worker_pool_size;
   8776 
   8777       mhd_assert (2 <= daemon->worker_pool_size);
   8778       i = 0;     /* we need this in case fcntl or malloc fails */
   8779 
   8780       /* Allocate memory for pooled objects */
   8781       daemon->worker_pool = malloc (sizeof (struct MHD_Daemon)
   8782                                     * daemon->worker_pool_size);
   8783       if (NULL == daemon->worker_pool)
   8784         goto thread_failed;
   8785 
   8786       /* Start the workers in the pool */
   8787       for (i = 0; i < daemon->worker_pool_size; ++i)
   8788       {
   8789         /* Create copy of the Daemon object for each worker */
   8790         struct MHD_Daemon *d = &daemon->worker_pool[i];
   8791 
   8792         memcpy (d, daemon, sizeof (struct MHD_Daemon));
   8793         /* Adjust polling params for worker daemons; note that memcpy()
   8794            has already copied MHD_USE_INTERNAL_POLLING_THREAD thread mode into
   8795            the worker threads. */
   8796         d->master = daemon;
   8797         d->worker_pool_size = 0;
   8798         d->worker_pool = NULL;
   8799         if (! MHD_mutex_init_ (&d->cleanup_connection_mutex))
   8800         {
   8801 #ifdef HAVE_MESSAGES
   8802           MHD_DLOG (daemon,
   8803                     _ ("Failed to initialise internal lists mutex.\n"));
   8804 #endif
   8805           goto thread_failed;
   8806         }
   8807         if (! MHD_mutex_init_ (&d->new_connections_mutex))
   8808         {
   8809 #ifdef HAVE_MESSAGES
   8810           MHD_DLOG (daemon,
   8811                     _ ("Failed to initialise mutex.\n"));
   8812 #endif
   8813           MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex);
   8814           goto thread_failed;
   8815         }
   8816         if (0 != (*pflags & MHD_USE_ITC))
   8817         {
   8818           if (! MHD_itc_init_ (d->itc))
   8819           {
   8820 #ifdef HAVE_MESSAGES
   8821             MHD_DLOG (daemon,
   8822                       _ ("Failed to create worker inter-thread " \
   8823                          "communication channel: %s\n"),
   8824                       MHD_itc_last_strerror_ () );
   8825 #endif
   8826             MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
   8827             MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex);
   8828             goto thread_failed;
   8829           }
   8830           if (MHD_D_IS_USING_SELECT_ (d) &&
   8831               (! MHD_D_DOES_SCKT_FIT_FDSET_ (MHD_itc_r_fd_ (d->itc), daemon)) )
   8832           {
   8833 #ifdef HAVE_MESSAGES
   8834             MHD_DLOG (daemon,
   8835                       _ ("File descriptor for worker inter-thread " \
   8836                          "communication channel exceeds maximum value.\n"));
   8837 #endif
   8838             MHD_itc_destroy_chk_ (d->itc);
   8839             MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
   8840             MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex);
   8841             goto thread_failed;
   8842           }
   8843         }
   8844         else
   8845           MHD_itc_set_invalid_ (d->itc);
   8846 
   8847 #ifdef HAVE_LISTEN_SHUTDOWN
   8848         mhd_assert ((MHD_ITC_IS_VALID_ (d->itc)) || \
   8849                     (MHD_INVALID_SOCKET != d->listen_fd));
   8850 #else  /* ! HAVE_LISTEN_SHUTDOWN */
   8851         mhd_assert (MHD_ITC_IS_VALID_ (d->itc));
   8852 #endif /* ! HAVE_LISTEN_SHUTDOWN */
   8853 
   8854         /* Divide available connections evenly amongst the threads.
   8855          * Thread indexes in [0, leftover_conns) each get one of the
   8856          * leftover connections. */
   8857         d->connection_limit = conns_per_thread;
   8858         if (i < leftover_conns)
   8859           ++d->connection_limit;
   8860 #ifdef EPOLL_SUPPORT
   8861         if (MHD_D_IS_USING_EPOLL_ (d) &&
   8862             (MHD_NO == setup_epoll_to_listen (d)) )
   8863         {
   8864           if (MHD_ITC_IS_VALID_ (d->itc))
   8865             MHD_itc_destroy_chk_ (d->itc);
   8866           MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
   8867           MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex);
   8868           goto thread_failed;
   8869         }
   8870 #endif
   8871         /* Some members must be used only in master daemon */
   8872 #if defined(MHD_USE_THREADS)
   8873         memset (&d->per_ip_connection_mutex, 0x7F,
   8874                 sizeof(d->per_ip_connection_mutex));
   8875 #endif /* MHD_USE_THREADS */
   8876 #ifdef DAUTH_SUPPORT
   8877         d->nnc = NULL;
   8878         d->nonce_nc_size = 0;
   8879         d->digest_auth_random_copy = NULL;
   8880 #if defined(MHD_USE_THREADS)
   8881         memset (&d->nnc_lock, 0x7F, sizeof(d->nnc_lock));
   8882 #endif /* MHD_USE_THREADS */
   8883 #endif /* DAUTH_SUPPORT */
   8884 
   8885         /* Spawn the worker thread */
   8886         if (! MHD_create_named_thread_ (&d->tid,
   8887                                         "MHD-worker",
   8888                                         daemon->thread_stack_size,
   8889                                         &MHD_polling_thread,
   8890                                         d))
   8891         {
   8892 #ifdef HAVE_MESSAGES
   8893 #ifdef EAGAIN
   8894           if (EAGAIN == errno)
   8895             MHD_DLOG (daemon,
   8896                       _ ("Failed to create a new pool thread because it would " \
   8897                          "have exceeded the system limit on the number of " \
   8898                          "threads or no system resources available.\n"));
   8899           else
   8900 #endif /* EAGAIN */
   8901           MHD_DLOG (daemon,
   8902                     _ ("Failed to create pool thread: %s\n"),
   8903                     MHD_strerror_ (errno));
   8904 #endif
   8905           /* Free memory for this worker; cleanup below handles
   8906            * all previously-created workers. */
   8907           MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex);
   8908           if (MHD_ITC_IS_VALID_ (d->itc))
   8909             MHD_itc_destroy_chk_ (d->itc);
   8910           MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
   8911           MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex);
   8912           goto thread_failed;
   8913         }
   8914       }
   8915     }
   8916   }
   8917   else
   8918   { /* Daemon without internal threads */
   8919     if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex))
   8920     {
   8921 #ifdef HAVE_MESSAGES
   8922       MHD_DLOG (daemon,
   8923                 _ ("Failed to initialise internal lists mutex.\n"));
   8924 #endif
   8925       MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
   8926       goto free_and_fail;
   8927     }
   8928     if (! MHD_mutex_init_ (&daemon->new_connections_mutex))
   8929     {
   8930 #ifdef HAVE_MESSAGES
   8931       MHD_DLOG (daemon,
   8932                 _ ("Failed to initialise mutex.\n"));
   8933 #endif
   8934       MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
   8935       MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
   8936       goto free_and_fail;
   8937     }
   8938   }
   8939 #endif
   8940 #ifdef HTTPS_SUPPORT
   8941   /* API promises to never use the password after initialization,
   8942      so we additionally NULL it here to not deref a dangling pointer. */
   8943   daemon->https_key_password = NULL;
   8944 #endif /* HTTPS_SUPPORT */
   8945 
   8946   return daemon;
   8947 
   8948 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8949 thread_failed:
   8950   /* If no worker threads created, then shut down normally. Calling
   8951      MHD_stop_daemon (as we do below) doesn't work here since it
   8952      assumes a 0-sized thread pool means we had been in the default
   8953      MHD_USE_INTERNAL_POLLING_THREAD mode. */
   8954   if (0 == i)
   8955   {
   8956     MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
   8957     if (NULL != daemon->worker_pool)
   8958       free (daemon->worker_pool);
   8959     goto free_and_fail;
   8960   }
   8961 
   8962   /* Shutdown worker threads we've already created. Pretend
   8963      as though we had fully initialized our daemon, but
   8964      with a smaller number of threads than had been
   8965      requested. */
   8966   daemon->worker_pool_size = i;
   8967   MHD_stop_daemon (daemon);
   8968   return NULL;
   8969 #endif
   8970 
   8971 free_and_fail:
   8972   /* clean up basic memory state in 'daemon' and return NULL to
   8973      indicate failure */
   8974 #ifdef EPOLL_SUPPORT
   8975 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   8976   if (daemon->upgrade_fd_in_epoll)
   8977   {
   8978     if (0 != epoll_ctl (daemon->epoll_fd,
   8979                         EPOLL_CTL_DEL,
   8980                         daemon->epoll_upgrade_fd,
   8981                         NULL))
   8982       MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
   8983     daemon->upgrade_fd_in_epoll = false;
   8984   }
   8985 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   8986   if (-1 != daemon->epoll_fd)
   8987     close (daemon->epoll_fd);
   8988 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   8989   if (-1 != daemon->epoll_upgrade_fd)
   8990     close (daemon->epoll_upgrade_fd);
   8991 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   8992 #endif /* EPOLL_SUPPORT */
   8993 #ifdef DAUTH_SUPPORT
   8994   free (daemon->digest_auth_random_copy);
   8995   free (daemon->nnc);
   8996 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8997   MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
   8998 #endif
   8999 #endif
   9000 #ifdef HTTPS_SUPPORT
   9001   if (0 != (*pflags & MHD_USE_TLS))
   9002   {
   9003     gnutls_priority_deinit (daemon->priority_cache);
   9004     if (daemon->x509_cred)
   9005       gnutls_certificate_free_credentials (daemon->x509_cred);
   9006     if (daemon->psk_cred)
   9007       gnutls_psk_free_server_credentials (daemon->psk_cred);
   9008   }
   9009 #endif /* HTTPS_SUPPORT */
   9010   if (MHD_ITC_IS_VALID_ (daemon->itc))
   9011     MHD_itc_destroy_chk_ (daemon->itc);
   9012   if (MHD_INVALID_SOCKET != daemon->listen_fd)
   9013     (void) MHD_socket_close_ (daemon->listen_fd);
   9014   free (daemon);
   9015   return NULL;
   9016 }
   9017 
   9018 
   9019 /**
   9020  * Close all connections for the daemon.
   9021  * Must only be called when MHD_Daemon::shutdown was set to true.
   9022  * @remark To be called only from thread that process
   9023  * daemon's select()/poll()/etc.
   9024  *
   9025  * @param daemon daemon to close down
   9026  */
   9027 static void
   9028 close_all_connections (struct MHD_Daemon *daemon)
   9029 {
   9030   struct MHD_Connection *pos;
   9031   const bool used_thr_p_c = MHD_D_IS_USING_THREAD_PER_CONN_ (daemon);
   9032 #ifdef UPGRADE_SUPPORT
   9033   const bool upg_allowed = (0 != (daemon->options & MHD_ALLOW_UPGRADE));
   9034 #endif /* UPGRADE_SUPPORT */
   9035 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   9036   struct MHD_UpgradeResponseHandle *urh;
   9037   struct MHD_UpgradeResponseHandle *urhn;
   9038   const bool used_tls = (0 != (daemon->options & MHD_USE_TLS));
   9039 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   9040 
   9041 #ifdef MHD_USE_THREADS
   9042   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   9043                MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) || \
   9044                MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   9045   mhd_assert (NULL == daemon->worker_pool);
   9046 #endif /* MHD_USE_THREADS */
   9047   mhd_assert (daemon->shutdown);
   9048 
   9049 #ifdef MHD_USE_THREADS
   9050 /* Remove externally added new connections that are
   9051    * not processed by the daemon thread. */
   9052   MHD_mutex_lock_chk_ (&daemon->new_connections_mutex);
   9053   while (NULL != (pos = daemon->new_connections_tail))
   9054   {
   9055     mhd_assert (MHD_D_IS_USING_THREADS_ (daemon));
   9056     DLL_remove (daemon->new_connections_head,
   9057                 daemon->new_connections_tail,
   9058                 pos);
   9059     new_connection_close_ (daemon, pos);
   9060   }
   9061   MHD_mutex_unlock_chk_ (&daemon->new_connections_mutex);
   9062 #endif /* MHD_USE_THREADS */
   9063 
   9064 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   9065   /* give upgraded HTTPS connections a chance to finish */
   9066   /* 'daemon->urh_head' is not used in thread-per-connection mode. */
   9067   for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
   9068   {
   9069     mhd_assert (! used_thr_p_c);
   9070     urhn = urh->prev;
   9071     /* call generic forwarding function for passing data
   9072        with chance to detect that application is done. */
   9073     process_urh (urh);
   9074     MHD_connection_finish_forward_ (urh->connection);
   9075     urh->clean_ready = true;
   9076     /* Resuming will move connection to cleanup list. */
   9077     MHD_resume_connection (urh->connection);
   9078   }
   9079 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   9080 
   9081   /* Give suspended connections a chance to resume to avoid
   9082      running into the check for there not being any suspended
   9083      connections left in case of a tight race with a recently
   9084      resumed connection. */
   9085   if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
   9086   {
   9087     daemon->resuming = true;   /* Force check for pending resume. */
   9088     resume_suspended_connections (daemon);
   9089   }
   9090   /* first, make sure all threads are aware of shutdown; need to
   9091      traverse DLLs in peace... */
   9092 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9093   MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   9094 #endif
   9095 #ifdef UPGRADE_SUPPORT
   9096   if (upg_allowed)
   9097   {
   9098     struct MHD_Connection *susp;
   9099 
   9100     susp = daemon->suspended_connections_tail;
   9101     while (NULL != susp)
   9102     {
   9103       if (NULL == susp->urh)     /* "Upgraded" connection? */
   9104         MHD_PANIC (_ ("MHD_stop_daemon() called while we have " \
   9105                       "suspended connections.\n"));
   9106 #ifdef HTTPS_SUPPORT
   9107       else if (used_tls &&
   9108                used_thr_p_c &&
   9109                (! susp->urh->clean_ready) )
   9110         shutdown (susp->urh->app.socket,
   9111                   SHUT_RDWR);     /* Wake thread by shutdown of app socket. */
   9112 #endif /* HTTPS_SUPPORT */
   9113       else
   9114       {
   9115 #ifdef HAVE_MESSAGES
   9116         if (! susp->urh->was_closed)
   9117           MHD_DLOG (daemon,
   9118                     _ ("Initiated daemon shutdown while \"upgraded\" " \
   9119                        "connection was not closed.\n"));
   9120 #endif
   9121         susp->urh->was_closed = true;
   9122         /* If thread-per-connection is used, connection's thread
   9123          * may still processing "upgrade" (exiting). */
   9124         if (! used_thr_p_c)
   9125           MHD_connection_finish_forward_ (susp);
   9126         /* Do not use MHD_resume_connection() as mutex is
   9127          * already locked. */
   9128         susp->resuming = true;
   9129         daemon->resuming = true;
   9130       }
   9131       susp = susp->prev;
   9132     }
   9133   }
   9134   else /* This 'else' is combined with next 'if' */
   9135 #endif /* UPGRADE_SUPPORT */
   9136   if (NULL != daemon->suspended_connections_head)
   9137     MHD_PANIC (_ ("MHD_stop_daemon() called while we have " \
   9138                   "suspended connections.\n"));
   9139 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
   9140 #ifdef MHD_USE_THREADS
   9141   if (upg_allowed && used_tls && used_thr_p_c)
   9142   {
   9143     /* "Upgraded" threads may be running in parallel. Connection will not be
   9144      * moved to the "cleanup list" until connection's thread finishes.
   9145      * We must ensure that all "upgraded" connections are finished otherwise
   9146      * connection may stay in "suspended" list and will not be cleaned. */
   9147     for (pos = daemon->suspended_connections_tail; NULL != pos; pos = pos->prev)
   9148     {
   9149       /* Any connection found here is "upgraded" connection, normal suspended
   9150        * connections are already removed from this list. */
   9151       mhd_assert (NULL != pos->urh);
   9152       if (! pos->thread_joined)
   9153       {
   9154         /* While "cleanup" list is not manipulated by "upgraded"
   9155          * connection, "cleanup" mutex is required for call of
   9156          * MHD_resume_connection() during finishing of "upgraded"
   9157          * thread. */
   9158         MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   9159         if (! MHD_thread_handle_ID_join_thread_ (pos->tid))
   9160           MHD_PANIC (_ ("Failed to join a thread.\n"));
   9161         pos->thread_joined = true;
   9162         MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   9163       }
   9164     }
   9165   }
   9166 #endif /* MHD_USE_THREADS */
   9167 #endif
   9168   for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
   9169   {
   9170     shutdown (pos->socket_fd,
   9171               SHUT_RDWR);
   9172 #ifdef MHD_WINSOCK_SOCKETS
   9173     if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) &&
   9174         (MHD_ITC_IS_VALID_ (daemon->itc)) &&
   9175         (! MHD_itc_activate_ (daemon->itc, "e")) )
   9176       MHD_PANIC (_ ("Failed to signal shutdown via inter-thread " \
   9177                     "communication channel.\n"));
   9178 #endif
   9179   }
   9180 
   9181 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9182   /* now, collect per-connection threads */
   9183   if (used_thr_p_c)
   9184   {
   9185     pos = daemon->connections_tail;
   9186     while (NULL != pos)
   9187     {
   9188       if (! pos->thread_joined)
   9189       {
   9190         MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   9191         if (! MHD_thread_handle_ID_join_thread_ (pos->tid))
   9192           MHD_PANIC (_ ("Failed to join a thread.\n"));
   9193         MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   9194         pos->thread_joined = true;
   9195         /* The thread may have concurrently modified the DLL,
   9196            need to restart from the beginning */
   9197         pos = daemon->connections_tail;
   9198         continue;
   9199       }
   9200       pos = pos->prev;
   9201     }
   9202   }
   9203   MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   9204 #endif
   9205 
   9206 #ifdef UPGRADE_SUPPORT
   9207   /* Finished threads with "upgraded" connections need to be moved
   9208    * to cleanup list by resume_suspended_connections(). */
   9209   /* "Upgraded" connections that were not closed explicitly by
   9210    * application should be moved to cleanup list too. */
   9211   if (upg_allowed)
   9212   {
   9213     daemon->resuming = true;   /* Force check for pending resume. */
   9214     resume_suspended_connections (daemon);
   9215   }
   9216 #endif /* UPGRADE_SUPPORT */
   9217 
   9218   mhd_assert (NULL == daemon->suspended_connections_head);
   9219   /* now that we're alone, move everyone to cleanup */
   9220   while (NULL != (pos = daemon->connections_tail))
   9221   {
   9222 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9223     if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) &&
   9224         (! pos->thread_joined) )
   9225       MHD_PANIC (_ ("Failed to join a thread.\n"));
   9226 #endif
   9227     close_connection (pos);
   9228   }
   9229   MHD_cleanup_connections (daemon);
   9230 }
   9231 
   9232 
   9233 /**
   9234  * Shutdown an HTTP daemon.
   9235  *
   9236  * @param daemon daemon to stop
   9237  * @ingroup event
   9238  */
   9239 _MHD_EXTERN void
   9240 MHD_stop_daemon (struct MHD_Daemon *daemon)
   9241 {
   9242   MHD_socket fd;
   9243 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9244   unsigned int i;
   9245 #endif
   9246 
   9247   if (NULL == daemon)
   9248     return;
   9249   if ( (daemon->shutdown) && (NULL == daemon->master) )
   9250     MHD_PANIC (_ ("MHD_stop_daemon() was called twice."));
   9251 
   9252   mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   9253               (NULL != daemon->worker_pool) || \
   9254               (MHD_thread_handle_ID_is_valid_handle_ (daemon->tid)));
   9255   mhd_assert (((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) &&
   9256                (NULL == daemon->worker_pool)) || \
   9257               (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid)));
   9258 
   9259   /* Slave daemons must be stopped by master daemon. */
   9260   mhd_assert ( (NULL == daemon->master) || (daemon->shutdown) );
   9261 
   9262   daemon->shutdown = true;
   9263   if (daemon->was_quiesced)
   9264     fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */
   9265   else
   9266     fd = daemon->listen_fd;
   9267 
   9268 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9269   if (NULL != daemon->worker_pool)
   9270   {   /* Master daemon with worker pool. */
   9271     mhd_assert (1 < daemon->worker_pool_size);
   9272     mhd_assert (MHD_D_IS_USING_THREADS_ (daemon));
   9273 
   9274     /* Let workers shutdown in parallel. */
   9275     for (i = 0; i < daemon->worker_pool_size; ++i)
   9276     {
   9277       daemon->worker_pool[i].shutdown = true;
   9278       if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc))
   9279       {
   9280         if (! MHD_itc_activate_ (daemon->worker_pool[i].itc,
   9281                                  "e"))
   9282           MHD_PANIC (_ ("Failed to signal shutdown via inter-thread " \
   9283                         "communication channel.\n"));
   9284       }
   9285       else
   9286         mhd_assert (MHD_INVALID_SOCKET != fd);
   9287     }
   9288 #ifdef HAVE_LISTEN_SHUTDOWN
   9289     if (MHD_INVALID_SOCKET != fd)
   9290     {
   9291       (void) shutdown (fd,
   9292                        SHUT_RDWR);
   9293     }
   9294 #endif /* HAVE_LISTEN_SHUTDOWN */
   9295     for (i = 0; i < daemon->worker_pool_size; ++i)
   9296     {
   9297       MHD_stop_daemon (&daemon->worker_pool[i]);
   9298     }
   9299     free (daemon->worker_pool);
   9300     mhd_assert (MHD_ITC_IS_INVALID_ (daemon->itc));
   9301 #ifdef EPOLL_SUPPORT
   9302     mhd_assert (-1 == daemon->epoll_fd);
   9303 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   9304     mhd_assert (-1 == daemon->epoll_upgrade_fd);
   9305 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   9306 #endif /* EPOLL_SUPPORT */
   9307   }
   9308   else
   9309 #endif
   9310   {   /* Worker daemon or single daemon. */
   9311 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9312     if (MHD_D_IS_USING_THREADS_ (daemon))
   9313     {     /* Worker daemon or single daemon with internal thread(s). */
   9314       mhd_assert (0 == daemon->worker_pool_size);
   9315       /* Separate thread(s) is used for polling sockets. */
   9316       if (MHD_ITC_IS_VALID_ (daemon->itc))
   9317       {
   9318         if (! MHD_itc_activate_ (daemon->itc,
   9319                                  "e"))
   9320           MHD_PANIC (_ ("Failed to signal shutdown via inter-thread " \
   9321                         "communication channel.\n"));
   9322       }
   9323       else
   9324       {
   9325 #ifdef HAVE_LISTEN_SHUTDOWN
   9326         if (MHD_INVALID_SOCKET != fd)
   9327         {
   9328           if (NULL == daemon->master)
   9329             (void) shutdown (fd,
   9330                              SHUT_RDWR);
   9331         }
   9332         else
   9333 #endif /* HAVE_LISTEN_SHUTDOWN */
   9334         mhd_assert (false); /* Should never happen */
   9335       }
   9336 
   9337       if (! MHD_thread_handle_ID_join_thread_ (daemon->tid))
   9338       {
   9339         MHD_PANIC (_ ("Failed to join a thread.\n"));
   9340       }
   9341       /* close_all_connections() was called in daemon thread. */
   9342     }
   9343     else
   9344 #endif
   9345     {
   9346       /* No internal threads are used for polling sockets. */
   9347       close_all_connections (daemon);
   9348     }
   9349     mhd_assert (NULL == daemon->connections_head);
   9350     mhd_assert (NULL == daemon->cleanup_head);
   9351     mhd_assert (NULL == daemon->suspended_connections_head);
   9352     mhd_assert (NULL == daemon->new_connections_head);
   9353 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
   9354     mhd_assert (NULL == daemon->urh_head);
   9355 #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */
   9356 
   9357     if (MHD_ITC_IS_VALID_ (daemon->itc))
   9358       MHD_itc_destroy_chk_ (daemon->itc);
   9359 
   9360 #ifdef EPOLL_SUPPORT
   9361     if (MHD_D_IS_USING_EPOLL_ (daemon) &&
   9362         (-1 != daemon->epoll_fd) )
   9363       MHD_socket_close_chk_ (daemon->epoll_fd);
   9364 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   9365     if (MHD_D_IS_USING_EPOLL_ (daemon) &&
   9366         (-1 != daemon->epoll_upgrade_fd) )
   9367       MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
   9368 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   9369 #endif /* EPOLL_SUPPORT */
   9370 
   9371 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9372     MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
   9373     MHD_mutex_destroy_chk_ (&daemon->new_connections_mutex);
   9374 #endif
   9375   }
   9376 
   9377   if (NULL == daemon->master)
   9378   {   /* Cleanup that should be done only one time in master/single daemon.
   9379        * Do not perform this cleanup in worker daemons. */
   9380 
   9381     if (MHD_INVALID_SOCKET != fd)
   9382       MHD_socket_close_chk_ (fd);
   9383 
   9384     /* TLS clean up */
   9385 #ifdef HTTPS_SUPPORT
   9386     if (daemon->have_dhparams)
   9387     {
   9388       gnutls_dh_params_deinit (daemon->https_mem_dhparams);
   9389       daemon->have_dhparams = false;
   9390     }
   9391     if (0 != (daemon->options & MHD_USE_TLS))
   9392     {
   9393       gnutls_priority_deinit (daemon->priority_cache);
   9394       if (daemon->x509_cred)
   9395         gnutls_certificate_free_credentials (daemon->x509_cred);
   9396       if (daemon->psk_cred)
   9397         gnutls_psk_free_server_credentials (daemon->psk_cred);
   9398     }
   9399 #endif /* HTTPS_SUPPORT */
   9400 
   9401 #ifdef DAUTH_SUPPORT
   9402     free (daemon->digest_auth_random_copy);
   9403     free (daemon->nnc);
   9404 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9405     MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
   9406 #endif
   9407 #endif
   9408 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9409     MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
   9410 #endif
   9411     free (daemon);
   9412   }
   9413 }
   9414 
   9415 
   9416 /**
   9417  * Obtain information about the given daemon.
   9418  * The returned pointer is invalidated with the next call of this function or
   9419  * when the daemon is stopped.
   9420  *
   9421  * @param daemon what daemon to get information about
   9422  * @param info_type what information is desired?
   9423  * @param ... depends on @a info_type
   9424  * @return NULL if this information is not available
   9425  *         (or if the @a info_type is unknown)
   9426  * @ingroup specialized
   9427  */
   9428 _MHD_EXTERN const union MHD_DaemonInfo *
   9429 MHD_get_daemon_info (struct MHD_Daemon *daemon,
   9430                      enum MHD_DaemonInfoType info_type,
   9431                      ...)
   9432 {
   9433   if (NULL == daemon)
   9434     return NULL;
   9435 
   9436   mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   9437               (NULL != daemon->worker_pool) || \
   9438               (MHD_thread_handle_ID_is_valid_handle_ (daemon->tid)));
   9439   mhd_assert (((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) &&
   9440                (NULL == daemon->worker_pool)) || \
   9441               (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid)));
   9442 
   9443   switch (info_type)
   9444   {
   9445   case MHD_DAEMON_INFO_KEY_SIZE:
   9446     return NULL;   /* no longer supported */
   9447   case MHD_DAEMON_INFO_MAC_KEY_SIZE:
   9448     return NULL;   /* no longer supported */
   9449   case MHD_DAEMON_INFO_LISTEN_FD:
   9450     daemon->daemon_info_dummy_listen_fd.listen_fd = daemon->listen_fd;
   9451     return &daemon->daemon_info_dummy_listen_fd;
   9452   case MHD_DAEMON_INFO_EPOLL_FD:
   9453 #ifdef EPOLL_SUPPORT
   9454     daemon->daemon_info_dummy_epoll_fd.epoll_fd = daemon->epoll_fd;
   9455     return &daemon->daemon_info_dummy_epoll_fd;
   9456 #else  /* ! EPOLL_SUPPORT */
   9457     return NULL;
   9458 #endif /* ! EPOLL_SUPPORT */
   9459   case MHD_DAEMON_INFO_CURRENT_CONNECTIONS:
   9460     if (! MHD_D_IS_THREAD_SAFE_ (daemon))
   9461       MHD_cleanup_connections (daemon);
   9462 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9463     else if (daemon->worker_pool)
   9464     {
   9465       unsigned int i;
   9466       /* Collect the connection information stored in the workers. */
   9467       daemon->connections = 0;
   9468       for (i = 0; i < daemon->worker_pool_size; i++)
   9469       {
   9470         /* FIXME: next line is thread-safe only if read is atomic. */
   9471         daemon->connections += daemon->worker_pool[i].connections;
   9472       }
   9473     }
   9474 #endif
   9475     daemon->daemon_info_dummy_num_connections.num_connections
   9476       = daemon->connections;
   9477     return &daemon->daemon_info_dummy_num_connections;
   9478   case MHD_DAEMON_INFO_FLAGS:
   9479     daemon->daemon_info_dummy_flags.flags = daemon->options;
   9480     return &daemon->daemon_info_dummy_flags;
   9481   case MHD_DAEMON_INFO_BIND_PORT:
   9482     daemon->daemon_info_dummy_port.port = daemon->port;
   9483     return &daemon->daemon_info_dummy_port;
   9484   default:
   9485     return NULL;
   9486   }
   9487 }
   9488 
   9489 
   9490 /**
   9491  * Obtain the version of this library
   9492  *
   9493  * @return static version string, e.g. "0.9.9"
   9494  * @ingroup specialized
   9495  */
   9496 _MHD_EXTERN const char *
   9497 MHD_get_version (void)
   9498 {
   9499 #ifdef PACKAGE_VERSION
   9500   return PACKAGE_VERSION;
   9501 #else  /* !PACKAGE_VERSION */
   9502   static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0";
   9503   if (0 == ver[0])
   9504   {
   9505     int res = MHD_snprintf_ (ver,
   9506                              sizeof(ver),
   9507                              "%x.%x.%x",
   9508                              (int) (((uint32_t) MHD_VERSION >> 24) & 0xFF),
   9509                              (int) (((uint32_t) MHD_VERSION >> 16) & 0xFF),
   9510                              (int) (((uint32_t) MHD_VERSION >> 8) & 0xFF));
   9511     if ((0 >= res) || (sizeof(ver) <= res))
   9512       return "0.0.0"; /* Can't return real version */
   9513   }
   9514   return ver;
   9515 #endif /* !PACKAGE_VERSION */
   9516 }
   9517 
   9518 
   9519 /**
   9520  * Obtain the version of this library as a binary value.
   9521  *
   9522  * @return version binary value, e.g. "0x00090900" (#MHD_VERSION of
   9523  *         compiled MHD binary)
   9524  * @note Available since #MHD_VERSION 0x00097601
   9525  * @ingroup specialized
   9526  */
   9527 _MHD_EXTERN uint32_t
   9528 MHD_get_version_bin (void)
   9529 {
   9530   return (uint32_t) MHD_VERSION;
   9531 }
   9532 
   9533 
   9534 /**
   9535  * Get information about supported MHD features.
   9536  * Indicate that MHD was compiled with or without support for
   9537  * particular feature. Some features require additional support
   9538  * by kernel. Kernel support is not checked by this function.
   9539  *
   9540  * @param feature type of requested information
   9541  * @return #MHD_YES if feature is supported by MHD, #MHD_NO if
   9542  * feature is not supported or feature is unknown.
   9543  * @ingroup specialized
   9544  */
   9545 _MHD_EXTERN enum MHD_Result
   9546 MHD_is_feature_supported (enum MHD_FEATURE feature)
   9547 {
   9548   switch (feature)
   9549   {
   9550   case MHD_FEATURE_MESSAGES:
   9551 #ifdef HAVE_MESSAGES
   9552     return MHD_YES;
   9553 #else
   9554     return MHD_NO;
   9555 #endif
   9556   case MHD_FEATURE_TLS:
   9557 #ifdef HTTPS_SUPPORT
   9558     return MHD_YES;
   9559 #else  /* ! HTTPS_SUPPORT */
   9560     return MHD_NO;
   9561 #endif  /* ! HTTPS_SUPPORT */
   9562   case MHD_FEATURE_HTTPS_CERT_CALLBACK:
   9563 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3
   9564     return MHD_YES;
   9565 #else  /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
   9566     return MHD_NO;
   9567 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
   9568   case MHD_FEATURE_HTTPS_CERT_CALLBACK2:
   9569 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030603
   9570     return MHD_YES;
   9571 #else  /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */
   9572     return MHD_NO;
   9573 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */
   9574   case MHD_FEATURE_IPv6:
   9575 #ifdef HAVE_INET6
   9576     return MHD_YES;
   9577 #else
   9578     return MHD_NO;
   9579 #endif
   9580   case MHD_FEATURE_IPv6_ONLY:
   9581 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
   9582     return MHD_YES;
   9583 #else
   9584     return MHD_NO;
   9585 #endif
   9586   case MHD_FEATURE_POLL:
   9587 #ifdef HAVE_POLL
   9588     return MHD_YES;
   9589 #else
   9590     return MHD_NO;
   9591 #endif
   9592   case MHD_FEATURE_EPOLL:
   9593 #ifdef EPOLL_SUPPORT
   9594     return MHD_YES;
   9595 #else
   9596     return MHD_NO;
   9597 #endif
   9598   case MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET:
   9599 #ifdef HAVE_LISTEN_SHUTDOWN
   9600     return MHD_YES;
   9601 #else
   9602     return MHD_NO;
   9603 #endif
   9604   case MHD_FEATURE_SOCKETPAIR:
   9605 #ifdef _MHD_ITC_SOCKETPAIR
   9606     return MHD_YES;
   9607 #else
   9608     return MHD_NO;
   9609 #endif
   9610   case MHD_FEATURE_TCP_FASTOPEN:
   9611 #ifdef TCP_FASTOPEN
   9612     return MHD_YES;
   9613 #else
   9614     return MHD_NO;
   9615 #endif
   9616   case MHD_FEATURE_BASIC_AUTH:
   9617 #ifdef BAUTH_SUPPORT
   9618     return MHD_YES;
   9619 #else
   9620     return MHD_NO;
   9621 #endif
   9622   case MHD_FEATURE_DIGEST_AUTH:
   9623 #ifdef DAUTH_SUPPORT
   9624     return MHD_YES;
   9625 #else
   9626     return MHD_NO;
   9627 #endif
   9628   case MHD_FEATURE_POSTPROCESSOR:
   9629 #ifdef HAVE_POSTPROCESSOR
   9630     return MHD_YES;
   9631 #else
   9632     return MHD_NO;
   9633 #endif
   9634   case MHD_FEATURE_HTTPS_KEY_PASSWORD:
   9635 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111
   9636     return MHD_YES;
   9637 #else  /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
   9638     return MHD_NO;
   9639 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
   9640   case MHD_FEATURE_LARGE_FILE:
   9641 #if defined(HAVE_PREAD64) || defined(_WIN32)
   9642     return MHD_YES;
   9643 #elif defined(HAVE_PREAD)
   9644     return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
   9645 #elif defined(HAVE_LSEEK64)
   9646     return MHD_YES;
   9647 #else
   9648     return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
   9649 #endif
   9650   case MHD_FEATURE_THREAD_NAMES:
   9651 #if defined(MHD_USE_THREAD_NAME_)
   9652     return MHD_YES;
   9653 #else
   9654     return MHD_NO;
   9655 #endif
   9656   case MHD_FEATURE_UPGRADE:
   9657 #if defined(UPGRADE_SUPPORT)
   9658     return MHD_YES;
   9659 #else
   9660     return MHD_NO;
   9661 #endif
   9662   case MHD_FEATURE_RESPONSES_SHARED_FD:
   9663 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32)
   9664     return MHD_YES;
   9665 #else
   9666     return MHD_NO;
   9667 #endif
   9668   case MHD_FEATURE_AUTODETECT_BIND_PORT:
   9669 #ifdef MHD_USE_GETSOCKNAME
   9670     return MHD_YES;
   9671 #else
   9672     return MHD_NO;
   9673 #endif
   9674   case MHD_FEATURE_AUTOSUPPRESS_SIGPIPE:
   9675 #if defined(MHD_SEND_SPIPE_SUPPRESS_POSSIBLE) || \
   9676     ! defined(MHD_SEND_SPIPE_SUPPRESS_NEEDED)
   9677     return MHD_YES;
   9678 #else
   9679     return MHD_NO;
   9680 #endif
   9681   case MHD_FEATURE_SENDFILE:
   9682 #ifdef _MHD_HAVE_SENDFILE
   9683     return MHD_YES;
   9684 #else
   9685     return MHD_NO;
   9686 #endif
   9687   case MHD_FEATURE_THREADS:
   9688 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9689     return MHD_YES;
   9690 #else
   9691     return MHD_NO;
   9692 #endif
   9693   case MHD_FEATURE_COOKIE_PARSING:
   9694 #if defined(COOKIE_SUPPORT)
   9695     return MHD_YES;
   9696 #else
   9697     return MHD_NO;
   9698 #endif
   9699   case MHD_FEATURE_DIGEST_AUTH_RFC2069:
   9700 #ifdef DAUTH_SUPPORT
   9701     return MHD_YES;
   9702 #else
   9703     return MHD_NO;
   9704 #endif
   9705   case MHD_FEATURE_DIGEST_AUTH_MD5:
   9706 #if defined(DAUTH_SUPPORT) && defined(MHD_MD5_SUPPORT)
   9707     return MHD_YES;
   9708 #else
   9709     return MHD_NO;
   9710 #endif
   9711   case MHD_FEATURE_DIGEST_AUTH_SHA256:
   9712 #if defined(DAUTH_SUPPORT) && defined(MHD_SHA256_SUPPORT)
   9713     return MHD_YES;
   9714 #else
   9715     return MHD_NO;
   9716 #endif
   9717   case MHD_FEATURE_DIGEST_AUTH_SHA512_256:
   9718 #if defined(DAUTH_SUPPORT) && defined(MHD_SHA512_256_SUPPORT)
   9719     return MHD_YES;
   9720 #else
   9721     return MHD_NO;
   9722 #endif
   9723   case MHD_FEATURE_DIGEST_AUTH_AUTH_INT:
   9724 #ifdef DAUTH_SUPPORT
   9725     return MHD_NO;
   9726 #else
   9727     return MHD_NO;
   9728 #endif
   9729   case MHD_FEATURE_DIGEST_AUTH_ALGO_SESSION:
   9730 #ifdef DAUTH_SUPPORT
   9731     return MHD_NO;
   9732 #else
   9733     return MHD_NO;
   9734 #endif
   9735   case MHD_FEATURE_DIGEST_AUTH_USERHASH:
   9736 #ifdef DAUTH_SUPPORT
   9737     return MHD_YES;
   9738 #else
   9739     return MHD_NO;
   9740 #endif
   9741   case MHD_FEATURE_EXTERN_HASH:
   9742 #if defined(MHD_MD5_TLSLIB) || defined(MHD_SHA256_TLSLIB)
   9743     return MHD_YES;
   9744 #else
   9745     return MHD_NO;
   9746 #endif
   9747   case MHD_FEATURE_DEBUG_BUILD:
   9748 #ifdef _DEBUG
   9749     return MHD_YES;
   9750 #else
   9751     return MHD_NO;
   9752 #endif
   9753   case MHD_FEATURE_FLEXIBLE_FD_SETSIZE:
   9754 #ifdef HAS_FD_SETSIZE_OVERRIDABLE
   9755     return MHD_YES;
   9756 #else  /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   9757     return MHD_NO;
   9758 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   9759 
   9760   default:
   9761     break;
   9762   }
   9763   return MHD_NO;
   9764 }
   9765 
   9766 
   9767 #ifdef MHD_HTTPS_REQUIRE_GCRYPT
   9768 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600
   9769 #if defined(MHD_USE_POSIX_THREADS)
   9770 GCRY_THREAD_OPTION_PTHREAD_IMPL;
   9771 #elif defined(MHD_W32_MUTEX_)
   9772 
   9773 static int
   9774 gcry_w32_mutex_init (void **ppmtx)
   9775 {
   9776   *ppmtx = malloc (sizeof (MHD_mutex_));
   9777 
   9778   if (NULL == *ppmtx)
   9779     return ENOMEM;
   9780   if (! MHD_mutex_init_ ((MHD_mutex_ *) *ppmtx))
   9781   {
   9782     free (*ppmtx);
   9783     *ppmtx = NULL;
   9784     return EPERM;
   9785   }
   9786 
   9787   return 0;
   9788 }
   9789 
   9790 
   9791 static int
   9792 gcry_w32_mutex_destroy (void **ppmtx)
   9793 {
   9794   int res = (MHD_mutex_destroy_ ((MHD_mutex_ *) *ppmtx)) ? 0 : EINVAL;
   9795   free (*ppmtx);
   9796   return res;
   9797 }
   9798 
   9799 
   9800 static int
   9801 gcry_w32_mutex_lock (void **ppmtx)
   9802 {
   9803   return MHD_mutex_lock_ ((MHD_mutex_ *) *ppmtx) ? 0 : EINVAL;
   9804 }
   9805 
   9806 
   9807 static int
   9808 gcry_w32_mutex_unlock (void **ppmtx)
   9809 {
   9810   return MHD_mutex_unlock_ ((MHD_mutex_ *) *ppmtx) ? 0 : EINVAL;
   9811 }
   9812 
   9813 
   9814 static struct gcry_thread_cbs gcry_threads_w32 = {
   9815   (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
   9816   NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
   9817   gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
   9818   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
   9819 };
   9820 
   9821 #endif /* defined(MHD_W32_MUTEX_) */
   9822 #endif /* HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600 */
   9823 #endif /* MHD_HTTPS_REQUIRE_GCRYPT */
   9824 
   9825 /**
   9826  * Initialize do setup work.
   9827  */
   9828 void
   9829 MHD_init (void)
   9830 {
   9831 #if defined(MHD_WINSOCK_SOCKETS)
   9832   WSADATA wsd;
   9833 #endif /* MHD_WINSOCK_SOCKETS */
   9834 
   9835   MHD_set_panic_func (NULL, NULL);
   9836 
   9837 #if defined(MHD_WINSOCK_SOCKETS)
   9838   if (0 != WSAStartup (MAKEWORD (2, 2), &wsd))
   9839     MHD_PANIC (_ ("Failed to initialize winsock.\n"));
   9840   if ((2 != LOBYTE (wsd.wVersion)) && (2 != HIBYTE (wsd.wVersion)))
   9841     MHD_PANIC (_ ("Winsock version 2.2 is not available.\n"));
   9842 #endif /* MHD_WINSOCK_SOCKETS */
   9843 #ifdef HTTPS_SUPPORT
   9844 #ifdef MHD_HTTPS_REQUIRE_GCRYPT
   9845 #if GCRYPT_VERSION_NUMBER < 0x010600
   9846 #if GNUTLS_VERSION_NUMBER <= 0x020b00
   9847 #if defined(MHD_USE_POSIX_THREADS)
   9848   if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
   9849                          &gcry_threads_pthread))
   9850     MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt.\n"));
   9851 #elif defined(MHD_W32_MUTEX_)
   9852   if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
   9853                          &gcry_threads_w32))
   9854     MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt.\n"));
   9855 #endif /* defined(MHD_W32_MUTEX_) */
   9856 #endif /* GNUTLS_VERSION_NUMBER <= 0x020b00 */
   9857   gcry_check_version (NULL);
   9858 #else
   9859   if (NULL == gcry_check_version ("1.6.0"))
   9860     MHD_PANIC (_ ("libgcrypt is too old. MHD was compiled for " \
   9861                   "libgcrypt 1.6.0 or newer.\n"));
   9862 #endif
   9863 #endif /* MHD_HTTPS_REQUIRE_GCRYPT */
   9864   gnutls_global_init ();
   9865 #endif /* HTTPS_SUPPORT */
   9866   MHD_monotonic_sec_counter_init ();
   9867   MHD_send_init_static_vars_ ();
   9868   MHD_init_mem_pools_ ();
   9869   /* Check whether sizes were correctly detected by configure */
   9870 #ifdef _DEBUG
   9871   if (1)
   9872   {
   9873     struct timeval tv;
   9874     mhd_assert (sizeof(tv.tv_sec) == SIZEOF_STRUCT_TIMEVAL_TV_SEC);
   9875   }
   9876 #endif /* _DEBUG */
   9877   mhd_assert (sizeof(uint64_t) == SIZEOF_UINT64_T);
   9878 }
   9879 
   9880 
   9881 void
   9882 MHD_fini (void)
   9883 {
   9884 #ifdef HTTPS_SUPPORT
   9885   gnutls_global_deinit ();
   9886 #endif /* HTTPS_SUPPORT */
   9887 #if defined(MHD_WINSOCK_SOCKETS)
   9888   WSACleanup ();
   9889 #endif /* MHD_WINSOCK_SOCKETS */
   9890   MHD_monotonic_sec_counter_finish ();
   9891 }
   9892 
   9893 
   9894 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
   9895 _SET_INIT_AND_DEINIT_FUNCS (MHD_init, MHD_fini);
   9896 #endif /* _AUTOINIT_FUNCS_ARE_SUPPORTED */
   9897 
   9898 /* end of daemon.c */