blob: 787c4a0d94ab1adc30a8cc257d576117ad501500 [file] [log] [blame]
Andy Green58eaa742011-03-07 17:54:06 +00001/*
Andy Greena0da8a82010-11-08 17:12:19 +00002 * libwebsockets - small server side websockets and web server implementation
Andy Green8f037e42010-12-19 22:13:26 +00003 *
Andy Green158e8042014-04-02 14:25:10 +08004 * Copyright (C) 2010-2014 Andy Green <andy@warmcat.com>
Andy Greena0da8a82010-11-08 17:12:19 +00005 *
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
Andy Green05a0a7b2010-10-31 17:51:39 +000020 */
21
Andy Green7c212cc2010-11-08 20:20:42 +000022#include "private-libwebsockets.h"
Andy Greenff95d7a2010-10-28 22:36:01 +010023
Andy Green3d67f512014-04-03 07:29:50 +080024int log_level = LLL_ERR | LLL_WARN | LLL_NOTICE;
Andy Green058ba812013-01-19 11:32:18 +080025static void (*lwsl_emit)(int level, const char *line) = lwsl_emit_stderr;
26
Andy Greenb5b23192013-02-11 17:13:32 +080027static const char * const log_level_names[] = {
Andy Green43db0452013-01-10 19:50:35 +080028 "ERR",
29 "WARN",
Andy Green7c19c342013-01-19 12:18:07 +080030 "NOTICE",
Andy Green43db0452013-01-10 19:50:35 +080031 "INFO",
32 "DEBUG",
33 "PARSER",
34 "HEADER",
35 "EXTENSION",
36 "CLIENT",
Andy Greend636e352013-01-29 12:36:17 +080037 "LATENCY",
Andy Green43db0452013-01-10 19:50:35 +080038};
39
Andy Green8f037e42010-12-19 22:13:26 +000040void
Andy Green4b85c1d2015-12-04 11:08:32 +080041lws_free_wsi(struct lws *wsi)
=?UTF-8?q?Joakim=20S=C3=B6derberg?=caf7e3d2015-06-25 17:51:07 +020042{
43 if (!wsi)
44 return;
45
46 /* Protocol user data may be allocated either internally by lws
47 * or by specified the user. Important we don't free external user data */
48 if (wsi->protocol && wsi->protocol->per_session_data_size
49 && wsi->user_space && !wsi->user_space_externally_allocated) {
50 lws_free(wsi->user_space);
51 }
52
53 lws_free2(wsi->rxflow_buffer);
54 lws_free2(wsi->truncated_send_malloc);
55
56 // TODO: Probably should handle the union structs in wsi->u here depending
57 // on connection mode as well. Too spaghetti for me to follow however...
58
59 lws_free_header_table(wsi);
60 lws_free(wsi);
61}
62
63void
Andy Green4b85c1d2015-12-04 11:08:32 +080064lws_close_and_free_session(struct lws_context *context,
65 struct lws *wsi, enum lws_close_status reason)
Andy Green251f6fa2010-11-03 11:13:06 +000066{
Andy Greene40aa9b2014-04-02 21:02:54 +080067 int n, m, ret;
Andy Green62c54d22011-02-14 09:14:25 +000068 int old_state;
Andy Green5e1fa172011-02-10 09:07:05 +000069 unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 +
70 LWS_SEND_BUFFER_POST_PADDING];
Andy Greenc44159f2011-03-07 07:08:18 +000071 struct lws_tokens eff_buf;
Andy Greenb45993c2010-12-18 15:13:50 +000072
Andy Green4b6fbe12011-02-14 08:03:48 +000073 if (!wsi)
Andy Greenb45993c2010-12-18 15:13:50 +000074 return;
75
Andy Green62c54d22011-02-14 09:14:25 +000076 old_state = wsi->state;
Andy Green251f6fa2010-11-03 11:13:06 +000077
Andy Green408f5372015-04-12 08:17:26 +080078 if (wsi->socket_is_permanently_unusable ||
79 reason == LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY)
Andy Green1e499182014-10-16 08:23:46 +080080 goto just_kill_connection;
81
Andy Greena1a24d22014-04-10 14:25:24 +080082 switch (old_state) {
83 case WSI_STATE_DEAD_SOCKET:
Andy Green5e1fa172011-02-10 09:07:05 +000084 return;
85
Andy Green22524a62013-02-15 22:48:58 +080086 /* we tried the polite way... */
Andy Greena1a24d22014-04-10 14:25:24 +080087 case WSI_STATE_AWAITING_CLOSE_ACK:
Andy Green22524a62013-02-15 22:48:58 +080088 goto just_kill_connection;
89
Andy Greena1a24d22014-04-10 14:25:24 +080090 case WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE:
91 if (wsi->truncated_send_len) {
Andy Green62304762015-12-04 08:43:54 +080092 lws_callback_on_writable(context, wsi);
Andy Greena1a24d22014-04-10 14:25:24 +080093 return;
94 }
95 lwsl_info("wsi %p completed WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi);
96 goto just_kill_connection;
97 default:
98 if (wsi->truncated_send_len) {
99 lwsl_info("wsi %p entering WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi);
100 wsi->state = WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE;
Andy Green62304762015-12-04 08:43:54 +0800101 lws_set_timeout(wsi, PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE, 5);
Andy Greena1a24d22014-04-10 14:25:24 +0800102 return;
103 }
104 break;
105 }
106
Andy Green623a98d2013-01-21 11:04:23 +0800107 wsi->u.ws.close_reason = reason;
Andy Greenda527df2011-03-07 07:08:12 +0000108
Andy Green5dc62ea2013-09-20 20:26:12 +0800109 if (wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT ||
Andy Green0c8a8542015-10-28 19:50:41 +0800110 wsi->mode == LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE)
Andy Green5dc62ea2013-09-20 20:26:12 +0800111 goto just_kill_connection;
Andy Green5dc62ea2013-09-20 20:26:12 +0800112
Drew Noakes6a779772015-01-28 04:15:13 +0800113 if (wsi->mode == LWS_CONNMODE_HTTP_SERVING)
114 context->protocols[0].callback(context, wsi,
115 LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0);
116
kapejodce64fb02013-11-19 13:38:16 +0100117 if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED) {
Patrick Gansterer81338aa2014-02-27 03:21:50 +0100118 if (wsi->u.http.fd != LWS_INVALID_FILE) {
=?UTF-8?q?Joakim=20S=C3=B6derberg?=caf7e3d2015-06-25 17:51:07 +0200119 // TODO: If we're just closing with LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY this file descriptor might leak?
Patrick Gansterer81338aa2014-02-27 03:21:50 +0100120 lwsl_debug("closing http file\n");
Andy Green158e8042014-04-02 14:25:10 +0800121 compatible_file_close(wsi->u.http.fd);
Patrick Gansterer81338aa2014-02-27 03:21:50 +0100122 wsi->u.http.fd = LWS_INVALID_FILE;
kapejodce64fb02013-11-19 13:38:16 +0100123 context->protocols[0].callback(context, wsi,
124 LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0);
125 }
Andy Greenb8b247d2013-01-22 07:20:08 +0800126 }
127
Andy Greenda527df2011-03-07 07:08:12 +0000128 /*
Andy Green68b45042011-05-25 21:41:57 +0100129 * are his extensions okay with him closing? Eg he might be a mux
130 * parent and just his ch1 aspect is closing?
131 */
Andy Greene40aa9b2014-04-02 21:02:54 +0800132
133 if (lws_ext_callback_for_each_active(wsi,
134 LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE, NULL, 0) > 0) {
135 lwsl_ext("extension vetoed close\n");
136 return;
Andy Green68b45042011-05-25 21:41:57 +0100137 }
138
Andy Green68b45042011-05-25 21:41:57 +0100139 /*
Andy Greenc44159f2011-03-07 07:08:18 +0000140 * flush any tx pending from extensions, since we may send close packet
141 * if there are problems with send, just nuke the connection
142 */
143
Andy Greene40aa9b2014-04-02 21:02:54 +0800144 do {
Andy Greenc44159f2011-03-07 07:08:18 +0000145 ret = 0;
146 eff_buf.token = NULL;
147 eff_buf.token_len = 0;
148
149 /* show every extension the new incoming data */
150
Andy Greene40aa9b2014-04-02 21:02:54 +0800151 m = lws_ext_callback_for_each_active(wsi,
152 LWS_EXT_CALLBACK_FLUSH_PENDING_TX, &eff_buf, 0);
153 if (m < 0) {
154 lwsl_ext("Extension reports fatal error\n");
155 goto just_kill_connection;
Andy Greenc44159f2011-03-07 07:08:18 +0000156 }
Andy Greene40aa9b2014-04-02 21:02:54 +0800157 if (m)
158 /*
159 * at least one extension told us he has more
160 * to spill, so we will go around again after
161 */
162 ret = 1;
Andy Greenc44159f2011-03-07 07:08:18 +0000163
164 /* assuming they left us something to send, send it */
165
166 if (eff_buf.token_len)
167 if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
Andy Greenfc7c5e42013-02-23 10:50:10 +0800168 eff_buf.token_len) != eff_buf.token_len) {
Andy Greenb5b23192013-02-11 17:13:32 +0800169 lwsl_debug("close: ext spill failed\n");
Andy Greenc44159f2011-03-07 07:08:18 +0000170 goto just_kill_connection;
Andy Green0303db42013-01-17 14:46:43 +0800171 }
Andy Greene40aa9b2014-04-02 21:02:54 +0800172 } while (ret);
Andy Greenc44159f2011-03-07 07:08:18 +0000173
174 /*
Andy Green62304762015-12-04 08:43:54 +0800175 * signal we are closing, lws_write will
Andy Greenda527df2011-03-07 07:08:12 +0000176 * add any necessary version-specific stuff. If the write fails,
177 * no worries we are closing anyway. If we didn't initiate this
178 * close, then our state has been changed to
179 * WSI_STATE_RETURNED_CLOSE_ALREADY and we will skip this.
180 *
181 * Likewise if it's a second call to close this connection after we
182 * sent the close indication to the peer already, we are in state
183 * WSI_STATE_AWAITING_CLOSE_ACK and will skip doing this a second time.
184 */
185
186 if (old_state == WSI_STATE_ESTABLISHED &&
Andy Green8ec78022015-03-25 01:53:58 +0800187 reason != LWS_CLOSE_STATUS_NOSTATUS &&
188 reason != LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY) {
Andy Green66a16f32011-05-24 22:07:45 +0100189
Andy Green43db0452013-01-10 19:50:35 +0800190 lwsl_debug("sending close indication...\n");
Andy Green66a16f32011-05-24 22:07:45 +0100191
Andy Greenfdd305a2013-02-11 14:32:48 +0800192 /* make valgrind happy */
Andy Greenb5b23192013-02-11 17:13:32 +0800193 memset(buf, 0, sizeof(buf));
Andy Green62304762015-12-04 08:43:54 +0800194 n = lws_write(wsi,
Andy Greenb5b23192013-02-11 17:13:32 +0800195 &buf[LWS_SEND_BUFFER_PRE_PADDING + 2],
Andy Greenda527df2011-03-07 07:08:12 +0000196 0, LWS_WRITE_CLOSE);
Andy Greenfc7c5e42013-02-23 10:50:10 +0800197 if (n >= 0) {
Andy Greenda527df2011-03-07 07:08:12 +0000198 /*
199 * we have sent a nice protocol level indication we
200 * now wish to close, we should not send anything more
201 */
202
203 wsi->state = WSI_STATE_AWAITING_CLOSE_ACK;
204
Andy Greenb5b23192013-02-11 17:13:32 +0800205 /*
206 * ...and we should wait for a reply for a bit
207 * out of politeness
208 */
Andy Greenda527df2011-03-07 07:08:12 +0000209
Andy Green62304762015-12-04 08:43:54 +0800210 lws_set_timeout(wsi,
Andy Green0303db42013-01-17 14:46:43 +0800211 PENDING_TIMEOUT_CLOSE_ACK, 1);
Andy Greenda527df2011-03-07 07:08:12 +0000212
Andy Green43db0452013-01-10 19:50:35 +0800213 lwsl_debug("sent close indication, awaiting ack\n");
Andy Greenda527df2011-03-07 07:08:12 +0000214
215 return;
216 }
217
Andy Greenb5b23192013-02-11 17:13:32 +0800218 lwsl_info("close: sending close packet failed, hanging up\n");
Andy Green0303db42013-01-17 14:46:43 +0800219
Andy Greenda527df2011-03-07 07:08:12 +0000220 /* else, the send failed and we should just hang up */
221 }
222
Andy Greenc44159f2011-03-07 07:08:18 +0000223just_kill_connection:
Andy Green66a16f32011-05-24 22:07:45 +0100224
Andy Greenb5b23192013-02-11 17:13:32 +0800225 lwsl_debug("close: just_kill_connection\n");
Andy Green66a16f32011-05-24 22:07:45 +0100226
Andy Greenda527df2011-03-07 07:08:12 +0000227 /*
228 * we won't be servicing or receiving anything further from this guy
Andy Greendfb23042013-01-17 12:26:48 +0800229 * delete socket from the internal poll list if still present
Andy Greenda527df2011-03-07 07:08:12 +0000230 */
Andy Green4b6fbe12011-02-14 08:03:48 +0000231
Andy Green52815602015-01-29 08:36:18 +0800232 lws_ssl_remove_wsi_from_buffered_list(context, wsi);
233
Andy Green1963c9a2015-10-15 07:39:33 +0800234 // checking return redundant since we anyway close
Andy Greendfb23042013-01-17 12:26:48 +0800235 remove_wsi_socket_from_fds(context, wsi);
Andy Green4b6fbe12011-02-14 08:03:48 +0000236
Andy Green251f6fa2010-11-03 11:13:06 +0000237 wsi->state = WSI_STATE_DEAD_SOCKET;
Alejandro Meryac3ec392014-12-05 00:09:20 +0100238
239 lws_free2(wsi->rxflow_buffer);
=?UTF-8?q?Joakim=20S=C3=B6derberg?=caf7e3d2015-06-25 17:51:07 +0200240 lws_free_header_table(wsi);
Alejandro Meryac3ec392014-12-05 00:09:20 +0100241
Andy Greenb5b23192013-02-11 17:13:32 +0800242 if ((old_state == WSI_STATE_ESTABLISHED ||
243 wsi->mode == LWS_CONNMODE_WS_SERVING ||
Andy Green3ee9b312013-02-12 12:52:39 +0800244 wsi->mode == LWS_CONNMODE_WS_CLIENT)) {
245
Alejandro Meryac3ec392014-12-05 00:09:20 +0100246 lws_free2(wsi->u.ws.rx_user_buffer);
Andy Green024eb6c2014-10-08 12:00:53 +0800247
Andy Green2764eba2013-12-09 14:16:17 +0800248 if (wsi->truncated_send_malloc) {
Andy Green1f4267b2013-10-17 08:09:19 +0800249 /* not going to be completed... nuke it */
Alejandro Meryac3ec392014-12-05 00:09:20 +0100250 lws_free2(wsi->truncated_send_malloc);
Andy Greene254d952014-03-23 11:41:15 +0800251 wsi->truncated_send_len = 0;
Andy Green1f4267b2013-10-17 08:09:19 +0800252 }
Andy Green82bac6b2014-08-24 14:39:19 +0800253 if (wsi->u.ws.ping_payload_buf) {
Alejandro Meryac3ec392014-12-05 00:09:20 +0100254 lws_free2(wsi->u.ws.ping_payload_buf);
Andy Green82bac6b2014-08-24 14:39:19 +0800255 wsi->u.ws.ping_payload_alloc = 0;
256 wsi->u.ws.ping_payload_len = 0;
Andy Green2fd6e6f2015-03-24 21:07:01 +0800257 wsi->u.ws.ping_pending_flag = 0;
Andy Green82bac6b2014-08-24 14:39:19 +0800258 }
Andy Green54495112013-02-06 21:10:16 +0900259 }
260
Andy Green4b6fbe12011-02-14 08:03:48 +0000261 /* tell the user it's all over for this guy */
262
Andy Greend4302732011-02-28 07:45:29 +0000263 if (wsi->protocol && wsi->protocol->callback &&
Andy Green6ee372f2012-04-09 15:09:01 +0800264 ((old_state == WSI_STATE_ESTABLISHED) ||
265 (old_state == WSI_STATE_RETURNED_CLOSE_ALREADY) ||
Stefan Schuermansb944cc12014-09-08 14:01:58 +0800266 (old_state == WSI_STATE_AWAITING_CLOSE_ACK) ||
267 (old_state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE))) {
Andy Green43db0452013-01-10 19:50:35 +0800268 lwsl_debug("calling back CLOSED\n");
Peter Hinz56885f32011-03-02 22:03:47 +0000269 wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLOSED,
Andy Greene77ddd82010-11-13 10:03:47 +0000270 wsi->user_space, NULL, 0);
Andy Green158e8042014-04-02 14:25:10 +0800271 } else if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED) {
Niall T. Davidsondb761be2013-06-29 10:16:18 +0800272 lwsl_debug("calling back CLOSED_HTTP\n");
273 context->protocols[0].callback(context, wsi,
274 LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0 );
Andy Greenb7a721f2015-04-27 19:07:38 +0800275 } else if (wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY ||
276 wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT) {
Andy Greenbb90f9b2015-04-16 19:55:42 +0800277 lwsl_debug("Connection closed before server reply\n");
278 context->protocols[0].callback(context, wsi,
279 LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
280 wsi->user_space, NULL, 0 );
Andy Greencc012472011-11-07 19:53:23 +0800281 } else
Andy Greenbb90f9b2015-04-16 19:55:42 +0800282 lwsl_debug("not calling back closed mode=%d state=%d\n",
283 wsi->mode, old_state);
Andy Green251f6fa2010-11-03 11:13:06 +0000284
Andy Greenef660a92011-03-06 10:29:38 +0000285 /* deallocate any active extension contexts */
Andy Greene40aa9b2014-04-02 21:02:54 +0800286
287 if (lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_DESTROY, NULL, 0) < 0)
288 lwsl_warn("extension destruction failed\n");
289#ifndef LWS_NO_EXTENSIONS
290 for (n = 0; n < wsi->count_active_extensions; n++)
Alejandro Mery6ff28242014-12-04 23:59:35 +0100291 lws_free(wsi->active_extensions_user[n]);
Andy Greene40aa9b2014-04-02 21:02:54 +0800292#endif
Andy Greena41314f2011-05-23 10:00:03 +0100293 /*
294 * inform all extensions in case they tracked this guy out of band
295 * even though not active on him specifically
296 */
Andy Greene40aa9b2014-04-02 21:02:54 +0800297 if (lws_ext_callback_for_each_extension_type(context, wsi,
298 LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING, NULL, 0) < 0)
299 lwsl_warn("ext destroy wsi failed\n");
Andy Greena41314f2011-05-23 10:00:03 +0100300
Andy Green43db0452013-01-10 19:50:35 +0800301/* lwsl_info("closing fd=%d\n", wsi->sock); */
Andy Green251f6fa2010-11-03 11:13:06 +0000302
Andy Greenfc772cc2015-11-14 13:48:58 +0800303 if (!lws_ssl_close(wsi) && lws_socket_is_valid(wsi->sock)) {
Andy Green8c0d3c02015-11-02 20:34:12 +0800304#if LWS_POSIX
Andy Greencdb9bf92014-04-12 10:07:02 +0800305 n = shutdown(wsi->sock, SHUT_RDWR);
306 if (n)
307 lwsl_debug("closing: shutdown ret %d\n", LWS_ERRNO);
Andy Green3fc2c652013-01-14 15:35:02 +0800308
Andy Greencdb9bf92014-04-12 10:07:02 +0800309 n = compatible_close(wsi->sock);
310 if (n)
311 lwsl_debug("closing: close ret %d\n", LWS_ERRNO);
Andy Green8c0d3c02015-11-02 20:34:12 +0800312
Andy Green11f27342015-11-08 12:10:26 +0800313#else
314 compatible_close(wsi->sock);
Andy Green8c0d3c02015-11-02 20:34:12 +0800315#endif
Andy Green11f27342015-11-08 12:10:26 +0800316 wsi->sock = LWS_SOCK_INVALID;
Andy Green3faa9c72010-11-08 17:03:03 +0000317 }
Andy Green76b6ea12014-02-15 19:25:50 +0800318
319 /* outermost destroy notification for wsi (user_space still intact) */
320 context->protocols[0].callback(context, wsi,
321 LWS_CALLBACK_WSI_DESTROY, wsi->user_space, NULL, 0);
322
=?UTF-8?q?Joakim=20S=C3=B6derberg?=caf7e3d2015-06-25 17:51:07 +0200323 lws_free_wsi(wsi);
Andy Green251f6fa2010-11-03 11:13:06 +0000324}
325
Andy Green7e37d102015-01-28 21:03:49 +0800326LWS_VISIBLE int
Andy Green4b85c1d2015-12-04 11:08:32 +0800327lws_get_addresses(struct lws_context *context,
Andy Green7e37d102015-01-28 21:03:49 +0800328 void *ads, char *name, int name_len,
329 char *rip, int rip_len)
330{
Andy Green8c0d3c02015-11-02 20:34:12 +0800331#if LWS_POSIX
Andy Green7e37d102015-01-28 21:03:49 +0800332 struct addrinfo ai, *res;
Andrejs Haninsf94dd2e2015-10-15 13:02:03 +0300333 struct sockaddr_in addr4;
Andy Green7e37d102015-01-28 21:03:49 +0800334
335 rip[0] = '\0';
336 name[0] = '\0';
Andrejs Haninsf94dd2e2015-10-15 13:02:03 +0300337 addr4.sin_family = AF_UNSPEC;
Andy Green7e37d102015-01-28 21:03:49 +0800338
339#ifdef LWS_USE_IPV6
340 if (LWS_IPV6_ENABLED(context)) {
341 if (!lws_plat_inet_ntop(AF_INET6, &((struct sockaddr_in6 *)ads)->sin6_addr, rip, rip_len)) {
342 lwsl_err("inet_ntop", strerror(LWS_ERRNO));
343 return -1;
344 }
345
346 // Strip off the IPv4 to IPv6 header if one exists
347 if (strncmp(rip, "::ffff:", 7) == 0)
348 memmove(rip, rip + 7, strlen(rip) - 6);
349
350 getnameinfo((struct sockaddr *)ads,
351 sizeof(struct sockaddr_in6), name,
352 name_len, NULL, 0, 0);
353
354 return 0;
355 } else
356#endif
357 {
Andrejs Haninsf94dd2e2015-10-15 13:02:03 +0300358 struct addrinfo *result;
359
Andy Green7e37d102015-01-28 21:03:49 +0800360 memset(&ai, 0, sizeof ai);
361 ai.ai_family = PF_UNSPEC;
362 ai.ai_socktype = SOCK_STREAM;
363 ai.ai_flags = AI_CANONNAME;
364
365 if (getnameinfo((struct sockaddr *)ads,
366 sizeof(struct sockaddr_in),
367 name, name_len, NULL, 0, 0))
368 return -1;
369
370 if (!rip)
371 return 0;
372
Andrejs Haninsf94dd2e2015-10-15 13:02:03 +0300373 if (getaddrinfo(name, NULL, &ai, &result))
Andy Green7e37d102015-01-28 21:03:49 +0800374 return -1;
375
Andrejs Haninsf94dd2e2015-10-15 13:02:03 +0300376 res = result;
377 while (addr4.sin_family == AF_UNSPEC && res) {
Andy Green7e37d102015-01-28 21:03:49 +0800378 switch (res->ai_family) {
379 case AF_INET:
Andrejs Haninsf94dd2e2015-10-15 13:02:03 +0300380 addr4.sin_addr = ((struct sockaddr_in *)res->ai_addr)->sin_addr;
381 addr4.sin_family = AF_INET;
Andy Green7e37d102015-01-28 21:03:49 +0800382 break;
383 }
384
385 res = res->ai_next;
386 }
Andrejs Haninsf94dd2e2015-10-15 13:02:03 +0300387 freeaddrinfo(result);
Andy Green7e37d102015-01-28 21:03:49 +0800388 }
389
Andrejs Haninsf94dd2e2015-10-15 13:02:03 +0300390 if (addr4.sin_family == AF_UNSPEC)
Andy Green7e37d102015-01-28 21:03:49 +0800391 return -1;
392
Andrejs Haninsf94dd2e2015-10-15 13:02:03 +0300393 lws_plat_inet_ntop(AF_INET, &addr4.sin_addr, rip, rip_len);
Andy Green7e37d102015-01-28 21:03:49 +0800394
395 return 0;
Andy Green8c0d3c02015-11-02 20:34:12 +0800396#else
397 (void)context;
398 (void)ads;
399 (void)name;
400 (void)name_len;
401 (void)rip;
402 (void)rip_len;
403
404 return -1;
405#endif
Andy Green7e37d102015-01-28 21:03:49 +0800406}
407
Andy Green07034092011-02-13 08:37:12 +0000408/**
Andy Green62304762015-12-04 08:43:54 +0800409 * lws_get_peer_addresses() - Get client address information
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800410 * @context: Libwebsockets context
Andy Green4b85c1d2015-12-04 11:08:32 +0800411 * @wsi: Local struct lws associated with
Andy Green07034092011-02-13 08:37:12 +0000412 * @fd: Connection socket descriptor
413 * @name: Buffer to take client address name
414 * @name_len: Length of client address name buffer
Drew Noakesefe10b02014-10-23 15:34:26 +0100415 * @rip: Buffer to take client address IP dotted quad
Andy Green07034092011-02-13 08:37:12 +0000416 * @rip_len: Length of client address IP buffer
417 *
418 * This function fills in @name and @rip with the name and IP of
Andy Green6ee372f2012-04-09 15:09:01 +0800419 * the client connected with socket descriptor @fd. Names may be
420 * truncated if there is not enough room. If either cannot be
421 * determined, they will be returned as valid zero-length strings.
Andy Green07034092011-02-13 08:37:12 +0000422 */
423
Peter Pentchev9a4fef72013-03-30 09:52:21 +0800424LWS_VISIBLE void
Andy Green4b85c1d2015-12-04 11:08:32 +0800425lws_get_peer_addresses(struct lws_context *context,
426 struct lws *wsi, lws_sockfd_type fd, char *name, int name_len,
Andy Green07034092011-02-13 08:37:12 +0000427 char *rip, int rip_len)
428{
Andy Green8c0d3c02015-11-02 20:34:12 +0800429#if LWS_POSIX
Bob Robertsac049112013-04-25 09:16:30 +0800430 socklen_t len;
Andy Green055f2972014-03-24 16:09:25 +0800431#ifdef LWS_USE_IPV6
James Devine3f13ea22014-03-24 16:09:25 +0800432 struct sockaddr_in6 sin6;
433#endif
434 struct sockaddr_in sin4;
James Devine3f13ea22014-03-24 16:09:25 +0800435 int ret = -1;
Andy Green7e37d102015-01-28 21:03:49 +0800436 void *p;
Andy Green07034092011-02-13 08:37:12 +0000437
438 rip[0] = '\0';
439 name[0] = '\0';
440
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800441 lws_latency_pre(context, wsi);
442
Andy Green055f2972014-03-24 16:09:25 +0800443#ifdef LWS_USE_IPV6
James Devine3f13ea22014-03-24 16:09:25 +0800444 if (LWS_IPV6_ENABLED(context)) {
James Devine3f13ea22014-03-24 16:09:25 +0800445 len = sizeof(sin6);
Andy Green7e37d102015-01-28 21:03:49 +0800446 p = &sin6;
James Devine3f13ea22014-03-24 16:09:25 +0800447 } else
Peter Hinzbb45a902011-03-10 18:14:01 +0000448#endif
James Devine3f13ea22014-03-24 16:09:25 +0800449 {
450 len = sizeof(sin4);
Andy Green7e37d102015-01-28 21:03:49 +0800451 p = &sin4;
Andy Green07034092011-02-13 08:37:12 +0000452 }
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800453
Andy Green7e37d102015-01-28 21:03:49 +0800454 if (getpeername(fd, p, &len) < 0) {
455 lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO));
456 goto bail;
457 }
458
Andy Green3ef579b2015-12-04 09:23:56 +0800459 ret = lws_get_addresses(context, p, name, name_len, rip, rip_len);
Andy Green7e37d102015-01-28 21:03:49 +0800460
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800461bail:
Andy Green62304762015-12-04 08:43:54 +0800462 lws_latency(context, wsi, "lws_get_peer_addresses", ret, 1);
Andy Green8c0d3c02015-11-02 20:34:12 +0800463#else
464 (void)context;
465 (void)wsi;
466 (void)fd;
467 (void)name;
468 (void)name_len;
469 (void)rip;
470 (void)rip_len;
471#endif
Andy Green07034092011-02-13 08:37:12 +0000472}
Andy Green9f990342011-02-12 11:57:45 +0000473
Andy Greend88146d2013-01-22 12:40:35 +0800474/**
Andy Green62304762015-12-04 08:43:54 +0800475 * lws_context_user() - get the user data associated with the context
Andy Greend88146d2013-01-22 12:40:35 +0800476 * @context: Websocket context
477 *
478 * This returns the optional user allocation that can be attached to
479 * the context the sockets live in at context_create time. It's a way
480 * to let all sockets serviced in the same context share data without
481 * using globals statics in the user code.
482 */
Alon Levy0291eb32012-10-19 11:21:56 +0200483LWS_EXTERN void *
Andy Green4b85c1d2015-12-04 11:08:32 +0800484lws_context_user(struct lws_context *context)
Alon Levy0291eb32012-10-19 11:21:56 +0200485{
Andy Greenb5b23192013-02-11 17:13:32 +0800486 return context->user_space;
Alon Levy0291eb32012-10-19 11:21:56 +0200487}
488
Andy Greene92cd172011-01-19 13:11:55 +0000489
Andy Greenbe93fef2011-02-14 20:25:43 +0000490/**
Andy Green62304762015-12-04 08:43:54 +0800491 * lws_callback_all_protocol() - Callback all connections using
Andy Greene39e6ef2014-02-15 16:36:38 +0800492 * the given protocol with the given reason
493 *
494 * @protocol: Protocol whose connections will get callbacks
495 * @reason: Callback reason index
496 */
497
498LWS_VISIBLE int
Andy Green62304762015-12-04 08:43:54 +0800499lws_callback_all_protocol(
Andy Green4b85c1d2015-12-04 11:08:32 +0800500 const struct lws_protocols *protocol, int reason)
Andy Greene39e6ef2014-02-15 16:36:38 +0800501{
Andy Green4b85c1d2015-12-04 11:08:32 +0800502 struct lws_context *context = protocol->owning_server;
Andy Greene39e6ef2014-02-15 16:36:38 +0800503 int n;
Andy Green4b85c1d2015-12-04 11:08:32 +0800504 struct lws *wsi;
Andy Greene39e6ef2014-02-15 16:36:38 +0800505
506 for (n = 0; n < context->fds_count; n++) {
Bud Davis229bfec2015-01-30 10:13:01 +0800507 wsi = wsi_from_fd(context, context->fds[n].fd);
Andy Greene39e6ef2014-02-15 16:36:38 +0800508 if (!wsi)
509 continue;
510 if (wsi->protocol == protocol)
511 protocol->callback(context, wsi,
512 reason, wsi->user_space, NULL, 0);
513 }
514
515 return 0;
516}
517
518/**
Andy Green62304762015-12-04 08:43:54 +0800519 * lws_set_timeout() - marks the wsi as subject to a timeout
Andy Greenbe93fef2011-02-14 20:25:43 +0000520 *
521 * You will not need this unless you are doing something special
522 *
523 * @wsi: Websocket connection instance
524 * @reason: timeout reason
525 * @secs: how many seconds
526 */
527
Craig McQueene7fd8b12014-02-19 09:24:17 +1100528LWS_VISIBLE void
Andy Green4b85c1d2015-12-04 11:08:32 +0800529lws_set_timeout(struct lws *wsi,
Andy Greenbe93fef2011-02-14 20:25:43 +0000530 enum pending_timeout reason, int secs)
531{
Patrick Gansterer92792b42014-02-26 21:37:31 +0100532 time_t now;
Andy Greenbe93fef2011-02-14 20:25:43 +0000533
Patrick Gansterer92792b42014-02-26 21:37:31 +0100534 time(&now);
Andy Greenbe93fef2011-02-14 20:25:43 +0000535
Patrick Gansterer92792b42014-02-26 21:37:31 +0100536 wsi->pending_timeout_limit = now + secs;
Andy Greenbe93fef2011-02-14 20:25:43 +0000537 wsi->pending_timeout = reason;
538}
539
Andy Greena6cbece2011-01-27 20:06:03 +0000540
Andy Green8c0d3c02015-11-02 20:34:12 +0800541#if LWS_POSIX
542
Andy Greena6cbece2011-01-27 20:06:03 +0000543/**
Andy Green62304762015-12-04 08:43:54 +0800544 * lws_get_socket_fd() - returns the socket file descriptor
Andy Greena6cbece2011-01-27 20:06:03 +0000545 *
546 * You will not need this unless you are doing something special
547 *
548 * @wsi: Websocket connection instance
549 */
550
Peter Pentchev9a4fef72013-03-30 09:52:21 +0800551LWS_VISIBLE int
Andy Green4b85c1d2015-12-04 11:08:32 +0800552lws_get_socket_fd(struct lws *wsi)
Andy Greena6cbece2011-01-27 20:06:03 +0000553{
554 return wsi->sock;
555}
556
Andy Green8c0d3c02015-11-02 20:34:12 +0800557#endif
558
Andy Greend636e352013-01-29 12:36:17 +0800559#ifdef LWS_LATENCY
560void
Andy Green4b85c1d2015-12-04 11:08:32 +0800561lws_latency(struct lws_context *context, struct lws *wsi,
Andy Greenb5b23192013-02-11 17:13:32 +0800562 const char *action, int ret, int completed)
Andy Greend636e352013-01-29 12:36:17 +0800563{
Patrick Gansterer92792b42014-02-26 21:37:31 +0100564 unsigned long long u;
Andy Greend636e352013-01-29 12:36:17 +0800565 char buf[256];
566
Patrick Gansterer92792b42014-02-26 21:37:31 +0100567 u = time_in_microseconds();
Andy Greend636e352013-01-29 12:36:17 +0800568
Andy Greenbfaea952014-03-31 11:01:32 +0800569 if (!action) {
Andy Greend636e352013-01-29 12:36:17 +0800570 wsi->latency_start = u;
571 if (!wsi->action_start)
572 wsi->action_start = u;
Andy Greenbfaea952014-03-31 11:01:32 +0800573 return;
Andy Greend636e352013-01-29 12:36:17 +0800574 }
Andy Greenbfaea952014-03-31 11:01:32 +0800575 if (completed) {
576 if (wsi->action_start == wsi->latency_start)
577 sprintf(buf,
Cong Ma10da1172014-07-05 10:50:47 +0800578 "Completion first try lat %lluus: %p: ret %d: %s\n",
Andy Greenbfaea952014-03-31 11:01:32 +0800579 u - wsi->latency_start,
580 (void *)wsi, ret, action);
581 else
582 sprintf(buf,
Cong Ma10da1172014-07-05 10:50:47 +0800583 "Completion %lluus: lat %lluus: %p: ret %d: %s\n",
Andy Greenbfaea952014-03-31 11:01:32 +0800584 u - wsi->action_start,
585 u - wsi->latency_start,
586 (void *)wsi, ret, action);
587 wsi->action_start = 0;
588 } else
Cong Ma10da1172014-07-05 10:50:47 +0800589 sprintf(buf, "lat %lluus: %p: ret %d: %s\n",
Andy Greenbfaea952014-03-31 11:01:32 +0800590 u - wsi->latency_start, (void *)wsi, ret, action);
591
592 if (u - wsi->latency_start > context->worst_latency) {
593 context->worst_latency = u - wsi->latency_start;
594 strcpy(context->worst_latency_info, buf);
595 }
596 lwsl_latency("%s", buf);
Andy Greend636e352013-01-29 12:36:17 +0800597}
598#endif
599
Andy Green706961d2013-01-17 16:50:35 +0800600
Andy Green706961d2013-01-17 16:50:35 +0800601
Andy Green90c7cbc2011-01-27 06:26:52 +0000602/**
Andy Green62304762015-12-04 08:43:54 +0800603 * lws_rx_flow_control() - Enable and disable socket servicing for
Drew Noakesefe10b02014-10-23 15:34:26 +0100604 * received packets.
Andy Green90c7cbc2011-01-27 06:26:52 +0000605 *
606 * If the output side of a server process becomes choked, this allows flow
607 * control for the input side.
608 *
609 * @wsi: Websocket connection instance to get callback for
610 * @enable: 0 = disable read servicing for this connection, 1 = enable
611 */
612
Peter Pentchev9a4fef72013-03-30 09:52:21 +0800613LWS_VISIBLE int
Andy Green4b85c1d2015-12-04 11:08:32 +0800614lws_rx_flow_control(struct lws *wsi, int enable)
Andy Green90c7cbc2011-01-27 06:26:52 +0000615{
Andy Green024eb6c2014-10-08 12:00:53 +0800616 if (enable == (wsi->rxflow_change_to & LWS_RXFLOW_ALLOW))
Andy Greenca0a1292013-03-16 11:24:23 +0800617 return 0;
618
Andy Green62304762015-12-04 08:43:54 +0800619 lwsl_info("lws_rx_flow_control(0x%p, %d)\n", wsi, enable);
Andy Green024eb6c2014-10-08 12:00:53 +0800620 wsi->rxflow_change_to = LWS_RXFLOW_PENDING_CHANGE | !!enable;
Andy Green90c7cbc2011-01-27 06:26:52 +0000621
Andy Green706961d2013-01-17 16:50:35 +0800622 return 0;
Andy Green90c7cbc2011-01-27 06:26:52 +0000623}
624
Andy Greenb55451c2013-03-16 12:32:27 +0800625/**
Andy Green62304762015-12-04 08:43:54 +0800626 * lws_rx_flow_allow_all_protocol() - Allow all connections with this protocol to receive
Andy Greenb55451c2013-03-16 12:32:27 +0800627 *
628 * When the user server code realizes it can accept more input, it can
629 * call this to have the RX flow restriction removed from all connections using
630 * the given protocol.
631 *
632 * @protocol: all connections using this protocol will be allowed to receive
633 */
634
Peter Pentchev9a4fef72013-03-30 09:52:21 +0800635LWS_VISIBLE void
Andy Green62304762015-12-04 08:43:54 +0800636lws_rx_flow_allow_all_protocol(
Andy Green4b85c1d2015-12-04 11:08:32 +0800637 const struct lws_protocols *protocol)
Andy Greenb55451c2013-03-16 12:32:27 +0800638{
Andy Green4b85c1d2015-12-04 11:08:32 +0800639 struct lws_context *context = protocol->owning_server;
Andy Greenb55451c2013-03-16 12:32:27 +0800640 int n;
Andy Green4b85c1d2015-12-04 11:08:32 +0800641 struct lws *wsi;
Andy Greenb55451c2013-03-16 12:32:27 +0800642
643 for (n = 0; n < context->fds_count; n++) {
Bud Davis229bfec2015-01-30 10:13:01 +0800644 wsi = wsi_from_fd(context, context->fds[n].fd);
Andy Greenb55451c2013-03-16 12:32:27 +0800645 if (!wsi)
646 continue;
647 if (wsi->protocol == protocol)
Andy Green62304762015-12-04 08:43:54 +0800648 lws_rx_flow_control(wsi, LWS_RXFLOW_ALLOW);
Andy Greenb55451c2013-03-16 12:32:27 +0800649 }
650}
651
Andy Green706961d2013-01-17 16:50:35 +0800652
Andy Green2ac5a6f2011-01-28 10:00:18 +0000653/**
Andy Green62304762015-12-04 08:43:54 +0800654 * lws_canonical_hostname() - returns this host's hostname
Andy Green2ac5a6f2011-01-28 10:00:18 +0000655 *
656 * This is typically used by client code to fill in the host parameter
657 * when making a client connection. You can only call it after the context
658 * has been created.
659 *
Peter Hinz56885f32011-03-02 22:03:47 +0000660 * @context: Websocket context
Andy Green2ac5a6f2011-01-28 10:00:18 +0000661 */
Peter Pentchev9a4fef72013-03-30 09:52:21 +0800662LWS_VISIBLE extern const char *
Andy Green4b85c1d2015-12-04 11:08:32 +0800663lws_canonical_hostname(struct lws_context *context)
Andy Green2ac5a6f2011-01-28 10:00:18 +0000664{
Peter Hinz56885f32011-03-02 22:03:47 +0000665 return (const char *)context->canonical_hostname;
Andy Green2ac5a6f2011-01-28 10:00:18 +0000666}
667
Andy Green706961d2013-01-17 16:50:35 +0800668int user_callback_handle_rxflow(callback_function callback_function,
Andy Green4b85c1d2015-12-04 11:08:32 +0800669 struct lws_context *context,
670 struct lws *wsi,
671 enum lws_callback_reasons reason, void *user,
Andy Green706961d2013-01-17 16:50:35 +0800672 void *in, size_t len)
673{
674 int n;
675
676 n = callback_function(context, wsi, reason, user, in, len);
Andy Greenaedc9532013-02-10 21:21:24 +0800677 if (!n)
Andy Green62304762015-12-04 08:43:54 +0800678 n = _lws_rx_flow_control(wsi);
Andy Green706961d2013-01-17 16:50:35 +0800679
Andy Greenaedc9532013-02-10 21:21:24 +0800680 return n;
Andy Green706961d2013-01-17 16:50:35 +0800681}
682
Andy Greenb45993c2010-12-18 15:13:50 +0000683
Andy Greenb45993c2010-12-18 15:13:50 +0000684/**
Andy Green4b85c1d2015-12-04 11:08:32 +0800685 * lws_set_proxy() - Setups proxy to lws_context.
686 * @context: pointer to struct lws_context you want set proxy to
shysb4e800e2013-10-24 22:12:03 +0800687 * @proxy: pointer to c string containing proxy in format address:port
688 *
689 * Returns 0 if proxy string was parsed and proxy was setup.
690 * Returns -1 if @proxy is NULL or has incorrect format.
691 *
692 * This is only required if your OS does not provide the http_proxy
Drew Noakesefe10b02014-10-23 15:34:26 +0100693 * environment variable (eg, OSX)
shysb4e800e2013-10-24 22:12:03 +0800694 *
695 * IMPORTANT! You should call this function right after creation of the
Andy Green4b85c1d2015-12-04 11:08:32 +0800696 * lws_context and before call to connect. If you call this
shysb4e800e2013-10-24 22:12:03 +0800697 * function after connect behavior is undefined.
Andy Green4b85c1d2015-12-04 11:08:32 +0800698 * This function will override proxy settings made on lws_context
shysb4e800e2013-10-24 22:12:03 +0800699 * creation with genenv() call.
700 */
701
702LWS_VISIBLE int
Andy Green4b85c1d2015-12-04 11:08:32 +0800703lws_set_proxy(struct lws_context *context, const char *proxy)
shysb4e800e2013-10-24 22:12:03 +0800704{
705 char *p;
Andy Green6e405562015-11-08 10:15:01 +0800706 char authstring[96];
shysb4e800e2013-10-24 22:12:03 +0800707
708 if (!proxy)
709 return -1;
710
Andy Green6e405562015-11-08 10:15:01 +0800711 p = strchr(proxy, '@');
712 if (p) { /* auth is around */
713
Andy Green11f27342015-11-08 12:10:26 +0800714 if ((unsigned int)(p - proxy) > sizeof(authstring) - 1)
Andy Green6e405562015-11-08 10:15:01 +0800715 goto auth_too_long;
716
Andy Greenf2280d62015-11-18 19:32:01 +0800717 strncpy(authstring, proxy, p - proxy);
Andy Green6e405562015-11-08 10:15:01 +0800718 // null termination not needed on input
719 if (lws_b64_encode_string(authstring, (p - proxy),
720 context->proxy_basic_auth_token,
721 sizeof context->proxy_basic_auth_token) < 0)
722 goto auth_too_long;
723
724 lwsl_notice(" Proxy auth in use\n");
725
726 proxy = p + 1;
727 } else
728 context->proxy_basic_auth_token[0] = '\0';
729
shysb4e800e2013-10-24 22:12:03 +0800730 strncpy(context->http_proxy_address, proxy,
731 sizeof(context->http_proxy_address) - 1);
732 context->http_proxy_address[
733 sizeof(context->http_proxy_address) - 1] = '\0';
Andy Green6e405562015-11-08 10:15:01 +0800734
shysb4e800e2013-10-24 22:12:03 +0800735 p = strchr(context->http_proxy_address, ':');
Andy Green6e405562015-11-08 10:15:01 +0800736 if (!p && !context->http_proxy_port) {
shysb4e800e2013-10-24 22:12:03 +0800737 lwsl_err("http_proxy needs to be ads:port\n");
738
739 return -1;
Andy Green6e405562015-11-08 10:15:01 +0800740 } else {
741 *p = '\0';
742 context->http_proxy_port = atoi(p + 1);
shysb4e800e2013-10-24 22:12:03 +0800743 }
Andy Green6e405562015-11-08 10:15:01 +0800744
shysb4e800e2013-10-24 22:12:03 +0800745 lwsl_notice(" Proxy %s:%u\n", context->http_proxy_address,
746 context->http_proxy_port);
747
748 return 0;
Andy Green6e405562015-11-08 10:15:01 +0800749
750auth_too_long:
751 lwsl_err("proxy auth too long\n");
752
753 return -1;
shysb4e800e2013-10-24 22:12:03 +0800754}
755
756/**
Andy Green62304762015-12-04 08:43:54 +0800757 * lws_get_protocol() - Returns a protocol pointer from a websocket
Andy Green8f037e42010-12-19 22:13:26 +0000758 * connection.
Andy Greenb45993c2010-12-18 15:13:50 +0000759 * @wsi: pointer to struct websocket you want to know the protocol of
760 *
Andy Green8f037e42010-12-19 22:13:26 +0000761 *
Andy Green6f520a52013-01-29 17:57:39 +0800762 * Some apis can act on all live connections of a given protocol,
763 * this is how you can get a pointer to the active protocol if needed.
Andy Greenb45993c2010-12-18 15:13:50 +0000764 */
Andy Greenab990e42010-10-31 12:42:52 +0000765
Andy Green4b85c1d2015-12-04 11:08:32 +0800766LWS_VISIBLE const struct lws_protocols *
767lws_get_protocol(struct lws *wsi)
Andy Greenb45993c2010-12-18 15:13:50 +0000768{
769 return wsi->protocol;
770}
771
Peter Pentchev9a4fef72013-03-30 09:52:21 +0800772LWS_VISIBLE int
Andy Green4b85c1d2015-12-04 11:08:32 +0800773lws_is_final_fragment(struct lws *wsi)
Andy Green82c3d542011-03-07 21:16:31 +0000774{
Andy Green623a98d2013-01-21 11:04:23 +0800775 return wsi->u.ws.final;
Andy Green82c3d542011-03-07 21:16:31 +0000776}
Alex Bligh49146db2011-11-07 17:19:25 +0800777
Peter Pentchev9a4fef72013-03-30 09:52:21 +0800778LWS_VISIBLE unsigned char
Andy Green4b85c1d2015-12-04 11:08:32 +0800779lws_get_reserved_bits(struct lws *wsi)
David Galeanoe2cf9922013-01-09 18:06:55 +0800780{
Andy Green623a98d2013-01-21 11:04:23 +0800781 return wsi->u.ws.rsv;
David Galeanoe2cf9922013-01-09 18:06:55 +0800782}
783
Andy Green2af4d5b2013-02-18 16:30:10 +0800784int
Andy Green4b85c1d2015-12-04 11:08:32 +0800785lws_ensure_user_space(struct lws *wsi)
Alex Bligh49146db2011-11-07 17:19:25 +0800786{
Andy Green7df53c52014-10-22 15:37:28 +0800787 lwsl_info("%s: %p protocol %p\n", __func__, wsi, wsi->protocol);
Andy Green67d556c2013-02-15 22:31:55 +0800788 if (!wsi->protocol)
Andy Green2af4d5b2013-02-18 16:30:10 +0800789 return 1;
Andy Green67d556c2013-02-15 22:31:55 +0800790
Alex Bligh49146db2011-11-07 17:19:25 +0800791 /* allocate the per-connection user memory (if any) */
792
793 if (wsi->protocol->per_session_data_size && !wsi->user_space) {
Alejandro Mery6ff28242014-12-04 23:59:35 +0100794 wsi->user_space = lws_zalloc(wsi->protocol->per_session_data_size);
Alex Bligh49146db2011-11-07 17:19:25 +0800795 if (wsi->user_space == NULL) {
Andy Green43db0452013-01-10 19:50:35 +0800796 lwsl_err("Out of memory for conn user space\n");
Andy Green2af4d5b2013-02-18 16:30:10 +0800797 return 1;
Alex Bligh49146db2011-11-07 17:19:25 +0800798 }
Andy Green7df53c52014-10-22 15:37:28 +0800799 } else
800 lwsl_info("%s: %p protocol pss %u, user_space=%d\n", __func__, wsi, wsi->protocol->per_session_data_size, wsi->user_space);
Andy Green2af4d5b2013-02-18 16:30:10 +0800801 return 0;
Alex Bligh49146db2011-11-07 17:19:25 +0800802}
Andy Green43db0452013-01-10 19:50:35 +0800803
Andy Greenb25b85f2014-04-03 23:34:09 +0800804LWS_VISIBLE void lwsl_emit_stderr(int level, const char *line)
Andy Greende8f27a2013-01-12 09:17:42 +0800805{
Andy Green0b319092013-01-19 11:17:56 +0800806 char buf[300];
Patrick Gansterer92792b42014-02-26 21:37:31 +0100807 unsigned long long now;
Andy Green0b319092013-01-19 11:17:56 +0800808 int n;
809
Andy Green0b319092013-01-19 11:17:56 +0800810 buf[0] = '\0';
811 for (n = 0; n < LLL_COUNT; n++)
812 if (level == (1 << n)) {
Patrick Gansterer92792b42014-02-26 21:37:31 +0100813 now = time_in_microseconds() / 100;
Imo Farcher97a748a2015-01-26 15:39:36 +0800814 sprintf(buf, "[%llu:%04d] %s: ", (unsigned long long) now / 10000,
Patrick Gansterer92792b42014-02-26 21:37:31 +0100815 (int)(now % 10000), log_level_names[n]);
Andy Green0b319092013-01-19 11:17:56 +0800816 break;
817 }
Andy Greenb5b23192013-02-11 17:13:32 +0800818
Andy Green0b319092013-01-19 11:17:56 +0800819 fprintf(stderr, "%s%s", buf, line);
Andy Greende8f27a2013-01-12 09:17:42 +0800820}
821
Andy Greenc11db202013-01-19 11:12:16 +0800822
Neal Horman98e491f2014-12-10 18:50:28 -0600823LWS_VISIBLE void _lws_logv(int filter, const char *format, va_list vl)
Andy Green43db0452013-01-10 19:50:35 +0800824{
Andy Greende8f27a2013-01-12 09:17:42 +0800825 char buf[256];
Andy Green43db0452013-01-10 19:50:35 +0800826
827 if (!(log_level & filter))
828 return;
829
Neal Horman98e491f2014-12-10 18:50:28 -0600830 vsnprintf(buf, sizeof(buf), format, vl);
Andy Greenb5b23192013-02-11 17:13:32 +0800831 buf[sizeof(buf) - 1] = '\0';
Andy Greende8f27a2013-01-12 09:17:42 +0800832
Andy Green0b319092013-01-19 11:17:56 +0800833 lwsl_emit(filter, buf);
Andy Green43db0452013-01-10 19:50:35 +0800834}
835
Neal Horman98e491f2014-12-10 18:50:28 -0600836LWS_VISIBLE void _lws_log(int filter, const char *format, ...)
837{
838 va_list ap;
839
840 va_start(ap, format);
841 _lws_logv(filter, format, ap);
842 va_end(ap);
843}
844
Andy Green43db0452013-01-10 19:50:35 +0800845/**
846 * lws_set_log_level() - Set the logging bitfield
847 * @level: OR together the LLL_ debug contexts you want output from
Andy Greende8f27a2013-01-12 09:17:42 +0800848 * @log_emit_function: NULL to leave it as it is, or a user-supplied
849 * function to perform log string emission instead of
850 * the default stderr one.
Andy Green43db0452013-01-10 19:50:35 +0800851 *
Andy Greenc6511a02013-02-19 10:01:48 +0800852 * log level defaults to "err", "warn" and "notice" contexts enabled and
Andy Greende8f27a2013-01-12 09:17:42 +0800853 * emission on stderr.
Andy Green43db0452013-01-10 19:50:35 +0800854 */
855
Peter Pentchev9a4fef72013-03-30 09:52:21 +0800856LWS_VISIBLE void lws_set_log_level(int level, void (*log_emit_function)(int level,
Andy Greenb5b23192013-02-11 17:13:32 +0800857 const char *line))
Andy Green43db0452013-01-10 19:50:35 +0800858{
859 log_level = level;
Andy Greende8f27a2013-01-12 09:17:42 +0800860 if (log_emit_function)
861 lwsl_emit = log_emit_function;
vpeter44dd8ada2014-04-27 13:28:22 +0200862}
Andy Greenb128ccc2014-08-16 09:54:27 +0800863
864/**
865 * lws_use_ssl() - Find out if connection is using SSL
866 * @wsi: websocket connection to check
867 *
868 * Returns 0 if the connection is not using SSL, 1 if using SSL and
869 * using verified cert, and 2 if using SSL but the cert was not
870 * checked (appears for client wsi told to skip check on connection)
871 */
872LWS_VISIBLE int
Andy Green4b85c1d2015-12-04 11:08:32 +0800873lws_is_ssl(struct lws *wsi)
Andy Greenb128ccc2014-08-16 09:54:27 +0800874{
Andy Greenfc9871e2014-08-19 08:41:26 +0800875#ifdef LWS_OPENSSL_SUPPORT
Andy Greenb128ccc2014-08-16 09:54:27 +0800876 return wsi->use_ssl;
Andy Greenfc9871e2014-08-19 08:41:26 +0800877#else
Andy Green2cd30742015-11-02 13:10:33 +0800878 (void)wsi;
Andy Greenfc9871e2014-08-19 08:41:26 +0800879 return 0;
880#endif
Andy Greenb128ccc2014-08-16 09:54:27 +0800881}
Andy Green14425ea2014-08-18 22:49:39 +0800882
883/**
884 * lws_partial_buffered() - find out if lws buffered the last write
885 * @wsi: websocket connection to check
886 *
Andy Green62304762015-12-04 08:43:54 +0800887 * Returns 1 if you cannot use lws_write because the last
Andy Green14425ea2014-08-18 22:49:39 +0800888 * write on this connection is still buffered, and can't be cleared without
889 * returning to the service loop and waiting for the connection to be
890 * writeable again.
891 *
Andy Green62304762015-12-04 08:43:54 +0800892 * If you will try to do >1 lws_write call inside a single
Andy Green14425ea2014-08-18 22:49:39 +0800893 * WRITEABLE callback, you must check this after every write and bail if
894 * set, ask for a new writeable callback and continue writing from there.
895 *
896 * This is never set at the start of a writeable callback, but any write
897 * may set it.
898 */
899
900LWS_VISIBLE int
Andy Green4b85c1d2015-12-04 11:08:32 +0800901lws_partial_buffered(struct lws *wsi)
Andy Green14425ea2014-08-18 22:49:39 +0800902{
903 return !!wsi->truncated_send_len;
904}
Andy Green024eb6c2014-10-08 12:00:53 +0800905
Andy Green4b85c1d2015-12-04 11:08:32 +0800906void lws_set_protocol_write_pending(struct lws_context *context,
907 struct lws *wsi,
Andy Green024eb6c2014-10-08 12:00:53 +0800908 enum lws_pending_protocol_send pend)
909{
Andy Green97ee57f2014-10-29 09:39:08 +0800910 lwsl_info("setting pps %d\n", pend);
Andy Green024eb6c2014-10-08 12:00:53 +0800911
912 if (wsi->pps)
913 lwsl_err("pps overwrite\n");
914 wsi->pps = pend;
Andy Green62304762015-12-04 08:43:54 +0800915 lws_rx_flow_control(wsi, 0);
916 lws_callback_on_writable(context, wsi);
Andy Green260a0fc2014-10-18 18:52:39 +0800917}
Andy Green97ee57f2014-10-29 09:39:08 +0800918
919LWS_VISIBLE size_t
Andy Green4b85c1d2015-12-04 11:08:32 +0800920lws_get_peer_write_allowance(struct lws *wsi)
Andy Green97ee57f2014-10-29 09:39:08 +0800921{
922#ifdef LWS_USE_HTTP2
923 /* only if we are using HTTP2 on this connection */
924 if (wsi->mode != LWS_CONNMODE_HTTP2_SERVING)
925 return -1;
926 /* user is only interested in how much he can send, or that he can't */
927 if (wsi->u.http2.tx_credit <= 0)
928 return 0;
929
930 return wsi->u.http2.tx_credit;
931#else
Andy Green2cd30742015-11-02 13:10:33 +0800932 (void)wsi;
Andy Green97ee57f2014-10-29 09:39:08 +0800933 return -1;
934#endif
935}
Andy Green44c11612014-11-08 11:18:47 +0800936
937LWS_VISIBLE void
Andy Green4b85c1d2015-12-04 11:08:32 +0800938lws_union_transition(struct lws *wsi, enum connection_mode mode)
Andy Green44c11612014-11-08 11:18:47 +0800939{
940 memset(&wsi->u, 0, sizeof(wsi->u));
941 wsi->mode = mode;
942}
Andy Green6d417202015-12-04 10:39:23 +0800943
944
945#ifdef LWS_WITH_OLD_API_WRAPPERS
946
947/*
948 * To maintain .so abi, also produce wrappers using old api naming.
949 *
950 * This is disabled by default, use "LWS_WITH_OLD_API_WRAPPERS" on cmake to
951 * enable.
952 *
953 * You only need these if you have existing binary applications using the old
954 * api names and you don't want to / can't recompile them against new lws.
955 * With these new lws .so is compatible with old and new api names.
956 *
957 * If you can recompile your application (using old api names still) against
958 * current lws, you don't need these compatibility helpers since
959 * libwebsockets.h will map them at compile time.
960 */
961
Andy Green4b85c1d2015-12-04 11:08:32 +0800962#undef libwebsocket
963
Andy Green6d417202015-12-04 10:39:23 +0800964#undef libwebsocket_create_context
Andy Green4b85c1d2015-12-04 11:08:32 +0800965LWS_VISIBLE LWS_EXTERN struct lws_context *
Andy Green6d417202015-12-04 10:39:23 +0800966libwebsocket_create_context(struct lws_context_creation_info *info)
967{
968 return lws_create_context(info);
969}
970
971#undef libwebsocket_set_proxy
972LWS_VISIBLE LWS_EXTERN int
Andy Green4b85c1d2015-12-04 11:08:32 +0800973libwebsocket_set_proxy(struct lws_context *context, const char *proxy)
Andy Green6d417202015-12-04 10:39:23 +0800974{
975 return lws_set_proxy(context, proxy);
976}
977
Andy Green4b85c1d2015-12-04 11:08:32 +0800978#undef lws_context_destroy
Andy Green6d417202015-12-04 10:39:23 +0800979LWS_VISIBLE LWS_EXTERN void
Andy Green4b85c1d2015-12-04 11:08:32 +0800980libwebsocket_context_destroy(struct lws_context *context)
Andy Green6d417202015-12-04 10:39:23 +0800981{
982 lws_context_destroy(context);
983}
984
985#undef libwebsocket_service
986LWS_VISIBLE LWS_EXTERN int
Andy Green4b85c1d2015-12-04 11:08:32 +0800987libwebsocket_service(struct lws_context *context, int timeout_ms)
Andy Green6d417202015-12-04 10:39:23 +0800988{
989 return lws_service(context, timeout_ms);
990}
991
992#undef libwebsocket_cancel_service
993LWS_VISIBLE LWS_EXTERN void
Andy Green4b85c1d2015-12-04 11:08:32 +0800994libwebsocket_cancel_service(struct lws_context *context)
Andy Green6d417202015-12-04 10:39:23 +0800995{
996 lws_cancel_service(context);
997}
998
999#ifdef LWS_USE_LIBEV
1000#undef libwebsocket_sigint_cfg
1001LWS_VISIBLE LWS_EXTERN int
1002libwebsocket_sigint_cfg(
Andy Green4b85c1d2015-12-04 11:08:32 +08001003 struct lws_context *context,
Andy Green6d417202015-12-04 10:39:23 +08001004 int use_ev_sigint,
1005 lws_ev_signal_cb* cb)
1006{
1007 return lws_sigint_cfg(context, use_ev_sigint, cb);
1008}
1009
1010#undef libwebsocket_initloop
1011LWS_VISIBLE LWS_EXTERN int
Andy Green4b85c1d2015-12-04 11:08:32 +08001012libwebsocket_initloop(struct lws_context *context, struct ev_loop *loop)
Andy Green6d417202015-12-04 10:39:23 +08001013{
1014 return lws_initloop(context, loop);
1015}
1016
1017#undef libwebsocket_sigint_cb
1018LWS_VISIBLE void
1019libwebsocket_sigint_cb(
1020 struct ev_loop *loop, struct ev_signal *watcher, int revents)
1021{
1022 lws_sigint_cb(loop, watcher, revents);
1023}
1024#endif /* LWS_USE_LIBEV */
1025
1026#undef libwebsocket_service_fd
1027LWS_VISIBLE LWS_EXTERN int
Andy Green4b85c1d2015-12-04 11:08:32 +08001028libwebsocket_service_fd(struct lws_context *context,
1029 struct lws_pollfd *pollfd)
Andy Green6d417202015-12-04 10:39:23 +08001030{
1031 return lws_service_fd(context, pollfd);
1032}
1033
Andy Green4b85c1d2015-12-04 11:08:32 +08001034#undef lws_context_user
Andy Green6d417202015-12-04 10:39:23 +08001035LWS_VISIBLE LWS_EXTERN void *
Andy Green4b85c1d2015-12-04 11:08:32 +08001036libwebsocket_context_user(struct lws_context *context)
Andy Green6d417202015-12-04 10:39:23 +08001037{
1038 return lws_context_user(context);
1039}
1040
1041#undef libwebsocket_set_timeout
1042LWS_VISIBLE LWS_EXTERN void
Andy Green4b85c1d2015-12-04 11:08:32 +08001043libwebsocket_set_timeout(struct lws *wsi,
Andy Green6d417202015-12-04 10:39:23 +08001044 enum pending_timeout reason, int secs)
1045{
1046 lws_set_timeout(wsi, reason, secs);
1047}
1048
1049#undef libwebsocket_write
1050LWS_VISIBLE LWS_EXTERN int
Andy Green4b85c1d2015-12-04 11:08:32 +08001051libwebsocket_write(struct lws *wsi, unsigned char *buf, size_t len,
Andy Green6d417202015-12-04 10:39:23 +08001052 enum lws_write_protocol protocol)
1053{
1054 return lws_write(wsi, buf, len, protocol);
1055}
1056
1057#undef libwebsockets_serve_http_file_fragment
1058LWS_VISIBLE LWS_EXTERN int
Andy Green4b85c1d2015-12-04 11:08:32 +08001059libwebsockets_serve_http_file_fragment(struct lws_context *context,
1060 struct lws *wsi)
Andy Green6d417202015-12-04 10:39:23 +08001061{
1062 return lws_serve_http_file_fragment(context, wsi);
1063}
1064
1065#undef libwebsockets_serve_http_file
1066LWS_VISIBLE LWS_EXTERN int
Andy Green4b85c1d2015-12-04 11:08:32 +08001067libwebsockets_serve_http_file(struct lws_context *context,
1068 struct lws *wsi, const char *file,
Andy Green6d417202015-12-04 10:39:23 +08001069 const char *content_type, const char *other_headers,
1070 int other_headers_len)
1071{
1072 return lws_serve_http_file(context, wsi, file, content_type,
1073 other_headers, other_headers_len);
1074}
1075
1076#undef libwebsockets_return_http_status
1077LWS_VISIBLE LWS_EXTERN int
1078libwebsockets_return_http_status(
Andy Green4b85c1d2015-12-04 11:08:32 +08001079 struct lws_context *context,
1080 struct lws *wsi, unsigned int code,
Andy Green6d417202015-12-04 10:39:23 +08001081 const char *html_body)
1082{
1083 return lws_return_http_status(context, wsi, code, html_body);
1084}
1085
1086#undef libwebsockets_get_protocol
Andy Green4b85c1d2015-12-04 11:08:32 +08001087LWS_VISIBLE LWS_EXTERN const struct lws_protocols *
1088libwebsockets_get_protocol(struct lws *wsi)
Andy Green6d417202015-12-04 10:39:23 +08001089{
1090 return lws_get_protocol(wsi);
1091}
1092
1093#undef libwebsocket_callback_on_writable_all_protocol
1094LWS_VISIBLE LWS_EXTERN int
1095libwebsocket_callback_on_writable_all_protocol(
Andy Green4b85c1d2015-12-04 11:08:32 +08001096 const struct lws_protocols *protocol)
Andy Green6d417202015-12-04 10:39:23 +08001097{
1098 return lws_callback_on_writable_all_protocol(protocol);
1099}
1100
1101#undef libwebsocket_callback_on_writable
1102LWS_VISIBLE LWS_EXTERN int
Andy Green4b85c1d2015-12-04 11:08:32 +08001103libwebsocket_callback_on_writable(struct lws_context *context,
1104 struct lws *wsi)
Andy Green6d417202015-12-04 10:39:23 +08001105{
1106 return lws_callback_on_writable(context, wsi);
1107}
1108
1109#undef libwebsocket_callback_all_protocol
1110LWS_VISIBLE LWS_EXTERN int
1111libwebsocket_callback_all_protocol(
Andy Green4b85c1d2015-12-04 11:08:32 +08001112 const struct lws_protocols *protocol, int reason)
Andy Green6d417202015-12-04 10:39:23 +08001113{
1114 return lws_callback_all_protocol(protocol, reason);
1115}
1116
1117#undef libwebsocket_get_socket_fd
1118LWS_VISIBLE LWS_EXTERN int
Andy Green4b85c1d2015-12-04 11:08:32 +08001119libwebsocket_get_socket_fd(struct lws *wsi)
Andy Green6d417202015-12-04 10:39:23 +08001120{
1121 return lws_get_socket_fd(wsi);
1122}
1123
1124#undef libwebsocket_is_final_fragment
1125LWS_VISIBLE LWS_EXTERN int
Andy Green4b85c1d2015-12-04 11:08:32 +08001126libwebsocket_is_final_fragment(struct lws *wsi)
Andy Green6d417202015-12-04 10:39:23 +08001127{
1128 return lws_is_final_fragment(wsi);
1129}
1130
1131#undef libwebsocket_get_reserved_bits
1132LWS_VISIBLE LWS_EXTERN unsigned char
Andy Green4b85c1d2015-12-04 11:08:32 +08001133libwebsocket_get_reserved_bits(struct lws *wsi)
Andy Green6d417202015-12-04 10:39:23 +08001134{
1135 return lws_get_reserved_bits(wsi);
1136}
1137
1138#undef libwebsocket_rx_flow_control
1139LWS_VISIBLE LWS_EXTERN int
Andy Green4b85c1d2015-12-04 11:08:32 +08001140libwebsocket_rx_flow_control(struct lws *wsi, int enable)
Andy Green6d417202015-12-04 10:39:23 +08001141{
1142 return lws_rx_flow_control(wsi, enable);
1143}
1144
1145#undef libwebsocket_rx_flow_allow_all_protocol
1146LWS_VISIBLE LWS_EXTERN void
Andy Green4b85c1d2015-12-04 11:08:32 +08001147libwebsocket_rx_flow_allow_all_protocol(const struct lws_protocols *protocol)
Andy Green6d417202015-12-04 10:39:23 +08001148{
1149 lws_rx_flow_allow_all_protocol(protocol);
1150}
1151
1152#undef libwebsockets_remaining_packet_payload
1153LWS_VISIBLE LWS_EXTERN size_t
Andy Green4b85c1d2015-12-04 11:08:32 +08001154libwebsockets_remaining_packet_payload(struct lws *wsi)
Andy Green6d417202015-12-04 10:39:23 +08001155{
1156 return lws_remaining_packet_payload(wsi);
1157}
1158
1159#undef libwebsocket_client_connect
Andy Green4b85c1d2015-12-04 11:08:32 +08001160LWS_VISIBLE LWS_EXTERN struct lws *
1161libwebsocket_client_connect(struct lws_context *clients,
Andy Green6d417202015-12-04 10:39:23 +08001162 const char *address,
1163 int port,
1164 int ssl_connection,
1165 const char *path,
1166 const char *host,
1167 const char *origin,
1168 const char *protocol,
1169 int ietf_version_or_minus_one)
1170{
1171 return lws_client_connect(clients, address, port, ssl_connection,
1172 path, host, origin, protocol, ietf_version_or_minus_one);
1173}
Andy Green4b85c1d2015-12-04 11:08:32 +08001174LWS_VISIBLE LWS_EXTERN struct lws *
1175libwebsocket_client_connect_extended(struct lws_context *clients,
Andy Green6d417202015-12-04 10:39:23 +08001176 const char *address,
1177 int port,
1178 int ssl_connection,
1179 const char *path,
1180 const char *host,
1181 const char *origin,
1182 const char *protocol,
1183 int ietf_version_or_minus_one, void *userdata)
1184{
1185 return lws_client_connect_extended(clients, address, port, ssl_connection,
1186 path, host, origin, protocol, ietf_version_or_minus_one,
1187 userdata);
1188}
1189
1190#undef libwebsocket_canonical_hostname
1191LWS_VISIBLE LWS_EXTERN const char *
Andy Green4b85c1d2015-12-04 11:08:32 +08001192libwebsocket_canonical_hostname(struct lws_context *context)
Andy Green6d417202015-12-04 10:39:23 +08001193{
1194 return lws_canonical_hostname(context);
1195}
1196
1197#undef libwebsockets_get_peer_addresses
1198LWS_VISIBLE LWS_EXTERN void
Andy Green4b85c1d2015-12-04 11:08:32 +08001199libwebsockets_get_peer_addresses(struct lws_context *context,
1200 struct lws *wsi, lws_sockfd_type fd, char *name,
Andy Green6d417202015-12-04 10:39:23 +08001201 int name_len, char *rip, int rip_len)
1202{
1203 lws_get_peer_addresses(context, wsi, fd, name, name_len, rip, rip_len);
1204}
1205
1206#undef libwebsockets_get_random
1207LWS_VISIBLE LWS_EXTERN int
Andy Green4b85c1d2015-12-04 11:08:32 +08001208libwebsockets_get_random(struct lws_context *context, void *buf, int len)
Andy Green6d417202015-12-04 10:39:23 +08001209{
1210 return lws_get_random(context, buf, len);
1211}
1212
1213#ifndef LWS_SHA1_USE_OPENSSL_NAME
1214#undef libwebsockets_SHA1
1215LWS_VISIBLE LWS_EXTERN unsigned char *
1216libwebsockets_SHA1(const unsigned char *d, size_t n, unsigned char *md)
1217{
1218 return lws_SHA1(d, n, md);
1219}
1220#endif
1221
1222#undef libwebsocket_read
1223LWS_VISIBLE LWS_EXTERN int
Andy Green4b85c1d2015-12-04 11:08:32 +08001224libwebsocket_read(struct lws_context *context, struct lws *wsi,
Andy Green6d417202015-12-04 10:39:23 +08001225 unsigned char *buf, size_t len)
1226{
1227 return lws_read(context, wsi, buf, len);
1228}
1229
1230#ifndef LWS_NO_EXTENSIONS
1231#undef libwebsocket_get_internal_extensions
Andy Green4b85c1d2015-12-04 11:08:32 +08001232LWS_VISIBLE LWS_EXTERN struct lws_extension *
Andy Green6d417202015-12-04 10:39:23 +08001233libwebsocket_get_internal_extensions()
1234{
1235 return lws_get_internal_extensions();
1236}
1237#endif
1238
1239#endif
1240