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