libmicrohttpd

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

daemon.c (333174B)


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