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