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