client-parser.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010-2014 Andy Green <andy@warmcat.com>
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation:
  9. * version 2.1 of the License.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  19. * MA 02110-1301 USA
  20. */
  21. #include "private-libwebsockets.h"
  22. int lws_client_rx_sm(struct lws *wsi, unsigned char c)
  23. {
  24. struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
  25. int callback_action = LWS_CALLBACK_CLIENT_RECEIVE;
  26. int handled, n, m, rx_draining_ext = 0;
  27. unsigned short close_code;
  28. struct lws_tokens eff_buf;
  29. unsigned char *pp;
  30. if (wsi->u.ws.rx_draining_ext) {
  31. struct lws **w = &pt->rx_draining_ext_list;
  32. lwsl_ext("%s: RX EXT DRAINING: Removing from list\n", __func__, c);
  33. assert(!c);
  34. eff_buf.token = NULL;
  35. eff_buf.token_len = 0;
  36. wsi->u.ws.rx_draining_ext = 0;
  37. /* remove us from context draining ext list */
  38. while (*w) {
  39. if (*w == wsi) {
  40. *w = wsi->u.ws.rx_draining_ext_list;
  41. break;
  42. }
  43. w = &((*w)->u.ws.rx_draining_ext_list);
  44. }
  45. wsi->u.ws.rx_draining_ext_list = NULL;
  46. rx_draining_ext = 1;
  47. goto drain_extension;
  48. }
  49. switch (wsi->lws_rx_parse_state) {
  50. case LWS_RXPS_NEW:
  51. /* control frames (PING) may interrupt checkable sequences */
  52. wsi->u.ws.defeat_check_utf8 = 0;
  53. switch (wsi->ietf_spec_revision) {
  54. case 13:
  55. wsi->u.ws.opcode = c & 0xf;
  56. /* revisit if an extension wants them... */
  57. switch (wsi->u.ws.opcode) {
  58. case LWSWSOPC_TEXT_FRAME:
  59. wsi->u.ws.rsv_first_msg = (c & 0x70);
  60. wsi->u.ws.continuation_possible = 1;
  61. wsi->u.ws.check_utf8 = lws_check_opt(
  62. wsi->context->options,
  63. LWS_SERVER_OPTION_VALIDATE_UTF8);
  64. wsi->u.ws.utf8 = 0;
  65. break;
  66. case LWSWSOPC_BINARY_FRAME:
  67. wsi->u.ws.rsv_first_msg = (c & 0x70);
  68. wsi->u.ws.check_utf8 = 0;
  69. wsi->u.ws.continuation_possible = 1;
  70. break;
  71. case LWSWSOPC_CONTINUATION:
  72. if (!wsi->u.ws.continuation_possible) {
  73. lwsl_info("disordered continuation\n");
  74. return -1;
  75. }
  76. break;
  77. case LWSWSOPC_CLOSE:
  78. wsi->u.ws.check_utf8 = 0;
  79. wsi->u.ws.utf8 = 0;
  80. break;
  81. case 3:
  82. case 4:
  83. case 5:
  84. case 6:
  85. case 7:
  86. case 0xb:
  87. case 0xc:
  88. case 0xd:
  89. case 0xe:
  90. case 0xf:
  91. lwsl_info("illegal opcode\n");
  92. return -1;
  93. default:
  94. wsi->u.ws.defeat_check_utf8 = 1;
  95. break;
  96. }
  97. wsi->u.ws.rsv = (c & 0x70);
  98. /* revisit if an extension wants them... */
  99. if (
  100. #ifndef LWS_NO_EXTENSIONS
  101. !wsi->count_act_ext &&
  102. #endif
  103. wsi->u.ws.rsv) {
  104. lwsl_info("illegal rsv bits set\n");
  105. return -1;
  106. }
  107. wsi->u.ws.final = !!((c >> 7) & 1);
  108. lwsl_ext("%s: This RX frame Final %d\n", __func__, wsi->u.ws.final);
  109. if (wsi->u.ws.owed_a_fin &&
  110. (wsi->u.ws.opcode == LWSWSOPC_TEXT_FRAME ||
  111. wsi->u.ws.opcode == LWSWSOPC_BINARY_FRAME)) {
  112. lwsl_info("hey you owed us a FIN\n");
  113. return -1;
  114. }
  115. if ((!(wsi->u.ws.opcode & 8)) && wsi->u.ws.final) {
  116. wsi->u.ws.continuation_possible = 0;
  117. wsi->u.ws.owed_a_fin = 0;
  118. }
  119. if ((wsi->u.ws.opcode & 8) && !wsi->u.ws.final) {
  120. lwsl_info("control message cannot be fragmented\n");
  121. return -1;
  122. }
  123. if (!wsi->u.ws.final)
  124. wsi->u.ws.owed_a_fin = 1;
  125. switch (wsi->u.ws.opcode) {
  126. case LWSWSOPC_TEXT_FRAME:
  127. case LWSWSOPC_BINARY_FRAME:
  128. wsi->u.ws.frame_is_binary = wsi->u.ws.opcode ==
  129. LWSWSOPC_BINARY_FRAME;
  130. break;
  131. }
  132. wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
  133. break;
  134. default:
  135. lwsl_err("unknown spec version %02d\n",
  136. wsi->ietf_spec_revision);
  137. break;
  138. }
  139. break;
  140. case LWS_RXPS_04_FRAME_HDR_LEN:
  141. wsi->u.ws.this_frame_masked = !!(c & 0x80);
  142. switch (c & 0x7f) {
  143. case 126:
  144. /* control frames are not allowed to have big lengths */
  145. if (wsi->u.ws.opcode & 8)
  146. goto illegal_ctl_length;
  147. wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
  148. break;
  149. case 127:
  150. /* control frames are not allowed to have big lengths */
  151. if (wsi->u.ws.opcode & 8)
  152. goto illegal_ctl_length;
  153. wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
  154. break;
  155. default:
  156. wsi->u.ws.rx_packet_length = c;
  157. if (wsi->u.ws.this_frame_masked)
  158. wsi->lws_rx_parse_state =
  159. LWS_RXPS_07_COLLECT_FRAME_KEY_1;
  160. else {
  161. if (c)
  162. wsi->lws_rx_parse_state =
  163. LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
  164. else {
  165. wsi->lws_rx_parse_state = LWS_RXPS_NEW;
  166. goto spill;
  167. }
  168. }
  169. break;
  170. }
  171. break;
  172. case LWS_RXPS_04_FRAME_HDR_LEN16_2:
  173. wsi->u.ws.rx_packet_length = c << 8;
  174. wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
  175. break;
  176. case LWS_RXPS_04_FRAME_HDR_LEN16_1:
  177. wsi->u.ws.rx_packet_length |= c;
  178. if (wsi->u.ws.this_frame_masked)
  179. wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_1;
  180. else {
  181. if (wsi->u.ws.rx_packet_length)
  182. wsi->lws_rx_parse_state =
  183. LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
  184. else {
  185. wsi->lws_rx_parse_state = LWS_RXPS_NEW;
  186. goto spill;
  187. }
  188. }
  189. break;
  190. case LWS_RXPS_04_FRAME_HDR_LEN64_8:
  191. if (c & 0x80) {
  192. lwsl_warn("b63 of length must be zero\n");
  193. /* kill the connection */
  194. return -1;
  195. }
  196. #if defined __LP64__
  197. wsi->u.ws.rx_packet_length = ((size_t)c) << 56;
  198. #else
  199. wsi->u.ws.rx_packet_length = 0;
  200. #endif
  201. wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
  202. break;
  203. case LWS_RXPS_04_FRAME_HDR_LEN64_7:
  204. #if defined __LP64__
  205. wsi->u.ws.rx_packet_length |= ((size_t)c) << 48;
  206. #endif
  207. wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
  208. break;
  209. case LWS_RXPS_04_FRAME_HDR_LEN64_6:
  210. #if defined __LP64__
  211. wsi->u.ws.rx_packet_length |= ((size_t)c) << 40;
  212. #endif
  213. wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
  214. break;
  215. case LWS_RXPS_04_FRAME_HDR_LEN64_5:
  216. #if defined __LP64__
  217. wsi->u.ws.rx_packet_length |= ((size_t)c) << 32;
  218. #endif
  219. wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
  220. break;
  221. case LWS_RXPS_04_FRAME_HDR_LEN64_4:
  222. wsi->u.ws.rx_packet_length |= ((size_t)c) << 24;
  223. wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
  224. break;
  225. case LWS_RXPS_04_FRAME_HDR_LEN64_3:
  226. wsi->u.ws.rx_packet_length |= ((size_t)c) << 16;
  227. wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
  228. break;
  229. case LWS_RXPS_04_FRAME_HDR_LEN64_2:
  230. wsi->u.ws.rx_packet_length |= ((size_t)c) << 8;
  231. wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
  232. break;
  233. case LWS_RXPS_04_FRAME_HDR_LEN64_1:
  234. wsi->u.ws.rx_packet_length |= (size_t)c;
  235. if (wsi->u.ws.this_frame_masked)
  236. wsi->lws_rx_parse_state =
  237. LWS_RXPS_07_COLLECT_FRAME_KEY_1;
  238. else {
  239. if (wsi->u.ws.rx_packet_length)
  240. wsi->lws_rx_parse_state =
  241. LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
  242. else {
  243. wsi->lws_rx_parse_state = LWS_RXPS_NEW;
  244. goto spill;
  245. }
  246. }
  247. break;
  248. case LWS_RXPS_07_COLLECT_FRAME_KEY_1:
  249. wsi->u.ws.mask[0] = c;
  250. if (c)
  251. wsi->u.ws.all_zero_nonce = 0;
  252. wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2;
  253. break;
  254. case LWS_RXPS_07_COLLECT_FRAME_KEY_2:
  255. wsi->u.ws.mask[1] = c;
  256. if (c)
  257. wsi->u.ws.all_zero_nonce = 0;
  258. wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3;
  259. break;
  260. case LWS_RXPS_07_COLLECT_FRAME_KEY_3:
  261. wsi->u.ws.mask[2] = c;
  262. if (c)
  263. wsi->u.ws.all_zero_nonce = 0;
  264. wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4;
  265. break;
  266. case LWS_RXPS_07_COLLECT_FRAME_KEY_4:
  267. wsi->u.ws.mask[3] = c;
  268. if (c)
  269. wsi->u.ws.all_zero_nonce = 0;
  270. if (wsi->u.ws.rx_packet_length)
  271. wsi->lws_rx_parse_state =
  272. LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
  273. else {
  274. wsi->lws_rx_parse_state = LWS_RXPS_NEW;
  275. goto spill;
  276. }
  277. break;
  278. case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
  279. assert(wsi->u.ws.rx_ubuf);
  280. if (wsi->u.ws.this_frame_masked && !wsi->u.ws.all_zero_nonce)
  281. c ^= wsi->u.ws.mask[(wsi->u.ws.mask_idx++) & 3];
  282. wsi->u.ws.rx_ubuf[LWS_PRE + (wsi->u.ws.rx_ubuf_head++)] = c;
  283. if (--wsi->u.ws.rx_packet_length == 0) {
  284. /* spill because we have the whole frame */
  285. wsi->lws_rx_parse_state = LWS_RXPS_NEW;
  286. goto spill;
  287. }
  288. /*
  289. * if there's no protocol max frame size given, we are
  290. * supposed to default to context->pt_serv_buf_size
  291. */
  292. if (!wsi->protocol->rx_buffer_size &&
  293. wsi->u.ws.rx_ubuf_head != wsi->context->pt_serv_buf_size)
  294. break;
  295. if (wsi->protocol->rx_buffer_size &&
  296. wsi->u.ws.rx_ubuf_head != wsi->protocol->rx_buffer_size)
  297. break;
  298. /* spill because we filled our rx buffer */
  299. spill:
  300. handled = 0;
  301. /*
  302. * is this frame a control packet we should take care of at this
  303. * layer? If so service it and hide it from the user callback
  304. */
  305. switch (wsi->u.ws.opcode) {
  306. case LWSWSOPC_CLOSE:
  307. pp = (unsigned char *)&wsi->u.ws.rx_ubuf[LWS_PRE];
  308. if (lws_check_opt(wsi->context->options,
  309. LWS_SERVER_OPTION_VALIDATE_UTF8) &&
  310. wsi->u.ws.rx_ubuf_head > 2 &&
  311. lws_check_utf8(&wsi->u.ws.utf8, pp + 2,
  312. wsi->u.ws.rx_ubuf_head - 2))
  313. goto utf8_fail;
  314. /* is this an acknowledgement of our close? */
  315. if (wsi->state == LWSS_AWAITING_CLOSE_ACK) {
  316. /*
  317. * fine he has told us he is closing too, let's
  318. * finish our close
  319. */
  320. lwsl_parser("seen server's close ack\n");
  321. return -1;
  322. }
  323. lwsl_parser("client sees server close len = %d\n",
  324. wsi->u.ws.rx_ubuf_head);
  325. if (wsi->u.ws.rx_ubuf_head >= 2) {
  326. close_code = (pp[0] << 8) | pp[1];
  327. if (close_code < 1000 || close_code == 1004 ||
  328. close_code == 1005 || close_code == 1006 ||
  329. close_code == 1012 || close_code == 1013 ||
  330. close_code == 1014 || close_code == 1015 ||
  331. (close_code >= 1016 && close_code < 3000)
  332. ) {
  333. pp[0] = (LWS_CLOSE_STATUS_PROTOCOL_ERR >> 8) & 0xff;
  334. pp[1] = LWS_CLOSE_STATUS_PROTOCOL_ERR & 0xff;
  335. }
  336. }
  337. if (user_callback_handle_rxflow(
  338. wsi->protocol->callback, wsi,
  339. LWS_CALLBACK_WS_PEER_INITIATED_CLOSE,
  340. wsi->user_space, pp,
  341. wsi->u.ws.rx_ubuf_head))
  342. return -1;
  343. /*
  344. * parrot the close packet payload back
  345. * we do not care about how it went, we are closing
  346. * immediately afterwards
  347. */
  348. lws_write(wsi, (unsigned char *)&wsi->u.ws.rx_ubuf[LWS_PRE],
  349. wsi->u.ws.rx_ubuf_head, LWS_WRITE_CLOSE);
  350. wsi->state = LWSS_RETURNED_CLOSE_ALREADY;
  351. /* close the connection */
  352. return -1;
  353. case LWSWSOPC_PING:
  354. lwsl_info("received %d byte ping, sending pong\n",
  355. wsi->u.ws.rx_ubuf_head);
  356. /* he set a close reason on this guy, ignore PING */
  357. if (wsi->u.ws.close_in_ping_buffer_len)
  358. goto ping_drop;
  359. if (wsi->u.ws.ping_pending_flag) {
  360. /*
  361. * there is already a pending ping payload
  362. * we should just log and drop
  363. */
  364. lwsl_parser("DROP PING since one pending\n");
  365. goto ping_drop;
  366. }
  367. /* control packets can only be < 128 bytes long */
  368. if (wsi->u.ws.rx_ubuf_head > 128 - 3) {
  369. lwsl_parser("DROP PING payload too large\n");
  370. goto ping_drop;
  371. }
  372. /* stash the pong payload */
  373. memcpy(wsi->u.ws.ping_payload_buf + LWS_PRE,
  374. &wsi->u.ws.rx_ubuf[LWS_PRE],
  375. wsi->u.ws.rx_ubuf_head);
  376. wsi->u.ws.ping_payload_len = wsi->u.ws.rx_ubuf_head;
  377. wsi->u.ws.ping_pending_flag = 1;
  378. /* get it sent as soon as possible */
  379. lws_callback_on_writable(wsi);
  380. ping_drop:
  381. wsi->u.ws.rx_ubuf_head = 0;
  382. handled = 1;
  383. break;
  384. case LWSWSOPC_PONG:
  385. lwsl_info("client receied pong\n");
  386. lwsl_hexdump(&wsi->u.ws.rx_ubuf[LWS_PRE],
  387. wsi->u.ws.rx_ubuf_head);
  388. if (wsi->pending_timeout == PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG) {
  389. lwsl_info("received expected PONG on wsi %p\n", wsi);
  390. lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
  391. }
  392. /* issue it */
  393. callback_action = LWS_CALLBACK_CLIENT_RECEIVE_PONG;
  394. break;
  395. case LWSWSOPC_CONTINUATION:
  396. case LWSWSOPC_TEXT_FRAME:
  397. case LWSWSOPC_BINARY_FRAME:
  398. break;
  399. default:
  400. lwsl_parser("Reserved opc 0x%2X\n", wsi->u.ws.opcode);
  401. /*
  402. * It's something special we can't understand here.
  403. * Pass the payload up to the extension's parsing
  404. * state machine.
  405. */
  406. eff_buf.token = &wsi->u.ws.rx_ubuf[LWS_PRE];
  407. eff_buf.token_len = wsi->u.ws.rx_ubuf_head;
  408. if (lws_ext_cb_active(wsi,
  409. LWS_EXT_CB_EXTENDED_PAYLOAD_RX,
  410. &eff_buf, 0) <= 0) { /* not handle or fail */
  411. lwsl_ext("Unhandled ext opc 0x%x\n", wsi->u.ws.opcode);
  412. wsi->u.ws.rx_ubuf_head = 0;
  413. return 0;
  414. }
  415. handled = 1;
  416. break;
  417. }
  418. /*
  419. * No it's real payload, pass it up to the user callback.
  420. * It's nicely buffered with the pre-padding taken care of
  421. * so it can be sent straight out again using lws_write
  422. */
  423. if (handled)
  424. goto already_done;
  425. eff_buf.token = &wsi->u.ws.rx_ubuf[LWS_PRE];
  426. eff_buf.token_len = wsi->u.ws.rx_ubuf_head;
  427. drain_extension:
  428. n = lws_ext_cb_active(wsi, LWS_EXT_CB_PAYLOAD_RX, &eff_buf, 0);
  429. lwsl_ext("Ext RX returned %d\n", n);
  430. if (n < 0) /* fail */
  431. return -1;
  432. lwsl_ext("post inflate eff_buf len %d\n", eff_buf.token_len);
  433. if (rx_draining_ext && !eff_buf.token_len) {
  434. lwsl_err(" --- ignoring zero drain result, ending drain\n");
  435. goto already_done;
  436. }
  437. if (wsi->u.ws.check_utf8 && !wsi->u.ws.defeat_check_utf8) {
  438. if (lws_check_utf8(&wsi->u.ws.utf8,
  439. (unsigned char *)eff_buf.token,
  440. eff_buf.token_len))
  441. goto utf8_fail;
  442. /* we are ending partway through utf-8 character? */
  443. if (!wsi->u.ws.rx_packet_length && wsi->u.ws.final && wsi->u.ws.utf8 && !n) {
  444. lwsl_info("FINAL utf8 error\n");
  445. utf8_fail: lwsl_info("utf8 error\n");
  446. return -1;
  447. }
  448. }
  449. if (eff_buf.token_len < 0 &&
  450. callback_action != LWS_CALLBACK_CLIENT_RECEIVE_PONG)
  451. goto already_done;
  452. if (!eff_buf.token)
  453. goto already_done;
  454. eff_buf.token[eff_buf.token_len] = '\0';
  455. if (!wsi->protocol->callback)
  456. goto already_done;
  457. if (callback_action == LWS_CALLBACK_CLIENT_RECEIVE_PONG)
  458. lwsl_info("Client doing pong callback\n");
  459. if (n && eff_buf.token_len) {
  460. /* extension had more... main loop will come back
  461. * we want callback to be done with this set, if so,
  462. * because lws_is_final() hides it was final until the
  463. * last chunk
  464. */
  465. wsi->u.ws.rx_draining_ext = 1;
  466. wsi->u.ws.rx_draining_ext_list = pt->rx_draining_ext_list;
  467. pt->rx_draining_ext_list = wsi;
  468. lwsl_ext("%s: RX EXT DRAINING: Adding to list\n", __func__);
  469. }
  470. if (wsi->state == LWSS_RETURNED_CLOSE_ALREADY ||
  471. wsi->state == LWSS_AWAITING_CLOSE_ACK)
  472. goto already_done;
  473. m = wsi->protocol->callback(wsi,
  474. (enum lws_callback_reasons)callback_action,
  475. wsi->user_space, eff_buf.token, eff_buf.token_len);
  476. /* if user code wants to close, let caller know */
  477. if (m)
  478. return 1;
  479. already_done:
  480. wsi->u.ws.rx_ubuf_head = 0;
  481. break;
  482. default:
  483. lwsl_err("client rx illegal state\n");
  484. return 1;
  485. }
  486. return 0;
  487. illegal_ctl_length:
  488. lwsl_warn("Control frame asking for extended length is illegal\n");
  489. /* kill the connection */
  490. return -1;
  491. }