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_CORE_NET_PRIVATE_H__)
26 #define __LWS_CORE_NET_PRIVATE_H__
27
28 #if !defined(_POSIX_C_SOURCE)
29 #define _POSIX_C_SOURCE 200112L
30 #endif
31
32 /*
33 * Generic pieces needed to manage muxable stream protocols like h2
34 */
35
36 struct lws_muxable {
37 struct lws *parent_wsi;
38 struct lws *child_list;
39 struct lws *sibling_list;
40
41 unsigned int my_sid;
42 unsigned int child_count;
43
44 uint32_t highest_sid;
45
46 uint8_t requested_POLLOUT;
47 };
48
49 #include "private-lib-roles.h"
50
51 #ifdef __cplusplus
52 extern "C" {
53 #endif
54
55 #define __lws_sul_insert_us(owner, sul, _us) \
56 (sul)->us = lws_now_usecs() + (lws_usec_t)(_us); \
57 __lws_sul_insert(owner, sul)
58
59
60 /*
61 *
62 * ------ roles ------
63 *
64 */
65
66 /* null-terminated array of pointers to roles lws built with */
67 extern const struct lws_role_ops *available_roles[];
68
69 #define LWS_FOR_EVERY_AVAILABLE_ROLE_START(xx) { \
70 const struct lws_role_ops **ppxx = available_roles; \
71 while (*ppxx) { \
72 const struct lws_role_ops *xx = *ppxx++;
73
74 #define LWS_FOR_EVERY_AVAILABLE_ROLE_END }}
75
76 /*
77 *
78 * ------ event_loop ops ------
79 *
80 */
81
82 /* enums of socks version */
83 enum socks_version {
84 SOCKS_VERSION_4 = 4,
85 SOCKS_VERSION_5 = 5
86 };
87
88 /* enums of subnegotiation version */
89 enum socks_subnegotiation_version {
90 SOCKS_SUBNEGOTIATION_VERSION_1 = 1,
91 };
92
93 /* enums of socks commands */
94 enum socks_command {
95 SOCKS_COMMAND_CONNECT = 1,
96 SOCKS_COMMAND_BIND = 2,
97 SOCKS_COMMAND_UDP_ASSOCIATE = 3
98 };
99
100 /* enums of socks address type */
101 enum socks_atyp {
102 SOCKS_ATYP_IPV4 = 1,
103 SOCKS_ATYP_DOMAINNAME = 3,
104 SOCKS_ATYP_IPV6 = 4
105 };
106
107 /* enums of socks authentication methods */
108 enum socks_auth_method {
109 SOCKS_AUTH_NO_AUTH = 0,
110 SOCKS_AUTH_GSSAPI = 1,
111 SOCKS_AUTH_USERNAME_PASSWORD = 2
112 };
113
114 /* enums of subnegotiation status */
115 enum socks_subnegotiation_status {
116 SOCKS_SUBNEGOTIATION_STATUS_SUCCESS = 0,
117 };
118
119 /* enums of socks request reply */
120 enum socks_request_reply {
121 SOCKS_REQUEST_REPLY_SUCCESS = 0,
122 SOCKS_REQUEST_REPLY_FAILURE_GENERAL = 1,
123 SOCKS_REQUEST_REPLY_CONNECTION_NOT_ALLOWED = 2,
124 SOCKS_REQUEST_REPLY_NETWORK_UNREACHABLE = 3,
125 SOCKS_REQUEST_REPLY_HOST_UNREACHABLE = 4,
126 SOCKS_REQUEST_REPLY_CONNECTION_REFUSED = 5,
127 SOCKS_REQUEST_REPLY_TTL_EXPIRED = 6,
128 SOCKS_REQUEST_REPLY_COMMAND_NOT_SUPPORTED = 7,
129 SOCKS_REQUEST_REPLY_ATYP_NOT_SUPPORTED = 8
130 };
131
132 /* enums used to generate socks messages */
133 enum socks_msg_type {
134 /* greeting */
135 SOCKS_MSG_GREETING,
136 /* credential, user name and password */
137 SOCKS_MSG_USERNAME_PASSWORD,
138 /* connect command */
139 SOCKS_MSG_CONNECT
140 };
141
142 enum {
143 LWS_RXFLOW_ALLOW = (1 << 0),
144 LWS_RXFLOW_PENDING_CHANGE = (1 << 1),
145 };
146
147 typedef enum lws_parser_return {
148 LPR_FORBIDDEN = -2,
149 LPR_FAIL = -1,
150 LPR_OK = 0,
151 LPR_DO_FALLBACK = 2,
152 } lws_parser_return_t;
153
154 enum pmd_return {
155 PMDR_UNKNOWN,
156 PMDR_DID_NOTHING,
157 PMDR_HAS_PENDING,
158 PMDR_EMPTY_NONFINAL,
159 PMDR_EMPTY_FINAL,
160 PMDR_NOTHING_WE_SHOULD_DO,
161
162 PMDR_FAILED = -1
163 };
164
165 #if defined(LWS_WITH_PEER_LIMITS)
166 struct lws_peer {
167 struct lws_peer *next;
168 struct lws_peer *peer_wait_list;
169
170 lws_sockaddr46 sa46;
171
172 time_t time_created;
173 time_t time_closed_all;
174
175 uint32_t hash;
176 uint32_t count_wsi;
177 uint32_t total_wsi;
178
179 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
180 struct lws_peer_role_http http;
181 #endif
182 };
183 #endif
184
185 #ifdef LWS_WITH_IPV6
186 #define LWS_IPV6_ENABLED(vh) \
187 (!lws_check_opt(vh->context->options, LWS_SERVER_OPTION_DISABLE_IPV6) && \
188 !lws_check_opt(vh->options, LWS_SERVER_OPTION_DISABLE_IPV6))
189 #else
190 #define LWS_IPV6_ENABLED(context) (0)
191 #endif
192
193 #ifdef LWS_WITH_UNIX_SOCK
194 #define LWS_UNIX_SOCK_ENABLED(vhost) \
195 (vhost->options & LWS_SERVER_OPTION_UNIX_SOCK)
196 #else
197 #define LWS_UNIX_SOCK_ENABLED(vhost) (0)
198 #endif
199
200 enum uri_path_states {
201 URIPS_IDLE,
202 URIPS_SEEN_SLASH,
203 URIPS_SEEN_SLASH_DOT,
204 URIPS_SEEN_SLASH_DOT_DOT,
205 };
206
207 enum uri_esc_states {
208 URIES_IDLE,
209 URIES_SEEN_PERCENT,
210 URIES_SEEN_PERCENT_H1,
211 };
212
213 #if defined(LWS_WITH_CLIENT)
214
215 enum {
216 CIS_ADDRESS,
217 CIS_PATH,
218 CIS_HOST,
219 CIS_ORIGIN,
220 CIS_PROTOCOL,
221 CIS_METHOD,
222 CIS_IFACE,
223 CIS_ALPN,
224
225
226 CIS_COUNT
227 };
228
229 struct client_info_stash {
230 char *cis[CIS_COUNT];
231 void *opaque_user_data; /* not allocated or freed by lws */
232 };
233 #endif
234
235 #if defined(LWS_WITH_UDP)
236 #define lws_wsi_is_udp(___wsi) (!!___wsi->udp)
237 #endif
238
239 #define LWS_H2_FRAME_HEADER_LENGTH 9
240
241 lws_usec_t
242 __lws_sul_service_ripe(lws_dll2_owner_t *own, int num_own, lws_usec_t usnow);
243
244 /*
245 * lws_async_dns
246 */
247
248 typedef struct lws_async_dns {
249 lws_sockaddr46 sa46; /* nameserver */
250 lws_dll2_owner_t waiting;
251 lws_dll2_owner_t cached;
252 struct lws *wsi;
253 time_t time_set_server;
254 uint8_t dns_server_set:1;
255 uint8_t dns_server_connected:1;
256 } lws_async_dns_t;
257
258 typedef enum {
259 LADNS_CONF_SERVER_UNKNOWN = -1,
260 LADNS_CONF_SERVER_SAME,
261 LADNS_CONF_SERVER_CHANGED
262 } lws_async_dns_server_check_t;
263
264 #if defined(LWS_WITH_SYS_ASYNC_DNS)
265 void
266 lws_aysnc_dns_completed(struct lws *wsi, void *sa, size_t salen,
267 lws_async_dns_retcode_t ret);
268 #endif
269 void
270 lws_async_dns_cancel(struct lws *wsi);
271
272 void
273 lws_async_dns_drop_server(struct lws_context *context);
274
275 /*
276 * so we can have n connections being serviced simultaneously,
277 * these things need to be isolated per-thread.
278 */
279
280 struct lws_context_per_thread {
281 #if LWS_MAX_SMP > 1
282 pthread_mutex_t lock_stats;
283 struct lws_mutex_refcount mr;
284 pthread_t self;
285 #endif
286 struct lws_dll2_owner dll_buflist_owner; /* guys with pending rxflow */
287 struct lws_dll2_owner seq_owner; /* list of lws_sequencer-s */
288 lws_dll2_owner_t attach_owner; /* pending lws_attach */
289
290 #if defined(LWS_WITH_SECURE_STREAMS)
291 lws_dll2_owner_t ss_owner;
292 #endif
293 #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API) || \
294 defined(LWS_WITH_SECURE_STREAMS_THREAD_API)
295 lws_dll2_owner_t ss_dsh_owner;
296 lws_dll2_owner_t ss_client_owner;
297 #endif
298
299 struct lws_dll2_owner pt_sul_owner[LWS_COUNT_PT_SUL_OWNERS];
300
301 #if defined (LWS_WITH_SEQUENCER)
302 lws_sorted_usec_list_t sul_seq_heartbeat;
303 #endif
304 #if (defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)) && defined(LWS_WITH_SERVER)
305 lws_sorted_usec_list_t sul_ah_lifecheck;
306 #endif
307 #if defined(LWS_WITH_TLS) && defined(LWS_WITH_SERVER)
308 lws_sorted_usec_list_t sul_tls;
309 #endif
310 #if defined(LWS_PLAT_UNIX)
311 lws_sorted_usec_list_t sul_plat;
312 #endif
313 #if defined(LWS_ROLE_CGI)
314 lws_sorted_usec_list_t sul_cgi;
315 #endif
316 #if defined(LWS_WITH_PEER_LIMITS)
317 lws_sorted_usec_list_t sul_peer_limits;
318 #endif
319
320 #if !defined(LWS_PLAT_FREERTOS)
321 struct lws *fake_wsi; /* used for callbacks where there's no wsi */
322 #endif
323
324 #if defined(WIN32)
325 struct sockaddr_in frt_pipe_si;
326 #endif
327
328 #if defined(LWS_WITH_TLS)
329 struct lws_pt_tls tls;
330 #endif
331 struct lws_context *context;
332
333 /*
334 * usable by anything in the service code, but only if the scope
335 * does not last longer than the service action (since next service
336 * of any socket can likewise use it and overwrite)
337 */
338 unsigned char *serv_buf;
339
340 struct lws_pollfd *fds;
341 volatile struct lws_foreign_thread_pollfd * volatile foreign_pfd_list;
342
343 lws_sockfd_type dummy_pipe_fds[2];
344 struct lws *pipe_wsi;
345
346 /* --- role based members --- */
347
348 #if defined(LWS_ROLE_WS) && !defined(LWS_WITHOUT_EXTENSIONS)
349 struct lws_pt_role_ws ws;
350 #endif
351 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
352 struct lws_pt_role_http http;
353 #endif
354 #if defined(LWS_ROLE_DBUS)
355 struct lws_pt_role_dbus dbus;
356 #endif
357 /* --- event library based members --- */
358
359 void *evlib_pt; /* overallocated */
360
361 /* --- */
362
363 unsigned long count_conns;
364 unsigned int fds_count;
365
366 /*
367 * set to the Thread ID that's doing the service loop just before entry
368 * to poll indicates service thread likely idling in poll()
369 * volatile because other threads may check it as part of processing
370 * for pollfd event change.
371 */
372 volatile int service_tid;
373 int service_tid_detected;
374 #if !defined(LWS_PLAT_FREERTOS)
375 int count_event_loop_static_asset_handles;
376 #endif
377
378 volatile unsigned char inside_poll;
379 volatile unsigned char foreign_spinlock;
380
381 unsigned char tid;
382
383 unsigned char inside_service:1;
384 unsigned char inside_lws_service:1;
385 unsigned char event_loop_foreign:1;
386 unsigned char event_loop_destroy_processing_done:1;
387 unsigned char event_loop_pt_unused:1;
388 unsigned char destroy_self:1;
389 unsigned char is_destroyed:1;
390 };
391
392 /*
393 * virtual host -related context information
394 * vhostwide SSL context
395 * vhostwide proxy
396 *
397 * hierarchy:
398 *
399 * context -> vhost -> wsi
400 *
401 * incoming connection non-SSL vhost binding:
402 *
403 * listen socket -> wsi -> select vhost after first headers
404 *
405 * incoming connection SSL vhost binding:
406 *
407 * SSL SNI -> wsi -> bind after SSL negotiation
408 */
409
410 struct lws_vhost {
411 #if defined(LWS_WITH_CLIENT) && defined(LWS_CLIENT_HTTP_PROXYING)
412 char proxy_basic_auth_token[128];
413 #endif
414 #if LWS_MAX_SMP > 1
415 struct lws_mutex_refcount mr;
416 char close_flow_vs_tsi[LWS_MAX_SMP];
417 #endif
418
419 #if defined(LWS_ROLE_H2)
420 struct lws_vhost_role_h2 h2;
421 #endif
422 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
423 struct lws_vhost_role_http http;
424 #endif
425 #if defined(LWS_ROLE_WS) && !defined(LWS_WITHOUT_EXTENSIONS)
426 struct lws_vhost_role_ws ws;
427 #endif
428
429 lws_lifecycle_t lc;
430 lws_dll2_t vh_being_destroyed_list;
431
432 #if defined(LWS_WITH_SOCKS5)
433 char socks_proxy_address[128];
434 char socks_user[96];
435 char socks_password[96];
436 #endif
437
438 #if defined(LWS_WITH_TLS_SESSIONS)
439 lws_dll2_owner_t tls_sessions; /* vh lock */
440 #endif
441
442 #if defined(LWS_WITH_EVENT_LIBS)
443 void *evlib_vh; /* overallocated */
444 #endif
445 #if defined(LWS_WITH_SYS_METRICS)
446 lws_metric_t *mt_traffic_rx;
447 lws_metric_t *mt_traffic_tx;
448 #endif
449
450 #if defined(LWS_WITH_SYS_FAULT_INJECTION)
451 lws_fi_ctx_t fic;
452 /**< Fault Injection ctx for the vhost, hierarchy vhost->context */
453 #endif
454
455 uint64_t options;
456
457 struct lws_context *context;
458 struct lws_vhost *vhost_next;
459
460 const lws_retry_bo_t *retry_policy;
461
462 #if defined(LWS_WITH_TLS_JIT_TRUST)
463 lws_sorted_usec_list_t sul_unref; /* grace period after idle */
464 #endif
465
466 #if defined(LWS_WITH_SERVER) && defined(LWS_WITH_SECURE_STREAMS)
467 lws_ss_handle_t *ss_handle; /* ss handle for the server obj */
468 #endif
469
470 lws_dll2_owner_t listen_wsi;
471
472 const char *name;
473 const char *iface;
474 const char *listen_accept_role;
475 const char *listen_accept_protocol;
476 const char *unix_socket_perms;
477
478 void (*finalize)(struct lws_vhost *vh, void *arg);
479 void *finalize_arg;
480
481 const struct lws_protocols *protocols;
482 void **protocol_vh_privs;
483 const struct lws_protocol_vhost_options *pvo;
484 const struct lws_protocol_vhost_options *headers;
485 struct lws_dll2_owner *same_vh_protocol_owner;
486 struct lws_vhost *no_listener_vhost_list;
487 struct lws_dll2_owner abstract_instances_owner; /* vh lock */
488
489 #if defined(LWS_WITH_CLIENT)
490 struct lws_dll2_owner dll_cli_active_conns_owner;
491 #endif
492 struct lws_dll2_owner vh_awaiting_socket_owner;
493
494 #if defined(LWS_WITH_TLS)
495 struct lws_vhost_tls tls;
496 #endif
497
498 void *user;
499
500 int listen_port;
501 #if !defined(LWS_PLAT_FREERTOS) && !defined(OPTEE_TA) && !defined(WIN32)
502 int bind_iface;
503 #endif
504
505 #if defined(LWS_WITH_SOCKS5)
506 unsigned int socks_proxy_port;
507 #endif
508 int count_protocols;
509 int ka_time;
510 int ka_probes;
511 int ka_interval;
512 int keepalive_timeout;
513 int timeout_secs_ah_idle;
514 int connect_timeout_secs;
515 int fo_listen_queue;
516
517 int count_bound_wsi;
518
519 #ifdef LWS_WITH_ACCESS_LOG
520 int log_fd;
521 #endif
522
523 #if defined(LWS_WITH_TLS_SESSIONS)
524 uint32_t tls_session_cache_max;
525 #endif
526
527 #if defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY) || defined(LWS_WITH_SECURE_STREAMS_CPP)
528 int8_t ss_refcount;
529 /**< refcount of number of ss connections with streamtypes using this
530 * trust store */
531 #endif
532
533 uint8_t allocated_vhost_protocols:1;
534 uint8_t created_vhost_protocols:1;
535 uint8_t being_destroyed:1;
536 uint8_t from_ss_policy:1;
537 #if defined(LWS_WITH_TLS_JIT_TRUST)
538 uint8_t grace_after_unref:1;
539 /* grace time / autodelete aoplies to us */
540 #endif
541
542 unsigned char default_protocol_index;
543 unsigned char raw_protocol_index;
544 };
545
546 void
547 __lws_vhost_destroy2(struct lws_vhost *vh);
548
549 #define mux_to_wsi(_m) lws_container_of(_m, struct lws, mux)
550
551 void
552 lws_wsi_mux_insert(struct lws *wsi, struct lws *parent_wsi, unsigned int sid);
553 int
554 lws_wsi_mux_mark_parents_needing_writeable(struct lws *wsi);
555 struct lws *
556 lws_wsi_mux_move_child_to_tail(struct lws **wsi2);
557 int
558 lws_wsi_mux_action_pending_writeable_reqs(struct lws *wsi);
559
560 void
561 lws_wsi_mux_dump_children(struct lws *wsi);
562
563 void
564 lws_wsi_mux_close_children(struct lws *wsi, int reason);
565
566 void
567 lws_wsi_mux_sibling_disconnect(struct lws *wsi);
568
569 void
570 lws_wsi_mux_dump_waiting_children(struct lws *wsi);
571
572 int
573 lws_wsi_mux_apply_queue(struct lws *wsi);
574
575 /*
576 * struct lws
577 */
578
579 /*
580 * These pieces are very commonly used (via accessors) in user protocol handlers
581 * and have to be valid, even in the case no real wsi is available for the cb.
582 *
583 * We put all this category of pointers in there and compose it at the top of
584 * struct lws, so a dummy wsi providing these only needs to be this big, while
585 * still being castable for being a struct wsi *
586 */
587
588 struct lws_a {
589 struct lws_context *context;
590 struct lws_vhost *vhost;
591 const struct lws_protocols *protocol;
592 void *opaque_user_data;
593 };
594
595 /*
596 * For RTOS-class platforms, their code is relatively new, post-minimal examples
597 * and tend to not have legacy user protocol handler baggage touching unexpected
598 * things in fakewsi unconditionally... we can use an lws_a on the stack and
599 * don't need to define the rest of the wsi content, just cast it, this saves
600 * a wsi footprint in heap (typ 800 bytes nowadays even on RTOS).
601 *
602 * For other platforms that have been around for years and have thousands of
603 * different user protocol handler implementations, it's likely some of them
604 * will be touching the struct lws content unconditionally in the handler even
605 * when we are calling back with a non wsi-specific reason, and may react badly
606 * to it being garbage. So continue to implement those as a full, zero-ed down
607 * prepared fakewsi on heap at context creation time.
608 */
609
610 #if defined(LWS_PLAT_FREERTOS)
611 #define lws_fakewsi_def_plwsa(pt) struct lws_a lwsa, *plwsa = &lwsa
612 #else
613 #define lws_fakewsi_def_plwsa(pt) struct lws_a *plwsa = &(pt)->fake_wsi->a
614 #endif
615 /* since we reuse the pt version, also correct to zero down the lws_a part */
616 #define lws_fakewsi_prep_plwsa_ctx(_c) \
617 memset(plwsa, 0, sizeof(*plwsa)); plwsa->context = _c
618
619 struct lws {
620
621 struct lws_a a;
622
623 /* structs */
624
625 #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
626 struct _lws_http_mode_related http;
627 #endif
628 #if defined(LWS_ROLE_H2)
629 struct _lws_h2_related h2;
630 #endif
631 #if defined(LWS_ROLE_WS)
632 struct _lws_websocket_related *ws; /* allocated if we upgrade to ws */
633 #endif
634 #if defined(LWS_ROLE_DBUS)
635 struct _lws_dbus_mode_related dbus;
636 #endif
637 #if defined(LWS_ROLE_MQTT)
638 struct _lws_mqtt_related *mqtt;
639 #endif
640
641 #if defined(LWS_ROLE_H2) || defined(LWS_ROLE_MQTT)
642 struct lws_muxable mux;
643 struct lws_tx_credit txc;
644 #endif
645
646 lws_lifecycle_t lc;
647
648 /* lifetime members */
649
650 #if defined(LWS_WITH_EVENT_LIBS)
651 void *evlib_wsi; /* overallocated */
652 #endif
653
654 lws_sorted_usec_list_t sul_timeout;
655 lws_sorted_usec_list_t sul_hrtimer;
656 lws_sorted_usec_list_t sul_validity;
657 lws_sorted_usec_list_t sul_connect_timeout;
658
659 struct lws_dll2 dll_buflist; /* guys with pending rxflow */
660 struct lws_dll2 same_vh_protocol;
661 struct lws_dll2 vh_awaiting_socket;
662 #if defined(LWS_WITH_SYS_ASYNC_DNS)
663 struct lws_dll2 adns; /* on adns list of guys to tell result */
664 lws_async_dns_cb_t adns_cb; /* callback with result */
665 #endif
666 #if defined(LWS_WITH_SERVER)
667 struct lws_dll2 listen_list;
668 #endif
669 #if defined(LWS_WITH_CLIENT)
670 struct lws_dll2 dll_cli_active_conns;
671 struct lws_dll2 dll2_cli_txn_queue;
672 struct lws_dll2_owner dll2_cli_txn_queue_owner;
673
674 /**< caliper is reused for tcp, tls and txn conn phases */
675
676 lws_dll2_t speculative_list;
677 lws_dll2_owner_t speculative_connect_owner;
678 /* wsis: additional connection candidates */
679 lws_dll2_owner_t dns_sorted_list;
680 /* lws_dns_sort_t: dns results wrapped and sorted in a linked-list...
681 * deleted as they are tried, list empty == everything tried */
682 #endif
683
684 #if defined(LWS_WITH_SYS_FAULT_INJECTION)
685 lws_fi_ctx_t fic;
686 /**< Fault Injection ctx for the wsi, hierarchy wsi->vhost->context */
687 lws_sorted_usec_list_t sul_fault_timedclose;
688 /**< used to inject a fault that closes the wsi after a random time */
689 #endif
690
691 #if defined(LWS_WITH_SYS_METRICS)
692 lws_metrics_caliper_compose(cal_conn)
693 #endif
694
695 lws_sockaddr46 sa46_local;
696 lws_sockaddr46 sa46_peer;
697
698 /* pointers */
699
700 struct lws *parent; /* points to parent, if any */
701 struct lws *child_list; /* points to first child */
702 struct lws *sibling_list; /* subsequent children at same level */
703 const struct lws_role_ops *role_ops;
704 struct lws_sequencer *seq; /* associated sequencer if any */
705 const lws_retry_bo_t *retry_policy;
706
707 lws_log_cx_t *log_cx;
708
709 #if defined(LWS_WITH_THREADPOOL) && defined(LWS_HAVE_PTHREAD_H)
710 lws_dll2_owner_t tp_task_owner; /* struct lws_threadpool_task */
711 #endif
712
713 #if defined(LWS_WITH_PEER_LIMITS)
714 struct lws_peer *peer;
715 #endif
716
717 #if defined(LWS_WITH_UDP)
718 struct lws_udp *udp;
719 #endif
720 #if defined(LWS_WITH_CLIENT)
721 struct client_info_stash *stash;
722 char *cli_hostname_copy;
723
724 #if defined(LWS_WITH_CONMON)
725 struct lws_conmon conmon;
726 lws_usec_t conmon_datum;
727 #endif
728 #endif /* WITH_CLIENT */
729 void *user_space;
730 void *opaque_parent_data;
731
732 struct lws_buflist *buflist; /* input-side buflist */
733 struct lws_buflist *buflist_out; /* output-side buflist */
734
735 #if defined(LWS_WITH_TLS)
736 struct lws_lws_tls tls;
737 char alpn[24];
738 #endif
739
740 lws_sock_file_fd_type desc; /* .filefd / .sockfd */
741
742 lws_wsi_state_t wsistate;
743 lws_wsi_state_t wsistate_pre_close;
744
745 /* ints */
746 #define LWS_NO_FDS_POS (-1)
747 int position_in_fds_table;
748
749 #if defined(LWS_WITH_CLIENT)
750 int chunk_remaining;
751 int flags;
752 #endif
753 unsigned int cache_secs;
754
755 short bugcatcher;
756
757 unsigned int hdr_parsing_completed:1;
758 unsigned int mux_substream:1;
759 unsigned int upgraded_to_http2:1;
760 unsigned int mux_stream_immortal:1;
761 unsigned int h2_stream_carries_ws:1; /* immortal set as well */
762 unsigned int h2_stream_carries_sse:1; /* immortal set as well */
763 unsigned int h2_acked_settings:1;
764 unsigned int seen_nonpseudoheader:1;
765 unsigned int listener:1;
766 unsigned int pf_packet:1;
767 unsigned int do_broadcast:1;
768 unsigned int user_space_externally_allocated:1;
769 unsigned int socket_is_permanently_unusable:1;
770 unsigned int rxflow_change_to:2;
771 unsigned int conn_stat_done:1;
772 unsigned int cache_reuse:1;
773 unsigned int cache_revalidate:1;
774 unsigned int cache_intermediaries:1;
775 unsigned int favoured_pollin:1;
776 unsigned int sending_chunked:1;
777 unsigned int interpreting:1;
778 unsigned int already_did_cce:1;
779 unsigned int told_user_closed:1;
780 unsigned int told_event_loop_closed:1;
781 unsigned int waiting_to_send_close_frame:1;
782 unsigned int close_needs_ack:1;
783 unsigned int ipv6:1;
784 unsigned int parent_pending_cb_on_writable:1;
785 unsigned int cgi_stdout_zero_length:1;
786 unsigned int seen_zero_length_recv:1;
787 unsigned int rxflow_will_be_applied:1;
788 unsigned int event_pipe:1;
789 unsigned int handling_404:1;
790 unsigned int protocol_bind_balance:1;
791 unsigned int unix_skt:1;
792 unsigned int close_when_buffered_out_drained:1;
793 unsigned int h1_ws_proxied:1;
794 unsigned int proxied_ws_parent:1;
795 unsigned int do_bind:1;
796 unsigned int validity_hup:1;
797 unsigned int skip_fallback:1;
798 unsigned int file_desc:1;
799 unsigned int conn_validity_wakesuspend:1;
800 unsigned int dns_reachability:1;
801
802 unsigned int could_have_pending:1; /* detect back-to-back writes */
803 unsigned int outer_will_close:1;
804 unsigned int shadow:1; /* we do not control fd lifecycle at all */
805 #if defined(LWS_WITH_SECURE_STREAMS)
806 unsigned int for_ss:1;
807 unsigned int bound_ss_proxy_conn:1;
808 unsigned int client_bound_sspc:1;
809 unsigned int client_proxy_onward:1;
810 #endif
811 unsigned int tls_borrowed:1;
812 unsigned int tls_borrowed_hs:1;
813 unsigned int tls_read_wanted_write:1;
814
815 #ifdef LWS_WITH_ACCESS_LOG
816 unsigned int access_log_pending:1;
817 #endif
818 #if defined(LWS_WITH_CLIENT)
819 unsigned int do_ws:1; /* whether we are doing http or ws flow */
820 unsigned int chunked:1; /* if the clientside connection is chunked */
821 unsigned int client_rx_avail:1;
822 unsigned int client_http_body_pending:1;
823 unsigned int transaction_from_pipeline_queue:1;
824 unsigned int keepalive_active:1;
825 unsigned int keepalive_rejected:1;
826 unsigned int redirected_to_get:1;
827 unsigned int client_pipeline:1;
828 unsigned int client_h2_alpn:1;
829 unsigned int client_mux_substream:1;
830 unsigned int client_mux_migrated:1;
831 unsigned int client_subsequent_mime_part:1;
832 unsigned int client_no_follow_redirect:1;
833 unsigned int client_suppress_CONNECTION_ERROR:1;
834 /**< because the client connection creation api is still the parent of
835 * this activity, and will report the failure */
836 unsigned int tls_session_reused:1;
837 unsigned int perf_done:1;
838 unsigned int close_is_redirect:1;
839 unsigned int client_mux_substream_was:1;
840 #endif
841
842 #ifdef _WIN32
843 unsigned int sock_send_blocking:1;
844 #endif
845
846 uint16_t ocport, c_port, conn_port;
847 uint16_t retry;
848 #if defined(LWS_WITH_CLIENT)
849 uint16_t keep_warm_secs;
850 #endif
851
852 /* chars */
853
854 char lws_rx_parse_state; /* enum lws_rx_parse_state */
855 char rx_frame_type; /* enum lws_write_protocol */
856 char pending_timeout; /* enum pending_timeout */
857 char tsi; /* thread service index we belong to */
858 char protocol_interpret_idx;
859 char redirects;
860 uint8_t rxflow_bitmap;
861 uint8_t bound_vhost_index;
862 uint8_t lsp_channel; /* which of stdin/out/err */
863 #ifdef LWS_WITH_CGI
864 char hdr_state;
865 #endif
866 #if defined(LWS_WITH_CLIENT)
867 char chunk_parser; /* enum lws_chunk_parser */
868 uint8_t addrinfo_idx;
869 uint8_t sys_tls_client_cert;
870 uint8_t c_pri;
871 #endif
872 uint8_t af;
873 #if defined(LWS_WITH_CGI) || defined(LWS_WITH_CLIENT)
874 char reason_bf; /* internal writeable callback reason bitfield */
875 #endif
876 #if defined(LWS_WITH_NETLINK)
877 lws_route_uidx_t peer_route_uidx;
878 /**< unique index of the route the connection is estimated to take */
879 #endif
880 uint8_t immortal_substream_count;
881 /* volatile to make sure code is aware other thread can change */
882 volatile char handling_pollout;
883 volatile char leave_pollout_active;
884 #if LWS_MAX_SMP > 1
885 volatile char undergoing_init_from_other_pt;
886 #endif
887
888 };
889
890 #define lws_is_flowcontrolled(w) (!!(wsi->rxflow_bitmap))
891
892 #if defined(LWS_WITH_SPAWN)
893
894 #if defined(WIN32) || defined(_WIN32)
895 #else
896 #include <sys/wait.h>
897 #include <sys/times.h>
898 #endif
899
900 struct lws_spawn_piped {
901
902 struct lws_spawn_piped_info info;
903
904 struct lws_dll2 dll;
905 lws_sorted_usec_list_t sul;
906 lws_sorted_usec_list_t sul_reap;
907
908 struct lws_context *context;
909 struct lws *stdwsi[3];
910 lws_filefd_type pipe_fds[3][2];
911 int count_log_lines;
912
913 lws_usec_t created; /* set by lws_spawn_piped() */
914 lws_usec_t reaped;
915
916 lws_usec_t accounting[4];
917
918 #if defined(WIN32)
919 HANDLE child_pid;
920 lws_sorted_usec_list_t sul_poll;
921 #else
922 pid_t child_pid;
923
924 siginfo_t si;
925 #endif
926 int reap_retry_budget;
927
928 uint8_t pipes_alive:2;
929 uint8_t we_killed_him_timeout:1;
930 uint8_t we_killed_him_spew:1;
931 uint8_t ungraceful:1;
932 };
933
934 void
935 lws_spawn_piped_destroy(struct lws_spawn_piped **lsp);
936
937 int
938 lws_spawn_reap(struct lws_spawn_piped *lsp);
939
940 #endif
941
942 void
943 lws_service_do_ripe_rxflow(struct lws_context_per_thread *pt);
944
945 const struct lws_role_ops *
946 lws_role_by_name(const char *name);
947
948 int
949 lws_socket_bind(struct lws_vhost *vhost, struct lws *wsi,
950 lws_sockfd_type sockfd, int port, const char *iface,
951 int ipv6_allowed);
952
953 #if defined(LWS_WITH_SYS_FAULT_INJECTION)
954 void
955 lws_wsi_fault_timedclose(struct lws *wsi);
956 #else
957 #define lws_wsi_fault_timedclose(_w)
958 #endif
959
960 #if defined(LWS_WITH_IPV6)
961 unsigned long
962 lws_get_addr_scope(struct lws *wsi, const char *ipaddr);
963 #endif
964
965 void
966 lws_close_free_wsi(struct lws *wsi, enum lws_close_status, const char *caller);
967 void
968 __lws_close_free_wsi(struct lws *wsi, enum lws_close_status, const char *caller);
969
970 void
971 __lws_free_wsi(struct lws *wsi);
972
973 void
974 lws_conmon_addrinfo_destroy(struct addrinfo *ai);
975
976 int
977 lws_conmon_append_copy_new_dns_results(struct lws *wsi,
978 const struct addrinfo *cai);
979
980 #if LWS_MAX_SMP > 1
981
982 static LWS_INLINE void
lws_pt_mutex_init(struct lws_context_per_thread * pt)983 lws_pt_mutex_init(struct lws_context_per_thread *pt)
984 {
985 lws_mutex_refcount_init(&pt->mr);
986 pthread_mutex_init(&pt->lock_stats, NULL);
987 }
988
989 static LWS_INLINE void
lws_pt_mutex_destroy(struct lws_context_per_thread * pt)990 lws_pt_mutex_destroy(struct lws_context_per_thread *pt)
991 {
992 pthread_mutex_destroy(&pt->lock_stats);
993 lws_mutex_refcount_destroy(&pt->mr);
994 }
995
996 #define lws_pt_lock(pt, reason) lws_mutex_refcount_lock(&pt->mr, reason)
997 #define lws_pt_unlock(pt) lws_mutex_refcount_unlock(&pt->mr)
998 #define lws_pt_assert_lock_held(pt) lws_mutex_refcount_assert_held(&pt->mr)
999
1000 static LWS_INLINE void
lws_pt_stats_lock(struct lws_context_per_thread * pt)1001 lws_pt_stats_lock(struct lws_context_per_thread *pt)
1002 {
1003 pthread_mutex_lock(&pt->lock_stats);
1004 }
1005
1006 static LWS_INLINE void
lws_pt_stats_unlock(struct lws_context_per_thread * pt)1007 lws_pt_stats_unlock(struct lws_context_per_thread *pt)
1008 {
1009 pthread_mutex_unlock(&pt->lock_stats);
1010 }
1011 #endif
1012
1013 /*
1014 * EXTENSIONS
1015 */
1016
1017 #if defined(LWS_WITHOUT_EXTENSIONS)
1018 #define lws_any_extension_handled(_a, _b, _c, _d) (0)
1019 #define lws_ext_cb_active(_a, _b, _c, _d) (0)
1020 #define lws_ext_cb_all_exts(_a, _b, _c, _d, _e) (0)
1021 #define lws_issue_raw_ext_access lws_issue_raw
1022 #define lws_context_init_extensions(_a, _b)
1023 #endif
1024
1025 int LWS_WARN_UNUSED_RESULT
1026 lws_client_interpret_server_handshake(struct lws *wsi);
1027
1028 int LWS_WARN_UNUSED_RESULT
1029 lws_ws_rx_sm(struct lws *wsi, char already_processed, unsigned char c);
1030
1031 int LWS_WARN_UNUSED_RESULT
1032 lws_issue_raw_ext_access(struct lws *wsi, unsigned char *buf, size_t len);
1033
1034 void
1035 lws_role_transition(struct lws *wsi, enum lwsi_role role, enum lwsi_state state,
1036 const struct lws_role_ops *ops);
1037
1038 int
1039 lws_http_to_fallback(struct lws *wsi, unsigned char *buf, size_t len);
1040
1041 int LWS_WARN_UNUSED_RESULT
1042 user_callback_handle_rxflow(lws_callback_function, struct lws *wsi,
1043 enum lws_callback_reasons reason, void *user,
1044 void *in, size_t len);
1045
1046 int
1047 lws_plat_set_nonblocking(lws_sockfd_type fd);
1048
1049 int
1050 lws_plat_set_socket_options(struct lws_vhost *vhost, lws_sockfd_type fd,
1051 int unix_skt);
1052
1053 int
1054 lws_plat_set_socket_options_ip(lws_sockfd_type fd, uint8_t pri, int lws_flags);
1055
1056 int
1057 lws_plat_check_connection_error(struct lws *wsi);
1058
1059 int LWS_WARN_UNUSED_RESULT
1060 lws_header_table_attach(struct lws *wsi, int autoservice);
1061
1062 int
1063 lws_header_table_detach(struct lws *wsi, int autoservice);
1064 int
1065 __lws_header_table_detach(struct lws *wsi, int autoservice);
1066
1067 void
1068 lws_header_table_reset(struct lws *wsi, int autoservice);
1069
1070 void
1071 __lws_header_table_reset(struct lws *wsi, int autoservice);
1072
1073 char * LWS_WARN_UNUSED_RESULT
1074 lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h);
1075
1076 int LWS_WARN_UNUSED_RESULT
1077 lws_hdr_simple_create(struct lws *wsi, enum lws_token_indexes h, const char *s);
1078
1079 int LWS_WARN_UNUSED_RESULT
1080 lws_ensure_user_space(struct lws *wsi);
1081
1082 int LWS_WARN_UNUSED_RESULT
1083 lws_change_pollfd(struct lws *wsi, int _and, int _or);
1084
1085 #if defined(LWS_WITH_SERVER)
1086 int _lws_vhost_init_server(const struct lws_context_creation_info *info,
1087 struct lws_vhost *vhost);
1088 struct lws_vhost *
1089 lws_select_vhost(struct lws_context *context, int port, const char *servername);
1090 int LWS_WARN_UNUSED_RESULT
1091 lws_parse_ws(struct lws *wsi, unsigned char **buf, size_t len);
1092 void
1093 lws_server_get_canonical_hostname(struct lws_context *context,
1094 const struct lws_context_creation_info *info);
1095 #else
1096 #define _lws_vhost_init_server(_a, _b) (0)
1097 #define lws_parse_ws(_a, _b, _c) (0)
1098 #define lws_server_get_canonical_hostname(_a, _b)
1099 #endif
1100
1101 int
1102 __remove_wsi_socket_from_fds(struct lws *wsi);
1103
1104 enum {
1105 LWSRXFC_ERROR = -1,
1106 LWSRXFC_CACHED = 0,
1107 LWSRXFC_ADDITIONAL = 1,
1108 LWSRXFC_TRIMMED = 2,
1109 };
1110
1111
1112 int
1113 _lws_plat_service_forced_tsi(struct lws_context *context, int tsi);
1114
1115 int
1116 lws_rxflow_cache(struct lws *wsi, unsigned char *buf, size_t n, size_t len);
1117
1118 int
1119 lws_service_flag_pending(struct lws_context *context, int tsi);
1120
1121 int
1122 lws_has_buffered_out(struct lws *wsi);
1123
1124 int LWS_WARN_UNUSED_RESULT
1125 lws_ws_client_rx_sm(struct lws *wsi, unsigned char c);
1126
1127 lws_parser_return_t LWS_WARN_UNUSED_RESULT
1128 lws_parse(struct lws *wsi, unsigned char *buf, int *len);
1129
1130 int LWS_WARN_UNUSED_RESULT
1131 lws_parse_urldecode(struct lws *wsi, uint8_t *_c);
1132
1133 void
1134 lws_sa46_copy_address(lws_sockaddr46 *sa46a, const void *in, int af);
1135
1136 int LWS_WARN_UNUSED_RESULT
1137 lws_http_action(struct lws *wsi);
1138
1139 void
1140 __lws_close_free_wsi_final(struct lws *wsi);
1141 void
1142 lws_libuv_closehandle(struct lws *wsi);
1143 int
1144 lws_libuv_check_watcher_active(struct lws *wsi);
1145
1146 #if defined(LWS_WITH_EVLIB_PLUGINS) || defined(LWS_WITH_PLUGINS)
1147 const lws_plugin_header_t *
1148 lws_plat_dlopen(struct lws_plugin **pplugin, const char *libpath,
1149 const char *sofilename, const char *_class,
1150 each_plugin_cb_t each, void *each_user);
1151
1152 int
1153 lws_plat_destroy_dl(struct lws_plugin *p);
1154 #endif
1155
1156 struct lws *
1157 lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd);
1158
1159 void
1160 lws_vhost_bind_wsi(struct lws_vhost *vh, struct lws *wsi);
1161 void
1162 __lws_vhost_unbind_wsi(struct lws *wsi); /* req cx + vh lock */
1163
1164 void
1165 __lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs);
1166 int
1167 __lws_change_pollfd(struct lws *wsi, int _and, int _or);
1168
1169
1170 int
1171 lws_callback_as_writeable(struct lws *wsi);
1172
1173 int
1174 lws_role_call_client_bind(struct lws *wsi,
1175 const struct lws_client_connect_info *i);
1176 void
1177 lws_remove_child_from_any_parent(struct lws *wsi);
1178
1179 char *
1180 lws_generate_client_ws_handshake(struct lws *wsi, char *p, const char *conn1);
1181 int
1182 lws_client_ws_upgrade(struct lws *wsi, const char **cce);
1183 int
1184 lws_create_client_ws_object(const struct lws_client_connect_info *i,
1185 struct lws *wsi);
1186 int
1187 lws_alpn_comma_to_openssl(const char *comma, uint8_t *os, int len);
1188 int
1189 lws_role_call_alpn_negotiated(struct lws *wsi, const char *alpn);
1190 int
1191 lws_tls_server_conn_alpn(struct lws *wsi);
1192
1193 int
1194 lws_ws_client_rx_sm_block(struct lws *wsi, unsigned char **buf, size_t len);
1195 void
1196 lws_destroy_event_pipe(struct lws *wsi);
1197
1198 /* socks */
1199 int
1200 lws_socks5c_generate_msg(struct lws *wsi, enum socks_msg_type type, ssize_t *msg_len);
1201
1202 int LWS_WARN_UNUSED_RESULT
1203 __insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi);
1204
1205 int LWS_WARN_UNUSED_RESULT
1206 lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len);
1207
1208 lws_usec_t
1209 __lws_seq_timeout_check(struct lws_context_per_thread *pt, lws_usec_t usnow);
1210
1211 lws_usec_t
1212 __lws_ss_timeout_check(struct lws_context_per_thread *pt, lws_usec_t usnow);
1213
1214 struct lws * LWS_WARN_UNUSED_RESULT
1215 lws_client_connect_2_dnsreq(struct lws *wsi);
1216
1217 LWS_VISIBLE struct lws * LWS_WARN_UNUSED_RESULT
1218 lws_client_reset(struct lws **wsi, int ssl, const char *address, int port,
1219 const char *path, const char *host, char weak);
1220
1221 struct lws * LWS_WARN_UNUSED_RESULT
1222 lws_create_new_server_wsi(struct lws_vhost *vhost, int fixed_tsi, const char *desc);
1223
1224 char * LWS_WARN_UNUSED_RESULT
1225 lws_generate_client_handshake(struct lws *wsi, char *pkt);
1226
1227 int
1228 lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd);
1229
1230 struct lws *
1231 lws_http_client_connect_via_info2(struct lws *wsi);
1232
1233
1234 struct lws *
1235 __lws_wsi_create_with_role(struct lws_context *context, int tsi,
1236 const struct lws_role_ops *ops,
1237 lws_log_cx_t *log_cx_template);
1238 int
1239 lws_wsi_inject_to_loop(struct lws_context_per_thread *pt, struct lws *wsi);
1240
1241 int
1242 lws_wsi_extract_from_loop(struct lws *wsi);
1243
1244
1245 #if defined(LWS_WITH_CLIENT)
1246 int
1247 lws_http_client_socket_service(struct lws *wsi, struct lws_pollfd *pollfd);
1248
1249 int LWS_WARN_UNUSED_RESULT
1250 lws_http_transaction_completed_client(struct lws *wsi);
1251 #if !defined(LWS_WITH_TLS)
1252 #define lws_context_init_client_ssl(_a, _b) (0)
1253 #endif
1254 void
1255 lws_decode_ssl_error(void);
1256 #else
1257 #define lws_context_init_client_ssl(_a, _b) (0)
1258 #endif
1259
1260 int
1261 __lws_rx_flow_control(struct lws *wsi);
1262
1263 int
1264 _lws_change_pollfd(struct lws *wsi, int _and, int _or, struct lws_pollargs *pa);
1265
1266 #if defined(LWS_WITH_SERVER)
1267 int
1268 lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len);
1269 #else
1270 #define lws_server_socket_service(_b, _c) (0)
1271 #define lws_handshake_server(_a, _b, _c) (0)
1272 #endif
1273
1274 #ifdef LWS_WITH_ACCESS_LOG
1275 int
1276 lws_access_log(struct lws *wsi);
1277 void
1278 lws_prepare_access_log_info(struct lws *wsi, char *uri_ptr, int len, int meth);
1279 #else
1280 #define lws_access_log(_a)
1281 #endif
1282
1283 #if defined(_DEBUG)
1284 void
1285 lws_wsi_txc_describe(struct lws_tx_credit *txc, const char *at, uint32_t sid);
1286 #else
1287 #define lws_wsi_txc_describe(x, y, z) { (void)x; }
1288 #endif
1289
1290 int
1291 lws_wsi_txc_check_skint(struct lws_tx_credit *txc, int32_t tx_cr);
1292
1293 int
1294 lws_wsi_txc_report_manual_txcr_in(struct lws *wsi, int32_t bump);
1295
1296 void
1297 lws_mux_mark_immortal(struct lws *wsi);
1298 void
1299 lws_http_close_immortal(struct lws *wsi);
1300
1301 int
1302 lws_cgi_kill_terminated(struct lws_context_per_thread *pt);
1303
1304 void
1305 lws_cgi_remove_and_kill(struct lws *wsi);
1306
1307 void
1308 lws_plat_delete_socket_from_fds(struct lws_context *context,
1309 struct lws *wsi, int m);
1310 void
1311 lws_plat_insert_socket_into_fds(struct lws_context *context,
1312 struct lws *wsi);
1313
1314 int
1315 lws_plat_change_pollfd(struct lws_context *context, struct lws *wsi,
1316 struct lws_pollfd *pfd);
1317
1318 #if defined(LWS_WITH_SERVER) && defined(LWS_WITH_SECURE_STREAMS)
1319 int
1320 lws_adopt_ss_server_accept(struct lws *new_wsi);
1321 #endif
1322
1323 int
1324 lws_plat_pipe_create(struct lws *wsi);
1325 int
1326 lws_plat_pipe_signal(struct lws_context *ctx, int tsi);
1327 void
1328 lws_plat_pipe_close(struct lws *wsi);
1329
1330 void
1331 lws_addrinfo_clean(struct lws *wsi);
1332
1333 void
1334 lws_add_wsi_to_draining_ext_list(struct lws *wsi);
1335 void
1336 lws_remove_wsi_from_draining_ext_list(struct lws *wsi);
1337 int
1338 lws_poll_listen_fd(struct lws_pollfd *fd);
1339 int
1340 lws_plat_service(struct lws_context *context, int timeout_ms);
1341 LWS_VISIBLE int
1342 _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi);
1343
1344 int
1345 lws_pthread_self_to_tsi(struct lws_context *context);
1346 const char * LWS_WARN_UNUSED_RESULT
1347 lws_plat_inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
1348 int LWS_WARN_UNUSED_RESULT
1349 lws_plat_inet_pton(int af, const char *src, void *dst);
1350
1351 void
1352 lws_same_vh_protocol_remove(struct lws *wsi);
1353 void
1354 __lws_same_vh_protocol_remove(struct lws *wsi);
1355 void
1356 lws_same_vh_protocol_insert(struct lws *wsi, int n);
1357
1358 int
1359 lws_client_stash_create(struct lws *wsi, const char **cisin);
1360
1361 void
1362 lws_seq_destroy_all_on_pt(struct lws_context_per_thread *pt);
1363
1364 void
1365 lws_addrinfo_clean(struct lws *wsi);
1366
1367 int
1368 _lws_route_pt_close_unroutable(struct lws_context_per_thread *pt);
1369
1370 void
1371 _lws_routing_entry_dump(struct lws_context *cx, lws_route_t *rou);
1372
1373 void
1374 _lws_routing_table_dump(struct lws_context *cx);
1375
1376 #define LRR_IGNORE_PRI (1 << 0)
1377 #define LRR_MATCH_SRC (1 << 1)
1378 #define LRR_MATCH_DST (1 << 2)
1379
1380 lws_route_t *
1381 _lws_route_remove(struct lws_context_per_thread *pt, lws_route_t *robj, int flags);
1382
1383 void
1384 _lws_route_table_empty(struct lws_context_per_thread *pt);
1385
1386 void
1387 _lws_route_table_ifdown(struct lws_context_per_thread *pt, int idx);
1388
1389 lws_route_uidx_t
1390 _lws_route_get_uidx(struct lws_context *cx);
1391
1392 int
1393 _lws_route_pt_close_route_users(struct lws_context_per_thread *pt,
1394 lws_route_uidx_t uidx);
1395
1396 lws_route_t *
1397 _lws_route_est_outgoing(struct lws_context_per_thread *pt,
1398 const lws_sockaddr46 *dest);
1399
1400 int
1401 lws_sort_dns(struct lws *wsi, const struct addrinfo *result);
1402
1403 int
1404 lws_broadcast(struct lws_context_per_thread *pt, int reason, void *in, size_t len);
1405
1406
1407 #if defined(LWS_WITH_PEER_LIMITS)
1408 void
1409 lws_peer_track_wsi_close(struct lws_context *context, struct lws_peer *peer);
1410 int
1411 lws_peer_confirm_ah_attach_ok(struct lws_context *context,
1412 struct lws_peer *peer);
1413 void
1414 lws_peer_track_ah_detach(struct lws_context *context, struct lws_peer *peer);
1415 void
1416 lws_peer_cull_peer_wait_list(struct lws_context *context);
1417 struct lws_peer *
1418 lws_get_or_create_peer(struct lws_vhost *vhost, lws_sockfd_type sockfd);
1419 void
1420 lws_peer_add_wsi(struct lws_context *context, struct lws_peer *peer,
1421 struct lws *wsi);
1422 void
1423 lws_peer_dump_from_wsi(struct lws *wsi);
1424 #endif
1425
1426 #ifdef LWS_WITH_HUBBUB
1427 hubbub_error
1428 html_parser_cb(const hubbub_token *token, void *pw);
1429 #endif
1430
1431 #if defined(_DEBUG)
1432 void
1433 lws_service_assert_loop_thread(struct lws_context *cx, int tsi);
1434 #else
1435 #define lws_service_assert_loop_thread(_cx, _tsi)
1436 #endif
1437
1438 int
1439 lws_threadpool_tsi_context(struct lws_context *context, int tsi);
1440
1441 void
1442 lws_threadpool_wsi_closing(struct lws *wsi);
1443
1444 void
1445 __lws_wsi_remove_from_sul(struct lws *wsi);
1446
1447 void
1448 lws_validity_confirmed(struct lws *wsi);
1449 void
1450 _lws_validity_confirmed_role(struct lws *wsi);
1451
1452 int
1453 lws_seq_pt_init(struct lws_context_per_thread *pt);
1454
1455 int
1456 lws_buflist_aware_read(struct lws_context_per_thread *pt, struct lws *wsi,
1457 struct lws_tokens *ebuf, char fr, const char *hint);
1458 int
1459 lws_buflist_aware_finished_consuming(struct lws *wsi, struct lws_tokens *ebuf,
1460 int used, int buffered, const char *hint);
1461
1462 extern const struct lws_protocols protocol_abs_client_raw_skt,
1463 protocol_abs_client_unit_test;
1464
1465 void
1466 __lws_reset_wsi(struct lws *wsi);
1467
1468 void
1469 lws_metrics_dump(struct lws_context *ctx);
1470
1471 void
1472 lws_inform_client_conn_fail(struct lws *wsi, void *arg, size_t len);
1473
1474 #if defined(LWS_WITH_SYS_ASYNC_DNS)
1475 lws_async_dns_server_check_t
1476 lws_plat_asyncdns_init(struct lws_context *context, lws_sockaddr46 *sa);
1477 int
1478 lws_async_dns_init(struct lws_context *context);
1479 void
1480 lws_async_dns_deinit(lws_async_dns_t *dns);
1481 #endif
1482
1483 int
1484 lws_protocol_init_vhost(struct lws_vhost *vh, int *any);
1485 int
1486 _lws_generic_transaction_completed_active_conn(struct lws **wsi, char take_vh_lock);
1487
1488 #define ACTIVE_CONNS_SOLO 0
1489 #define ACTIVE_CONNS_MUXED 1
1490 #define ACTIVE_CONNS_QUEUED 2
1491 #define ACTIVE_CONNS_FAILED 3
1492
1493 #if defined(_DEBUG) && !defined(LWS_PLAT_FREERTOS) && !defined(WIN32) && !defined(LWS_PLAT_OPTEE)
1494
1495 int
1496 sanity_assert_no_wsi_traces(const struct lws_context *context, struct lws *wsi);
1497 int
1498 sanity_assert_no_sockfd_traces(const struct lws_context *context,
1499 lws_sockfd_type sfd);
1500 #else
sanity_assert_no_wsi_traces(const struct lws_context * context,struct lws * wsi)1501 static inline int sanity_assert_no_wsi_traces(const struct lws_context *context, struct lws *wsi) { (void)context; (void)wsi; return 0; }
sanity_assert_no_sockfd_traces(const struct lws_context * context,lws_sockfd_type sfd)1502 static inline int sanity_assert_no_sockfd_traces(const struct lws_context *context, lws_sockfd_type sfd) { (void)context; (void)sfd; return 0; }
1503 #endif
1504
1505
1506 void
1507 delete_from_fdwsi(const struct lws_context *context, struct lws *wsi);
1508
1509 int
1510 lws_vhost_active_conns(struct lws *wsi, struct lws **nwsi, const char *adsin);
1511
1512 const char *
1513 lws_wsi_client_stash_item(struct lws *wsi, int stash_idx, int hdr_idx);
1514
1515 int
1516 lws_plat_BINDTODEVICE(lws_sockfd_type fd, const char *ifname);
1517
1518 int
1519 lws_socks5c_ads_server(struct lws_vhost *vh,
1520 const struct lws_context_creation_info *info);
1521
1522 int
1523 lws_socks5c_handle_state(struct lws *wsi, struct lws_pollfd *pollfd,
1524 const char **pcce);
1525
1526 int
1527 lws_socks5c_greet(struct lws *wsi, const char **pcce);
1528
1529 int
1530 lws_plat_mbedtls_net_send(void *ctx, const uint8_t *buf, size_t len);
1531
1532 int
1533 lws_plat_mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len);
1534
1535 lws_usec_t
1536 lws_sul_nonmonotonic_adjust(struct lws_context *ctx, int64_t step_us);
1537
1538 void
1539 __lws_vhost_destroy_pt_wsi_dieback_start(struct lws_vhost *vh);
1540
1541 int
1542 lws_vhost_compare_listen(struct lws_vhost *v1, struct lws_vhost *v2);
1543
1544 void
1545 lws_netdev_instance_remove_destroy(struct lws_netdev_instance *ni);
1546
1547 int
1548 lws_score_dns_results(struct lws_context *ctx,
1549 const struct addrinfo **result);
1550
1551 #if defined(LWS_WITH_SYS_SMD)
1552 int
1553 lws_netdev_smd_cb(void *opaque, lws_smd_class_t _class, lws_usec_t timestamp,
1554 void *buf, size_t len);
1555 #endif
1556
1557 void
1558 lws_netdev_instance_create(lws_netdev_instance_t *ni, struct lws_context *ctx,
1559 const lws_netdev_ops_t *ops, const char *name,
1560 void *platinfo);
1561
1562 int
1563 lws_netdev_wifi_rssi_sort_compare(const lws_dll2_t *d, const lws_dll2_t *i);
1564 void
1565 lws_netdev_wifi_scan_empty(lws_netdev_instance_wifi_t *wnd);
1566
1567 lws_wifi_sta_t *
1568 lws_netdev_wifi_scan_find(lws_netdev_instance_wifi_t *wnd, const char *ssid,
1569 const uint8_t *bssid);
1570
1571 int
1572 lws_netdev_wifi_scan_select(lws_netdev_instance_wifi_t *wnd);
1573
1574 lws_wifi_creds_t *
1575 lws_netdev_credentials_find(lws_netdevs_t *netdevs, const char *ssid,
1576 const uint8_t *bssid);
1577
1578 int
1579 lws_netdev_wifi_redo_last(lws_netdev_instance_wifi_t *wnd);
1580
1581 void
1582 lws_ntpc_trigger(struct lws_context *ctx);
1583
1584 void
1585 lws_netdev_wifi_scan(lws_sorted_usec_list_t *sul);
1586
1587 #define lws_netdevs_from_ndi(ni) \
1588 lws_container_of((ni)->list.owner, lws_netdevs_t, owner)
1589
1590 #define lws_context_from_netdevs(nd) \
1591 lws_container_of(nd, struct lws_context, netdevs)
1592
1593 /* get the owner of the ni, then compute the context the owner is embedded in */
1594 #define netdev_instance_to_ctx(ni) \
1595 lws_container_of(lws_netdevs_from_ndi(ni), \
1596 struct lws_context, netdevs)
1597
1598 enum {
1599 LW5CHS_RET_RET0,
1600 LW5CHS_RET_BAIL3,
1601 LW5CHS_RET_STARTHS,
1602 LW5CHS_RET_NOTHING
1603 };
1604
1605 void
1606 lws_4to6(uint8_t *v6addr, const uint8_t *v4addr);
1607 void
1608 lws_sa46_4to6(lws_sockaddr46 *sa46, const uint8_t *v4addr, uint16_t port);
1609
1610 #ifdef __cplusplus
1611 };
1612 #endif
1613
1614 #endif
1615