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