private-lib-roles.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
  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. typedef uint32_t lws_wsi_state_t;
  25. /*
  26. * The wsi->role_ops pointer decides almost everything about what role the wsi
  27. * will play, h2, raw, ws, etc.
  28. *
  29. * However there are a few additional flags needed that vary, such as if the
  30. * role is a client or server side, if it has that concept. And the connection
  31. * fulfilling the role, has a separate dynamic state.
  32. *
  33. * 31 16 15 0
  34. * [ role flags ] [ state ]
  35. *
  36. * The role flags part is generally invariant for the lifetime of the wsi,
  37. * although it can change if the connection role itself does, eg, if the
  38. * connection upgrades from H1 -> WS1 the role flags may be changed at that
  39. * point.
  40. *
  41. * The state part reflects the dynamic connection state, and the states are
  42. * reused between roles.
  43. *
  44. * None of the internal role or state representations are made available outside
  45. * of lws internals. Even for lws internals, if you add stuff here, please keep
  46. * the constants inside this header only by adding necessary helpers here and
  47. * use the helpers in the actual code. This is to ease any future refactors.
  48. *
  49. * Notice LWSIFR_ENCAP means we have a parent wsi that actually carries our
  50. * data as a stream inside a different protocol.
  51. */
  52. #define _RS 16
  53. #define LWSIFR_CLIENT (0x1000 << _RS) /* client side */
  54. #define LWSIFR_SERVER (0x2000 << _RS) /* server side */
  55. #define LWSIFR_P_ENCAP_H2 (0x0100 << _RS) /* we are encapsulated by h2 */
  56. enum lwsi_role {
  57. LWSI_ROLE_MASK = (0xffff << _RS),
  58. LWSI_ROLE_ENCAP_MASK = (0x0f00 << _RS),
  59. };
  60. #define lwsi_role(wsi) (wsi->wsistate & LWSI_ROLE_MASK)
  61. #if !defined (_DEBUG)
  62. #define lwsi_set_role(wsi, role) wsi->wsistate = \
  63. (wsi->wsistate & (~LWSI_ROLE_MASK)) | role
  64. #else
  65. void lwsi_set_role(struct lws *wsi, lws_wsi_state_t role);
  66. #endif
  67. #define lwsi_role_client(wsi) (!!(wsi->wsistate & LWSIFR_CLIENT))
  68. #define lwsi_role_server(wsi) (!!(wsi->wsistate & LWSIFR_SERVER))
  69. #define lwsi_role_h2_ENCAPSULATION(wsi) \
  70. ((wsi->wsistate & LWSI_ROLE_ENCAP_MASK) == LWSIFR_P_ENCAP_H2)
  71. /* Pollout wants a callback in this state */
  72. #define LWSIFS_POCB (0x100)
  73. /* Before any protocol connection was established */
  74. #define LWSIFS_NOT_EST (0x200)
  75. enum lwsi_state {
  76. /* Phase 1: pre-transport */
  77. LRS_UNCONNECTED = LWSIFS_NOT_EST | 0,
  78. LRS_WAITING_DNS = LWSIFS_NOT_EST | 1,
  79. LRS_WAITING_CONNECT = LWSIFS_NOT_EST | 2,
  80. /* Phase 2: establishing intermediaries on top of transport */
  81. LRS_WAITING_PROXY_REPLY = LWSIFS_NOT_EST | 3,
  82. LRS_WAITING_SSL = LWSIFS_NOT_EST | 4,
  83. LRS_WAITING_SOCKS_GREETING_REPLY = LWSIFS_NOT_EST | 5,
  84. LRS_WAITING_SOCKS_CONNECT_REPLY = LWSIFS_NOT_EST | 6,
  85. LRS_WAITING_SOCKS_AUTH_REPLY = LWSIFS_NOT_EST | 7,
  86. /* Phase 3: establishing tls tunnel */
  87. LRS_SSL_INIT = LWSIFS_NOT_EST | 8,
  88. LRS_SSL_ACK_PENDING = LWSIFS_NOT_EST | 9,
  89. LRS_PRE_WS_SERVING_ACCEPT = LWSIFS_NOT_EST | 10,
  90. /* Phase 4: connected */
  91. LRS_WAITING_SERVER_REPLY = LWSIFS_NOT_EST | 11,
  92. LRS_H2_AWAIT_PREFACE = LWSIFS_NOT_EST | 12,
  93. LRS_H2_AWAIT_SETTINGS = LWSIFS_NOT_EST |
  94. LWSIFS_POCB | 13,
  95. LRS_MQTTC_IDLE = LWSIFS_POCB | 33,
  96. LRS_MQTTC_AWAIT_CONNACK = 34,
  97. /* Phase 5: protocol logically established */
  98. LRS_H2_CLIENT_SEND_SETTINGS = LWSIFS_POCB | 14,
  99. LRS_H2_WAITING_TO_SEND_HEADERS = LWSIFS_POCB | 15,
  100. LRS_DEFERRING_ACTION = LWSIFS_POCB | 16,
  101. LRS_IDLING = 17,
  102. LRS_H1C_ISSUE_HANDSHAKE = 18,
  103. LRS_H1C_ISSUE_HANDSHAKE2 = 19,
  104. LRS_ISSUE_HTTP_BODY = 20,
  105. LRS_ISSUING_FILE = 21,
  106. LRS_HEADERS = 22,
  107. LRS_BODY = 23,
  108. LRS_DISCARD_BODY = 24,
  109. LRS_ESTABLISHED = LWSIFS_POCB | 25,
  110. /* we are established, but we have embarked on serving a single
  111. * transaction. Other transaction input may be pending, but we will
  112. * not service it while we are busy dealing with the current
  113. * transaction.
  114. *
  115. * When we complete the current transaction, we would reset our state
  116. * back to ESTABLISHED and start to process the next transaction.
  117. */
  118. LRS_DOING_TRANSACTION = LWSIFS_POCB | 26,
  119. /* Phase 6: finishing */
  120. LRS_WAITING_TO_SEND_CLOSE = LWSIFS_POCB | 27,
  121. LRS_RETURNED_CLOSE = LWSIFS_POCB | 28,
  122. LRS_AWAITING_CLOSE_ACK = LWSIFS_POCB | 29,
  123. LRS_FLUSHING_BEFORE_CLOSE = LWSIFS_POCB | 30,
  124. LRS_SHUTDOWN = 31,
  125. /* Phase 7: dead */
  126. LRS_DEAD_SOCKET = 32,
  127. LRS_MASK = 0xffff
  128. };
  129. #define lwsi_state(wsi) ((enum lwsi_state)(wsi->wsistate & LRS_MASK))
  130. #define lwsi_state_PRE_CLOSE(wsi) \
  131. ((enum lwsi_state)(wsi->wsistate_pre_close & LRS_MASK))
  132. #define lwsi_state_est(wsi) (!(wsi->wsistate & LWSIFS_NOT_EST))
  133. #define lwsi_state_est_PRE_CLOSE(wsi) \
  134. (!(wsi->wsistate_pre_close & LWSIFS_NOT_EST))
  135. #define lwsi_state_can_handle_POLLOUT(wsi) (wsi->wsistate & LWSIFS_POCB)
  136. #if !defined (_DEBUG)
  137. #define lwsi_set_state(wsi, lrs) wsi->wsistate = \
  138. (wsi->wsistate & (~LRS_MASK)) | lrs
  139. #else
  140. void lwsi_set_state(struct lws *wsi, lws_wsi_state_t lrs);
  141. #endif
  142. #define _LWS_ADOPT_FINISH (1 << 24)
  143. /*
  144. * internal role-specific ops
  145. */
  146. struct lws_context_per_thread;
  147. struct lws_role_ops {
  148. const char *name;
  149. const char *alpn;
  150. /*
  151. * After http headers have parsed, this is the last chance for a role
  152. * to upgrade the connection to something else using the headers.
  153. * ws-over-h2 is upgraded from h2 like this.
  154. */
  155. int (*check_upgrades)(struct lws *wsi);
  156. /* role-specific context init during context creation */
  157. int (*pt_init_destroy)(struct lws_context *context,
  158. const struct lws_context_creation_info *info,
  159. struct lws_context_per_thread *pt, int destroy);
  160. /* role-specific per-vhost init during vhost creation */
  161. int (*init_vhost)(struct lws_vhost *vh,
  162. const struct lws_context_creation_info *info);
  163. /* role-specific per-vhost destructor during vhost destroy */
  164. int (*destroy_vhost)(struct lws_vhost *vh);
  165. /* chance for the role to force POLLIN without network activity */
  166. int (*service_flag_pending)(struct lws_context *context, int tsi);
  167. /* an fd using this role has POLLIN signalled */
  168. int (*handle_POLLIN)(struct lws_context_per_thread *pt, struct lws *wsi,
  169. struct lws_pollfd *pollfd);
  170. /* an fd using the role wanted a POLLOUT callback and now has it */
  171. int (*handle_POLLOUT)(struct lws *wsi);
  172. /* perform user pollout */
  173. int (*perform_user_POLLOUT)(struct lws *wsi);
  174. /* do effective callback on writeable */
  175. int (*callback_on_writable)(struct lws *wsi);
  176. /* connection-specific tx credit in bytes */
  177. int (*tx_credit)(struct lws *wsi, char peer_to_us, int add);
  178. /* role-specific write formatting */
  179. int (*write_role_protocol)(struct lws *wsi, unsigned char *buf,
  180. size_t len, enum lws_write_protocol *wp);
  181. /* get encapsulation parent */
  182. struct lws * (*encapsulation_parent)(struct lws *wsi);
  183. /* role-specific destructor */
  184. int (*alpn_negotiated)(struct lws *wsi, const char *alpn);
  185. /* chance for the role to handle close in the protocol */
  186. int (*close_via_role_protocol)(struct lws *wsi,
  187. enum lws_close_status reason);
  188. /* role-specific close processing */
  189. int (*close_role)(struct lws_context_per_thread *pt, struct lws *wsi);
  190. /* role-specific connection close processing */
  191. int (*close_kill_connection)(struct lws *wsi,
  192. enum lws_close_status reason);
  193. /* role-specific destructor */
  194. int (*destroy_role)(struct lws *wsi);
  195. /* role-specific socket-adopt */
  196. int (*adoption_bind)(struct lws *wsi, int type, const char *prot);
  197. /* role-specific client-bind:
  198. * ret 1 = bound, 0 = not bound, -1 = fail out
  199. * i may be NULL, indicating client_bind is being called after
  200. * a successful bind earlier, to finalize the binding. In that
  201. * case ret 0 = OK, 1 = fail, wsi needs freeing, -1 = fail, wsi freed */
  202. int (*client_bind)(struct lws *wsi,
  203. const struct lws_client_connect_info *i);
  204. /* isvalid = 0: request a role-specific keepalive (PING etc)
  205. * = 1: reset any related validity timer */
  206. int (*issue_keepalive)(struct lws *wsi, int isvalid);
  207. /*
  208. * the callback reasons for adoption for client, server
  209. * (just client applies if no concept of client or server)
  210. */
  211. uint16_t adoption_cb[2];
  212. /*
  213. * the callback reasons for adoption for client, server
  214. * (just client applies if no concept of client or server)
  215. */
  216. uint16_t rx_cb[2];
  217. /*
  218. * the callback reasons for WRITEABLE for client, server
  219. * (just client applies if no concept of client or server)
  220. */
  221. uint16_t writeable_cb[2];
  222. /*
  223. * the callback reasons for CLOSE for client, server
  224. * (just client applies if no concept of client or server)
  225. */
  226. uint16_t close_cb[2];
  227. /*
  228. * the callback reasons for protocol bind for client, server
  229. * (just client applies if no concept of client or server)
  230. */
  231. uint16_t protocol_bind_cb[2];
  232. /*
  233. * the callback reasons for protocol unbind for client, server
  234. * (just client applies if no concept of client or server)
  235. */
  236. uint16_t protocol_unbind_cb[2];
  237. unsigned int file_handle:1; /* role operates on files not sockets */
  238. };
  239. /* core roles */
  240. extern const struct lws_role_ops role_ops_raw_skt, role_ops_raw_file,
  241. role_ops_listen, role_ops_pipe;
  242. /* bring in role private declarations */
  243. #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
  244. #include "private-lib-roles-http.h"
  245. #else
  246. #define lwsi_role_http(wsi) (0)
  247. #endif
  248. #if defined(LWS_ROLE_H1)
  249. #include "private-lib-roles-h1.h"
  250. #else
  251. #define lwsi_role_h1(wsi) (0)
  252. #endif
  253. #if defined(LWS_ROLE_H2)
  254. #include "private-lib-roles-h2.h"
  255. #else
  256. #define lwsi_role_h2(wsi) (0)
  257. #endif
  258. #if defined(LWS_ROLE_WS)
  259. #include "private-lib-roles-ws.h"
  260. #else
  261. #define lwsi_role_ws(wsi) (0)
  262. #endif
  263. #if defined(LWS_ROLE_CGI)
  264. #include "private-lib-roles-cgi.h"
  265. #else
  266. #define lwsi_role_cgi(wsi) (0)
  267. #endif
  268. #if defined(LWS_ROLE_DBUS)
  269. #include "private-lib-roles-dbus.h"
  270. #else
  271. #define lwsi_role_dbus(wsi) (0)
  272. #endif
  273. #if defined(LWS_ROLE_RAW_PROXY)
  274. #include "private-lib-roles-raw-proxy.h"
  275. #else
  276. #define lwsi_role_raw_proxy(wsi) (0)
  277. #endif
  278. #if defined(LWS_ROLE_MQTT)
  279. #include "mqtt/private-lib-roles-mqtt.h"
  280. #else
  281. #define lwsi_role_mqtt(wsi) (0)
  282. #endif
  283. enum {
  284. LWS_HP_RET_BAIL_OK,
  285. LWS_HP_RET_BAIL_DIE,
  286. LWS_HP_RET_USER_SERVICE,
  287. LWS_HP_RET_DROP_POLLOUT,
  288. LWS_HPI_RET_WSI_ALREADY_DIED, /* we closed it */
  289. LWS_HPI_RET_HANDLED, /* no probs */
  290. LWS_HPI_RET_PLEASE_CLOSE_ME, /* close it for us */
  291. LWS_UPG_RET_DONE,
  292. LWS_UPG_RET_CONTINUE,
  293. LWS_UPG_RET_BAIL
  294. };
  295. #define LWS_CONNECT_COMPLETION_GOOD (-99)
  296. int
  297. lws_role_call_adoption_bind(struct lws *wsi, int type, const char *prot);
  298. struct lws *
  299. lws_client_connect_4_established(struct lws *wsi, struct lws *wsi_piggyback, ssize_t plen);
  300. struct lws *
  301. lws_client_connect_3_connect(struct lws *wsi, const char *ads,
  302. const struct addrinfo *result, int n, void *opaque);