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