libmicrohttpd2

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

mhd_daemon.h (30891B)


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