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