ws_frame.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2012-2013 Crocodile RCS Ltd
  5. *
  6. * This file is part of Kamailio, a free SIP server.
  7. *
  8. * Kamailio is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * Kamailio is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. *
  22. */
  23. #include <limits.h>
  24. #include <unistr.h>
  25. #include "../../events.h"
  26. #include "../../receive.h"
  27. #include "../../stats.h"
  28. #include "../../str.h"
  29. #include "../../tcp_conn.h"
  30. #include "../../tcp_read.h"
  31. #include "../../tcp_server.h"
  32. #include "../../lib/kcore/kstats_wrapper.h"
  33. #include "../../lib/kmi/tree.h"
  34. #include "../../mem/mem.h"
  35. #include "ws_conn.h"
  36. #include "ws_frame.h"
  37. #include "ws_mod.h"
  38. #include "ws_handshake.h"
  39. #include "config.h"
  40. /* 0 1 2 3
  41. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  42. +-+-+-+-+-------+-+-------------+-------------------------------+
  43. |F|R|R|R| opcode|M| Payload len | Extended payload length |
  44. |I|S|S|S| (4) |A| (7) | (16/64) |
  45. |N|V|V|V| |S| | (if payload len==126/127) |
  46. | |1|2|3| |K| | |
  47. +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
  48. | Extended payload length continued, if payload len == 127 |
  49. + - - - - - - - - - - - - - - - +-------------------------------+
  50. | |Masking-key, if MASK set to 1 |
  51. +-------------------------------+-------------------------------+
  52. | Masking-key (continued) | Payload Data |
  53. +-------------------------------- - - - - - - - - - - - - - - - +
  54. : Payload Data continued ... :
  55. + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
  56. | Payload Data continued ... |
  57. +---------------------------------------------------------------+ */
  58. typedef struct {
  59. unsigned int fin;
  60. unsigned int rsv1;
  61. unsigned int rsv2;
  62. unsigned int rsv3;
  63. unsigned int opcode;
  64. unsigned int mask;
  65. unsigned int payload_len;
  66. unsigned char masking_key[4];
  67. char *payload_data;
  68. ws_connection_t *wsc;
  69. } ws_frame_t;
  70. typedef enum
  71. {
  72. CONN_CLOSE_DO = 0,
  73. CONN_CLOSE_DONT
  74. } conn_close_t;
  75. #define BYTE0_MASK_FIN (0x80)
  76. #define BYTE0_MASK_RSV1 (0x40)
  77. #define BYTE0_MASK_RSV2 (0x20)
  78. #define BYTE0_MASK_RSV3 (0x10)
  79. #define BYTE0_MASK_OPCODE (0x0F)
  80. #define BYTE1_MASK_MASK (0x80)
  81. #define BYTE1_MASK_PAYLOAD_LEN (0x7F)
  82. #define OPCODE_CONTINUATION (0x0)
  83. #define OPCODE_TEXT_FRAME (0x1)
  84. #define OPCODE_BINARY_FRAME (0x2)
  85. /* 0x3 - 0x7 are reserved for further non-control frames */
  86. #define OPCODE_CLOSE (0x8)
  87. #define OPCODE_PING (0x9)
  88. #define OPCODE_PONG (0xa)
  89. /* 0xb - 0xf are reserved for further control frames */
  90. int ws_keepalive_mechanism = DEFAULT_KEEPALIVE_MECHANISM;
  91. str ws_ping_application_data = {0, 0};
  92. stat_var *ws_failed_connections;
  93. stat_var *ws_local_closed_connections;
  94. stat_var *ws_received_frames;
  95. stat_var *ws_remote_closed_connections;
  96. stat_var *ws_transmitted_frames;
  97. stat_var *ws_sip_failed_connections;
  98. stat_var *ws_sip_local_closed_connections;
  99. stat_var *ws_sip_received_frames;
  100. stat_var *ws_sip_remote_closed_connections;
  101. stat_var *ws_sip_transmitted_frames;
  102. stat_var *ws_msrp_failed_connections;
  103. stat_var *ws_msrp_local_closed_connections;
  104. stat_var *ws_msrp_received_frames;
  105. stat_var *ws_msrp_remote_closed_connections;
  106. stat_var *ws_msrp_transmitted_frames;
  107. /* WebSocket status text */
  108. static str str_status_normal_closure = str_init("Normal closure");
  109. static str str_status_protocol_error = str_init("Protocol error");
  110. static str str_status_unsupported_opcode = str_init("Unsupported opcode");
  111. static str str_status_message_too_big = str_init("Message too big");
  112. /* MI command status text */
  113. static str str_status_empty_param = str_init("Empty connection ID parameter");
  114. static str str_status_too_many_params = str_init("Too many parameters");
  115. static str str_status_bad_param = str_init("Bad connection ID parameter");
  116. static str str_status_error_closing = str_init("Error closing connection");
  117. static str str_status_error_sending = str_init("Error sending frame");
  118. static str str_status_string_error = str_init("Error converting string to int");
  119. static int encode_and_send_ws_frame(ws_frame_t *frame, conn_close_t conn_close)
  120. {
  121. int pos = 0, extended_length;
  122. unsigned int frame_length;
  123. char *send_buf;
  124. struct tcp_connection *con;
  125. struct dest_info dst;
  126. union sockaddr_union *from = NULL;
  127. union sockaddr_union local_addr;
  128. LM_DBG("encoding WebSocket frame\n");
  129. if (frame->wsc->state != WS_S_OPEN)
  130. {
  131. LM_WARN("sending on closing connection\n");
  132. return -1;
  133. }
  134. wsconn_update(frame->wsc);
  135. /* Validate the first byte */
  136. if (!frame->fin)
  137. {
  138. LM_ERR("WebSocket fragmentation not supported in the sip "
  139. "sub-protocol\n");
  140. return -1;
  141. }
  142. if (frame->rsv1 || frame->rsv2 || frame->rsv3)
  143. {
  144. LM_ERR("WebSocket reserved fields with non-zero values\n");
  145. return -1;
  146. }
  147. switch(frame->opcode)
  148. {
  149. case OPCODE_TEXT_FRAME:
  150. case OPCODE_BINARY_FRAME:
  151. LM_DBG("supported non-control frame: 0x%x\n",
  152. (unsigned char) frame->opcode);
  153. break;
  154. case OPCODE_CLOSE:
  155. case OPCODE_PING:
  156. case OPCODE_PONG:
  157. LM_DBG("supported control frame: 0x%x\n",
  158. (unsigned char) frame->opcode);
  159. break;
  160. default:
  161. LM_ERR("unsupported opcode: 0x%x\n",
  162. (unsigned char) frame->opcode);
  163. return -1;
  164. }
  165. /* validate the second byte */
  166. if (frame->mask)
  167. {
  168. LM_ERR("this is a server - all messages sent will be "
  169. "unmasked\n");
  170. return -1;
  171. }
  172. if (frame->payload_len < 126) extended_length = 0;
  173. else if (frame->payload_len <= USHRT_MAX ) extended_length = 2;
  174. else if (frame->payload_len <= UINT_MAX) extended_length = 4;
  175. else
  176. {
  177. LM_ERR("Kamailio only supports WebSocket frames with payload "
  178. "<= %u\n", UINT_MAX);
  179. return -1;
  180. }
  181. /* Allocate send buffer and build frame */
  182. frame_length = frame->payload_len + extended_length + 2;
  183. if ((send_buf = pkg_malloc(sizeof(unsigned char) * frame_length))
  184. == NULL)
  185. {
  186. LM_ERR("allocating send buffer from pkg memory\n");
  187. return -1;
  188. }
  189. memset(send_buf, 0, sizeof(unsigned char) * frame_length);
  190. send_buf[pos++] = 0x80 | (frame->opcode & 0xff);
  191. if (extended_length == 0)
  192. send_buf[pos++] = (frame->payload_len & 0xff);
  193. else if (extended_length == 2)
  194. {
  195. send_buf[pos++] = 126;
  196. send_buf[pos++] = (frame->payload_len & 0xff00) >> 8;
  197. send_buf[pos++] = (frame->payload_len & 0x00ff) >> 0;
  198. }
  199. else
  200. {
  201. send_buf[pos++] = 127;
  202. send_buf[pos++] = (frame->payload_len & 0xff000000) >> 24;
  203. send_buf[pos++] = (frame->payload_len & 0x00ff0000) >> 16;
  204. send_buf[pos++] = (frame->payload_len & 0x0000ff00) >> 8;
  205. send_buf[pos++] = (frame->payload_len & 0x000000ff) >> 0;
  206. }
  207. memcpy(&send_buf[pos], frame->payload_data, frame->payload_len);
  208. if ((con = tcpconn_get(frame->wsc->id, 0, 0, 0, 0)) == NULL)
  209. {
  210. LM_WARN("TCP/TLS connection get failed\n");
  211. pkg_free(send_buf);
  212. if (wsconn_rm(frame->wsc, WSCONN_EVENTROUTE_YES) < 0)
  213. LM_ERR("removing WebSocket connection\n");
  214. return -1;
  215. }
  216. init_dst_from_rcv(&dst, &con->rcv);
  217. if (conn_close == CONN_CLOSE_DO)
  218. {
  219. dst.send_flags.f |= SND_F_CON_CLOSE;
  220. if (wsconn_rm(frame->wsc, WSCONN_EVENTROUTE_YES) < 0)
  221. {
  222. LM_ERR("removing WebSocket connection\n");
  223. tcpconn_put(con);
  224. pkg_free(send_buf);
  225. return -1;
  226. }
  227. }
  228. if (dst.proto == PROTO_WS)
  229. {
  230. if (unlikely(tcp_disable))
  231. {
  232. STATS_TX_DROPS;
  233. LM_WARN("TCP disabled\n");
  234. pkg_free(send_buf);
  235. tcpconn_put(con);
  236. return -1;
  237. }
  238. }
  239. #ifdef USE_TLS
  240. else if (dst.proto == PROTO_WSS)
  241. {
  242. if (unlikely(tls_disable))
  243. {
  244. STATS_TX_DROPS;
  245. LM_WARN("TLS disabled\n");
  246. pkg_free(send_buf);
  247. tcpconn_put(con);
  248. return -1;
  249. }
  250. }
  251. #endif /* USE_TLS */
  252. if (unlikely((dst.send_flags.f & SND_F_FORCE_SOCKET)
  253. && dst.send_sock))
  254. {
  255. local_addr = dst.send_sock->su;
  256. su_setport(&local_addr, 0);
  257. from = &local_addr;
  258. }
  259. /* Regardless of what has been set before _always_ use existing
  260. connections for WebSockets. This is required because a WebSocket
  261. server (which Kamailio is) CANNOT create connections. */
  262. dst.send_flags.f |= SND_F_FORCE_CON_REUSE;
  263. if (tcp_send(&dst, from, send_buf, frame_length) < 0)
  264. {
  265. STATS_TX_DROPS;
  266. LM_ERR("sending WebSocket frame\n");
  267. pkg_free(send_buf);
  268. update_stat(ws_failed_connections, 1);
  269. if (frame->wsc->sub_protocol == SUB_PROTOCOL_SIP)
  270. update_stat(ws_sip_failed_connections, 1);
  271. else if (frame->wsc->sub_protocol == SUB_PROTOCOL_MSRP)
  272. update_stat(ws_msrp_failed_connections, 1);
  273. if (wsconn_rm(frame->wsc, WSCONN_EVENTROUTE_YES) < 0)
  274. LM_ERR("removing WebSocket connection\n");
  275. tcpconn_put(con);
  276. return -1;
  277. }
  278. update_stat(ws_transmitted_frames, 1);
  279. switch (frame->opcode)
  280. {
  281. case OPCODE_TEXT_FRAME:
  282. case OPCODE_BINARY_FRAME:
  283. if (frame->wsc->sub_protocol == SUB_PROTOCOL_SIP)
  284. update_stat(ws_sip_transmitted_frames, 1);
  285. else if (frame->wsc->sub_protocol == SUB_PROTOCOL_MSRP)
  286. update_stat(ws_msrp_transmitted_frames, 1);
  287. }
  288. pkg_free(send_buf);
  289. tcpconn_put(con);
  290. return 0;
  291. }
  292. static int close_connection(ws_connection_t *wsc, ws_close_type_t type,
  293. short int status, str reason)
  294. {
  295. char *data;
  296. ws_frame_t frame;
  297. if (wsc->state == WS_S_OPEN)
  298. {
  299. data = pkg_malloc(sizeof(char) * (reason.len + 2));
  300. if (data == NULL)
  301. {
  302. LM_ERR("allocating pkg memory\n");
  303. return -1;
  304. }
  305. data[0] = (status & 0xff00) >> 8;
  306. data[1] = (status & 0x00ff) >> 0;
  307. memcpy(&data[2], reason.s, reason.len);
  308. memset(&frame, 0, sizeof(frame));
  309. frame.fin = 1;
  310. frame.opcode = OPCODE_CLOSE;
  311. frame.payload_len = reason.len + 2;
  312. frame.payload_data = data;
  313. frame.wsc = wsc;
  314. if (encode_and_send_ws_frame(&frame,
  315. type ==
  316. REMOTE_CLOSE ? CONN_CLOSE_DO : CONN_CLOSE_DONT) < 0)
  317. {
  318. LM_ERR("sending WebSocket close\n");
  319. pkg_free(data);
  320. return -1;
  321. }
  322. pkg_free(data);
  323. if (type == LOCAL_CLOSE)
  324. {
  325. frame.wsc->state = WS_S_CLOSING;
  326. update_stat(ws_local_closed_connections, 1);
  327. if (frame.wsc->sub_protocol == SUB_PROTOCOL_SIP)
  328. update_stat(ws_sip_local_closed_connections, 1);
  329. else if (frame.wsc->sub_protocol == SUB_PROTOCOL_MSRP)
  330. update_stat(ws_msrp_local_closed_connections,
  331. 1);
  332. }
  333. else
  334. {
  335. update_stat(ws_remote_closed_connections, 1);
  336. if (frame.wsc->sub_protocol == SUB_PROTOCOL_SIP)
  337. update_stat(ws_sip_remote_closed_connections,
  338. 1);
  339. else if (frame.wsc->sub_protocol == SUB_PROTOCOL_MSRP)
  340. update_stat(ws_msrp_remote_closed_connections,
  341. 1);
  342. }
  343. }
  344. else /* if (frame->wsc->state == WS_S_CLOSING) */
  345. wsconn_close_now(wsc);
  346. return 0;
  347. }
  348. static int decode_and_validate_ws_frame(ws_frame_t *frame,
  349. tcp_event_info_t *tcpinfo)
  350. {
  351. unsigned int i, len = tcpinfo->len;
  352. int mask_start, j;
  353. char *buf = tcpinfo->buf;
  354. LM_DBG("decoding WebSocket frame\n");
  355. if ((frame->wsc = wsconn_get(tcpinfo->con->id)) == NULL)
  356. {
  357. LM_ERR("WebSocket connection not found\n");
  358. return -1;
  359. }
  360. wsconn_update(frame->wsc);
  361. /* Decode and validate first 9 bits */
  362. if (len < 2)
  363. {
  364. LM_WARN("message is too short\n");
  365. if (close_connection(frame->wsc, LOCAL_CLOSE, 1002,
  366. str_status_protocol_error) < 0)
  367. LM_ERR("closing connection\n");
  368. return -1;
  369. }
  370. frame->fin = (buf[0] & 0xff) & BYTE0_MASK_FIN;
  371. frame->rsv1 = (buf[0] & 0xff) & BYTE0_MASK_RSV1;
  372. frame->rsv2 = (buf[0] & 0xff) & BYTE0_MASK_RSV2;
  373. frame->rsv3 = (buf[0] & 0xff) & BYTE0_MASK_RSV3;
  374. frame->opcode = (buf[0] & 0xff) & BYTE0_MASK_OPCODE;
  375. frame->mask = (buf[1] & 0xff) & BYTE1_MASK_MASK;
  376. if (!frame->fin)
  377. {
  378. LM_WARN("WebSocket fragmentation not supported in the sip "
  379. "sub-protocol\n");
  380. if (close_connection(frame->wsc, LOCAL_CLOSE, 1002,
  381. str_status_protocol_error) < 0)
  382. LM_ERR("closing connection\n");
  383. return -1;
  384. }
  385. if (frame->rsv1 || frame->rsv2 || frame->rsv3)
  386. {
  387. LM_WARN("WebSocket reserved fields with non-zero values\n");
  388. if (close_connection(frame->wsc, LOCAL_CLOSE, 1002,
  389. str_status_protocol_error) < 0)
  390. LM_ERR("closing connection\n");
  391. return -1;
  392. }
  393. switch(frame->opcode)
  394. {
  395. case OPCODE_TEXT_FRAME:
  396. case OPCODE_BINARY_FRAME:
  397. LM_DBG("supported non-control frame: 0x%x\n",
  398. (unsigned char) frame->opcode);
  399. break;
  400. case OPCODE_CLOSE:
  401. case OPCODE_PING:
  402. case OPCODE_PONG:
  403. LM_DBG("supported control frame: 0x%x\n",
  404. (unsigned char) frame->opcode);
  405. break;
  406. default:
  407. LM_WARN("unsupported opcode: 0x%x\n",
  408. (unsigned char) frame->opcode);
  409. if (close_connection(frame->wsc, LOCAL_CLOSE, 1008,
  410. str_status_unsupported_opcode) < 0)
  411. LM_ERR("closing connection\n");
  412. return -1;
  413. }
  414. if (!frame->mask)
  415. {
  416. LM_WARN("this is a server - all received messages must be "
  417. "masked\n");
  418. if (close_connection(frame->wsc, LOCAL_CLOSE, 1002,
  419. str_status_protocol_error) < 0)
  420. LM_ERR("closing connection\n");
  421. return -1;
  422. }
  423. /* Decode and validate length */
  424. frame->payload_len = (buf[1] & 0xff) & BYTE1_MASK_PAYLOAD_LEN;
  425. if (frame->payload_len == 126)
  426. {
  427. if (len < 4)
  428. {
  429. LM_WARN("message is too short\n");
  430. if (close_connection(frame->wsc, LOCAL_CLOSE, 1002,
  431. str_status_protocol_error) < 0)
  432. LM_ERR("closing connection\n");
  433. return -1;
  434. }
  435. mask_start = 4;
  436. frame->payload_len = ((buf[2] & 0xff) << 8)
  437. | ((buf[3] & 0xff) << 0);
  438. }
  439. else if (frame->payload_len == 127)
  440. {
  441. if (len < 10)
  442. {
  443. LM_WARN("message is too short\n");
  444. if (close_connection(frame->wsc, LOCAL_CLOSE, 1002,
  445. str_status_protocol_error) < 0)
  446. LM_ERR("closing connection\n");
  447. return -1;
  448. }
  449. mask_start = 10;
  450. if ((buf[2] & 0xff) != 0 || (buf[3] & 0xff) != 0
  451. || (buf[4] & 0xff) != 0 || (buf[5] & 0xff) != 0)
  452. {
  453. LM_WARN("message is too long\n");
  454. if (close_connection(frame->wsc, LOCAL_CLOSE, 1009,
  455. str_status_message_too_big) < 0)
  456. LM_ERR("closing connection\n");
  457. return -1;
  458. }
  459. /* Only decoding the last four bytes of the length...
  460. This limits the size of WebSocket messages that can be
  461. handled to 2^32 = which should be plenty for SIP! */
  462. frame->payload_len = ((buf[6] & 0xff) << 24)
  463. | ((buf[7] & 0xff) << 16)
  464. | ((buf[8] & 0xff) << 8)
  465. | ((buf[9] & 0xff) << 0);
  466. }
  467. else
  468. mask_start = 2;
  469. /* Decode mask */
  470. frame->masking_key[0] = (buf[mask_start + 0] & 0xff);
  471. frame->masking_key[1] = (buf[mask_start + 1] & 0xff);
  472. frame->masking_key[2] = (buf[mask_start + 2] & 0xff);
  473. frame->masking_key[3] = (buf[mask_start + 3] & 0xff);
  474. /* Decode and unmask payload */
  475. if (len != frame->payload_len + mask_start + 4)
  476. {
  477. LM_WARN("message not complete frame size %u but received %u\n",
  478. frame->payload_len + mask_start + 4, len);
  479. if (close_connection(frame->wsc, LOCAL_CLOSE, 1002,
  480. str_status_protocol_error) < 0)
  481. LM_ERR("closing connection\n");
  482. return -1;
  483. }
  484. frame->payload_data = &buf[mask_start + 4];
  485. for (i = 0; i < frame->payload_len; i++)
  486. {
  487. j = i % 4;
  488. frame->payload_data[i]
  489. = frame->payload_data[i] ^ frame->masking_key[j];
  490. }
  491. LM_DBG("Rx (decoded): %.*s\n",
  492. (int) frame->payload_len, frame->payload_data);
  493. return frame->opcode;
  494. }
  495. static int handle_close(ws_frame_t *frame)
  496. {
  497. unsigned short code = 0;
  498. str reason = {0, 0};
  499. if (frame->payload_len >= 2)
  500. code = ((frame->payload_data[0] & 0xff) << 8)
  501. | ((frame->payload_data[1] & 0xff) << 0);
  502. if (frame->payload_len > 2)
  503. {
  504. reason.s = &frame->payload_data[2];
  505. reason.len = frame->payload_len - 2;
  506. }
  507. LM_DBG("Rx Close: %hu %.*s\n", code, reason.len, reason.s);
  508. if (close_connection(frame->wsc,
  509. frame->wsc->state == WS_S_OPEN ? REMOTE_CLOSE : LOCAL_CLOSE,
  510. 1000, str_status_normal_closure) < 0)
  511. {
  512. LM_ERR("closing connection\n");
  513. return -1;
  514. }
  515. return 0;
  516. }
  517. static int handle_ping(ws_frame_t *frame)
  518. {
  519. LM_DBG("Rx Ping: %.*s\n", frame->payload_len, frame->payload_data);
  520. frame->opcode = OPCODE_PONG;
  521. frame->mask = 0;
  522. if (encode_and_send_ws_frame(frame, CONN_CLOSE_DONT) < 0)
  523. {
  524. LM_ERR("sending Pong\n");
  525. return -1;
  526. }
  527. return 0;
  528. }
  529. static int handle_pong(ws_frame_t *frame)
  530. {
  531. LM_DBG("Rx Pong: %.*s\n", frame->payload_len, frame->payload_data);
  532. if (strncmp(frame->payload_data, ws_ping_application_data.s,
  533. ws_ping_application_data.len) == 0)
  534. frame->wsc->awaiting_pong = 0;
  535. return 0;
  536. }
  537. int ws_frame_receive(void *data)
  538. {
  539. ws_frame_t frame;
  540. tcp_event_info_t *tcpinfo = (tcp_event_info_t *) data;
  541. update_stat(ws_received_frames, 1);
  542. if (tcpinfo == NULL || tcpinfo->buf == NULL || tcpinfo->len <= 0)
  543. {
  544. LM_WARN("received bad frame\n");
  545. return -1;
  546. }
  547. switch(decode_and_validate_ws_frame(&frame, tcpinfo))
  548. {
  549. case OPCODE_TEXT_FRAME:
  550. case OPCODE_BINARY_FRAME:
  551. if (likely(frame.wsc->sub_protocol == SUB_PROTOCOL_SIP))
  552. {
  553. LM_DBG("Rx SIP message:\n%.*s\n", frame.payload_len,
  554. frame.payload_data);
  555. update_stat(ws_sip_received_frames, 1);
  556. return receive_msg(frame.payload_data,
  557. frame.payload_len,
  558. tcpinfo->rcv);
  559. }
  560. else if (frame.wsc->sub_protocol == SUB_PROTOCOL_MSRP)
  561. {
  562. LM_DBG("Rx MSRP frame:\n%.*s\n", frame.payload_len,
  563. frame.payload_data);
  564. update_stat(ws_msrp_received_frames, 1);
  565. if (likely(sr_event_enabled(SREV_TCP_MSRP_FRAME)))
  566. {
  567. tcp_event_info_t tev;
  568. memset(&tev, 0, sizeof(tcp_event_info_t));
  569. tev.type = SREV_TCP_MSRP_FRAME;
  570. tev.buf = frame.payload_data;
  571. tev.len = frame.payload_len;
  572. tev.rcv = tcpinfo->rcv;
  573. tev.con = tcpinfo->con;
  574. return sr_event_exec(SREV_TCP_MSRP_FRAME,
  575. (void *) &tev);
  576. }
  577. else
  578. {
  579. LM_ERR("no callback registerd for MSRP\n");
  580. return -1;
  581. }
  582. }
  583. case OPCODE_CLOSE:
  584. return handle_close(&frame);
  585. case OPCODE_PING:
  586. return handle_ping(&frame);
  587. case OPCODE_PONG:
  588. return handle_pong(&frame);
  589. default:
  590. LM_WARN("received bad frame\n");
  591. return -1;
  592. }
  593. return 0;
  594. }
  595. int ws_frame_transmit(void *data)
  596. {
  597. ws_event_info_t *wsev = (ws_event_info_t *) data;
  598. ws_frame_t frame;
  599. memset(&frame, 0, sizeof(frame));
  600. frame.fin = 1;
  601. /* Can't be sure whether this message is UTF-8 or not so check to see
  602. if it "might" be UTF-8 and send as binary if it definitely isn't */
  603. frame.opcode = (u8_check((uint8_t *) wsev->buf, wsev->len) == NULL) ?
  604. OPCODE_TEXT_FRAME : OPCODE_BINARY_FRAME;
  605. frame.payload_len = wsev->len;
  606. frame.payload_data = wsev->buf;
  607. frame.wsc = wsconn_get(wsev->id);
  608. LM_DBG("Tx message:\n%.*s\n", frame.payload_len,
  609. frame.payload_data);
  610. if (encode_and_send_ws_frame(&frame, CONN_CLOSE_DONT) < 0)
  611. {
  612. LM_ERR("sending message\n");
  613. return -1;
  614. }
  615. return 0;
  616. }
  617. static int ping_pong(ws_connection_t *wsc, int opcode)
  618. {
  619. ws_frame_t frame;
  620. memset(&frame, 0, sizeof(frame));
  621. frame.fin = 1;
  622. frame.opcode = opcode;
  623. frame.payload_len = ws_ping_application_data.len;
  624. frame.payload_data = ws_ping_application_data.s;
  625. frame.wsc = wsc;
  626. if (encode_and_send_ws_frame(&frame, CONN_CLOSE_DONT) < 0)
  627. {
  628. LM_ERR("sending keepalive\n");
  629. return -1;
  630. }
  631. if (opcode == OPCODE_PING)
  632. wsc->awaiting_pong = 1;
  633. return 0;
  634. }
  635. struct mi_root *ws_mi_close(struct mi_root *cmd, void *param)
  636. {
  637. unsigned int id;
  638. struct mi_node *node = NULL;
  639. ws_connection_t *wsc;
  640. node = cmd->node.kids;
  641. if (node == NULL)
  642. {
  643. LM_WARN("no connection ID parameter\n");
  644. return init_mi_tree(400, str_status_empty_param.s,
  645. str_status_empty_param.len);
  646. }
  647. if (node->value.s == NULL || node->value.len == 0)
  648. {
  649. LM_WARN("empty connection ID parameter\n");
  650. return init_mi_tree(400, str_status_empty_param.s,
  651. str_status_empty_param.len);
  652. }
  653. if (str2int(&node->value, &id) < 0)
  654. {
  655. LM_ERR("converting string to int\n");
  656. return init_mi_tree(400, str_status_string_error.s,
  657. str_status_string_error.len);
  658. }
  659. if (node->next != NULL)
  660. {
  661. LM_WARN("too many parameters\n");
  662. return init_mi_tree(400, str_status_too_many_params.s,
  663. str_status_too_many_params.len);
  664. }
  665. if ((wsc = wsconn_get(id)) == NULL)
  666. {
  667. LM_WARN("bad connection ID parameter\n");
  668. return init_mi_tree(400, str_status_bad_param.s,
  669. str_status_bad_param.len);
  670. }
  671. if (close_connection(wsc, LOCAL_CLOSE, 1000,
  672. str_status_normal_closure) < 0)
  673. {
  674. LM_WARN("closing connection\n");
  675. return init_mi_tree(500, str_status_error_closing.s,
  676. str_status_error_closing.len);
  677. }
  678. return init_mi_tree(200, MI_OK_S, MI_OK_LEN);
  679. }
  680. static struct mi_root *mi_ping_pong(struct mi_root *cmd, void *param,
  681. int opcode)
  682. {
  683. unsigned int id;
  684. struct mi_node *node = NULL;
  685. ws_connection_t *wsc;
  686. node = cmd->node.kids;
  687. if (node == NULL)
  688. {
  689. LM_WARN("no connection ID parameter\n");
  690. return init_mi_tree(400, str_status_empty_param.s,
  691. str_status_empty_param.len);
  692. }
  693. if (node->value.s == NULL || node->value.len == 0)
  694. {
  695. LM_WARN("empty connection ID parameter\n");
  696. return init_mi_tree(400, str_status_empty_param.s,
  697. str_status_empty_param.len);
  698. }
  699. if (str2int(&node->value, &id) < 0)
  700. {
  701. LM_ERR("converting string to int\n");
  702. return init_mi_tree(400, str_status_string_error.s,
  703. str_status_string_error.len);
  704. }
  705. if (node->next != NULL)
  706. {
  707. LM_WARN("too many parameters\n");
  708. return init_mi_tree(400, str_status_too_many_params.s,
  709. str_status_too_many_params.len);
  710. }
  711. if ((wsc = wsconn_get(id)) == NULL)
  712. {
  713. LM_WARN("bad connection ID parameter\n");
  714. return init_mi_tree(400, str_status_bad_param.s,
  715. str_status_bad_param.len);
  716. }
  717. if (ping_pong(wsc, opcode) < 0)
  718. {
  719. LM_WARN("sending %s\n", OPCODE_PING ? "Ping" : "Pong");
  720. return init_mi_tree(500, str_status_error_sending.s,
  721. str_status_error_sending.len);
  722. }
  723. return init_mi_tree(200, MI_OK_S, MI_OK_LEN);
  724. }
  725. struct mi_root *ws_mi_ping(struct mi_root *cmd, void *param)
  726. {
  727. return mi_ping_pong(cmd, param, OPCODE_PING);
  728. }
  729. struct mi_root *ws_mi_pong(struct mi_root *cmd, void *param)
  730. {
  731. return mi_ping_pong(cmd, param, OPCODE_PONG);
  732. }
  733. void ws_keepalive(unsigned int ticks, void *param)
  734. {
  735. int check_time = (int) time(NULL)
  736. - cfg_get(websocket, ws_cfg, keepalive_timeout);
  737. ws_connection_t *wsc = wsconn_used_list->head;
  738. while (wsc && wsc->last_used < check_time)
  739. {
  740. if (wsc->state == WS_S_CLOSING
  741. || wsc->awaiting_pong)
  742. {
  743. LM_WARN("forcibly closing connection\n");
  744. wsconn_close_now(wsc);
  745. }
  746. else
  747. ping_pong(wsconn_used_list->head,
  748. ws_keepalive_mechanism == KEEPALIVE_MECHANISM_PING
  749. ? OPCODE_PING : OPCODE_PONG);
  750. wsc = wsconn_used_list->head;
  751. }
  752. }
  753. int ws_close(sip_msg_t *msg)
  754. {
  755. ws_connection_t *wsc;
  756. if ((wsc = wsconn_get(msg->rcv.proto_reserved1)) == NULL) {
  757. LM_ERR("failed to retrieve WebSocket connection\n");
  758. return -1;
  759. }
  760. return (close_connection(wsc, LOCAL_CLOSE, 1000,
  761. str_status_normal_closure) == 0) ? 1: 0;
  762. }
  763. int ws_close2(sip_msg_t *msg, char *_status, char *_reason)
  764. {
  765. int status;
  766. str reason;
  767. ws_connection_t *wsc;
  768. if (get_int_fparam(&status, msg, (fparam_t *) _status) < 0) {
  769. LM_ERR("failed to get status code\n");
  770. return -1;
  771. }
  772. if (get_str_fparam(&reason, msg, (fparam_t *) _reason) < 0) {
  773. LM_ERR("failed to get reason string\n");
  774. return -1;
  775. }
  776. if ((wsc = wsconn_get(msg->rcv.proto_reserved1)) == NULL) {
  777. LM_ERR("failed to retrieve WebSocket connection\n");
  778. return -1;
  779. }
  780. return (close_connection(wsc, LOCAL_CLOSE, status, reason) == 0) ? 1: 0;
  781. }
  782. int ws_close3(sip_msg_t *msg, char *_status, char *_reason, char *_con)
  783. {
  784. int status;
  785. str reason;
  786. int con;
  787. ws_connection_t *wsc;
  788. if (get_int_fparam(&status, msg, (fparam_t *) _status) < 0) {
  789. LM_ERR("failed to get status code\n");
  790. return -1;
  791. }
  792. if (get_str_fparam(&reason, msg, (fparam_t *) _reason) < 0) {
  793. LM_ERR("failed to get reason string\n");
  794. return -1;
  795. }
  796. if (get_int_fparam(&con, msg, (fparam_t *) _con) < 0) {
  797. LM_ERR("failed to get connection ID\n");
  798. return -1;
  799. }
  800. if ((wsc = wsconn_get(con)) == NULL) {
  801. LM_ERR("failed to retrieve WebSocket connection\n");
  802. return -1;
  803. }
  804. return (close_connection(wsc, LOCAL_CLOSE, status, reason) == 0) ? 1: 0;
  805. }