/lib/libwebsockets.c

https://gitlab.com/libwebsockets/libwebsockets · C · 939 lines · 577 code · 151 blank · 211 comment · 110 complexity · 341d532f65ef972549b6da2b8ff353aa MD5 · raw file

  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 log_level = LLL_ERR | LLL_WARN | LLL_NOTICE;
  23. static void (*lwsl_emit)(int level, const char *line) = lwsl_emit_stderr;
  24. static const char * const log_level_names[] = {
  25. "ERR",
  26. "WARN",
  27. "NOTICE",
  28. "INFO",
  29. "DEBUG",
  30. "PARSER",
  31. "HEADER",
  32. "EXTENSION",
  33. "CLIENT",
  34. "LATENCY",
  35. };
  36. void
  37. lws_free_wsi(struct lws *wsi)
  38. {
  39. if (!wsi)
  40. return;
  41. /* Protocol user data may be allocated either internally by lws
  42. * or by specified the user.
  43. * We should only free what we allocated. */
  44. if (wsi->protocol && wsi->protocol->per_session_data_size &&
  45. wsi->user_space && !wsi->user_space_externally_allocated)
  46. lws_free(wsi->user_space);
  47. lws_free_set_NULL(wsi->rxflow_buffer);
  48. lws_free_set_NULL(wsi->trunc_alloc);
  49. lws_free_header_table(wsi);
  50. lws_free(wsi);
  51. }
  52. void
  53. lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason)
  54. {
  55. struct lws_context *context = wsi->context;
  56. int n, m, ret, old_state;
  57. struct lws_tokens eff_buf;
  58. unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 +
  59. LWS_SEND_BUFFER_POST_PADDING];
  60. if (!wsi)
  61. return;
  62. old_state = wsi->state;
  63. if (wsi->mode == LWSCM_HTTP_SERVING_ACCEPTED &&
  64. wsi->u.http.fd != LWS_INVALID_FILE) {
  65. lwsl_debug("closing http file\n");
  66. lws_plat_file_close(wsi, wsi->u.http.fd);
  67. wsi->u.http.fd = LWS_INVALID_FILE;
  68. context->protocols[0].callback(wsi, LWS_CALLBACK_CLOSED_HTTP,
  69. wsi->user_space, NULL, 0);
  70. }
  71. if (wsi->socket_is_permanently_unusable ||
  72. reason == LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY)
  73. goto just_kill_connection;
  74. switch (old_state) {
  75. case LWSS_DEAD_SOCKET:
  76. return;
  77. /* we tried the polite way... */
  78. case LWSS_AWAITING_CLOSE_ACK:
  79. goto just_kill_connection;
  80. case LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE:
  81. if (wsi->trunc_len) {
  82. lws_callback_on_writable(wsi);
  83. return;
  84. }
  85. lwsl_info("wsi %p completed LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi);
  86. goto just_kill_connection;
  87. default:
  88. if (wsi->trunc_len) {
  89. lwsl_info("wsi %p entering LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi);
  90. wsi->state = LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE;
  91. lws_set_timeout(wsi, PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE, 5);
  92. return;
  93. }
  94. break;
  95. }
  96. wsi->u.ws.close_reason = reason;
  97. if (wsi->mode == LWSCM_WSCL_WAITING_CONNECT ||
  98. wsi->mode == LWSCM_WSCL_ISSUE_HANDSHAKE)
  99. goto just_kill_connection;
  100. if (wsi->mode == LWSCM_HTTP_SERVING)
  101. context->protocols[0].callback(wsi, LWS_CALLBACK_CLOSED_HTTP,
  102. wsi->user_space, NULL, 0);
  103. /*
  104. * are his extensions okay with him closing? Eg he might be a mux
  105. * parent and just his ch1 aspect is closing?
  106. */
  107. if (lws_ext_cb_wsi_active_exts(wsi,
  108. LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE, NULL, 0) > 0) {
  109. lwsl_ext("extension vetoed close\n");
  110. return;
  111. }
  112. /*
  113. * flush any tx pending from extensions, since we may send close packet
  114. * if there are problems with send, just nuke the connection
  115. */
  116. do {
  117. ret = 0;
  118. eff_buf.token = NULL;
  119. eff_buf.token_len = 0;
  120. /* show every extension the new incoming data */
  121. m = lws_ext_cb_wsi_active_exts(wsi,
  122. LWS_EXT_CALLBACK_FLUSH_PENDING_TX, &eff_buf, 0);
  123. if (m < 0) {
  124. lwsl_ext("Extension reports fatal error\n");
  125. goto just_kill_connection;
  126. }
  127. if (m)
  128. /*
  129. * at least one extension told us he has more
  130. * to spill, so we will go around again after
  131. */
  132. ret = 1;
  133. /* assuming they left us something to send, send it */
  134. if (eff_buf.token_len)
  135. if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
  136. eff_buf.token_len) !=
  137. eff_buf.token_len) {
  138. lwsl_debug("close: ext spill failed\n");
  139. goto just_kill_connection;
  140. }
  141. } while (ret);
  142. /*
  143. * signal we are closing, lws_write will
  144. * add any necessary version-specific stuff. If the write fails,
  145. * no worries we are closing anyway. If we didn't initiate this
  146. * close, then our state has been changed to
  147. * LWSS_RETURNED_CLOSE_ALREADY and we will skip this.
  148. *
  149. * Likewise if it's a second call to close this connection after we
  150. * sent the close indication to the peer already, we are in state
  151. * LWSS_AWAITING_CLOSE_ACK and will skip doing this a second time.
  152. */
  153. if (old_state == LWSS_ESTABLISHED &&
  154. reason != LWS_CLOSE_STATUS_NOSTATUS &&
  155. reason != LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY) {
  156. lwsl_debug("sending close indication...\n");
  157. /* make valgrind happy */
  158. memset(buf, 0, sizeof(buf));
  159. n = lws_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING + 2],
  160. 0, LWS_WRITE_CLOSE);
  161. if (n >= 0) {
  162. /*
  163. * we have sent a nice protocol level indication we
  164. * now wish to close, we should not send anything more
  165. */
  166. wsi->state = LWSS_AWAITING_CLOSE_ACK;
  167. /*
  168. * ...and we should wait for a reply for a bit
  169. * out of politeness
  170. */
  171. lws_set_timeout(wsi, PENDING_TIMEOUT_CLOSE_ACK, 1);
  172. lwsl_debug("sent close indication, awaiting ack\n");
  173. return;
  174. }
  175. lwsl_info("close: sending close packet failed, hanging up\n");
  176. /* else, the send failed and we should just hang up */
  177. }
  178. just_kill_connection:
  179. lwsl_debug("close: just_kill_connection\n");
  180. /*
  181. * we won't be servicing or receiving anything further from this guy
  182. * delete socket from the internal poll list if still present
  183. */
  184. lws_ssl_remove_wsi_from_buffered_list(wsi);
  185. /* checking return redundant since we anyway close */
  186. remove_wsi_socket_from_fds(wsi);
  187. wsi->state = LWSS_DEAD_SOCKET;
  188. lws_free_set_NULL(wsi->rxflow_buffer);
  189. lws_free_header_table(wsi);
  190. if (old_state == LWSS_ESTABLISHED ||
  191. wsi->mode == LWSCM_WS_SERVING ||
  192. wsi->mode == LWSCM_WS_CLIENT) {
  193. lws_free_set_NULL(wsi->u.ws.rx_user_buffer);
  194. if (wsi->trunc_alloc)
  195. /* not going to be completed... nuke it */
  196. lws_free_set_NULL(wsi->trunc_alloc);
  197. if (wsi->u.ws.ping_payload_buf) {
  198. lws_free_set_NULL(wsi->u.ws.ping_payload_buf);
  199. wsi->u.ws.ping_payload_alloc = 0;
  200. wsi->u.ws.ping_payload_len = 0;
  201. wsi->u.ws.ping_pending_flag = 0;
  202. }
  203. }
  204. /* tell the user it's all over for this guy */
  205. if (wsi->protocol && wsi->protocol->callback &&
  206. ((old_state == LWSS_ESTABLISHED) ||
  207. (old_state == LWSS_RETURNED_CLOSE_ALREADY) ||
  208. (old_state == LWSS_AWAITING_CLOSE_ACK) ||
  209. (old_state == LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE))) {
  210. lwsl_debug("calling back CLOSED\n");
  211. wsi->protocol->callback(wsi, LWS_CALLBACK_CLOSED,
  212. wsi->user_space, NULL, 0);
  213. } else if (wsi->mode == LWSCM_HTTP_SERVING_ACCEPTED) {
  214. lwsl_debug("calling back CLOSED_HTTP\n");
  215. context->protocols[0].callback(wsi, LWS_CALLBACK_CLOSED_HTTP,
  216. wsi->user_space, NULL, 0 );
  217. } else if (wsi->mode == LWSCM_WSCL_WAITING_SERVER_REPLY ||
  218. wsi->mode == LWSCM_WSCL_WAITING_CONNECT) {
  219. lwsl_debug("Connection closed before server reply\n");
  220. context->protocols[0].callback(wsi,
  221. LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
  222. wsi->user_space, NULL, 0);
  223. } else
  224. lwsl_debug("not calling back closed mode=%d state=%d\n",
  225. wsi->mode, old_state);
  226. /* deallocate any active extension contexts */
  227. if (lws_ext_cb_wsi_active_exts(wsi, LWS_EXT_CALLBACK_DESTROY, NULL, 0) < 0)
  228. lwsl_warn("extension destruction failed\n");
  229. #ifndef LWS_NO_EXTENSIONS
  230. for (n = 0; n < wsi->count_active_extensions; n++)
  231. lws_free(wsi->active_extensions_user[n]);
  232. #endif
  233. /*
  234. * inform all extensions in case they tracked this guy out of band
  235. * even though not active on him specifically
  236. */
  237. if (lws_ext_cb_all_exts(context, wsi,
  238. LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING, NULL, 0) < 0)
  239. lwsl_warn("ext destroy wsi failed\n");
  240. if (!lws_ssl_close(wsi) && lws_socket_is_valid(wsi->sock)) {
  241. #if LWS_POSIX
  242. n = shutdown(wsi->sock, SHUT_RDWR);
  243. if (n)
  244. lwsl_debug("closing: shutdown ret %d\n", LWS_ERRNO);
  245. n = compatible_close(wsi->sock);
  246. if (n)
  247. lwsl_debug("closing: close ret %d\n", LWS_ERRNO);
  248. #else
  249. compatible_close(wsi->sock);
  250. #endif
  251. wsi->sock = LWS_SOCK_INVALID;
  252. }
  253. /* outermost destroy notification for wsi (user_space still intact) */
  254. context->protocols[0].callback(wsi, LWS_CALLBACK_WSI_DESTROY,
  255. wsi->user_space, NULL, 0);
  256. lws_free_wsi(wsi);
  257. }
  258. LWS_VISIBLE int
  259. lws_get_addresses(struct lws_context *context, void *ads, char *name,
  260. int name_len, char *rip, int rip_len)
  261. {
  262. #if LWS_POSIX
  263. struct addrinfo ai, *res;
  264. struct sockaddr_in addr4;
  265. if (rip)
  266. rip[0] = '\0';
  267. name[0] = '\0';
  268. addr4.sin_family = AF_UNSPEC;
  269. #ifdef LWS_USE_IPV6
  270. if (LWS_IPV6_ENABLED(context)) {
  271. if (!lws_plat_inet_ntop(AF_INET6, &((struct sockaddr_in6 *)ads)->sin6_addr, rip, rip_len)) {
  272. lwsl_err("inet_ntop", strerror(LWS_ERRNO));
  273. return -1;
  274. }
  275. // Strip off the IPv4 to IPv6 header if one exists
  276. if (strncmp(rip, "::ffff:", 7) == 0)
  277. memmove(rip, rip + 7, strlen(rip) - 6);
  278. getnameinfo((struct sockaddr *)ads,
  279. sizeof(struct sockaddr_in6), name,
  280. name_len, NULL, 0, 0);
  281. return 0;
  282. } else
  283. #endif
  284. {
  285. struct addrinfo *result;
  286. memset(&ai, 0, sizeof ai);
  287. ai.ai_family = PF_UNSPEC;
  288. ai.ai_socktype = SOCK_STREAM;
  289. ai.ai_flags = AI_CANONNAME;
  290. if (getnameinfo((struct sockaddr *)ads,
  291. sizeof(struct sockaddr_in),
  292. name, name_len, NULL, 0, 0))
  293. return -1;
  294. if (!rip)
  295. return 0;
  296. if (getaddrinfo(name, NULL, &ai, &result))
  297. return -1;
  298. res = result;
  299. while (addr4.sin_family == AF_UNSPEC && res) {
  300. switch (res->ai_family) {
  301. case AF_INET:
  302. addr4.sin_addr = ((struct sockaddr_in *)res->ai_addr)->sin_addr;
  303. addr4.sin_family = AF_INET;
  304. break;
  305. }
  306. res = res->ai_next;
  307. }
  308. freeaddrinfo(result);
  309. }
  310. if (addr4.sin_family == AF_UNSPEC)
  311. return -1;
  312. lws_plat_inet_ntop(AF_INET, &addr4.sin_addr, rip, rip_len);
  313. return 0;
  314. #else
  315. (void)context;
  316. (void)ads;
  317. (void)name;
  318. (void)name_len;
  319. (void)rip;
  320. (void)rip_len;
  321. return -1;
  322. #endif
  323. }
  324. /**
  325. * lws_get_peer_addresses() - Get client address information
  326. * @wsi: Local struct lws associated with
  327. * @fd: Connection socket descriptor
  328. * @name: Buffer to take client address name
  329. * @name_len: Length of client address name buffer
  330. * @rip: Buffer to take client address IP dotted quad
  331. * @rip_len: Length of client address IP buffer
  332. *
  333. * This function fills in @name and @rip with the name and IP of
  334. * the client connected with socket descriptor @fd. Names may be
  335. * truncated if there is not enough room. If either cannot be
  336. * determined, they will be returned as valid zero-length strings.
  337. */
  338. LWS_VISIBLE void
  339. lws_get_peer_addresses(struct lws *wsi, lws_sockfd_type fd, char *name,
  340. int name_len, char *rip, int rip_len)
  341. {
  342. #if LWS_POSIX
  343. socklen_t len;
  344. #ifdef LWS_USE_IPV6
  345. struct sockaddr_in6 sin6;
  346. #endif
  347. struct sockaddr_in sin4;
  348. struct lws_context *context = wsi->context;
  349. int ret = -1;
  350. void *p;
  351. rip[0] = '\0';
  352. name[0] = '\0';
  353. lws_latency_pre(context, wsi);
  354. #ifdef LWS_USE_IPV6
  355. if (LWS_IPV6_ENABLED(context)) {
  356. len = sizeof(sin6);
  357. p = &sin6;
  358. } else
  359. #endif
  360. {
  361. len = sizeof(sin4);
  362. p = &sin4;
  363. }
  364. if (getpeername(fd, p, &len) < 0) {
  365. lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO));
  366. goto bail;
  367. }
  368. ret = lws_get_addresses(context, p, name, name_len, rip, rip_len);
  369. bail:
  370. lws_latency(context, wsi, "lws_get_peer_addresses", ret, 1);
  371. #else
  372. (void)wsi;
  373. (void)fd;
  374. (void)name;
  375. (void)name_len;
  376. (void)rip;
  377. (void)rip_len;
  378. #endif
  379. }
  380. /**
  381. * lws_context_user() - get the user data associated with the context
  382. * @context: Websocket context
  383. *
  384. * This returns the optional user allocation that can be attached to
  385. * the context the sockets live in at context_create time. It's a way
  386. * to let all sockets serviced in the same context share data without
  387. * using globals statics in the user code.
  388. */
  389. LWS_EXTERN void *
  390. lws_context_user(struct lws_context *context)
  391. {
  392. return context->user_space;
  393. }
  394. /**
  395. * lws_callback_all_protocol() - Callback all connections using
  396. * the given protocol with the given reason
  397. *
  398. * @protocol: Protocol whose connections will get callbacks
  399. * @reason: Callback reason index
  400. */
  401. LWS_VISIBLE int
  402. lws_callback_all_protocol(struct lws_context *context,
  403. const struct lws_protocols *protocol, int reason)
  404. {
  405. struct lws *wsi;
  406. int n;
  407. for (n = 0; n < context->fds_count; n++) {
  408. wsi = wsi_from_fd(context, context->fds[n].fd);
  409. if (!wsi)
  410. continue;
  411. if (wsi->protocol == protocol)
  412. protocol->callback(wsi, reason, wsi->user_space, NULL, 0);
  413. }
  414. return 0;
  415. }
  416. /**
  417. * lws_set_timeout() - marks the wsi as subject to a timeout
  418. *
  419. * You will not need this unless you are doing something special
  420. *
  421. * @wsi: Websocket connection instance
  422. * @reason: timeout reason
  423. * @secs: how many seconds
  424. */
  425. LWS_VISIBLE void
  426. lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs)
  427. {
  428. time_t now;
  429. time(&now);
  430. wsi->pending_timeout_limit = now + secs;
  431. wsi->pending_timeout = reason;
  432. }
  433. #if LWS_POSIX
  434. /**
  435. * lws_get_socket_fd() - returns the socket file descriptor
  436. *
  437. * You will not need this unless you are doing something special
  438. *
  439. * @wsi: Websocket connection instance
  440. */
  441. LWS_VISIBLE int
  442. lws_get_socket_fd(struct lws *wsi)
  443. {
  444. return wsi->sock;
  445. }
  446. #endif
  447. #ifdef LWS_LATENCY
  448. void
  449. lws_latency(struct lws_context *context, struct lws *wsi, const char *action,
  450. int ret, int completed)
  451. {
  452. unsigned long long u;
  453. char buf[256];
  454. u = time_in_microseconds();
  455. if (!action) {
  456. wsi->latency_start = u;
  457. if (!wsi->action_start)
  458. wsi->action_start = u;
  459. return;
  460. }
  461. if (completed) {
  462. if (wsi->action_start == wsi->latency_start)
  463. sprintf(buf,
  464. "Completion first try lat %lluus: %p: ret %d: %s\n",
  465. u - wsi->latency_start,
  466. (void *)wsi, ret, action);
  467. else
  468. sprintf(buf,
  469. "Completion %lluus: lat %lluus: %p: ret %d: %s\n",
  470. u - wsi->action_start,
  471. u - wsi->latency_start,
  472. (void *)wsi, ret, action);
  473. wsi->action_start = 0;
  474. } else
  475. sprintf(buf, "lat %lluus: %p: ret %d: %s\n",
  476. u - wsi->latency_start, (void *)wsi, ret, action);
  477. if (u - wsi->latency_start > context->worst_latency) {
  478. context->worst_latency = u - wsi->latency_start;
  479. strcpy(context->worst_latency_info, buf);
  480. }
  481. lwsl_latency("%s", buf);
  482. }
  483. #endif
  484. /**
  485. * lws_rx_flow_control() - Enable and disable socket servicing for
  486. * received packets.
  487. *
  488. * If the output side of a server process becomes choked, this allows flow
  489. * control for the input side.
  490. *
  491. * @wsi: Websocket connection instance to get callback for
  492. * @enable: 0 = disable read servicing for this connection, 1 = enable
  493. */
  494. LWS_VISIBLE int
  495. lws_rx_flow_control(struct lws *wsi, int enable)
  496. {
  497. if (enable == (wsi->rxflow_change_to & LWS_RXFLOW_ALLOW))
  498. return 0;
  499. lwsl_info("%s: (0x%p, %d)\n", __func__, wsi, enable);
  500. wsi->rxflow_change_to = LWS_RXFLOW_PENDING_CHANGE | !!enable;
  501. return 0;
  502. }
  503. /**
  504. * lws_rx_flow_allow_all_protocol() - Allow all connections with this protocol to receive
  505. *
  506. * When the user server code realizes it can accept more input, it can
  507. * call this to have the RX flow restriction removed from all connections using
  508. * the given protocol.
  509. *
  510. * @protocol: all connections using this protocol will be allowed to receive
  511. */
  512. LWS_VISIBLE void
  513. lws_rx_flow_allow_all_protocol(const struct lws_context *context,
  514. const struct lws_protocols *protocol)
  515. {
  516. int n;
  517. struct lws *wsi;
  518. for (n = 0; n < context->fds_count; n++) {
  519. wsi = wsi_from_fd(context, context->fds[n].fd);
  520. if (!wsi)
  521. continue;
  522. if (wsi->protocol == protocol)
  523. lws_rx_flow_control(wsi, LWS_RXFLOW_ALLOW);
  524. }
  525. }
  526. /**
  527. * lws_canonical_hostname() - returns this host's hostname
  528. *
  529. * This is typically used by client code to fill in the host parameter
  530. * when making a client connection. You can only call it after the context
  531. * has been created.
  532. *
  533. * @context: Websocket context
  534. */
  535. LWS_VISIBLE extern const char *
  536. lws_canonical_hostname(struct lws_context *context)
  537. {
  538. return (const char *)context->canonical_hostname;
  539. }
  540. int user_callback_handle_rxflow(callback_function callback_function,
  541. struct lws *wsi,
  542. enum lws_callback_reasons reason, void *user,
  543. void *in, size_t len)
  544. {
  545. int n;
  546. n = callback_function(wsi, reason, user, in, len);
  547. if (!n)
  548. n = _lws_rx_flow_control(wsi);
  549. return n;
  550. }
  551. /**
  552. * lws_set_proxy() - Setups proxy to lws_context.
  553. * @context: pointer to struct lws_context you want set proxy to
  554. * @proxy: pointer to c string containing proxy in format address:port
  555. *
  556. * Returns 0 if proxy string was parsed and proxy was setup.
  557. * Returns -1 if @proxy is NULL or has incorrect format.
  558. *
  559. * This is only required if your OS does not provide the http_proxy
  560. * environment variable (eg, OSX)
  561. *
  562. * IMPORTANT! You should call this function right after creation of the
  563. * lws_context and before call to connect. If you call this
  564. * function after connect behavior is undefined.
  565. * This function will override proxy settings made on lws_context
  566. * creation with genenv() call.
  567. */
  568. LWS_VISIBLE int
  569. lws_set_proxy(struct lws_context *context, const char *proxy)
  570. {
  571. char *p;
  572. char authstring[96];
  573. if (!proxy)
  574. return -1;
  575. p = strchr(proxy, '@');
  576. if (p) { /* auth is around */
  577. if ((unsigned int)(p - proxy) > sizeof(authstring) - 1)
  578. goto auth_too_long;
  579. strncpy(authstring, proxy, p - proxy);
  580. // null termination not needed on input
  581. if (lws_b64_encode_string(authstring, (p - proxy),
  582. context->proxy_basic_auth_token,
  583. sizeof context->proxy_basic_auth_token) < 0)
  584. goto auth_too_long;
  585. lwsl_notice(" Proxy auth in use\n");
  586. proxy = p + 1;
  587. } else
  588. context->proxy_basic_auth_token[0] = '\0';
  589. strncpy(context->http_proxy_address, proxy,
  590. sizeof(context->http_proxy_address) - 1);
  591. context->http_proxy_address[
  592. sizeof(context->http_proxy_address) - 1] = '\0';
  593. p = strchr(context->http_proxy_address, ':');
  594. if (!p && !context->http_proxy_port) {
  595. lwsl_err("http_proxy needs to be ads:port\n");
  596. return -1;
  597. } else {
  598. if (p) {
  599. *p = '\0';
  600. context->http_proxy_port = atoi(p + 1);
  601. }
  602. }
  603. lwsl_notice(" Proxy %s:%u\n", context->http_proxy_address,
  604. context->http_proxy_port);
  605. return 0;
  606. auth_too_long:
  607. lwsl_err("proxy auth too long\n");
  608. return -1;
  609. }
  610. /**
  611. * lws_get_protocol() - Returns a protocol pointer from a websocket
  612. * connection.
  613. * @wsi: pointer to struct websocket you want to know the protocol of
  614. *
  615. *
  616. * Some apis can act on all live connections of a given protocol,
  617. * this is how you can get a pointer to the active protocol if needed.
  618. */
  619. LWS_VISIBLE const struct lws_protocols *
  620. lws_get_protocol(struct lws *wsi)
  621. {
  622. return wsi->protocol;
  623. }
  624. LWS_VISIBLE int
  625. lws_is_final_fragment(struct lws *wsi)
  626. {
  627. return wsi->u.ws.final;
  628. }
  629. LWS_VISIBLE unsigned char
  630. lws_get_reserved_bits(struct lws *wsi)
  631. {
  632. return wsi->u.ws.rsv;
  633. }
  634. int
  635. lws_ensure_user_space(struct lws *wsi)
  636. {
  637. lwsl_info("%s: %p protocol %p\n", __func__, wsi, wsi->protocol);
  638. if (!wsi->protocol)
  639. return 1;
  640. /* allocate the per-connection user memory (if any) */
  641. if (wsi->protocol->per_session_data_size && !wsi->user_space) {
  642. wsi->user_space = lws_zalloc(wsi->protocol->per_session_data_size);
  643. if (wsi->user_space == NULL) {
  644. lwsl_err("Out of memory for conn user space\n");
  645. return 1;
  646. }
  647. } else
  648. lwsl_info("%s: %p protocol pss %u, user_space=%d\n",
  649. __func__, wsi, wsi->protocol->per_session_data_size,
  650. wsi->user_space);
  651. return 0;
  652. }
  653. LWS_VISIBLE void lwsl_emit_stderr(int level, const char *line)
  654. {
  655. unsigned long long now;
  656. char buf[300];
  657. int n;
  658. buf[0] = '\0';
  659. for (n = 0; n < LLL_COUNT; n++) {
  660. if (level != (1 << n))
  661. continue;
  662. now = time_in_microseconds() / 100;
  663. sprintf(buf, "[%llu:%04d] %s: ",
  664. (unsigned long long) now / 10000,
  665. (int)(now % 10000), log_level_names[n]);
  666. break;
  667. }
  668. fprintf(stderr, "%s%s", buf, line);
  669. }
  670. LWS_VISIBLE void _lws_logv(int filter, const char *format, va_list vl)
  671. {
  672. char buf[256];
  673. if (!(log_level & filter))
  674. return;
  675. vsnprintf(buf, sizeof(buf), format, vl);
  676. buf[sizeof(buf) - 1] = '\0';
  677. lwsl_emit(filter, buf);
  678. }
  679. LWS_VISIBLE void _lws_log(int filter, const char *format, ...)
  680. {
  681. va_list ap;
  682. va_start(ap, format);
  683. _lws_logv(filter, format, ap);
  684. va_end(ap);
  685. }
  686. /**
  687. * lws_set_log_level() - Set the logging bitfield
  688. * @level: OR together the LLL_ debug contexts you want output from
  689. * @log_emit_function: NULL to leave it as it is, or a user-supplied
  690. * function to perform log string emission instead of
  691. * the default stderr one.
  692. *
  693. * log level defaults to "err", "warn" and "notice" contexts enabled and
  694. * emission on stderr.
  695. */
  696. LWS_VISIBLE void lws_set_log_level(int level,
  697. void (*func)(int level, const char *line))
  698. {
  699. log_level = level;
  700. if (func)
  701. lwsl_emit = func;
  702. }
  703. /**
  704. * lws_use_ssl() - Find out if connection is using SSL
  705. * @wsi: websocket connection to check
  706. *
  707. * Returns 0 if the connection is not using SSL, 1 if using SSL and
  708. * using verified cert, and 2 if using SSL but the cert was not
  709. * checked (appears for client wsi told to skip check on connection)
  710. */
  711. LWS_VISIBLE int
  712. lws_is_ssl(struct lws *wsi)
  713. {
  714. #ifdef LWS_OPENSSL_SUPPORT
  715. return wsi->use_ssl;
  716. #else
  717. (void)wsi;
  718. return 0;
  719. #endif
  720. }
  721. /**
  722. * lws_partial_buffered() - find out if lws buffered the last write
  723. * @wsi: websocket connection to check
  724. *
  725. * Returns 1 if you cannot use lws_write because the last
  726. * write on this connection is still buffered, and can't be cleared without
  727. * returning to the service loop and waiting for the connection to be
  728. * writeable again.
  729. *
  730. * If you will try to do >1 lws_write call inside a single
  731. * WRITEABLE callback, you must check this after every write and bail if
  732. * set, ask for a new writeable callback and continue writing from there.
  733. *
  734. * This is never set at the start of a writeable callback, but any write
  735. * may set it.
  736. */
  737. LWS_VISIBLE int
  738. lws_partial_buffered(struct lws *wsi)
  739. {
  740. return !!wsi->trunc_len;
  741. }
  742. void lws_set_protocol_write_pending(struct lws *wsi,
  743. enum lws_pending_protocol_send pend)
  744. {
  745. lwsl_info("setting pps %d\n", pend);
  746. if (wsi->pps)
  747. lwsl_err("pps overwrite\n");
  748. wsi->pps = pend;
  749. lws_rx_flow_control(wsi, 0);
  750. lws_callback_on_writable(wsi);
  751. }
  752. LWS_VISIBLE size_t
  753. lws_get_peer_write_allowance(struct lws *wsi)
  754. {
  755. #ifdef LWS_USE_HTTP2
  756. /* only if we are using HTTP2 on this connection */
  757. if (wsi->mode != LWSCM_HTTP2_SERVING)
  758. return -1;
  759. /* user is only interested in how much he can send, or that he can't */
  760. if (wsi->u.http2.tx_credit <= 0)
  761. return 0;
  762. return wsi->u.http2.tx_credit;
  763. #else
  764. (void)wsi;
  765. return -1;
  766. #endif
  767. }
  768. LWS_VISIBLE void
  769. lws_union_transition(struct lws *wsi, enum connection_mode mode)
  770. {
  771. memset(&wsi->u, 0, sizeof(wsi->u));
  772. wsi->mode = mode;
  773. }
  774. LWS_VISIBLE struct lws_plat_file_ops *
  775. lws_get_fops(struct lws_context *context)
  776. {
  777. return &context->fops;
  778. }
  779. LWS_VISIBLE LWS_EXTERN struct lws_context *
  780. lws_get_context(const struct lws *wsi)
  781. {
  782. return wsi->context;
  783. }
  784. LWS_VISIBLE LWS_EXTERN void *
  785. lws_wsi_user(struct lws *wsi)
  786. {
  787. return wsi->user_space;
  788. }