xref: /aosp_15_r20/external/libwebsockets/lib/roles/private-lib-roles.h (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker  * libwebsockets - small server side websockets and web server implementation
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker  * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker  * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker  *
13*1c60b9acSAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker  *
16*1c60b9acSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker  * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker  */
24*1c60b9acSAndroid Build Coastguard Worker 
25*1c60b9acSAndroid Build Coastguard Worker typedef uint32_t lws_wsi_state_t;
26*1c60b9acSAndroid Build Coastguard Worker 
27*1c60b9acSAndroid Build Coastguard Worker /*
28*1c60b9acSAndroid Build Coastguard Worker  * The wsi->role_ops pointer decides almost everything about what role the wsi
29*1c60b9acSAndroid Build Coastguard Worker  * will play, h2, raw, ws, etc.
30*1c60b9acSAndroid Build Coastguard Worker  *
31*1c60b9acSAndroid Build Coastguard Worker  * However there are a few additional flags needed that vary, such as if the
32*1c60b9acSAndroid Build Coastguard Worker  * role is a client or server side, if it has that concept.  And the connection
33*1c60b9acSAndroid Build Coastguard Worker  * fulfilling the role, has a separate dynamic state.
34*1c60b9acSAndroid Build Coastguard Worker  *
35*1c60b9acSAndroid Build Coastguard Worker  *   31           16 15      0
36*1c60b9acSAndroid Build Coastguard Worker  *   [  role flags ] [ state ]
37*1c60b9acSAndroid Build Coastguard Worker  *
38*1c60b9acSAndroid Build Coastguard Worker  * The role flags part is generally invariant for the lifetime of the wsi,
39*1c60b9acSAndroid Build Coastguard Worker  * although it can change if the connection role itself does, eg, if the
40*1c60b9acSAndroid Build Coastguard Worker  * connection upgrades from H1 -> WS1 the role flags may be changed at that
41*1c60b9acSAndroid Build Coastguard Worker  * point.
42*1c60b9acSAndroid Build Coastguard Worker  *
43*1c60b9acSAndroid Build Coastguard Worker  * The state part reflects the dynamic connection state, and the states are
44*1c60b9acSAndroid Build Coastguard Worker  * reused between roles.
45*1c60b9acSAndroid Build Coastguard Worker  *
46*1c60b9acSAndroid Build Coastguard Worker  * None of the internal role or state representations are made available outside
47*1c60b9acSAndroid Build Coastguard Worker  * of lws internals.  Even for lws internals, if you add stuff here, please keep
48*1c60b9acSAndroid Build Coastguard Worker  * the constants inside this header only by adding necessary helpers here and
49*1c60b9acSAndroid Build Coastguard Worker  * use the helpers in the actual code.  This is to ease any future refactors.
50*1c60b9acSAndroid Build Coastguard Worker  *
51*1c60b9acSAndroid Build Coastguard Worker  * Notice LWSIFR_ENCAP means we have a parent wsi that actually carries our
52*1c60b9acSAndroid Build Coastguard Worker  * data as a stream inside a different protocol.
53*1c60b9acSAndroid Build Coastguard Worker  */
54*1c60b9acSAndroid Build Coastguard Worker 
55*1c60b9acSAndroid Build Coastguard Worker #define _RS 16
56*1c60b9acSAndroid Build Coastguard Worker 
57*1c60b9acSAndroid Build Coastguard Worker #define LWSIFR_CLIENT		(0x1000 << _RS) /* client side */
58*1c60b9acSAndroid Build Coastguard Worker #define LWSIFR_SERVER		(0x2000 << _RS) /* server side */
59*1c60b9acSAndroid Build Coastguard Worker 
60*1c60b9acSAndroid Build Coastguard Worker #define LWSIFR_P_ENCAP_H2	(0x0100 << _RS) /* we are encapsulated by h2 */
61*1c60b9acSAndroid Build Coastguard Worker 
62*1c60b9acSAndroid Build Coastguard Worker enum lwsi_role {
63*1c60b9acSAndroid Build Coastguard Worker 	LWSI_ROLE_MASK		=			     (0xffff << _RS),
64*1c60b9acSAndroid Build Coastguard Worker 	LWSI_ROLE_ENCAP_MASK	=			     (0x0f00 << _RS),
65*1c60b9acSAndroid Build Coastguard Worker };
66*1c60b9acSAndroid Build Coastguard Worker 
67*1c60b9acSAndroid Build Coastguard Worker #define lwsi_role(wsi) (wsi->wsistate & (unsigned int)LWSI_ROLE_MASK)
68*1c60b9acSAndroid Build Coastguard Worker #if !defined (_DEBUG)
69*1c60b9acSAndroid Build Coastguard Worker #define lwsi_set_role(wsi, role) wsi->wsistate = \
70*1c60b9acSAndroid Build Coastguard Worker 				(wsi->wsistate & (~LWSI_ROLE_MASK)) | role
71*1c60b9acSAndroid Build Coastguard Worker #else
72*1c60b9acSAndroid Build Coastguard Worker void lwsi_set_role(struct lws *wsi, lws_wsi_state_t role);
73*1c60b9acSAndroid Build Coastguard Worker #endif
74*1c60b9acSAndroid Build Coastguard Worker 
75*1c60b9acSAndroid Build Coastguard Worker #define lwsi_role_client(wsi) (!!(wsi->wsistate & LWSIFR_CLIENT))
76*1c60b9acSAndroid Build Coastguard Worker #define lwsi_role_server(wsi) (!!(wsi->wsistate & LWSIFR_SERVER))
77*1c60b9acSAndroid Build Coastguard Worker #define lwsi_role_h2_ENCAPSULATION(wsi) \
78*1c60b9acSAndroid Build Coastguard Worker 		((wsi->wsistate & LWSI_ROLE_ENCAP_MASK) == LWSIFR_P_ENCAP_H2)
79*1c60b9acSAndroid Build Coastguard Worker 
80*1c60b9acSAndroid Build Coastguard Worker /* Pollout wants a callback in this state */
81*1c60b9acSAndroid Build Coastguard Worker #define LWSIFS_POCB		(0x100)
82*1c60b9acSAndroid Build Coastguard Worker /* Before any protocol connection was established */
83*1c60b9acSAndroid Build Coastguard Worker #define LWSIFS_NOT_EST		(0x200)
84*1c60b9acSAndroid Build Coastguard Worker 
85*1c60b9acSAndroid Build Coastguard Worker enum lwsi_state {
86*1c60b9acSAndroid Build Coastguard Worker 
87*1c60b9acSAndroid Build Coastguard Worker 	/* Phase 1: pre-transport */
88*1c60b9acSAndroid Build Coastguard Worker 
89*1c60b9acSAndroid Build Coastguard Worker 	LRS_UNCONNECTED				= LWSIFS_NOT_EST | 0,
90*1c60b9acSAndroid Build Coastguard Worker 	LRS_WAITING_DNS				= LWSIFS_NOT_EST | 1,
91*1c60b9acSAndroid Build Coastguard Worker 	LRS_WAITING_CONNECT			= LWSIFS_NOT_EST | 2,
92*1c60b9acSAndroid Build Coastguard Worker 
93*1c60b9acSAndroid Build Coastguard Worker 	/* Phase 2: establishing intermediaries on top of transport */
94*1c60b9acSAndroid Build Coastguard Worker 
95*1c60b9acSAndroid Build Coastguard Worker 	LRS_WAITING_PROXY_REPLY			= LWSIFS_NOT_EST | 3,
96*1c60b9acSAndroid Build Coastguard Worker 	LRS_WAITING_SSL				= LWSIFS_NOT_EST | 4,
97*1c60b9acSAndroid Build Coastguard Worker 	LRS_WAITING_SOCKS_GREETING_REPLY	= LWSIFS_NOT_EST | 5,
98*1c60b9acSAndroid Build Coastguard Worker 	LRS_WAITING_SOCKS_CONNECT_REPLY		= LWSIFS_NOT_EST | 6,
99*1c60b9acSAndroid Build Coastguard Worker 	LRS_WAITING_SOCKS_AUTH_REPLY		= LWSIFS_NOT_EST | 7,
100*1c60b9acSAndroid Build Coastguard Worker 
101*1c60b9acSAndroid Build Coastguard Worker 	/* Phase 3: establishing tls tunnel */
102*1c60b9acSAndroid Build Coastguard Worker 
103*1c60b9acSAndroid Build Coastguard Worker 	LRS_SSL_INIT				= LWSIFS_NOT_EST | 8,
104*1c60b9acSAndroid Build Coastguard Worker 	LRS_SSL_ACK_PENDING			= LWSIFS_NOT_EST | 9,
105*1c60b9acSAndroid Build Coastguard Worker 	LRS_PRE_WS_SERVING_ACCEPT		= LWSIFS_NOT_EST | 10,
106*1c60b9acSAndroid Build Coastguard Worker 
107*1c60b9acSAndroid Build Coastguard Worker 	/* Phase 4: connected */
108*1c60b9acSAndroid Build Coastguard Worker 
109*1c60b9acSAndroid Build Coastguard Worker 	LRS_WAITING_SERVER_REPLY		= LWSIFS_NOT_EST | 11,
110*1c60b9acSAndroid Build Coastguard Worker 	LRS_H2_AWAIT_PREFACE			= LWSIFS_NOT_EST | 12,
111*1c60b9acSAndroid Build Coastguard Worker 	LRS_H2_AWAIT_SETTINGS			= LWSIFS_NOT_EST |
112*1c60b9acSAndroid Build Coastguard Worker 						  LWSIFS_POCB | 13,
113*1c60b9acSAndroid Build Coastguard Worker 	LRS_MQTTC_IDLE				= LWSIFS_POCB | 33,
114*1c60b9acSAndroid Build Coastguard Worker 	LRS_MQTTC_AWAIT_CONNACK			= 34,
115*1c60b9acSAndroid Build Coastguard Worker 
116*1c60b9acSAndroid Build Coastguard Worker 	/* Phase 5: protocol logically established */
117*1c60b9acSAndroid Build Coastguard Worker 
118*1c60b9acSAndroid Build Coastguard Worker 	LRS_H2_CLIENT_SEND_SETTINGS		= LWSIFS_POCB | 14,
119*1c60b9acSAndroid Build Coastguard Worker 	LRS_H2_WAITING_TO_SEND_HEADERS		= LWSIFS_POCB | 15,
120*1c60b9acSAndroid Build Coastguard Worker 	LRS_DEFERRING_ACTION			= LWSIFS_POCB | 16,
121*1c60b9acSAndroid Build Coastguard Worker 	LRS_IDLING				= 17,
122*1c60b9acSAndroid Build Coastguard Worker 	LRS_H1C_ISSUE_HANDSHAKE			= 18,
123*1c60b9acSAndroid Build Coastguard Worker 	LRS_H1C_ISSUE_HANDSHAKE2		= 19,
124*1c60b9acSAndroid Build Coastguard Worker 	LRS_ISSUE_HTTP_BODY			= 20,
125*1c60b9acSAndroid Build Coastguard Worker 	LRS_ISSUING_FILE			= 21,
126*1c60b9acSAndroid Build Coastguard Worker 	LRS_HEADERS				= 22,
127*1c60b9acSAndroid Build Coastguard Worker 	LRS_BODY				= 23,
128*1c60b9acSAndroid Build Coastguard Worker 	LRS_DISCARD_BODY			= 24,
129*1c60b9acSAndroid Build Coastguard Worker 	LRS_ESTABLISHED				= LWSIFS_POCB | 25,
130*1c60b9acSAndroid Build Coastguard Worker 
131*1c60b9acSAndroid Build Coastguard Worker 	/* we are established, but we have embarked on serving a single
132*1c60b9acSAndroid Build Coastguard Worker 	 * transaction.  Other transaction input may be pending, but we will
133*1c60b9acSAndroid Build Coastguard Worker 	 * not service it while we are busy dealing with the current
134*1c60b9acSAndroid Build Coastguard Worker 	 * transaction.
135*1c60b9acSAndroid Build Coastguard Worker 	 *
136*1c60b9acSAndroid Build Coastguard Worker 	 * When we complete the current transaction, we would reset our state
137*1c60b9acSAndroid Build Coastguard Worker 	 * back to ESTABLISHED and start to process the next transaction.
138*1c60b9acSAndroid Build Coastguard Worker 	 */
139*1c60b9acSAndroid Build Coastguard Worker 	LRS_DOING_TRANSACTION			= LWSIFS_POCB | 26,
140*1c60b9acSAndroid Build Coastguard Worker 
141*1c60b9acSAndroid Build Coastguard Worker 	/* Phase 6: finishing */
142*1c60b9acSAndroid Build Coastguard Worker 
143*1c60b9acSAndroid Build Coastguard Worker 	LRS_WAITING_TO_SEND_CLOSE		= LWSIFS_POCB | 27,
144*1c60b9acSAndroid Build Coastguard Worker 	LRS_RETURNED_CLOSE			= LWSIFS_POCB | 28,
145*1c60b9acSAndroid Build Coastguard Worker 	LRS_AWAITING_CLOSE_ACK			= LWSIFS_POCB | 29,
146*1c60b9acSAndroid Build Coastguard Worker 	LRS_FLUSHING_BEFORE_CLOSE		= LWSIFS_POCB | 30,
147*1c60b9acSAndroid Build Coastguard Worker 	LRS_SHUTDOWN				= 31,
148*1c60b9acSAndroid Build Coastguard Worker 
149*1c60b9acSAndroid Build Coastguard Worker 	/* Phase 7: dead */
150*1c60b9acSAndroid Build Coastguard Worker 
151*1c60b9acSAndroid Build Coastguard Worker 	LRS_DEAD_SOCKET				= 32,
152*1c60b9acSAndroid Build Coastguard Worker 
153*1c60b9acSAndroid Build Coastguard Worker 	LRS_MASK				= 0xffff
154*1c60b9acSAndroid Build Coastguard Worker };
155*1c60b9acSAndroid Build Coastguard Worker 
156*1c60b9acSAndroid Build Coastguard Worker #define lwsi_state(wsi) ((enum lwsi_state)(wsi->wsistate & LRS_MASK))
157*1c60b9acSAndroid Build Coastguard Worker #define lwsi_state_PRE_CLOSE(wsi) \
158*1c60b9acSAndroid Build Coastguard Worker 		((enum lwsi_state)(wsi->wsistate_pre_close & LRS_MASK))
159*1c60b9acSAndroid Build Coastguard Worker #define lwsi_state_est(wsi) (!(wsi->wsistate & LWSIFS_NOT_EST))
160*1c60b9acSAndroid Build Coastguard Worker #define lwsi_state_est_PRE_CLOSE(wsi) \
161*1c60b9acSAndroid Build Coastguard Worker 		(!(wsi->wsistate_pre_close & LWSIFS_NOT_EST))
162*1c60b9acSAndroid Build Coastguard Worker #define lwsi_state_can_handle_POLLOUT(wsi) (wsi->wsistate & LWSIFS_POCB)
163*1c60b9acSAndroid Build Coastguard Worker #if !defined (_DEBUG)
164*1c60b9acSAndroid Build Coastguard Worker #define lwsi_set_state(wsi, lrs) wsi->wsistate = \
165*1c60b9acSAndroid Build Coastguard Worker 			  (wsi->wsistate & (lws_wsi_state_t)(~LRS_MASK)) | lrs
166*1c60b9acSAndroid Build Coastguard Worker #else
167*1c60b9acSAndroid Build Coastguard Worker void lwsi_set_state(struct lws *wsi, lws_wsi_state_t lrs);
168*1c60b9acSAndroid Build Coastguard Worker #endif
169*1c60b9acSAndroid Build Coastguard Worker 
170*1c60b9acSAndroid Build Coastguard Worker #define _LWS_ADOPT_FINISH (1 << 24)
171*1c60b9acSAndroid Build Coastguard Worker 
172*1c60b9acSAndroid Build Coastguard Worker /*
173*1c60b9acSAndroid Build Coastguard Worker  * Internal role-specific ops
174*1c60b9acSAndroid Build Coastguard Worker  *
175*1c60b9acSAndroid Build Coastguard Worker  * Many roles are sparsely filled with callbacks, rather than has 20 x
176*1c60b9acSAndroid Build Coastguard Worker  * function pointers in the ops struct, let's have a 20 nybble array telling us
177*1c60b9acSAndroid Build Coastguard Worker  * if the pointer doesn't exist, or its offset in a smaller "just pointers that
178*1c60b9acSAndroid Build Coastguard Worker  * exist" array.
179*1c60b9acSAndroid Build Coastguard Worker  *
180*1c60b9acSAndroid Build Coastguard Worker  * We can support up to 15 valid pointers in the role that way and only have to
181*1c60b9acSAndroid Build Coastguard Worker  * provide pointers that exist for that role, at the cost of a 10-byte nybble
182*1c60b9acSAndroid Build Coastguard Worker  * table.
183*1c60b9acSAndroid Build Coastguard Worker  *
184*1c60b9acSAndroid Build Coastguard Worker  * For x86_64, a set 196 byte allocation becomes 60 + 8 bytes per defined ptr,
185*1c60b9acSAndroid Build Coastguard Worker  * where the ops table is sparse this is a considable .rodata saving, for 32-bit
186*1c60b9acSAndroid Build Coastguard Worker  * 52 + 4 bytes per defined ptr accounting for padding.
187*1c60b9acSAndroid Build Coastguard Worker  */
188*1c60b9acSAndroid Build Coastguard Worker 
189*1c60b9acSAndroid Build Coastguard Worker /*
190*1c60b9acSAndroid Build Coastguard Worker  * After http headers have parsed, this is the last chance for a role
191*1c60b9acSAndroid Build Coastguard Worker  * to upgrade the connection to something else using the headers.
192*1c60b9acSAndroid Build Coastguard Worker  * ws-over-h2 is upgraded from h2 like this.
193*1c60b9acSAndroid Build Coastguard Worker  */
194*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_check_upgrades_t)(struct lws *wsi);
195*1c60b9acSAndroid Build Coastguard Worker /* role-specific context init during context creation */
196*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_pt_init_destroy_t)(struct lws_context *context,
197*1c60b9acSAndroid Build Coastguard Worker 				const struct lws_context_creation_info *info,
198*1c60b9acSAndroid Build Coastguard Worker 				struct lws_context_per_thread *pt, int destroy);
199*1c60b9acSAndroid Build Coastguard Worker /* role-specific per-vhost init during vhost creation */
200*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_init_vhost_t)(struct lws_vhost *vh,
201*1c60b9acSAndroid Build Coastguard Worker 				  const struct lws_context_creation_info *info);
202*1c60b9acSAndroid Build Coastguard Worker /* role-specific per-vhost destructor during vhost destroy */
203*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_destroy_vhost_t)(struct lws_vhost *vh);
204*1c60b9acSAndroid Build Coastguard Worker /* chance for the role to force POLLIN without network activity */
205*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_service_flag_pending_t)(struct lws_context *context,
206*1c60b9acSAndroid Build Coastguard Worker 					       int tsi);
207*1c60b9acSAndroid Build Coastguard Worker /* an fd using this role has POLLIN signalled */
208*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_handle_POLLIN_t)(struct lws_context_per_thread *pt,
209*1c60b9acSAndroid Build Coastguard Worker 					struct lws *wsi,
210*1c60b9acSAndroid Build Coastguard Worker 					struct lws_pollfd *pollfd);
211*1c60b9acSAndroid Build Coastguard Worker /* an fd using the role wanted a POLLOUT callback and now has it */
212*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_handle_POLLOUT_t)(struct lws *wsi);
213*1c60b9acSAndroid Build Coastguard Worker /* perform user pollout */
214*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_perform_user_POLLOUT_t)(struct lws *wsi);
215*1c60b9acSAndroid Build Coastguard Worker /* do effective callback on writeable */
216*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_callback_on_writable_t)(struct lws *wsi);
217*1c60b9acSAndroid Build Coastguard Worker /* connection-specific tx credit in bytes */
218*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_tx_credit_t)(struct lws *wsi, char peer_to_us, int add);
219*1c60b9acSAndroid Build Coastguard Worker /* role-specific write formatting */
220*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_write_role_protocol_t)(struct lws *wsi,
221*1c60b9acSAndroid Build Coastguard Worker 					      unsigned char *buf, size_t len,
222*1c60b9acSAndroid Build Coastguard Worker 					      enum lws_write_protocol *wp);
223*1c60b9acSAndroid Build Coastguard Worker 
224*1c60b9acSAndroid Build Coastguard Worker /* get encapsulation parent */
225*1c60b9acSAndroid Build Coastguard Worker typedef struct lws * (*lws_rops_encapsulation_parent_t)(struct lws *wsi);
226*1c60b9acSAndroid Build Coastguard Worker 
227*1c60b9acSAndroid Build Coastguard Worker /* role-specific destructor */
228*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_alpn_negotiated_t)(struct lws *wsi, const char *alpn);
229*1c60b9acSAndroid Build Coastguard Worker 
230*1c60b9acSAndroid Build Coastguard Worker /* chance for the role to handle close in the protocol */
231*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_close_via_role_protocol_t)(struct lws *wsi,
232*1c60b9acSAndroid Build Coastguard Worker 						  enum lws_close_status reason);
233*1c60b9acSAndroid Build Coastguard Worker /* role-specific close processing */
234*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_close_role_t)(struct lws_context_per_thread *pt,
235*1c60b9acSAndroid Build Coastguard Worker 				     struct lws *wsi);
236*1c60b9acSAndroid Build Coastguard Worker /* role-specific connection close processing */
237*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_close_kill_connection_t)(struct lws *wsi,
238*1c60b9acSAndroid Build Coastguard Worker 						enum lws_close_status reason);
239*1c60b9acSAndroid Build Coastguard Worker /* role-specific destructor */
240*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_destroy_role_t)(struct lws *wsi);
241*1c60b9acSAndroid Build Coastguard Worker 
242*1c60b9acSAndroid Build Coastguard Worker /* role-specific socket-adopt */
243*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_adoption_bind_t)(struct lws *wsi, int type,
244*1c60b9acSAndroid Build Coastguard Worker 					const char *prot);
245*1c60b9acSAndroid Build Coastguard Worker /* role-specific client-bind:
246*1c60b9acSAndroid Build Coastguard Worker  * ret 1 = bound, 0 = not bound, -1 = fail out
247*1c60b9acSAndroid Build Coastguard Worker  * i may be NULL, indicating client_bind is being called after
248*1c60b9acSAndroid Build Coastguard Worker  * a successful bind earlier, to finalize the binding.  In that
249*1c60b9acSAndroid Build Coastguard Worker  * case ret 0 = OK, 1 = fail, wsi needs freeing, -1 = fail, wsi freed */
250*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_client_bind_t)(struct lws *wsi,
251*1c60b9acSAndroid Build Coastguard Worker 				      const struct lws_client_connect_info *i);
252*1c60b9acSAndroid Build Coastguard Worker /* isvalid = 0: request a role-specific keepalive (PING etc)
253*1c60b9acSAndroid Build Coastguard Worker  *         = 1: reset any related validity timer */
254*1c60b9acSAndroid Build Coastguard Worker typedef int (*lws_rops_issue_keepalive_t)(struct lws *wsi, int isvalid);
255*1c60b9acSAndroid Build Coastguard Worker 
256*1c60b9acSAndroid Build Coastguard Worker #define LWS_COUNT_ROLE_OPS			20
257*1c60b9acSAndroid Build Coastguard Worker 
258*1c60b9acSAndroid Build Coastguard Worker typedef union lws_rops {
259*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_check_upgrades_t		check_upgrades;
260*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_pt_init_destroy_t		pt_init_destroy;
261*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_init_vhost_t			init_vhost;
262*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_destroy_vhost_t		destroy_vhost;
263*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_service_flag_pending_t		service_flag_pending;
264*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_handle_POLLIN_t		handle_POLLIN;
265*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_handle_POLLOUT_t		handle_POLLOUT;
266*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_perform_user_POLLOUT_t		perform_user_POLLOUT;
267*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_callback_on_writable_t		callback_on_writable;
268*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_tx_credit_t			tx_credit;
269*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_write_role_protocol_t		write_role_protocol;
270*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_encapsulation_parent_t		encapsulation_parent;
271*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_alpn_negotiated_t		alpn_negotiated;
272*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_close_via_role_protocol_t	close_via_role_protocol;
273*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_close_role_t			close_role;
274*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_close_kill_connection_t	close_kill_connection;
275*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_destroy_role_t			destroy_role;
276*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_adoption_bind_t		adoption_bind;
277*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_client_bind_t			client_bind;
278*1c60b9acSAndroid Build Coastguard Worker 	lws_rops_issue_keepalive_t		issue_keepalive;
279*1c60b9acSAndroid Build Coastguard Worker } lws_rops_t;
280*1c60b9acSAndroid Build Coastguard Worker 
281*1c60b9acSAndroid Build Coastguard Worker typedef enum {
282*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_check_upgrades,
283*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_pt_init_destroy,
284*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_init_vhost,
285*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_destroy_vhost,
286*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_service_flag_pending,
287*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_handle_POLLIN,
288*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_handle_POLLOUT,
289*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_perform_user_POLLOUT,
290*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_callback_on_writable,
291*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_tx_credit,
292*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_write_role_protocol,
293*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_encapsulation_parent,
294*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_alpn_negotiated,
295*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_close_via_role_protocol,
296*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_close_role,
297*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_close_kill_connection,
298*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_destroy_role,
299*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_adoption_bind,
300*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_client_bind,
301*1c60b9acSAndroid Build Coastguard Worker 	LWS_ROPS_issue_keepalive,
302*1c60b9acSAndroid Build Coastguard Worker } lws_rops_func_idx_t;
303*1c60b9acSAndroid Build Coastguard Worker 
304*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread;
305*1c60b9acSAndroid Build Coastguard Worker 
306*1c60b9acSAndroid Build Coastguard Worker struct lws_role_ops {
307*1c60b9acSAndroid Build Coastguard Worker 	const char		*name;
308*1c60b9acSAndroid Build Coastguard Worker 	const char		*alpn;
309*1c60b9acSAndroid Build Coastguard Worker 
310*1c60b9acSAndroid Build Coastguard Worker 	const lws_rops_t	*rops_table;
311*1c60b9acSAndroid Build Coastguard Worker 	/**< the occupied role ops func ptrs */
312*1c60b9acSAndroid Build Coastguard Worker 	uint8_t			rops_idx[(LWS_COUNT_ROLE_OPS + 1) / 2];
313*1c60b9acSAndroid Build Coastguard Worker 	/**< translates role index into .rops[] offset */
314*1c60b9acSAndroid Build Coastguard Worker 
315*1c60b9acSAndroid Build Coastguard Worker 	/*
316*1c60b9acSAndroid Build Coastguard Worker 	 * the callback reasons for adoption for client, server
317*1c60b9acSAndroid Build Coastguard Worker 	 * (just client applies if no concept of client or server)
318*1c60b9acSAndroid Build Coastguard Worker 	 */
319*1c60b9acSAndroid Build Coastguard Worker 	uint8_t			adoption_cb[2];
320*1c60b9acSAndroid Build Coastguard Worker 	/*
321*1c60b9acSAndroid Build Coastguard Worker 	 * the callback reasons for adoption for client, server
322*1c60b9acSAndroid Build Coastguard Worker 	 * (just client applies if no concept of client or server)
323*1c60b9acSAndroid Build Coastguard Worker 	 */
324*1c60b9acSAndroid Build Coastguard Worker 	uint8_t			rx_cb[2];
325*1c60b9acSAndroid Build Coastguard Worker 	/*
326*1c60b9acSAndroid Build Coastguard Worker 	 * the callback reasons for WRITEABLE for client, server
327*1c60b9acSAndroid Build Coastguard Worker 	 * (just client applies if no concept of client or server)
328*1c60b9acSAndroid Build Coastguard Worker 	 */
329*1c60b9acSAndroid Build Coastguard Worker 	uint8_t			writeable_cb[2];
330*1c60b9acSAndroid Build Coastguard Worker 	/*
331*1c60b9acSAndroid Build Coastguard Worker 	 * the callback reasons for CLOSE for client, server
332*1c60b9acSAndroid Build Coastguard Worker 	 * (just client applies if no concept of client or server)
333*1c60b9acSAndroid Build Coastguard Worker 	 */
334*1c60b9acSAndroid Build Coastguard Worker 	uint8_t			close_cb[2];
335*1c60b9acSAndroid Build Coastguard Worker 	/*
336*1c60b9acSAndroid Build Coastguard Worker 	 * the callback reasons for protocol bind for client, server
337*1c60b9acSAndroid Build Coastguard Worker 	 * (just client applies if no concept of client or server)
338*1c60b9acSAndroid Build Coastguard Worker 	 */
339*1c60b9acSAndroid Build Coastguard Worker 	uint8_t			protocol_bind_cb[2];
340*1c60b9acSAndroid Build Coastguard Worker 	/*
341*1c60b9acSAndroid Build Coastguard Worker 	 * the callback reasons for protocol unbind for client, server
342*1c60b9acSAndroid Build Coastguard Worker 	 * (just client applies if no concept of client or server)
343*1c60b9acSAndroid Build Coastguard Worker 	 */
344*1c60b9acSAndroid Build Coastguard Worker 	uint8_t			protocol_unbind_cb[2];
345*1c60b9acSAndroid Build Coastguard Worker 
346*1c60b9acSAndroid Build Coastguard Worker 	uint8_t			file_handle:1;
347*1c60b9acSAndroid Build Coastguard Worker 	/* role operates on files not sockets */
348*1c60b9acSAndroid Build Coastguard Worker };
349*1c60b9acSAndroid Build Coastguard Worker 
350*1c60b9acSAndroid Build Coastguard Worker #define lws_rops_fidx(_rops, fidx) \
351*1c60b9acSAndroid Build Coastguard Worker 		((fidx & 1) ? (_rops)->rops_idx[fidx / 2] & 0xf : \
352*1c60b9acSAndroid Build Coastguard Worker 			      (_rops)->rops_idx[fidx / 2] >> 4)
353*1c60b9acSAndroid Build Coastguard Worker 
354*1c60b9acSAndroid Build Coastguard Worker #define lws_rops_func_fidx(_rops, fidx) \
355*1c60b9acSAndroid Build Coastguard Worker 		((_rops)->rops_table[lws_rops_fidx(_rops, fidx) - 1])
356*1c60b9acSAndroid Build Coastguard Worker 
357*1c60b9acSAndroid Build Coastguard Worker /* core roles */
358*1c60b9acSAndroid Build Coastguard Worker extern const struct lws_role_ops role_ops_raw_skt, role_ops_raw_file,
359*1c60b9acSAndroid Build Coastguard Worker 				 role_ops_listen, role_ops_pipe,
360*1c60b9acSAndroid Build Coastguard Worker 				 role_ops_netlink;
361*1c60b9acSAndroid Build Coastguard Worker 
362*1c60b9acSAndroid Build Coastguard Worker /* bring in role private declarations */
363*1c60b9acSAndroid Build Coastguard Worker 
364*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
365*1c60b9acSAndroid Build Coastguard Worker  #include "private-lib-roles-http.h"
366*1c60b9acSAndroid Build Coastguard Worker #else
367*1c60b9acSAndroid Build Coastguard Worker  #define lwsi_role_http(wsi) (0)
368*1c60b9acSAndroid Build Coastguard Worker #endif
369*1c60b9acSAndroid Build Coastguard Worker 
370*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_H1)
371*1c60b9acSAndroid Build Coastguard Worker  #include "private-lib-roles-h1.h"
372*1c60b9acSAndroid Build Coastguard Worker #else
373*1c60b9acSAndroid Build Coastguard Worker  #define lwsi_role_h1(wsi) (0)
374*1c60b9acSAndroid Build Coastguard Worker #endif
375*1c60b9acSAndroid Build Coastguard Worker 
376*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_H2)
377*1c60b9acSAndroid Build Coastguard Worker  #include "private-lib-roles-h2.h"
378*1c60b9acSAndroid Build Coastguard Worker #else
379*1c60b9acSAndroid Build Coastguard Worker  #define lwsi_role_h2(wsi) (0)
380*1c60b9acSAndroid Build Coastguard Worker #endif
381*1c60b9acSAndroid Build Coastguard Worker 
382*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_WS)
383*1c60b9acSAndroid Build Coastguard Worker  #include "private-lib-roles-ws.h"
384*1c60b9acSAndroid Build Coastguard Worker #else
385*1c60b9acSAndroid Build Coastguard Worker  #define lwsi_role_ws(wsi) (0)
386*1c60b9acSAndroid Build Coastguard Worker #endif
387*1c60b9acSAndroid Build Coastguard Worker 
388*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_CGI)
389*1c60b9acSAndroid Build Coastguard Worker  #include "private-lib-roles-cgi.h"
390*1c60b9acSAndroid Build Coastguard Worker #else
391*1c60b9acSAndroid Build Coastguard Worker  #define lwsi_role_cgi(wsi) (0)
392*1c60b9acSAndroid Build Coastguard Worker #endif
393*1c60b9acSAndroid Build Coastguard Worker 
394*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_DBUS)
395*1c60b9acSAndroid Build Coastguard Worker  #include "private-lib-roles-dbus.h"
396*1c60b9acSAndroid Build Coastguard Worker #else
397*1c60b9acSAndroid Build Coastguard Worker  #define lwsi_role_dbus(wsi) (0)
398*1c60b9acSAndroid Build Coastguard Worker #endif
399*1c60b9acSAndroid Build Coastguard Worker 
400*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_RAW_PROXY)
401*1c60b9acSAndroid Build Coastguard Worker  #include "private-lib-roles-raw-proxy.h"
402*1c60b9acSAndroid Build Coastguard Worker #else
403*1c60b9acSAndroid Build Coastguard Worker  #define lwsi_role_raw_proxy(wsi) (0)
404*1c60b9acSAndroid Build Coastguard Worker #endif
405*1c60b9acSAndroid Build Coastguard Worker 
406*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_MQTT)
407*1c60b9acSAndroid Build Coastguard Worker  #include "mqtt/private-lib-roles-mqtt.h"
408*1c60b9acSAndroid Build Coastguard Worker #else
409*1c60b9acSAndroid Build Coastguard Worker  #define lwsi_role_mqtt(wsi) (0)
410*1c60b9acSAndroid Build Coastguard Worker #endif
411*1c60b9acSAndroid Build Coastguard Worker 
412*1c60b9acSAndroid Build Coastguard Worker enum {
413*1c60b9acSAndroid Build Coastguard Worker 	LWS_HP_RET_BAIL_OK,
414*1c60b9acSAndroid Build Coastguard Worker 	LWS_HP_RET_BAIL_DIE,
415*1c60b9acSAndroid Build Coastguard Worker 	LWS_HP_RET_USER_SERVICE,
416*1c60b9acSAndroid Build Coastguard Worker 	LWS_HP_RET_DROP_POLLOUT,
417*1c60b9acSAndroid Build Coastguard Worker 
418*1c60b9acSAndroid Build Coastguard Worker 	LWS_HPI_RET_WSI_ALREADY_DIED,	/* we closed it */
419*1c60b9acSAndroid Build Coastguard Worker 	LWS_HPI_RET_HANDLED,		/* no probs */
420*1c60b9acSAndroid Build Coastguard Worker 	LWS_HPI_RET_PLEASE_CLOSE_ME,	/* close it for us */
421*1c60b9acSAndroid Build Coastguard Worker 
422*1c60b9acSAndroid Build Coastguard Worker 	LWS_UPG_RET_DONE,
423*1c60b9acSAndroid Build Coastguard Worker 	LWS_UPG_RET_CONTINUE,
424*1c60b9acSAndroid Build Coastguard Worker 	LWS_UPG_RET_BAIL
425*1c60b9acSAndroid Build Coastguard Worker };
426*1c60b9acSAndroid Build Coastguard Worker 
427*1c60b9acSAndroid Build Coastguard Worker #define LWS_CONNECT_COMPLETION_GOOD (-99)
428*1c60b9acSAndroid Build Coastguard Worker 
429*1c60b9acSAndroid Build Coastguard Worker int
430*1c60b9acSAndroid Build Coastguard Worker lws_role_call_adoption_bind(struct lws *wsi, int type, const char *prot);
431*1c60b9acSAndroid Build Coastguard Worker 
432*1c60b9acSAndroid Build Coastguard Worker struct lws *
433*1c60b9acSAndroid Build Coastguard Worker lws_client_connect_4_established(struct lws *wsi, struct lws *wsi_piggyback,
434*1c60b9acSAndroid Build Coastguard Worker 				 ssize_t plen);
435*1c60b9acSAndroid Build Coastguard Worker 
436*1c60b9acSAndroid Build Coastguard Worker struct lws *
437*1c60b9acSAndroid Build Coastguard Worker lws_client_connect_3_connect(struct lws *wsi, const char *ads,
438*1c60b9acSAndroid Build Coastguard Worker 			     const struct addrinfo *result, int n, void *opaque);
439