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