mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
1159 lines
25 KiB
C
1159 lines
25 KiB
C
/*
|
|
This file is part of GNU libmicrohttpd
|
|
Copyright (C) 2024 Evgeny Grin (Karlson2k)
|
|
|
|
GNU libmicrohttpd is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
GNU libmicrohttpd is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
/**
|
|
* @file src/mhd2/mhd_daemon.h
|
|
* @brief The header for declaration of struct MHD_Daemon
|
|
* @author Karlson2k (Evgeny Grin)
|
|
*/
|
|
|
|
#ifndef MHD_DAEMON_H
|
|
#define MHD_DAEMON_H 1
|
|
|
|
#include "mhd_sys_options.h"
|
|
|
|
#include "sys_bool_type.h"
|
|
#include "sys_base_types.h"
|
|
|
|
#include "mhd_dlinked_list.h"
|
|
|
|
#include "mhd_buffer.h"
|
|
#include "mhd_socket_type.h"
|
|
#include "mhd_atomic_counter.h"
|
|
|
|
#ifdef MHD_SUPPORT_AUTH_DIGEST
|
|
# include "mhd_digest_auth_data.h"
|
|
#endif
|
|
|
|
#ifdef MHD_SUPPORT_HTTPS
|
|
# include "mhd_tls_choice.h"
|
|
#endif
|
|
|
|
#ifdef MHD_SUPPORT_THREADS
|
|
# include "mhd_threads.h"
|
|
# include "mhd_itc_types.h"
|
|
# include "mhd_locks.h"
|
|
#endif
|
|
|
|
#include "sys_select.h"
|
|
#include "sys_poll.h"
|
|
#ifdef MHD_SUPPORT_EPOLL
|
|
# include <sys/epoll.h>
|
|
#endif
|
|
|
|
#include "mhd_public_api.h"
|
|
|
|
struct DaemonOptions; /* Forward declaration */
|
|
struct MHD_Connection; /* Forward declaration */
|
|
|
|
/**
|
|
* The helper struct for the connections list
|
|
*/
|
|
mhd_DLINKEDL_LIST_DEF (MHD_Connection);
|
|
|
|
/**
|
|
* The current phase of the daemon life
|
|
*/
|
|
enum MHD_FIXED_ENUM_ mhd_DaemonState
|
|
{
|
|
/**
|
|
* The daemon has been created, but not yet started.
|
|
* Setting configuration options is possible.
|
|
*/
|
|
mhd_DAEMON_STATE_NOT_STARTED = 0
|
|
,
|
|
/**
|
|
* The daemon is being started.
|
|
*/
|
|
mhd_DAEMON_STATE_STARTING
|
|
,
|
|
/**
|
|
* The daemon has been started.
|
|
* Normal operations.
|
|
*/
|
|
mhd_DAEMON_STATE_STARTED
|
|
,
|
|
/**
|
|
* The daemon has failed to start
|
|
*/
|
|
mhd_DAEMON_STATE_FAILED
|
|
,
|
|
/**
|
|
* The daemon is being stopped.
|
|
*/
|
|
mhd_DAEMON_STATE_STOPPING
|
|
,
|
|
/**
|
|
* The daemon is stopped.
|
|
* The state should rarely visible as daemon should be destroyed when stopped.
|
|
*/
|
|
mhd_DAEMON_STATE_STOPPED
|
|
};
|
|
|
|
|
|
/**
|
|
* Internal version of the daemon work mode type
|
|
*/
|
|
enum MHD_FIXED_ENUM_ mhd_WorkModeIntType
|
|
{
|
|
/**
|
|
* Network edge-triggered events are monitored and provided by application.
|
|
* Receiving, sending and processing of the network data if performed when
|
|
* special MHD function is called by application.
|
|
* No threads managed by the daemon.
|
|
*/
|
|
mhd_WM_INT_EXTERNAL_EVENTS_EDGE
|
|
,
|
|
/**
|
|
* Network level-triggered events are monitored and provided by application.
|
|
* Receiving, sending and processing of the network data if performed when
|
|
* special MHD function is called by application.
|
|
* No threads managed by the daemon.
|
|
*/
|
|
mhd_WM_INT_EXTERNAL_EVENTS_LEVEL
|
|
,
|
|
/**
|
|
* The daemon checks for the network events, receives, sends and process
|
|
* the network data when special MHD function is called by application.
|
|
* No threads managed by the daemon.
|
|
*/
|
|
mhd_WM_INT_INTERNAL_EVENTS_NO_THREADS
|
|
,
|
|
/**
|
|
* The daemon runs its own single thread, where the daemon monitors
|
|
* all network events, receives, sends and process the network data.
|
|
*/
|
|
mhd_WM_INT_INTERNAL_EVENTS_ONE_THREAD
|
|
,
|
|
/**
|
|
* The daemon runs its own single thread, where the daemon monitors
|
|
* the new incoming connections, and runs individual thread for each
|
|
* established connection, where the daemon monitors connection, receives,
|
|
* sends and process the network data.
|
|
*/
|
|
mhd_WM_INT_INTERNAL_EVENTS_THREAD_PER_CONNECTION
|
|
,
|
|
/**
|
|
* The daemon runs its fixed number of threads, all threads monitors the
|
|
* new incoming connections and each thread handles own subset of the network
|
|
* connections (monitors connections network events, receives, sends and
|
|
* process the network data).
|
|
*/
|
|
mhd_WM_INT_INTERNAL_EVENTS_THREAD_POOL
|
|
};
|
|
|
|
/**
|
|
* Check whether given mhd_WorkModeIntType value should have internal threads,
|
|
* either directly controlled or indirectly, via additional workers daemons.
|
|
*/
|
|
#define mhd_WM_INT_HAS_THREADS(wm_i) \
|
|
(mhd_WM_INT_INTERNAL_EVENTS_ONE_THREAD <= wm_i)
|
|
|
|
/**
|
|
* Check whether given mhd_WorkModeIntType value has external events
|
|
*/
|
|
#define mhd_WM_INT_HAS_EXT_EVENTS(wm_i) \
|
|
(mhd_WM_INT_EXTERNAL_EVENTS_LEVEL >= wm_i)
|
|
|
|
|
|
/**
|
|
* Sockets polling internal syscalls used by MHD.
|
|
*
|
|
* The same value used as by #MHD_SockPollSyscall, however instead of "auto"
|
|
* method this enum uses "not yet set" and enum is extended with an additional
|
|
* "external" value.
|
|
*/
|
|
enum MHD_FIXED_ENUM_ mhd_IntPollType
|
|
{
|
|
/**
|
|
* External sockets polling is used.
|
|
*/
|
|
mhd_POLL_TYPE_EXT = -1
|
|
,
|
|
/**
|
|
* Internal sockets polling syscall has not been selected yet.
|
|
*/
|
|
mhd_POLL_TYPE_NOT_SET_YET = MHD_SPS_AUTO
|
|
,
|
|
/**
|
|
* Use select().
|
|
*/
|
|
mhd_POLL_TYPE_SELECT = MHD_SPS_SELECT
|
|
,
|
|
/**
|
|
* Use poll().
|
|
*/
|
|
mhd_POLL_TYPE_POLL = MHD_SPS_POLL
|
|
,
|
|
/**
|
|
* Use epoll.
|
|
*/
|
|
mhd_POLL_TYPE_EPOLL = MHD_SPS_EPOLL
|
|
};
|
|
|
|
#if defined(HAVE_UINTPTR_T)
|
|
typedef uintptr_t mhd_SockRelMarker;
|
|
#else
|
|
typedef unsigned char *mhd_SockRelMarker;
|
|
#endif
|
|
|
|
|
|
#define mhd_SOCKET_REL_MARKER_EMPTY ((mhd_SockRelMarker) 0)
|
|
|
|
#define mhd_SOCKET_REL_MARKER_ITC ((mhd_SockRelMarker) - 1)
|
|
|
|
#define mhd_SOCKET_REL_MARKER_LISTEN (mhd_SOCKET_REL_MARKER_ITC - 1)
|
|
/**
|
|
* Identifier of the FD related to event
|
|
*/
|
|
union mhd_SocketRelation
|
|
{
|
|
/**
|
|
* Identifier of the FD.
|
|
* Only valid when it is equal to #mhd_SOCKET_REL_MARKER_EMPTY,
|
|
* #mhd_SOCKET_REL_MARKER_ITC or #mhd_SOCKET_REL_MARKER_LISTEN.
|
|
*/
|
|
mhd_SockRelMarker fd_id;
|
|
/**
|
|
* This is a connection's FD.
|
|
* This is valid only when @a fd_id is not valid.
|
|
*/
|
|
struct MHD_Connection *connection;
|
|
};
|
|
|
|
#ifdef MHD_SUPPORT_SELECT
|
|
|
|
/**
|
|
* Daemon's pointers to the preallocated arrays for running sockets monitoring
|
|
* by poll().
|
|
*/
|
|
struct mhd_DaemonEventsSelectData
|
|
{
|
|
/**
|
|
* Set of sockets monitored for read (receive) readiness.
|
|
*/
|
|
fd_set *rfds;
|
|
/**
|
|
* Set of sockets monitored for write (send) readiness.
|
|
*/
|
|
fd_set *wfds;
|
|
/**
|
|
* Set of sockets monitored for exception (error) readiness.
|
|
*/
|
|
fd_set *efds;
|
|
};
|
|
|
|
#endif /* MHD_SUPPORT_SELECT */
|
|
|
|
#ifdef MHD_SUPPORT_POLL
|
|
|
|
/**
|
|
* Daemon's pointers to the preallocated arrays for running sockets monitoring
|
|
* by poll().
|
|
*/
|
|
struct mhd_DaemonEventsPollData
|
|
{
|
|
/**
|
|
* Array of sockets monitored for read (receive) readiness.
|
|
* The size of the array is maximum number of connections per this daemon plus
|
|
* two (one for the listen socket and one for ITC).
|
|
* ITC FDs and the listening are always the first (and the second), if used.
|
|
* The number of elements is always two plus maximum number of connections
|
|
* allowed for the daemon.
|
|
*/
|
|
struct pollfd *fds;
|
|
/**
|
|
* Array of the @a fds identifications.
|
|
* Each slot matches the slot with the same number in @a fds.
|
|
* Up to two first positions reserved for the ITC and the listening.
|
|
* The number of elements is always two plus maximum number of connections
|
|
* allowed for the daemon.
|
|
*/
|
|
union mhd_SocketRelation *rel;
|
|
};
|
|
|
|
#endif /* MHD_SUPPORT_POLL */
|
|
|
|
#ifdef MHD_SUPPORT_EPOLL
|
|
/**
|
|
* Daemon's parameters and pointers to the preallocated memory for running
|
|
* sockets monitoring by epoll.
|
|
*/
|
|
struct mhd_DaemonEventsEPollData
|
|
{
|
|
/**
|
|
* The epoll control FD.
|
|
*/
|
|
int e_fd;
|
|
/**
|
|
* The array of events reported by epoll.
|
|
*/
|
|
struct epoll_event *events;
|
|
|
|
/**
|
|
* The number of elements in the allocated @a events arrays.
|
|
*/
|
|
size_t num_elements;
|
|
};
|
|
|
|
#endif
|
|
|
|
/**
|
|
* Daemon's data for external events for sockets monitoring.
|
|
* Internal version of struct MHD_WorkModeExternalEventLoopCBParam.
|
|
*/
|
|
struct mhd_DaemonEventsExternal
|
|
{
|
|
/**
|
|
* Socket registration callback
|
|
*/
|
|
MHD_SocketRegistrationUpdateCallback cb;
|
|
/**
|
|
* Closure for the @a cb
|
|
*/
|
|
void *cls;
|
|
};
|
|
|
|
/**
|
|
* Type-specific events monitoring data
|
|
*/
|
|
union mhd_DaemonEventMonitoringTypeSpecificData
|
|
{
|
|
#ifdef MHD_SUPPORT_SELECT
|
|
/**
|
|
* Daemon's pointers to the preallocated arrays for running sockets monitoring
|
|
* by poll().
|
|
*/
|
|
struct mhd_DaemonEventsSelectData select;
|
|
#endif /* MHD_SUPPORT_SELECT */
|
|
|
|
#ifdef MHD_SUPPORT_POLL
|
|
/**
|
|
* Daemon's pointers to the preallocated arrays for running sockets monitoring
|
|
* by poll().
|
|
*/
|
|
struct mhd_DaemonEventsPollData poll;
|
|
#endif /* MHD_SUPPORT_POLL */
|
|
|
|
#ifdef MHD_SUPPORT_EPOLL
|
|
/**
|
|
* Daemon's parameters and pointers to the preallocated memory for running
|
|
* sockets monitoring by epoll.
|
|
*/
|
|
struct mhd_DaemonEventsEPollData epoll;
|
|
#endif
|
|
|
|
/**
|
|
* Daemon's data for external events for sockets monitoring.
|
|
* Internal version of struct MHD_WorkModeExternalEventLoopCBParam.
|
|
*/
|
|
struct mhd_DaemonEventsExternal ext;
|
|
};
|
|
|
|
|
|
/**
|
|
* The required actions for the daemon
|
|
*/
|
|
struct mhd_DaemonEventActionRequired
|
|
{
|
|
/**
|
|
* If 'true' then connection is waiting to be accepted
|
|
*/
|
|
bool accept;
|
|
};
|
|
|
|
|
|
/**
|
|
* The data for events monitoring
|
|
*/
|
|
struct mhd_DaemonEventMonitoringData
|
|
{
|
|
/**
|
|
* Sockets polling type used by the daemon.
|
|
*/
|
|
enum mhd_IntPollType poll_type;
|
|
|
|
/**
|
|
* Type-specific events monitoring data
|
|
*/
|
|
union mhd_DaemonEventMonitoringTypeSpecificData data;
|
|
|
|
/**
|
|
* The required actions for the daemon.
|
|
* If daemon has internal thread, this should be changed only inside
|
|
* the daemon's thread.
|
|
*/
|
|
struct mhd_DaemonEventActionRequired act_req;
|
|
|
|
/**
|
|
* Indicate that daemon already has some data to be processed on the next
|
|
* cycle
|
|
*/
|
|
bool zero_wait;
|
|
|
|
/**
|
|
* The list of the daemon's connections that need processing
|
|
*/
|
|
mhd_DLNKDL_LIST (MHD_Connection,proc_ready);
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* The type of the socket
|
|
*/
|
|
enum MHD_FIXED_ENUM_ mhd_SocketType
|
|
{
|
|
/**
|
|
* The socket type is some non-IP type.
|
|
*/
|
|
mhd_SOCKET_TYPE_NON_IP = -2
|
|
,
|
|
/**
|
|
* The socket type is UNIX (LOCAL)
|
|
*/
|
|
mhd_SOCKET_TYPE_UNIX = -1
|
|
,
|
|
/**
|
|
* The socket is unknown yet. It can be IP or non-IP.
|
|
*/
|
|
mhd_SOCKET_TYPE_UNKNOWN = 0
|
|
,
|
|
/**
|
|
* The socket is definitely IP.
|
|
*/
|
|
mhd_SOCKET_TYPE_IP = 1
|
|
};
|
|
|
|
/**
|
|
* Listen socket data
|
|
*/
|
|
struct mhd_ListenSocket
|
|
{
|
|
/**
|
|
* The listening socket
|
|
*/
|
|
MHD_Socket fd;
|
|
/**
|
|
* The type of the listening socket @a fd
|
|
*/
|
|
enum mhd_SocketType type;
|
|
/**
|
|
* 'true' if @a fd is non-blocking
|
|
*/
|
|
bool non_block;
|
|
/**
|
|
* The port number for @a fd
|
|
*
|
|
* Zero if unknown and for non-IP socket.
|
|
*/
|
|
uint_least16_t port;
|
|
};
|
|
|
|
/**
|
|
* Configured settings for the daemon's network data
|
|
*/
|
|
struct mhd_DaemonNetworkSettings
|
|
{
|
|
#ifdef MHD_SOCKETS_KIND_POSIX
|
|
/**
|
|
* The maximum number for the network FDs.
|
|
* The valid FD number must be less then @a max_fd_num.
|
|
*/
|
|
MHD_Socket max_fd_num;
|
|
#else
|
|
int dummy; /* mute compiler warning */
|
|
#endif
|
|
};
|
|
|
|
/**
|
|
* The daemon network/sockets data
|
|
*/
|
|
struct mhd_DaemonNetwork
|
|
{
|
|
/**
|
|
* The listening socket
|
|
*/
|
|
struct mhd_ListenSocket listen;
|
|
|
|
#ifdef MHD_SUPPORT_EPOLL
|
|
/**
|
|
* The epoll FD.
|
|
* Set to '-1' when epoll is not used.
|
|
*/
|
|
int epoll_fd;
|
|
#endif
|
|
/**
|
|
* Configured settings for the daemon's network data
|
|
*/
|
|
struct mhd_DaemonNetworkSettings cfg;
|
|
};
|
|
|
|
#ifdef MHD_SUPPORT_AUTH_DIGEST
|
|
|
|
/**
|
|
* Digest Auth nonce data
|
|
*/
|
|
struct mhd_DaemonAuthDigestNonceData
|
|
{
|
|
/**
|
|
* The nonce value in the binary form, excluding validity tail
|
|
*/
|
|
uint8_t nonce[mhd_AUTH_DIGEST_NONCE_RAND_BIN_SIZE];
|
|
|
|
/**
|
|
* The nonce validity time
|
|
*/
|
|
uint_fast32_t valid_time;
|
|
|
|
/**
|
|
* The largest last received 'nc' value.
|
|
* This 'nc' value has been already used by the client.
|
|
*/
|
|
uint_fast32_t max_recvd_nc;
|
|
|
|
/**
|
|
* Bitmask over the previous 64 nc values (down to to nc-64).
|
|
* Used to allow out-of-order 'nc'.
|
|
* If bit in the bitmask is set to one, then this 'nc' value was already used
|
|
* by the client.
|
|
*/
|
|
uint_fast64_t nmask;
|
|
};
|
|
|
|
/**
|
|
* Digest Auth daemon configuration data
|
|
*/
|
|
struct mhd_DaemonAuthDigestCfg
|
|
{
|
|
/**
|
|
* The number of elements in the nonces array
|
|
*/
|
|
size_t nonces_num;
|
|
|
|
/**
|
|
* The nonce validity time (in seconds)
|
|
*/
|
|
unsigned int nonce_tmout;
|
|
|
|
/**
|
|
* The default maximum value of nc
|
|
*/
|
|
uint_fast32_t def_max_nc;
|
|
};
|
|
|
|
/**
|
|
* The Digest Auth daemon's data
|
|
*/
|
|
struct mhd_DaemonAuthDigestData
|
|
{
|
|
/**
|
|
* The entropy data used for Digests generation
|
|
*/
|
|
struct mhd_Buffer entropy;
|
|
|
|
/**
|
|
* The array of generated nonce and related nc
|
|
*/
|
|
struct mhd_DaemonAuthDigestNonceData *nonces;
|
|
|
|
/**
|
|
* Number of nonces has been generated.
|
|
* Used as addition for the nonce source data to ensure unique nonce value.
|
|
* TODO: remove and directly use random generator for nonce generation.
|
|
*/
|
|
struct mhd_AtomicCounter num_gen_nonces;
|
|
|
|
#ifdef MHD_SUPPORT_THREADS
|
|
/**
|
|
* The mutex to change or access the @a nonces data
|
|
*/
|
|
mhd_mutex nonces_lock;
|
|
#endif
|
|
|
|
/**
|
|
* Digest Auth daemon configuration data
|
|
*/
|
|
struct mhd_DaemonAuthDigestCfg cfg;
|
|
};
|
|
|
|
#endif /* MHD_SUPPORT_AUTH_DIGEST */
|
|
|
|
#ifdef MHD_SUPPORT_THREADS
|
|
|
|
/**
|
|
* The type of the daemon
|
|
*/
|
|
enum MHD_FIXED_ENUM_ mhd_DaemonType
|
|
{
|
|
/**
|
|
* A single daemon, performing all the work.
|
|
*
|
|
* This daemon may have a optional single thread, managed by MHD.
|
|
*/
|
|
mhd_DAEMON_TYPE_SINGLE
|
|
#ifndef NDEBUG
|
|
= 1
|
|
#endif
|
|
,
|
|
/**
|
|
* A master daemon, only controlling worker daemons.
|
|
*
|
|
* This daemon never handle any network activity directly.
|
|
*/
|
|
mhd_DAEMON_TYPE_MASTER_CONTROL_ONLY
|
|
,
|
|
/**
|
|
* A daemon with single internal thread for listening and multiple threads
|
|
* handling connections with the clients, one thread per connection.
|
|
*/
|
|
mhd_DAEMON_TYPE_LISTEN_ONLY
|
|
,
|
|
/**
|
|
* A worker daemon, performing the same work as a single daemon, but
|
|
* controlled by master daemon.
|
|
*
|
|
* This type of daemon always have single internal tread and never exposed
|
|
* to application directly.
|
|
*/
|
|
mhd_DAEMON_TYPE_WORKER
|
|
};
|
|
|
|
/**
|
|
* Check whether the daemon type is allowed to have internal thread with
|
|
* direct control
|
|
*/
|
|
#define mhd_D_TYPE_IS_VALID(t) \
|
|
((mhd_DAEMON_TYPE_SINGLE <= (t)) && (mhd_DAEMON_TYPE_WORKER >= (t)))
|
|
|
|
/**
|
|
* Check whether the daemon type must not be exposed to the application
|
|
*/
|
|
#define mhd_D_TYPE_IS_INTERNAL_ONLY(t) \
|
|
(mhd_DAEMON_TYPE_WORKER == (t))
|
|
|
|
/**
|
|
* Check whether the daemon type is allowed to process the network data
|
|
*/
|
|
#define mhd_D_TYPE_HAS_EVENTS_PROCESSING(t) \
|
|
(mhd_DAEMON_TYPE_MASTER_CONTROL_ONLY != (t))
|
|
|
|
/**
|
|
* Check whether the daemon type must not be exposed to the application
|
|
*/
|
|
#define mhd_D_TYPE_HAS_WORKERS(t) \
|
|
(mhd_DAEMON_TYPE_MASTER_CONTROL_ONLY == (t))
|
|
|
|
/**
|
|
* Check whether the daemon type has master (controlling) daemon
|
|
*/
|
|
#define mhd_D_TYPE_HAS_MASTER_DAEMON(t) \
|
|
(mhd_DAEMON_TYPE_WORKER == (t))
|
|
|
|
#else /* ! MHD_SUPPORT_THREADS */
|
|
|
|
/**
|
|
* Check whether the daemon type is allowed to have internal thread with
|
|
* direct control
|
|
*/
|
|
#define mhd_D_TYPE_IS_VALID(t) (! 0)
|
|
|
|
/**
|
|
* Check whether the daemon type must not be exposed to the application
|
|
*/
|
|
#define mhd_D_TYPE_IS_INTERNAL_ONLY(t) (0)
|
|
|
|
/**
|
|
* Check whether the daemon type is allowed to process the network data
|
|
*/
|
|
#define mhd_D_TYPE_HAS_EVENTS_PROCESSING(t) (! 0)
|
|
|
|
/**
|
|
* Check whether the daemon type must not be exposed to the application
|
|
*/
|
|
#define mhd_D_TYPE_HAS_WORKERS(t) (0)
|
|
|
|
/**
|
|
* Check whether the daemon type has master (controlling) daemon
|
|
*/
|
|
#define mhd_D_TYPE_HAS_MASTER_DAEMON(t) (0)
|
|
|
|
#endif /* ! MHD_SUPPORT_THREADS */
|
|
|
|
#ifdef MHD_SUPPORT_THREADS
|
|
|
|
/**
|
|
* Workers pool data
|
|
*/
|
|
struct mhd_DaemonWorkerPoolData
|
|
{
|
|
/**
|
|
* Array of worker daemons
|
|
*/
|
|
struct MHD_Daemon *workers;
|
|
|
|
/**
|
|
* The number of workers in the @a workers array
|
|
*/
|
|
unsigned int num;
|
|
};
|
|
|
|
/**
|
|
* Hierarchy data for the daemon
|
|
*/
|
|
union mhd_DeamonHierarchyData
|
|
{
|
|
/**
|
|
* The pointer to the master daemon
|
|
* Only for #mhd_DAEMON_TYPE_WORKER daemons.
|
|
*/
|
|
struct MHD_Daemon *master;
|
|
|
|
/**
|
|
* Workers pool data.
|
|
* Only for #mhd_DAEMON_TYPE_MASTER_CONTROL_ONLY daemons.
|
|
*/
|
|
struct mhd_DaemonWorkerPoolData pool;
|
|
};
|
|
|
|
/**
|
|
* Configured settings for threading
|
|
*/
|
|
struct mhd_DaemonThreadingDataSettings
|
|
{
|
|
/**
|
|
* The size of the stack.
|
|
* Zero to use system's defaults.
|
|
*/
|
|
size_t stack_size;
|
|
};
|
|
|
|
/**
|
|
* Threading and Inter-Thread Communication data
|
|
*/
|
|
struct mhd_DaemonThreadingData
|
|
{
|
|
/**
|
|
* The type of this daemon
|
|
*/
|
|
enum mhd_DaemonType d_type;
|
|
|
|
/**
|
|
* Inter-Thread Communication channel.
|
|
* Used to trigger processing of the command or the data provided or updated
|
|
* by the application.
|
|
*/
|
|
struct mhd_itc itc;
|
|
|
|
/**
|
|
* 'True' if stop has been requested.
|
|
* The daemon thread should stop all connections and then close.
|
|
*/
|
|
volatile bool stop_requested;
|
|
|
|
/**
|
|
* 'True' if resuming of any connection has been requested.
|
|
*/
|
|
volatile bool resume_requested;
|
|
|
|
/**
|
|
* The handle of the daemon's thread (if managed by the daemon)
|
|
*/
|
|
mhd_thread_handle_ID tid;
|
|
|
|
/**
|
|
* The hierarchy data for the daemon.
|
|
* Used only when @a d_type is #mhd_DAEMON_TYPE_MASTER_CONTROL_ONLY or
|
|
* #mhd_DAEMON_TYPE_WORKER.
|
|
*/
|
|
union mhd_DeamonHierarchyData hier;
|
|
|
|
/**
|
|
* Configured settings for threading
|
|
*/
|
|
struct mhd_DaemonThreadingDataSettings cfg;
|
|
};
|
|
|
|
#endif /* MHD_SUPPORT_THREADS */
|
|
|
|
/**
|
|
* Configured settings for the daemon's connections
|
|
*/
|
|
struct mhd_DaemonConnectionsSettings
|
|
{
|
|
/**
|
|
* The maximum number of connections handled by the daemon
|
|
*/
|
|
unsigned int count_limit;
|
|
|
|
/**
|
|
* Connection's default timeout value (in seconds)
|
|
*/
|
|
unsigned int timeout;
|
|
|
|
/**
|
|
* Connection's memory pool size
|
|
*/
|
|
size_t mem_pool_size;
|
|
};
|
|
|
|
#ifdef MHD_SUPPORT_UPGRADE
|
|
|
|
/**
|
|
* The data for HTTP-Upgraded connections
|
|
*/
|
|
struct mhd_DaemonConnectionsUpgraded
|
|
{
|
|
/**
|
|
* The list of HTTP-Upgraded connection closed by application and
|
|
* queued for cleanup
|
|
*/
|
|
mhd_DLNKDL_LIST (MHD_Connection,upgr_cleanup);
|
|
|
|
#ifdef MHD_SUPPORT_THREADS
|
|
/**
|
|
* The mutex to change or check the @a upgr_cleanup list values
|
|
*/
|
|
mhd_mutex ucu_lock;
|
|
#endif
|
|
};
|
|
|
|
#endif /* MHD_SUPPORT_UPGRADE */
|
|
|
|
/**
|
|
* Connections handling data
|
|
*/
|
|
struct mhd_DaemonConnections
|
|
{
|
|
|
|
/**
|
|
* The list of all daemon's connections.
|
|
* All connection are listed here, expect connection in @a to_clean list.
|
|
*/
|
|
mhd_DLNKDL_LIST (MHD_Connection,all_conn);
|
|
|
|
/**
|
|
* The list of connections sorted by last activity
|
|
*/
|
|
mhd_DLNKDL_LIST (MHD_Connection,def_timeout);
|
|
|
|
/**
|
|
* The list of connections with custom timeouts
|
|
*/
|
|
mhd_DLNKDL_LIST (MHD_Connection,cust_timeout);
|
|
|
|
/**
|
|
* The current number of connections handled by the daemon
|
|
*/
|
|
unsigned int count;
|
|
|
|
/**
|
|
* If set to 'true' then no new connection is allowed.
|
|
* New connection may be blocked because of various system limits, when
|
|
* additional connection would fail anyway. This flag should be cleared
|
|
* when any already processing connection closed.
|
|
* Can be checked from other threads
|
|
*/
|
|
volatile bool block_new;
|
|
|
|
/**
|
|
* Configured settings for the daemon's connections
|
|
*/
|
|
struct mhd_DaemonConnectionsSettings cfg;
|
|
|
|
#ifdef MHD_SUPPORT_UPGRADE
|
|
/**
|
|
* The data for HTTP-Upgraded connections
|
|
*/
|
|
struct mhd_DaemonConnectionsUpgraded upgr;
|
|
#endif /* MHD_SUPPORT_UPGRADE */
|
|
};
|
|
|
|
/**
|
|
* Early URI callback
|
|
*/
|
|
struct mhd_DaemonRequestUriCB
|
|
{
|
|
/**
|
|
* The callback
|
|
*/
|
|
MHD_EarlyUriLogCallback cb;
|
|
/**
|
|
* The callback closure
|
|
*/
|
|
void *cls;
|
|
};
|
|
|
|
/**
|
|
* Shared large buffer data
|
|
*/
|
|
struct mhd_DeamonLargeBuffer
|
|
{
|
|
/**
|
|
* The amount of memory left allowed to be allocated for the large buffer
|
|
*/
|
|
size_t space_left;
|
|
|
|
#ifdef MHD_SUPPORT_THREADS
|
|
/**
|
|
* The mutex to change or check the @a space_left value
|
|
*/
|
|
mhd_mutex lock;
|
|
#endif
|
|
};
|
|
|
|
/**
|
|
* Settings for requests processing
|
|
*/
|
|
struct mhd_DaemonRequestProcessingSettings
|
|
{
|
|
/**
|
|
* Request callback.
|
|
* The main request processing callback.
|
|
*/
|
|
MHD_RequestCallback cb;
|
|
|
|
/**
|
|
* The closure for @a req_cb
|
|
*/
|
|
void *cb_cls;
|
|
|
|
/**
|
|
* Protocol strictness enforced by MHD on clients.
|
|
*/
|
|
enum MHD_ProtocolStrictLevel strictness;
|
|
|
|
#ifdef MHD_SUPPORT_COOKIES
|
|
/**
|
|
* Disable automatic cookies parsing
|
|
*/
|
|
bool disable_cookies;
|
|
#endif
|
|
|
|
/**
|
|
* Early URI callback
|
|
*/
|
|
struct mhd_DaemonRequestUriCB uri_cb; // TODO: set from settings
|
|
|
|
/**
|
|
* Shared large buffer data
|
|
*/
|
|
struct mhd_DeamonLargeBuffer large_buf; // TODO: set from settings
|
|
|
|
/**
|
|
* Suppress "Date:" header in responses
|
|
*/
|
|
bool suppress_date;
|
|
};
|
|
|
|
|
|
/**
|
|
* Get whether bare LF in HTTP header and other protocol elements
|
|
* should be treated as the line termination depending on the configured
|
|
* strictness level.
|
|
* RFC 9112, section 2.2
|
|
*/
|
|
#define mhd_ALLOW_BARE_LF_AS_CRLF(strictness) (0 >= strictness)
|
|
|
|
|
|
#ifndef NDEBUG
|
|
/**
|
|
* Various debugging data
|
|
*/
|
|
struct mhd_daemon_debug
|
|
{
|
|
bool net_inited;
|
|
bool net_deinited;
|
|
bool tls_inited;
|
|
bool events_allocated;
|
|
unsigned int num_events_elements;
|
|
bool events_fully_inited;
|
|
bool thread_pool_inited;
|
|
bool threading_inited;
|
|
bool connections_inited;
|
|
bool avoid_accept4;
|
|
size_t initial_lbuf_size;
|
|
};
|
|
#endif /* NDEBUG */
|
|
|
|
|
|
struct MHD_Daemon
|
|
{
|
|
/* General data */
|
|
|
|
/**
|
|
* The daemon state
|
|
*/
|
|
enum mhd_DaemonState state;
|
|
|
|
/**
|
|
* The daemon work mode (private version)
|
|
*/
|
|
enum mhd_WorkModeIntType wmode_int;
|
|
|
|
/* Events/sockets monitoring/polling data */
|
|
|
|
/**
|
|
* The data for events monitoring
|
|
*/
|
|
struct mhd_DaemonEventMonitoringData events;
|
|
|
|
/* Network/sockets data */
|
|
|
|
/**
|
|
* The daemon network/sockets data
|
|
*/
|
|
struct mhd_DaemonNetwork net;
|
|
|
|
#ifdef MHD_SUPPORT_AUTH_DIGEST
|
|
/**
|
|
* The Digest Auth daemon's data
|
|
*/
|
|
struct mhd_DaemonAuthDigestData auth_dg;
|
|
#endif /* MHD_SUPPORT_AUTH_DIGEST */
|
|
|
|
#ifdef MHD_SUPPORT_HTTPS
|
|
/**
|
|
* The pointer to the daemon TLS data.
|
|
* If set to non-NULL then HTTPS protocol is used, if set to NULL then
|
|
* plain HTTP protocol used.
|
|
*/
|
|
struct mhd_TlsDaemonData *tls;
|
|
#endif
|
|
|
|
#ifdef MHD_SUPPORT_THREADS
|
|
/* Threading data */
|
|
|
|
/**
|
|
* The daemon threading and Inter-Thread Communication data
|
|
*/
|
|
struct mhd_DaemonThreadingData threading;
|
|
#endif
|
|
|
|
/* Connections handling */
|
|
|
|
/**
|
|
* The connections handling data
|
|
*/
|
|
struct mhd_DaemonConnections conns;
|
|
|
|
/* Request processing data */
|
|
|
|
/**
|
|
* Settings for requests processing
|
|
*/
|
|
struct mhd_DaemonRequestProcessingSettings req_cfg;
|
|
|
|
/* Other data */
|
|
|
|
/**
|
|
* Daemon logging parameters
|
|
*/
|
|
struct MHD_DaemonOptionValueLog log_params;
|
|
|
|
|
|
/* Temporal data */
|
|
|
|
/**
|
|
* User settings, before applied to the daemon itself
|
|
*/
|
|
struct DaemonOptions *settings;
|
|
|
|
#ifndef NDEBUG
|
|
/* Debug data */
|
|
|
|
struct mhd_daemon_debug dbg;
|
|
#endif
|
|
};
|
|
|
|
|
|
#ifdef MHD_SOCKETS_KIND_POSIX
|
|
/**
|
|
* Checks whether @a fd socket number fits limitations for the @a d_ptr daemon
|
|
*/
|
|
# define mhd_FD_FITS_DAEMON(d_ptr,fd) \
|
|
((MHD_INVALID_SOCKET == d_ptr->net.cfg.max_fd_num) || \
|
|
(d_ptr->net.cfg.max_fd_num > fd))
|
|
#else
|
|
# define mhd_FD_FITS_DAEMON(d_ptr,fd) (! 0)
|
|
#endif
|
|
|
|
#ifdef MHD_SUPPORT_EPOLL
|
|
# define mhd_D_IS_USING_EPOLL(d) \
|
|
(mhd_POLL_TYPE_EPOLL == ((d)->events.poll_type))
|
|
#else
|
|
# define mhd_D_IS_USING_EPOLL(d) (0)
|
|
#endif
|
|
|
|
/**
|
|
* Check whether the daemon has edge-triggered sockets polling
|
|
*/
|
|
#define mhd_D_HAS_EDGE_TRIGG(d) \
|
|
((mhd_WM_INT_EXTERNAL_EVENTS_EDGE == (d)->wmode_int) || \
|
|
mhd_D_IS_USING_EPOLL (d))
|
|
|
|
#ifdef MHD_SUPPORT_THREADS
|
|
# define mhd_D_HAS_THREADS(d) mhd_WM_INT_HAS_THREADS ((d)->wmode_int)
|
|
#else
|
|
# define mhd_D_HAS_THREADS(d) (0)
|
|
#endif
|
|
|
|
#ifdef MHD_SUPPORT_THREADS
|
|
# define mhd_D_HAS_THR_PER_CONN(d) \
|
|
(mhd_WM_INT_INTERNAL_EVENTS_THREAD_PER_CONNECTION == \
|
|
((d)->wmode_int))
|
|
#else
|
|
# define mhd_D_HAS_THR_PER_CONN(d) (0)
|
|
#endif
|
|
|
|
#define mhd_D_HAS_WORKERS(d) mhd_D_TYPE_HAS_WORKERS ((d)->threading.d_type)
|
|
|
|
#define mhd_D_HAS_MASTER(d) mhd_D_TYPE_HAS_MASTER_DAEMON ((d)->threading.d_type)
|
|
|
|
#define mhd_D_IS_INTERNAL_ONLY(d) \
|
|
mhd_D_TYPE_IS_INTERNAL_ONLY ((d)->threading.d_type)
|
|
|
|
#define mhd_D_IS_USING_EDGE_TRIG(d) \
|
|
(mhd_D_IS_USING_EPOLL (d) || \
|
|
(mhd_WM_INT_EXTERNAL_EVENTS_EDGE ==((d)->wmode_int)))
|
|
|
|
#ifdef MHD_SUPPORT_HTTPS
|
|
/**
|
|
* Returns non-zero if daemon has TLS enabled or zero otherwise
|
|
*/
|
|
# define mhd_D_HAS_TLS(d) (((d)->tls) ? (! 0) : (0))
|
|
#else
|
|
/**
|
|
* Returns non-zero if daemon has TLS enabled or zero otherwise
|
|
*/
|
|
# define mhd_D_HAS_TLS(d) (0)
|
|
#endif
|
|
|
|
/*
|
|
* Check whether the daemon support Digest Auth
|
|
*/
|
|
#ifdef MHD_SUPPORT_AUTH_DIGEST
|
|
# define mhd_D_HAS_AUTH_DIGEST(d) (NULL != (d)->auth_dg.nonces)
|
|
#else
|
|
# define mhd_D_HAS_AUTH_DIGEST(d) (! ! 0)
|
|
#endif
|
|
|
|
#endif /* ! MHD_DAEMON_H */
|