libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

mhd_daemon.h (35880B)


      1 /* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */
      2 /*
      3   This file is part of GNU libmicrohttpd.
      4   Copyright (C) 2024-2026 Evgeny Grin (Karlson2k)
      5 
      6   GNU libmicrohttpd 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   GNU libmicrohttpd 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   Alternatively, you can redistribute GNU libmicrohttpd and/or
     17   modify it under the terms of the GNU General Public License as
     18   published by the Free Software Foundation; either version 2 of
     19   the License, or (at your option) any later version, together
     20   with the eCos exception, as follows:
     21 
     22     As a special exception, if other files instantiate templates or
     23     use macros or inline functions from this file, or you compile this
     24     file and link it with other works to produce a work based on this
     25     file, this file does not by itself cause the resulting work to be
     26     covered by the GNU General Public License. However the source code
     27     for this file must still be made available in accordance with
     28     section (3) of the GNU General Public License v2.
     29 
     30     This exception does not invalidate any other reasons why a work
     31     based on this file might be covered by the GNU General Public
     32     License.
     33 
     34   You should have received copies of the GNU Lesser General Public
     35   License and the GNU General Public License along with this library;
     36   if not, see <https://www.gnu.org/licenses/>.
     37 */
     38 
     39 /**
     40  * @file src/mhd2/mhd_daemon.h
     41  * @brief  The header for declaration of struct MHD_Daemon
     42  * @author Karlson2k (Evgeny Grin)
     43  */
     44 
     45 #ifndef MHD_DAEMON_H
     46 #define MHD_DAEMON_H 1
     47 
     48 #include "mhd_sys_options.h"
     49 
     50 #include "sys_bool_type.h"
     51 #include "sys_base_types.h"
     52 
     53 #include "mhd_dlinked_list.h"
     54 
     55 #include "mhd_buffer.h"
     56 #include "mhd_socket_type.h"
     57 #include "mhd_atomic_counter.h"
     58 
     59 #ifdef MHD_SUPPORT_AUTH_DIGEST
     60 #  include "mhd_digest_auth_data.h"
     61 #endif
     62 
     63 #ifdef MHD_SUPPORT_HTTPS
     64 #  include "mhd_tls_choice.h"
     65 #endif
     66 
     67 #ifdef MHD_SUPPORT_THREADS
     68 #  include "mhd_threads.h"
     69 #  include "mhd_itc_types.h"
     70 #endif
     71 
     72 #include "mhd_locks.h"
     73 
     74 #include "sys_select.h"
     75 #include "sys_poll.h"
     76 #ifdef MHD_SUPPORT_EPOLL
     77 #  include <sys/epoll.h>
     78 #endif
     79 #include "sys_kqueue.h"
     80 
     81 #include "mempool_types.h"
     82 
     83 #ifdef mhd_HAVE_TLS_ACME
     84 #  include "mhd_tls_certs_list.h"
     85 #endif
     86 
     87 #include "mhd_public_api.h"
     88 
     89 struct DaemonOptions; /* Forward declaration */
     90 struct MHD_Connection; /* Forward declaration */
     91 struct sockaddr_storage; /* Forward declaration */
     92 
     93 /**
     94  * The helper struct for the connections list
     95  */
     96 mhd_DLINKEDL_LIST_DEF (MHD_Connection);
     97 
     98 /**
     99  * The current phase of the daemon life
    100  */
    101 enum MHD_FIXED_ENUM_ mhd_DaemonState
    102 {
    103   /**
    104    * The daemon has been created, but not yet started.
    105    * Setting configuration options is possible.
    106    */
    107   mhd_DAEMON_STATE_NOT_STARTED = 0
    108   ,
    109   /**
    110    * The daemon is being started.
    111    */
    112   mhd_DAEMON_STATE_STARTING
    113   ,
    114   /**
    115    * The daemon has been started.
    116    * Normal operations.
    117    */
    118   mhd_DAEMON_STATE_STARTED
    119   ,
    120   /**
    121    * The daemon has failed to start
    122    */
    123   mhd_DAEMON_STATE_FAILED
    124   ,
    125   /**
    126    * The daemon is being stopped.
    127    */
    128   mhd_DAEMON_STATE_STOPPING
    129   ,
    130   /**
    131    * The daemon is stopped.
    132    * The state should rarely visible as daemon should be destroyed when stopped.
    133    */
    134   mhd_DAEMON_STATE_STOPPED
    135 };
    136 
    137 
    138 /**
    139  * Internal version of the daemon work mode type
    140  */
    141 enum MHD_FIXED_ENUM_ mhd_WorkModeIntType
    142 {
    143   /**
    144    * Network edge-triggered events are monitored and provided by application.
    145    * Receiving, sending and processing of the network data if performed when
    146    * special MHD function is called by application.
    147    * No threads managed by the daemon.
    148    */
    149   mhd_WM_INT_EXTERNAL_EVENTS_EDGE
    150   ,
    151   /**
    152    * Network level-triggered events are monitored and provided by application.
    153    * Receiving, sending and processing of the network data if performed when
    154    * special MHD function is called by application.
    155    * No threads managed by the daemon.
    156    */
    157   mhd_WM_INT_EXTERNAL_EVENTS_LEVEL
    158   ,
    159   /**
    160    * The daemon checks for the network events, receives, sends and process
    161    * the network data when special MHD function is called by application.
    162    * No threads managed by the daemon.
    163    */
    164   mhd_WM_INT_INTERNAL_EVENTS_NO_THREADS
    165 #ifdef MHD_SUPPORT_THREADS
    166   ,
    167   /**
    168    * The daemon runs its own single thread, where the daemon monitors
    169    * all network events, receives, sends and process the network data.
    170    */
    171   mhd_WM_INT_INTERNAL_EVENTS_ONE_THREAD
    172   ,
    173   /**
    174    * The daemon runs its own single thread, where the daemon monitors
    175    * the new incoming connections, and runs individual thread for each
    176    * established connection, where the daemon monitors connection, receives,
    177    * sends and process the network data.
    178    */
    179   mhd_WM_INT_INTERNAL_EVENTS_THREAD_PER_CONNECTION
    180   ,
    181   /**
    182    * The daemon runs its fixed number of threads, all threads monitors the
    183    * new incoming connections and each thread handles own subset of the network
    184    * connections (monitors connections network events, receives, sends and
    185    * process the network data).
    186    */
    187   mhd_WM_INT_INTERNAL_EVENTS_THREAD_POOL
    188 #endif
    189 };
    190 
    191 #ifdef MHD_SUPPORT_THREADS
    192 /**
    193  * Check whether given mhd_WorkModeIntType value should have internal threads,
    194  * either directly controlled or indirectly, via additional workers daemons.
    195  */
    196 #  define mhd_WM_INT_HAS_THREADS(wm_i) \
    197           (mhd_WM_INT_INTERNAL_EVENTS_ONE_THREAD <= wm_i)
    198 /**
    199  * Check whether given mhd_WorkModeIntType value equals "thread-per-connection"
    200  */
    201 #  define mhd_WM_INT_IS_THREAD_PER_CONN(wm_i) \
    202           (mhd_WM_INT_INTERNAL_EVENTS_THREAD_PER_CONNECTION == wm_i)
    203 /**
    204  * Check whether given mhd_WorkModeIntType value equals "thread pool"
    205  */
    206 #  define mhd_WM_INT_IS_THREAD_POOL(wm_i) \
    207           (mhd_WM_INT_INTERNAL_EVENTS_THREAD_POOL == wm_i)
    208 #else  /* ! MHD_SUPPORT_THREADS */
    209 #  define mhd_WM_INT_HAS_THREADS(wm_i)          (0)
    210 #  define mhd_WM_INT_IS_THREAD_PER_CONN(wm_i)   (0)
    211 #  define mhd_WM_INT_IS_THREAD_POOL(wm_i)       (0)
    212 #endif /* ! MHD_SUPPORT_THREADS */
    213 
    214 /**
    215  * Check whether given mhd_WorkModeIntType value has external events
    216  */
    217 #define mhd_WM_INT_HAS_EXT_EVENTS(wm_i) \
    218         (mhd_WM_INT_EXTERNAL_EVENTS_LEVEL >= wm_i)
    219 
    220 
    221 /**
    222  * Sockets polling internal syscalls used by MHD.
    223  *
    224  * The same value used as by #MHD_SockPollSyscall, however instead of "auto"
    225  * method this enum uses "not yet set" and enum is extended with an additional
    226  * "external" value.
    227  */
    228 enum MHD_FIXED_ENUM_ mhd_IntPollType
    229 {
    230   /**
    231    * External sockets polling is used.
    232    */
    233   mhd_POLL_TYPE_EXT = -1
    234   ,
    235   /**
    236    * Internal sockets polling syscall has not been selected yet.
    237    */
    238   mhd_POLL_TYPE_NOT_SET_YET = MHD_SPS_AUTO
    239   ,
    240   /**
    241    * Use select().
    242    */
    243   mhd_POLL_TYPE_SELECT = MHD_SPS_SELECT
    244   ,
    245   /**
    246    * Use poll().
    247    */
    248   mhd_POLL_TYPE_POLL = MHD_SPS_POLL
    249 #ifdef MHD_SUPPORT_EPOLL
    250   ,
    251   /**
    252    * Use epoll.
    253    */
    254   mhd_POLL_TYPE_EPOLL = MHD_SPS_EPOLL
    255 #endif /* MHD_SUPPORT_EPOLL */
    256 #ifdef MHD_SUPPORT_KQUEUE
    257   ,
    258   /**
    259    * Use kqueue.
    260    */
    261   mhd_POLL_TYPE_KQUEUE = MHD_SPS_KQUEUE
    262 #endif /* MHD_SUPPORT_KQUEUE */
    263 };
    264 
    265 
    266 #ifdef MHD_SUPPORT_EPOLL
    267 /**
    268  * Check whether provided mhd_IntPollType value is "epoll"
    269  */
    270 #  define mhd_POLL_TYPE_INT_IS_EPOLL(poll_type) \
    271           (mhd_POLL_TYPE_EPOLL == (poll_type))
    272 #else
    273 #  define mhd_POLL_TYPE_INT_IS_EPOLL(poll_type) (0)
    274 #endif
    275 
    276 #ifdef MHD_SUPPORT_KQUEUE
    277 /**
    278  * Check whether provided mhd_IntPollType value is "kqueue"
    279  */
    280 #  define mhd_POLL_TYPE_INT_IS_KQUEUE(poll_type) \
    281           (mhd_POLL_TYPE_KQUEUE == (poll_type))
    282 #else
    283 #  define mhd_POLL_TYPE_INT_IS_KQUEUE(poll_type) (0)
    284 #endif
    285 
    286 #define mhd_POLL_TYPE_INT_IS_EDGE_TRIG(poll_type) \
    287         (mhd_POLL_TYPE_INT_IS_EPOLL (poll_type) \
    288          || mhd_POLL_TYPE_INT_IS_KQUEUE (poll_type))
    289 
    290 #if defined(HAVE_UINTPTR_T)
    291 typedef uintptr_t mhd_SockRelMarker;
    292 #else
    293 typedef unsigned char *mhd_SockRelMarker;
    294 #endif
    295 
    296 /** The marker of the empty position */
    297 #define mhd_SOCKET_REL_MARKER_EMPTY    ((mhd_SockRelMarker) (0))
    298 
    299 /** The marker of the ITC slot */
    300 #define mhd_SOCKET_REL_MARKER_ITC      ((mhd_SockRelMarker) (-1))
    301 
    302 /** The marker of the listen socket slot */
    303 #define mhd_SOCKET_REL_MARKER_LISTEN   (mhd_SOCKET_REL_MARKER_ITC - 1)
    304 
    305 /* Pointer version of the markers */
    306 
    307 /** The marker of the empty position */
    308 #define mhd_SOCKET_REL_PTRMARKER_EMPTY  ((void*) mhd_SOCKET_REL_MARKER_EMPTY)
    309 
    310 /** The marker of the ITC slot */
    311 #define mhd_SOCKET_REL_PTRMARKER_ITC    ((void*) mhd_SOCKET_REL_MARKER_ITC)
    312 
    313 /** The marker of the listen socket slot */
    314 #define mhd_SOCKET_REL_PTRMARKER_LISTEN ((void*) mhd_SOCKET_REL_MARKER_LISTEN)
    315 
    316 /**
    317  * Identifier of the FD related to event
    318  */
    319 union mhd_SocketRelation
    320 {
    321   /**
    322    * Identifier of the FD.
    323    * Only valid when it is equal to #mhd_SOCKET_REL_MARKER_EMPTY,
    324    * #mhd_SOCKET_REL_MARKER_ITC or #mhd_SOCKET_REL_MARKER_LISTEN.
    325    */
    326   mhd_SockRelMarker fd_id;
    327   /**
    328    * This is a connection's FD.
    329    * This is valid only when @a fd_id is not valid.
    330    */
    331   struct MHD_Connection *connection;
    332 };
    333 
    334 #ifdef MHD_SUPPORT_SELECT
    335 
    336 /**
    337  * Daemon's pointers to the preallocated arrays for running sockets monitoring
    338  * by poll().
    339  */
    340 struct mhd_DaemonEventsSelectData
    341 {
    342   /**
    343    * Set of sockets monitored for read (receive) readiness.
    344    */
    345   fd_set *rfds;
    346   /**
    347    * Set of sockets monitored for write (send) readiness.
    348    */
    349   fd_set *wfds;
    350   /**
    351    * Set of sockets monitored for exception (error) readiness.
    352    */
    353   fd_set *efds;
    354 };
    355 
    356 #endif /* MHD_SUPPORT_SELECT */
    357 
    358 #ifdef MHD_SUPPORT_POLL
    359 
    360 /**
    361  * Daemon's pointers to the preallocated arrays for running sockets monitoring
    362  * by poll().
    363  */
    364 struct mhd_DaemonEventsPollData
    365 {
    366   /**
    367    * Array of sockets monitored for read (receive) readiness.
    368    * The size of the array is maximum number of connections per this daemon plus
    369    * two (one for the listen socket and one for ITC).
    370    * ITC FDs and the listening are always the first (and the second), if used.
    371    * The number of elements is always two plus maximum number of connections
    372    * allowed for the daemon.
    373    */
    374   struct pollfd *fds;
    375   /**
    376    * Array of the @a fds identifications.
    377    * Each slot matches the slot with the same number in @a fds.
    378    * Up to two first positions reserved for the ITC and the listening.
    379    * The number of elements is always two plus maximum number of connections
    380    * allowed for the daemon.
    381    */
    382   union mhd_SocketRelation *rel;
    383 };
    384 
    385 #endif /* MHD_SUPPORT_POLL */
    386 
    387 #ifdef MHD_SUPPORT_EPOLL
    388 /**
    389  * Daemon's parameters and pointers to the preallocated memory for running
    390  * sockets monitoring by epoll.
    391  */
    392 struct mhd_DaemonEventsEPollData
    393 {
    394   /**
    395    * The epoll control FD.
    396    */
    397   int e_fd;
    398   /**
    399    * The array of events reported by epoll.
    400    */
    401   struct epoll_event *events;
    402   /**
    403    * The number of elements in the allocated @a events arrays.
    404    */
    405   size_t num_elements;
    406   /**
    407    * The epoll control FD, created by probing during early daemon
    408    * initialisation.
    409    * Temporal location.
    410    * Must be moved to @a e_fd with events initialisation.
    411    */
    412   int early_fd;
    413 };
    414 
    415 #endif
    416 
    417 #ifdef MHD_SUPPORT_KQUEUE
    418 /**
    419  * Daemon's parameters and pointers to the preallocated memory for running
    420  * sockets monitoring by kqueue.
    421  */
    422 struct mhd_DaemonEventsKQueueData
    423 {
    424   /**
    425    * The kqueue FD.
    426    */
    427   int kq_fd;
    428 
    429   /**
    430    * The array of kevents used for both registering filters and getting events
    431    */
    432   struct kevent *kes;
    433 
    434   /**
    435    * The number of elements in the allocated @a kes array.
    436    *
    437    * Note: kqueue API uses 'int' for the number of elements
    438    */
    439   unsigned int num_elements;
    440 };
    441 
    442 #endif /* MHD_SUPPORT_KQUEUE */
    443 
    444 /**
    445  * Daemon's data for external events callback.
    446  * Internal version of struct MHD_WorkModeExternalEventLoopCBParam.
    447  */
    448 struct mhd_DaemonEventsExternalCallback
    449 {
    450   /**
    451    * Socket registration callback
    452    */
    453   MHD_SocketRegistrationUpdateCallback cb;
    454   /**
    455    * Closure for the @a cb
    456    */
    457   void *cls;
    458 };
    459 
    460 
    461 #ifdef MHD_SUPPORT_THREADS
    462 /**
    463  * External events data for ITC FD
    464  */
    465 struct mhd_DaemonEventsExternalDaemonItcData
    466 {
    467   /**
    468    * Application context for ITC FD
    469    */
    470   void *app_cntx;
    471 
    472   /**
    473    * Set to 'true' when active state was detected on ITC by
    474    * external polling
    475    */
    476   bool is_active;
    477 
    478   /**
    479    * Set to 'true' when error state was detected on ITC by
    480    * external polling.
    481    * The daemon may become non-functional.
    482    */
    483   bool is_broken;
    484 };
    485 #endif /* MHD_SUPPORT_THREADS */
    486 
    487 /**
    488  * External events data for the listen socket
    489  */
    490 struct mhd_DaemonEventsExternalDaemonListenData
    491 {
    492   /**
    493    * Application context for ITC FD
    494    */
    495   void *app_cntx;
    496 };
    497 
    498 /**
    499  * Daemon's data for external events for sockets monitoring.
    500  */
    501 struct mhd_DaemonEventsExternal
    502 {
    503   /**
    504    * Daemon's data for external events callback.
    505    * Internal version of struct MHD_WorkModeExternalEventLoopCBParam.
    506    */
    507   struct mhd_DaemonEventsExternalCallback cb_data;
    508 
    509 #ifdef MHD_SUPPORT_THREADS
    510   /**
    511    * External events data for ITC FD
    512    */
    513   struct mhd_DaemonEventsExternalDaemonItcData itc_data;
    514 #endif /* MHD_SUPPORT_THREADS */
    515 
    516   /**
    517    * External events data for the listen socket
    518    */
    519   struct mhd_DaemonEventsExternalDaemonListenData listen_data;
    520 
    521   /**
    522    * If set to 'true' then all FDs must be registered each round.
    523    * If set to 'false' then only changed FDs must be registered.
    524    */
    525   bool reg_all;
    526 };
    527 
    528 /**
    529  * Type-specific events monitoring data
    530  */
    531 union mhd_DaemonEventMonitoringTypeSpecificData
    532 {
    533 #ifdef MHD_SUPPORT_SELECT
    534   /**
    535    * Daemon's pointers to the preallocated arrays for running sockets monitoring
    536    * by poll().
    537    */
    538   struct mhd_DaemonEventsSelectData select;
    539 #endif /* MHD_SUPPORT_SELECT */
    540 
    541 #ifdef MHD_SUPPORT_POLL
    542   /**
    543    * Daemon's pointers to the preallocated arrays for running sockets monitoring
    544    * by poll().
    545    */
    546   struct mhd_DaemonEventsPollData poll;
    547 #endif /* MHD_SUPPORT_POLL */
    548 
    549 #ifdef MHD_SUPPORT_EPOLL
    550   /**
    551    * Daemon's parameters and pointers to the preallocated memory for running
    552    * sockets monitoring by epoll.
    553    */
    554   struct mhd_DaemonEventsEPollData epoll;
    555 #endif
    556 
    557 #ifdef MHD_SUPPORT_KQUEUE
    558   /**
    559    * Daemon's parameters and pointers to the preallocated memory for running
    560    * sockets monitoring by kqueue.
    561    */
    562   struct mhd_DaemonEventsKQueueData kq;
    563 #endif
    564 
    565   /**
    566    * Daemon's data for external events for sockets monitoring.
    567    */
    568   struct mhd_DaemonEventsExternal extr;
    569 };
    570 
    571 
    572 struct mhd_DaemonExtAddedConn; /* Forward declaration */
    573 mhd_DLINKEDL_STRUCTS_DEFS (mhd_DaemonExtAddedConn);
    574 
    575 /**
    576  * Information about externally added connection
    577  */
    578 struct mhd_DaemonExtAddedConn
    579 {
    580   /**
    581    * The links to the other externally added connections in the queue
    582    */
    583   mhd_DLNKDL_LINKS (mhd_DaemonExtAddedConn, queue);
    584 
    585   /**
    586    * The socket of the externally added connection
    587    */
    588   MHD_Socket skt;
    589 
    590   /**
    591    * The size of the data pointed by @a addr.
    592    * Zero fi @a addr is NULL.
    593    */
    594   size_t addr_size;
    595 
    596   /**
    597    * Pointer to socket address.
    598    * Allocated by malloc(), must be freed;
    599    * May be NULL.
    600    */
    601   struct sockaddr_storage *addr;
    602 
    603   /**
    604    * 'true' if @a skt is non-blocking
    605    */
    606   bool is_nonblock;
    607 
    608   /**
    609    * 'true' if @a skt has SIGPIPE suppressed
    610    */
    611   bool has_spipe_suppr;
    612 };
    613 
    614 
    615 /**
    616  * Information about externally added connections for the worker daemon
    617  */
    618 struct mhd_DaemonExtAddedConnectionsWorker
    619 {
    620 #ifdef MHD_SUPPORT_THREADS
    621   /**
    622    * The lock to access @a queue list
    623    */
    624   mhd_mutex q_lock;
    625 #endif /* MHD_SUPPORT_THREADS */
    626   /**
    627    * The list with the queue of externally added connections
    628    */
    629   mhd_DLNKDL_LIST (mhd_DaemonExtAddedConn, queue);
    630 };
    631 
    632 #ifdef MHD_SUPPORT_THREADS
    633 /**
    634  * Information about externally added connections for the master daemon
    635  */
    636 struct mhd_DaemonExtAddedConnectionsMaster
    637 {
    638   /**
    639    * The index (modulo number of workers) of the next worker daemon to add
    640    * connection
    641    */
    642   struct mhd_AtomicCounter next_d_idx;
    643 };
    644 #endif /* MHD_SUPPORT_THREADS */
    645 
    646 /**
    647  * Information about externally added connections
    648  */
    649 union mhd_DaemonExtAddedConnections
    650 {
    651 #ifdef MHD_SUPPORT_THREADS
    652   /**
    653    * Information about externally added connections for the master daemon
    654    */
    655   struct mhd_DaemonExtAddedConnectionsMaster master;
    656 #endif /* MHD_SUPPORT_THREADS */
    657   /**
    658    * Information about externally added connections for the worker daemon
    659    */
    660   struct mhd_DaemonExtAddedConnectionsWorker worker;
    661 };
    662 
    663 
    664 /**
    665  * The required actions for the daemon
    666  */
    667 struct mhd_DaemonEventActionRequired
    668 {
    669   /**
    670    * If 'true' connection resuming is required.
    671    */
    672   bool resume;
    673 
    674   /**
    675    * Information about externally added connections
    676    */
    677   union mhd_DaemonExtAddedConnections ext_added;
    678 };
    679 
    680 /**
    681  * The daemon's time data
    682  */
    683 struct mhd_DaemonEventsCurTime
    684 {
    685   /**
    686    * 'true' if @a cur is set
    687    */
    688   bool is_set;
    689   /**
    690    * Current value of monotonic milliseconds counter.
    691    * Valid only if @a is_set is 'true'.
    692    * Updated once per processing round.
    693    */
    694   uint_fast64_t cur;
    695 };
    696 
    697 /**
    698  * The data for events monitoring
    699  */
    700 struct mhd_DaemonEventMonitoringData
    701 {
    702   /**
    703    * Sockets polling type used by the daemon.
    704    */
    705   enum mhd_IntPollType poll_type;
    706 
    707   /**
    708    * Type-specific events monitoring data
    709    */
    710   union mhd_DaemonEventMonitoringTypeSpecificData data;
    711 
    712   /**
    713    * The required actions for the daemon.
    714    */
    715   struct mhd_DaemonEventActionRequired act_req;
    716 
    717   /**
    718    * When set to 'true' the listen socket has new incoming connection(s).
    719    */
    720   bool accept_pending;
    721 
    722   /**
    723    * The list of the daemon's connections that need processing
    724    */
    725   mhd_DLNKDL_LIST (MHD_Connection, proc_ready);
    726 
    727   /**
    728    * The daemon's time data
    729    */
    730   struct mhd_DaemonEventsCurTime time;
    731 };
    732 
    733 
    734 /**
    735  * The type of the socket
    736  */
    737 enum MHD_FIXED_ENUM_ mhd_SocketType
    738 {
    739   /**
    740    * The socket type is some non-IP type.
    741    */
    742   mhd_SOCKET_TYPE_NON_IP = -2
    743   ,
    744   /**
    745    * The socket type is UNIX (LOCAL)
    746    */
    747   mhd_SOCKET_TYPE_UNIX = -1
    748   ,
    749   /**
    750    * The socket is unknown yet. It can be IP or non-IP.
    751    */
    752   mhd_SOCKET_TYPE_UNKNOWN = 0
    753   ,
    754   /**
    755    * The socket is definitely IP.
    756    */
    757   mhd_SOCKET_TYPE_IP = 1
    758 };
    759 
    760 /**
    761  * Listen socket data
    762  */
    763 struct mhd_ListenSocket
    764 {
    765   /**
    766    * The listening socket
    767    */
    768   MHD_Socket fd;
    769   /**
    770    * Set to 'true' when unrecoverable error is detected on the listen socket.
    771    * If set to 'true', but @a fd is not #MHD_INVALID_SOCKET then "broken" state
    772    * has not yet processed by MHD.
    773    */
    774   bool is_broken;
    775   /**
    776    * The type of the listening socket @a fd
    777    */
    778   enum mhd_SocketType type;
    779   /**
    780    * 'true' if @a fd is non-blocking
    781    */
    782   bool non_block;
    783   /**
    784    * The port number for @a fd
    785    *
    786    * Zero if unknown and for non-IP socket.
    787    */
    788   uint_least16_t port;
    789 };
    790 
    791 /**
    792  * Configured settings for the daemon's network data
    793  */
    794 struct mhd_DaemonNetworkSettings
    795 {
    796 #ifdef MHD_SOCKETS_KIND_POSIX
    797   /**
    798    * The maximum number for the network FDs.
    799    * The valid FD number must be less then @a max_fd_num.
    800    */
    801   MHD_Socket max_fd_num;
    802 #else
    803   int dummy; /* mute compiler warning */
    804 #endif
    805 };
    806 
    807 /**
    808  * The daemon network/sockets data
    809  *
    810  * This structure holds mostly static information -- typically initialised once
    811  * when the daemon starts, and possibly updated once later (e.g., if the
    812  * listening socket fails or is closed).
    813  *
    814  * It does NOT contain any operational states.
    815  */
    816 struct mhd_DaemonNetwork
    817 {
    818   /**
    819    * The listening socket
    820    */
    821   struct mhd_ListenSocket listen;
    822   /**
    823    * Configured settings for the daemon's network data
    824    */
    825   struct mhd_DaemonNetworkSettings cfg;
    826 };
    827 
    828 #ifdef MHD_SUPPORT_AUTH_DIGEST
    829 
    830 /**
    831  * Digest Auth nonce data
    832  */
    833 struct mhd_DaemonAuthDigestNonceData
    834 {
    835   /**
    836    * The nonce value in the binary form, excluding validity tail
    837    */
    838   uint8_t nonce[mhd_AUTH_DIGEST_NONCE_RAND_BIN_SIZE];
    839 
    840   /**
    841    * The nonce validity time
    842    */
    843   uint_fast32_t valid_time;
    844 
    845   /**
    846    * The largest last received 'nc' value.
    847    * This 'nc' value has been already used by the client.
    848    */
    849   uint_fast32_t max_recvd_nc;
    850 
    851   /**
    852    * Bitmask over the previous 64 nc values (down to to nc-64).
    853    * Used to allow out-of-order 'nc'.
    854    * If bit in the bitmask is set to one, then this 'nc' value was already used
    855    * by the client.
    856    */
    857   uint_fast64_t nmask;
    858 };
    859 
    860 /**
    861  * Digest Auth daemon configuration data
    862  */
    863 struct mhd_DaemonAuthDigestCfg
    864 {
    865   /**
    866    * The number of elements in the nonces array
    867    */
    868   size_t nonces_num;
    869 
    870   /**
    871    * The nonce validity time (in seconds)
    872    */
    873   unsigned int nonce_tmout;
    874 
    875   /**
    876    * The default maximum value of nc
    877    */
    878   uint_fast32_t def_max_nc;
    879 };
    880 
    881 /**
    882  * The Digest Auth daemon's data
    883  */
    884 struct mhd_DaemonAuthDigestData
    885 {
    886   /**
    887    * The entropy data used for Digests generation
    888    */
    889   struct mhd_Buffer entropy;
    890 
    891   /**
    892    * The array of generated nonce and related nc
    893    */
    894   struct mhd_DaemonAuthDigestNonceData *nonces;
    895 
    896   /**
    897    * Number of nonces has been generated.
    898    * Used as addition for the nonce source data to ensure unique nonce value.
    899    * TODO: remove and directly use random generator for nonce generation.
    900    */
    901   struct mhd_AtomicCounter num_gen_nonces;
    902 
    903 #  ifdef MHD_SUPPORT_THREADS
    904   /**
    905    * The mutex to change or access the @a nonces data
    906    */
    907   mhd_mutex nonces_lock;
    908 #  endif
    909 
    910   /**
    911    * Digest Auth daemon configuration data
    912    */
    913   struct mhd_DaemonAuthDigestCfg cfg;
    914 };
    915 
    916 #endif /* MHD_SUPPORT_AUTH_DIGEST */
    917 
    918 #ifdef MHD_SUPPORT_ACME
    919 
    920 /**
    921  * Daemon's ACME data
    922  */
    923 struct mhd_DaemonAcmeData
    924 {
    925 #  ifdef mhd_HAVE_TLS_ACME
    926   /**
    927    * Special certificates for ACME ALPN challenges
    928    */
    929   struct mhd_TlsCertsList alpn;
    930 #  else
    931   /**
    932    * Unused
    933    */
    934   int dummy; /* TODO: A placeholder. Remove after adding non-TLS data */
    935 #  endif /* MHD_SUPPORT_HTTPS */
    936 };
    937 #endif /* MHD_SUPPORT_ACME */
    938 
    939 
    940 #ifdef MHD_SUPPORT_THREADS
    941 
    942 /**
    943  * The type of the daemon
    944  */
    945 enum MHD_FIXED_ENUM_ mhd_DaemonType
    946 {
    947   /**
    948    * A single daemon, performing all the work.
    949    *
    950    * This daemon may have a optional single thread, managed by MHD.
    951    */
    952   mhd_DAEMON_TYPE_SINGLE
    953 #  ifndef NDEBUG
    954     = 1
    955 #  endif
    956 #  ifdef MHD_SUPPORT_THREADS
    957   ,
    958   /**
    959    * A master daemon, only controlling worker daemons.
    960    *
    961    * This daemon never handle any network activity directly.
    962    */
    963   mhd_DAEMON_TYPE_MASTER_CONTROL_ONLY
    964   ,
    965   /**
    966    * A daemon with single internal thread for listening and multiple threads
    967    * handling connections with the clients, one thread per connection.
    968    */
    969   mhd_DAEMON_TYPE_LISTEN_ONLY
    970   ,
    971   /**
    972    * A worker daemon, performing the same work as a single daemon, but
    973    * controlled by master daemon.
    974    *
    975    * This type of daemon always have single internal tread and never exposed
    976    * to application directly.
    977    */
    978   mhd_DAEMON_TYPE_WORKER
    979 #  endif /* MHD_SUPPORT_THREADS */
    980 };
    981 
    982 /**
    983  * Check whether the daemon type is allowed to have internal thread with
    984  * direct control
    985  */
    986 #  define mhd_D_TYPE_IS_VALID(t) \
    987           ((mhd_DAEMON_TYPE_SINGLE <= (t)) && (mhd_DAEMON_TYPE_WORKER >= (t)))
    988 
    989 /**
    990  * Check whether the daemon type must not be exposed to the application
    991  */
    992 #  define mhd_D_TYPE_IS_INTERNAL_ONLY(t) \
    993           (mhd_DAEMON_TYPE_WORKER == (t))
    994 /**
    995  * Check whether the daemon type is allowed to process the network data
    996  */
    997 #  define mhd_D_TYPE_HAS_EVENTS_PROCESSING(t) \
    998           (mhd_DAEMON_TYPE_MASTER_CONTROL_ONLY != (t))
    999 
   1000 /**
   1001  * Check whether the daemon type must not be exposed to the application
   1002  */
   1003 #  define mhd_D_TYPE_HAS_WORKERS(t) \
   1004           (mhd_DAEMON_TYPE_MASTER_CONTROL_ONLY == (t))
   1005 
   1006 /**
   1007  * Check whether the daemon type has master (controlling) daemon
   1008  */
   1009 #  define mhd_D_TYPE_HAS_MASTER_DAEMON(t) \
   1010           (mhd_DAEMON_TYPE_WORKER == (t))
   1011 
   1012 /**
   1013  * Check whether the daemon is listening only (with connection data
   1014  * processed in separate threads)
   1015  */
   1016 #  define mhd_D_TYPE_IS_LISTEN_ONLY(t) \
   1017           (mhd_DAEMON_TYPE_LISTEN_ONLY == (t))
   1018 
   1019 #else  /* ! MHD_SUPPORT_THREADS */
   1020 
   1021 /**
   1022  * Check whether the daemon type is allowed to have internal thread with
   1023  * direct control
   1024  */
   1025 #  define mhd_D_TYPE_IS_VALID(t) (! 0)
   1026 
   1027 /**
   1028  * Check whether the daemon type must not be exposed to the application
   1029  */
   1030 #  define mhd_D_TYPE_IS_INTERNAL_ONLY(t) (0)
   1031 
   1032 /**
   1033  * Check whether the daemon type is allowed to process the network data
   1034  */
   1035 #  define mhd_D_TYPE_HAS_EVENTS_PROCESSING(t) (! 0)
   1036 
   1037 /**
   1038  * Check whether the daemon type must not be exposed to the application
   1039  */
   1040 #  define mhd_D_TYPE_HAS_WORKERS(t) (0)
   1041 
   1042 /**
   1043  * Check whether the daemon type has master (controlling) daemon
   1044  */
   1045 #  define mhd_D_TYPE_HAS_MASTER_DAEMON(t)  (0)
   1046 
   1047 /**
   1048  * Check whether the daemon is listening only (with connection data
   1049  * processed in separate threads)
   1050  */
   1051 #  define mhd_D_TYPE_IS_LISTEN_ONLY(t)    (0)
   1052 
   1053 #endif /* ! MHD_SUPPORT_THREADS */
   1054 
   1055 #ifdef MHD_SUPPORT_THREADS
   1056 
   1057 /**
   1058  * Workers pool data
   1059  */
   1060 struct mhd_DaemonWorkerPoolData
   1061 {
   1062   /**
   1063    * Array of worker daemons
   1064    */
   1065   struct MHD_Daemon *workers;
   1066 
   1067   /**
   1068    * The number of workers in the @a workers array
   1069    */
   1070   unsigned int num;
   1071 };
   1072 
   1073 /**
   1074  * Hierarchy data for the daemon
   1075  */
   1076 union mhd_DaemonHierarchyData
   1077 {
   1078   /**
   1079    * The pointer to the master daemon
   1080    * Only for #mhd_DAEMON_TYPE_WORKER daemons.
   1081    */
   1082   struct MHD_Daemon *master;
   1083 
   1084   /**
   1085    * Workers pool data.
   1086    * Only for #mhd_DAEMON_TYPE_MASTER_CONTROL_ONLY daemons.
   1087    */
   1088   struct mhd_DaemonWorkerPoolData pool;
   1089 };
   1090 
   1091 /**
   1092  * Configured settings for threading
   1093  */
   1094 struct mhd_DaemonThreadingDataSettings
   1095 {
   1096   /**
   1097    * The size of the stack.
   1098    * Zero to use system's defaults.
   1099    */
   1100   size_t stack_size;
   1101 };
   1102 
   1103 /**
   1104  * Threading and Inter-Thread Communication data
   1105  */
   1106 struct mhd_DaemonThreadingData
   1107 {
   1108   /**
   1109    * The type of this daemon
   1110    */
   1111   enum mhd_DaemonType d_type;
   1112 
   1113   /**
   1114    * Inter-Thread Communication channel.
   1115    * Used to trigger processing of the command or the data provided or updated
   1116    * by the application.
   1117    */
   1118   struct mhd_itc itc;
   1119 
   1120   /**
   1121    * 'True' if stop has been requested.
   1122    * The daemon thread should stop all connections and then close.
   1123    */
   1124   volatile bool stop_requested;
   1125 
   1126   /**
   1127    * The handle of the daemon's thread (if managed by the daemon)
   1128    */
   1129   mhd_thread_handle_ID tid;
   1130 
   1131   /**
   1132    * The hierarchy data for the daemon.
   1133    * Used only when @a d_type is #mhd_DAEMON_TYPE_MASTER_CONTROL_ONLY or
   1134    * #mhd_DAEMON_TYPE_WORKER.
   1135    */
   1136   union mhd_DaemonHierarchyData hier;
   1137 
   1138   /**
   1139    * Configured settings for threading
   1140    */
   1141   struct mhd_DaemonThreadingDataSettings cfg;
   1142 };
   1143 
   1144 #endif /* MHD_SUPPORT_THREADS */
   1145 
   1146 /**
   1147  * Configured settings for the daemon's connections
   1148  */
   1149 struct mhd_DaemonConnectionsSettings
   1150 {
   1151   /**
   1152    * The maximum number of connections handled by the daemon
   1153    */
   1154   unsigned int count_limit;
   1155 
   1156   /**
   1157    * The maximum number of connections per any IP handled by the daemon
   1158    */
   1159   unsigned int per_ip_limit;
   1160 
   1161   /**
   1162    * Connection's default timeout value (in milliseconds)
   1163    */
   1164   uint_fast32_t timeout_milsec;
   1165 
   1166   /**
   1167    * Connection's memory pool size
   1168    */
   1169   size_t mem_pool_size;
   1170 
   1171   /**
   1172    * Memory pool zeroing mode
   1173    */
   1174   enum mhd_MemPoolZeroing mem_pool_zeroing;
   1175 };
   1176 
   1177 #ifdef MHD_SUPPORT_UPGRADE
   1178 
   1179 /**
   1180  * The data for HTTP-Upgraded connections
   1181  */
   1182 struct mhd_DaemonConnectionsUpgraded
   1183 {
   1184   /**
   1185    * The list of HTTP-Upgraded connection closed by application and
   1186    * queued for cleanup
   1187    */
   1188   mhd_DLNKDL_LIST (MHD_Connection, upgr_cleanup);
   1189 
   1190 #  ifdef MHD_SUPPORT_THREADS
   1191   /**
   1192    * The mutex to change or check the @a upgr_cleanup list values
   1193    */
   1194   mhd_mutex ucu_lock;
   1195 #  endif
   1196 };
   1197 
   1198 #endif /* MHD_SUPPORT_UPGRADE */
   1199 
   1200 /**
   1201  * Connections handling data
   1202  */
   1203 struct mhd_DaemonConnections
   1204 {
   1205 
   1206   /**
   1207    * The list of all daemon's connections.
   1208    * All connection are listed here, expect connection in @a to_clean list.
   1209    */
   1210   mhd_DLNKDL_LIST (MHD_Connection, all_conn);
   1211 
   1212   /**
   1213    * The list of connections sorted by last activity
   1214    */
   1215   mhd_DLNKDL_LIST (MHD_Connection, def_timeout);
   1216 
   1217   /**
   1218    * The list of connections with custom timeouts
   1219    */
   1220   mhd_DLNKDL_LIST (MHD_Connection, cust_timeout);
   1221 
   1222   /**
   1223    * The current number of connections handled by the daemon
   1224    */
   1225   unsigned int count;
   1226 
   1227   /**
   1228    * If set to 'true' then no new connection is allowed.
   1229    * New connection may be blocked because of various system limits, when
   1230    * additional connection would fail anyway. This flag should be cleared
   1231    * when any already processing connection closed.
   1232    * Can be checked from other threads
   1233    */
   1234   volatile bool block_new;
   1235 
   1236   /**
   1237    * Configured settings for the daemon's connections
   1238    */
   1239   struct mhd_DaemonConnectionsSettings cfg;
   1240 
   1241 #ifdef MHD_SUPPORT_UPGRADE
   1242   /**
   1243    * The data for HTTP-Upgraded connections
   1244    */
   1245   struct mhd_DaemonConnectionsUpgraded upgr;
   1246 #endif /* MHD_SUPPORT_UPGRADE */
   1247 };
   1248 
   1249 /**
   1250  * Early URI callback
   1251  */
   1252 struct mhd_DaemonRequestUriCB
   1253 {
   1254   /**
   1255    * The callback
   1256    */
   1257   MHD_EarlyUriLogCallback cb;
   1258   /**
   1259    * The callback closure
   1260    */
   1261   void *cls;
   1262 };
   1263 
   1264 /**
   1265  * Shared large buffer data
   1266  */
   1267 struct mhd_DaemonLargeBuffer
   1268 {
   1269   /**
   1270    * The amount of memory left allowed to be allocated for the large buffer
   1271    */
   1272   size_t space_left;
   1273 
   1274 #ifdef MHD_SUPPORT_THREADS
   1275   /**
   1276    * The mutex to change or check the @a space_left value
   1277    */
   1278   mhd_mutex lock;
   1279 #endif
   1280 };
   1281 
   1282 #ifdef MHD_SUPPORT_HTTP2
   1283 
   1284 /**
   1285  * Generic settings for HTTP layer communication handling.
   1286  *
   1287  * These settings do not include specific settings for requests processing.
   1288  */
   1289 struct mhd_DaemonHttpSettings
   1290 {
   1291   /**
   1292    * 'true' if HTTP/1.x communication is allowed
   1293    */
   1294   bool http1x;
   1295   /**
   1296    * 'true' if HTTP/2 communication is allowed
   1297    */
   1298   bool http2;
   1299 };
   1300 
   1301 #endif /* MHD_SUPPORT_HTTP2 */
   1302 
   1303 /**
   1304  * Settings for requests processing
   1305  */
   1306 struct mhd_DaemonRequestProcessingSettings
   1307 {
   1308   /**
   1309    * Request callback.
   1310    * The main request processing callback.
   1311    */
   1312   MHD_RequestCallback cb;
   1313 
   1314   /**
   1315    * The closure for @a req_cb
   1316    */
   1317   void *cb_cls;
   1318 
   1319   /**
   1320    * Protocol strictness enforced by MHD on clients.
   1321    */
   1322   enum MHD_ProtocolStrictLevel strictness;
   1323 
   1324 #ifdef MHD_SUPPORT_COOKIES
   1325   /**
   1326    * Disable automatic cookies parsing
   1327    */
   1328   bool disable_cookies;
   1329 #endif
   1330 
   1331   /**
   1332    * Early URI callback
   1333    */
   1334   struct mhd_DaemonRequestUriCB uri_cb; // TODO: set from settings
   1335 
   1336   /**
   1337    * Shared large buffer data
   1338    */
   1339   struct mhd_DaemonLargeBuffer large_buf; // TODO: set from settings
   1340 
   1341   /**
   1342    * Suppress "Date:" header in responses
   1343    */
   1344   bool suppress_date;
   1345 };
   1346 
   1347 
   1348 /**
   1349  * Get whether bare LF in HTTP header and other protocol elements
   1350  * should be treated as the line termination depending on the configured
   1351  * strictness level.
   1352  * RFC 9112, section 2.2
   1353  */
   1354 #define mhd_ALLOW_BARE_LF_AS_CRLF(strictness) (0 >= strictness)
   1355 
   1356 
   1357 #ifndef NDEBUG
   1358 /**
   1359  * Various debugging data
   1360  */
   1361 struct mhd_daemon_debug
   1362 {
   1363   bool net_inited;
   1364   bool net_deinited;
   1365   bool master_only_inited;
   1366   bool worker_only_inited;
   1367   bool events_fd_inited;
   1368   bool tls_inited;
   1369   bool events_allocated;
   1370   unsigned int num_events_elements;
   1371   bool events_fully_inited;
   1372   bool thread_pool_inited;
   1373   bool threading_inited;
   1374   bool connections_inited;
   1375   bool avoid_accept4;
   1376   size_t initial_lbuf_size;
   1377 };
   1378 #endif /* NDEBUG */
   1379 
   1380 
   1381 struct MHD_Daemon
   1382 {
   1383   /* General data */
   1384 
   1385   /**
   1386    * The daemon state
   1387    */
   1388   enum mhd_DaemonState state;
   1389 
   1390   /**
   1391    * The daemon work mode (private version)
   1392    */
   1393   enum mhd_WorkModeIntType wmode_int;
   1394 
   1395   /* Events/sockets monitoring/polling data */
   1396 
   1397   /**
   1398    * The data for events monitoring
   1399    */
   1400   struct mhd_DaemonEventMonitoringData events;
   1401 
   1402   /* Network/sockets data */
   1403 
   1404   /**
   1405    * The daemon network/sockets data
   1406    *
   1407    * This structure holds mostly static information -- typically initialised
   1408    * once when the daemon starts, and possibly updated once later (e.g., if the
   1409    * listening socket fails or is closed).
   1410    *
   1411    * It does NOT contain any operational states.
   1412    */
   1413   struct mhd_DaemonNetwork net;
   1414 
   1415 #ifdef MHD_SUPPORT_AUTH_DIGEST
   1416   /**
   1417    * The Digest Auth daemon's data
   1418    */
   1419   struct mhd_DaemonAuthDigestData auth_dg;
   1420 #endif /* MHD_SUPPORT_AUTH_DIGEST */
   1421 
   1422 #ifdef MHD_SUPPORT_ACME
   1423   /**
   1424    * Daemon's ACME data
   1425    */
   1426   struct mhd_DaemonAcmeData acme;
   1427 #endif /* MHD_SUPPORT_ACME */
   1428 
   1429 #ifdef MHD_SUPPORT_HTTPS
   1430   /**
   1431    * The pointer to the daemon TLS data.
   1432    * If set to non-NULL then HTTPS protocol is used, if set to NULL then
   1433    * plain HTTP protocol used.
   1434    */
   1435   struct mhd_TlsDaemonData *tls;
   1436 #endif /* MHD_SUPPORT_HTTPS */
   1437 
   1438 #ifdef MHD_SUPPORT_THREADS
   1439   /* Threading data */
   1440 
   1441   /**
   1442    * The daemon threading and Inter-Thread Communication data
   1443    */
   1444   struct mhd_DaemonThreadingData threading;
   1445 #endif
   1446 
   1447   /* Connections handling */
   1448 
   1449   /**
   1450    * The connections handling data
   1451    */
   1452   struct mhd_DaemonConnections conns;
   1453 
   1454 
   1455   /* HTTP communication layer */
   1456 #ifdef MHD_SUPPORT_HTTP2
   1457   /**
   1458    * Generic settings for HTTP layer communication handling.
   1459    *
   1460    * These settings do not include specific settings for requests processing.
   1461    */
   1462   struct mhd_DaemonHttpSettings http_cfg;
   1463 #endif /* MHD_SUPPORT_HTTP2 */
   1464 
   1465 
   1466   /* Request processing data */
   1467 
   1468   /**
   1469    * Settings for requests processing
   1470    */
   1471   struct mhd_DaemonRequestProcessingSettings req_cfg;
   1472 
   1473   /* Other data */
   1474 
   1475   /**
   1476    * Daemon logging parameters
   1477    */
   1478   struct MHD_DaemonOptionValueLog log_params;
   1479 
   1480 
   1481   /* Temporal data */
   1482 
   1483   /**
   1484    * User settings, before applied to the daemon itself
   1485    */
   1486   struct DaemonOptions *settings;
   1487 
   1488 #ifndef NDEBUG
   1489   /* Debug data */
   1490 
   1491   struct mhd_daemon_debug dbg;
   1492 #endif
   1493 };
   1494 
   1495 
   1496 #ifdef MHD_SOCKETS_KIND_POSIX
   1497 /**
   1498  * Checks whether @a fd socket number fits limitations for the @a d_ptr daemon
   1499  */
   1500 #  define mhd_FD_FITS_DAEMON(d_ptr, fd) \
   1501           ((MHD_INVALID_SOCKET == d_ptr->net.cfg.max_fd_num) || \
   1502            (d_ptr->net.cfg.max_fd_num > fd))
   1503 #else
   1504 #  define mhd_FD_FITS_DAEMON(d_ptr, fd) (! 0)
   1505 #endif
   1506 
   1507 #define mhd_D_IS_USING_EPOLL(d) \
   1508         mhd_POLL_TYPE_INT_IS_EPOLL ((d)->events.poll_type)
   1509 
   1510 #define mhd_D_IS_USING_KQUEUE(d) \
   1511         mhd_POLL_TYPE_INT_IS_KQUEUE ((d)->events.poll_type)
   1512 
   1513 #define mhd_D_POLL_IS_EDGE_TRIG(d) \
   1514         mhd_POLL_TYPE_INT_IS_EDGE_TRIG ((d)->events.poll_type)
   1515 
   1516 /**
   1517  * Check whether the daemon has edge-triggered sockets polling
   1518  */
   1519 #define mhd_D_HAS_EDGE_TRIGG(d) \
   1520         ((mhd_WM_INT_EXTERNAL_EVENTS_EDGE == (d)->wmode_int) || \
   1521          mhd_D_POLL_IS_EDGE_TRIG (d))
   1522 
   1523 #ifdef MHD_SUPPORT_THREADS
   1524 #  define mhd_D_HAS_THREADS(d) mhd_WM_INT_HAS_THREADS ((d)->wmode_int)
   1525 #else
   1526 #  define mhd_D_HAS_THREADS(d) (0)
   1527 #endif
   1528 
   1529 #ifdef MHD_SUPPORT_THREADS
   1530 #  define mhd_D_HAS_THR_PER_CONN(d) \
   1531           (mhd_WM_INT_INTERNAL_EVENTS_THREAD_PER_CONNECTION == \
   1532            ((d)->wmode_int))
   1533 #else
   1534 #  define mhd_D_HAS_THR_PER_CONN(d) (0)
   1535 #endif
   1536 
   1537 #ifdef MHD_SUPPORT_THREADS
   1538 #  define mhd_D_HAS_STOP_REQ(d)         (d->threading.stop_requested)
   1539 #else
   1540 #  define mhd_D_HAS_STOP_REQ(d)         (0)
   1541 #endif
   1542 
   1543 #define mhd_D_HAS_WORKERS(d) mhd_D_TYPE_HAS_WORKERS ((d)->threading.d_type)
   1544 
   1545 #define mhd_D_HAS_MASTER(d) mhd_D_TYPE_HAS_MASTER_DAEMON ((d)->threading.d_type)
   1546 
   1547 #define mhd_D_IS_INTERNAL_ONLY(d) \
   1548         mhd_D_TYPE_IS_INTERNAL_ONLY ((d)->threading.d_type)
   1549 
   1550 #ifdef MHD_SUPPORT_HTTPS
   1551 /**
   1552  * Returns non-zero if daemon has TLS enabled or zero otherwise
   1553  */
   1554 #  define mhd_D_HAS_TLS(d) (((d)->tls) ? (! 0) : (0))
   1555 #else
   1556 /**
   1557  * Returns non-zero if daemon has TLS enabled or zero otherwise
   1558  */
   1559 #  define mhd_D_HAS_TLS(d) (0)
   1560 #endif
   1561 
   1562 /*
   1563  * Check whether the daemon support Digest Auth
   1564  */
   1565 #ifdef MHD_SUPPORT_AUTH_DIGEST
   1566 #  define mhd_D_HAS_AUTH_DIGEST(d) (NULL != (d)->auth_dg.nonces)
   1567 #else
   1568 #  define mhd_D_HAS_AUTH_DIGEST(d) (! ! 0)
   1569 #endif
   1570 
   1571 #ifdef MHD_SUPPORT_HTTP2
   1572 #  define mhd_D_IS_HTTP1_ENABLED(d)     (d->http_cfg.http1x)
   1573 #  define mhd_D_IS_HTTP2_ENABLED(d)     (d->http_cfg.http2)
   1574 #else  /* ! MHD_SUPPORT_HTTP2 */
   1575 #  define mhd_D_IS_HTTP1_ENABLED(d)     (! 0)
   1576 #  define mhd_D_IS_HTTP2_ENABLED(d)     (! ! 0)
   1577 #endif /* ! MHD_SUPPORT_HTTP2 */
   1578 
   1579 
   1580 #endif /* ! MHD_DAEMON_H */