• 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 #define PAYLOAD_BUF_SIZE 128 - 3 + LWS_PRE
91 
92 struct _lws_websocket_related {
93 	unsigned char *rx_ubuf;
94 #if !defined(LWS_WITHOUT_EXTENSIONS)
95 	const struct lws_extension *active_extensions[LWS_MAX_EXTENSIONS_ACTIVE];
96 	void *act_ext_user[LWS_MAX_EXTENSIONS_ACTIVE];
97 	struct lws *rx_draining_ext_list;
98 	struct lws *tx_draining_ext_list;
99 #endif
100 
101 #if defined(LWS_WITH_HTTP_PROXY)
102 	struct lws_dll2_owner proxy_owner;
103 	char actual_protocol[16];
104 	size_t proxy_buffered;
105 #endif
106 
107 	/* Also used for close content... control opcode == < 128 */
108 	uint8_t ping_payload_buf[PAYLOAD_BUF_SIZE];
109 	uint8_t pong_payload_buf[PAYLOAD_BUF_SIZE];
110 
111 	unsigned int final:1;
112 	unsigned int frame_is_binary:1;
113 	unsigned int all_zero_nonce:1;
114 	unsigned int this_frame_masked:1;
115 	unsigned int inside_frame:1; /* next write will be more of frame */
116 	unsigned int clean_buffer:1; /* buffer not rewritten by extension */
117 	unsigned int payload_is_close:1; /* process as PONG, but it is close */
118 	unsigned int pong_pending_flag:1;
119 	unsigned int continuation_possible:1;
120 	unsigned int owed_a_fin:1;
121 	unsigned int check_utf8:1;
122 	unsigned int defeat_check_utf8:1;
123 	unsigned int stashed_write_pending:1;
124 	unsigned int send_check_ping:1;
125 	unsigned int first_fragment:1;
126 	unsigned int peer_has_sent_close:1;
127 #if !defined(LWS_WITHOUT_EXTENSIONS)
128 	unsigned int extension_data_pending:1;
129 	unsigned int rx_draining_ext:1;
130 	unsigned int tx_draining_ext:1;
131 	unsigned int pmd_trailer_application:1;
132 #endif
133 
134 	uint8_t mask[4];
135 
136 	size_t rx_packet_length;
137 	uint32_t rx_ubuf_head;
138 	uint32_t rx_ubuf_alloc;
139 
140 	uint8_t pong_payload_len;
141 	uint8_t mask_idx;
142 	uint8_t opcode;
143 	uint8_t rsv;
144 	uint8_t rsv_first_msg;
145 	/* zero if no info, or length including 2-byte close code */
146 	uint8_t close_in_ping_buffer_len;
147 	uint8_t utf8;
148 	uint8_t stashed_write_type;
149 	uint8_t tx_draining_stashed_wp;
150 	uint8_t ietf_spec_revision;
151 #if !defined(LWS_WITHOUT_EXTENSIONS)
152 	uint8_t count_act_ext;
153 #endif
154 };
155 
156 /*
157  * we need to separately track what's happening with both compressed rx in
158  * and with inflated rx out that will be passed to the user code
159  */
160 
161 struct lws_ext_pm_deflate_rx_ebufs {
162 	struct lws_tokens eb_in;
163 	struct lws_tokens eb_out;
164 };
165 
166 int
167 lws_ws_handshake_client(struct lws *wsi, unsigned char **buf, size_t len);
168 
169 #if !defined(LWS_WITHOUT_EXTENSIONS)
170 LWS_VISIBLE void
171 lws_context_init_extensions(const struct lws_context_creation_info *info,
172 			    struct lws_context *context);
173 LWS_EXTERN int
174 lws_any_extension_handled(struct lws *wsi, enum lws_extension_callback_reasons r,
175 			  void *v, size_t len);
176 
177 LWS_EXTERN int
178 lws_ext_cb_active(struct lws *wsi, int reason, void *buf, int len);
179 LWS_EXTERN int
180 lws_ext_cb_all_exts(struct lws_context *context, struct lws *wsi, int reason,
181 		    void *arg, int len);
182 #endif
183 
184 int
185 handshake_0405(struct lws_context *context, struct lws *wsi);
186 int
187 lws_process_ws_upgrade(struct lws *wsi);
188 
189 int
190 lws_process_ws_upgrade2(struct lws *wsi);
191 
192 extern const struct lws_protocols lws_ws_proxy;
193 
194 int
195 lws_server_init_wsi_for_ws(struct lws *wsi);
196 
197 void
198 lws_sul_wsping_cb(lws_sorted_usec_list_t *sul);
199