close.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  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. #include "private-lib-core.h"
  25. #if defined(LWS_WITH_CLIENT)
  26. static int
  27. lws_close_trans_q_leader(struct lws_dll2 *d, void *user)
  28. {
  29. struct lws *w = lws_container_of(d, struct lws, dll2_cli_txn_queue);
  30. __lws_close_free_wsi(w, -1, "trans q leader closing");
  31. return 0;
  32. }
  33. #endif
  34. void
  35. __lws_reset_wsi(struct lws *wsi)
  36. {
  37. if (!wsi)
  38. return;
  39. #if defined(LWS_WITH_CLIENT)
  40. lws_free_set_NULL(wsi->cli_hostname_copy);
  41. /*
  42. * if we have wsi in our transaction queue, if we are closing we
  43. * must go through and close all those first
  44. */
  45. if (wsi->a.vhost) {
  46. /* we are no longer an active client connection that can piggyback */
  47. lws_dll2_remove(&wsi->dll_cli_active_conns);
  48. lws_dll2_foreach_safe(&wsi->dll2_cli_txn_queue_owner, NULL,
  49. lws_close_trans_q_leader);
  50. /*
  51. * !!! If we are closing, but we have pending pipelined
  52. * transaction results we already sent headers for, that's going
  53. * to destroy sync for HTTP/1 and leave H2 stream with no live
  54. * swsi.`
  55. *
  56. * However this is normal if we are being closed because the
  57. * transaction queue leader is closing.
  58. */
  59. lws_dll2_remove(&wsi->dll2_cli_txn_queue);
  60. }
  61. #endif
  62. if (wsi->a.vhost) {
  63. lws_vhost_lock(wsi->a.vhost);
  64. lws_dll2_remove(&wsi->vh_awaiting_socket);
  65. lws_vhost_unlock(wsi->a.vhost);
  66. }
  67. /*
  68. * Protocol user data may be allocated either internally by lws
  69. * or by specified the user. We should only free what we allocated.
  70. */
  71. if (wsi->a.protocol && wsi->a.protocol->per_session_data_size &&
  72. wsi->user_space && !wsi->user_space_externally_allocated) {
  73. /* confirm no sul left scheduled in user data itself */
  74. lws_sul_debug_zombies(wsi->a.context, wsi->user_space,
  75. wsi->a.protocol->per_session_data_size, __func__);
  76. lws_free_set_NULL(wsi->user_space);
  77. }
  78. /*
  79. * Don't let buflist content or state from the wsi's previous life
  80. * carry over to the new life
  81. */
  82. lws_buflist_destroy_all_segments(&wsi->buflist);
  83. lws_dll2_remove(&wsi->dll_buflist);
  84. lws_buflist_destroy_all_segments(&wsi->buflist_out);
  85. #if defined(LWS_WITH_UDP)
  86. if (wsi->udp) {
  87. /* confirm no sul left scheduled in wsi->udp itself */
  88. lws_sul_debug_zombies(wsi->a.context, wsi->udp,
  89. sizeof(*wsi->udp), "close udp wsi");
  90. lws_free_set_NULL(wsi->udp);
  91. }
  92. #endif
  93. wsi->retry = 0;
  94. #if defined(LWS_WITH_CLIENT)
  95. lws_dll2_remove(&wsi->dll2_cli_txn_queue);
  96. lws_dll2_remove(&wsi->dll_cli_active_conns);
  97. #endif
  98. #if defined(LWS_WITH_SYS_ASYNC_DNS)
  99. lws_async_dns_cancel(wsi);
  100. #endif
  101. #if defined(LWS_WITH_HTTP_PROXY)
  102. if (wsi->http.buflist_post_body)
  103. lws_buflist_destroy_all_segments(&wsi->http.buflist_post_body);
  104. #endif
  105. if (wsi->a.vhost && wsi->a.vhost->lserv_wsi == wsi)
  106. wsi->a.vhost->lserv_wsi = NULL;
  107. #if defined(LWS_WITH_CLIENT)
  108. if (wsi->a.vhost)
  109. lws_dll2_remove(&wsi->dll_cli_active_conns);
  110. #endif
  111. wsi->a.context->count_wsi_allocated--;
  112. __lws_same_vh_protocol_remove(wsi);
  113. #if defined(LWS_WITH_CLIENT)
  114. lws_free_set_NULL(wsi->stash);
  115. lws_free_set_NULL(wsi->cli_hostname_copy);
  116. #endif
  117. #if defined(LWS_WITH_PEER_LIMITS)
  118. lws_peer_track_wsi_close(wsi->a.context, wsi->peer);
  119. wsi->peer = NULL;
  120. #endif
  121. /* since we will destroy the wsi, make absolutely sure now */
  122. #if defined(LWS_WITH_OPENSSL)
  123. __lws_ssl_remove_wsi_from_buffered_list(wsi);
  124. #endif
  125. __lws_wsi_remove_from_sul(wsi);
  126. if (wsi->role_ops->destroy_role)
  127. wsi->role_ops->destroy_role(wsi);
  128. #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
  129. __lws_header_table_detach(wsi, 0);
  130. #endif
  131. }
  132. void
  133. __lws_free_wsi(struct lws *wsi)
  134. {
  135. if (!wsi)
  136. return;
  137. __lws_reset_wsi(wsi);
  138. __lws_wsi_remove_from_sul(wsi);
  139. if (wsi->a.context->event_loop_ops->destroy_wsi)
  140. wsi->a.context->event_loop_ops->destroy_wsi(wsi);
  141. lws_vhost_unbind_wsi(wsi);
  142. lwsl_debug("%s: %p, remaining wsi %d, tsi fds count %d\n", __func__, wsi,
  143. wsi->a.context->count_wsi_allocated,
  144. wsi->a.context->pt[(int)wsi->tsi].fds_count);
  145. /* confirm no sul left scheduled in wsi itself */
  146. lws_sul_debug_zombies(wsi->a.context, wsi, sizeof(wsi), __func__);
  147. lws_free(wsi);
  148. }
  149. void
  150. lws_remove_child_from_any_parent(struct lws *wsi)
  151. {
  152. struct lws **pwsi;
  153. int seen = 0;
  154. if (!wsi->parent)
  155. return;
  156. /* detach ourselves from parent's child list */
  157. pwsi = &wsi->parent->child_list;
  158. while (*pwsi) {
  159. if (*pwsi == wsi) {
  160. lwsl_info("%s: detach %p from parent %p\n", __func__,
  161. wsi, wsi->parent);
  162. if (wsi->parent->a.protocol)
  163. wsi->parent->a.protocol->callback(wsi,
  164. LWS_CALLBACK_CHILD_CLOSING,
  165. wsi->parent->user_space, wsi, 0);
  166. *pwsi = wsi->sibling_list;
  167. seen = 1;
  168. break;
  169. }
  170. pwsi = &(*pwsi)->sibling_list;
  171. }
  172. if (!seen)
  173. lwsl_err("%s: failed to detach from parent\n", __func__);
  174. wsi->parent = NULL;
  175. }
  176. #if defined(LWS_WITH_CLIENT)
  177. void
  178. lws_inform_client_conn_fail(struct lws *wsi, void *arg, size_t len)
  179. {
  180. lws_addrinfo_clean(wsi);
  181. if (wsi->already_did_cce)
  182. return;
  183. wsi->already_did_cce = 1;
  184. lws_stats_bump(&wsi->a.context->pt[(int)wsi->tsi],
  185. LWSSTATS_C_CONNS_CLIENT_FAILED, 1);
  186. if (!wsi->a.protocol)
  187. return;
  188. if (!wsi->client_suppress_CONNECTION_ERROR)
  189. wsi->a.protocol->callback(wsi,
  190. LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
  191. wsi->user_space, arg, len);
  192. }
  193. #endif
  194. void
  195. lws_addrinfo_clean(struct lws *wsi)
  196. {
  197. #if defined(LWS_WITH_CLIENT)
  198. if (!wsi->dns_results)
  199. return;
  200. #if defined(LWS_WITH_SYS_ASYNC_DNS)
  201. lws_async_dns_freeaddrinfo(&wsi->dns_results);
  202. #else
  203. freeaddrinfo((struct addrinfo *)wsi->dns_results);
  204. #endif
  205. wsi->dns_results = NULL;
  206. #endif
  207. }
  208. void
  209. __lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason,
  210. const char *caller)
  211. {
  212. struct lws_context_per_thread *pt;
  213. const struct lws_protocols *pro;
  214. struct lws_context *context;
  215. struct lws *wsi1, *wsi2;
  216. int n, ccb;
  217. lwsl_info("%s: %p: caller: %s\n", __func__, wsi, caller);
  218. if (!wsi)
  219. return;
  220. lws_access_log(wsi);
  221. if (!lws_dll2_is_detached(&wsi->dll_buflist)) {
  222. lwsl_info("%s: wsi %p: going down with stuff in buflist\n",
  223. __func__, wsi); }
  224. context = wsi->a.context;
  225. pt = &context->pt[(int)wsi->tsi];
  226. lws_pt_assert_lock_held(pt);
  227. lws_stats_bump(pt, LWSSTATS_C_API_CLOSE, 1);
  228. #if defined(LWS_WITH_CLIENT)
  229. lws_free_set_NULL(wsi->cli_hostname_copy);
  230. lws_addrinfo_clean(wsi);
  231. #endif
  232. #if defined(LWS_WITH_HTTP2)
  233. if (wsi->mux_stream_immortal)
  234. lws_http_close_immortal(wsi);
  235. #endif
  236. /* if we have children, close them first */
  237. if (wsi->child_list) {
  238. wsi2 = wsi->child_list;
  239. while (wsi2) {
  240. wsi1 = wsi2->sibling_list;
  241. // wsi2->parent = NULL;
  242. /* stop it doing shutdown processing */
  243. wsi2->socket_is_permanently_unusable = 1;
  244. __lws_close_free_wsi(wsi2, reason,
  245. "general child recurse");
  246. wsi2 = wsi1;
  247. }
  248. wsi->child_list = NULL;
  249. }
  250. #if defined(LWS_ROLE_RAW_FILE)
  251. if (wsi->role_ops == &role_ops_raw_file) {
  252. lws_remove_child_from_any_parent(wsi);
  253. __remove_wsi_socket_from_fds(wsi);
  254. if (wsi->a.protocol)
  255. wsi->a.protocol->callback(wsi, wsi->role_ops->close_cb[0],
  256. wsi->user_space, NULL, 0);
  257. goto async_close;
  258. }
  259. #endif
  260. wsi->wsistate_pre_close = wsi->wsistate;
  261. #ifdef LWS_WITH_CGI
  262. if (wsi->role_ops == &role_ops_cgi) {
  263. // lwsl_debug("%s: closing stdwsi index %d\n", __func__, (int)wsi->lsp_channel);
  264. /* we are not a network connection, but a handler for CGI io */
  265. if (wsi->parent && wsi->parent->http.cgi) {
  266. /*
  267. * We need to keep the logical cgi around so we can
  268. * drain it
  269. */
  270. // if (wsi->parent->child_list == wsi && !wsi->sibling_list)
  271. // lws_cgi_remove_and_kill(wsi->parent);
  272. /* end the binding between us and master */
  273. if (wsi->parent->http.cgi && wsi->parent->http.cgi->lsp)
  274. wsi->parent->http.cgi->lsp->stdwsi[(int)wsi->lsp_channel] =
  275. NULL;
  276. }
  277. wsi->socket_is_permanently_unusable = 1;
  278. goto just_kill_connection;
  279. }
  280. if (wsi->http.cgi)
  281. lws_cgi_remove_and_kill(wsi);
  282. #endif
  283. #if defined(LWS_WITH_CLIENT)
  284. lws_free_set_NULL(wsi->stash);
  285. #endif
  286. if (wsi->role_ops == &role_ops_raw_skt) {
  287. wsi->socket_is_permanently_unusable = 1;
  288. goto just_kill_connection;
  289. }
  290. #if defined(LWS_WITH_FILE_OPS) && (defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2))
  291. if (lwsi_role_http(wsi) && lwsi_role_server(wsi) &&
  292. wsi->http.fop_fd != NULL)
  293. lws_vfs_file_close(&wsi->http.fop_fd);
  294. #endif
  295. if (lwsi_state(wsi) == LRS_DEAD_SOCKET)
  296. return;
  297. if (wsi->socket_is_permanently_unusable ||
  298. reason == LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY ||
  299. lwsi_state(wsi) == LRS_SHUTDOWN)
  300. goto just_kill_connection;
  301. switch (lwsi_state_PRE_CLOSE(wsi)) {
  302. case LRS_DEAD_SOCKET:
  303. return;
  304. /* we tried the polite way... */
  305. case LRS_WAITING_TO_SEND_CLOSE:
  306. case LRS_AWAITING_CLOSE_ACK:
  307. case LRS_RETURNED_CLOSE:
  308. goto just_kill_connection;
  309. case LRS_FLUSHING_BEFORE_CLOSE:
  310. if (lws_has_buffered_out(wsi)
  311. #if defined(LWS_WITH_HTTP_STREAM_COMPRESSION)
  312. || wsi->http.comp_ctx.buflist_comp ||
  313. wsi->http.comp_ctx.may_have_more
  314. #endif
  315. ) {
  316. lws_callback_on_writable(wsi);
  317. return;
  318. }
  319. lwsl_info("%p: end LRS_FLUSHING_BEFORE_CLOSE\n", wsi);
  320. goto just_kill_connection;
  321. default:
  322. if (lws_has_buffered_out(wsi)
  323. #if defined(LWS_WITH_HTTP_STREAM_COMPRESSION)
  324. || wsi->http.comp_ctx.buflist_comp ||
  325. wsi->http.comp_ctx.may_have_more
  326. #endif
  327. ) {
  328. lwsl_info("%p: LRS_FLUSHING_BEFORE_CLOSE\n", wsi);
  329. lwsi_set_state(wsi, LRS_FLUSHING_BEFORE_CLOSE);
  330. __lws_set_timeout(wsi,
  331. PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE, 5);
  332. return;
  333. }
  334. break;
  335. }
  336. if (lwsi_state(wsi) == LRS_WAITING_CONNECT ||
  337. lwsi_state(wsi) == LRS_WAITING_DNS ||
  338. lwsi_state(wsi) == LRS_H1C_ISSUE_HANDSHAKE)
  339. goto just_kill_connection;
  340. if (!wsi->told_user_closed && wsi->user_space && wsi->a.protocol &&
  341. wsi->protocol_bind_balance) {
  342. wsi->a.protocol->callback(wsi,
  343. wsi->role_ops->protocol_unbind_cb[
  344. !!lwsi_role_server(wsi)],
  345. wsi->user_space, (void *)__func__, 0);
  346. wsi->protocol_bind_balance = 0;
  347. }
  348. /*
  349. * signal we are closing, lws_write will
  350. * add any necessary version-specific stuff. If the write fails,
  351. * no worries we are closing anyway. If we didn't initiate this
  352. * close, then our state has been changed to
  353. * LRS_RETURNED_CLOSE and we will skip this.
  354. *
  355. * Likewise if it's a second call to close this connection after we
  356. * sent the close indication to the peer already, we are in state
  357. * LRS_AWAITING_CLOSE_ACK and will skip doing this a second time.
  358. */
  359. if (wsi->role_ops->close_via_role_protocol &&
  360. wsi->role_ops->close_via_role_protocol(wsi, reason))
  361. return;
  362. just_kill_connection:
  363. #if defined(LWS_WITH_FILE_OPS) && (defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2))
  364. if (lwsi_role_http(wsi) && lwsi_role_server(wsi) &&
  365. wsi->http.fop_fd != NULL)
  366. lws_vfs_file_close(&wsi->http.fop_fd);
  367. #endif
  368. lws_sul_cancel(&wsi->sul_connect_timeout);
  369. #if defined(LWS_WITH_SYS_ASYNC_DNS)
  370. lws_async_dns_cancel(wsi);
  371. #endif
  372. #if defined(LWS_WITH_HTTP_PROXY)
  373. if (wsi->http.buflist_post_body)
  374. lws_buflist_destroy_all_segments(&wsi->http.buflist_post_body);
  375. #endif
  376. #if defined(LWS_WITH_UDP)
  377. if (wsi->udp) {
  378. /* confirm no sul left scheduled in wsi->udp itself */
  379. lws_sul_debug_zombies(wsi->a.context, wsi->udp,
  380. sizeof(*wsi->udp), "close udp wsi");
  381. lws_free_set_NULL(wsi->udp);
  382. }
  383. #endif
  384. if (wsi->role_ops->close_kill_connection)
  385. wsi->role_ops->close_kill_connection(wsi, reason);
  386. n = 0;
  387. if (!wsi->told_user_closed && wsi->user_space &&
  388. wsi->protocol_bind_balance && wsi->a.protocol) {
  389. lwsl_debug("%s: %p: DROP_PROTOCOL %s\n", __func__, wsi,
  390. wsi->a.protocol ? wsi->a.protocol->name: "NULL");
  391. if (wsi->a.protocol)
  392. wsi->a.protocol->callback(wsi,
  393. wsi->role_ops->protocol_unbind_cb[
  394. !!lwsi_role_server(wsi)],
  395. wsi->user_space, (void *)__func__, 0);
  396. wsi->protocol_bind_balance = 0;
  397. }
  398. #if defined(LWS_WITH_SECURE_STREAMS) && defined(LWS_WITH_SERVER)
  399. if (wsi->for_ss) {
  400. /*
  401. * We were adopted for a particular ss, but, eg, we may not
  402. * have succeeded with the connection... we are closing which is
  403. * good, but we have to invalidate any pointer the related ss
  404. * handle may be holding on us
  405. */
  406. lws_ss_handle_t *h = (lws_ss_handle_t *)wsi->a.opaque_user_data;
  407. if (h) {
  408. h->wsi = NULL;
  409. wsi->a.opaque_user_data = NULL;
  410. }
  411. }
  412. #endif
  413. #if defined(LWS_WITH_CLIENT)
  414. if ((
  415. #if defined(LWS_ROLE_WS)
  416. /*
  417. * If our goal is a ws upgrade, effectively we did not reach
  418. * ESTABLISHED if we did not get the upgrade server reply
  419. */
  420. (lwsi_state(wsi) == LRS_WAITING_SERVER_REPLY &&
  421. wsi->role_ops == &role_ops_ws) ||
  422. #endif
  423. lwsi_state(wsi) == LRS_WAITING_DNS ||
  424. lwsi_state(wsi) == LRS_WAITING_CONNECT) &&
  425. !wsi->already_did_cce && wsi->a.protocol) {
  426. static const char _reason[] = "closed before established";
  427. lwsl_debug("%s: closing in unestablished state 0x%x\n",
  428. __func__, lwsi_state(wsi));
  429. wsi->socket_is_permanently_unusable = 1;
  430. lws_inform_client_conn_fail(wsi,
  431. (void *)_reason, sizeof(_reason));
  432. }
  433. #endif
  434. /*
  435. * Testing with ab shows that we have to stage the socket close when
  436. * the system is under stress... shutdown any further TX, change the
  437. * state to one that won't emit anything more, and wait with a timeout
  438. * for the POLLIN to show a zero-size rx before coming back and doing
  439. * the actual close.
  440. */
  441. if (wsi->role_ops != &role_ops_raw_skt && !lwsi_role_client(wsi) &&
  442. lwsi_state(wsi) != LRS_SHUTDOWN &&
  443. lwsi_state(wsi) != LRS_UNCONNECTED &&
  444. reason != LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY &&
  445. !wsi->socket_is_permanently_unusable) {
  446. #if defined(LWS_WITH_TLS)
  447. if (lws_is_ssl(wsi) && wsi->tls.ssl) {
  448. n = 0;
  449. switch (__lws_tls_shutdown(wsi)) {
  450. case LWS_SSL_CAPABLE_DONE:
  451. case LWS_SSL_CAPABLE_ERROR:
  452. case LWS_SSL_CAPABLE_MORE_SERVICE_READ:
  453. case LWS_SSL_CAPABLE_MORE_SERVICE_WRITE:
  454. case LWS_SSL_CAPABLE_MORE_SERVICE:
  455. break;
  456. }
  457. } else
  458. #endif
  459. {
  460. lwsl_info("%s: shutdown conn: %p (sk %d, state 0x%x)\n",
  461. __func__, wsi, (int)(lws_intptr_t)wsi->desc.sockfd,
  462. lwsi_state(wsi));
  463. if (!wsi->socket_is_permanently_unusable &&
  464. lws_socket_is_valid(wsi->desc.sockfd)) {
  465. wsi->socket_is_permanently_unusable = 1;
  466. n = shutdown(wsi->desc.sockfd, SHUT_WR);
  467. }
  468. }
  469. if (n)
  470. lwsl_debug("closing: shutdown (state 0x%x) ret %d\n",
  471. lwsi_state(wsi), LWS_ERRNO);
  472. /*
  473. * This causes problems on WINCE / ESP32 with disconnection
  474. * when the events are half closing connection
  475. */
  476. #if !defined(_WIN32_WCE) && !defined(LWS_PLAT_FREERTOS)
  477. /* libuv: no event available to guarantee completion */
  478. if (!wsi->socket_is_permanently_unusable &&
  479. lws_socket_is_valid(wsi->desc.sockfd) &&
  480. lwsi_state(wsi) != LRS_SHUTDOWN &&
  481. (context->event_loop_ops->flags & LELOF_ISPOLL)) {
  482. __lws_change_pollfd(wsi, LWS_POLLOUT, LWS_POLLIN);
  483. lwsi_set_state(wsi, LRS_SHUTDOWN);
  484. __lws_set_timeout(wsi, PENDING_TIMEOUT_SHUTDOWN_FLUSH,
  485. context->timeout_secs);
  486. return;
  487. }
  488. #endif
  489. }
  490. lwsl_debug("%s: real just_kill_connection: %p (sockfd %d)\n", __func__,
  491. wsi, wsi->desc.sockfd);
  492. #ifdef LWS_WITH_HUBBUB
  493. if (wsi->http.rw) {
  494. lws_rewrite_destroy(wsi->http.rw);
  495. wsi->http.rw = NULL;
  496. }
  497. #endif
  498. if (wsi->http.pending_return_headers)
  499. lws_free_set_NULL(wsi->http.pending_return_headers);
  500. /*
  501. * we won't be servicing or receiving anything further from this guy
  502. * delete socket from the internal poll list if still present
  503. */
  504. __lws_ssl_remove_wsi_from_buffered_list(wsi);
  505. __lws_wsi_remove_from_sul(wsi);
  506. //if (wsi->told_event_loop_closed) // cgi std close case (dummy-callback)
  507. // return;
  508. // lwsl_notice("%s: wsi %p, fd %d\n", __func__, wsi, wsi->desc.sockfd);
  509. /* checking return redundant since we anyway close */
  510. __remove_wsi_socket_from_fds(wsi);
  511. lwsi_set_state(wsi, LRS_DEAD_SOCKET);
  512. lws_buflist_destroy_all_segments(&wsi->buflist);
  513. lws_dll2_remove(&wsi->dll_buflist);
  514. if (wsi->role_ops->close_role)
  515. wsi->role_ops->close_role(pt, wsi);
  516. /* tell the user it's all over for this guy */
  517. ccb = 0;
  518. if ((lwsi_state_est_PRE_CLOSE(wsi) ||
  519. /* raw skt adopted but didn't complete tls hs should CLOSE */
  520. (wsi->role_ops == &role_ops_raw_skt && !lwsi_role_client(wsi)) ||
  521. lwsi_state_PRE_CLOSE(wsi) == LRS_WAITING_SERVER_REPLY) &&
  522. !wsi->told_user_closed &&
  523. wsi->role_ops->close_cb[lwsi_role_server(wsi)]) {
  524. if (!wsi->upgraded_to_http2 || !lwsi_role_client(wsi))
  525. ccb = 1;
  526. /*
  527. * The network wsi for a client h2 connection shouldn't
  528. * call back for its role: the child stream connections
  529. * own the role. Otherwise h2 will call back closed
  530. * one too many times as the children do it and then
  531. * the closing network stream.
  532. */
  533. }
  534. if (!wsi->told_user_closed &&
  535. !lws_dll2_is_detached(&wsi->vh_awaiting_socket))
  536. /*
  537. * He's a guy who go started with dns, but failed or is
  538. * caught with a shutdown before he got the result. We have
  539. * to issue him a close cb
  540. */
  541. ccb = 1;
  542. pro = wsi->a.protocol;
  543. if (wsi->already_did_cce)
  544. /*
  545. * If we handled this by CLIENT_CONNECTION_ERROR, it's
  546. * mutually exclusive with CLOSE
  547. */
  548. ccb = 0;
  549. #if defined(LWS_WITH_CLIENT)
  550. if (!ccb && (lwsi_state_PRE_CLOSE(wsi) & LWSIFS_NOT_EST) &&
  551. lwsi_role_client(wsi)) {
  552. lws_inform_client_conn_fail(wsi, "Closed before conn", 18);
  553. }
  554. #endif
  555. if (ccb) {
  556. if (!wsi->a.protocol && wsi->a.vhost && wsi->a.vhost->protocols)
  557. pro = &wsi->a.vhost->protocols[0];
  558. if (pro)
  559. pro->callback(wsi,
  560. wsi->role_ops->close_cb[lwsi_role_server(wsi)],
  561. wsi->user_space, NULL, 0);
  562. wsi->told_user_closed = 1;
  563. }
  564. #if defined(LWS_ROLE_RAW_FILE)
  565. async_close:
  566. #endif
  567. lws_remove_child_from_any_parent(wsi);
  568. wsi->socket_is_permanently_unusable = 1;
  569. if (wsi->a.context->event_loop_ops->wsi_logical_close)
  570. if (wsi->a.context->event_loop_ops->wsi_logical_close(wsi))
  571. return;
  572. __lws_close_free_wsi_final(wsi);
  573. }
  574. void
  575. __lws_close_free_wsi_final(struct lws *wsi)
  576. {
  577. int n;
  578. if (!wsi->shadow &&
  579. lws_socket_is_valid(wsi->desc.sockfd) && !lws_ssl_close(wsi)) {
  580. lwsl_debug("%s: wsi %p: fd %d\n", __func__, wsi, wsi->desc.sockfd);
  581. n = compatible_close(wsi->desc.sockfd);
  582. if (n)
  583. lwsl_debug("closing: close ret %d\n", LWS_ERRNO);
  584. __remove_wsi_socket_from_fds(wsi);
  585. if (lws_socket_is_valid(wsi->desc.sockfd))
  586. delete_from_fd(wsi->a.context, wsi->desc.sockfd);
  587. #if !defined(LWS_PLAT_FREERTOS) && !defined(WIN32) && !defined(LWS_PLAT_OPTEE)
  588. delete_from_fdwsi(wsi->a.context, wsi);
  589. #endif
  590. sanity_assert_no_sockfd_traces(wsi->a.context, wsi->desc.sockfd);
  591. wsi->desc.sockfd = LWS_SOCK_INVALID;
  592. }
  593. /* outermost destroy notification for wsi (user_space still intact) */
  594. if (wsi->a.vhost)
  595. wsi->a.vhost->protocols[0].callback(wsi, LWS_CALLBACK_WSI_DESTROY,
  596. wsi->user_space, NULL, 0);
  597. #ifdef LWS_WITH_CGI
  598. if (wsi->http.cgi) {
  599. lws_spawn_piped_destroy(&wsi->http.cgi->lsp);
  600. lws_sul_cancel(&wsi->http.cgi->sul_grace);
  601. lws_free_set_NULL(wsi->http.cgi);
  602. }
  603. #endif
  604. __lws_wsi_remove_from_sul(wsi);
  605. sanity_assert_no_wsi_traces(wsi->a.context, wsi);
  606. __lws_free_wsi(wsi);
  607. }
  608. void
  609. lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason, const char *caller)
  610. {
  611. struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
  612. lws_pt_lock(pt, __func__);
  613. __lws_close_free_wsi(wsi, reason, caller);
  614. lws_pt_unlock(pt);
  615. }