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