1 /* 2 * libwebsockets - small server side websockets and web server implementation 3 * 4 * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 */ 24 25 #if !defined(__LWS_PRIVATE_LIB_CORE_H__) 26 #define __LWS_PRIVATE_LIB_CORE_H__ 27 28 #include "lws_config.h" 29 #include "lws_config_private.h" 30 31 32 #if defined(LWS_WITH_CGI) && defined(LWS_HAVE_VFORK) && \ 33 !defined(NO_GNU_SOURCE_THIS_TIME) && !defined(_GNU_SOURCE) 34 #define _GNU_SOURCE 35 #endif 36 37 /* 38 #if !defined(_POSIX_C_SOURCE) 39 #define _POSIX_C_SOURCE 200112L 40 #endif 41 */ 42 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <time.h> 47 #include <ctype.h> 48 #include <limits.h> 49 #include <stdarg.h> 50 #include <errno.h> 51 52 #ifdef LWS_HAVE_INTTYPES_H 53 #include <inttypes.h> 54 #endif 55 56 #include <assert.h> 57 58 #ifdef LWS_HAVE_SYS_TYPES_H 59 #include <sys/types.h> 60 #endif 61 #if defined(LWS_HAVE_SYS_STAT_H) && !defined(LWS_PLAT_OPTEE) 62 #include <sys/stat.h> 63 #endif 64 65 #if LWS_MAX_SMP > 1 || defined(LWS_WITH_SYS_SMD) 66 /* https://stackoverflow.com/questions/33557506/timespec-redefinition-error */ 67 #define HAVE_STRUCT_TIMESPEC 68 #include <pthread.h> 69 #else 70 #if !defined(pid_t) && defined(WIN32) 71 #define pid_t int 72 #endif 73 #endif 74 75 #ifndef LWS_DEF_HEADER_LEN 76 #define LWS_DEF_HEADER_LEN 4096 77 #endif 78 #ifndef LWS_DEF_HEADER_POOL 79 #define LWS_DEF_HEADER_POOL 4 80 #endif 81 #ifndef LWS_MAX_PROTOCOLS 82 #define LWS_MAX_PROTOCOLS 5 83 #endif 84 #ifndef LWS_MAX_EXTENSIONS_ACTIVE 85 #define LWS_MAX_EXTENSIONS_ACTIVE 1 86 #endif 87 #ifndef LWS_MAX_EXT_OFFERS 88 #define LWS_MAX_EXT_OFFERS 8 89 #endif 90 #ifndef SPEC_LATEST_SUPPORTED 91 #define SPEC_LATEST_SUPPORTED 13 92 #endif 93 #ifndef CIPHERS_LIST_STRING 94 #define CIPHERS_LIST_STRING "DEFAULT" 95 #endif 96 #ifndef LWS_SOMAXCONN 97 #define LWS_SOMAXCONN SOMAXCONN 98 #endif 99 100 #define MAX_WEBSOCKET_04_KEY_LEN 128 101 102 #ifndef SYSTEM_RANDOM_FILEPATH 103 #define SYSTEM_RANDOM_FILEPATH "/dev/urandom" 104 #endif 105 106 #define LWS_H2_RX_SCRATCH_SIZE 512 107 108 #define lws_socket_is_valid(x) (x != LWS_SOCK_INVALID) 109 110 #ifndef LWS_HAVE_STRERROR 111 #define strerror(x) "" 112 #endif 113 114 /* 115 * 116 * ------ private platform defines ------ 117 * 118 */ 119 120 #if defined(LWS_PLAT_FREERTOS) 121 #include "private-lib-plat-freertos.h" 122 #else 123 #if defined(WIN32) || defined(_WIN32) 124 #include "private-lib-plat-windows.h" 125 #else 126 #if defined(LWS_PLAT_OPTEE) 127 #include "private-lib-plat.h" 128 #else 129 #include "private-lib-plat-unix.h" 130 #endif 131 #endif 132 #endif 133 134 /* 135 * 136 * ------ public api ------ 137 * 138 */ 139 140 #include "libwebsockets.h" 141 142 /* 143 * lws_dsh 144 */ 145 146 typedef struct lws_dsh_obj_head { 147 lws_dll2_owner_t owner; 148 size_t total_size; /* for this kind in dsh */ 149 int kind; 150 } lws_dsh_obj_head_t; 151 152 typedef struct lws_dsh_obj { 153 lws_dll2_t list; /* must be first */ 154 struct lws_dsh *dsh; /* invalid when on free list */ 155 size_t size; /* invalid when on free list */ 156 size_t asize; 157 int kind; /* so we can account at free */ 158 } lws_dsh_obj_t; 159 160 typedef struct lws_dsh { 161 lws_dll2_t list; 162 uint8_t *buf; 163 lws_dsh_obj_head_t *oha; /* array of object heads/kind */ 164 size_t buffer_size; 165 size_t locally_in_use; 166 size_t locally_free; 167 int count_kinds; 168 uint8_t being_destroyed; 169 /* 170 * Overallocations at create: 171 * 172 * - the buffer itself 173 * - the object heads array 174 */ 175 } lws_dsh_t; 176 177 /* 178 * 179 * ------ lifecycle defines ------ 180 * 181 */ 182 183 typedef struct lws_lifecycle_group { 184 lws_dll2_owner_t owner; /* active count / list */ 185 uint64_t ordinal; /* monotonic uid count */ 186 const char *tag_prefix; /* eg, "wsi" */ 187 } lws_lifecycle_group_t; 188 189 typedef struct lws_lifecycle { 190 #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API) 191 /* we append parent streams on the tag */ 192 char gutag[96]; /* object unique tag + relationship info */ 193 #else 194 char gutag[64]; 195 #endif 196 lws_dll2_t list; /* group list membership */ 197 uint64_t us_creation; /* creation timestamp */ 198 lws_log_cx_t *log_cx; 199 } lws_lifecycle_t; 200 201 void 202 __lws_lc_tag(struct lws_context *cx, lws_lifecycle_group_t *grp, 203 lws_lifecycle_t *lc, const char *format, ...); 204 205 void 206 __lws_lc_tag_append(lws_lifecycle_t *lc, const char *app); 207 208 void 209 __lws_lc_untag(struct lws_context *cx, lws_lifecycle_t *lc); 210 211 const char * 212 lws_lc_tag(lws_lifecycle_t *lc); 213 214 extern lws_log_cx_t log_cx; 215 216 /* 217 * Generic bidi tx credit management 218 */ 219 220 struct lws_tx_credit { 221 int32_t tx_cr; /* our credit to write peer */ 222 int32_t peer_tx_cr_est; /* peer's credit to write us */ 223 224 int32_t manual_initial_tx_credit; 225 226 uint8_t skint; /* unable to write anything */ 227 uint8_t manual; 228 }; 229 230 #ifdef LWS_WITH_IPV6 231 #if defined(WIN32) || defined(_WIN32) 232 #include <iphlpapi.h> 233 #else 234 #include <net/if.h> 235 #endif 236 #endif 237 238 #undef X509_NAME 239 240 /* 241 * All lws_tls...() functions must return this type, converting the 242 * native backend result and doing the extra work to determine which one 243 * as needed. 244 * 245 * Native TLS backend return codes are NOT ALLOWED outside the backend. 246 * 247 * Non-SSL mode also uses these types. 248 */ 249 enum lws_ssl_capable_status { 250 LWS_SSL_CAPABLE_ERROR = -1, /* it failed */ 251 LWS_SSL_CAPABLE_DONE = 0, /* it succeeded */ 252 LWS_SSL_CAPABLE_MORE_SERVICE_READ = -2, /* retry WANT_READ */ 253 LWS_SSL_CAPABLE_MORE_SERVICE_WRITE = -3, /* retry WANT_WRITE */ 254 LWS_SSL_CAPABLE_MORE_SERVICE = -4, /* general retry */ 255 }; 256 257 enum lws_context_destroy { 258 LWSCD_NO_DESTROY, /* running */ 259 LWSCD_PT_WAS_DEFERRED, /* destroy from inside service */ 260 LWSCD_PT_WAIT_ALL_DESTROYED, /* libuv ends up here later */ 261 LWSCD_FINALIZATION /* the final destruction of context */ 262 }; 263 264 #if defined(LWS_WITH_TLS) 265 #include "private-lib-tls.h" 266 #endif 267 268 #if defined(WIN32) || defined(_WIN32) 269 // Visual studio older than 2015 and WIN_CE has only _stricmp 270 #if (defined(_MSC_VER) && _MSC_VER < 1900) || defined(_WIN32_WCE) 271 #define strcasecmp _stricmp 272 #define strncasecmp _strnicmp 273 #elif !defined(__MINGW32__) 274 #define strcasecmp stricmp 275 #define strncasecmp strnicmp 276 #endif 277 #define getdtablesize() 30000 278 #endif 279 280 #ifndef LWS_ARRAY_SIZE 281 #define LWS_ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) 282 #endif 283 284 #ifdef __cplusplus 285 extern "C" { 286 #endif 287 288 #define lws_safe_modulo(_a, _b) ((_b) ? ((_a) % (_b)) : 0) 289 290 #if defined(__clang__) 291 #define lws_memory_barrier() __sync_synchronize() 292 #elif defined(__GNUC__) 293 #define lws_memory_barrier() __sync_synchronize() 294 #else 295 #define lws_memory_barrier() 296 #endif 297 298 299 struct lws_ring { 300 void *buf; 301 void (*destroy_element)(void *element); 302 uint32_t buflen; 303 uint32_t element_len; 304 uint32_t head; 305 uint32_t oldest_tail; 306 }; 307 308 struct lws_protocols; 309 struct lws; 310 311 #if defined(LWS_WITH_NETWORK) /* network */ 312 #include "private-lib-event-libs.h" 313 314 #if defined(LWS_WITH_SECURE_STREAMS) 315 #include "private-lib-secure-streams.h" 316 #endif 317 318 #if defined(LWS_WITH_SYS_SMD) 319 #include "private-lib-system-smd.h" 320 #endif 321 322 #if defined(LWS_WITH_SYS_FAULT_INJECTION) 323 #include "private-lib-system-fault-injection.h" 324 #endif 325 326 #include "private-lib-system-metrics.h" 327 328 329 struct lws_foreign_thread_pollfd { 330 struct lws_foreign_thread_pollfd *next; 331 int fd_index; 332 int _and; 333 int _or; 334 }; 335 #endif /* network */ 336 337 #if defined(LWS_WITH_NETWORK) 338 #include "private-lib-core-net.h" 339 #endif 340 341 struct lws_system_blob { 342 union { 343 struct lws_buflist *bl; 344 struct { 345 const uint8_t *ptr; 346 size_t len; 347 } direct; 348 } u; 349 char is_direct; 350 }; 351 352 353 typedef struct lws_attach_item { 354 lws_dll2_t list; 355 lws_attach_cb_t cb; 356 void *opaque; 357 lws_system_states_t state; 358 } lws_attach_item_t; 359 360 /* 361 * These are the context's lifecycle group indexes that exist in this build 362 * configuration. If you add some, make sure to also add the tag_prefix in 363 * context.c context creation with matching preprocessor conditionals. 364 */ 365 366 enum { 367 LWSLCG_WSI, /* generic wsi, eg, pipe, listen */ 368 LWSLCG_VHOST, 369 370 LWSLCG_WSI_SERVER, /* server wsi */ 371 372 #if defined(LWS_ROLE_H2) || defined(LWS_ROLE_MQTT) 373 LWSLCG_WSI_MUX, /* a mux child wsi */ 374 #endif 375 376 #if defined(LWS_WITH_CLIENT) 377 LWSLCG_WSI_CLIENT, /* client wsi */ 378 #endif 379 380 #if defined(LWS_WITH_SECURE_STREAMS) 381 #if defined(LWS_WITH_CLIENT) 382 LWSLCG_SS_CLIENT, /* secstream client handle */ 383 #endif 384 #if defined(LWS_WITH_SERVER) 385 LWSLCG_SS_SERVER, /* secstream server handle */ 386 #endif 387 #if defined(LWS_WITH_CLIENT) 388 LWSLCG_WSI_SS_CLIENT, /* wsi bound to ss client handle */ 389 #endif 390 #if defined(LWS_WITH_SERVER) 391 LWSLCG_WSI_SS_SERVER, /* wsi bound to ss server handle */ 392 #endif 393 #endif 394 395 #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API) 396 #if defined(LWS_WITH_CLIENT) 397 LWSLCG_SSP_CLIENT, /* SSPC handle client connection to proxy */ 398 #endif 399 #if defined(LWS_WITH_SERVER) 400 LWSLCG_SSP_ONWARD, /* SS handle at proxy for onward conn */ 401 #endif 402 #if defined(LWS_WITH_CLIENT) 403 LWSLCG_WSI_SSP_CLIENT, /* wsi bound to SSPC cli conn to proxy */ 404 #endif 405 #if defined(LWS_WITH_SERVER) 406 LWSLCG_WSI_SSP_ONWARD, /* wsi bound to Proxy onward connection */ 407 #endif 408 #endif 409 410 /* always last */ 411 LWSLCG_COUNT 412 }; 413 414 /* 415 * the rest is managed per-context, that includes 416 * 417 * - processwide single fd -> wsi lookup 418 * - contextwide headers pool 419 */ 420 421 struct lws_context { 422 #if defined(LWS_WITH_SERVER) 423 char canonical_hostname[96]; 424 #endif 425 426 #if defined(LWS_WITH_FILE_OPS) 427 struct lws_plat_file_ops fops_platform; 428 #endif 429 430 #if defined(LWS_WITH_ZIP_FOPS) 431 struct lws_plat_file_ops fops_zip; 432 #endif 433 434 lws_system_blob_t system_blobs[LWS_SYSBLOB_TYPE_COUNT]; 435 436 #if defined(LWS_WITH_SYS_SMD) 437 lws_smd_t smd; 438 #endif 439 #if defined(LWS_WITH_SECURE_STREAMS) 440 struct lws_ss_handle *ss_cpd; 441 #endif 442 lws_sorted_usec_list_t sul_cpd_defer; 443 444 #if defined(LWS_WITH_NETWORK) 445 struct lws_context_per_thread pt[LWS_MAX_SMP]; 446 lws_retry_bo_t default_retry; 447 lws_sorted_usec_list_t sul_system_state; 448 449 lws_lifecycle_group_t lcg[LWSLCG_COUNT]; 450 451 const struct lws_protocols *protocols_copy; 452 453 #if defined(LWS_WITH_NETLINK) 454 lws_sorted_usec_list_t sul_nl_coldplug; 455 /* process can only have one netlink socket, have to do it in ctx */ 456 lws_dll2_owner_t routing_table; 457 struct lws *netlink; 458 #endif 459 460 #if defined(LWS_PLAT_FREERTOS) 461 struct sockaddr_in frt_pipe_si; 462 #endif 463 464 #if defined(LWS_WITH_HTTP2) 465 struct http2_settings set; 466 #endif 467 468 #if LWS_MAX_SMP > 1 469 struct lws_mutex_refcount mr; 470 #endif 471 472 #if defined(LWS_WITH_SYS_METRICS) 473 lws_dll2_owner_t owner_mtr_dynpol; 474 /**< owner for lws_metric_policy_dyn_t (dynamic part of metric pols) */ 475 lws_dll2_owner_t owner_mtr_no_pol; 476 /**< owner for lws_metric_pub_t with no policy to bind to */ 477 #endif 478 479 #if defined(LWS_WITH_NETWORK) 480 /* 481 * LWS_WITH_NETWORK =====> 482 */ 483 484 lws_dll2_owner_t owner_vh_being_destroyed; 485 486 lws_metric_t *mt_service; /* doing service */ 487 const lws_metric_policy_t *metrics_policies; 488 const char *metrics_prefix; 489 490 #if defined(LWS_WITH_SYS_METRICS) && defined(LWS_WITH_CLIENT) 491 lws_metric_t *mt_conn_tcp; /* client tcp conns */ 492 lws_metric_t *mt_conn_tls; /* client tcp conns */ 493 lws_metric_t *mt_conn_dns; /* client dns external lookups */ 494 lws_metric_t *mth_conn_failures; /* histogram of conn failure reasons */ 495 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) 496 lws_metric_t *mt_http_txn; /* client http transaction */ 497 #endif 498 #if defined(LWS_WITH_SYS_ASYNC_DNS) 499 lws_metric_t *mt_adns_cache; /* async dns lookup lat */ 500 #endif 501 #if defined(LWS_WITH_SECURE_STREAMS) 502 lws_metric_t *mth_ss_conn; /* SS connection outcomes */ 503 #endif 504 #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API) 505 lws_metric_t *mt_ss_cliprox_conn; /* SS cli->prox conn */ 506 lws_metric_t *mt_ss_cliprox_paylat; /* cli->prox payload latency */ 507 lws_metric_t *mt_ss_proxcli_paylat; /* prox->cli payload latency */ 508 #endif 509 #endif /* client */ 510 511 #if defined(LWS_WITH_SERVER) 512 lws_metric_t *mth_srv; 513 #endif 514 515 #if defined(LWS_WITH_EVENT_LIBS) 516 struct lws_plugin *evlib_plugin_list; 517 void *evlib_ctx; /* overallocated */ 518 #endif 519 520 #if defined(LWS_WITH_TLS) 521 struct lws_context_tls tls; 522 #if defined (LWS_WITH_TLS_JIT_TRUST) 523 lws_dll2_owner_t jit_inflight; 524 /* ongoing sync or async jit trust lookups */ 525 struct lws_cache_ttl_lru *trust_cache; 526 /* caches host -> truncated trust SKID mappings */ 527 #endif 528 #endif 529 #if defined(LWS_WITH_DRIVERS) 530 lws_netdevs_t netdevs; 531 #endif 532 533 #if defined(LWS_WITH_SYS_ASYNC_DNS) 534 lws_async_dns_t async_dns; 535 #endif 536 537 #if defined(LWS_WITH_SYS_FAULT_INJECTION) 538 lws_fi_ctx_t fic; 539 /**< Toplevel Fault Injection ctx */ 540 #endif 541 542 #if defined(LWS_WITH_CACHE_NSCOOKIEJAR) && defined(LWS_WITH_CLIENT) 543 struct lws_cache_ttl_lru *l1, *nsc; 544 #endif 545 546 #if defined(LWS_WITH_SYS_NTPCLIENT) 547 void *ntpclient_priv; 548 #endif 549 550 #if defined(LWS_WITH_SECURE_STREAMS) 551 struct lws_ss_handle *hss_fetch_policy; 552 #if defined(LWS_WITH_SECURE_STREAMS_SYS_AUTH_API_AMAZON_COM) 553 struct lws_ss_handle *hss_auth; 554 lws_sorted_usec_list_t sul_api_amazon_com; 555 lws_sorted_usec_list_t sul_api_amazon_com_kick; 556 #endif 557 #if !defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY) 558 struct lws_ss_x509 *server_der_list; 559 #endif 560 #endif 561 562 #if defined(LWS_WITH_SYS_STATE) 563 lws_state_manager_t mgr_system; 564 lws_state_notify_link_t protocols_notify; 565 #endif 566 #if defined (LWS_WITH_SYS_DHCP_CLIENT) 567 lws_dll2_owner_t dhcpc_owner; 568 /**< list of ifaces with dhcpc */ 569 #endif 570 571 /* pointers */ 572 573 struct lws_vhost *vhost_list; 574 struct lws_vhost *no_listener_vhost_list; 575 struct lws_vhost *vhost_pending_destruction_list; 576 struct lws_vhost *vhost_system; 577 578 #if defined(LWS_WITH_SERVER) 579 const char *server_string; 580 #endif 581 582 const struct lws_event_loop_ops *event_loop_ops; 583 #endif 584 585 #if defined(LWS_WITH_TLS) 586 const struct lws_tls_ops *tls_ops; 587 #endif 588 589 #if defined(LWS_WITH_PLUGINS) 590 struct lws_plugin *plugin_list; 591 #endif 592 #ifdef _WIN32 593 /* different implementation between unix and windows */ 594 struct lws_fd_hashtable fd_hashtable[FD_HASHTABLE_MODULUS]; 595 #else 596 struct lws **lws_lookup; 597 598 #endif 599 600 /* 601 * <====== LWS_WITH_NETWORK end 602 */ 603 604 #endif /* NETWORK */ 605 606 lws_log_cx_t *log_cx; 607 const char *name; 608 609 #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API) 610 const char *ss_proxy_bind; 611 const char *ss_proxy_address; 612 #endif 613 614 #if defined(LWS_WITH_FILE_OPS) 615 const struct lws_plat_file_ops *fops; 616 #endif 617 618 struct lws_context **pcontext_finalize; 619 #if !defined(LWS_PLAT_FREERTOS) 620 const char *username, *groupname; 621 #endif 622 623 #if defined(LWS_WITH_MBEDTLS) 624 mbedtls_entropy_context mec; 625 mbedtls_ctr_drbg_context mcdc; 626 #endif 627 628 #if defined(LWS_WITH_THREADPOOL) 629 struct lws_threadpool *tp_list_head; 630 #endif 631 632 #if defined(LWS_WITH_PEER_LIMITS) 633 struct lws_peer **pl_hash_table; 634 struct lws_peer *peer_wait_list; 635 lws_peer_limits_notify_t pl_notify_cb; 636 time_t next_cull; 637 #endif 638 639 const lws_system_ops_t *system_ops; 640 641 #if defined(LWS_WITH_SECURE_STREAMS) 642 #if !defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY) 643 const char *pss_policies_json; 644 struct lwsac *ac_policy; 645 void *pol_args; 646 #endif 647 const lws_ss_policy_t *pss_policies; 648 const lws_ss_auth_t *pss_auths; 649 #if defined(LWS_WITH_SSPLUGINS) 650 const lws_ss_plugin_t **pss_plugins; 651 #endif 652 #endif 653 654 void *external_baggage_free_on_destroy; 655 const struct lws_token_limits *token_limits; 656 void *user_space; 657 #if defined(LWS_WITH_SERVER) 658 const struct lws_protocol_vhost_options *reject_service_keywords; 659 lws_reload_func deprecation_cb; 660 #endif 661 #if !defined(LWS_PLAT_FREERTOS) 662 void (*eventlib_signal_cb)(void *event_lib_handle, int signum); 663 #endif 664 665 #if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) 666 cap_value_t caps[4]; 667 char count_caps; 668 #endif 669 670 lws_usec_t time_up; /* monotonic */ 671 #if defined(LWS_WITH_SYS_SMD) 672 lws_usec_t smd_ttl_us; 673 #endif 674 uint64_t options; 675 676 time_t last_ws_ping_pong_check_s; 677 #if defined(LWS_WITH_SECURE_STREAMS) 678 time_t last_policy; 679 #endif 680 681 #if defined(LWS_PLAT_FREERTOS) 682 unsigned long time_last_state_dump; 683 uint32_t last_free_heap; 684 #endif 685 686 unsigned int max_fds; 687 #if !defined(LWS_NO_DAEMONIZE) 688 pid_t started_with_parent; 689 #endif 690 691 #if !defined(LWS_PLAT_FREERTOS) 692 uid_t uid; 693 gid_t gid; 694 int fd_random; 695 int count_cgi_spawned; 696 #endif 697 698 unsigned int fd_limit_per_thread; 699 unsigned int timeout_secs; 700 unsigned int pt_serv_buf_size; 701 unsigned int max_http_header_data; 702 unsigned int max_http_header_pool; 703 int simultaneous_ssl_restriction; 704 int simultaneous_ssl; 705 int simultaneous_ssl_handshake_restriction; 706 int simultaneous_ssl_handshake; 707 #if defined(LWS_WITH_TLS_JIT_TRUST) 708 int vh_idle_grace_ms; 709 #endif 710 #if defined(LWS_WITH_PEER_LIMITS) 711 uint32_t pl_hash_elements; /* protected by context->lock */ 712 uint32_t count_peers; /* protected by context->lock */ 713 unsigned short ip_limit_ah; 714 unsigned short ip_limit_wsi; 715 #endif 716 717 #if defined(LWS_WITH_SYS_SMD) 718 uint16_t smd_queue_depth; 719 #endif 720 721 #if defined(LWS_WITH_NETLINK) 722 lws_route_uidx_t route_uidx; 723 #endif 724 725 char tls_gate_accepts; 726 727 unsigned int deprecated:1; 728 unsigned int inside_context_destroy:1; 729 unsigned int being_destroyed:1; 730 unsigned int service_no_longer_possible:1; 731 unsigned int being_destroyed2:1; 732 unsigned int requested_stop_internal_loops:1; 733 unsigned int protocol_init_done:1; 734 unsigned int doing_protocol_init:1; 735 unsigned int done_protocol_destroy_cb:1; 736 unsigned int evlib_finalize_destroy_after_int_loops_stop:1; 737 unsigned int max_fds_unrelated_to_ulimit:1; 738 unsigned int policy_updated:1; 739 #if defined(LWS_WITH_NETLINK) 740 unsigned int nl_initial_done:1; 741 #endif 742 743 unsigned short count_threads; 744 unsigned short undestroyed_threads; 745 short plugin_protocol_count; 746 short plugin_extension_count; 747 short server_string_len; 748 unsigned short deprecation_pending_listen_close_count; 749 #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API) 750 uint16_t ss_proxy_port; 751 #endif 752 /* 0 if not known, else us resolution of the poll wait */ 753 uint16_t us_wait_resolution; 754 755 uint8_t max_fi; 756 uint8_t captive_portal_detect; 757 uint8_t captive_portal_detect_type; 758 759 uint8_t destroy_state; /* enum lws_context_destroy */ 760 }; 761 762 #define lws_get_context_protocol(ctx, x) ctx->vhost_list->protocols[x] 763 #define lws_get_vh_protocol(vh, x) vh->protocols[x] 764 765 int 766 lws_jws_base64_enc(const char *in, size_t in_len, char *out, size_t out_max); 767 768 void 769 lws_vhost_destroy1(struct lws_vhost *vh); 770 771 #if defined(LWS_WITH_CACHE_NSCOOKIEJAR) && defined(LWS_WITH_CLIENT) 772 int 773 lws_parse_set_cookie(struct lws *wsi); 774 775 int 776 lws_cookie_send_cookies(struct lws *wsi, char **pp, char *end); 777 #endif 778 779 #if defined(LWS_PLAT_FREERTOS) 780 int 781 lws_find_string_in_file(const char *filename, const char *str, int stringlen); 782 #endif 783 784 signed char char_to_hex(const char c); 785 786 #if defined(LWS_WITH_NETWORK) 787 int 788 lws_system_do_attach(struct lws_context_per_thread *pt); 789 #endif 790 791 struct lws_buflist { 792 struct lws_buflist *next; 793 size_t len; 794 size_t pos; 795 }; 796 797 char * 798 lws_strdup(const char *s); 799 800 int 801 lws_b64_selftest(void); 802 803 804 #ifndef LWS_NO_DAEMONIZE 805 pid_t get_daemonize_pid(); 806 #else 807 #define get_daemonize_pid() (0) 808 #endif 809 810 void lwsl_emit_stderr(int level, const char *line); 811 812 #if !defined(LWS_WITH_TLS) 813 #define LWS_SSL_ENABLED(context) (0) 814 #define lws_context_init_server_ssl(_a, _b) (0) 815 #define lws_ssl_destroy(_a) 816 #define lws_context_init_alpn(_a) 817 #define lws_ssl_capable_read lws_ssl_capable_read_no_ssl 818 #define lws_ssl_capable_write lws_ssl_capable_write_no_ssl 819 #define lws_ssl_pending lws_ssl_pending_no_ssl 820 #define lws_server_socket_service_ssl(_b, _c, _d) (0) 821 #define lws_ssl_close(_a) (0) 822 #define lws_ssl_context_destroy(_a) 823 #define lws_ssl_SSL_CTX_destroy(_a) 824 #define lws_ssl_remove_wsi_from_buffered_list(_a) 825 #define __lws_ssl_remove_wsi_from_buffered_list(_a) 826 #define lws_context_init_ssl_library(_a, _b) 827 #define lws_context_deinit_ssl_library(_a) 828 #define lws_tls_check_all_cert_lifetimes(_a) 829 #define lws_tls_acme_sni_cert_destroy(_a) 830 #endif 831 832 833 834 #if LWS_MAX_SMP > 1 835 #define lws_context_lock(c, reason) lws_mutex_refcount_lock(&c->mr, reason) 836 #define lws_context_unlock(c) lws_mutex_refcount_unlock(&c->mr) 837 #define lws_context_assert_lock_held(c) lws_mutex_refcount_assert_held(&c->mr) 838 #define lws_vhost_assert_lock_held(v) lws_mutex_refcount_assert_held(&v->mr) 839 /* enforce context lock held */ 840 #define lws_vhost_lock(v) lws_mutex_refcount_lock(&v->mr, __func__) 841 #define lws_vhost_unlock(v) lws_mutex_refcount_unlock(&v->mr) 842 843 844 #else 845 #define lws_pt_mutex_init(_a) (void)(_a) 846 #define lws_pt_mutex_destroy(_a) (void)(_a) 847 #define lws_pt_lock(_a, b) (void)(_a) 848 #define lws_pt_assert_lock_held(_a) (void)(_a) 849 #define lws_pt_unlock(_a) (void)(_a) 850 #define lws_context_lock(_a, _b) (void)(_a) 851 #define lws_context_unlock(_a) (void)(_a) 852 #define lws_context_assert_lock_held(_a) (void)(_a) 853 #define lws_vhost_assert_lock_held(_a) (void)(_a) 854 #define lws_vhost_lock(_a) (void)(_a) 855 #define lws_vhost_unlock(_a) (void)(_a) 856 #define lws_pt_stats_lock(_a) (void)(_a) 857 #define lws_pt_stats_unlock(_a) (void)(_a) 858 #endif 859 860 int LWS_WARN_UNUSED_RESULT 861 lws_ssl_capable_read_no_ssl(struct lws *wsi, unsigned char *buf, size_t len); 862 863 int LWS_WARN_UNUSED_RESULT 864 lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, size_t len); 865 866 int LWS_WARN_UNUSED_RESULT 867 lws_ssl_pending_no_ssl(struct lws *wsi); 868 869 int 870 lws_tls_check_cert_lifetime(struct lws_vhost *vhost); 871 872 int lws_jws_selftest(void); 873 int lws_jwe_selftest(void); 874 875 int 876 lws_protocol_init(struct lws_context *context); 877 878 int 879 lws_bind_protocol(struct lws *wsi, const struct lws_protocols *p, 880 const char *reason); 881 882 const struct lws_protocol_vhost_options * 883 lws_vhost_protocol_options(struct lws_vhost *vh, const char *name); 884 885 const struct lws_http_mount * 886 lws_find_mount(struct lws *wsi, const char *uri_ptr, int uri_len); 887 888 #ifdef LWS_WITH_HTTP2 889 int lws_wsi_is_h2(struct lws *wsi); 890 #endif 891 /* 892 * custom allocator 893 */ 894 void * 895 lws_realloc(void *ptr, size_t size, const char *reason); 896 897 void * LWS_WARN_UNUSED_RESULT 898 lws_zalloc(size_t size, const char *reason); 899 900 #ifdef LWS_PLAT_OPTEE 901 void *lws_malloc(size_t size, const char *reason); 902 void lws_free(void *p); 903 #define lws_free_set_NULL(P) do { lws_free(P); (P) = NULL; } while(0) 904 #else 905 #define lws_malloc(S, R) lws_realloc(NULL, S, R) 906 #define lws_free(P) lws_realloc(P, 0, "lws_free") 907 #define lws_free_set_NULL(P) do { lws_realloc(P, 0, "free"); (P) = NULL; } while(0) 908 #endif 909 910 int 911 __lws_create_event_pipes(struct lws_context *context); 912 913 int 914 lws_plat_apply_FD_CLOEXEC(int n); 915 916 const struct lws_plat_file_ops * 917 lws_vfs_select_fops(const struct lws_plat_file_ops *fops, const char *vfs_path, 918 const char **vpath); 919 920 /* lws_plat_ */ 921 922 int 923 lws_plat_context_early_init(void); 924 void 925 lws_plat_context_early_destroy(struct lws_context *context); 926 void 927 lws_plat_context_late_destroy(struct lws_context *context); 928 929 int 930 lws_plat_init(struct lws_context *context, 931 const struct lws_context_creation_info *info); 932 int 933 lws_plat_drop_app_privileges(struct lws_context *context, int actually_drop); 934 935 #if defined(LWS_WITH_UNIX_SOCK) && !defined(WIN32) 936 int 937 lws_plat_user_colon_group_to_ids(const char *u_colon_g, uid_t *puid, gid_t *pgid); 938 #endif 939 940 int 941 lws_plat_ntpclient_config(struct lws_context *context); 942 943 int 944 lws_plat_ifname_to_hwaddr(int fd, const char *ifname, uint8_t *hwaddr, int len); 945 946 int 947 lws_plat_vhost_tls_client_ctx_init(struct lws_vhost *vhost); 948 949 int 950 lws_check_byte_utf8(unsigned char state, unsigned char c); 951 int LWS_WARN_UNUSED_RESULT 952 lws_check_utf8(unsigned char *state, unsigned char *buf, size_t len); 953 int alloc_file(struct lws_context *context, const char *filename, 954 uint8_t **buf, lws_filepos_t *amount); 955 956 int 957 lws_lec_scratch(lws_lec_pctx_t *ctx); 958 void 959 lws_lec_signed(lws_lec_pctx_t *ctx, int64_t num); 960 961 int 962 lws_cose_key_checks(const lws_cose_key_t *key, int64_t kty, int64_t alg, 963 int key_op, const char *crv); 964 965 void lws_msleep(unsigned int); 966 967 void 968 lws_context_destroy2(struct lws_context *context); 969 970 #if !defined(PRIu64) 971 #define PRIu64 "llu" 972 #endif 973 974 #if defined(LWS_WITH_ABSTRACT) 975 #include "private-lib-abstract.h" 976 #endif 977 978 #ifdef __cplusplus 979 }; 980 #endif 981 982 #endif 983