libmicrohttpd

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

daemon.c (320855B)


      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_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
    963   if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
    964     urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
    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 
   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 (UINT_MAX < app_psk_size)
   2474   {
   2475 #ifdef HAVE_MESSAGES
   2476     MHD_DLOG (daemon,
   2477               _ ("PSK authentication failed: PSK too long.\n"));
   2478 #endif
   2479     free (app_psk);
   2480     return -1;
   2481   }
   2482   if (NULL == (key->data = gnutls_malloc (app_psk_size)))
   2483   {
   2484 #ifdef HAVE_MESSAGES
   2485     MHD_DLOG (daemon,
   2486               _ ("PSK authentication failed: gnutls_malloc failed to " \
   2487                  "allocate memory.\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;
   4282        NULL != pos;
   4283        pos = pos->prevX)
   4284   {
   4285     if (0 != pos->connection_timeout_ms)
   4286     {
   4287       if ( (NULL == earliest_tmot_conn) ||
   4288            (earliest_deadline >
   4289             pos->last_activity + pos->connection_timeout_ms) )
   4290       {
   4291         earliest_tmot_conn = pos;
   4292         earliest_deadline = pos->last_activity + pos->connection_timeout_ms;
   4293       }
   4294     }
   4295   }
   4296 
   4297   if (NULL != earliest_tmot_conn)
   4298   {
   4299     *timeout64 = connection_get_wait (earliest_tmot_conn);
   4300     return MHD_YES;
   4301   }
   4302   return MHD_NO;
   4303 }
   4304 
   4305 
   4306 #if defined(HAVE_POLL) || defined(EPOLL_SUPPORT)
   4307 /**
   4308  * Obtain timeout value for external polling function for this daemon.
   4309  *
   4310  * This function set value to the amount of milliseconds for which polling
   4311  * function (`select()`, `poll()` or epoll) should at most block, not the
   4312  * timeout value set for connections.
   4313  *
   4314  * Any "external" sockets polling function must be called with the timeout
   4315  * value provided by this function (if returned value is non-negative).
   4316  * Smaller timeout values can be used for polling function if it is required
   4317  * for any reason, but using larger timeout value or no timeout (indefinite
   4318  * timeout) when this function returns non-negative value will break MHD
   4319  * processing logic and result in "hung" connections with data pending in
   4320  * network buffers and other problems.
   4321  *
   4322  * It is important to always use this function (or #MHD_get_timeout(),
   4323  * #MHD_get_timeout64(), #MHD_get_timeout_i() functions) when "external"
   4324  * polling is used.
   4325  * If this function returns non-negative value then #MHD_run() (or
   4326  * #MHD_run_from_select()) must be called right after return from polling
   4327  * function, regardless of the states of MHD FDs.
   4328  *
   4329  * In practice, if zero or positive value is returned then #MHD_run() (or
   4330  * #MHD_run_from_select()) must be called not later than returned amount of
   4331  * millisecond even if no activity is detected on sockets by sockets
   4332  * polling function.
   4333  * @remark To be called only from thread that process
   4334  * daemon's select()/poll()/etc.
   4335  *
   4336  * @param daemon the daemon to query for timeout
   4337  * @return -1 if connections' timeouts are not set and no data processing
   4338  *         is pending, so external polling function may wait for sockets
   4339  *         activity for indefinite amount of time,
   4340  *         otherwise returned value is the the maximum amount of millisecond
   4341  *         that external polling function must wait for the activity of FDs.
   4342  * @note Available since #MHD_VERSION 0x00097701
   4343  * @ingroup event
   4344  */
   4345 _MHD_EXTERN int64_t
   4346 MHD_get_timeout64s (struct MHD_Daemon *daemon)
   4347 {
   4348   uint64_t utimeout;
   4349   if (MHD_NO == MHD_get_timeout64 (daemon, &utimeout))
   4350     return -1;
   4351   if (INT64_MAX < utimeout)
   4352     return INT64_MAX;
   4353 
   4354   return (int64_t) utimeout;
   4355 }
   4356 
   4357 
   4358 /**
   4359  * Obtain timeout value for external polling function for this daemon.
   4360  *
   4361  * This function set value to the amount of milliseconds for which polling
   4362  * function (`select()`, `poll()` or epoll) should at most block, not the
   4363  * timeout value set for connections.
   4364  *
   4365  * Any "external" sockets polling function must be called with the timeout
   4366  * value provided by this function (if returned value is non-negative).
   4367  * Smaller timeout values can be used for polling function if it is required
   4368  * for any reason, but using larger timeout value or no timeout (indefinite
   4369  * timeout) when this function returns non-negative value will break MHD
   4370  * processing logic and result in "hung" connections with data pending in
   4371  * network buffers and other problems.
   4372  *
   4373  * It is important to always use this function (or #MHD_get_timeout(),
   4374  * #MHD_get_timeout64(), #MHD_get_timeout64s() functions) when "external"
   4375  * polling is used.
   4376  * If this function returns non-negative value then #MHD_run() (or
   4377  * #MHD_run_from_select()) must be called right after return from polling
   4378  * function, regardless of the states of MHD FDs.
   4379  *
   4380  * In practice, if zero or positive value is returned then #MHD_run() (or
   4381  * #MHD_run_from_select()) must be called not later than returned amount of
   4382  * millisecond even if no activity is detected on sockets by sockets
   4383  * polling function.
   4384  * @remark To be called only from thread that process
   4385  * daemon's select()/poll()/etc.
   4386  *
   4387  * @param daemon the daemon to query for timeout
   4388  * @return -1 if connections' timeouts are not set and no data processing
   4389  *         is pending, so external polling function may wait for sockets
   4390  *         activity for indefinite amount of time,
   4391  *         otherwise returned value is the the maximum amount of millisecond
   4392  *         (capped at INT_MAX) that external polling function must wait
   4393  *         for the activity of FDs.
   4394  * @note Available since #MHD_VERSION 0x00097701
   4395  * @ingroup event
   4396  */
   4397 _MHD_EXTERN int
   4398 MHD_get_timeout_i (struct MHD_Daemon *daemon)
   4399 {
   4400 #if SIZEOF_INT >= SIZEOF_INT64_T
   4401   return MHD_get_timeout64s (daemon);
   4402 #else  /* SIZEOF_INT < SIZEOF_INT64_T */
   4403   const int64_t to64 = MHD_get_timeout64s (daemon);
   4404   if (INT_MAX >= to64)
   4405     return (int) to64;
   4406   return INT_MAX;
   4407 #endif /* SIZEOF_INT < SIZEOF_INT64_T */
   4408 }
   4409 
   4410 
   4411 /**
   4412  * Obtain timeout value for polling function for this daemon.
   4413  * @remark To be called only from the thread that processes
   4414  * daemon's select()/poll()/etc.
   4415  *
   4416  * @param daemon the daemon to query for timeout
   4417  * @param max_timeout the maximum return value (in milliseconds),
   4418  *                    ignored if set to '-1'
   4419  * @return timeout value in milliseconds or -1 if no timeout is expected.
   4420  */
   4421 static int64_t
   4422 get_timeout_millisec_ (struct MHD_Daemon *daemon,
   4423                        int32_t max_timeout)
   4424 {
   4425   uint64_t d_timeout;
   4426   mhd_assert (0 <= max_timeout || -1 == max_timeout);
   4427   if (0 == max_timeout)
   4428     return 0;
   4429 
   4430   if (MHD_NO == MHD_get_timeout64 (daemon, &d_timeout))
   4431     return max_timeout;
   4432 
   4433   if ((0 < max_timeout) && ((uint64_t) max_timeout < d_timeout))
   4434     return max_timeout;
   4435 
   4436   if (INT64_MAX <= d_timeout)
   4437     return INT64_MAX;
   4438 
   4439   return (int64_t) d_timeout;
   4440 }
   4441 
   4442 
   4443 /**
   4444  * Obtain timeout value for polling function for this daemon.
   4445  * @remark To be called only from the thread that processes
   4446  * daemon's select()/poll()/etc.
   4447  *
   4448  * @param daemon the daemon to query for timeout
   4449  * @param max_timeout the maximum return value (in milliseconds),
   4450  *                    ignored if set to '-1'
   4451  * @return timeout value in milliseconds, capped to INT_MAX, or
   4452  *         -1 if no timeout is expected.
   4453  */
   4454 static int
   4455 get_timeout_millisec_int (struct MHD_Daemon *daemon,
   4456                           int32_t max_timeout)
   4457 {
   4458   int64_t res;
   4459 
   4460   res = get_timeout_millisec_ (daemon, max_timeout);
   4461 #if SIZEOF_INT < SIZEOF_INT64_T
   4462   if (INT_MAX <= res)
   4463     return INT_MAX;
   4464 #endif /* SIZEOF_INT < SIZEOF_INT64_T */
   4465   return (int) res;
   4466 }
   4467 
   4468 
   4469 #endif /* HAVE_POLL || EPOLL_SUPPORT */
   4470 
   4471 /**
   4472  * Internal version of #MHD_run_from_select().
   4473  *
   4474  * @param daemon daemon to run select loop for
   4475  * @param read_fd_set read set
   4476  * @param write_fd_set write set
   4477  * @param except_fd_set except set
   4478  * @param fd_setsize value of FD_SETSIZE used when fd_sets were created
   4479  * @return #MHD_NO on serious errors, #MHD_YES on success
   4480  * @ingroup event
   4481  */
   4482 static enum MHD_Result
   4483 internal_run_from_select (struct MHD_Daemon *daemon,
   4484                           const fd_set *read_fd_set,
   4485                           const fd_set *write_fd_set,
   4486                           const fd_set *except_fd_set,
   4487                           int fd_setsize)
   4488 {
   4489   MHD_socket ds;
   4490 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   4491   struct MHD_UpgradeResponseHandle *urh;
   4492   struct MHD_UpgradeResponseHandle *urhn;
   4493 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   4494 
   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_valid_ID_ (daemon->tid)));
   4499   mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   4500               (MHD_thread_handle_ID_is_current_thread_ (daemon->tid)));
   4501 
   4502   mhd_assert (0 < fd_setsize);
   4503   (void) fd_setsize; /* Mute compiler warning */
   4504 #ifndef HAS_FD_SETSIZE_OVERRIDABLE
   4505   (void) fd_setsize; /* Mute compiler warning */
   4506   mhd_assert (((int) FD_SETSIZE) <= fd_setsize);
   4507   fd_setsize = FD_SETSIZE; /* Help compiler to optimise */
   4508 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   4509 
   4510   /* Clear ITC to avoid spinning select */
   4511   /* Do it before any other processing so new signals
   4512      will trigger select again and will be processed */
   4513   if (MHD_ITC_IS_VALID_ (daemon->itc))
   4514   { /* Have ITC */
   4515     bool need_to_clear_itc = true; /* ITC is always non-blocking, it is safe to clear even if ITC not activated */
   4516     if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (MHD_itc_r_fd_ (daemon->itc),
   4517                                          NULL, fd_setsize))
   4518       need_to_clear_itc = FD_ISSET (MHD_itc_r_fd_ (daemon->itc), \
   4519                                     (fd_set *) _MHD_DROP_CONST (read_fd_set)); /* Skip clearing, if not needed */
   4520     if (need_to_clear_itc)
   4521       MHD_itc_clear_ (daemon->itc);
   4522   }
   4523 
   4524   /* Reset. New value will be set when connections are processed. */
   4525   /* Note: no-op for thread-per-connection as it is always false in that mode. */
   4526   daemon->data_already_pending = false;
   4527 
   4528   /* Process externally added connection if any */
   4529   if (daemon->have_new)
   4530     new_connections_list_process_ (daemon);
   4531 
   4532   /* select connection thread handling type */
   4533   ds = daemon->listen_fd;
   4534   if ( (MHD_INVALID_SOCKET != ds) &&
   4535        (! daemon->was_quiesced) )
   4536   {
   4537     bool need_to_accept;
   4538     if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (ds, NULL, fd_setsize))
   4539       need_to_accept = FD_ISSET (ds,
   4540                                  (fd_set *) _MHD_DROP_CONST (read_fd_set));
   4541     else                                       /* Cannot check whether new connection are pending */
   4542       need_to_accept = daemon->listen_nonblk;  /* Try to accept if non-blocking */
   4543 
   4544     if (need_to_accept)
   4545       (void) MHD_accept_connection (daemon);
   4546   }
   4547 
   4548   if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   4549   {
   4550     /* do not have a thread per connection, process all connections now */
   4551     struct MHD_Connection *pos;
   4552     struct MHD_Connection *prev;
   4553 
   4554     for (pos = daemon->connections_tail; NULL != pos; pos = prev)
   4555     {
   4556       MHD_socket cs;
   4557       bool r_ready;
   4558       bool w_ready;
   4559       bool has_err;
   4560 
   4561       prev = pos->prev;
   4562       cs = pos->socket_fd;
   4563       if (MHD_INVALID_SOCKET == cs)
   4564         continue;
   4565 
   4566       if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (cs, NULL, fd_setsize))
   4567       {
   4568         r_ready = FD_ISSET (cs,
   4569                             (fd_set *) _MHD_DROP_CONST (read_fd_set));
   4570         w_ready = FD_ISSET (cs,
   4571                             (fd_set *) _MHD_DROP_CONST (write_fd_set));
   4572         has_err = (NULL != except_fd_set) &&
   4573                   FD_ISSET (cs,
   4574                             (fd_set *) _MHD_DROP_CONST (except_fd_set));
   4575       }
   4576       else
   4577       { /* Cannot check the real readiness */
   4578         r_ready = pos->sk_nonblck;
   4579         w_ready = r_ready;
   4580         has_err = false;
   4581       }
   4582       call_handlers (pos,
   4583                      r_ready,
   4584                      w_ready,
   4585                      has_err);
   4586     }
   4587   }
   4588 
   4589 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   4590   /* handle upgraded HTTPS connections */
   4591   for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
   4592   {
   4593     urhn = urh->prev;
   4594     /* update urh state based on select() output */
   4595     urh_from_fdset (urh,
   4596                     read_fd_set,
   4597                     write_fd_set,
   4598                     except_fd_set,
   4599                     fd_setsize);
   4600     /* call generic forwarding function for passing data */
   4601     process_urh (urh);
   4602     /* Finished forwarding? */
   4603     if ( (0 == urh->in_buffer_size) &&
   4604          (0 == urh->out_buffer_size) &&
   4605          (0 == urh->in_buffer_used) &&
   4606          (0 == urh->out_buffer_used) )
   4607     {
   4608       MHD_connection_finish_forward_ (urh->connection);
   4609       urh->clean_ready = true;
   4610       /* Resuming will move connection to cleanup list. */
   4611       MHD_resume_connection (urh->connection);
   4612     }
   4613   }
   4614 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   4615   MHD_cleanup_connections (daemon);
   4616   return MHD_YES;
   4617 }
   4618 
   4619 
   4620 #undef MHD_run_from_select
   4621 
   4622 /**
   4623  * Run webserver operations. This method should be called by clients
   4624  * in combination with #MHD_get_fdset and #MHD_get_timeout() if the
   4625  * client-controlled select method is used.
   4626  * This function specifies FD_SETSIZE used when provided fd_sets were
   4627  * created. It is important on platforms where FD_SETSIZE can be
   4628  * overridden.
   4629  *
   4630  * You can use this function instead of #MHD_run if you called
   4631  * 'select()' on the result from #MHD_get_fdset2().  File descriptors in
   4632  * the sets that are not controlled by MHD will be ignored.  Calling
   4633  * this function instead of #MHD_run() is more efficient as MHD will
   4634  * not have to call 'select()' again to determine which operations are
   4635  * ready.
   4636  *
   4637  * If #MHD_get_timeout() returned #MHD_YES, than this function must be
   4638  * called right after 'select()' returns regardless of detected activity
   4639  * on the daemon's FDs.
   4640  *
   4641  * This function cannot be used with daemon started with
   4642  * #MHD_USE_INTERNAL_POLLING_THREAD flag.
   4643  *
   4644  * @param daemon the daemon to run select loop for
   4645  * @param read_fd_set the read set
   4646  * @param write_fd_set the write set
   4647  * @param except_fd_set the except set
   4648  * @param fd_setsize the value of FD_SETSIZE
   4649  * @return #MHD_NO on serious errors, #MHD_YES on success
   4650  * @sa #MHD_get_fdset2(), #MHD_OPTION_APP_FD_SETSIZE
   4651  * @ingroup event
   4652  */
   4653 _MHD_EXTERN enum MHD_Result
   4654 MHD_run_from_select2 (struct MHD_Daemon *daemon,
   4655                       const fd_set *read_fd_set,
   4656                       const fd_set *write_fd_set,
   4657                       const fd_set *except_fd_set,
   4658                       unsigned int fd_setsize)
   4659 {
   4660   if (MHD_D_IS_USING_POLL_ (daemon) ||
   4661       MHD_D_IS_USING_THREADS_ (daemon))
   4662     return MHD_NO;
   4663   if ((NULL == read_fd_set) || (NULL == write_fd_set))
   4664     return MHD_NO;
   4665 #ifdef HAVE_MESSAGES
   4666   if (NULL == except_fd_set)
   4667   {
   4668     MHD_DLOG (daemon,
   4669               _ ("MHD_run_from_select() called with except_fd_set "
   4670                  "set to NULL. Such behavior is deprecated.\n"));
   4671   }
   4672 #endif /* HAVE_MESSAGES */
   4673 
   4674 #ifdef HAS_FD_SETSIZE_OVERRIDABLE
   4675   if (0 == fd_setsize)
   4676     return MHD_NO;
   4677   else if (((unsigned int) INT_MAX) < fd_setsize)
   4678     fd_setsize = (unsigned int) INT_MAX;
   4679 #ifdef HAVE_MESSAGES
   4680   else if (daemon->fdset_size > ((int) fd_setsize))
   4681   {
   4682     if (daemon->fdset_size_set_by_app)
   4683     {
   4684       MHD_DLOG (daemon,
   4685                 _ ("%s() called with fd_setsize (%u) " \
   4686                    "less than value set by MHD_OPTION_APP_FD_SETSIZE (%d). " \
   4687                    "Some socket FDs may be not processed. " \
   4688                    "Use MHD_OPTION_APP_FD_SETSIZE with the correct value.\n"),
   4689                 "MHD_run_from_select2", fd_setsize, daemon->fdset_size);
   4690     }
   4691     else
   4692     {
   4693       MHD_DLOG (daemon,
   4694                 _ ("%s() called with fd_setsize (%u) " \
   4695                    "less than FD_SETSIZE used by MHD (%d). " \
   4696                    "Some socket FDs may be not processed. " \
   4697                    "Consider using MHD_OPTION_APP_FD_SETSIZE option.\n"),
   4698                 "MHD_run_from_select2", fd_setsize, daemon->fdset_size);
   4699     }
   4700   }
   4701 #endif /* HAVE_MESSAGES */
   4702 #else  /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   4703   if (((unsigned int) FD_SETSIZE) > fd_setsize)
   4704   {
   4705 #ifdef HAVE_MESSAGES
   4706     MHD_DLOG (daemon,
   4707               _ ("%s() called with fd_setsize (%u) " \
   4708                  "less than fixed FD_SETSIZE value (%d) used on the " \
   4709                  "platform.\n"),
   4710               "MHD_run_from_select2", fd_setsize, (int) FD_SETSIZE);
   4711 #endif /* HAVE_MESSAGES */
   4712     return MHD_NO;
   4713   }
   4714 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   4715 
   4716   if (MHD_D_IS_USING_EPOLL_ (daemon))
   4717   {
   4718 #ifdef EPOLL_SUPPORT
   4719     enum MHD_Result ret = MHD_epoll (daemon,
   4720                                      0);
   4721 
   4722     MHD_cleanup_connections (daemon);
   4723     return ret;
   4724 #else  /* ! EPOLL_SUPPORT */
   4725     return MHD_NO;
   4726 #endif /* ! EPOLL_SUPPORT */
   4727   }
   4728 
   4729   /* Resuming external connections when using an extern mainloop  */
   4730   if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
   4731     resume_suspended_connections (daemon);
   4732 
   4733   return internal_run_from_select (daemon,
   4734                                    read_fd_set,
   4735                                    write_fd_set,
   4736                                    except_fd_set,
   4737                                    (int) fd_setsize);
   4738 }
   4739 
   4740 
   4741 /**
   4742  * Run webserver operations. This method should be called by clients
   4743  * in combination with #MHD_get_fdset and #MHD_get_timeout() if the
   4744  * client-controlled select method is used.
   4745  *
   4746  * You can use this function instead of #MHD_run if you called
   4747  * `select()` on the result from #MHD_get_fdset.  File descriptors in
   4748  * the sets that are not controlled by MHD will be ignored.  Calling
   4749  * this function instead of #MHD_run is more efficient as MHD will
   4750  * not have to call `select()` again to determine which operations are
   4751  * ready.
   4752  *
   4753  * If #MHD_get_timeout() returned #MHD_YES, than this function must be
   4754  * called right after `select()` returns regardless of detected activity
   4755  * on the daemon's FDs.
   4756  *
   4757  * This function cannot be used with daemon started with
   4758  * #MHD_USE_INTERNAL_POLLING_THREAD flag.
   4759  *
   4760  * @param daemon daemon to run select loop for
   4761  * @param read_fd_set read set
   4762  * @param write_fd_set write set
   4763  * @param except_fd_set except set
   4764  * @return #MHD_NO on serious errors, #MHD_YES on success
   4765  * @ingroup event
   4766  */
   4767 _MHD_EXTERN enum MHD_Result
   4768 MHD_run_from_select (struct MHD_Daemon *daemon,
   4769                      const fd_set *read_fd_set,
   4770                      const fd_set *write_fd_set,
   4771                      const fd_set *except_fd_set)
   4772 {
   4773   return MHD_run_from_select2 (daemon,
   4774                                read_fd_set,
   4775                                write_fd_set,
   4776                                except_fd_set,
   4777 #ifdef HAS_FD_SETSIZE_OVERRIDABLE
   4778                                daemon->fdset_size_set_by_app ?
   4779                                ((unsigned int) daemon->fdset_size) :
   4780                                ((unsigned int) _MHD_SYS_DEFAULT_FD_SETSIZE)
   4781 #else  /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   4782                                ((unsigned int) _MHD_SYS_DEFAULT_FD_SETSIZE)
   4783 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   4784                                );
   4785 }
   4786 
   4787 
   4788 /**
   4789  * Main internal select() call.  Will compute select sets, call select()
   4790  * and then #internal_run_from_select with the result.
   4791  *
   4792  * @param daemon daemon to run select() loop for
   4793  * @param millisec the maximum time in milliseconds to wait for events,
   4794  *                 set to '0' for non-blocking processing,
   4795  *                 set to '-1' to wait indefinitely.
   4796  * @return #MHD_NO on serious errors, #MHD_YES on success
   4797  */
   4798 static enum MHD_Result
   4799 MHD_select (struct MHD_Daemon *daemon,
   4800             int32_t millisec)
   4801 {
   4802   int num_ready;
   4803   fd_set rs;
   4804   fd_set ws;
   4805   fd_set es;
   4806   MHD_socket maxsock;
   4807   struct timeval timeout;
   4808   struct timeval *tv;
   4809   int err_state;
   4810   MHD_socket ls;
   4811 
   4812   timeout.tv_sec = 0;
   4813   timeout.tv_usec = 0;
   4814   if (daemon->shutdown)
   4815     return MHD_NO;
   4816   FD_ZERO (&rs);
   4817   FD_ZERO (&ws);
   4818   FD_ZERO (&es);
   4819   maxsock = MHD_INVALID_SOCKET;
   4820   err_state = MHD_NO;
   4821   if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
   4822        (MHD_NO != resume_suspended_connections (daemon)) &&
   4823        (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) )
   4824     millisec = 0;
   4825 
   4826   if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   4827   {
   4828     /* single-threaded, go over everything */
   4829     if (MHD_NO ==
   4830         internal_get_fdset2 (daemon,
   4831                              &rs,
   4832                              &ws,
   4833                              &es,
   4834                              &maxsock,
   4835                              (int) FD_SETSIZE))
   4836     {
   4837 #ifdef HAVE_MESSAGES
   4838       MHD_DLOG (daemon,
   4839                 _ ("Could not obtain daemon fdsets.\n"));
   4840 #endif
   4841       err_state = MHD_YES;
   4842     }
   4843   }
   4844   else
   4845   {
   4846     bool itc_added;
   4847     /* accept only, have one thread per connection */
   4848     itc_added = false;
   4849     if (MHD_ITC_IS_VALID_ (daemon->itc))
   4850     {
   4851       itc_added = MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
   4852                                       &rs,
   4853                                       &maxsock,
   4854                                       (int) FD_SETSIZE);
   4855       if (! itc_added)
   4856       {
   4857 #ifdef HAVE_MESSAGES
   4858         MHD_DLOG (daemon, _ ("Could not add control inter-thread " \
   4859                              "communication channel FD to fdset.\n"));
   4860 #endif
   4861         err_state = MHD_YES;
   4862       }
   4863     }
   4864     if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
   4865          (! daemon->was_quiesced) )
   4866     {
   4867       /* Stop listening if we are at the configured connection limit */
   4868       /* If we're at the connection limit, no point in really
   4869          accepting new connections; however, make sure we do not miss
   4870          the shutdown OR the termination of an existing connection; so
   4871          only do this optimisation if we have a signaling ITC in
   4872          place. */
   4873       if (! itc_added ||
   4874           ((daemon->connections < daemon->connection_limit) &&
   4875            ! daemon->at_limit))
   4876       {
   4877         if (! MHD_add_to_fd_set_ (ls,
   4878                                   &rs,
   4879                                   &maxsock,
   4880                                   (int) FD_SETSIZE))
   4881         {
   4882 #ifdef HAVE_MESSAGES
   4883           MHD_DLOG (daemon,
   4884                     _ ("Could not add listen socket to fdset.\n"));
   4885 #endif
   4886           err_state = MHD_YES;
   4887         }
   4888       }
   4889     }
   4890   }
   4891 
   4892   if (MHD_NO != err_state)
   4893     millisec = 0;
   4894   if (0 == millisec)
   4895   {
   4896     timeout.tv_usec = 0;
   4897     timeout.tv_sec = 0;
   4898     tv = &timeout;
   4899   }
   4900   else
   4901   {
   4902     uint64_t mhd_tmo;
   4903     uint64_t select_tmo;
   4904 
   4905     if ( (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) &&
   4906          (MHD_NO != MHD_get_timeout64 (daemon, &mhd_tmo)) )
   4907     {
   4908       if ( (0 < millisec) &&
   4909            (mhd_tmo > (uint64_t) millisec) )
   4910         select_tmo = (uint64_t) millisec;
   4911       else
   4912         select_tmo = mhd_tmo;
   4913       tv = &timeout; /* have timeout value */
   4914     }
   4915     else if (0 < millisec)
   4916     {
   4917       select_tmo = (uint64_t) millisec;
   4918       tv = &timeout; /* have timeout value */
   4919     }
   4920     else
   4921     {
   4922       select_tmo = 0; /* Not actually used, silent compiler warning */
   4923       tv = NULL;
   4924     }
   4925 
   4926     if (NULL != tv)
   4927     { /* have timeout value */
   4928 #if (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC
   4929       if (select_tmo / 1000 > TIMEVAL_TV_SEC_MAX)
   4930         timeout.tv_sec = TIMEVAL_TV_SEC_MAX;
   4931       else
   4932 #endif /* (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC */
   4933       timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) (select_tmo / 1000);
   4934 
   4935       timeout.tv_usec = ((uint16_t) (select_tmo % 1000)) * ((int32_t) 1000);
   4936     }
   4937   }
   4938   num_ready = MHD_SYS_select_ (maxsock + 1,
   4939                                &rs,
   4940                                &ws,
   4941                                &es,
   4942                                tv);
   4943   if (daemon->shutdown)
   4944     return MHD_NO;
   4945   if (num_ready < 0)
   4946   {
   4947     const int err = MHD_socket_get_error_ ();
   4948     if (MHD_SCKT_ERR_IS_EINTR_ (err))
   4949       return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
   4950 #ifdef HAVE_MESSAGES
   4951     MHD_DLOG (daemon,
   4952               _ ("select failed: %s\n"),
   4953               MHD_socket_strerr_ (err));
   4954 #endif
   4955     return MHD_NO;
   4956   }
   4957   if (MHD_NO != internal_run_from_select (daemon,
   4958                                           &rs,
   4959                                           &ws,
   4960                                           &es,
   4961                                           (int) FD_SETSIZE))
   4962     return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
   4963   return MHD_NO;
   4964 }
   4965 
   4966 
   4967 #ifdef HAVE_POLL
   4968 /**
   4969  * Process all of our connections and possibly the server
   4970  * socket using poll().
   4971  *
   4972  * @param daemon daemon to run poll loop for
   4973  * @param millisec the maximum time in milliseconds to wait for events,
   4974  *                 set to '0' for non-blocking processing,
   4975  *                 set to '-1' to wait indefinitely.
   4976  * @return #MHD_NO on serious errors, #MHD_YES on success
   4977  */
   4978 static enum MHD_Result
   4979 MHD_poll_all (struct MHD_Daemon *daemon,
   4980               int32_t millisec)
   4981 {
   4982   unsigned int num_connections;
   4983   struct MHD_Connection *pos;
   4984   struct MHD_Connection *prev;
   4985 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   4986   struct MHD_UpgradeResponseHandle *urh;
   4987   struct MHD_UpgradeResponseHandle *urhn;
   4988 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   4989 
   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_valid_ID_ (daemon->tid)));
   4994   mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   4995               (MHD_thread_handle_ID_is_current_thread_ (daemon->tid)));
   4996 
   4997   if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
   4998        (MHD_NO != resume_suspended_connections (daemon)) )
   4999     millisec = 0;
   5000 
   5001   /* count number of connections and thus determine poll set size */
   5002   num_connections = 0;
   5003   for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
   5004     num_connections++;
   5005 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5006   for (urh = daemon->urh_head; NULL != urh; urh = urh->next)
   5007     num_connections += 2;
   5008 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5009   {
   5010     unsigned int i;
   5011     int timeout;
   5012     unsigned int poll_server;
   5013     int poll_listen;
   5014     int poll_itc_idx;
   5015     struct pollfd *p;
   5016     MHD_socket ls;
   5017 
   5018     p = MHD_calloc_ ((2 + (size_t) num_connections),
   5019                      sizeof (struct pollfd));
   5020     if (NULL == p)
   5021     {
   5022 #ifdef HAVE_MESSAGES
   5023       MHD_DLOG (daemon,
   5024                 _ ("Error allocating memory: %s\n"),
   5025                 MHD_strerror_ (errno));
   5026 #endif
   5027       return MHD_NO;
   5028     }
   5029     poll_server = 0;
   5030     poll_listen = -1;
   5031     if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
   5032          (! daemon->was_quiesced) &&
   5033          (daemon->connections < daemon->connection_limit) &&
   5034          (! daemon->at_limit) )
   5035     {
   5036       /* only listen if we are not at the connection limit */
   5037       p[poll_server].fd = ls;
   5038       p[poll_server].events = POLLIN;
   5039       p[poll_server].revents = 0;
   5040       poll_listen = (int) poll_server;
   5041       poll_server++;
   5042     }
   5043     poll_itc_idx = -1;
   5044     if (MHD_ITC_IS_VALID_ (daemon->itc))
   5045     {
   5046       p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc);
   5047       p[poll_server].events = POLLIN;
   5048       p[poll_server].revents = 0;
   5049       poll_itc_idx = (int) poll_server;
   5050       poll_server++;
   5051     }
   5052 
   5053     timeout = get_timeout_millisec_int (daemon, millisec);
   5054 
   5055     i = 0;
   5056     for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
   5057     {
   5058       p[poll_server + i].fd = pos->socket_fd;
   5059       switch (pos->event_loop_info)
   5060       {
   5061       case MHD_EVENT_LOOP_INFO_READ:
   5062       case MHD_EVENT_LOOP_INFO_PROCESS_READ:
   5063         p[poll_server + i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
   5064         break;
   5065       case MHD_EVENT_LOOP_INFO_WRITE:
   5066         p[poll_server + i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
   5067         break;
   5068       case MHD_EVENT_LOOP_INFO_PROCESS:
   5069         p[poll_server + i].events |=  MHD_POLL_EVENTS_ERR_DISC;
   5070         break;
   5071       case MHD_EVENT_LOOP_INFO_CLEANUP:
   5072         timeout = 0; /* clean up "pos" immediately */
   5073         break;
   5074       }
   5075       i++;
   5076     }
   5077 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5078     for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
   5079     {
   5080       urh_to_pollfd (urh, &(p[poll_server + i]));
   5081       i += 2;
   5082     }
   5083 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5084     if (0 == poll_server + num_connections)
   5085     {
   5086       free (p);
   5087       return MHD_YES;
   5088     }
   5089     if (MHD_sys_poll_ (p,
   5090                        poll_server + num_connections,
   5091                        timeout) < 0)
   5092     {
   5093       const int err = MHD_socket_get_error_ ();
   5094       if (MHD_SCKT_ERR_IS_EINTR_ (err))
   5095       {
   5096         free (p);
   5097         return MHD_YES;
   5098       }
   5099 #ifdef HAVE_MESSAGES
   5100       MHD_DLOG (daemon,
   5101                 _ ("poll failed: %s\n"),
   5102                 MHD_socket_strerr_ (err));
   5103 #endif
   5104       free (p);
   5105       return MHD_NO;
   5106     }
   5107 
   5108     /* handle ITC FD */
   5109     /* do it before any other processing so
   5110        new signals will be processed in next loop */
   5111     if ( (-1 != poll_itc_idx) &&
   5112          (0 != (p[poll_itc_idx].revents & POLLIN)) )
   5113       MHD_itc_clear_ (daemon->itc);
   5114 
   5115     /* handle shutdown */
   5116     if (daemon->shutdown)
   5117     {
   5118       free (p);
   5119       return MHD_NO;
   5120     }
   5121 
   5122     /* Process externally added connection if any */
   5123     if (daemon->have_new)
   5124       new_connections_list_process_ (daemon);
   5125 
   5126     /* handle 'listen' FD */
   5127     if ( (-1 != poll_listen) &&
   5128          (0 != (p[poll_listen].revents & POLLIN)) )
   5129       (void) MHD_accept_connection (daemon);
   5130 
   5131     /* Reset. New value will be set when connections are processed. */
   5132     daemon->data_already_pending = false;
   5133 
   5134     i = 0;
   5135     prev = daemon->connections_tail;
   5136     while (NULL != (pos = prev))
   5137     {
   5138       prev = pos->prev;
   5139       /* first, sanity checks */
   5140       if (i >= num_connections)
   5141         break;     /* connection list changed somehow, retry later ... */
   5142       if (p[poll_server + i].fd != pos->socket_fd)
   5143         continue;  /* fd mismatch, something else happened, retry later ... */
   5144       call_handlers (pos,
   5145                      0 != (p[poll_server + i].revents & POLLIN),
   5146                      0 != (p[poll_server + i].revents & POLLOUT),
   5147                      0 != (p[poll_server + i].revents
   5148                            & MHD_POLL_REVENTS_ERR_DISC));
   5149       i++;
   5150     }
   5151 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5152     for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
   5153     {
   5154       if (i >= num_connections)
   5155         break;   /* connection list changed somehow, retry later ... */
   5156 
   5157       /* Get next connection here as connection can be removed
   5158        * from 'daemon->urh_head' list. */
   5159       urhn = urh->prev;
   5160       /* Check for fd mismatch. FIXME: required for safety? */
   5161       if ((p[poll_server + i].fd != urh->connection->socket_fd) ||
   5162           (p[poll_server + i + 1].fd != urh->mhd.socket))
   5163         break;
   5164       urh_from_pollfd (urh,
   5165                        &p[poll_server + i]);
   5166       i += 2;
   5167       process_urh (urh);
   5168       /* Finished forwarding? */
   5169       if ( (0 == urh->in_buffer_size) &&
   5170            (0 == urh->out_buffer_size) &&
   5171            (0 == urh->in_buffer_used) &&
   5172            (0 == urh->out_buffer_used) )
   5173       {
   5174         /* MHD_connection_finish_forward_() will remove connection from
   5175          * 'daemon->urh_head' list. */
   5176         MHD_connection_finish_forward_ (urh->connection);
   5177         urh->clean_ready = true;
   5178         /* If 'urh->was_closed' already was set to true, connection will be
   5179          * moved immediately to cleanup list. Otherwise connection
   5180          * will stay in suspended list until 'urh' will be marked
   5181          * with 'was_closed' by application. */
   5182         MHD_resume_connection (urh->connection);
   5183       }
   5184     }
   5185 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5186 
   5187     free (p);
   5188   }
   5189   return MHD_YES;
   5190 }
   5191 
   5192 
   5193 /**
   5194  * Process only the listen socket using poll().
   5195  *
   5196  * @param daemon daemon to run poll loop for
   5197  * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
   5198  * @return #MHD_NO on serious errors, #MHD_YES on success
   5199  */
   5200 static enum MHD_Result
   5201 MHD_poll_listen_socket (struct MHD_Daemon *daemon,
   5202                         int may_block)
   5203 {
   5204   struct pollfd p[2];
   5205   int timeout;
   5206   unsigned int poll_count;
   5207   int poll_listen;
   5208   int poll_itc_idx;
   5209   MHD_socket ls;
   5210 
   5211   mhd_assert (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid));
   5212   mhd_assert (MHD_thread_handle_ID_is_current_thread_ (daemon->tid));
   5213 
   5214   memset (&p,
   5215           0,
   5216           sizeof (p));
   5217   poll_count = 0;
   5218   poll_listen = -1;
   5219   poll_itc_idx = -1;
   5220   if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
   5221        (! daemon->was_quiesced) )
   5222 
   5223   {
   5224     p[poll_count].fd = ls;
   5225     p[poll_count].events = POLLIN;
   5226     p[poll_count].revents = 0;
   5227     poll_listen = (int) poll_count;
   5228     poll_count++;
   5229   }
   5230   if (MHD_ITC_IS_VALID_ (daemon->itc))
   5231   {
   5232     p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc);
   5233     p[poll_count].events = POLLIN;
   5234     p[poll_count].revents = 0;
   5235     poll_itc_idx = (int) poll_count;
   5236     poll_count++;
   5237   }
   5238 
   5239   if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
   5240     (void) resume_suspended_connections (daemon);
   5241 
   5242   if (MHD_NO == may_block)
   5243     timeout = 0;
   5244   else
   5245     timeout = -1;
   5246   if (0 == poll_count)
   5247     return MHD_YES;
   5248   if (MHD_sys_poll_ (p,
   5249                      poll_count,
   5250                      timeout) < 0)
   5251   {
   5252     const int err = MHD_socket_get_error_ ();
   5253 
   5254     if (MHD_SCKT_ERR_IS_EINTR_ (err))
   5255       return MHD_YES;
   5256 #ifdef HAVE_MESSAGES
   5257     MHD_DLOG (daemon,
   5258               _ ("poll failed: %s\n"),
   5259               MHD_socket_strerr_ (err));
   5260 #endif
   5261     return MHD_NO;
   5262   }
   5263   if ( (0 <= poll_itc_idx) &&
   5264        (0 != (p[poll_itc_idx].revents & POLLIN)) )
   5265     MHD_itc_clear_ (daemon->itc);
   5266 
   5267   /* handle shutdown */
   5268   if (daemon->shutdown)
   5269     return MHD_NO;
   5270 
   5271   /* Process externally added connection if any */
   5272   if (daemon->have_new)
   5273     new_connections_list_process_ (daemon);
   5274 
   5275   if ( (0 <= poll_listen) &&
   5276        (0 != (p[poll_listen].revents & POLLIN)) )
   5277     (void) MHD_accept_connection (daemon);
   5278   return MHD_YES;
   5279 }
   5280 
   5281 
   5282 #endif
   5283 
   5284 #ifdef HAVE_POLL
   5285 
   5286 /**
   5287  * Do poll()-based processing.
   5288  *
   5289  * @param daemon daemon to run poll()-loop for
   5290  * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
   5291  * @return #MHD_NO on serious errors, #MHD_YES on success
   5292  */
   5293 static enum MHD_Result
   5294 MHD_poll (struct MHD_Daemon *daemon,
   5295           int may_block)
   5296 {
   5297   if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   5298     return MHD_poll_all (daemon,
   5299                          may_block ? -1 : 0);
   5300   return MHD_poll_listen_socket (daemon,
   5301                                  may_block);
   5302 }
   5303 
   5304 
   5305 #endif /* HAVE_POLL */
   5306 
   5307 
   5308 #ifdef EPOLL_SUPPORT
   5309 
   5310 /**
   5311  * How many events to we process at most per epoll() call?  Trade-off
   5312  * between required stack-size and number of system calls we have to
   5313  * make; 128 should be way enough to avoid more than one system call
   5314  * for most scenarios, and still be moderate in stack size
   5315  * consumption.  Embedded systems might want to choose a smaller value
   5316  * --- but why use epoll() on such a system in the first place?
   5317  */
   5318 #define MAX_EVENTS 128
   5319 
   5320 
   5321 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5322 
   5323 /**
   5324  * Checks whether @a urh has some data to process.
   5325  *
   5326  * @param urh upgrade handler to analyse
   5327  * @return 'true' if @a urh has some data to process,
   5328  *         'false' otherwise
   5329  */
   5330 static bool
   5331 is_urh_ready (struct MHD_UpgradeResponseHandle *const urh)
   5332 {
   5333   const struct MHD_Connection *const connection = urh->connection;
   5334 
   5335   if ( (0 == urh->in_buffer_size) &&
   5336        (0 == urh->out_buffer_size) &&
   5337        (0 == urh->in_buffer_used) &&
   5338        (0 == urh->out_buffer_used) )
   5339     return false;
   5340   if (connection->daemon->shutdown)
   5341     return true;
   5342   if ( ( (0 != ((MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_ERROR)
   5343                 & urh->app.celi)) ||
   5344          (connection->tls_read_ready) ) &&
   5345        (urh->in_buffer_used < urh->in_buffer_size) )
   5346     return true;
   5347   if ( ( (0 != ((MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_ERROR)
   5348                 & urh->mhd.celi)) ||
   5349          urh->was_closed) &&
   5350        (urh->out_buffer_used < urh->out_buffer_size) )
   5351     return true;
   5352   if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
   5353        (urh->out_buffer_used > 0) )
   5354     return true;
   5355   if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
   5356        (urh->in_buffer_used > 0) )
   5357     return true;
   5358   return false;
   5359 }
   5360 
   5361 
   5362 /**
   5363  * Do epoll()-based processing for TLS connections that have been
   5364  * upgraded.  This requires a separate epoll() invocation as we
   5365  * cannot use the `struct MHD_Connection` data structures for
   5366  * the `union epoll_data` in this case.
   5367  * @remark To be called only from thread that process
   5368  * daemon's select()/poll()/etc.
   5369  */
   5370 static enum MHD_Result
   5371 run_epoll_for_upgrade (struct MHD_Daemon *daemon)
   5372 {
   5373   struct epoll_event events[MAX_EVENTS];
   5374   int num_events;
   5375   struct MHD_UpgradeResponseHandle *pos;
   5376   struct MHD_UpgradeResponseHandle *prev;
   5377 
   5378 #ifdef MHD_USE_THREADS
   5379   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   5380                MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   5381 #endif /* MHD_USE_THREADS */
   5382 
   5383   num_events = MAX_EVENTS;
   5384   while (0 != num_events)
   5385   {
   5386     unsigned int i;
   5387     /* update event masks */
   5388     num_events = epoll_wait (daemon->epoll_upgrade_fd,
   5389                              events,
   5390                              MAX_EVENTS,
   5391                              0);
   5392     if (-1 == num_events)
   5393     {
   5394       const int err = MHD_socket_get_error_ ();
   5395 
   5396       if (MHD_SCKT_ERR_IS_EINTR_ (err))
   5397         return MHD_YES;
   5398 #ifdef HAVE_MESSAGES
   5399       MHD_DLOG (daemon,
   5400                 _ ("Call to epoll_wait failed: %s\n"),
   5401                 MHD_socket_strerr_ (err));
   5402 #endif
   5403       return MHD_NO;
   5404     }
   5405     for (i = 0; i < (unsigned int) num_events; i++)
   5406     {
   5407       struct UpgradeEpollHandle *const ueh = events[i].data.ptr;
   5408       struct MHD_UpgradeResponseHandle *const urh = ueh->urh;
   5409       bool new_err_state = false;
   5410 
   5411       if (urh->clean_ready)
   5412         continue;
   5413 
   5414       /* Update ueh state based on what is ready according to epoll() */
   5415       if (0 != (events[i].events & EPOLLIN))
   5416       {
   5417         ueh->celi |= MHD_EPOLL_STATE_READ_READY;
   5418       }
   5419       if (0 != (events[i].events & EPOLLOUT))
   5420       {
   5421         ueh->celi |= MHD_EPOLL_STATE_WRITE_READY;
   5422       }
   5423       if (0 != (events[i].events & EPOLLHUP))
   5424       {
   5425         ueh->celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
   5426       }
   5427 
   5428       if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) &&
   5429            (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
   5430       {
   5431         /* Process new error state only one time and avoid continuously
   5432          * marking this connection as 'ready'. */
   5433         ueh->celi |= MHD_EPOLL_STATE_ERROR;
   5434         new_err_state = true;
   5435       }
   5436       if (! urh->in_eready_list)
   5437       {
   5438         if (new_err_state ||
   5439             is_urh_ready (urh))
   5440         {
   5441           EDLL_insert (daemon->eready_urh_head,
   5442                        daemon->eready_urh_tail,
   5443                        urh);
   5444           urh->in_eready_list = true;
   5445         }
   5446       }
   5447     }
   5448   }
   5449   prev = daemon->eready_urh_tail;
   5450   while (NULL != (pos = prev))
   5451   {
   5452     prev = pos->prevE;
   5453     process_urh (pos);
   5454     if (! is_urh_ready (pos))
   5455     {
   5456       EDLL_remove (daemon->eready_urh_head,
   5457                    daemon->eready_urh_tail,
   5458                    pos);
   5459       pos->in_eready_list = false;
   5460     }
   5461     /* Finished forwarding? */
   5462     if ( (0 == pos->in_buffer_size) &&
   5463          (0 == pos->out_buffer_size) &&
   5464          (0 == pos->in_buffer_used) &&
   5465          (0 == pos->out_buffer_used) )
   5466     {
   5467       MHD_connection_finish_forward_ (pos->connection);
   5468       pos->clean_ready = true;
   5469       /* If 'pos->was_closed' already was set to true, connection
   5470        * will be moved immediately to cleanup list. Otherwise
   5471        * connection will stay in suspended list until 'pos' will
   5472        * be marked with 'was_closed' by application. */
   5473       MHD_resume_connection (pos->connection);
   5474     }
   5475   }
   5476 
   5477   return MHD_YES;
   5478 }
   5479 
   5480 
   5481 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5482 
   5483 
   5484 /**
   5485  * Pointer-marker to distinguish ITC slot in epoll sets.
   5486  */
   5487 static const char *const epoll_itc_marker = "itc_marker";
   5488 
   5489 
   5490 /**
   5491  * Do epoll()-based processing.
   5492  *
   5493  * @param daemon daemon to run poll loop for
   5494  * @param millisec the maximum time in milliseconds to wait for events,
   5495  *                 set to '0' for non-blocking processing,
   5496  *                 set to '-1' to wait indefinitely.
   5497  * @return #MHD_NO on serious errors, #MHD_YES on success
   5498  */
   5499 static enum MHD_Result
   5500 MHD_epoll (struct MHD_Daemon *daemon,
   5501            int32_t millisec)
   5502 {
   5503 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5504   static const char *const upgrade_marker = "upgrade_ptr";
   5505 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5506   struct MHD_Connection *pos;
   5507   struct MHD_Connection *prev;
   5508   struct epoll_event events[MAX_EVENTS];
   5509   struct epoll_event event;
   5510   int timeout_ms;
   5511   int num_events;
   5512   unsigned int i;
   5513   MHD_socket ls;
   5514 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5515   bool run_upgraded = false;
   5516 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5517   bool need_to_accept;
   5518 
   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_valid_ID_ (daemon->tid)));
   5523   mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   5524               (MHD_thread_handle_ID_is_current_thread_ (daemon->tid)));
   5525 
   5526   if (-1 == daemon->epoll_fd)
   5527     return MHD_NO; /* we're down! */
   5528   if (daemon->shutdown)
   5529     return MHD_NO;
   5530   if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
   5531        (! daemon->was_quiesced) &&
   5532        (daemon->connections < daemon->connection_limit) &&
   5533        (! daemon->listen_socket_in_epoll) &&
   5534        (! daemon->at_limit) )
   5535   {
   5536     event.events = EPOLLIN | EPOLLRDHUP;
   5537     event.data.ptr = daemon;
   5538     if (0 != epoll_ctl (daemon->epoll_fd,
   5539                         EPOLL_CTL_ADD,
   5540                         ls,
   5541                         &event))
   5542     {
   5543 #ifdef HAVE_MESSAGES
   5544       MHD_DLOG (daemon,
   5545                 _ ("Call to epoll_ctl failed: %s\n"),
   5546                 MHD_socket_last_strerr_ ());
   5547 #endif
   5548       return MHD_NO;
   5549     }
   5550     daemon->listen_socket_in_epoll = true;
   5551   }
   5552   if ( (daemon->was_quiesced) &&
   5553        (daemon->listen_socket_in_epoll) )
   5554   {
   5555     if ( (0 != epoll_ctl (daemon->epoll_fd,
   5556                           EPOLL_CTL_DEL,
   5557                           ls,
   5558                           NULL)) &&
   5559          (ENOENT != errno) )   /* ENOENT can happen due to race with
   5560                                   #MHD_quiesce_daemon() */
   5561       MHD_PANIC ("Failed to remove listen FD from epoll set.\n");
   5562     daemon->listen_socket_in_epoll = false;
   5563   }
   5564 
   5565 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5566   if ( ( (! daemon->upgrade_fd_in_epoll) &&
   5567          (-1 != daemon->epoll_upgrade_fd) ) )
   5568   {
   5569     event.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP;
   5570     event.data.ptr = _MHD_DROP_CONST (upgrade_marker);
   5571     if (0 != epoll_ctl (daemon->epoll_fd,
   5572                         EPOLL_CTL_ADD,
   5573                         daemon->epoll_upgrade_fd,
   5574                         &event))
   5575     {
   5576 #ifdef HAVE_MESSAGES
   5577       MHD_DLOG (daemon,
   5578                 _ ("Call to epoll_ctl failed: %s\n"),
   5579                 MHD_socket_last_strerr_ ());
   5580 #endif
   5581       return MHD_NO;
   5582     }
   5583     daemon->upgrade_fd_in_epoll = true;
   5584   }
   5585 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5586   if ( (daemon->listen_socket_in_epoll) &&
   5587        ( (daemon->connections == daemon->connection_limit) ||
   5588          (daemon->at_limit) ||
   5589          (daemon->was_quiesced) ) )
   5590   {
   5591     /* we're at the connection limit, disable listen socket
   5592  for event loop for now */
   5593     if (0 != epoll_ctl (daemon->epoll_fd,
   5594                         EPOLL_CTL_DEL,
   5595                         ls,
   5596                         NULL))
   5597       MHD_PANIC (_ ("Failed to remove listen FD from epoll set.\n"));
   5598     daemon->listen_socket_in_epoll = false;
   5599   }
   5600 
   5601   if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
   5602        (MHD_NO != resume_suspended_connections (daemon)) )
   5603     millisec = 0;
   5604 
   5605   timeout_ms = get_timeout_millisec_int (daemon,
   5606                                          millisec);
   5607 
   5608   /* Reset. New value will be set when connections are processed. */
   5609   /* Note: Used mostly for uniformity here as same situation is
   5610    * signaled in epoll mode by non-empty eready DLL. */
   5611   daemon->data_already_pending = false;
   5612 
   5613   need_to_accept = false;
   5614   /* drain 'epoll' event queue; need to iterate as we get at most
   5615      MAX_EVENTS in one system call here; in practice this should
   5616      pretty much mean only one round, but better an extra loop here
   5617      than unfair behavior... */
   5618   num_events = MAX_EVENTS;
   5619   while (MAX_EVENTS == num_events)
   5620   {
   5621     /* update event masks */
   5622     num_events = epoll_wait (daemon->epoll_fd,
   5623                              events,
   5624                              MAX_EVENTS,
   5625                              timeout_ms);
   5626     if (-1 == num_events)
   5627     {
   5628       const int err = MHD_socket_get_error_ ();
   5629       if (MHD_SCKT_ERR_IS_EINTR_ (err))
   5630         return MHD_YES;
   5631 #ifdef HAVE_MESSAGES
   5632       MHD_DLOG (daemon,
   5633                 _ ("Call to epoll_wait failed: %s\n"),
   5634                 MHD_socket_strerr_ (err));
   5635 #endif
   5636       return MHD_NO;
   5637     }
   5638     for (i = 0; i < (unsigned int) num_events; i++)
   5639     {
   5640       /* First, check for the values of `ptr` that would indicate
   5641          that this event is not about a normal connection. */
   5642       if (NULL == events[i].data.ptr)
   5643         continue;     /* shutdown signal! */
   5644 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5645       if (upgrade_marker == events[i].data.ptr)
   5646       {
   5647         /* activity on an upgraded connection, we process
   5648            those in a separate epoll() */
   5649         run_upgraded = true;
   5650         continue;
   5651       }
   5652 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5653       if (epoll_itc_marker == events[i].data.ptr)
   5654       {
   5655         /* It's OK to clear ITC here as all external
   5656            conditions will be processed later. */
   5657         MHD_itc_clear_ (daemon->itc);
   5658         continue;
   5659       }
   5660       if (daemon == events[i].data.ptr)
   5661       {
   5662         /* Check for error conditions on listen socket. */
   5663         /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */
   5664         if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
   5665           need_to_accept = true;
   5666         continue;
   5667       }
   5668       /* this is an event relating to a 'normal' connection,
   5669          remember the event and if appropriate mark the
   5670          connection as 'eready'. */
   5671       pos = events[i].data.ptr;
   5672       /* normal processing: update read/write data */
   5673       if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
   5674       {
   5675         pos->epoll_state |= MHD_EPOLL_STATE_ERROR;
   5676         if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
   5677         {
   5678           EDLL_insert (daemon->eready_head,
   5679                        daemon->eready_tail,
   5680                        pos);
   5681           pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
   5682         }
   5683       }
   5684       else
   5685       {
   5686         if (0 != (events[i].events & EPOLLIN))
   5687         {
   5688           pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
   5689           if ( ( (0 != (MHD_EVENT_LOOP_INFO_READ & pos->event_loop_info)) ||
   5690                  (pos->read_buffer_size > pos->read_buffer_offset) ) &&
   5691                (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
   5692           {
   5693             EDLL_insert (daemon->eready_head,
   5694                          daemon->eready_tail,
   5695                          pos);
   5696             pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
   5697           }
   5698         }
   5699         if (0 != (events[i].events & EPOLLOUT))
   5700         {
   5701           pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
   5702           if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
   5703                (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
   5704           {
   5705             EDLL_insert (daemon->eready_head,
   5706                          daemon->eready_tail,
   5707                          pos);
   5708             pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
   5709           }
   5710         }
   5711       }
   5712     }
   5713   }
   5714 
   5715   /* Process externally added connection if any */
   5716   if (daemon->have_new)
   5717     new_connections_list_process_ (daemon);
   5718 
   5719   if (need_to_accept)
   5720   {
   5721     unsigned int series_length = 0;
   5722 
   5723     /* Run 'accept' until it fails or daemon at limit of connections.
   5724      * Do not accept more then 10 connections at once. The rest will
   5725      * be accepted on next turn (level trigger is used for listen
   5726      * socket). */
   5727     while ( (MHD_NO != MHD_accept_connection (daemon)) &&
   5728             (series_length < 10) &&
   5729             (daemon->connections < daemon->connection_limit) &&
   5730             (! daemon->at_limit) )
   5731       series_length++;
   5732   }
   5733 
   5734   /* Handle timed-out connections; we need to do this here
   5735      as the epoll mechanism won't call the 'MHD_connection_handle_idle()' on everything,
   5736      as the other event loops do.  As timeouts do not get an explicit
   5737      event, we need to find those connections that might have timed out
   5738      here.
   5739 
   5740      Connections with custom timeouts must all be looked at, as we
   5741      do not bother to sort that (presumably very short) list. */
   5742   prev = daemon->manual_timeout_tail;
   5743   while (NULL != (pos = prev))
   5744   {
   5745     prev = pos->prevX;
   5746     MHD_connection_handle_idle (pos);
   5747   }
   5748   /* Connections with the default timeout are sorted by prepending
   5749      them to the head of the list whenever we touch the connection;
   5750      thus it suffices to iterate from the tail until the first
   5751      connection is NOT timed out */
   5752   prev = daemon->normal_timeout_tail;
   5753   while (NULL != (pos = prev))
   5754   {
   5755     prev = pos->prevX;
   5756     MHD_connection_handle_idle (pos);
   5757     if (MHD_CONNECTION_CLOSED != pos->state)
   5758       break; /* sorted by timeout, no need to visit the rest! */
   5759   }
   5760 
   5761 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   5762   if (run_upgraded || (NULL != daemon->eready_urh_head))
   5763     run_epoll_for_upgrade (daemon);
   5764 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   5765 
   5766   /* process events for connections */
   5767   prev = daemon->eready_tail;
   5768   while (NULL != (pos = prev))
   5769   {
   5770     prev = pos->prevE;
   5771     call_handlers (pos,
   5772                    0 != (pos->epoll_state & MHD_EPOLL_STATE_READ_READY),
   5773                    0 != (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY),
   5774                    0 != (pos->epoll_state & MHD_EPOLL_STATE_ERROR));
   5775     if (MHD_EPOLL_STATE_IN_EREADY_EDLL ==
   5776         (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED
   5777                              | MHD_EPOLL_STATE_IN_EREADY_EDLL)))
   5778     {
   5779       if ( ((MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) &&
   5780             (0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) ||
   5781            ((MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
   5782             (0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ) ||
   5783            (MHD_EVENT_LOOP_INFO_CLEANUP == pos->event_loop_info) )
   5784       {
   5785         EDLL_remove (daemon->eready_head,
   5786                      daemon->eready_tail,
   5787                      pos);
   5788         pos->epoll_state &=
   5789           ~((enum MHD_EpollState) MHD_EPOLL_STATE_IN_EREADY_EDLL);
   5790       }
   5791     }
   5792   }
   5793 
   5794   return MHD_YES;
   5795 }
   5796 
   5797 
   5798 #endif
   5799 
   5800 
   5801 /**
   5802  * Run webserver operations (without blocking unless in client callbacks).
   5803  *
   5804  * This method should be called by clients in combination with
   5805  * #MHD_get_fdset() (or #MHD_get_daemon_info() with MHD_DAEMON_INFO_EPOLL_FD
   5806  * if epoll is used) and #MHD_get_timeout() if the client-controlled
   5807  * connection polling method is used (i.e. daemon was started without
   5808  * #MHD_USE_INTERNAL_POLLING_THREAD flag).
   5809  *
   5810  * This function is a convenience method, which is useful if the
   5811  * fd_sets from #MHD_get_fdset were not directly passed to `select()`;
   5812  * with this function, MHD will internally do the appropriate `select()`
   5813  * call itself again.  While it is acceptable to call #MHD_run (if
   5814  * #MHD_USE_INTERNAL_POLLING_THREAD is not set) at any moment, you should
   5815  * call #MHD_run_from_select() if performance is important (as it saves an
   5816  * expensive call to `select()`).
   5817  *
   5818  * If #MHD_get_timeout() returned #MHD_YES, than this function must be called
   5819  * right after polling function returns regardless of detected activity on
   5820  * the daemon's FDs.
   5821  *
   5822  * @param daemon daemon to run
   5823  * @return #MHD_YES on success, #MHD_NO if this
   5824  *         daemon was not started with the right
   5825  *         options for this call.
   5826  * @ingroup event
   5827  */
   5828 _MHD_EXTERN enum MHD_Result
   5829 MHD_run (struct MHD_Daemon *daemon)
   5830 {
   5831   if ( (daemon->shutdown) ||
   5832        MHD_D_IS_USING_THREADS_ (daemon) )
   5833     return MHD_NO;
   5834 
   5835   (void) MHD_run_wait (daemon, 0);
   5836   return MHD_YES;
   5837 }
   5838 
   5839 
   5840 /**
   5841  * Run webserver operation with possible blocking.
   5842  *
   5843  * This function does the following: waits for any network event not more than
   5844  * specified number of milliseconds, processes all incoming and outgoing data,
   5845  * processes new connections, processes any timed-out connection, and does
   5846  * other things required to run webserver.
   5847  * Once all connections are processed, function returns.
   5848  *
   5849  * This function is useful for quick and simple (lazy) webserver implementation
   5850  * if application needs to run a single thread only and does not have any other
   5851  * network activity.
   5852  *
   5853  * This function calls MHD_get_timeout() internally and use returned value as
   5854  * maximum wait time if it less than value of @a millisec parameter.
   5855  *
   5856  * It is expected that the "external" socket polling function is not used in
   5857  * conjunction with this function unless the @a millisec is set to zero.
   5858  *
   5859  * @param daemon the daemon to run
   5860  * @param millisec the maximum time in milliseconds to wait for network and
   5861  *                 other events. Note: there is no guarantee that function
   5862  *                 blocks for the specified amount of time. The real processing
   5863  *                 time can be shorter (if some data or connection timeout
   5864  *                 comes earlier) or longer (if data processing requires more
   5865  *                 time, especially in user callbacks).
   5866  *                 If set to '0' then function does not block and processes
   5867  *                 only already available data (if any).
   5868  *                 If set to '-1' then function waits for events
   5869  *                 indefinitely (blocks until next network activity or
   5870  *                 connection timeout).
   5871  * @return #MHD_YES on success, #MHD_NO if this
   5872  *         daemon was not started with the right
   5873  *         options for this call or some serious
   5874  *         unrecoverable error occurs.
   5875  * @note Available since #MHD_VERSION 0x00097206
   5876  * @ingroup event
   5877  */
   5878 _MHD_EXTERN enum MHD_Result
   5879 MHD_run_wait (struct MHD_Daemon *daemon,
   5880               int32_t millisec)
   5881 {
   5882   enum MHD_Result res;
   5883   if ( (daemon->shutdown) ||
   5884        MHD_D_IS_USING_THREADS_ (daemon) )
   5885     return MHD_NO;
   5886 
   5887   mhd_assert (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid));
   5888 
   5889   if (0 > millisec)
   5890     millisec = -1;
   5891 #ifdef HAVE_POLL
   5892   if (MHD_D_IS_USING_POLL_ (daemon))
   5893   {
   5894     res = MHD_poll_all (daemon, millisec);
   5895     MHD_cleanup_connections (daemon);
   5896   }
   5897   else
   5898 #endif /* HAVE_POLL */
   5899 #ifdef EPOLL_SUPPORT
   5900   if (MHD_D_IS_USING_EPOLL_ (daemon))
   5901   {
   5902     res = MHD_epoll (daemon, millisec);
   5903     MHD_cleanup_connections (daemon);
   5904   }
   5905   else
   5906 #endif
   5907   if (1)
   5908   {
   5909     mhd_assert (MHD_D_IS_USING_SELECT_ (daemon));
   5910 #ifdef HAS_FD_SETSIZE_OVERRIDABLE
   5911 #ifdef HAVE_MESSAGES
   5912     if (daemon->fdset_size_set_by_app
   5913         && (((int) FD_SETSIZE) < daemon->fdset_size))
   5914     {
   5915       MHD_DLOG (daemon,
   5916                 _ ("MHD_run()/MHD_run_wait() called for daemon started with " \
   5917                    "MHD_OPTION_APP_FD_SETSIZE option (%d). " \
   5918                    "The library was compiled with smaller FD_SETSIZE (%d). " \
   5919                    "Some socket FDs may be not processed. " \
   5920                    "Use MHD_run_from_select2() instead of MHD_run() or " \
   5921                    "do not use MHD_OPTION_APP_FD_SETSIZE option.\n"),
   5922                 daemon->fdset_size, (int) FD_SETSIZE);
   5923     }
   5924 #endif /* HAVE_MESSAGES */
   5925 #endif /* HAS_FD_SETSIZE_OVERRIDABLE */
   5926 
   5927     res = MHD_select (daemon, millisec);
   5928     /* MHD_select does MHD_cleanup_connections already */
   5929   }
   5930   return res;
   5931 }
   5932 
   5933 
   5934 /**
   5935  * Close the given connection, remove it from all of its
   5936  * DLLs and move it into the cleanup queue.
   5937  * @remark To be called only from thread that
   5938  * process daemon's select()/poll()/etc.
   5939  *
   5940  * @param pos connection to move to cleanup
   5941  */
   5942 static void
   5943 close_connection (struct MHD_Connection *pos)
   5944 {
   5945   struct MHD_Daemon *daemon = pos->daemon;
   5946 
   5947 #ifdef MHD_USE_THREADS
   5948   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   5949                MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   5950   mhd_assert (NULL == daemon->worker_pool);
   5951 #endif /* MHD_USE_THREADS */
   5952 
   5953   if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   5954   {
   5955     MHD_connection_mark_closed_ (pos);
   5956     return;   /* must let thread to do the rest */
   5957   }
   5958   MHD_connection_close_ (pos,
   5959                          MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN);
   5960 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   5961   MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   5962 #endif
   5963   mhd_assert (! pos->suspended);
   5964   mhd_assert (! pos->resuming);
   5965   if (pos->connection_timeout_ms == daemon->connection_timeout_ms)
   5966     XDLL_remove (daemon->normal_timeout_head,
   5967                  daemon->normal_timeout_tail,
   5968                  pos);
   5969   else
   5970     XDLL_remove (daemon->manual_timeout_head,
   5971                  daemon->manual_timeout_tail,
   5972                  pos);
   5973   DLL_remove (daemon->connections_head,
   5974               daemon->connections_tail,
   5975               pos);
   5976   DLL_insert (daemon->cleanup_head,
   5977               daemon->cleanup_tail,
   5978               pos);
   5979   daemon->data_already_pending = true;
   5980 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   5981   MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   5982 #endif
   5983 }
   5984 
   5985 
   5986 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   5987 /**
   5988  * Thread that runs the polling loop until the daemon
   5989  * is explicitly shut down.
   5990  *
   5991  * @param cls `struct MHD_Deamon` to run select loop in a thread for
   5992  * @return always 0 (on shutdown)
   5993  */
   5994 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
   5995 MHD_polling_thread (void *cls)
   5996 {
   5997   struct MHD_Daemon *daemon = cls;
   5998 #ifdef HAVE_PTHREAD_SIGMASK
   5999   sigset_t s_mask;
   6000   int err;
   6001 #endif /* HAVE_PTHREAD_SIGMASK */
   6002 
   6003   MHD_thread_handle_ID_set_current_thread_ID_ (&(daemon->tid));
   6004 #ifdef HAVE_PTHREAD_SIGMASK
   6005   if ((0 == sigemptyset (&s_mask)) &&
   6006       (0 == sigaddset (&s_mask, SIGPIPE)))
   6007   {
   6008     err = pthread_sigmask (SIG_BLOCK, &s_mask, NULL);
   6009   }
   6010   else
   6011     err = errno;
   6012   if (0 == err)
   6013     daemon->sigpipe_blocked = true;
   6014 #ifdef HAVE_MESSAGES
   6015   else
   6016     MHD_DLOG (daemon,
   6017               _ ("Failed to block SIGPIPE on daemon thread: %s\n"),
   6018               MHD_strerror_ (errno));
   6019 #endif /* HAVE_MESSAGES */
   6020 #endif /* HAVE_PTHREAD_SIGMASK */
   6021   while (! daemon->shutdown)
   6022   {
   6023 #ifdef HAVE_POLL
   6024     if (MHD_D_IS_USING_POLL_ (daemon))
   6025       MHD_poll (daemon, MHD_YES);
   6026     else
   6027 #endif /* HAVE_POLL */
   6028 #ifdef EPOLL_SUPPORT
   6029     if (MHD_D_IS_USING_EPOLL_ (daemon))
   6030       MHD_epoll (daemon, -1);
   6031     else
   6032 #endif
   6033     MHD_select (daemon, -1);
   6034     MHD_cleanup_connections (daemon);
   6035   }
   6036 
   6037   /* Resume any pending for resume connections, join
   6038    * all connection's threads (if any) and finally cleanup
   6039    * everything. */
   6040   if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
   6041     resume_suspended_connections (daemon);
   6042   close_all_connections (daemon);
   6043 
   6044   return (MHD_THRD_RTRN_TYPE_) 0;
   6045 }
   6046 
   6047 
   6048 #endif
   6049 
   6050 
   6051 /**
   6052  * Process escape sequences ('%HH') Updates val in place; the
   6053  * result cannot be larger than the input.
   6054  * The result must also still be 0-terminated.
   6055  *
   6056  * @param cls closure (use NULL)
   6057  * @param connection handle to connection, not used
   6058  * @param val value to unescape (modified in the process)
   6059  * @return length of the resulting val (strlen(val) maybe
   6060  *  shorter afterwards due to elimination of escape sequences)
   6061  */
   6062 static size_t
   6063 unescape_wrapper (void *cls,
   6064                   struct MHD_Connection *connection,
   6065                   char *val)
   6066 {
   6067   bool broken;
   6068   size_t res;
   6069   (void) cls; /* Mute compiler warning. */
   6070 
   6071   /* TODO: add individual parameter */
   6072   if (0 <= connection->daemon->client_discipline)
   6073     return MHD_str_pct_decode_in_place_strict_ (val);
   6074 
   6075   res = MHD_str_pct_decode_in_place_lenient_ (val, &broken);
   6076 #ifdef HAVE_MESSAGES
   6077   if (broken)
   6078   {
   6079     MHD_DLOG (connection->daemon,
   6080               _ ("The URL encoding is broken.\n"));
   6081   }
   6082 #endif /* HAVE_MESSAGES */
   6083   return res;
   6084 }
   6085 
   6086 
   6087 /**
   6088  * Start a webserver on the given port.  Variadic version of
   6089  * #MHD_start_daemon_va.
   6090  *
   6091  * @param flags combination of `enum MHD_FLAG` values
   6092  * @param port port to bind to (in host byte order),
   6093  *        use '0' to bind to random free port,
   6094  *        ignored if #MHD_OPTION_SOCK_ADDR or
   6095  *        #MHD_OPTION_LISTEN_SOCKET is provided
   6096  *        or #MHD_USE_NO_LISTEN_SOCKET is specified
   6097  * @param apc callback to call to check which clients
   6098  *        will be allowed to connect; you can pass NULL
   6099  *        in which case connections from any IP will be
   6100  *        accepted
   6101  * @param apc_cls extra argument to @a apc
   6102  * @param dh handler called for all requests (repeatedly)
   6103  * @param dh_cls extra argument to @a dh
   6104  * @return NULL on error, handle to daemon on success
   6105  * @ingroup event
   6106  */
   6107 _MHD_EXTERN struct MHD_Daemon *
   6108 MHD_start_daemon (unsigned int flags,
   6109                   uint16_t port,
   6110                   MHD_AcceptPolicyCallback apc,
   6111                   void *apc_cls,
   6112                   MHD_AccessHandlerCallback dh,
   6113                   void *dh_cls,
   6114                   ...)
   6115 {
   6116   struct MHD_Daemon *daemon;
   6117   va_list ap;
   6118 
   6119   va_start (ap,
   6120             dh_cls);
   6121   daemon = MHD_start_daemon_va (flags,
   6122                                 port,
   6123                                 apc,
   6124                                 apc_cls,
   6125                                 dh,
   6126                                 dh_cls,
   6127                                 ap);
   6128   va_end (ap);
   6129   return daemon;
   6130 }
   6131 
   6132 
   6133 /**
   6134  * Stop accepting connections from the listening socket.  Allows
   6135  * clients to continue processing, but stops accepting new
   6136  * connections.  Note that the caller is responsible for closing the
   6137  * returned socket; however, if MHD is run using threads (anything but
   6138  * external select mode), socket will be removed from existing threads
   6139  * with some delay and it must not be closed while it's in use. To make
   6140  * sure that the socket is not used anymore, call #MHD_stop_daemon.
   6141  *
   6142  * Note that some thread modes require the caller to have passed
   6143  * #MHD_USE_ITC when using this API.  If this daemon is
   6144  * in one of those modes and this option was not given to
   6145  * #MHD_start_daemon, this function will return #MHD_INVALID_SOCKET.
   6146  *
   6147  * @param daemon daemon to stop accepting new connections for
   6148  * @return old listen socket on success, #MHD_INVALID_SOCKET if
   6149  *         the daemon was already not listening anymore
   6150  * @ingroup specialized
   6151  */
   6152 _MHD_EXTERN MHD_socket
   6153 MHD_quiesce_daemon (struct MHD_Daemon *daemon)
   6154 {
   6155 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   6156   unsigned int i;
   6157 #endif
   6158   MHD_socket ret;
   6159 
   6160   ret = daemon->listen_fd;
   6161   if ((MHD_INVALID_SOCKET == ret)
   6162       || daemon->was_quiesced)
   6163     return MHD_INVALID_SOCKET;
   6164   if ( (0 == (daemon->options & (MHD_USE_ITC))) &&
   6165        MHD_D_IS_USING_THREADS_ (daemon) )
   6166   {
   6167 #ifdef HAVE_MESSAGES
   6168     MHD_DLOG (daemon,
   6169               _ ("Using MHD_quiesce_daemon in this mode " \
   6170                  "requires MHD_USE_ITC.\n"));
   6171 #endif
   6172     return MHD_INVALID_SOCKET;
   6173   }
   6174 
   6175 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   6176   if (NULL != daemon->worker_pool)
   6177     for (i = 0; i < daemon->worker_pool_size; i++)
   6178     {
   6179       daemon->worker_pool[i].was_quiesced = true;
   6180 #ifdef EPOLL_SUPPORT
   6181       if (MHD_D_IS_USING_EPOLL_ (daemon) &&
   6182           (-1 != daemon->worker_pool[i].epoll_fd) &&
   6183           (daemon->worker_pool[i].listen_socket_in_epoll) )
   6184       {
   6185         if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
   6186                             EPOLL_CTL_DEL,
   6187                             ret,
   6188                             NULL))
   6189           MHD_PANIC (_ ("Failed to remove listen FD from epoll set.\n"));
   6190         daemon->worker_pool[i].listen_socket_in_epoll = false;
   6191       }
   6192       else
   6193 #endif
   6194       if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc))
   6195       {
   6196         if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q"))
   6197           MHD_PANIC (_ ("Failed to signal quiesce via inter-thread " \
   6198                         "communication channel.\n"));
   6199       }
   6200     }
   6201 #endif
   6202   daemon->was_quiesced = true;
   6203 #ifdef EPOLL_SUPPORT
   6204   if (MHD_D_IS_USING_EPOLL_ (daemon) &&
   6205       (-1 != daemon->epoll_fd) &&
   6206       (daemon->listen_socket_in_epoll) )
   6207   {
   6208     if ( (0 != epoll_ctl (daemon->epoll_fd,
   6209                           EPOLL_CTL_DEL,
   6210                           ret,
   6211                           NULL)) &&
   6212          (ENOENT != errno) )   /* ENOENT can happen due to race with
   6213                                   #MHD_epoll() */
   6214       MHD_PANIC ("Failed to remove listen FD from epoll set.\n");
   6215     daemon->listen_socket_in_epoll = false;
   6216   }
   6217 #endif
   6218   if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
   6219        (! MHD_itc_activate_ (daemon->itc, "q")) )
   6220     MHD_PANIC (_ ("failed to signal quiesce via inter-thread " \
   6221                   "communication channel.\n"));
   6222   return ret;
   6223 }
   6224 
   6225 
   6226 /**
   6227  * Temporal location of the application-provided parameters/options.
   6228  * Used when options are decoded from #MHD_start_deamon() parameters, but
   6229  * not yet processed/applied.
   6230  */
   6231 struct MHD_InterimParams_
   6232 {
   6233   /**
   6234    * The total number of all user options used.
   6235    *
   6236    * Contains number only of meaningful options, i.e. #MHD_OPTION_END and
   6237    * #MHD_OPTION_ARRAY themselves are not counted, while options inside
   6238    * #MHD_OPTION_ARRAY are counted.
   6239    */
   6240   size_t num_opts;
   6241   /**
   6242    * Set to 'true' if @a fdset_size is set by application.
   6243    */
   6244   bool fdset_size_set;
   6245   /**
   6246    * The value for #MHD_OPTION_APP_FD_SETSIZE set by application.
   6247    */
   6248   int fdset_size;
   6249   /**
   6250    * Set to 'true' if @a listen_fd is set by application.
   6251    */
   6252   bool listen_fd_set;
   6253   /**
   6254    * Application-provided listen socket.
   6255    */
   6256   MHD_socket listen_fd;
   6257   /**
   6258    * Set to 'true' if @a server_addr is set by application.
   6259    */
   6260   bool pserver_addr_set;
   6261   /**
   6262    * Application-provided struct sockaddr to bind server to.
   6263    */
   6264   const struct sockaddr *pserver_addr;
   6265   /**
   6266    * Set to 'true' if @a server_addr_len is set by application.
   6267    */
   6268   bool server_addr_len_set;
   6269   /**
   6270    * Applicaiton-provided the size of the memory pointed by @a server_addr.
   6271    */
   6272   socklen_t server_addr_len;
   6273 };
   6274 
   6275 /**
   6276  * Signature of the MHD custom logger function.
   6277  *
   6278  * @param cls closure
   6279  * @param format format string
   6280  * @param va arguments to the format string (fprintf-style)
   6281  */
   6282 typedef void
   6283 (*VfprintfFunctionPointerType)(void *cls,
   6284                                const char *format,
   6285                                va_list va);
   6286 
   6287 
   6288 /**
   6289  * Parse a list of options given as varargs.
   6290  *
   6291  * @param daemon the daemon to initialize
   6292  * @param servaddr where to store the server's listen address
   6293  * @param params the interim parameters to be assigned to
   6294  * @param ap the options
   6295  * @return #MHD_YES on success, #MHD_NO on error
   6296  */
   6297 static enum MHD_Result
   6298 parse_options_va (struct MHD_Daemon *daemon,
   6299                   struct MHD_InterimParams_ *params,
   6300                   va_list ap);
   6301 
   6302 
   6303 /**
   6304  * Parse a list of options given as varargs.
   6305  *
   6306  * @param daemon the daemon to initialize
   6307  * @param servaddr where to store the server's listen address
   6308  * @param params the interim parameters to be assigned to
   6309  * @param ... the options
   6310  * @return #MHD_YES on success, #MHD_NO on error
   6311  */
   6312 static enum MHD_Result
   6313 parse_options (struct MHD_Daemon *daemon,
   6314                struct MHD_InterimParams_ *params,
   6315                ...)
   6316 {
   6317   va_list ap;
   6318   enum MHD_Result ret;
   6319 
   6320   va_start (ap, params);
   6321   ret = parse_options_va (daemon,
   6322                           params,
   6323                           ap);
   6324   va_end (ap);
   6325   return ret;
   6326 }
   6327 
   6328 
   6329 #ifdef HTTPS_SUPPORT
   6330 /**
   6331  * Type of GnuTLS priorities base string
   6332  */
   6333 enum MHD_TlsPrioritiesBaseType
   6334 {
   6335   MHD_TLS_PRIO_BASE_LIBMHD = 0, /**< @c "@LIBMICROHTTPD" */
   6336   MHD_TLS_PRIO_BASE_SYSTEM = 1, /**< @c "@SYSTEM" */
   6337 #if GNUTLS_VERSION_NUMBER >= 0x030300
   6338   MHD_TLS_PRIO_BASE_DEFAULT,    /**< Default priorities string */
   6339 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */
   6340   MHD_TLS_PRIO_BASE_NORMAL      /**< @c "NORMAL */
   6341 };
   6342 
   6343 static const struct _MHD_cstr_w_len MHD_TlsBasePriotities[] = {
   6344   _MHD_S_STR_W_LEN ("@LIBMICROHTTPD"),
   6345   _MHD_S_STR_W_LEN ("@SYSTEM"),
   6346 #if GNUTLS_VERSION_NUMBER >= 0x030300
   6347   {NULL, 0},
   6348 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */
   6349   _MHD_S_STR_W_LEN ("NORMAL")
   6350 };
   6351 
   6352 /**
   6353  * Initialise TLS priorities with default settings
   6354  * @param daemon the daemon to initialise TLS priorities
   6355  * @return true on success, false on error
   6356  */
   6357 static bool
   6358 daemon_tls_priorities_init_default (struct MHD_Daemon *daemon)
   6359 {
   6360   unsigned int p;
   6361   int res;
   6362 
   6363   mhd_assert (0 != (((unsigned int) daemon->options) & MHD_USE_TLS));
   6364   mhd_assert (NULL == daemon->priority_cache);
   6365   mhd_assert (MHD_TLS_PRIO_BASE_NORMAL + 1 == \
   6366               sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0]));
   6367 
   6368   res = GNUTLS_E_SUCCESS; /* Mute compiler warning */
   6369 
   6370   for (p = 0;
   6371        p < sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0]);
   6372        ++p)
   6373   {
   6374     res = gnutls_priority_init (&daemon->priority_cache,
   6375                                 MHD_TlsBasePriotities[p].str, NULL);
   6376     if (GNUTLS_E_SUCCESS == res)
   6377     {
   6378 #ifdef _DEBUG
   6379 #ifdef HAVE_MESSAGES
   6380       switch ((enum MHD_TlsPrioritiesBaseType) p)
   6381       {
   6382       case MHD_TLS_PRIO_BASE_LIBMHD:
   6383         MHD_DLOG (daemon,
   6384                   _ ("GnuTLS priorities have been initialised with " \
   6385                      "@LIBMICROHTTPD application-specific system-wide " \
   6386                      "configuration.\n") );
   6387         break;
   6388       case MHD_TLS_PRIO_BASE_SYSTEM:
   6389         MHD_DLOG (daemon,
   6390                   _ ("GnuTLS priorities have been initialised with " \
   6391                      "@SYSTEM system-wide configuration.\n") );
   6392         break;
   6393 #if GNUTLS_VERSION_NUMBER >= 0x030300
   6394       case MHD_TLS_PRIO_BASE_DEFAULT:
   6395         MHD_DLOG (daemon,
   6396                   _ ("GnuTLS priorities have been initialised with " \
   6397                      "GnuTLS default configuration.\n") );
   6398         break;
   6399 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */
   6400       case MHD_TLS_PRIO_BASE_NORMAL:
   6401         MHD_DLOG (daemon,
   6402                   _ ("GnuTLS priorities have been initialised with " \
   6403                      "NORMAL configuration.\n") );
   6404         break;
   6405       default:
   6406         mhd_assert (0);
   6407       }
   6408 #endif /* HAVE_MESSAGES */
   6409 #endif /* _DEBUG */
   6410       return true;
   6411     }
   6412   }
   6413 #ifdef HAVE_MESSAGES
   6414   MHD_DLOG (daemon,
   6415             _ ("Failed to set GnuTLS priorities. Last error: %s\n"),
   6416             gnutls_strerror (res));
   6417 #endif /* HAVE_MESSAGES */
   6418   return false;
   6419 }
   6420 
   6421 
   6422 /**
   6423  * The inner helper function for #daemon_tls_priorities_init_app().
   6424  * @param daemon the daemon to use
   6425  * @param prio   the appication-specified appendix for default priorities
   6426  * @param prio_len the length of @a prio
   6427  * @param buf    the temporal buffer for string manipulations
   6428  * @param buf_size the size of the @a buf
   6429  * @return true on success, false on error
   6430  */
   6431 static bool
   6432 daemon_tls_priorities_init_append_inner_ (struct MHD_Daemon *daemon,
   6433                                           const char *prio,
   6434                                           size_t prio_len,
   6435                                           char *buf,
   6436                                           const size_t buf_size)
   6437 {
   6438   unsigned int p;
   6439   int res;
   6440   const char *err_pos;
   6441 
   6442   (void) buf_size; /* Mute compiler warning for non-Debug builds */
   6443   mhd_assert (0 != (((unsigned int) daemon->options) & MHD_USE_TLS));
   6444   mhd_assert (NULL == daemon->priority_cache);
   6445   mhd_assert (MHD_TLS_PRIO_BASE_NORMAL + 1 == \
   6446               sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0]));
   6447 
   6448   res = GNUTLS_E_SUCCESS; /* Mute compiler warning */
   6449 
   6450   for (p = 0;
   6451        p < sizeof(MHD_TlsBasePriotities) / sizeof(MHD_TlsBasePriotities[0]);
   6452        ++p)
   6453   {
   6454 
   6455 #if GNUTLS_VERSION_NUMBER >= 0x030300
   6456 #if GNUTLS_VERSION_NUMBER >= 0x030603
   6457     if (NULL == MHD_TlsBasePriotities[p].str)
   6458       res = gnutls_priority_init2 (&daemon->priority_cache, prio, &err_pos,
   6459                                    GNUTLS_PRIORITY_INIT_DEF_APPEND);
   6460     else
   6461 #else /* 0x030300 <= GNUTLS_VERSION_NUMBER
   6462          && GNUTLS_VERSION_NUMBER < 0x030603 */
   6463     if (NULL == MHD_TlsBasePriotities[p].str)
   6464       continue; /* Skip the value, no way to append priorities to the default string */
   6465     else
   6466 #endif /* GNUTLS_VERSION_NUMBER < 0x030603 */
   6467 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */
   6468     if (1)
   6469     {
   6470       size_t buf_pos;
   6471 
   6472       mhd_assert (NULL != MHD_TlsBasePriotities[p].str);
   6473       buf_pos = 0;
   6474       memcpy (buf + buf_pos, MHD_TlsBasePriotities[p].str,
   6475               MHD_TlsBasePriotities[p].len);
   6476       buf_pos += MHD_TlsBasePriotities[p].len;
   6477       buf[buf_pos++] = ':';
   6478       memcpy (buf + buf_pos, prio, prio_len + 1);
   6479 #ifdef _DEBUG
   6480       buf_pos += prio_len + 1;
   6481       mhd_assert (buf_size >= buf_pos);
   6482 #endif /* _DEBUG */
   6483       res = gnutls_priority_init (&daemon->priority_cache, buf, &err_pos);
   6484     }
   6485     if (GNUTLS_E_SUCCESS == res)
   6486     {
   6487 #ifdef _DEBUG
   6488 #ifdef HAVE_MESSAGES
   6489       switch ((enum MHD_TlsPrioritiesBaseType) p)
   6490       {
   6491       case MHD_TLS_PRIO_BASE_LIBMHD:
   6492         MHD_DLOG (daemon,
   6493                   _ ("GnuTLS priorities have been initialised with " \
   6494                      "priorities specified by application appended to " \
   6495                      "@LIBMICROHTTPD application-specific system-wide " \
   6496                      "configuration.\n") );
   6497         break;
   6498       case MHD_TLS_PRIO_BASE_SYSTEM:
   6499         MHD_DLOG (daemon,
   6500                   _ ("GnuTLS priorities have been initialised with " \
   6501                      "priorities specified by application appended to " \
   6502                      "@SYSTEM system-wide configuration.\n") );
   6503         break;
   6504 #if GNUTLS_VERSION_NUMBER >= 0x030300
   6505       case MHD_TLS_PRIO_BASE_DEFAULT:
   6506         MHD_DLOG (daemon,
   6507                   _ ("GnuTLS priorities have been initialised with " \
   6508                      "priorities specified by application appended to " \
   6509                      "GnuTLS default configuration.\n") );
   6510         break;
   6511 #endif /* GNUTLS_VERSION_NUMBER >= 0x030300 */
   6512       case MHD_TLS_PRIO_BASE_NORMAL:
   6513         MHD_DLOG (daemon,
   6514                   _ ("GnuTLS priorities have been initialised with " \
   6515                      "priorities specified by application appended to " \
   6516                      "NORMAL configuration.\n") );
   6517         break;
   6518       default:
   6519         mhd_assert (0);
   6520       }
   6521 #endif /* HAVE_MESSAGES */
   6522 #endif /* _DEBUG */
   6523       return true;
   6524     }
   6525   }
   6526 #ifdef HAVE_MESSAGES
   6527   MHD_DLOG (daemon,
   6528             _ ("Failed to set GnuTLS priorities. Last error: %s. " \
   6529                "The problematic part starts at: %s\n"),
   6530             gnutls_strerror (res), err_pos);
   6531 #endif /* HAVE_MESSAGES */
   6532   return false;
   6533 }
   6534 
   6535 
   6536 #define LOCAL_BUFF_SIZE 128
   6537 
   6538 /**
   6539  * Initialise TLS priorities with default settings with application-specified
   6540  * appended string.
   6541  * @param daemon the daemon to initialise TLS priorities
   6542  * @param prio the application specified priorities to be appended to
   6543  *             the GnuTLS standard priorities string
   6544  * @return true on success, false on error
   6545  */
   6546 static bool
   6547 daemon_tls_priorities_init_append (struct MHD_Daemon *daemon, const char *prio)
   6548 {
   6549   static const size_t longest_base_prio = MHD_STATICSTR_LEN_ ("@LIBMICROHTTPD");
   6550   bool ret;
   6551   size_t prio_len;
   6552   size_t buf_size_needed;
   6553 
   6554   if (NULL == prio)
   6555     return daemon_tls_priorities_init_default (daemon);
   6556 
   6557   if (':' == prio[0])
   6558     ++prio;
   6559 
   6560   prio_len = strlen (prio);
   6561 
   6562   buf_size_needed = longest_base_prio + 1 + prio_len + 1;
   6563 
   6564   if (LOCAL_BUFF_SIZE >= buf_size_needed)
   6565   {
   6566     char local_buffer[LOCAL_BUFF_SIZE];
   6567     ret = daemon_tls_priorities_init_append_inner_ (daemon, prio, prio_len,
   6568                                                     local_buffer,
   6569                                                     LOCAL_BUFF_SIZE);
   6570   }
   6571   else
   6572   {
   6573     char *allocated_buffer;
   6574     allocated_buffer = (char *) malloc (buf_size_needed);
   6575     if (NULL == allocated_buffer)
   6576     {
   6577 #ifdef HAVE_MESSAGES
   6578       MHD_DLOG (daemon,
   6579                 _ ("Error allocating memory: %s\n"),
   6580                 MHD_strerror_ (errno));
   6581 #endif
   6582       return false;
   6583     }
   6584     ret = daemon_tls_priorities_init_append_inner_ (daemon, prio, prio_len,
   6585                                                     allocated_buffer,
   6586                                                     buf_size_needed);
   6587     free (allocated_buffer);
   6588   }
   6589   return ret;
   6590 }
   6591 
   6592 
   6593 #endif /* HTTPS_SUPPORT */
   6594 
   6595 
   6596 /**
   6597  * Parse a list of options given as varargs.
   6598  *
   6599  * @param[in,out] daemon the daemon to initialize
   6600  * @param[out] params the interim parameters to be assigned to
   6601  * @param ap the options
   6602  * @return #MHD_YES on success, #MHD_NO on error
   6603  */
   6604 static enum MHD_Result
   6605 parse_options_va (struct MHD_Daemon *daemon,
   6606                   struct MHD_InterimParams_ *params,
   6607                   va_list ap)
   6608 {
   6609   enum MHD_OPTION opt;
   6610   struct MHD_OptionItem *oa;
   6611   unsigned int i;
   6612   unsigned int uv;
   6613 #ifdef HTTPS_SUPPORT
   6614   const char *pstr;
   6615 #if GNUTLS_VERSION_MAJOR >= 3
   6616   gnutls_certificate_retrieve_function2 * pgcrf;
   6617 #endif
   6618 #if GNUTLS_VERSION_NUMBER >= 0x030603
   6619   gnutls_certificate_retrieve_function3 * pgcrf2;
   6620 #endif
   6621 #endif /* HTTPS_SUPPORT */
   6622 
   6623   while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int)))
   6624   {
   6625     /* Increase counter at start, so resulting value is number of
   6626      * processed options, including any failed ones. */
   6627     params->num_opts++;
   6628     switch (opt)
   6629     {
   6630     case MHD_OPTION_CONNECTION_MEMORY_LIMIT:
   6631       if (1)
   6632       {
   6633         size_t val;
   6634 
   6635         val = va_arg (ap,
   6636                       size_t);
   6637         if (0 != val)
   6638         {
   6639           daemon->pool_size = val;
   6640           if (64 > daemon->pool_size)
   6641           {
   6642 #ifdef HAVE_MESSAGES
   6643             MHD_DLOG (daemon,
   6644                       _ ("Warning: specified " \
   6645                          "MHD_OPTION_CONNECTION_MEMORY_LIMIT " \
   6646                          "value is too small and rounded up to 64.\n"));
   6647 #endif /* HAVE_MESSAGES */
   6648             daemon->pool_size = 64;
   6649           }
   6650           if (daemon->pool_size / 4 < daemon->pool_increment)
   6651             daemon->pool_increment = daemon->pool_size / 4;
   6652         }
   6653       }
   6654       break;
   6655     case MHD_OPTION_CONNECTION_MEMORY_INCREMENT:
   6656       if (1)
   6657       {
   6658         size_t val;
   6659 
   6660         val = va_arg (ap,
   6661                       size_t);
   6662 
   6663         if (0 != val)
   6664         {
   6665           daemon->pool_increment = val;
   6666           if (daemon->pool_size / 4 < daemon->pool_increment)
   6667           {
   6668 #ifdef HAVE_MESSAGES
   6669             MHD_DLOG (daemon,
   6670                       _ ("Warning: specified " \
   6671                          "MHD_OPTION_CONNECTION_MEMORY_INCREMENT value is " \
   6672                          "too large and rounded down to 1/4 of " \
   6673                          "MHD_OPTION_CONNECTION_MEMORY_LIMIT.\n"));
   6674 #endif /* HAVE_MESSAGES */
   6675             daemon->pool_increment = daemon->pool_size / 4;
   6676           }
   6677         }
   6678       }
   6679       break;
   6680     case MHD_OPTION_CONNECTION_LIMIT:
   6681       daemon->connection_limit = va_arg (ap,
   6682                                          unsigned int);
   6683       break;
   6684     case MHD_OPTION_CONNECTION_TIMEOUT:
   6685       uv = va_arg (ap,
   6686                    unsigned int);
   6687 #if (SIZEOF_UINT64_T - 2) <= SIZEOF_UNSIGNED_INT
   6688       if ((UINT64_MAX / 4000 - 1) < uv)
   6689       {
   6690 #ifdef HAVE_MESSAGES
   6691         MHD_DLOG (daemon,
   6692                   _ ("The specified connection timeout (%u) is too large. " \
   6693                      "Maximum allowed value (%" PRIu64 ") will be used " \
   6694                      "instead.\n"),
   6695                   uv,
   6696                   (UINT64_MAX / 4000 - 1));
   6697 #endif
   6698         uv = UINT64_MAX / 4000 - 1;
   6699       }
   6700 #endif /* (SIZEOF_UINT64_T - 2) <= SIZEOF_UNSIGNED_INT */
   6701       daemon->connection_timeout_ms = ((uint64_t) uv) * 1000;
   6702       break;
   6703     case MHD_OPTION_NOTIFY_COMPLETED:
   6704       daemon->notify_completed = va_arg (ap,
   6705                                          MHD_RequestCompletedCallback);
   6706       daemon->notify_completed_cls = va_arg (ap,
   6707                                              void *);
   6708       break;
   6709     case MHD_OPTION_NOTIFY_CONNECTION:
   6710       daemon->notify_connection = va_arg (ap,
   6711                                           MHD_NotifyConnectionCallback);
   6712       daemon->notify_connection_cls = va_arg (ap,
   6713                                               void *);
   6714       break;
   6715     case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
   6716       daemon->per_ip_connection_limit = va_arg (ap,
   6717                                                 unsigned int);
   6718       break;
   6719     case MHD_OPTION_SOCK_ADDR_LEN:
   6720       params->server_addr_len = va_arg (ap,
   6721                                         socklen_t);
   6722       params->server_addr_len_set = true;
   6723       params->pserver_addr = va_arg (ap,
   6724                                      const struct sockaddr *);
   6725       params->pserver_addr_set = true;
   6726       break;
   6727     case MHD_OPTION_SOCK_ADDR:
   6728       params->server_addr_len_set = false;
   6729       params->pserver_addr = va_arg (ap,
   6730                                      const struct sockaddr *);
   6731       params->pserver_addr_set = true;
   6732       break;
   6733     case MHD_OPTION_URI_LOG_CALLBACK:
   6734       daemon->uri_log_callback = va_arg (ap,
   6735                                          LogCallback);
   6736       daemon->uri_log_callback_cls = va_arg (ap,
   6737                                              void *);
   6738       break;
   6739     case MHD_OPTION_SERVER_INSANITY:
   6740       daemon->insanity_level = (enum MHD_DisableSanityCheck)
   6741                                va_arg (ap,
   6742                                        unsigned int);
   6743       break;
   6744 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   6745     case MHD_OPTION_THREAD_POOL_SIZE:
   6746       daemon->worker_pool_size = va_arg (ap,
   6747                                          unsigned int);
   6748       if (0 == daemon->worker_pool_size)
   6749       {
   6750         (void) 0; /* MHD_OPTION_THREAD_POOL_SIZE ignored, do nothing */
   6751       }
   6752       else if (1 == daemon->worker_pool_size)
   6753       {
   6754 #ifdef HAVE_MESSAGES
   6755         MHD_DLOG (daemon,
   6756                   _ ("Warning: value \"1\", specified as the thread pool " \
   6757                      "size, is ignored. Thread pool is not used.\n"));
   6758 #endif
   6759         daemon->worker_pool_size = 0;
   6760       }
   6761 #if SIZEOF_UNSIGNED_INT >= (SIZEOF_SIZE_T - 2)
   6762       /* Next comparison could be always false on some platforms and whole branch will
   6763        * be optimized out on these platforms. On others it will be compiled into real
   6764        * check. */
   6765       else if (daemon->worker_pool_size >=
   6766                (SIZE_MAX / sizeof (struct MHD_Daemon)))            /* Compiler may warn on some platforms, ignore warning. */
   6767       {
   6768 #ifdef HAVE_MESSAGES
   6769         MHD_DLOG (daemon,
   6770                   _ ("Specified thread pool size (%u) too big.\n"),
   6771                   daemon->worker_pool_size);
   6772 #endif
   6773         return MHD_NO;
   6774       }
   6775 #endif /* SIZEOF_UNSIGNED_INT >= (SIZEOF_SIZE_T - 2) */
   6776       else
   6777       {
   6778         if (! MHD_D_IS_USING_THREADS_ (daemon))
   6779         {
   6780 #ifdef HAVE_MESSAGES
   6781           MHD_DLOG (daemon,
   6782                     _ ("MHD_OPTION_THREAD_POOL_SIZE option is specified but "
   6783                        "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
   6784 #endif
   6785           return MHD_NO;
   6786         }
   6787         if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   6788         {
   6789 #ifdef HAVE_MESSAGES
   6790           MHD_DLOG (daemon,
   6791                     _ ("Both MHD_OPTION_THREAD_POOL_SIZE option and "
   6792                        "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
   6793 #endif
   6794           return MHD_NO;
   6795         }
   6796       }
   6797       break;
   6798 #endif
   6799 #ifdef HTTPS_SUPPORT
   6800     case MHD_OPTION_HTTPS_MEM_KEY:
   6801       pstr = va_arg (ap,
   6802                      const char *);
   6803       if (0 != (daemon->options & MHD_USE_TLS))
   6804         daemon->https_mem_key = pstr;
   6805 #ifdef HAVE_MESSAGES
   6806       else
   6807         MHD_DLOG (daemon,
   6808                   _ ("MHD HTTPS option %d passed to MHD but " \
   6809                      "MHD_USE_TLS not set.\n"),
   6810                   opt);
   6811 #endif
   6812       break;
   6813     case MHD_OPTION_HTTPS_KEY_PASSWORD:
   6814       pstr = va_arg (ap,
   6815                      const char *);
   6816       if (0 != (daemon->options & MHD_USE_TLS))
   6817         daemon->https_key_password = pstr;
   6818 #ifdef HAVE_MESSAGES
   6819       else
   6820         MHD_DLOG (daemon,
   6821                   _ ("MHD HTTPS option %d passed to MHD but " \
   6822                      "MHD_USE_TLS not set.\n"),
   6823                   opt);
   6824 #endif
   6825       break;
   6826     case MHD_OPTION_HTTPS_MEM_CERT:
   6827       pstr = va_arg (ap,
   6828                      const char *);
   6829       if (0 != (daemon->options & MHD_USE_TLS))
   6830         daemon->https_mem_cert = pstr;
   6831 #ifdef HAVE_MESSAGES
   6832       else
   6833         MHD_DLOG (daemon,
   6834                   _ ("MHD HTTPS option %d passed to MHD but " \
   6835                      "MHD_USE_TLS not set.\n"),
   6836                   opt);
   6837 #endif
   6838       break;
   6839     case MHD_OPTION_HTTPS_MEM_TRUST:
   6840       pstr = va_arg (ap,
   6841                      const char *);
   6842       if (0 != (daemon->options & MHD_USE_TLS))
   6843         daemon->https_mem_trust = pstr;
   6844 #ifdef HAVE_MESSAGES
   6845       else
   6846         MHD_DLOG (daemon,
   6847                   _ ("MHD HTTPS option %d passed to MHD but " \
   6848                      "MHD_USE_TLS not set.\n"),
   6849                   opt);
   6850 #endif
   6851       break;
   6852     case MHD_OPTION_HTTPS_CRED_TYPE:
   6853       daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
   6854                                                               int);
   6855       break;
   6856     case MHD_OPTION_HTTPS_MEM_DHPARAMS:
   6857       pstr = va_arg (ap,
   6858                      const char *);
   6859       if (0 != (daemon->options & MHD_USE_TLS))
   6860       {
   6861         gnutls_datum_t dhpar;
   6862         size_t pstr_len;
   6863 
   6864         if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
   6865         {
   6866 #ifdef HAVE_MESSAGES
   6867           MHD_DLOG (daemon,
   6868                     _ ("Error initializing DH parameters.\n"));
   6869 #endif
   6870           return MHD_NO;
   6871         }
   6872         dhpar.data = (unsigned char *) _MHD_DROP_CONST (pstr);
   6873         pstr_len = strlen (pstr);
   6874         if (UINT_MAX < pstr_len)
   6875         {
   6876 #ifdef HAVE_MESSAGES
   6877           MHD_DLOG (daemon,
   6878                     _ ("Diffie-Hellman parameters string too long.\n"));
   6879 #endif
   6880           return MHD_NO;
   6881         }
   6882         dhpar.size = (unsigned int) pstr_len;
   6883         if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
   6884                                            &dhpar,
   6885                                            GNUTLS_X509_FMT_PEM) < 0)
   6886         {
   6887 #ifdef HAVE_MESSAGES
   6888           MHD_DLOG (daemon,
   6889                     _ ("Bad Diffie-Hellman parameters format.\n"));
   6890 #endif
   6891           gnutls_dh_params_deinit (daemon->https_mem_dhparams);
   6892           return MHD_NO;
   6893         }
   6894         daemon->have_dhparams = true;
   6895       }
   6896 #ifdef HAVE_MESSAGES
   6897       else
   6898         MHD_DLOG (daemon,
   6899                   _ ("MHD HTTPS option %d passed to MHD but " \
   6900                      "MHD_USE_TLS not set.\n"),
   6901                   opt);
   6902 #endif
   6903       break;
   6904     case MHD_OPTION_HTTPS_PRIORITIES:
   6905     case MHD_OPTION_HTTPS_PRIORITIES_APPEND:
   6906       pstr = va_arg (ap,
   6907                      const char *);
   6908       if (0 != (daemon->options & MHD_USE_TLS))
   6909       {
   6910         if (NULL != daemon->priority_cache)
   6911           gnutls_priority_deinit (daemon->priority_cache);
   6912 
   6913         if (MHD_OPTION_HTTPS_PRIORITIES == opt)
   6914         {
   6915           int init_res;
   6916           const char *err_pos;
   6917           init_res = gnutls_priority_init (&daemon->priority_cache,
   6918                                            pstr,
   6919                                            &err_pos);
   6920           if (GNUTLS_E_SUCCESS != init_res)
   6921           {
   6922 #ifdef HAVE_MESSAGES
   6923             MHD_DLOG (daemon,
   6924                       _ ("Setting priorities to '%s' failed: %s " \
   6925                          "The problematic part starts at: %s\n"),
   6926                       pstr,
   6927                       gnutls_strerror (init_res),
   6928                       err_pos);
   6929 #endif
   6930             daemon->priority_cache = NULL;
   6931             return MHD_NO;
   6932           }
   6933         }
   6934         else
   6935         {
   6936           /* The cache has been deinited */
   6937           daemon->priority_cache = NULL;
   6938           if (! daemon_tls_priorities_init_append (daemon, pstr))
   6939             return MHD_NO;
   6940         }
   6941       }
   6942 #ifdef HAVE_MESSAGES
   6943       else
   6944         MHD_DLOG (daemon,
   6945                   _ ("MHD HTTPS option %d passed to MHD but " \
   6946                      "MHD_USE_TLS not set.\n"),
   6947                   opt);
   6948 #endif
   6949       break;
   6950     case MHD_OPTION_HTTPS_CERT_CALLBACK:
   6951 #if GNUTLS_VERSION_MAJOR < 3
   6952 #ifdef HAVE_MESSAGES
   6953       MHD_DLOG (daemon,
   6954                 _ ("MHD_OPTION_HTTPS_CERT_CALLBACK requires building " \
   6955                    "MHD with GnuTLS >= 3.0.\n"));
   6956 #endif
   6957       return MHD_NO;
   6958 #else
   6959       pgcrf = va_arg (ap,
   6960                       gnutls_certificate_retrieve_function2 *);
   6961       if (0 != (daemon->options & MHD_USE_TLS))
   6962         daemon->cert_callback = pgcrf;
   6963 #ifdef HAVE_MESSAGES
   6964       else
   6965         MHD_DLOG (daemon,
   6966                   _ ("MHD HTTPS option %d passed to MHD but " \
   6967                      "MHD_USE_TLS not set.\n"),
   6968                   opt);
   6969 #endif /*  HAVE_MESSAGES */
   6970       break;
   6971 #endif
   6972     case MHD_OPTION_HTTPS_CERT_CALLBACK2:
   6973 #if GNUTLS_VERSION_NUMBER < 0x030603
   6974 #ifdef HAVE_MESSAGES
   6975       MHD_DLOG (daemon,
   6976                 _ ("MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building " \
   6977                    "MHD with GnuTLS >= 3.6.3.\n"));
   6978 #endif
   6979       return MHD_NO;
   6980 #else
   6981       pgcrf2 = va_arg (ap,
   6982                        gnutls_certificate_retrieve_function3 *);
   6983       if (0 != (daemon->options & MHD_USE_TLS))
   6984         daemon->cert_callback2 = pgcrf2;
   6985 #ifdef HAVE_MESSAGES
   6986       else
   6987         MHD_DLOG (daemon,
   6988                   _ ("MHD HTTPS option %d passed to MHD but " \
   6989                      "MHD_USE_TLS not set.\n"),
   6990                   opt);
   6991 #endif /* HAVE_MESSAGES */
   6992       break;
   6993 #endif
   6994 #endif /* HTTPS_SUPPORT */
   6995 #ifdef DAUTH_SUPPORT
   6996     case MHD_OPTION_DIGEST_AUTH_RANDOM:
   6997     case MHD_OPTION_DIGEST_AUTH_RANDOM_COPY:
   6998       daemon->digest_auth_rand_size = va_arg (ap,
   6999                                               size_t);
   7000       daemon->digest_auth_random = va_arg (ap,
   7001                                            const char *);
   7002       if (MHD_OPTION_DIGEST_AUTH_RANDOM_COPY == opt)
   7003         /* Set to some non-NULL value just to indicate that copy is required. */
   7004         daemon->digest_auth_random_copy = daemon;
   7005       else
   7006         daemon->digest_auth_random_copy = NULL;
   7007       break;
   7008     case MHD_OPTION_NONCE_NC_SIZE:
   7009       daemon->nonce_nc_size = va_arg (ap,
   7010                                       unsigned int);
   7011       break;
   7012     case MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE:
   7013       daemon->dauth_bind_type = va_arg (ap,
   7014                                         unsigned int);
   7015       if (0 != (daemon->dauth_bind_type & MHD_DAUTH_BIND_NONCE_URI_PARAMS))
   7016         daemon->dauth_bind_type |= MHD_DAUTH_BIND_NONCE_URI;
   7017       break;
   7018     case MHD_OPTION_DIGEST_AUTH_DEFAULT_NONCE_TIMEOUT:
   7019       if (1)
   7020       {
   7021         unsigned int val;
   7022         val = va_arg (ap,
   7023                       unsigned int);
   7024         if (0 != val)
   7025           daemon->dauth_def_nonce_timeout = val;
   7026       }
   7027       break;
   7028     case MHD_OPTION_DIGEST_AUTH_DEFAULT_MAX_NC:
   7029       if (1)
   7030       {
   7031         uint32_t val;
   7032         val = va_arg (ap,
   7033                       uint32_t);
   7034         if (0 != val)
   7035           daemon->dauth_def_max_nc = val;
   7036       }
   7037       break;
   7038 #else  /* ! DAUTH_SUPPORT */
   7039     case MHD_OPTION_DIGEST_AUTH_RANDOM:
   7040     case MHD_OPTION_DIGEST_AUTH_RANDOM_COPY:
   7041     case MHD_OPTION_NONCE_NC_SIZE:
   7042     case MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE:
   7043     case MHD_OPTION_DIGEST_AUTH_DEFAULT_NONCE_TIMEOUT:
   7044     case MHD_OPTION_DIGEST_AUTH_DEFAULT_MAX_NC:
   7045 #ifdef HAVE_MESSAGES
   7046       MHD_DLOG (daemon,
   7047                 _ ("Digest Auth is disabled for this build " \
   7048                    "of GNU libmicrohttpd.\n"));
   7049 #endif /* HAVE_MESSAGES */
   7050       return MHD_NO;
   7051 #endif /* ! DAUTH_SUPPORT */
   7052     case MHD_OPTION_LISTEN_SOCKET:
   7053       params->listen_fd = va_arg (ap,
   7054                                   MHD_socket);
   7055       params->listen_fd_set = true;
   7056       break;
   7057     case MHD_OPTION_EXTERNAL_LOGGER:
   7058 #ifdef HAVE_MESSAGES
   7059       daemon->custom_error_log = va_arg (ap,
   7060                                          VfprintfFunctionPointerType);
   7061       daemon->custom_error_log_cls = va_arg (ap,
   7062                                              void *);
   7063       if (1 != params->num_opts)
   7064         MHD_DLOG (daemon,
   7065                   _ ("MHD_OPTION_EXTERNAL_LOGGER is not the first option "
   7066                      "specified for the daemon. Some messages may be "
   7067                      "printed by the standard MHD logger.\n"));
   7068 
   7069 #else
   7070       (void) va_arg (ap,
   7071                      VfprintfFunctionPointerType);
   7072       (void) va_arg (ap,
   7073                      void *);
   7074 #endif
   7075       break;
   7076 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   7077     case MHD_OPTION_THREAD_STACK_SIZE:
   7078       daemon->thread_stack_size = va_arg (ap,
   7079                                           size_t);
   7080       break;
   7081 #endif
   7082     case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE:
   7083 #ifdef TCP_FASTOPEN
   7084       daemon->fastopen_queue_size = va_arg (ap,
   7085                                             unsigned int);
   7086       break;
   7087 #else  /* ! TCP_FASTOPEN */
   7088 #ifdef HAVE_MESSAGES
   7089       MHD_DLOG (daemon,
   7090                 _ ("TCP fastopen is not supported on this platform.\n"));
   7091 #endif /* HAVE_MESSAGES */
   7092       return MHD_NO;
   7093 #endif /* ! TCP_FASTOPEN */
   7094     case MHD_OPTION_LISTENING_ADDRESS_REUSE:
   7095       daemon->listening_address_reuse = va_arg (ap,
   7096                                                 unsigned int) ? 1 : -1;
   7097       break;
   7098     case MHD_OPTION_LISTEN_BACKLOG_SIZE:
   7099       daemon->listen_backlog_size = va_arg (ap,
   7100                                             unsigned int);
   7101       break;
   7102     case MHD_OPTION_STRICT_FOR_CLIENT:
   7103       daemon->client_discipline = va_arg (ap, int); /* Temporal assignment */
   7104       /* Map to correct value */
   7105       if (-1 >= daemon->client_discipline)
   7106         daemon->client_discipline = -3;
   7107       else if (1 <= daemon->client_discipline)
   7108         daemon->client_discipline = 1;
   7109 #ifdef HAVE_MESSAGES
   7110       if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) &&
   7111            (1 != daemon->client_discipline) )
   7112       {
   7113         MHD_DLOG (daemon,
   7114                   _ ("Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
   7115                      "another behaviour is specified by "
   7116                      "MHD_OPTION_STRICT_CLIENT.\n"));
   7117       }
   7118 #endif /* HAVE_MESSAGES */
   7119       break;
   7120     case MHD_OPTION_CLIENT_DISCIPLINE_LVL:
   7121       daemon->client_discipline = va_arg (ap, int);
   7122 #ifdef HAVE_MESSAGES
   7123       if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) &&
   7124            (1 != daemon->client_discipline) )
   7125       {
   7126         MHD_DLOG (daemon,
   7127                   _ ("Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
   7128                      "another behaviour is specified by "
   7129                      "MHD_OPTION_CLIENT_DISCIPLINE_LVL.\n"));
   7130       }
   7131 #endif /* HAVE_MESSAGES */
   7132       break;
   7133     case MHD_OPTION_ALLOW_BIN_ZERO_IN_URI_PATH:
   7134       daemon->allow_bzero_in_url = va_arg (ap, int);
   7135       if ((0 > daemon->allow_bzero_in_url) ||
   7136           (2 < daemon->allow_bzero_in_url))
   7137         daemon->allow_bzero_in_url = 1;
   7138       break;
   7139     case MHD_OPTION_ARRAY:
   7140       params->num_opts--; /* Do not count MHD_OPTION_ARRAY */
   7141       oa = va_arg (ap, struct MHD_OptionItem *);
   7142       i = 0;
   7143       while (MHD_OPTION_END != (opt = oa[i].option))
   7144       {
   7145         switch (opt)
   7146         {
   7147         /* all options taking 'size_t' */
   7148         case MHD_OPTION_CONNECTION_MEMORY_LIMIT:
   7149         case MHD_OPTION_CONNECTION_MEMORY_INCREMENT:
   7150         case MHD_OPTION_THREAD_STACK_SIZE:
   7151           if (MHD_NO == parse_options (daemon,
   7152                                        params,
   7153                                        opt,
   7154                                        (size_t) oa[i].value,
   7155                                        MHD_OPTION_END))
   7156             return MHD_NO;
   7157           break;
   7158         /* all options taking 'unsigned int' */
   7159         case MHD_OPTION_NONCE_NC_SIZE:
   7160         case MHD_OPTION_CONNECTION_LIMIT:
   7161         case MHD_OPTION_CONNECTION_TIMEOUT:
   7162         case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
   7163         case MHD_OPTION_THREAD_POOL_SIZE:
   7164         case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE:
   7165         case MHD_OPTION_LISTENING_ADDRESS_REUSE:
   7166         case MHD_OPTION_LISTEN_BACKLOG_SIZE:
   7167         case MHD_OPTION_SERVER_INSANITY:
   7168         case MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE:
   7169         case MHD_OPTION_DIGEST_AUTH_DEFAULT_NONCE_TIMEOUT:
   7170           if (MHD_NO == parse_options (daemon,
   7171                                        params,
   7172                                        opt,
   7173                                        (unsigned int) oa[i].value,
   7174                                        MHD_OPTION_END))
   7175             return MHD_NO;
   7176           break;
   7177         /* all options taking 'enum' */
   7178         case MHD_OPTION_HTTPS_CRED_TYPE:
   7179 #ifdef HTTPS_SUPPORT
   7180           if (MHD_NO == parse_options (daemon,
   7181                                        params,
   7182                                        opt,
   7183                                        (gnutls_credentials_type_t) oa[i].value,
   7184                                        MHD_OPTION_END))
   7185 #endif /* HTTPS_SUPPORT */
   7186           return MHD_NO;
   7187           break;
   7188         /* all options taking 'MHD_socket' */
   7189         case MHD_OPTION_LISTEN_SOCKET:
   7190           if (MHD_NO == parse_options (daemon,
   7191                                        params,
   7192                                        opt,
   7193                                        (MHD_socket) oa[i].value,
   7194                                        MHD_OPTION_END))
   7195             return MHD_NO;
   7196           break;
   7197         /* all options taking 'int' */
   7198         case MHD_OPTION_STRICT_FOR_CLIENT:
   7199         case MHD_OPTION_CLIENT_DISCIPLINE_LVL:
   7200         case MHD_OPTION_SIGPIPE_HANDLED_BY_APP:
   7201         case MHD_OPTION_TLS_NO_ALPN:
   7202         case MHD_OPTION_APP_FD_SETSIZE:
   7203         case MHD_OPTION_ALLOW_BIN_ZERO_IN_URI_PATH:
   7204           if (MHD_NO == parse_options (daemon,
   7205                                        params,
   7206                                        opt,
   7207                                        (int) oa[i].value,
   7208                                        MHD_OPTION_END))
   7209             return MHD_NO;
   7210           break;
   7211         /* all options taking 'uint32_t' */
   7212         case MHD_OPTION_DIGEST_AUTH_DEFAULT_MAX_NC:
   7213           if (MHD_NO == parse_options (daemon,
   7214                                        params,
   7215                                        opt,
   7216                                        (uint32_t) oa[i].value,
   7217                                        MHD_OPTION_END))
   7218             return MHD_NO;
   7219           break;
   7220         /* all options taking one pointer */
   7221         case MHD_OPTION_SOCK_ADDR:
   7222         case MHD_OPTION_HTTPS_MEM_KEY:
   7223         case MHD_OPTION_HTTPS_KEY_PASSWORD:
   7224         case MHD_OPTION_HTTPS_MEM_CERT:
   7225         case MHD_OPTION_HTTPS_MEM_TRUST:
   7226         case MHD_OPTION_HTTPS_MEM_DHPARAMS:
   7227         case MHD_OPTION_HTTPS_PRIORITIES:
   7228         case MHD_OPTION_HTTPS_PRIORITIES_APPEND:
   7229         case MHD_OPTION_ARRAY:
   7230         case MHD_OPTION_HTTPS_CERT_CALLBACK:
   7231         case MHD_OPTION_HTTPS_CERT_CALLBACK2:
   7232           if (MHD_NO == parse_options (daemon,
   7233                                        params,
   7234                                        opt,
   7235                                        oa[i].ptr_value,
   7236                                        MHD_OPTION_END))
   7237             return MHD_NO;
   7238           break;
   7239         /* all options taking two pointers */
   7240         case MHD_OPTION_NOTIFY_COMPLETED:
   7241         case MHD_OPTION_NOTIFY_CONNECTION:
   7242         case MHD_OPTION_URI_LOG_CALLBACK:
   7243         case MHD_OPTION_EXTERNAL_LOGGER:
   7244         case MHD_OPTION_UNESCAPE_CALLBACK:
   7245         case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER:
   7246           if (MHD_NO == parse_options (daemon,
   7247                                        params,
   7248                                        opt,
   7249                                        (void *) oa[i].value,
   7250                                        oa[i].ptr_value,
   7251                                        MHD_OPTION_END))
   7252             return MHD_NO;
   7253           break;
   7254         /* options taking size_t-number followed by pointer */
   7255         case MHD_OPTION_DIGEST_AUTH_RANDOM:
   7256         case MHD_OPTION_DIGEST_AUTH_RANDOM_COPY:
   7257           if (MHD_NO == parse_options (daemon,
   7258                                        params,
   7259                                        opt,
   7260                                        (size_t) oa[i].value,
   7261                                        oa[i].ptr_value,
   7262                                        MHD_OPTION_END))
   7263             return MHD_NO;
   7264           break;
   7265         /* options taking socklen_t-number followed by pointer */
   7266         case MHD_OPTION_SOCK_ADDR_LEN:
   7267           if (MHD_NO == parse_options (daemon,
   7268                                        params,
   7269                                        opt,
   7270                                        (socklen_t) oa[i].value,
   7271                                        oa[i].ptr_value,
   7272                                        MHD_OPTION_END))
   7273             return MHD_NO;
   7274           break;
   7275         case MHD_OPTION_END: /* Not possible */
   7276         default:
   7277           return MHD_NO;
   7278         }
   7279         i++;
   7280       }
   7281       break;
   7282     case MHD_OPTION_UNESCAPE_CALLBACK:
   7283       daemon->unescape_callback = va_arg (ap,
   7284                                           UnescapeCallback);
   7285       daemon->unescape_callback_cls = va_arg (ap,
   7286                                               void *);
   7287       break;
   7288 #ifdef HTTPS_SUPPORT
   7289     case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER:
   7290 #if GNUTLS_VERSION_MAJOR >= 3
   7291       daemon->cred_callback = va_arg (ap,
   7292                                       MHD_PskServerCredentialsCallback);
   7293       daemon->cred_callback_cls = va_arg (ap,
   7294                                           void *);
   7295       break;
   7296 #else
   7297       MHD_DLOG (daemon,
   7298                 _ ("MHD HTTPS option %d passed to MHD compiled " \
   7299                    "without GNUtls >= 3.\n"),
   7300                 opt);
   7301       return MHD_NO;
   7302 #endif
   7303 #endif /* HTTPS_SUPPORT */
   7304     case MHD_OPTION_SIGPIPE_HANDLED_BY_APP:
   7305       if (! MHD_D_IS_USING_THREADS_ (daemon))
   7306         daemon->sigpipe_blocked = ( (va_arg (ap,
   7307                                              int)) != 0);
   7308       else
   7309       {
   7310         (void) va_arg (ap,
   7311                        int);
   7312       }
   7313       break;
   7314     case MHD_OPTION_TLS_NO_ALPN:
   7315 #ifdef HTTPS_SUPPORT
   7316       daemon->disable_alpn = (va_arg (ap,
   7317                                       int) != 0);
   7318 #else  /* ! HTTPS_SUPPORT */
   7319       (void) va_arg (ap, int);
   7320 #endif /* ! HTTPS_SUPPORT */
   7321 #ifdef HAVE_MESSAGES
   7322       if (0 == (daemon->options & MHD_USE_TLS))
   7323         MHD_DLOG (daemon,
   7324                   _ ("MHD HTTPS option %d passed to MHD " \
   7325                      "but MHD_USE_TLS not set.\n"),
   7326                   (int) opt);
   7327 #endif /* HAVE_MESSAGES */
   7328       break;
   7329     case MHD_OPTION_APP_FD_SETSIZE:
   7330       params->fdset_size_set = true;
   7331       params->fdset_size = va_arg (ap,
   7332                                    int);
   7333       break;
   7334 #ifndef HTTPS_SUPPORT
   7335     case MHD_OPTION_HTTPS_MEM_KEY:
   7336     case MHD_OPTION_HTTPS_MEM_CERT:
   7337     case MHD_OPTION_HTTPS_CRED_TYPE:
   7338     case MHD_OPTION_HTTPS_PRIORITIES:
   7339     case MHD_OPTION_HTTPS_PRIORITIES_APPEND:
   7340     case MHD_OPTION_HTTPS_MEM_TRUST:
   7341     case MHD_OPTION_HTTPS_CERT_CALLBACK:
   7342     case MHD_OPTION_HTTPS_MEM_DHPARAMS:
   7343     case MHD_OPTION_HTTPS_KEY_PASSWORD:
   7344     case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER:
   7345     case MHD_OPTION_HTTPS_CERT_CALLBACK2:
   7346 #ifdef HAVE_MESSAGES
   7347       MHD_DLOG (daemon,
   7348                 _ ("MHD HTTPS option %d passed to MHD "
   7349                    "compiled without HTTPS support.\n"),
   7350                 opt);
   7351 #endif
   7352       return MHD_NO;
   7353 #endif /* HTTPS_SUPPORT */
   7354     case MHD_OPTION_END: /* Not possible */
   7355     default:
   7356 #ifdef HAVE_MESSAGES
   7357       MHD_DLOG (daemon,
   7358                 _ ("Invalid option %d! (Did you terminate "
   7359                    "the list with MHD_OPTION_END?).\n"),
   7360                 opt);
   7361 #endif
   7362       return MHD_NO;
   7363     }
   7364   }
   7365   return MHD_YES;
   7366 }
   7367 
   7368 
   7369 #ifdef EPOLL_SUPPORT
   7370 static int
   7371 setup_epoll_fd (struct MHD_Daemon *daemon)
   7372 {
   7373   int fd;
   7374 
   7375 #ifndef HAVE_MESSAGES
   7376   (void) daemon; /* Mute compiler warning. */
   7377 #endif /* ! HAVE_MESSAGES */
   7378 
   7379 #ifdef USE_EPOLL_CREATE1
   7380   fd = epoll_create1 (EPOLL_CLOEXEC);
   7381 #else  /* ! USE_EPOLL_CREATE1 */
   7382   fd = epoll_create (MAX_EVENTS);
   7383 #endif /* ! USE_EPOLL_CREATE1 */
   7384   if (MHD_INVALID_SOCKET == fd)
   7385   {
   7386 #ifdef HAVE_MESSAGES
   7387     MHD_DLOG (daemon,
   7388               _ ("Call to epoll_create1 failed: %s\n"),
   7389               MHD_socket_last_strerr_ ());
   7390 #endif
   7391     return MHD_INVALID_SOCKET;
   7392   }
   7393 #if ! defined(USE_EPOLL_CREATE1)
   7394   if (! MHD_socket_noninheritable_ (fd))
   7395   {
   7396 #ifdef HAVE_MESSAGES
   7397     MHD_DLOG (daemon,
   7398               _ ("Failed to set noninheritable mode on epoll FD.\n"));
   7399 #endif
   7400   }
   7401 #endif /* ! USE_EPOLL_CREATE1 */
   7402   return fd;
   7403 }
   7404 
   7405 
   7406 /**
   7407  * Setup epoll() FD for the daemon and initialize it to listen
   7408  * on the listen FD.
   7409  * @remark To be called only from MHD_start_daemon_va()
   7410  *
   7411  * @param daemon daemon to initialize for epoll()
   7412  * @return #MHD_YES on success, #MHD_NO on failure
   7413  */
   7414 static enum MHD_Result
   7415 setup_epoll_to_listen (struct MHD_Daemon *daemon)
   7416 {
   7417   struct epoll_event event;
   7418   MHD_socket ls;
   7419 
   7420   mhd_assert (MHD_D_IS_USING_EPOLL_ (daemon));
   7421   mhd_assert (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION));
   7422   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   7423                (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) || \
   7424                MHD_ITC_IS_VALID_ (daemon->itc) );
   7425   daemon->epoll_fd = setup_epoll_fd (daemon);
   7426   if (! MHD_D_IS_USING_THREADS_ (daemon)
   7427       && (0 != (daemon->options & MHD_USE_AUTO)))
   7428   {
   7429     /* Application requested "MHD_USE_AUTO", probably MHD_get_fdset() will be
   7430        used.
   7431        Make sure that epoll FD is suitable for fd_set.
   7432        Actually, MHD_get_fdset() is allowed for MHD_USE_EPOLL direct,
   7433        but most probably direct requirement for MHD_USE_EPOLL means that
   7434        epoll FD will be used directly. This logic is fuzzy, but better
   7435        than nothing with current MHD API. */
   7436     if (! MHD_D_DOES_SCKT_FIT_FDSET_ (daemon->epoll_fd, daemon))
   7437     {
   7438 #ifdef HAVE_MESSAGES
   7439       MHD_DLOG (daemon,
   7440                 _ ("The epoll FD is too large to be used with fd_set.\n"));
   7441 #endif /* HAVE_MESSAGES */
   7442       return MHD_NO;
   7443     }
   7444   }
   7445   if (-1 == daemon->epoll_fd)
   7446     return MHD_NO;
   7447 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   7448   if (0 != (MHD_ALLOW_UPGRADE & daemon->options))
   7449   {
   7450     daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
   7451     if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd)
   7452       return MHD_NO;
   7453   }
   7454 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   7455   if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
   7456        (! daemon->was_quiesced) )
   7457   {
   7458     event.events = EPOLLIN | EPOLLRDHUP;
   7459     event.data.ptr = daemon;
   7460     if (0 != epoll_ctl (daemon->epoll_fd,
   7461                         EPOLL_CTL_ADD,
   7462                         ls,
   7463                         &event))
   7464     {
   7465 #ifdef HAVE_MESSAGES
   7466       MHD_DLOG (daemon,
   7467                 _ ("Call to epoll_ctl failed: %s\n"),
   7468                 MHD_socket_last_strerr_ ());
   7469 #endif
   7470       return MHD_NO;
   7471     }
   7472     daemon->listen_socket_in_epoll = true;
   7473   }
   7474 
   7475   if (MHD_ITC_IS_VALID_ (daemon->itc))
   7476   {
   7477     event.events = EPOLLIN | EPOLLRDHUP;
   7478     event.data.ptr = _MHD_DROP_CONST (epoll_itc_marker);
   7479     if (0 != epoll_ctl (daemon->epoll_fd,
   7480                         EPOLL_CTL_ADD,
   7481                         MHD_itc_r_fd_ (daemon->itc),
   7482                         &event))
   7483     {
   7484 #ifdef HAVE_MESSAGES
   7485       MHD_DLOG (daemon,
   7486                 _ ("Call to epoll_ctl failed: %s\n"),
   7487                 MHD_socket_last_strerr_ ());
   7488 #endif
   7489       return MHD_NO;
   7490     }
   7491   }
   7492   return MHD_YES;
   7493 }
   7494 
   7495 
   7496 #endif
   7497 
   7498 
   7499 /**
   7500  * Apply interim parameters
   7501  * @param[in,out] d the daemon to use
   7502  * @param[out] ppsockaddr the pointer to store the pointer to 'struct sockaddr'
   7503  *                        if provided by application
   7504  * @param[out] psockaddr_len the size memory area pointed by 'struct sockaddr'
   7505  *                           if provided by application
   7506  * @param[in,out] params the interim parameters to process
   7507  * @return true in case of success,
   7508  *         false in case of critical error (the daemon must be closed).
   7509  */
   7510 static bool
   7511 process_interim_params (struct MHD_Daemon *d,
   7512                         const struct sockaddr **ppsockaddr,
   7513                         socklen_t *psockaddr_len,
   7514                         struct MHD_InterimParams_ *params)
   7515 {
   7516   if (params->fdset_size_set)
   7517   {
   7518     if (0 >= params->fdset_size)
   7519     {
   7520 #ifdef HAVE_MESSAGES
   7521       MHD_DLOG (d,
   7522                 _ ("MHD_OPTION_APP_FD_SETSIZE value (%d) is not positive.\n"),
   7523                 params->fdset_size);
   7524 #endif /* HAVE_MESSAGES */
   7525       return false;
   7526     }
   7527     if (MHD_D_IS_USING_THREADS_ (d))
   7528     {
   7529 #ifdef HAVE_MESSAGES
   7530       MHD_DLOG (d,
   7531                 _ ("MHD_OPTION_APP_FD_SETSIZE is ignored for daemon started " \
   7532                    "with MHD_USE_INTERNAL_POLLING_THREAD.\n"));
   7533 #endif /* HAVE_MESSAGES */
   7534       (void) 0;
   7535     }
   7536     else if (MHD_D_IS_USING_POLL_ (d))
   7537     {
   7538 #ifdef HAVE_MESSAGES
   7539       MHD_DLOG (d,
   7540                 _ ("MHD_OPTION_APP_FD_SETSIZE is ignored for daemon started " \
   7541                    "with MHD_USE_POLL.\n"));
   7542 #endif /* HAVE_MESSAGES */
   7543       (void) 0;
   7544     }
   7545     else
   7546     { /* The daemon without internal threads, external sockets polling */
   7547 #ifndef HAS_FD_SETSIZE_OVERRIDABLE
   7548       if (((int) FD_SETSIZE) != params->fdset_size)
   7549       {
   7550 #ifdef HAVE_MESSAGES
   7551         MHD_DLOG (d,
   7552                   _ ("MHD_OPTION_APP_FD_SETSIZE value (%d) does not match " \
   7553                      "the platform FD_SETSIZE value (%d) and this platform " \
   7554                      "does not support overriding of FD_SETSIZE.\n"),
   7555                   params->fdset_size, (int) FD_SETSIZE);
   7556 #endif /* HAVE_MESSAGES */
   7557         return false;
   7558       }
   7559 #else  /* HAS_FD_SETSIZE_OVERRIDABLE */
   7560       d->fdset_size = params->fdset_size;
   7561       d->fdset_size_set_by_app = true;
   7562 #endif /* HAS_FD_SETSIZE_OVERRIDABLE */
   7563     }
   7564   }
   7565 
   7566   if (params->listen_fd_set)
   7567   {
   7568     if (MHD_INVALID_SOCKET == params->listen_fd)
   7569     {
   7570       (void) 0; /* Use MHD-created socket */
   7571     }
   7572 #ifdef HAS_SIGNED_SOCKET
   7573     else if (0 > params->listen_fd)
   7574     {
   7575 #ifdef HAVE_MESSAGES
   7576       MHD_DLOG (d,
   7577                 _ ("The value provided for MHD_OPTION_LISTEN_SOCKET " \
   7578                    "is invalid.\n"));
   7579 #endif /* HAVE_MESSAGES */
   7580       return false;
   7581     }
   7582 #endif /* HAS_SIGNED_SOCKET */
   7583     else if (0 != (d->options & MHD_USE_NO_LISTEN_SOCKET))
   7584     {
   7585 #ifdef HAVE_MESSAGES
   7586       MHD_DLOG (d,
   7587                 _ ("MHD_OPTION_LISTEN_SOCKET specified for daemon "
   7588                    "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
   7589 #endif /* HAVE_MESSAGES */
   7590       (void) MHD_socket_close_ (params->listen_fd);
   7591       return false;
   7592     }
   7593     else
   7594     {
   7595       d->listen_fd = params->listen_fd;
   7596       d->listen_is_unix = _MHD_UNKNOWN;
   7597 #ifdef MHD_USE_GETSOCKNAME
   7598       d->port = 0;  /* Force use of autodetection */
   7599 #endif /* MHD_USE_GETSOCKNAME */
   7600     }
   7601   }
   7602 
   7603   mhd_assert (! params->server_addr_len_set || params->pserver_addr_set);
   7604   if (params->pserver_addr_set)
   7605   {
   7606     if (NULL == params->pserver_addr)
   7607     {
   7608       /* The size must be zero if set */
   7609       if (params->server_addr_len_set && (0 != params->server_addr_len))
   7610         return false;
   7611       /* Ignore parameter if it is NULL */
   7612     }
   7613     else if (MHD_INVALID_SOCKET != d->listen_fd)
   7614     {
   7615 #ifdef HAVE_MESSAGES
   7616       MHD_DLOG (d,
   7617                 _ ("MHD_OPTION_LISTEN_SOCKET cannot be used together with " \
   7618                    "MHD_OPTION_SOCK_ADDR_LEN or MHD_OPTION_SOCK_ADDR.\n"));
   7619 #endif /* HAVE_MESSAGES */
   7620       return false;
   7621     }
   7622     else if (0 != (d->options & MHD_USE_NO_LISTEN_SOCKET))
   7623     {
   7624 #ifdef HAVE_MESSAGES
   7625       MHD_DLOG (d,
   7626                 _ ("MHD_OPTION_SOCK_ADDR_LEN or MHD_OPTION_SOCK_ADDR " \
   7627                    "specified for daemon with MHD_USE_NO_LISTEN_SOCKET " \
   7628                    "flag set.\n"));
   7629 #endif /* HAVE_MESSAGES */
   7630       if (MHD_INVALID_SOCKET != d->listen_fd)
   7631       {
   7632         (void) MHD_socket_close_ (params->listen_fd);
   7633         params->listen_fd = MHD_INVALID_SOCKET;
   7634       }
   7635       return false;
   7636     }
   7637     else
   7638     {
   7639       *ppsockaddr = params->pserver_addr;
   7640       if (params->server_addr_len_set)
   7641       {
   7642         /* The size must be non-zero if set */
   7643         if (0 == params->server_addr_len)
   7644           return false;
   7645         *psockaddr_len = params->server_addr_len;
   7646       }
   7647       else
   7648         *psockaddr_len = 0;
   7649     }
   7650   }
   7651   return true;
   7652 }
   7653 
   7654 
   7655 /**
   7656  * Start a webserver on the given port.
   7657  *
   7658  * @param flags combination of `enum MHD_FLAG` values
   7659  * @param port port to bind to (in host byte order),
   7660  *        use '0' to bind to random free port,
   7661  *        ignored if #MHD_OPTION_SOCK_ADDR or
   7662  *        #MHD_OPTION_LISTEN_SOCKET is provided
   7663  *        or #MHD_USE_NO_LISTEN_SOCKET is specified
   7664  * @param apc callback to call to check which clients
   7665  *        will be allowed to connect; you can pass NULL
   7666  *        in which case connections from any IP will be
   7667  *        accepted
   7668  * @param apc_cls extra argument to @a apc
   7669  * @param dh handler called for all requests (repeatedly)
   7670  * @param dh_cls extra argument to @a dh
   7671  * @param ap list of options (type-value pairs,
   7672  *        terminated with #MHD_OPTION_END).
   7673  * @return NULL on error, handle to daemon on success
   7674  * @ingroup event
   7675  */
   7676 _MHD_EXTERN struct MHD_Daemon *
   7677 MHD_start_daemon_va (unsigned int flags,
   7678                      uint16_t port,
   7679                      MHD_AcceptPolicyCallback apc,
   7680                      void *apc_cls,
   7681                      MHD_AccessHandlerCallback dh,
   7682                      void *dh_cls,
   7683                      va_list ap)
   7684 {
   7685   const MHD_SCKT_OPT_BOOL_ on = 1;
   7686   struct MHD_Daemon *daemon;
   7687   const struct sockaddr *pservaddr = NULL;
   7688   socklen_t addrlen;
   7689 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   7690   unsigned int i;
   7691 #endif
   7692   enum MHD_FLAG eflags; /* same type as in MHD_Daemon */
   7693   enum MHD_FLAG *pflags;
   7694   struct MHD_InterimParams_ *interim_params;
   7695 
   7696   MHD_check_global_init_ ();
   7697   eflags = (enum MHD_FLAG) flags;
   7698   pflags = &eflags;
   7699 
   7700   if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
   7701     *pflags |= MHD_USE_INTERNAL_POLLING_THREAD; /* Force enable, log warning later if needed */
   7702 
   7703 #ifndef HAVE_INET6
   7704   if (0 != (*pflags & MHD_USE_IPv6))
   7705     return NULL;
   7706 #endif
   7707 #ifndef HAVE_POLL
   7708   if (0 != (*pflags & MHD_USE_POLL))
   7709     return NULL;
   7710 #endif
   7711 #ifndef EPOLL_SUPPORT
   7712   if (0 != (*pflags & MHD_USE_EPOLL))
   7713     return NULL;
   7714 #endif /* ! EPOLL_SUPPORT */
   7715 #ifndef HTTPS_SUPPORT
   7716   if (0 != (*pflags & MHD_USE_TLS))
   7717     return NULL;
   7718 #endif /* ! HTTPS_SUPPORT */
   7719 #ifndef TCP_FASTOPEN
   7720   if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
   7721     return NULL;
   7722 #endif
   7723   if (0 != (*pflags & MHD_ALLOW_UPGRADE))
   7724   {
   7725 #ifdef UPGRADE_SUPPORT
   7726     *pflags |= MHD_ALLOW_SUSPEND_RESUME;
   7727 #else  /* ! UPGRADE_SUPPORT */
   7728     return NULL;
   7729 #endif /* ! UPGRADE_SUPPORT */
   7730   }
   7731 #ifdef MHD_USE_THREADS
   7732   if ((MHD_USE_NO_THREAD_SAFETY | MHD_USE_INTERNAL_POLLING_THREAD) ==
   7733       ((MHD_USE_NO_THREAD_SAFETY | MHD_USE_INTERNAL_POLLING_THREAD)
   7734        & *pflags))
   7735     return NULL; /* Cannot be thread-unsafe with multiple threads */
   7736 #else  /* ! MHD_USE_THREADS */
   7737   if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
   7738     return NULL;
   7739 #endif /* ! MHD_USE_THREADS */
   7740 
   7741   if (NULL == dh)
   7742     return NULL;
   7743 
   7744   /* Check for invalid combinations of flags. */
   7745   if ((0 != (*pflags & MHD_USE_POLL)) && (0 != (*pflags & MHD_USE_EPOLL)))
   7746     return NULL;
   7747   if ((0 != (*pflags & MHD_USE_EPOLL)) &&
   7748       (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)))
   7749     return NULL;
   7750   if ((0 != (*pflags & MHD_USE_POLL)) &&
   7751       (0 == (*pflags & (MHD_USE_INTERNAL_POLLING_THREAD
   7752                         | MHD_USE_THREAD_PER_CONNECTION))))
   7753     return NULL;
   7754   if ((0 != (*pflags & MHD_USE_AUTO)) &&
   7755       (0 != (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))))
   7756     return NULL;
   7757 
   7758   if (0 != (*pflags & MHD_USE_AUTO))
   7759   {
   7760 #if defined(EPOLL_SUPPORT) && defined(HAVE_POLL)
   7761     if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
   7762       *pflags |= MHD_USE_POLL;
   7763     else
   7764       *pflags |= MHD_USE_EPOLL; /* Including "external select" mode */
   7765 #elif defined(HAVE_POLL)
   7766     if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
   7767       *pflags |= MHD_USE_POLL; /* Including thread-per-connection */
   7768 #elif defined(EPOLL_SUPPORT)
   7769     if (0 == (*pflags & MHD_USE_THREAD_PER_CONNECTION))
   7770       *pflags |= MHD_USE_EPOLL; /* Including "external select" mode */
   7771 #else
   7772     /* No choice: use select() for any mode - do not modify flags */
   7773 #endif
   7774   }
   7775 
   7776   if (0 != (*pflags & MHD_USE_NO_THREAD_SAFETY))
   7777     *pflags = (*pflags & ~((enum MHD_FLAG) MHD_USE_ITC)); /* useless in single-threaded environment */
   7778   else if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
   7779   {
   7780 #ifdef HAVE_LISTEN_SHUTDOWN
   7781     if (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET))
   7782 #endif
   7783     *pflags |= MHD_USE_ITC;       /* yes, must use ITC to signal thread */
   7784   }
   7785 
   7786   if (NULL == (daemon = MHD_calloc_ (1, sizeof (struct MHD_Daemon))))
   7787     return NULL;
   7788   interim_params = (struct MHD_InterimParams_ *) \
   7789                    MHD_calloc_ (1, sizeof (struct MHD_InterimParams_));
   7790   if (NULL == interim_params)
   7791   {
   7792     int err_num = errno;
   7793     free (daemon);
   7794     errno = err_num;
   7795     return NULL;
   7796   }
   7797 #ifdef EPOLL_SUPPORT
   7798   daemon->epoll_fd = -1;
   7799 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   7800   daemon->epoll_upgrade_fd = -1;
   7801 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   7802 #endif
   7803   /* try to open listen socket */
   7804 #ifdef HTTPS_SUPPORT
   7805   daemon->priority_cache = NULL;
   7806 #endif /* HTTPS_SUPPORT */
   7807   daemon->listen_fd = MHD_INVALID_SOCKET;
   7808   daemon->listen_is_unix = _MHD_NO;
   7809   daemon->listening_address_reuse = 0;
   7810   daemon->options = *pflags;
   7811   pflags = &daemon->options;
   7812   daemon->client_discipline = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ?
   7813                               1 : 0;
   7814   daemon->port = port;
   7815   daemon->apc = apc;
   7816   daemon->apc_cls = apc_cls;
   7817   daemon->default_handler = dh;
   7818   daemon->default_handler_cls = dh_cls;
   7819   daemon->connections = 0;
   7820   daemon->connection_limit = MHD_MAX_CONNECTIONS_DEFAULT;
   7821   daemon->pool_size = MHD_POOL_SIZE_DEFAULT;
   7822   daemon->pool_increment = MHD_BUF_INC_SIZE;
   7823   daemon->unescape_callback = &unescape_wrapper;
   7824   daemon->connection_timeout_ms = 0;       /* no timeout */
   7825   MHD_itc_set_invalid_ (daemon->itc);
   7826 #ifdef MHD_USE_THREADS
   7827   MHD_thread_handle_ID_set_invalid_ (&daemon->tid);
   7828 #endif /* MHD_USE_THREADS */
   7829 #ifdef SOMAXCONN
   7830   daemon->listen_backlog_size = SOMAXCONN;
   7831 #else  /* !SOMAXCONN */
   7832   daemon->listen_backlog_size = 511; /* should be safe value */
   7833 #endif /* !SOMAXCONN */
   7834 #ifdef HAVE_MESSAGES
   7835   daemon->custom_error_log = &MHD_default_logger_;
   7836   daemon->custom_error_log_cls = stderr;
   7837 #endif
   7838 #ifndef MHD_WINSOCK_SOCKETS
   7839   daemon->sigpipe_blocked = false;
   7840 #else  /* MHD_WINSOCK_SOCKETS */
   7841   /* There is no SIGPIPE on W32, nothing to block. */
   7842   daemon->sigpipe_blocked = true;
   7843 #endif /* _WIN32 && ! __CYGWIN__ */
   7844 #if defined(_DEBUG) && defined(HAVE_ACCEPT4)
   7845   daemon->avoid_accept4 = false;
   7846 #endif /* _DEBUG */
   7847 #ifdef HAS_FD_SETSIZE_OVERRIDABLE
   7848   daemon->fdset_size = (int) FD_SETSIZE;
   7849   daemon->fdset_size_set_by_app = false;
   7850 #endif /* HAS_FD_SETSIZE_OVERRIDABLE */
   7851 
   7852 #ifdef DAUTH_SUPPORT
   7853   daemon->digest_auth_rand_size = 0;
   7854   daemon->digest_auth_random = NULL;
   7855   daemon->nonce_nc_size = 4; /* tiny */
   7856   daemon->dauth_def_nonce_timeout = MHD_DAUTH_DEF_TIMEOUT_;
   7857   daemon->dauth_def_max_nc = MHD_DAUTH_DEF_MAX_NC_;
   7858 #endif
   7859 #ifdef HTTPS_SUPPORT
   7860   if (0 != (*pflags & MHD_USE_TLS))
   7861   {
   7862     daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
   7863   }
   7864 #endif /* HTTPS_SUPPORT */
   7865 
   7866   interim_params->num_opts = 0;
   7867   interim_params->fdset_size_set = false;
   7868   interim_params->fdset_size = 0;
   7869   interim_params->listen_fd_set = false;
   7870   interim_params->listen_fd = MHD_INVALID_SOCKET;
   7871   interim_params->pserver_addr_set = false;
   7872   interim_params->pserver_addr = NULL;
   7873   interim_params->server_addr_len_set = false;
   7874   interim_params->server_addr_len = 0;
   7875 
   7876   if (MHD_NO == parse_options_va (daemon,
   7877                                   interim_params,
   7878                                   ap))
   7879   {
   7880 #ifdef HTTPS_SUPPORT
   7881     if ( (0 != (*pflags & MHD_USE_TLS)) &&
   7882          (NULL != daemon->priority_cache) )
   7883       gnutls_priority_deinit (daemon->priority_cache);
   7884 #endif /* HTTPS_SUPPORT */
   7885     free (interim_params);
   7886     free (daemon);
   7887     return NULL;
   7888   }
   7889   if (! process_interim_params (daemon,
   7890                                 &pservaddr,
   7891                                 &addrlen,
   7892                                 interim_params))
   7893   {
   7894     free (interim_params);
   7895     free (daemon);
   7896     return NULL;
   7897   }
   7898   free (interim_params);
   7899   interim_params = NULL;
   7900 #ifdef HTTPS_SUPPORT
   7901   if ((0 != (*pflags & MHD_USE_TLS))
   7902       && (NULL == daemon->priority_cache)
   7903       && ! daemon_tls_priorities_init_default (daemon))
   7904   {
   7905 #ifdef HAVE_MESSAGES
   7906     MHD_DLOG (daemon,
   7907               _ ("Failed to initialise GnuTLS priorities.\n"));
   7908 #endif /* HAVE_MESSAGES */
   7909     free (daemon);
   7910     return NULL;
   7911   }
   7912 #endif /* HTTPS_SUPPORT */
   7913 
   7914 #ifdef HAVE_MESSAGES
   7915   if ( (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) &&
   7916        (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD)) )
   7917   {
   7918     MHD_DLOG (daemon,
   7919               _ ("Warning: MHD_USE_THREAD_PER_CONNECTION must be used " \
   7920                  "only with MHD_USE_INTERNAL_POLLING_THREAD. " \
   7921                  "Flag MHD_USE_INTERNAL_POLLING_THREAD was added. " \
   7922                  "Consider setting MHD_USE_INTERNAL_POLLING_THREAD " \
   7923                  "explicitly.\n"));
   7924   }
   7925 #endif
   7926 
   7927   if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)
   7928       && ((NULL != daemon->notify_completed)
   7929           || (NULL != daemon->notify_connection)) )
   7930     *pflags |= MHD_USE_ITC; /* requires ITC */
   7931 
   7932 #ifdef _DEBUG
   7933 #ifdef HAVE_MESSAGES
   7934   MHD_DLOG (daemon,
   7935             _ ("Using debug build of libmicrohttpd.\n") );
   7936 #endif /* HAVE_MESSAGES */
   7937 #endif /* _DEBUG */
   7938 
   7939   if ( (0 != (*pflags & MHD_USE_ITC))
   7940 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   7941        && (0 == daemon->worker_pool_size)
   7942 #endif
   7943        )
   7944   {
   7945     if (! MHD_itc_init_ (daemon->itc))
   7946     {
   7947 #ifdef HAVE_MESSAGES
   7948       MHD_DLOG (daemon,
   7949                 _ ("Failed to create inter-thread communication channel: %s\n"),
   7950                 MHD_itc_last_strerror_ ());
   7951 #endif
   7952 #ifdef HTTPS_SUPPORT
   7953       if (NULL != daemon->priority_cache)
   7954         gnutls_priority_deinit (daemon->priority_cache);
   7955 #endif /* HTTPS_SUPPORT */
   7956       free (daemon);
   7957       return NULL;
   7958     }
   7959     if (MHD_D_IS_USING_SELECT_ (daemon) &&
   7960         (! MHD_D_DOES_SCKT_FIT_FDSET_ (MHD_itc_r_fd_ (daemon->itc), daemon)) )
   7961     {
   7962 #ifdef HAVE_MESSAGES
   7963       MHD_DLOG (daemon,
   7964                 _ ("file descriptor for inter-thread communication " \
   7965                    "channel exceeds maximum value.\n"));
   7966 #endif
   7967       MHD_itc_destroy_chk_ (daemon->itc);
   7968 #ifdef HTTPS_SUPPORT
   7969       if (NULL != daemon->priority_cache)
   7970         gnutls_priority_deinit (daemon->priority_cache);
   7971 #endif /* HTTPS_SUPPORT */
   7972       free (daemon);
   7973       return NULL;
   7974     }
   7975   }
   7976 
   7977 #ifdef DAUTH_SUPPORT
   7978   if (NULL != daemon->digest_auth_random_copy)
   7979   {
   7980     mhd_assert (daemon == daemon->digest_auth_random_copy);
   7981     daemon->digest_auth_random_copy = malloc (daemon->digest_auth_rand_size);
   7982     if (NULL == daemon->digest_auth_random_copy)
   7983     {
   7984 #ifdef HTTPS_SUPPORT
   7985       if (0 != (*pflags & MHD_USE_TLS))
   7986         gnutls_priority_deinit (daemon->priority_cache);
   7987 #endif /* HTTPS_SUPPORT */
   7988       free (daemon);
   7989       return NULL;
   7990     }
   7991     memcpy (daemon->digest_auth_random_copy,
   7992             daemon->digest_auth_random,
   7993             daemon->digest_auth_rand_size);
   7994     daemon->digest_auth_random = daemon->digest_auth_random_copy;
   7995   }
   7996   if (daemon->nonce_nc_size > 0)
   7997   {
   7998     if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc)))
   7999          / sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size)
   8000     {
   8001 #ifdef HAVE_MESSAGES
   8002       MHD_DLOG (daemon,
   8003                 _ ("Specified value for NC_SIZE too large.\n"));
   8004 #endif
   8005 #ifdef HTTPS_SUPPORT
   8006       if (0 != (*pflags & MHD_USE_TLS))
   8007         gnutls_priority_deinit (daemon->priority_cache);
   8008 #endif /* HTTPS_SUPPORT */
   8009       free (daemon->digest_auth_random_copy);
   8010       free (daemon);
   8011       return NULL;
   8012     }
   8013     daemon->nnc = MHD_calloc_ (daemon->nonce_nc_size,
   8014                                sizeof (struct MHD_NonceNc));
   8015     if (NULL == daemon->nnc)
   8016     {
   8017 #ifdef HAVE_MESSAGES
   8018       MHD_DLOG (daemon,
   8019                 _ ("Failed to allocate memory for nonce-nc map: %s\n"),
   8020                 MHD_strerror_ (errno));
   8021 #endif
   8022 #ifdef HTTPS_SUPPORT
   8023       if (0 != (*pflags & MHD_USE_TLS))
   8024         gnutls_priority_deinit (daemon->priority_cache);
   8025 #endif /* HTTPS_SUPPORT */
   8026       free (daemon->digest_auth_random_copy);
   8027       free (daemon);
   8028       return NULL;
   8029     }
   8030   }
   8031 
   8032 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8033   if (! MHD_mutex_init_ (&daemon->nnc_lock))
   8034   {
   8035 #ifdef HAVE_MESSAGES
   8036     MHD_DLOG (daemon,
   8037               _ ("MHD failed to initialize nonce-nc mutex.\n"));
   8038 #endif
   8039 #ifdef HTTPS_SUPPORT
   8040     if (0 != (*pflags & MHD_USE_TLS))
   8041       gnutls_priority_deinit (daemon->priority_cache);
   8042 #endif /* HTTPS_SUPPORT */
   8043     free (daemon->digest_auth_random_copy);
   8044     free (daemon->nnc);
   8045     free (daemon);
   8046     return NULL;
   8047   }
   8048 #endif
   8049 #endif
   8050 
   8051   /* Thread polling currently works only with internal select thread mode */
   8052 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8053   if ( (! MHD_D_IS_USING_THREADS_ (daemon)) &&
   8054        (daemon->worker_pool_size > 0) )
   8055   {
   8056 #ifdef HAVE_MESSAGES
   8057     MHD_DLOG (daemon,
   8058               _ ("MHD thread polling only works with " \
   8059                  "MHD_USE_INTERNAL_POLLING_THREAD.\n"));
   8060 #endif
   8061     goto free_and_fail;
   8062   }
   8063 #endif
   8064 
   8065   if ( (MHD_INVALID_SOCKET == daemon->listen_fd) &&
   8066        (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
   8067   {
   8068     /* try to open listen socket */
   8069     struct sockaddr_in servaddr4;
   8070 #ifdef HAVE_INET6
   8071     struct sockaddr_in6 servaddr6;
   8072     const bool use_ipv6 = (0 != (*pflags & MHD_USE_IPv6));
   8073 #else  /* ! HAVE_INET6 */
   8074     const bool use_ipv6 = false;
   8075 #endif /* ! HAVE_INET6 */
   8076     int domain;
   8077 
   8078     if (NULL != pservaddr)
   8079     {
   8080 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
   8081       const socklen_t sa_len = pservaddr->sa_len;
   8082 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
   8083 #ifdef HAVE_INET6
   8084       if (use_ipv6 && (AF_INET6 != pservaddr->sa_family))
   8085       {
   8086 #ifdef HAVE_MESSAGES
   8087         MHD_DLOG (daemon,
   8088                   _ ("MHD_USE_IPv6 is enabled, but 'struct sockaddr *' " \
   8089                      "specified for MHD_OPTION_SOCK_ADDR_LEN or " \
   8090                      "MHD_OPTION_SOCK_ADDR is not IPv6 address.\n"));
   8091 #endif /* HAVE_MESSAGES */
   8092         goto free_and_fail;
   8093       }
   8094 #endif /* HAVE_INET6 */
   8095       switch (pservaddr->sa_family)
   8096       {
   8097       case AF_INET:
   8098         if (1)
   8099         {
   8100           struct sockaddr_in sa4;
   8101           uint16_t sa4_port;
   8102           if ((0 != addrlen)
   8103               && (((socklen_t) sizeof(sa4)) > addrlen))
   8104           {
   8105 #ifdef HAVE_MESSAGES
   8106             MHD_DLOG (daemon,
   8107                       _ ("The size specified for MHD_OPTION_SOCK_ADDR_LEN " \
   8108                          "option is wrong.\n"));
   8109 #endif /* HAVE_MESSAGES */
   8110             goto free_and_fail;
   8111           }
   8112 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
   8113           if (0 != sa_len)
   8114           {
   8115             if (((socklen_t) sizeof(sa4)) > sa_len)
   8116             {
   8117 #ifdef HAVE_MESSAGES
   8118               MHD_DLOG (daemon,
   8119                         _ ("The value of 'struct sockaddr.sa_len' provided " \
   8120                            "via MHD_OPTION_SOCK_ADDR_LEN option is not zero " \
   8121                            "and does not match 'sa_family' value of the " \
   8122                            "same structure.\n"));
   8123 #endif /* HAVE_MESSAGES */
   8124               goto free_and_fail;
   8125             }
   8126             if ((0 == addrlen) || (sa_len < addrlen))
   8127               addrlen = sa_len; /* Use smaller value for safety */
   8128           }
   8129 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
   8130           if (0 == addrlen)
   8131             addrlen = sizeof(sa4);
   8132           memcpy (&sa4, pservaddr, sizeof(sa4));  /* Required due to stronger alignment */
   8133           sa4_port = (uint16_t) ntohs (sa4.sin_port);
   8134 #ifndef MHD_USE_GETSOCKNAME
   8135           if (0 != sa4_port)
   8136 #endif /* ! MHD_USE_GETSOCKNAME */
   8137           daemon->port = sa4_port;
   8138           domain = PF_INET;
   8139         }
   8140         break;
   8141 #ifdef HAVE_INET6
   8142       case AF_INET6:
   8143         if (1)
   8144         {
   8145           struct sockaddr_in6 sa6;
   8146           uint16_t sa6_port;
   8147           if ((0 != addrlen)
   8148               && (((socklen_t) sizeof(sa6)) > addrlen))
   8149           {
   8150 #ifdef HAVE_MESSAGES
   8151             MHD_DLOG (daemon,
   8152                       _ ("The size specified for MHD_OPTION_SOCK_ADDR_LEN " \
   8153                          "option is wrong.\n"));
   8154 #endif /* HAVE_MESSAGES */
   8155             goto free_and_fail;
   8156           }
   8157 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
   8158           if (0 != sa_len)
   8159           {
   8160             if (((socklen_t) sizeof(sa6)) > sa_len)
   8161             {
   8162 #ifdef HAVE_MESSAGES
   8163               MHD_DLOG (daemon,
   8164                         _ ("The value of 'struct sockaddr.sa_len' provided " \
   8165                            "via MHD_OPTION_SOCK_ADDR_LEN option is not zero " \
   8166                            "and does not match 'sa_family' value of the " \
   8167                            "same structure.\n"));
   8168 #endif /* HAVE_MESSAGES */
   8169               goto free_and_fail;
   8170             }
   8171             if ((0 == addrlen) || (sa_len < addrlen))
   8172               addrlen = sa_len; /* Use smaller value for safety */
   8173           }
   8174 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
   8175           if (0 == addrlen)
   8176             addrlen = sizeof(sa6);
   8177           memcpy (&sa6, pservaddr, sizeof(sa6));  /* Required due to stronger alignment */
   8178           sa6_port = (uint16_t) ntohs (sa6.sin6_port);
   8179 #ifndef MHD_USE_GETSOCKNAME
   8180           if (0 != sa6_port)
   8181 #endif /* ! MHD_USE_GETSOCKNAME */
   8182           daemon->port = sa6_port;
   8183           domain = PF_INET6;
   8184           *pflags |= ((enum MHD_FLAG) MHD_USE_IPv6);
   8185         }
   8186         break;
   8187 #endif /* HAVE_INET6 */
   8188 #ifdef AF_UNIX
   8189       case AF_UNIX:
   8190 #endif /* AF_UNIX */
   8191       default:
   8192 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
   8193         if (0 == addrlen)
   8194           addrlen = sa_len;
   8195         else if ((0 != sa_len) && (sa_len < addrlen))
   8196           addrlen = sa_len; /* Use smaller value for safety */
   8197 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
   8198         if (0 >= addrlen)
   8199         {
   8200 #ifdef HAVE_MESSAGES
   8201           MHD_DLOG (daemon,
   8202                     _ ("The 'sa_family' of the 'struct sockaddr' provided " \
   8203                        "via MHD_OPTION_SOCK_ADDR option is not supported.\n"));
   8204 #endif /* HAVE_MESSAGES */
   8205           goto free_and_fail;
   8206         }
   8207 #ifdef AF_UNIX
   8208         if (AF_UNIX == pservaddr->sa_family)
   8209         {
   8210           daemon->port = 0;     /* special value for UNIX domain sockets */
   8211           daemon->listen_is_unix = _MHD_YES;
   8212 #ifdef PF_UNIX
   8213           domain = PF_UNIX;
   8214 #else /* ! PF_UNIX */
   8215           domain = AF_UNIX;
   8216 #endif /* ! PF_UNIX */
   8217         }
   8218         else /* combined with the next 'if' */
   8219 #endif /* AF_UNIX */
   8220         if (1)
   8221         {
   8222           daemon->port = 0;     /* ugh */
   8223           daemon->listen_is_unix = _MHD_UNKNOWN;
   8224           /* Assumed the same values for AF_* and PF_* */
   8225           domain = pservaddr->sa_family;
   8226         }
   8227         break;
   8228       }
   8229     }
   8230     else
   8231     {
   8232       if (! use_ipv6)
   8233       {
   8234         memset (&servaddr4,
   8235                 0,
   8236                 sizeof (struct sockaddr_in));
   8237         servaddr4.sin_family = AF_INET;
   8238         servaddr4.sin_port = htons (port);
   8239         if (0 != INADDR_ANY)
   8240           servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
   8241 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
   8242         servaddr4.sin_len = sizeof (struct sockaddr_in);
   8243 #endif
   8244         pservaddr = (struct sockaddr *) &servaddr4;
   8245         addrlen = (socklen_t) sizeof(servaddr4);
   8246         daemon->listen_is_unix = _MHD_NO;
   8247         domain = PF_INET;
   8248       }
   8249 #ifdef HAVE_INET6
   8250       else
   8251       {
   8252 #ifdef IN6ADDR_ANY_INIT
   8253         static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
   8254 #endif
   8255         memset (&servaddr6,
   8256                 0,
   8257                 sizeof (struct sockaddr_in6));
   8258         servaddr6.sin6_family = AF_INET6;
   8259         servaddr6.sin6_port = htons (port);
   8260 #ifdef IN6ADDR_ANY_INIT
   8261         servaddr6.sin6_addr = static_in6any;
   8262 #endif
   8263 #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
   8264         servaddr6.sin6_len = sizeof (struct sockaddr_in6);
   8265 #endif
   8266         pservaddr = (struct sockaddr *) &servaddr6;
   8267         addrlen = (socklen_t) sizeof (servaddr6);
   8268         daemon->listen_is_unix = _MHD_NO;
   8269         domain = PF_INET6;
   8270       }
   8271 #endif /* HAVE_INET6 */
   8272     }
   8273 
   8274     daemon->listen_fd = MHD_socket_create_listen_ (domain);
   8275     if (MHD_INVALID_SOCKET == daemon->listen_fd)
   8276     {
   8277 #ifdef HAVE_MESSAGES
   8278       MHD_DLOG (daemon,
   8279                 _ ("Failed to create socket for listening: %s\n"),
   8280                 MHD_socket_last_strerr_ ());
   8281 #endif
   8282       goto free_and_fail;
   8283     }
   8284     if (MHD_D_IS_USING_SELECT_ (daemon) &&
   8285         (! MHD_D_DOES_SCKT_FIT_FDSET_ (daemon->listen_fd,
   8286                                        daemon)) )
   8287     {
   8288 #ifdef HAVE_MESSAGES
   8289       MHD_DLOG (daemon,
   8290                 _ ("Listen socket descriptor (%d) is not " \
   8291                    "less than daemon FD_SETSIZE value (%d).\n"),
   8292                 (int) daemon->listen_fd,
   8293                 (int) MHD_D_GET_FD_SETSIZE_ (daemon));
   8294 #endif
   8295       goto free_and_fail;
   8296     }
   8297 
   8298     /* Apply the socket options according to listening_address_reuse. */
   8299     if (0 == daemon->listening_address_reuse)
   8300     {
   8301 #ifndef MHD_WINSOCK_SOCKETS
   8302       /* No user requirement, use "traditional" default SO_REUSEADDR
   8303        * on non-W32 platforms, and do not fail if it doesn't work.
   8304        * Don't use it on W32, because on W32 it will allow multiple
   8305        * bind to the same address:port, like SO_REUSEPORT on others. */
   8306       if (0 > setsockopt (daemon->listen_fd,
   8307                           SOL_SOCKET,
   8308                           SO_REUSEADDR,
   8309                           (const void *) &on, sizeof (on)))
   8310       {
   8311 #ifdef HAVE_MESSAGES
   8312         MHD_DLOG (daemon,
   8313                   _ ("setsockopt failed: %s\n"),
   8314                   MHD_socket_last_strerr_ ());
   8315 #endif
   8316       }
   8317 #endif /* ! MHD_WINSOCK_SOCKETS */
   8318     }
   8319     else if (daemon->listening_address_reuse > 0)
   8320     {
   8321       /* User requested to allow reusing listening address:port. */
   8322 #ifndef MHD_WINSOCK_SOCKETS
   8323       /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if
   8324        * it doesn't work. */
   8325       if (0 > setsockopt (daemon->listen_fd,
   8326                           SOL_SOCKET,
   8327                           SO_REUSEADDR,
   8328                           (const void *) &on, sizeof (on)))
   8329       {
   8330 #ifdef HAVE_MESSAGES
   8331         MHD_DLOG (daemon,
   8332                   _ ("setsockopt failed: %s\n"),
   8333                   MHD_socket_last_strerr_ ());
   8334 #endif
   8335       }
   8336 #endif /* ! MHD_WINSOCK_SOCKETS */
   8337       /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
   8338        * Fail if SO_REUSEPORT is not defined or setsockopt fails.
   8339        */
   8340       /* SO_REUSEADDR on W32 has the same semantics
   8341          as SO_REUSEPORT on BSD/Linux */
   8342 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
   8343       if (0 > setsockopt (daemon->listen_fd,
   8344                           SOL_SOCKET,
   8345 #ifndef MHD_WINSOCK_SOCKETS
   8346                           SO_REUSEPORT,
   8347 #else  /* MHD_WINSOCK_SOCKETS */
   8348                           SO_REUSEADDR,
   8349 #endif /* MHD_WINSOCK_SOCKETS */
   8350                           (const void *) &on,
   8351                           sizeof (on)))
   8352       {
   8353 #ifdef HAVE_MESSAGES
   8354         MHD_DLOG (daemon,
   8355                   _ ("setsockopt failed: %s\n"),
   8356                   MHD_socket_last_strerr_ ());
   8357 #endif
   8358         goto free_and_fail;
   8359       }
   8360 #else  /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
   8361       /* we're supposed to allow address:port re-use, but
   8362          on this platform we cannot; fail hard */
   8363 #ifdef HAVE_MESSAGES
   8364       MHD_DLOG (daemon,
   8365                 _ ("Cannot allow listening address reuse: " \
   8366                    "SO_REUSEPORT not defined.\n"));
   8367 #endif
   8368       goto free_and_fail;
   8369 #endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
   8370     }
   8371     else   /* if (daemon->listening_address_reuse < 0) */
   8372     {
   8373       /* User requested to disallow reusing listening address:port.
   8374        * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
   8375        * is used and Solaris with SO_EXCLBIND.
   8376        * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE
   8377        * or setsockopt fails.
   8378        */
   8379 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \
   8380       (defined(__sun) && defined(SO_EXCLBIND))
   8381       if (0 > setsockopt (daemon->listen_fd,
   8382                           SOL_SOCKET,
   8383 #ifdef SO_EXCLUSIVEADDRUSE
   8384                           SO_EXCLUSIVEADDRUSE,
   8385 #else  /* SO_EXCLBIND */
   8386                           SO_EXCLBIND,
   8387 #endif /* SO_EXCLBIND */
   8388                           (const void *) &on,
   8389                           sizeof (on)))
   8390       {
   8391 #ifdef HAVE_MESSAGES
   8392         MHD_DLOG (daemon,
   8393                   _ ("setsockopt failed: %s\n"),
   8394                   MHD_socket_last_strerr_ ());
   8395 #endif
   8396         goto free_and_fail;
   8397       }
   8398 #elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */
   8399 #ifdef HAVE_MESSAGES
   8400       MHD_DLOG (daemon,
   8401                 _ ("Cannot disallow listening address reuse: " \
   8402                    "SO_EXCLUSIVEADDRUSE not defined.\n"));
   8403 #endif
   8404       goto free_and_fail;
   8405 #endif /* MHD_WINSOCK_SOCKETS */
   8406     }
   8407 
   8408     /* check for user supplied sockaddr */
   8409     if (0 != (*pflags & MHD_USE_IPv6))
   8410     {
   8411 #ifdef IPPROTO_IPV6
   8412 #ifdef IPV6_V6ONLY
   8413       /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
   8414          (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
   8415          and may also be missing on older POSIX systems; good luck if you have any of those,
   8416          your IPv6 socket may then also bind against IPv4 anyway... */
   8417       const MHD_SCKT_OPT_BOOL_ v6_only =
   8418         (MHD_USE_DUAL_STACK != (*pflags & MHD_USE_DUAL_STACK));
   8419       if (0 > setsockopt (daemon->listen_fd,
   8420                           IPPROTO_IPV6, IPV6_V6ONLY,
   8421                           (const void *) &v6_only,
   8422                           sizeof (v6_only)))
   8423       {
   8424 #ifdef HAVE_MESSAGES
   8425         MHD_DLOG (daemon,
   8426                   _ ("setsockopt failed: %s\n"),
   8427                   MHD_socket_last_strerr_ ());
   8428 #endif
   8429       }
   8430 #endif
   8431 #endif
   8432     }
   8433     if (0 != bind (daemon->listen_fd,
   8434                    pservaddr,
   8435                    addrlen))
   8436     {
   8437 #ifdef HAVE_MESSAGES
   8438       MHD_DLOG (daemon,
   8439                 _ ("Failed to bind to port %u: %s\n"),
   8440                 (unsigned int) port,
   8441                 MHD_socket_last_strerr_ ());
   8442 #endif
   8443       goto free_and_fail;
   8444     }
   8445 #ifdef TCP_FASTOPEN
   8446     if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
   8447     {
   8448       if (0 == daemon->fastopen_queue_size)
   8449         daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
   8450       if (0 != setsockopt (daemon->listen_fd,
   8451                            IPPROTO_TCP,
   8452                            TCP_FASTOPEN,
   8453                            (const void *) &daemon->fastopen_queue_size,
   8454                            sizeof (daemon->fastopen_queue_size)))
   8455       {
   8456 #ifdef HAVE_MESSAGES
   8457         MHD_DLOG (daemon,
   8458                   _ ("setsockopt failed: %s\n"),
   8459                   MHD_socket_last_strerr_ ());
   8460 #endif
   8461       }
   8462     }
   8463 #endif
   8464     if (0 != listen (daemon->listen_fd,
   8465                      (int) daemon->listen_backlog_size))
   8466     {
   8467 #ifdef HAVE_MESSAGES
   8468       MHD_DLOG (daemon,
   8469                 _ ("Failed to listen for connections: %s\n"),
   8470                 MHD_socket_last_strerr_ ());
   8471 #endif
   8472       goto free_and_fail;
   8473     }
   8474   }
   8475   else
   8476   {
   8477     if (MHD_D_IS_USING_SELECT_ (daemon) &&
   8478         (! MHD_D_DOES_SCKT_FIT_FDSET_ (daemon->listen_fd,
   8479                                        daemon)) )
   8480     {
   8481 #ifdef HAVE_MESSAGES
   8482       MHD_DLOG (daemon,
   8483                 _ ("Listen socket descriptor (%d) is not " \
   8484                    "less than daemon FD_SETSIZE value (%d).\n"),
   8485                 (int) daemon->listen_fd,
   8486                 (int) MHD_D_GET_FD_SETSIZE_ (daemon));
   8487 #endif
   8488       goto free_and_fail;
   8489     }
   8490     else
   8491     {
   8492 #if defined(SOL_SOCKET) && (defined(SO_DOMAIN) || defined(SO_PROTOCOL_INFOW))
   8493       int af;
   8494       int opt_name;
   8495       void *poptval;
   8496       socklen_t optval_size;
   8497 #ifdef SO_DOMAIN
   8498       opt_name = SO_DOMAIN;
   8499       poptval = &af;
   8500       optval_size = (socklen_t) sizeof (af);
   8501 #else  /* SO_PROTOCOL_INFOW */
   8502       WSAPROTOCOL_INFOW prot_info;
   8503       opt_name = SO_PROTOCOL_INFOW;
   8504       poptval = &prot_info;
   8505       optval_size = (socklen_t) sizeof (prot_info);
   8506 #endif /* SO_PROTOCOL_INFOW */
   8507 
   8508       if (0 == getsockopt (daemon->listen_fd,
   8509                            SOL_SOCKET,
   8510                            opt_name,
   8511                            poptval,
   8512                            &optval_size))
   8513       {
   8514 #ifndef SO_DOMAIN
   8515         af = prot_info.iAddressFamily;
   8516 #endif /* SO_DOMAIN */
   8517         switch (af)
   8518         {
   8519         case AF_INET:
   8520           daemon->listen_is_unix = _MHD_NO;
   8521           break;
   8522 #ifdef HAVE_INET6
   8523         case AF_INET6:
   8524           *pflags |= MHD_USE_IPv6;
   8525           daemon->listen_is_unix = _MHD_NO;
   8526           break;
   8527 #endif /* HAVE_INET6 */
   8528 #ifdef AF_UNIX
   8529         case AF_UNIX:
   8530           daemon->port = 0;     /* special value for UNIX domain sockets */
   8531           daemon->listen_is_unix = _MHD_YES;
   8532           break;
   8533 #endif /* AF_UNIX */
   8534         default:
   8535           daemon->port = 0;     /* ugh */
   8536           daemon->listen_is_unix = _MHD_UNKNOWN;
   8537           break;
   8538         }
   8539       }
   8540       else
   8541 #endif /* SOL_SOCKET && (SO_DOMAIN || SO_PROTOCOL_INFOW)) */
   8542       daemon->listen_is_unix = _MHD_UNKNOWN;
   8543     }
   8544 
   8545 #ifdef MHD_USE_GETSOCKNAME
   8546     daemon->port = 0;  /* Force use of autodetection */
   8547 #endif /* MHD_USE_GETSOCKNAME */
   8548   }
   8549 
   8550 #ifdef MHD_USE_GETSOCKNAME
   8551   if ( (0 == daemon->port) &&
   8552        (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) &&
   8553        (_MHD_YES != daemon->listen_is_unix) )
   8554   {   /* Get port number. */
   8555     struct sockaddr_storage bindaddr;
   8556 
   8557     memset (&bindaddr,
   8558             0,
   8559             sizeof (struct sockaddr_storage));
   8560     addrlen = sizeof (struct sockaddr_storage);
   8561 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
   8562     bindaddr.ss_len = (socklen_t) addrlen;
   8563 #endif
   8564     if (0 != getsockname (daemon->listen_fd,
   8565                           (struct sockaddr *) &bindaddr,
   8566                           &addrlen))
   8567     {
   8568 #ifdef HAVE_MESSAGES
   8569       MHD_DLOG (daemon,
   8570                 _ ("Failed to get listen port number: %s\n"),
   8571                 MHD_socket_last_strerr_ ());
   8572 #endif /* HAVE_MESSAGES */
   8573     }
   8574 #ifdef MHD_POSIX_SOCKETS
   8575     else if (sizeof (bindaddr) < addrlen)
   8576     {
   8577       /* should be impossible with `struct sockaddr_storage` */
   8578 #ifdef HAVE_MESSAGES
   8579       MHD_DLOG (daemon,
   8580                 _ ("Failed to get listen port number " \
   8581                    "(`struct sockaddr_storage` too small!?).\n"));
   8582 #endif /* HAVE_MESSAGES */
   8583     }
   8584 #ifndef __linux__
   8585     else if (0 == addrlen)
   8586     {
   8587       /* Many non-Linux-based platforms return zero addrlen
   8588        * for AF_UNIX sockets */
   8589       daemon->port = 0;     /* special value for UNIX domain sockets */
   8590       if (_MHD_UNKNOWN == daemon->listen_is_unix)
   8591         daemon->listen_is_unix = _MHD_YES;
   8592     }
   8593 #endif /* __linux__ */
   8594 #endif /* MHD_POSIX_SOCKETS */
   8595     else
   8596     {
   8597       switch (bindaddr.ss_family)
   8598       {
   8599       case AF_INET:
   8600         {
   8601           struct sockaddr_in *s4 = (struct sockaddr_in *) &bindaddr;
   8602 
   8603           daemon->port = ntohs (s4->sin_port);
   8604           daemon->listen_is_unix = _MHD_NO;
   8605           break;
   8606         }
   8607 #ifdef HAVE_INET6
   8608       case AF_INET6:
   8609         {
   8610           struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &bindaddr;
   8611 
   8612           daemon->port = ntohs (s6->sin6_port);
   8613           daemon->listen_is_unix = _MHD_NO;
   8614           mhd_assert (0 != (*pflags & MHD_USE_IPv6));
   8615           break;
   8616         }
   8617 #endif /* HAVE_INET6 */
   8618 #ifdef AF_UNIX
   8619       case AF_UNIX:
   8620         daemon->port = 0;     /* special value for UNIX domain sockets */
   8621         daemon->listen_is_unix = _MHD_YES;
   8622         break;
   8623 #endif
   8624       default:
   8625 #ifdef HAVE_MESSAGES
   8626         MHD_DLOG (daemon,
   8627                   _ ("Listen socket has unknown address family!\n"));
   8628 #endif
   8629         daemon->port = 0;     /* ugh */
   8630         daemon->listen_is_unix = _MHD_UNKNOWN;
   8631         break;
   8632       }
   8633     }
   8634   }
   8635 #endif /* MHD_USE_GETSOCKNAME */
   8636 
   8637   if (MHD_INVALID_SOCKET != daemon->listen_fd)
   8638   {
   8639     mhd_assert (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET));
   8640     if (! MHD_socket_nonblocking_ (daemon->listen_fd))
   8641     {
   8642 #ifdef HAVE_MESSAGES
   8643       MHD_DLOG (daemon,
   8644                 _ ("Failed to set nonblocking mode on listening socket: %s\n"),
   8645                 MHD_socket_last_strerr_ ());
   8646 #endif
   8647       if (MHD_D_IS_USING_EPOLL_ (daemon)
   8648 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8649           || (daemon->worker_pool_size > 0)
   8650 #endif
   8651           )
   8652       {
   8653         /* Accept must be non-blocking. Multiple children may wake up
   8654          * to handle a new connection, but only one will win the race.
   8655          * The others must immediately return. */
   8656         goto free_and_fail;
   8657       }
   8658       daemon->listen_nonblk = false;
   8659     }
   8660     else
   8661       daemon->listen_nonblk = true;
   8662   }
   8663   else
   8664   {
   8665     mhd_assert (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET));
   8666     daemon->listen_nonblk = false; /* Actually listen socket does not exist */
   8667   }
   8668 
   8669 #ifdef EPOLL_SUPPORT
   8670   if (MHD_D_IS_USING_EPOLL_ (daemon)
   8671 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8672       && (0 == daemon->worker_pool_size)
   8673 #endif
   8674       )
   8675   {
   8676     if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon))
   8677     {
   8678 #ifdef HAVE_MESSAGES
   8679       MHD_DLOG (daemon,
   8680                 _ ("Combining MHD_USE_THREAD_PER_CONNECTION and " \
   8681                    "MHD_USE_EPOLL is not supported.\n"));
   8682 #endif
   8683       goto free_and_fail;
   8684     }
   8685     if (MHD_NO == setup_epoll_to_listen (daemon))
   8686       goto free_and_fail;
   8687   }
   8688 #endif /* EPOLL_SUPPORT */
   8689 
   8690 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8691   if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex))
   8692   {
   8693 #ifdef HAVE_MESSAGES
   8694     MHD_DLOG (daemon,
   8695               _ ("MHD failed to initialize IP connection limit mutex.\n"));
   8696 #endif
   8697     goto free_and_fail;
   8698   }
   8699 #endif
   8700 
   8701 #ifdef HTTPS_SUPPORT
   8702   /* initialize HTTPS daemon certificate aspects & send / recv functions */
   8703   if ( (0 != (*pflags & MHD_USE_TLS)) &&
   8704        (0 != MHD_TLS_init (daemon)) )
   8705   {
   8706 #ifdef HAVE_MESSAGES
   8707     MHD_DLOG (daemon,
   8708               _ ("Failed to initialize TLS support.\n"));
   8709 #endif
   8710 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8711     MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
   8712 #endif
   8713     goto free_and_fail;
   8714   }
   8715 #endif /* HTTPS_SUPPORT */
   8716 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8717   /* Start threads if requested by parameters */
   8718   if (MHD_D_IS_USING_THREADS_ (daemon))
   8719   {
   8720     /* Internal thread (or threads) is used.
   8721      * Make sure that MHD will be able to communicate with threads. */
   8722     /* If using a thread pool ITC will be initialised later
   8723      * for each individual worker thread. */
   8724 #ifdef HAVE_LISTEN_SHUTDOWN
   8725     mhd_assert ((1 < daemon->worker_pool_size) || \
   8726                 (MHD_ITC_IS_VALID_ (daemon->itc)) || \
   8727                 (MHD_INVALID_SOCKET != daemon->listen_fd));
   8728 #else  /* ! HAVE_LISTEN_SHUTDOWN */
   8729     mhd_assert ((1 < daemon->worker_pool_size) || \
   8730                 (MHD_ITC_IS_VALID_ (daemon->itc)));
   8731 #endif /* ! HAVE_LISTEN_SHUTDOWN */
   8732     if (0 == daemon->worker_pool_size)
   8733     {
   8734       if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex))
   8735       {
   8736 #ifdef HAVE_MESSAGES
   8737         MHD_DLOG (daemon,
   8738                   _ ("Failed to initialise internal lists mutex.\n"));
   8739 #endif
   8740         MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
   8741         goto free_and_fail;
   8742       }
   8743       if (! MHD_mutex_init_ (&daemon->new_connections_mutex))
   8744       {
   8745 #ifdef HAVE_MESSAGES
   8746         MHD_DLOG (daemon,
   8747                   _ ("Failed to initialise mutex.\n"));
   8748 #endif
   8749         MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
   8750         MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
   8751         goto free_and_fail;
   8752       }
   8753       if (! MHD_create_named_thread_ (&daemon->tid,
   8754                                       MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) ?
   8755                                       "MHD-listen" : "MHD-single",
   8756                                       daemon->thread_stack_size,
   8757                                       &MHD_polling_thread,
   8758                                       daemon) )
   8759       {
   8760 #ifdef HAVE_MESSAGES
   8761 #ifdef EAGAIN
   8762         if (EAGAIN == errno)
   8763           MHD_DLOG (daemon,
   8764                     _ ("Failed to create a new thread because it would have " \
   8765                        "exceeded the system limit on the number of threads or " \
   8766                        "no system resources available.\n"));
   8767         else
   8768 #endif /* EAGAIN */
   8769         MHD_DLOG (daemon,
   8770                   _ ("Failed to create listen thread: %s\n"),
   8771                   MHD_strerror_ (errno));
   8772 #endif /* HAVE_MESSAGES */
   8773         MHD_mutex_destroy_chk_ (&daemon->new_connections_mutex);
   8774         MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
   8775         MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
   8776         goto free_and_fail;
   8777       }
   8778     }
   8779     else   /* 0 < daemon->worker_pool_size */
   8780     {
   8781       /* Coarse-grained count of connections per thread (note error
   8782        * due to integer division). Also keep track of how many
   8783        * connections are leftover after an equal split. */
   8784       unsigned int conns_per_thread = daemon->connection_limit
   8785                                       / daemon->worker_pool_size;
   8786       unsigned int leftover_conns = daemon->connection_limit
   8787                                     % daemon->worker_pool_size;
   8788 
   8789       mhd_assert (2 <= daemon->worker_pool_size);
   8790       i = 0;     /* we need this in case fcntl or malloc fails */
   8791 
   8792       /* Allocate memory for pooled objects */
   8793       daemon->worker_pool = malloc (sizeof (struct MHD_Daemon)
   8794                                     * daemon->worker_pool_size);
   8795       if (NULL == daemon->worker_pool)
   8796         goto thread_failed;
   8797 
   8798       /* Start the workers in the pool */
   8799       for (i = 0; i < daemon->worker_pool_size; ++i)
   8800       {
   8801         /* Create copy of the Daemon object for each worker */
   8802         struct MHD_Daemon *d = &daemon->worker_pool[i];
   8803 
   8804         memcpy (d, daemon, sizeof (struct MHD_Daemon));
   8805         /* Adjust polling params for worker daemons; note that memcpy()
   8806            has already copied MHD_USE_INTERNAL_POLLING_THREAD thread mode into
   8807            the worker threads. */
   8808         d->master = daemon;
   8809         d->worker_pool_size = 0;
   8810         d->worker_pool = NULL;
   8811         if (! MHD_mutex_init_ (&d->cleanup_connection_mutex))
   8812         {
   8813 #ifdef HAVE_MESSAGES
   8814           MHD_DLOG (daemon,
   8815                     _ ("Failed to initialise internal lists mutex.\n"));
   8816 #endif
   8817           goto thread_failed;
   8818         }
   8819         if (! MHD_mutex_init_ (&d->new_connections_mutex))
   8820         {
   8821 #ifdef HAVE_MESSAGES
   8822           MHD_DLOG (daemon,
   8823                     _ ("Failed to initialise mutex.\n"));
   8824 #endif
   8825           MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex);
   8826           goto thread_failed;
   8827         }
   8828         if (0 != (*pflags & MHD_USE_ITC))
   8829         {
   8830           if (! MHD_itc_init_ (d->itc))
   8831           {
   8832 #ifdef HAVE_MESSAGES
   8833             MHD_DLOG (daemon,
   8834                       _ ("Failed to create worker inter-thread " \
   8835                          "communication channel: %s\n"),
   8836                       MHD_itc_last_strerror_ () );
   8837 #endif
   8838             MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
   8839             MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex);
   8840             goto thread_failed;
   8841           }
   8842           if (MHD_D_IS_USING_SELECT_ (d) &&
   8843               (! MHD_D_DOES_SCKT_FIT_FDSET_ (MHD_itc_r_fd_ (d->itc), daemon)) )
   8844           {
   8845 #ifdef HAVE_MESSAGES
   8846             MHD_DLOG (daemon,
   8847                       _ ("File descriptor for worker inter-thread " \
   8848                          "communication channel exceeds maximum value.\n"));
   8849 #endif
   8850             MHD_itc_destroy_chk_ (d->itc);
   8851             MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
   8852             MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex);
   8853             goto thread_failed;
   8854           }
   8855         }
   8856         else
   8857           MHD_itc_set_invalid_ (d->itc);
   8858 
   8859 #ifdef HAVE_LISTEN_SHUTDOWN
   8860         mhd_assert ((MHD_ITC_IS_VALID_ (d->itc)) || \
   8861                     (MHD_INVALID_SOCKET != d->listen_fd));
   8862 #else  /* ! HAVE_LISTEN_SHUTDOWN */
   8863         mhd_assert (MHD_ITC_IS_VALID_ (d->itc));
   8864 #endif /* ! HAVE_LISTEN_SHUTDOWN */
   8865 
   8866         /* Divide available connections evenly amongst the threads.
   8867          * Thread indexes in [0, leftover_conns) each get one of the
   8868          * leftover connections. */
   8869         d->connection_limit = conns_per_thread;
   8870         if (i < leftover_conns)
   8871           ++d->connection_limit;
   8872 #ifdef EPOLL_SUPPORT
   8873         if (MHD_D_IS_USING_EPOLL_ (d) &&
   8874             (MHD_NO == setup_epoll_to_listen (d)) )
   8875         {
   8876           if (MHD_ITC_IS_VALID_ (d->itc))
   8877             MHD_itc_destroy_chk_ (d->itc);
   8878           MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
   8879           MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex);
   8880           goto thread_failed;
   8881         }
   8882 #endif
   8883         /* Some members must be used only in master daemon */
   8884 #if defined(MHD_USE_THREADS)
   8885         memset (&d->per_ip_connection_mutex, 0x7F,
   8886                 sizeof(d->per_ip_connection_mutex));
   8887 #endif /* MHD_USE_THREADS */
   8888 #ifdef DAUTH_SUPPORT
   8889         d->nnc = NULL;
   8890         d->nonce_nc_size = 0;
   8891         d->digest_auth_random_copy = NULL;
   8892 #if defined(MHD_USE_THREADS)
   8893         memset (&d->nnc_lock, 0x7F, sizeof(d->nnc_lock));
   8894 #endif /* MHD_USE_THREADS */
   8895 #endif /* DAUTH_SUPPORT */
   8896 
   8897         /* Spawn the worker thread */
   8898         if (! MHD_create_named_thread_ (&d->tid,
   8899                                         "MHD-worker",
   8900                                         daemon->thread_stack_size,
   8901                                         &MHD_polling_thread,
   8902                                         d))
   8903         {
   8904 #ifdef HAVE_MESSAGES
   8905 #ifdef EAGAIN
   8906           if (EAGAIN == errno)
   8907             MHD_DLOG (daemon,
   8908                       _ ("Failed to create a new pool thread because it would " \
   8909                          "have exceeded the system limit on the number of " \
   8910                          "threads or no system resources available.\n"));
   8911           else
   8912 #endif /* EAGAIN */
   8913           MHD_DLOG (daemon,
   8914                     _ ("Failed to create pool thread: %s\n"),
   8915                     MHD_strerror_ (errno));
   8916 #endif
   8917           /* Free memory for this worker; cleanup below handles
   8918            * all previously-created workers. */
   8919           if (MHD_ITC_IS_VALID_ (d->itc))
   8920             MHD_itc_destroy_chk_ (d->itc);
   8921           MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
   8922           MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex);
   8923           goto thread_failed;
   8924         }
   8925       }
   8926     }
   8927   }
   8928   else
   8929   { /* Daemon without internal threads */
   8930     if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex))
   8931     {
   8932 #ifdef HAVE_MESSAGES
   8933       MHD_DLOG (daemon,
   8934                 _ ("Failed to initialise internal lists mutex.\n"));
   8935 #endif
   8936       MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
   8937       goto free_and_fail;
   8938     }
   8939     if (! MHD_mutex_init_ (&daemon->new_connections_mutex))
   8940     {
   8941 #ifdef HAVE_MESSAGES
   8942       MHD_DLOG (daemon,
   8943                 _ ("Failed to initialise mutex.\n"));
   8944 #endif
   8945       MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
   8946       MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
   8947       goto free_and_fail;
   8948     }
   8949   }
   8950 #endif
   8951 #ifdef HTTPS_SUPPORT
   8952   /* API promises to never use the password after initialization,
   8953      so we additionally NULL it here to not deref a dangling pointer. */
   8954   daemon->https_key_password = NULL;
   8955 #endif /* HTTPS_SUPPORT */
   8956 
   8957   return daemon;
   8958 
   8959 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   8960 thread_failed:
   8961   /* If no worker threads created, then shut down normally. Calling
   8962      MHD_stop_daemon (as we do below) doesn't work here since it
   8963      assumes a 0-sized thread pool means we had been in the default
   8964      MHD_USE_INTERNAL_POLLING_THREAD mode. */
   8965   if (0 == i)
   8966   {
   8967     MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
   8968     if (NULL != daemon->worker_pool)
   8969       free (daemon->worker_pool);
   8970     goto free_and_fail;
   8971   }
   8972 
   8973   /* Shutdown worker threads we've already created. Pretend
   8974      as though we had fully initialized our daemon, but
   8975      with a smaller number of threads than had been
   8976      requested. */
   8977   daemon->worker_pool_size = i;
   8978   MHD_stop_daemon (daemon);
   8979   return NULL;
   8980 #endif
   8981 
   8982 free_and_fail:
   8983   /* clean up basic memory state in 'daemon' and return NULL to
   8984      indicate failure */
   8985 #ifdef EPOLL_SUPPORT
   8986 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   8987   if (daemon->upgrade_fd_in_epoll)
   8988   {
   8989     if (0 != epoll_ctl (daemon->epoll_fd,
   8990                         EPOLL_CTL_DEL,
   8991                         daemon->epoll_upgrade_fd,
   8992                         NULL))
   8993       MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
   8994     daemon->upgrade_fd_in_epoll = false;
   8995   }
   8996 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   8997   if (-1 != daemon->epoll_fd)
   8998     close (daemon->epoll_fd);
   8999 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   9000   if (-1 != daemon->epoll_upgrade_fd)
   9001     close (daemon->epoll_upgrade_fd);
   9002 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   9003 #endif /* EPOLL_SUPPORT */
   9004 #ifdef DAUTH_SUPPORT
   9005   free (daemon->digest_auth_random_copy);
   9006   free (daemon->nnc);
   9007 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9008   MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
   9009 #endif
   9010 #endif
   9011 #ifdef HTTPS_SUPPORT
   9012   if (0 != (*pflags & MHD_USE_TLS))
   9013   {
   9014     gnutls_priority_deinit (daemon->priority_cache);
   9015     if (daemon->x509_cred)
   9016       gnutls_certificate_free_credentials (daemon->x509_cred);
   9017     if (daemon->psk_cred)
   9018       gnutls_psk_free_server_credentials (daemon->psk_cred);
   9019   }
   9020 #endif /* HTTPS_SUPPORT */
   9021   if (MHD_ITC_IS_VALID_ (daemon->itc))
   9022     MHD_itc_destroy_chk_ (daemon->itc);
   9023   if (MHD_INVALID_SOCKET != daemon->listen_fd)
   9024     (void) MHD_socket_close_ (daemon->listen_fd);
   9025   free (daemon);
   9026   return NULL;
   9027 }
   9028 
   9029 
   9030 /**
   9031  * Close all connections for the daemon.
   9032  * Must only be called when MHD_Daemon::shutdown was set to true.
   9033  * @remark To be called only from thread that process
   9034  * daemon's select()/poll()/etc.
   9035  *
   9036  * @param daemon daemon to close down
   9037  */
   9038 static void
   9039 close_all_connections (struct MHD_Daemon *daemon)
   9040 {
   9041   struct MHD_Connection *pos;
   9042   const bool used_thr_p_c = MHD_D_IS_USING_THREAD_PER_CONN_ (daemon);
   9043 #ifdef UPGRADE_SUPPORT
   9044   const bool upg_allowed = (0 != (daemon->options & MHD_ALLOW_UPGRADE));
   9045 #endif /* UPGRADE_SUPPORT */
   9046 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   9047   struct MHD_UpgradeResponseHandle *urh;
   9048   struct MHD_UpgradeResponseHandle *urhn;
   9049   const bool used_tls = (0 != (daemon->options & MHD_USE_TLS));
   9050 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   9051 
   9052 #ifdef MHD_USE_THREADS
   9053   mhd_assert ( (! MHD_D_IS_USING_THREADS_ (daemon)) || \
   9054                MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) || \
   9055                MHD_thread_handle_ID_is_current_thread_ (daemon->tid) );
   9056   mhd_assert (NULL == daemon->worker_pool);
   9057 #endif /* MHD_USE_THREADS */
   9058   mhd_assert (daemon->shutdown);
   9059 
   9060 #ifdef MHD_USE_THREADS
   9061 /* Remove externally added new connections that are
   9062    * not processed by the daemon thread. */
   9063   MHD_mutex_lock_chk_ (&daemon->new_connections_mutex);
   9064   while (NULL != (pos = daemon->new_connections_tail))
   9065   {
   9066     mhd_assert (MHD_D_IS_USING_THREADS_ (daemon));
   9067     DLL_remove (daemon->new_connections_head,
   9068                 daemon->new_connections_tail,
   9069                 pos);
   9070     new_connection_close_ (daemon, pos);
   9071   }
   9072   MHD_mutex_unlock_chk_ (&daemon->new_connections_mutex);
   9073 #endif /* MHD_USE_THREADS */
   9074 
   9075 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   9076   /* give upgraded HTTPS connections a chance to finish */
   9077   /* 'daemon->urh_head' is not used in thread-per-connection mode. */
   9078   for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
   9079   {
   9080     mhd_assert (! used_thr_p_c);
   9081     urhn = urh->prev;
   9082     /* call generic forwarding function for passing data
   9083        with chance to detect that application is done. */
   9084     process_urh (urh);
   9085     MHD_connection_finish_forward_ (urh->connection);
   9086     urh->clean_ready = true;
   9087     /* Resuming will move connection to cleanup list. */
   9088     MHD_resume_connection (urh->connection);
   9089   }
   9090 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   9091 
   9092   /* Give suspended connections a chance to resume to avoid
   9093      running into the check for there not being any suspended
   9094      connections left in case of a tight race with a recently
   9095      resumed connection. */
   9096   if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
   9097   {
   9098     daemon->resuming = true;   /* Force check for pending resume. */
   9099     resume_suspended_connections (daemon);
   9100   }
   9101   /* first, make sure all threads are aware of shutdown; need to
   9102      traverse DLLs in peace... */
   9103 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9104   MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   9105 #endif
   9106 #ifdef UPGRADE_SUPPORT
   9107   if (upg_allowed)
   9108   {
   9109     struct MHD_Connection *susp;
   9110 
   9111     susp = daemon->suspended_connections_tail;
   9112     while (NULL != susp)
   9113     {
   9114       if (NULL == susp->urh)     /* "Upgraded" connection? */
   9115         MHD_PANIC (_ ("MHD_stop_daemon() called while we have " \
   9116                       "suspended connections.\n"));
   9117 #ifdef HTTPS_SUPPORT
   9118       else if (used_tls &&
   9119                used_thr_p_c &&
   9120                (! susp->urh->clean_ready) )
   9121         shutdown (susp->urh->app.socket,
   9122                   SHUT_RDWR);     /* Wake thread by shutdown of app socket. */
   9123 #endif /* HTTPS_SUPPORT */
   9124       else
   9125       {
   9126 #ifdef HAVE_MESSAGES
   9127         if (! susp->urh->was_closed)
   9128           MHD_DLOG (daemon,
   9129                     _ ("Initiated daemon shutdown while \"upgraded\" " \
   9130                        "connection was not closed.\n"));
   9131 #endif
   9132         susp->urh->was_closed = true;
   9133         /* If thread-per-connection is used, connection's thread
   9134          * may still processing "upgrade" (exiting). */
   9135         if (! used_thr_p_c)
   9136           MHD_connection_finish_forward_ (susp);
   9137         /* Do not use MHD_resume_connection() as mutex is
   9138          * already locked. */
   9139         susp->resuming = true;
   9140         daemon->resuming = true;
   9141       }
   9142       susp = susp->prev;
   9143     }
   9144   }
   9145   else /* This 'else' is combined with next 'if' */
   9146 #endif /* UPGRADE_SUPPORT */
   9147   if (NULL != daemon->suspended_connections_head)
   9148     MHD_PANIC (_ ("MHD_stop_daemon() called while we have " \
   9149                   "suspended connections.\n"));
   9150 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
   9151 #ifdef MHD_USE_THREADS
   9152   if (upg_allowed && used_tls && used_thr_p_c)
   9153   {
   9154     /* "Upgraded" threads may be running in parallel. Connection will not be
   9155      * moved to the "cleanup list" until connection's thread finishes.
   9156      * We must ensure that all "upgraded" connections are finished otherwise
   9157      * connection may stay in "suspended" list and will not be cleaned. */
   9158     for (pos = daemon->suspended_connections_tail; NULL != pos; pos = pos->prev)
   9159     {
   9160       /* Any connection found here is "upgraded" connection, normal suspended
   9161        * connections are already removed from this list. */
   9162       mhd_assert (NULL != pos->urh);
   9163       if (! pos->thread_joined)
   9164       {
   9165         /* While "cleanup" list is not manipulated by "upgraded"
   9166          * connection, "cleanup" mutex is required for call of
   9167          * MHD_resume_connection() during finishing of "upgraded"
   9168          * thread. */
   9169         MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   9170         if (! MHD_thread_handle_ID_join_thread_ (pos->tid))
   9171           MHD_PANIC (_ ("Failed to join a thread.\n"));
   9172         pos->thread_joined = true;
   9173         MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   9174       }
   9175     }
   9176   }
   9177 #endif /* MHD_USE_THREADS */
   9178 #endif
   9179   for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
   9180   {
   9181     shutdown (pos->socket_fd,
   9182               SHUT_RDWR);
   9183 #ifdef MHD_WINSOCK_SOCKETS
   9184     if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) &&
   9185         (MHD_ITC_IS_VALID_ (daemon->itc)) &&
   9186         (! MHD_itc_activate_ (daemon->itc, "e")) )
   9187       MHD_PANIC (_ ("Failed to signal shutdown via inter-thread " \
   9188                     "communication channel.\n"));
   9189 #endif
   9190   }
   9191 
   9192 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9193   /* now, collect per-connection threads */
   9194   if (used_thr_p_c)
   9195   {
   9196     pos = daemon->connections_tail;
   9197     while (NULL != pos)
   9198     {
   9199       if (! pos->thread_joined)
   9200       {
   9201         MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   9202         if (! MHD_thread_handle_ID_join_thread_ (pos->tid))
   9203           MHD_PANIC (_ ("Failed to join a thread.\n"));
   9204         MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
   9205         pos->thread_joined = true;
   9206         /* The thread may have concurrently modified the DLL,
   9207            need to restart from the beginning */
   9208         pos = daemon->connections_tail;
   9209         continue;
   9210       }
   9211       pos = pos->prev;
   9212     }
   9213   }
   9214   MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
   9215 #endif
   9216 
   9217 #ifdef UPGRADE_SUPPORT
   9218   /* Finished threads with "upgraded" connections need to be moved
   9219    * to cleanup list by resume_suspended_connections(). */
   9220   /* "Upgraded" connections that were not closed explicitly by
   9221    * application should be moved to cleanup list too. */
   9222   if (upg_allowed)
   9223   {
   9224     daemon->resuming = true;   /* Force check for pending resume. */
   9225     resume_suspended_connections (daemon);
   9226   }
   9227 #endif /* UPGRADE_SUPPORT */
   9228 
   9229   mhd_assert (NULL == daemon->suspended_connections_head);
   9230   /* now that we're alone, move everyone to cleanup */
   9231   while (NULL != (pos = daemon->connections_tail))
   9232   {
   9233 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9234     if (MHD_D_IS_USING_THREAD_PER_CONN_ (daemon) &&
   9235         (! pos->thread_joined) )
   9236       MHD_PANIC (_ ("Failed to join a thread.\n"));
   9237 #endif
   9238     close_connection (pos);
   9239   }
   9240   MHD_cleanup_connections (daemon);
   9241 }
   9242 
   9243 
   9244 /**
   9245  * Shutdown an HTTP daemon.
   9246  *
   9247  * @param daemon daemon to stop
   9248  * @ingroup event
   9249  */
   9250 _MHD_EXTERN void
   9251 MHD_stop_daemon (struct MHD_Daemon *daemon)
   9252 {
   9253   MHD_socket fd;
   9254 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9255   unsigned int i;
   9256 #endif
   9257 
   9258   if (NULL == daemon)
   9259     return;
   9260   if ( (daemon->shutdown) && (NULL == daemon->master) )
   9261     MHD_PANIC (_ ("MHD_stop_daemon() was called twice."));
   9262 
   9263   mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   9264               (NULL != daemon->worker_pool) || \
   9265               (MHD_thread_handle_ID_is_valid_handle_ (daemon->tid)));
   9266   mhd_assert (((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) &&
   9267                (NULL == daemon->worker_pool)) || \
   9268               (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid)));
   9269 
   9270   /* Slave daemons must be stopped by master daemon. */
   9271   mhd_assert ( (NULL == daemon->master) || (daemon->shutdown) );
   9272 
   9273   daemon->shutdown = true;
   9274   if (daemon->was_quiesced)
   9275     fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */
   9276   else
   9277     fd = daemon->listen_fd;
   9278 
   9279 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9280   if (NULL != daemon->worker_pool)
   9281   {   /* Master daemon with worker pool. */
   9282     mhd_assert (1 < daemon->worker_pool_size);
   9283     mhd_assert (MHD_D_IS_USING_THREADS_ (daemon));
   9284 
   9285     /* Let workers shutdown in parallel. */
   9286     for (i = 0; i < daemon->worker_pool_size; ++i)
   9287     {
   9288       daemon->worker_pool[i].shutdown = true;
   9289       if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc))
   9290       {
   9291         if (! MHD_itc_activate_ (daemon->worker_pool[i].itc,
   9292                                  "e"))
   9293           MHD_PANIC (_ ("Failed to signal shutdown via inter-thread " \
   9294                         "communication channel.\n"));
   9295       }
   9296       else
   9297         mhd_assert (MHD_INVALID_SOCKET != fd);
   9298     }
   9299 #ifdef HAVE_LISTEN_SHUTDOWN
   9300     if (MHD_INVALID_SOCKET != fd)
   9301     {
   9302       (void) shutdown (fd,
   9303                        SHUT_RDWR);
   9304     }
   9305 #endif /* HAVE_LISTEN_SHUTDOWN */
   9306     for (i = 0; i < daemon->worker_pool_size; ++i)
   9307     {
   9308       MHD_stop_daemon (&daemon->worker_pool[i]);
   9309     }
   9310     free (daemon->worker_pool);
   9311     mhd_assert (MHD_ITC_IS_INVALID_ (daemon->itc));
   9312 #ifdef EPOLL_SUPPORT
   9313     mhd_assert (-1 == daemon->epoll_fd);
   9314 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   9315     mhd_assert (-1 == daemon->epoll_upgrade_fd);
   9316 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   9317 #endif /* EPOLL_SUPPORT */
   9318   }
   9319   else
   9320 #endif
   9321   {   /* Worker daemon or single daemon. */
   9322 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9323     if (MHD_D_IS_USING_THREADS_ (daemon))
   9324     {     /* Worker daemon or single daemon with internal thread(s). */
   9325       mhd_assert (0 == daemon->worker_pool_size);
   9326       /* Separate thread(s) is used for polling sockets. */
   9327       if (MHD_ITC_IS_VALID_ (daemon->itc))
   9328       {
   9329         if (! MHD_itc_activate_ (daemon->itc,
   9330                                  "e"))
   9331           MHD_PANIC (_ ("Failed to signal shutdown via inter-thread " \
   9332                         "communication channel.\n"));
   9333       }
   9334       else
   9335       {
   9336 #ifdef HAVE_LISTEN_SHUTDOWN
   9337         if (MHD_INVALID_SOCKET != fd)
   9338         {
   9339           if (NULL == daemon->master)
   9340             (void) shutdown (fd,
   9341                              SHUT_RDWR);
   9342         }
   9343         else
   9344 #endif /* HAVE_LISTEN_SHUTDOWN */
   9345         mhd_assert (false); /* Should never happen */
   9346       }
   9347 
   9348       if (! MHD_thread_handle_ID_join_thread_ (daemon->tid))
   9349       {
   9350         MHD_PANIC (_ ("Failed to join a thread.\n"));
   9351       }
   9352       /* close_all_connections() was called in daemon thread. */
   9353     }
   9354     else
   9355 #endif
   9356     {
   9357       /* No internal threads are used for polling sockets. */
   9358       close_all_connections (daemon);
   9359     }
   9360     mhd_assert (NULL == daemon->connections_head);
   9361     mhd_assert (NULL == daemon->cleanup_head);
   9362     mhd_assert (NULL == daemon->suspended_connections_head);
   9363     mhd_assert (NULL == daemon->new_connections_head);
   9364 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
   9365     mhd_assert (NULL == daemon->urh_head);
   9366 #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */
   9367 
   9368     if (MHD_ITC_IS_VALID_ (daemon->itc))
   9369       MHD_itc_destroy_chk_ (daemon->itc);
   9370 
   9371 #ifdef EPOLL_SUPPORT
   9372     if (MHD_D_IS_USING_EPOLL_ (daemon) &&
   9373         (-1 != daemon->epoll_fd) )
   9374       MHD_socket_close_chk_ (daemon->epoll_fd);
   9375 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   9376     if (MHD_D_IS_USING_EPOLL_ (daemon) &&
   9377         (-1 != daemon->epoll_upgrade_fd) )
   9378       MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
   9379 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   9380 #endif /* EPOLL_SUPPORT */
   9381 
   9382 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9383     MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
   9384     MHD_mutex_destroy_chk_ (&daemon->new_connections_mutex);
   9385 #endif
   9386   }
   9387 
   9388   if (NULL == daemon->master)
   9389   {   /* Cleanup that should be done only one time in master/single daemon.
   9390        * Do not perform this cleanup in worker daemons. */
   9391 
   9392     if (MHD_INVALID_SOCKET != fd)
   9393       MHD_socket_close_chk_ (fd);
   9394 
   9395     /* TLS clean up */
   9396 #ifdef HTTPS_SUPPORT
   9397     if (daemon->have_dhparams)
   9398     {
   9399       gnutls_dh_params_deinit (daemon->https_mem_dhparams);
   9400       daemon->have_dhparams = false;
   9401     }
   9402     if (0 != (daemon->options & MHD_USE_TLS))
   9403     {
   9404       gnutls_priority_deinit (daemon->priority_cache);
   9405       if (daemon->x509_cred)
   9406         gnutls_certificate_free_credentials (daemon->x509_cred);
   9407       if (daemon->psk_cred)
   9408         gnutls_psk_free_server_credentials (daemon->psk_cred);
   9409     }
   9410 #endif /* HTTPS_SUPPORT */
   9411 
   9412 #ifdef DAUTH_SUPPORT
   9413     free (daemon->digest_auth_random_copy);
   9414     free (daemon->nnc);
   9415 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9416     MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
   9417 #endif
   9418 #endif
   9419 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9420     MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
   9421 #endif
   9422     free (daemon);
   9423   }
   9424 }
   9425 
   9426 
   9427 /**
   9428  * Obtain information about the given daemon.
   9429  * The returned pointer is invalidated with the next call of this function or
   9430  * when the daemon is stopped.
   9431  *
   9432  * @param daemon what daemon to get information about
   9433  * @param info_type what information is desired?
   9434  * @param ... depends on @a info_type
   9435  * @return NULL if this information is not available
   9436  *         (or if the @a info_type is unknown)
   9437  * @ingroup specialized
   9438  */
   9439 _MHD_EXTERN const union MHD_DaemonInfo *
   9440 MHD_get_daemon_info (struct MHD_Daemon *daemon,
   9441                      enum MHD_DaemonInfoType info_type,
   9442                      ...)
   9443 {
   9444   if (NULL == daemon)
   9445     return NULL;
   9446 
   9447   mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \
   9448               (NULL != daemon->worker_pool) || \
   9449               (MHD_thread_handle_ID_is_valid_handle_ (daemon->tid)));
   9450   mhd_assert (((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) &&
   9451                (NULL == daemon->worker_pool)) || \
   9452               (! MHD_thread_handle_ID_is_valid_handle_ (daemon->tid)));
   9453 
   9454   switch (info_type)
   9455   {
   9456   case MHD_DAEMON_INFO_KEY_SIZE:
   9457     return NULL;   /* no longer supported */
   9458   case MHD_DAEMON_INFO_MAC_KEY_SIZE:
   9459     return NULL;   /* no longer supported */
   9460   case MHD_DAEMON_INFO_LISTEN_FD:
   9461     daemon->daemon_info_dummy_listen_fd.listen_fd = daemon->listen_fd;
   9462     return &daemon->daemon_info_dummy_listen_fd;
   9463   case MHD_DAEMON_INFO_EPOLL_FD:
   9464 #ifdef EPOLL_SUPPORT
   9465     daemon->daemon_info_dummy_epoll_fd.epoll_fd = daemon->epoll_fd;
   9466     return &daemon->daemon_info_dummy_epoll_fd;
   9467 #else  /* ! EPOLL_SUPPORT */
   9468     return NULL;
   9469 #endif /* ! EPOLL_SUPPORT */
   9470   case MHD_DAEMON_INFO_CURRENT_CONNECTIONS:
   9471     if (! MHD_D_IS_THREAD_SAFE_ (daemon))
   9472       MHD_cleanup_connections (daemon);
   9473 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9474     else if (daemon->worker_pool)
   9475     {
   9476       unsigned int i;
   9477       /* Collect the connection information stored in the workers. */
   9478       daemon->connections = 0;
   9479       for (i = 0; i < daemon->worker_pool_size; i++)
   9480       {
   9481         /* FIXME: next line is thread-safe only if read is atomic. */
   9482         daemon->connections += daemon->worker_pool[i].connections;
   9483       }
   9484     }
   9485 #endif
   9486     daemon->daemon_info_dummy_num_connections.num_connections
   9487       = daemon->connections;
   9488     return &daemon->daemon_info_dummy_num_connections;
   9489   case MHD_DAEMON_INFO_FLAGS:
   9490     daemon->daemon_info_dummy_flags.flags = daemon->options;
   9491     return &daemon->daemon_info_dummy_flags;
   9492   case MHD_DAEMON_INFO_BIND_PORT:
   9493     daemon->daemon_info_dummy_port.port = daemon->port;
   9494     return &daemon->daemon_info_dummy_port;
   9495   default:
   9496     return NULL;
   9497   }
   9498 }
   9499 
   9500 
   9501 /**
   9502  * Obtain the version of this library
   9503  *
   9504  * @return static version string, e.g. "0.9.9"
   9505  * @ingroup specialized
   9506  */
   9507 _MHD_EXTERN const char *
   9508 MHD_get_version (void)
   9509 {
   9510 #ifdef PACKAGE_VERSION
   9511   return PACKAGE_VERSION;
   9512 #else  /* !PACKAGE_VERSION */
   9513   static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0";
   9514   if (0 == ver[0])
   9515   {
   9516     int res = MHD_snprintf_ (ver,
   9517                              sizeof(ver),
   9518                              "%x.%x.%x",
   9519                              (int) (((uint32_t) MHD_VERSION >> 24) & 0xFF),
   9520                              (int) (((uint32_t) MHD_VERSION >> 16) & 0xFF),
   9521                              (int) (((uint32_t) MHD_VERSION >> 8) & 0xFF));
   9522     if ((0 >= res) || (sizeof(ver) <= res))
   9523       return "0.0.0"; /* Can't return real version */
   9524   }
   9525   return ver;
   9526 #endif /* !PACKAGE_VERSION */
   9527 }
   9528 
   9529 
   9530 /**
   9531  * Obtain the version of this library as a binary value.
   9532  *
   9533  * @return version binary value, e.g. "0x00090900" (#MHD_VERSION of
   9534  *         compiled MHD binary)
   9535  * @note Available since #MHD_VERSION 0x00097601
   9536  * @ingroup specialized
   9537  */
   9538 _MHD_EXTERN uint32_t
   9539 MHD_get_version_bin (void)
   9540 {
   9541   return (uint32_t) MHD_VERSION;
   9542 }
   9543 
   9544 
   9545 /**
   9546  * Get information about supported MHD features.
   9547  * Indicate that MHD was compiled with or without support for
   9548  * particular feature. Some features require additional support
   9549  * by kernel. Kernel support is not checked by this function.
   9550  *
   9551  * @param feature type of requested information
   9552  * @return #MHD_YES if feature is supported by MHD, #MHD_NO if
   9553  * feature is not supported or feature is unknown.
   9554  * @ingroup specialized
   9555  */
   9556 _MHD_EXTERN enum MHD_Result
   9557 MHD_is_feature_supported (enum MHD_FEATURE feature)
   9558 {
   9559   switch (feature)
   9560   {
   9561   case MHD_FEATURE_MESSAGES:
   9562 #ifdef HAVE_MESSAGES
   9563     return MHD_YES;
   9564 #else
   9565     return MHD_NO;
   9566 #endif
   9567   case MHD_FEATURE_TLS:
   9568 #ifdef HTTPS_SUPPORT
   9569     return MHD_YES;
   9570 #else  /* ! HTTPS_SUPPORT */
   9571     return MHD_NO;
   9572 #endif  /* ! HTTPS_SUPPORT */
   9573   case MHD_FEATURE_HTTPS_CERT_CALLBACK:
   9574 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3
   9575     return MHD_YES;
   9576 #else  /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
   9577     return MHD_NO;
   9578 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
   9579   case MHD_FEATURE_HTTPS_CERT_CALLBACK2:
   9580 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030603
   9581     return MHD_YES;
   9582 #else  /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */
   9583     return MHD_NO;
   9584 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */
   9585   case MHD_FEATURE_IPv6:
   9586 #ifdef HAVE_INET6
   9587     return MHD_YES;
   9588 #else
   9589     return MHD_NO;
   9590 #endif
   9591   case MHD_FEATURE_IPv6_ONLY:
   9592 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
   9593     return MHD_YES;
   9594 #else
   9595     return MHD_NO;
   9596 #endif
   9597   case MHD_FEATURE_POLL:
   9598 #ifdef HAVE_POLL
   9599     return MHD_YES;
   9600 #else
   9601     return MHD_NO;
   9602 #endif
   9603   case MHD_FEATURE_EPOLL:
   9604 #ifdef EPOLL_SUPPORT
   9605     return MHD_YES;
   9606 #else
   9607     return MHD_NO;
   9608 #endif
   9609   case MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET:
   9610 #ifdef HAVE_LISTEN_SHUTDOWN
   9611     return MHD_YES;
   9612 #else
   9613     return MHD_NO;
   9614 #endif
   9615   case MHD_FEATURE_SOCKETPAIR:
   9616 #ifdef _MHD_ITC_SOCKETPAIR
   9617     return MHD_YES;
   9618 #else
   9619     return MHD_NO;
   9620 #endif
   9621   case MHD_FEATURE_TCP_FASTOPEN:
   9622 #ifdef TCP_FASTOPEN
   9623     return MHD_YES;
   9624 #else
   9625     return MHD_NO;
   9626 #endif
   9627   case MHD_FEATURE_BASIC_AUTH:
   9628 #ifdef BAUTH_SUPPORT
   9629     return MHD_YES;
   9630 #else
   9631     return MHD_NO;
   9632 #endif
   9633   case MHD_FEATURE_DIGEST_AUTH:
   9634 #ifdef DAUTH_SUPPORT
   9635     return MHD_YES;
   9636 #else
   9637     return MHD_NO;
   9638 #endif
   9639   case MHD_FEATURE_POSTPROCESSOR:
   9640 #ifdef HAVE_POSTPROCESSOR
   9641     return MHD_YES;
   9642 #else
   9643     return MHD_NO;
   9644 #endif
   9645   case MHD_FEATURE_HTTPS_KEY_PASSWORD:
   9646 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111
   9647     return MHD_YES;
   9648 #else  /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
   9649     return MHD_NO;
   9650 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
   9651   case MHD_FEATURE_LARGE_FILE:
   9652 #if defined(HAVE_PREAD64) || defined(_WIN32)
   9653     return MHD_YES;
   9654 #elif defined(HAVE_PREAD)
   9655     return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
   9656 #elif defined(HAVE_LSEEK64)
   9657     return MHD_YES;
   9658 #else
   9659     return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
   9660 #endif
   9661   case MHD_FEATURE_THREAD_NAMES:
   9662 #if defined(MHD_USE_THREAD_NAME_)
   9663     return MHD_YES;
   9664 #else
   9665     return MHD_NO;
   9666 #endif
   9667   case MHD_FEATURE_UPGRADE:
   9668 #if defined(UPGRADE_SUPPORT)
   9669     return MHD_YES;
   9670 #else
   9671     return MHD_NO;
   9672 #endif
   9673   case MHD_FEATURE_RESPONSES_SHARED_FD:
   9674 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32)
   9675     return MHD_YES;
   9676 #else
   9677     return MHD_NO;
   9678 #endif
   9679   case MHD_FEATURE_AUTODETECT_BIND_PORT:
   9680 #ifdef MHD_USE_GETSOCKNAME
   9681     return MHD_YES;
   9682 #else
   9683     return MHD_NO;
   9684 #endif
   9685   case MHD_FEATURE_AUTOSUPPRESS_SIGPIPE:
   9686 #if defined(MHD_SEND_SPIPE_SUPPRESS_POSSIBLE) || \
   9687     ! defined(MHD_SEND_SPIPE_SUPPRESS_NEEDED)
   9688     return MHD_YES;
   9689 #else
   9690     return MHD_NO;
   9691 #endif
   9692   case MHD_FEATURE_SENDFILE:
   9693 #ifdef _MHD_HAVE_SENDFILE
   9694     return MHD_YES;
   9695 #else
   9696     return MHD_NO;
   9697 #endif
   9698   case MHD_FEATURE_THREADS:
   9699 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
   9700     return MHD_YES;
   9701 #else
   9702     return MHD_NO;
   9703 #endif
   9704   case MHD_FEATURE_COOKIE_PARSING:
   9705 #if defined(COOKIE_SUPPORT)
   9706     return MHD_YES;
   9707 #else
   9708     return MHD_NO;
   9709 #endif
   9710   case MHD_FEATURE_DIGEST_AUTH_RFC2069:
   9711 #ifdef DAUTH_SUPPORT
   9712     return MHD_YES;
   9713 #else
   9714     return MHD_NO;
   9715 #endif
   9716   case MHD_FEATURE_DIGEST_AUTH_MD5:
   9717 #if defined(DAUTH_SUPPORT) && defined(MHD_MD5_SUPPORT)
   9718     return MHD_YES;
   9719 #else
   9720     return MHD_NO;
   9721 #endif
   9722   case MHD_FEATURE_DIGEST_AUTH_SHA256:
   9723 #if defined(DAUTH_SUPPORT) && defined(MHD_SHA256_SUPPORT)
   9724     return MHD_YES;
   9725 #else
   9726     return MHD_NO;
   9727 #endif
   9728   case MHD_FEATURE_DIGEST_AUTH_SHA512_256:
   9729 #if defined(DAUTH_SUPPORT) && defined(MHD_SHA512_256_SUPPORT)
   9730     return MHD_YES;
   9731 #else
   9732     return MHD_NO;
   9733 #endif
   9734   case MHD_FEATURE_DIGEST_AUTH_AUTH_INT:
   9735 #ifdef DAUTH_SUPPORT
   9736     return MHD_NO;
   9737 #else
   9738     return MHD_NO;
   9739 #endif
   9740   case MHD_FEATURE_DIGEST_AUTH_ALGO_SESSION:
   9741 #ifdef DAUTH_SUPPORT
   9742     return MHD_NO;
   9743 #else
   9744     return MHD_NO;
   9745 #endif
   9746   case MHD_FEATURE_DIGEST_AUTH_USERHASH:
   9747 #ifdef DAUTH_SUPPORT
   9748     return MHD_YES;
   9749 #else
   9750     return MHD_NO;
   9751 #endif
   9752   case MHD_FEATURE_EXTERN_HASH:
   9753 #if defined(MHD_MD5_TLSLIB) || defined(MHD_SHA256_TLSLIB)
   9754     return MHD_YES;
   9755 #else
   9756     return MHD_NO;
   9757 #endif
   9758   case MHD_FEATURE_DEBUG_BUILD:
   9759 #ifdef _DEBUG
   9760     return MHD_YES;
   9761 #else
   9762     return MHD_NO;
   9763 #endif
   9764   case MHD_FEATURE_FLEXIBLE_FD_SETSIZE:
   9765 #ifdef HAS_FD_SETSIZE_OVERRIDABLE
   9766     return MHD_YES;
   9767 #else  /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   9768     return MHD_NO;
   9769 #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */
   9770 
   9771   default:
   9772     break;
   9773   }
   9774   return MHD_NO;
   9775 }
   9776 
   9777 
   9778 #ifdef MHD_HTTPS_REQUIRE_GCRYPT
   9779 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600
   9780 #if defined(MHD_USE_POSIX_THREADS)
   9781 GCRY_THREAD_OPTION_PTHREAD_IMPL;
   9782 #elif defined(MHD_W32_MUTEX_)
   9783 
   9784 static int
   9785 gcry_w32_mutex_init (void **ppmtx)
   9786 {
   9787   *ppmtx = malloc (sizeof (MHD_mutex_));
   9788 
   9789   if (NULL == *ppmtx)
   9790     return ENOMEM;
   9791   if (! MHD_mutex_init_ ((MHD_mutex_ *) *ppmtx))
   9792   {
   9793     free (*ppmtx);
   9794     *ppmtx = NULL;
   9795     return EPERM;
   9796   }
   9797 
   9798   return 0;
   9799 }
   9800 
   9801 
   9802 static int
   9803 gcry_w32_mutex_destroy (void **ppmtx)
   9804 {
   9805   int res = (MHD_mutex_destroy_ ((MHD_mutex_ *) *ppmtx)) ? 0 : EINVAL;
   9806   free (*ppmtx);
   9807   return res;
   9808 }
   9809 
   9810 
   9811 static int
   9812 gcry_w32_mutex_lock (void **ppmtx)
   9813 {
   9814   return MHD_mutex_lock_ ((MHD_mutex_ *) *ppmtx) ? 0 : EINVAL;
   9815 }
   9816 
   9817 
   9818 static int
   9819 gcry_w32_mutex_unlock (void **ppmtx)
   9820 {
   9821   return MHD_mutex_unlock_ ((MHD_mutex_ *) *ppmtx) ? 0 : EINVAL;
   9822 }
   9823 
   9824 
   9825 static struct gcry_thread_cbs gcry_threads_w32 = {
   9826   (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
   9827   NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
   9828   gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
   9829   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
   9830 };
   9831 
   9832 #endif /* defined(MHD_W32_MUTEX_) */
   9833 #endif /* HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600 */
   9834 #endif /* MHD_HTTPS_REQUIRE_GCRYPT */
   9835 
   9836 /**
   9837  * Initialize do setup work.
   9838  */
   9839 void
   9840 MHD_init (void)
   9841 {
   9842 #if defined(MHD_WINSOCK_SOCKETS)
   9843   WSADATA wsd;
   9844 #endif /* MHD_WINSOCK_SOCKETS */
   9845 
   9846   MHD_set_panic_func (NULL, NULL);
   9847 
   9848 #if defined(MHD_WINSOCK_SOCKETS)
   9849   if (0 != WSAStartup (MAKEWORD (2, 2), &wsd))
   9850     MHD_PANIC (_ ("Failed to initialize winsock.\n"));
   9851   if ((2 != LOBYTE (wsd.wVersion)) && (2 != HIBYTE (wsd.wVersion)))
   9852     MHD_PANIC (_ ("Winsock version 2.2 is not available.\n"));
   9853 #endif /* MHD_WINSOCK_SOCKETS */
   9854 #ifdef HTTPS_SUPPORT
   9855 #ifdef MHD_HTTPS_REQUIRE_GCRYPT
   9856 #if GCRYPT_VERSION_NUMBER < 0x010600
   9857 #if GNUTLS_VERSION_NUMBER <= 0x020b00
   9858 #if defined(MHD_USE_POSIX_THREADS)
   9859   if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
   9860                          &gcry_threads_pthread))
   9861     MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt.\n"));
   9862 #elif defined(MHD_W32_MUTEX_)
   9863   if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
   9864                          &gcry_threads_w32))
   9865     MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt.\n"));
   9866 #endif /* defined(MHD_W32_MUTEX_) */
   9867 #endif /* GNUTLS_VERSION_NUMBER <= 0x020b00 */
   9868   gcry_check_version (NULL);
   9869 #else
   9870   if (NULL == gcry_check_version ("1.6.0"))
   9871     MHD_PANIC (_ ("libgcrypt is too old. MHD was compiled for " \
   9872                   "libgcrypt 1.6.0 or newer.\n"));
   9873 #endif
   9874 #endif /* MHD_HTTPS_REQUIRE_GCRYPT */
   9875   gnutls_global_init ();
   9876 #endif /* HTTPS_SUPPORT */
   9877   MHD_monotonic_sec_counter_init ();
   9878   MHD_send_init_static_vars_ ();
   9879   MHD_init_mem_pools_ ();
   9880   /* Check whether sizes were correctly detected by configure */
   9881 #ifdef _DEBUG
   9882   if (1)
   9883   {
   9884     struct timeval tv;
   9885     mhd_assert (sizeof(tv.tv_sec) == SIZEOF_STRUCT_TIMEVAL_TV_SEC);
   9886   }
   9887 #endif /* _DEBUG */
   9888   mhd_assert (sizeof(uint64_t) == SIZEOF_UINT64_T);
   9889 }
   9890 
   9891 
   9892 void
   9893 MHD_fini (void)
   9894 {
   9895 #ifdef HTTPS_SUPPORT
   9896   gnutls_global_deinit ();
   9897 #endif /* HTTPS_SUPPORT */
   9898 #if defined(MHD_WINSOCK_SOCKETS)
   9899   WSACleanup ();
   9900 #endif /* MHD_WINSOCK_SOCKETS */
   9901   MHD_monotonic_sec_counter_finish ();
   9902 }
   9903 
   9904 
   9905 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
   9906 _SET_INIT_AND_DEINIT_FUNCS (MHD_init, MHD_fini);
   9907 #endif /* _AUTOINIT_FUNCS_ARE_SUPPORTED */
   9908 
   9909 /* end of daemon.c */