ops-raw-skt.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010 - 2020 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. #include <private-lib-core.h>
  25. static int
  26. rops_handle_POLLIN_raw_skt(struct lws_context_per_thread *pt, struct lws *wsi,
  27. struct lws_pollfd *pollfd)
  28. {
  29. #if defined(LWS_WITH_SOCKS5)
  30. const char *cce = NULL;
  31. #endif
  32. struct lws_tokens ebuf;
  33. int n = 0, buffered = 0;
  34. /* pending truncated sends have uber priority */
  35. if (lws_has_buffered_out(wsi)) {
  36. if (!(pollfd->revents & LWS_POLLOUT))
  37. return LWS_HPI_RET_HANDLED;
  38. /* drain the output buflist */
  39. if (lws_issue_raw(wsi, NULL, 0) < 0)
  40. goto fail;
  41. /*
  42. * we can't afford to allow input processing to send
  43. * something new, so spin around he event loop until
  44. * he doesn't have any partials
  45. */
  46. return LWS_HPI_RET_HANDLED;
  47. }
  48. #if defined(LWS_WITH_SERVER)
  49. if (!lwsi_role_client(wsi) && lwsi_state(wsi) != LRS_ESTABLISHED) {
  50. lwsl_debug("%s: %p: wsistate 0x%x\n", __func__, wsi,
  51. (int)wsi->wsistate);
  52. if (lwsi_state(wsi) != LRS_SSL_INIT)
  53. if (lws_server_socket_service_ssl(wsi,
  54. LWS_SOCK_INVALID,
  55. !!(pollfd->revents & pollfd->events & LWS_POLLIN)))
  56. return LWS_HPI_RET_PLEASE_CLOSE_ME;
  57. return LWS_HPI_RET_HANDLED;
  58. }
  59. #endif
  60. if ((pollfd->revents & pollfd->events & LWS_POLLIN) &&
  61. !(wsi->favoured_pollin &&
  62. (pollfd->revents & pollfd->events & LWS_POLLOUT))) {
  63. lwsl_debug("%s: POLLIN: wsi %p, state 0x%x\n", __func__,
  64. wsi, lwsi_state(wsi));
  65. switch (lwsi_state(wsi)) {
  66. /* any tunnel has to have been established... */
  67. case LRS_SSL_ACK_PENDING:
  68. goto nope;
  69. /* we are actually connected */
  70. case LRS_WAITING_CONNECT:
  71. goto nope;
  72. #if defined(LWS_WITH_SOCKS5)
  73. /* SOCKS Greeting Reply */
  74. case LRS_WAITING_SOCKS_GREETING_REPLY:
  75. case LRS_WAITING_SOCKS_AUTH_REPLY:
  76. case LRS_WAITING_SOCKS_CONNECT_REPLY:
  77. switch (lws_socks5c_handle_state(wsi, pollfd, &cce)) {
  78. case LW5CHS_RET_RET0:
  79. goto nope;
  80. case LW5CHS_RET_BAIL3:
  81. lws_inform_client_conn_fail(wsi, (void *)cce, strlen(cce));
  82. goto fail;
  83. case LW5CHS_RET_STARTHS:
  84. lwsi_set_state(wsi, LRS_ESTABLISHED);
  85. lws_client_connect_4_established(wsi, NULL, 0);
  86. /*
  87. * Now we got the socks5 connection, we need to
  88. * go down the tls path on it now if that's what
  89. * we want
  90. */
  91. goto post_rx;
  92. default:
  93. break;
  94. }
  95. goto post_rx;
  96. #endif
  97. default:
  98. ebuf.token = NULL;
  99. ebuf.len = 0;
  100. buffered = lws_buflist_aware_read(pt, wsi, &ebuf, 1, __func__);
  101. switch (ebuf.len) {
  102. case 0:
  103. lwsl_info("%s: read 0 len\n", __func__);
  104. wsi->seen_zero_length_recv = 1;
  105. if (lws_change_pollfd(wsi, LWS_POLLIN, 0))
  106. goto fail;
  107. /*
  108. * we need to go to fail here, since it's the only
  109. * chance we get to understand that the socket has
  110. * closed
  111. */
  112. // goto try_pollout;
  113. goto fail;
  114. case LWS_SSL_CAPABLE_ERROR:
  115. goto fail;
  116. case LWS_SSL_CAPABLE_MORE_SERVICE:
  117. goto try_pollout;
  118. }
  119. #if defined(LWS_WITH_UDP)
  120. if (wsi->a.context->udp_loss_sim_rx_pc) {
  121. uint16_t u16;
  122. /*
  123. * We should randomly drop some of these
  124. */
  125. if (lws_get_random(wsi->a.context, &u16, 2) == 2 &&
  126. ((u16 * 100) / 0xffff) <=
  127. wsi->a.context->udp_loss_sim_rx_pc) {
  128. lwsl_warn("%s: dropping udp rx\n", __func__);
  129. /* pretend it was handled */
  130. n = ebuf.len;
  131. goto post_rx;
  132. }
  133. }
  134. #endif
  135. n = user_callback_handle_rxflow(wsi->a.protocol->callback,
  136. wsi, LWS_CALLBACK_RAW_RX,
  137. wsi->user_space, ebuf.token,
  138. ebuf.len);
  139. #if defined(LWS_WITH_UDP) || defined(LWS_WITH_SOCKS5)
  140. post_rx:
  141. #endif
  142. if (n < 0) {
  143. lwsl_info("LWS_CALLBACK_RAW_RX_fail\n");
  144. goto fail;
  145. }
  146. if (lws_buflist_aware_finished_consuming(wsi, &ebuf, ebuf.len,
  147. buffered, __func__))
  148. return LWS_HPI_RET_PLEASE_CLOSE_ME;
  149. goto try_pollout;
  150. }
  151. }
  152. nope:
  153. if (wsi->favoured_pollin &&
  154. (pollfd->revents & pollfd->events & LWS_POLLOUT))
  155. /* we balanced the last favouring of pollin */
  156. wsi->favoured_pollin = 0;
  157. try_pollout:
  158. if (!(pollfd->revents & LWS_POLLOUT))
  159. return LWS_HPI_RET_HANDLED;
  160. #if defined(LWS_WITH_CLIENT)
  161. if (lwsi_state(wsi) == LRS_WAITING_CONNECT &&
  162. !lws_client_connect_3_connect(wsi, NULL, NULL, 0, NULL))
  163. return LWS_HPI_RET_WSI_ALREADY_DIED;
  164. #endif
  165. /* one shot */
  166. if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) {
  167. lwsl_notice("%s a\n", __func__);
  168. goto fail;
  169. }
  170. /* clear back-to-back write detection */
  171. wsi->could_have_pending = 0;
  172. lws_stats_bump(pt, LWSSTATS_C_WRITEABLE_CB, 1);
  173. #if defined(LWS_WITH_STATS)
  174. if (wsi->active_writable_req_us) {
  175. uint64_t ul = lws_now_usecs() -
  176. wsi->active_writable_req_us;
  177. lws_stats_bump(pt, LWSSTATS_US_WRITABLE_DELAY_AVG, ul);
  178. lws_stats_max(pt,
  179. LWSSTATS_US_WORST_WRITABLE_DELAY, ul);
  180. wsi->active_writable_req_us = 0;
  181. }
  182. #endif
  183. n = user_callback_handle_rxflow(wsi->a.protocol->callback,
  184. wsi, LWS_CALLBACK_RAW_WRITEABLE,
  185. wsi->user_space, NULL, 0);
  186. if (n < 0) {
  187. lwsl_info("writeable_fail\n");
  188. goto fail;
  189. }
  190. return LWS_HPI_RET_HANDLED;
  191. fail:
  192. lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "raw svc fail");
  193. return LWS_HPI_RET_WSI_ALREADY_DIED;
  194. }
  195. #if defined(LWS_WITH_SERVER)
  196. static int
  197. rops_adoption_bind_raw_skt(struct lws *wsi, int type, const char *vh_prot_name)
  198. {
  199. /* no http but socket... must be raw skt */
  200. if ((type & LWS_ADOPT_HTTP) || !(type & LWS_ADOPT_SOCKET) ||
  201. (type & _LWS_ADOPT_FINISH))
  202. return 0; /* no match */
  203. #if defined(LWS_WITH_UDP)
  204. if (type & LWS_ADOPT_FLAG_UDP)
  205. /*
  206. * these can be >128 bytes, so just alloc for UDP
  207. */
  208. wsi->udp = lws_malloc(sizeof(*wsi->udp), "udp struct");
  209. #endif
  210. lws_role_transition(wsi, 0, (type & LWS_ADOPT_ALLOW_SSL) ? LRS_SSL_INIT :
  211. LRS_ESTABLISHED, &role_ops_raw_skt);
  212. if (vh_prot_name)
  213. lws_bind_protocol(wsi, wsi->a.protocol, __func__);
  214. else
  215. /* this is the only time he will transition */
  216. lws_bind_protocol(wsi,
  217. &wsi->a.vhost->protocols[wsi->a.vhost->raw_protocol_index],
  218. __func__);
  219. return 1; /* bound */
  220. }
  221. #endif
  222. #if defined(LWS_WITH_CLIENT)
  223. static int
  224. rops_client_bind_raw_skt(struct lws *wsi,
  225. const struct lws_client_connect_info *i)
  226. {
  227. if (!i) {
  228. /* finalize */
  229. if (!wsi->user_space && wsi->stash->cis[CIS_METHOD])
  230. if (lws_ensure_user_space(wsi))
  231. return 1;
  232. return 0;
  233. }
  234. /* we are a fallback if nothing else matched */
  235. if (!i->local_protocol_name ||
  236. strcmp(i->local_protocol_name, "raw-proxy"))
  237. lws_role_transition(wsi, LWSIFR_CLIENT, LRS_UNCONNECTED,
  238. &role_ops_raw_skt);
  239. return 1; /* matched */
  240. }
  241. #endif
  242. const struct lws_role_ops role_ops_raw_skt = {
  243. /* role name */ "raw-skt",
  244. /* alpn id */ NULL,
  245. /* check_upgrades */ NULL,
  246. /* pt_init_destroy */ NULL,
  247. /* init_vhost */ NULL,
  248. /* destroy_vhost */ NULL,
  249. /* service_flag_pending */ NULL,
  250. /* handle_POLLIN */ rops_handle_POLLIN_raw_skt,
  251. /* handle_POLLOUT */ NULL,
  252. /* perform_user_POLLOUT */ NULL,
  253. /* callback_on_writable */ NULL,
  254. /* tx_credit */ NULL,
  255. /* write_role_protocol */ NULL,
  256. /* encapsulation_parent */ NULL,
  257. /* alpn_negotiated */ NULL,
  258. /* close_via_role_protocol */ NULL,
  259. /* close_role */ NULL,
  260. /* close_kill_connection */ NULL,
  261. /* destroy_role */ NULL,
  262. #if defined(LWS_WITH_SERVER)
  263. /* adoption_bind */ rops_adoption_bind_raw_skt,
  264. #else
  265. NULL,
  266. #endif
  267. #if defined(LWS_WITH_CLIENT)
  268. /* client_bind */ rops_client_bind_raw_skt,
  269. #else
  270. NULL,
  271. #endif
  272. /* issue_keepalive */ NULL,
  273. /* adoption_cb clnt, srv */ { LWS_CALLBACK_RAW_CONNECTED,
  274. LWS_CALLBACK_RAW_ADOPT },
  275. /* rx_cb clnt, srv */ { LWS_CALLBACK_RAW_RX,
  276. LWS_CALLBACK_RAW_RX },
  277. /* writeable cb clnt, srv */ { LWS_CALLBACK_RAW_WRITEABLE,
  278. LWS_CALLBACK_RAW_WRITEABLE},
  279. /* close cb clnt, srv */ { LWS_CALLBACK_RAW_CLOSE,
  280. LWS_CALLBACK_RAW_CLOSE },
  281. /* protocol_bind cb c, srv */ { LWS_CALLBACK_RAW_SKT_BIND_PROTOCOL,
  282. LWS_CALLBACK_RAW_SKT_BIND_PROTOCOL },
  283. /* protocol_unbind cb c, srv */ { LWS_CALLBACK_RAW_SKT_DROP_PROTOCOL,
  284. LWS_CALLBACK_RAW_SKT_DROP_PROTOCOL },
  285. /* file_handle */ 0,
  286. };