libmicrohttpd

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

daemon.c (320944B)


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