• 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  *  This is included from private-lib-core.h if LWS_ROLE_WS
25  */
26 
27 extern const struct lws_role_ops role_ops_ws;
28 
29 #define lwsi_role_ws(wsi) (wsi->role_ops == &role_ops_ws)
30 
31 enum lws_rx_parse_state {
32 	LWS_RXPS_NEW,
33 
34 	LWS_RXPS_04_mask_1,
35 	LWS_RXPS_04_mask_2,
36 	LWS_RXPS_04_mask_3,
37 
38 	LWS_RXPS_04_FRAME_HDR_1,
39 	LWS_RXPS_04_FRAME_HDR_LEN,
40 	LWS_RXPS_04_FRAME_HDR_LEN16_2,
41 	LWS_RXPS_04_FRAME_HDR_LEN16_1,
42 	LWS_RXPS_04_FRAME_HDR_LEN64_8,
43 	LWS_RXPS_04_FRAME_HDR_LEN64_7,
44 	LWS_RXPS_04_FRAME_HDR_LEN64_6,
45 	LWS_RXPS_04_FRAME_HDR_LEN64_5,
46 	LWS_RXPS_04_FRAME_HDR_LEN64_4,
47 	LWS_RXPS_04_FRAME_HDR_LEN64_3,
48 	LWS_RXPS_04_FRAME_HDR_LEN64_2,
49 	LWS_RXPS_04_FRAME_HDR_LEN64_1,
50 
51 	LWS_RXPS_07_COLLECT_FRAME_KEY_1,
52 	LWS_RXPS_07_COLLECT_FRAME_KEY_2,
53 	LWS_RXPS_07_COLLECT_FRAME_KEY_3,
54 	LWS_RXPS_07_COLLECT_FRAME_KEY_4,
55 
56 	LWS_RXPS_WS_FRAME_PAYLOAD
57 };
58 
59 enum lws_websocket_opcodes_07 {
60 	LWSWSOPC_CONTINUATION = 0,
61 	LWSWSOPC_TEXT_FRAME = 1,
62 	LWSWSOPC_BINARY_FRAME = 2,
63 
64 	LWSWSOPC_NOSPEC__MUX = 7,
65 
66 	/* control extensions 8+ */
67 
68 	LWSWSOPC_CLOSE = 8,
69 	LWSWSOPC_PING = 9,
70 	LWSWSOPC_PONG = 0xa,
71 };
72 
73 /* this is not usable directly by user code any more, lws_close_reason() */
74 #define LWS_WRITE_CLOSE 4
75 
76 #define ALREADY_PROCESSED_IGNORE_CHAR 1
77 #define ALREADY_PROCESSED_NO_CB 2
78 
79 #if !defined(LWS_WITHOUT_EXTENSIONS)
80 struct lws_vhost_role_ws {
81 	const struct lws_extension *extensions;
82 };
83 
84 struct lws_pt_role_ws {
85 	struct lws *rx_draining_ext_list;
86 	struct lws *tx_draining_ext_list;
87 };
88 #endif
89 
90 struct _lws_websocket_related {
91 	unsigned char *rx_ubuf;
92 #if !defined(LWS_WITHOUT_EXTENSIONS)
93 	const struct lws_extension *active_extensions[LWS_MAX_EXTENSIONS_ACTIVE];
94 	void *act_ext_user[LWS_MAX_EXTENSIONS_ACTIVE];
95 	struct lws *rx_draining_ext_list;
96 	struct lws *tx_draining_ext_list;
97 #endif
98 
99 #if defined(LWS_WITH_HTTP_PROXY)
100 	struct lws_dll2_owner proxy_owner;
101 	char actual_protocol[16];
102 	size_t proxy_buffered;
103 #endif
104 
105 	/* Also used for close content... control opcode == < 128 */
106 	uint8_t ping_payload_buf[128 - 3 + LWS_PRE];
107 
108 	unsigned int final:1;
109 	unsigned int frame_is_binary:1;
110 	unsigned int all_zero_nonce:1;
111 	unsigned int this_frame_masked:1;
112 	unsigned int inside_frame:1; /* next write will be more of frame */
113 	unsigned int clean_buffer:1; /* buffer not rewritten by extension */
114 	unsigned int payload_is_close:1; /* process as PONG, but it is close */
115 	unsigned int ping_pending_flag:1;
116 	unsigned int continuation_possible:1;
117 	unsigned int owed_a_fin:1;
118 	unsigned int check_utf8:1;
119 	unsigned int defeat_check_utf8:1;
120 	unsigned int stashed_write_pending:1;
121 	unsigned int send_check_ping:1;
122 	unsigned int first_fragment:1;
123 	unsigned int peer_has_sent_close:1;
124 #if !defined(LWS_WITHOUT_EXTENSIONS)
125 	unsigned int extension_data_pending:1;
126 	unsigned int rx_draining_ext:1;
127 	unsigned int tx_draining_ext:1;
128 	unsigned int pmd_trailer_application:1;
129 #endif
130 
131 	uint8_t mask[4];
132 
133 	size_t rx_packet_length;
134 	uint32_t rx_ubuf_head;
135 	uint32_t rx_ubuf_alloc;
136 
137 	uint8_t ping_payload_len;
138 	uint8_t mask_idx;
139 	uint8_t opcode;
140 	uint8_t rsv;
141 	uint8_t rsv_first_msg;
142 	/* zero if no info, or length including 2-byte close code */
143 	uint8_t close_in_ping_buffer_len;
144 	uint8_t utf8;
145 	uint8_t stashed_write_type;
146 	uint8_t tx_draining_stashed_wp;
147 	uint8_t ietf_spec_revision;
148 #if !defined(LWS_WITHOUT_EXTENSIONS)
149 	uint8_t count_act_ext;
150 #endif
151 };
152 
153 /*
154  * we need to separately track what's happening with both compressed rx in
155  * and with inflated rx out that will be passed to the user code
156  */
157 
158 struct lws_ext_pm_deflate_rx_ebufs {
159 	struct lws_tokens eb_in;
160 	struct lws_tokens eb_out;
161 };
162 
163 int
164 lws_ws_handshake_client(struct lws *wsi, unsigned char **buf, size_t len);
165 
166 #if !defined(LWS_WITHOUT_EXTENSIONS)
167 LWS_VISIBLE void
168 lws_context_init_extensions(const struct lws_context_creation_info *info,
169 			    struct lws_context *context);
170 LWS_EXTERN int
171 lws_any_extension_handled(struct lws *wsi, enum lws_extension_callback_reasons r,
172 			  void *v, size_t len);
173 
174 LWS_EXTERN int
175 lws_ext_cb_active(struct lws *wsi, int reason, void *buf, int len);
176 LWS_EXTERN int
177 lws_ext_cb_all_exts(struct lws_context *context, struct lws *wsi, int reason,
178 		    void *arg, int len);
179 #endif
180 
181 int
182 handshake_0405(struct lws_context *context, struct lws *wsi);
183 int
184 lws_process_ws_upgrade(struct lws *wsi);
185 
186 int
187 lws_process_ws_upgrade2(struct lws *wsi);
188 
189 extern const struct lws_protocols lws_ws_proxy;
190 
191 int
192 lws_server_init_wsi_for_ws(struct lws *wsi);
193 
194 void
195 lws_sul_wsping_cb(lws_sorted_usec_list_t *sul);
196