blob: 7836f901bd8031aae157ea3956a401d5604f92b5 [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 Greena0da8a82010-11-08 17:12:19 +00004 * Copyright (C) 2010 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
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
Peter Hinz56885f32011-03-02 22:03:47 +000024#ifdef WIN32
David Galeanocb193682013-01-09 15:29:00 +080025#include <tchar.h>
26#include <io.h>
Peter Hinz56885f32011-03-02 22:03:47 +000027#else
Davidc4ef7b12013-01-12 20:39:47 +080028#ifdef LWS_BUILTIN_GETIFADDRS
29#include <getifaddrs.h>
30#else
Peter Hinz56885f32011-03-02 22:03:47 +000031#include <ifaddrs.h>
Davidc4ef7b12013-01-12 20:39:47 +080032#endif
Joakim Soderberg4c531232013-02-06 15:26:58 +090033#include <syslog.h>
Andy Green7627af52011-03-09 15:13:52 +000034#include <sys/un.h>
Andy Greena69f0512012-05-03 12:32:38 +080035#include <sys/socket.h>
36#include <netdb.h>
Peter Hinz56885f32011-03-02 22:03:47 +000037#endif
Andy Green2e24da02011-03-05 16:12:04 +000038
39#ifdef LWS_OPENSSL_SUPPORT
40int openssl_websocket_private_data_index;
41#endif
42
Andy Greenaa6fc442012-04-12 13:26:49 +080043#ifdef __MINGW32__
44#include "../win32port/win32helpers/websock-w32.c"
45#else
46#ifdef __MINGW64__
47#include "../win32port/win32helpers/websock-w32.c"
48#endif
49#endif
50
Andy Green7b405452013-02-01 10:50:15 +080051#ifndef LWS_BUILD_HASH
52#define LWS_BUILD_HASH "unknown-build-hash"
53#endif
Andy Green3182ece2013-01-20 17:08:31 +080054
Andy Green7c19c342013-01-19 12:18:07 +080055static int log_level = LLL_ERR | LLL_WARN | LLL_NOTICE;
Andy Green058ba812013-01-19 11:32:18 +080056static void lwsl_emit_stderr(int level, const char *line);
57static void (*lwsl_emit)(int level, const char *line) = lwsl_emit_stderr;
58
Andy Green7b405452013-02-01 10:50:15 +080059static const char *library_version = LWS_LIBRARY_VERSION " " LWS_BUILD_HASH;
60
Andy Green43db0452013-01-10 19:50:35 +080061static const char *log_level_names[] = {
62 "ERR",
63 "WARN",
Andy Green7c19c342013-01-19 12:18:07 +080064 "NOTICE",
Andy Green43db0452013-01-10 19:50:35 +080065 "INFO",
66 "DEBUG",
67 "PARSER",
68 "HEADER",
69 "EXTENSION",
70 "CLIENT",
Andy Greend636e352013-01-29 12:36:17 +080071 "LATENCY",
Andy Green43db0452013-01-10 19:50:35 +080072};
73
Andy Green7b405452013-02-01 10:50:15 +080074/**
75 * lws_get_library_version: get version and git hash library built from
76 *
77 * returns a const char * to a string like "1.1 178d78c"
78 * representing the library version followed by the git head hash it
79 * was built from
80 */
81
82const char *
83lws_get_library_version(void)
84{
85 return library_version;
86}
87
Andy Green0d338332011-02-12 11:57:43 +000088int
Andy Greendfb23042013-01-17 12:26:48 +080089insert_wsi_socket_into_fds(struct libwebsocket_context *context, struct libwebsocket *wsi)
Andy Green0d338332011-02-12 11:57:43 +000090{
Andy Greendfb23042013-01-17 12:26:48 +080091 if (context->fds_count >= context->max_fds) {
92 lwsl_err("Reached limit of fds tracking (%d)\n", context->max_fds);
Andy Green0d338332011-02-12 11:57:43 +000093 return 1;
94 }
95
Andy Greendfb23042013-01-17 12:26:48 +080096 if (wsi->sock > context->max_fds) {
97 lwsl_err("Socket fd %d is beyond what we can index (%d)\n", wsi->sock, context->max_fds);
98 return 1;
99 }
100
101 assert(wsi);
102 assert(wsi->sock);
103
104 lwsl_info("insert_wsi_socket_into_fds: wsi=%p, sock=%d, fds pos=%d\n", wsi, wsi->sock, context->fds_count);
105
106 context->lws_lookup[wsi->sock] = wsi;
107 wsi->position_in_fds_table = context->fds_count;
108 context->fds[context->fds_count].fd = wsi->sock;
109 context->fds[context->fds_count].events = POLLIN;
110 context->fds[context->fds_count++].revents = 0;
111
112 /* external POLL support via protocol 0 */
113 context->protocols[0].callback(context, wsi,
114 LWS_CALLBACK_ADD_POLL_FD,
115 (void *)(long)wsi->sock, NULL, POLLIN);
Andy Green0d338332011-02-12 11:57:43 +0000116
117 return 0;
118}
119
Andy Greendfb23042013-01-17 12:26:48 +0800120static int
121remove_wsi_socket_from_fds(struct libwebsocket_context *context, struct libwebsocket *wsi)
Andy Green0d338332011-02-12 11:57:43 +0000122{
Andy Greendfb23042013-01-17 12:26:48 +0800123 int m;
Andy Green0d338332011-02-12 11:57:43 +0000124
Andy Greendfb23042013-01-17 12:26:48 +0800125 if (!--context->fds_count)
126 goto do_ext;
Andy Green0d338332011-02-12 11:57:43 +0000127
Andy Greendfb23042013-01-17 12:26:48 +0800128 if (wsi->sock > context->max_fds) {
129 lwsl_err("Socket fd %d is beyond what we can index (%d)\n", wsi->sock, context->max_fds);
130 return 1;
131 }
Andy Green0d338332011-02-12 11:57:43 +0000132
Andy Greendfb23042013-01-17 12:26:48 +0800133 lwsl_info("remove_wsi_socket_from_fds: wsi=%p, sock=%d, fds pos=%d\n", wsi, wsi->sock, wsi->position_in_fds_table);
134
135 m = wsi->position_in_fds_table; /* replace the contents for this */
136
137 /* have the last guy take up the vacant slot */
138 context->fds[m] = context->fds[context->fds_count]; /* vacant fds slot filled with end one */
139 /* end guy's fds_lookup entry remains unchanged (still same fd pointing to same wsi) */
140 /* end guy's "position in fds table" changed */
141 context->lws_lookup[context->fds[context->fds_count].fd]->position_in_fds_table = m;
142 /* deletion guy's lws_lookup entry needs nuking */
143 context->lws_lookup[wsi->sock] = NULL; /* no WSI for the socket of the wsi being removed*/
144 wsi->position_in_fds_table = -1; /* removed wsi has no position any more */
145
146do_ext:
147 /* remove also from external POLL support via protocol 0 */
148 if (wsi->sock)
149 context->protocols[0].callback(context, wsi,
150 LWS_CALLBACK_DEL_POLL_FD, (void *)(long)wsi->sock, NULL, 0);
151
152 return 0;
Andy Green0d338332011-02-12 11:57:43 +0000153}
154
Andy Green32375b72011-02-19 08:32:53 +0000155
Andy Green8f037e42010-12-19 22:13:26 +0000156void
Peter Hinz56885f32011-03-02 22:03:47 +0000157libwebsocket_close_and_free_session(struct libwebsocket_context *context,
Andy Green687b0182011-02-26 11:04:01 +0000158 struct libwebsocket *wsi, enum lws_close_status reason)
Andy Green251f6fa2010-11-03 11:13:06 +0000159{
Andy Greenb45993c2010-12-18 15:13:50 +0000160 int n;
Andy Green62c54d22011-02-14 09:14:25 +0000161 int old_state;
Andy Green5e1fa172011-02-10 09:07:05 +0000162 unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 +
163 LWS_SEND_BUFFER_POST_PADDING];
Andy Green3182ece2013-01-20 17:08:31 +0800164#ifndef LWS_NO_EXTENSIONS
Andy Greenc44159f2011-03-07 07:08:18 +0000165 int ret;
166 int m;
167 struct lws_tokens eff_buf;
Andy Greena41314f2011-05-23 10:00:03 +0100168 struct libwebsocket_extension *ext;
Andy Green3182ece2013-01-20 17:08:31 +0800169#endif
Andy Greenb45993c2010-12-18 15:13:50 +0000170
Andy Green4b6fbe12011-02-14 08:03:48 +0000171 if (!wsi)
Andy Greenb45993c2010-12-18 15:13:50 +0000172 return;
173
Andy Green62c54d22011-02-14 09:14:25 +0000174 old_state = wsi->state;
Andy Green251f6fa2010-11-03 11:13:06 +0000175
Andy Green62c54d22011-02-14 09:14:25 +0000176 if (old_state == WSI_STATE_DEAD_SOCKET)
Andy Green5e1fa172011-02-10 09:07:05 +0000177 return;
178
Andy Green623a98d2013-01-21 11:04:23 +0800179 wsi->u.ws.close_reason = reason;
Andy Greenda527df2011-03-07 07:08:12 +0000180
Andy Green3182ece2013-01-20 17:08:31 +0800181#ifndef LWS_NO_EXTENSIONS
Andy Greenda527df2011-03-07 07:08:12 +0000182 /*
Andy Green68b45042011-05-25 21:41:57 +0100183 * are his extensions okay with him closing? Eg he might be a mux
184 * parent and just his ch1 aspect is closing?
185 */
186
Andy Green68b45042011-05-25 21:41:57 +0100187 for (n = 0; n < wsi->count_active_extensions; n++) {
188 if (!wsi->active_extensions[n]->callback)
189 continue;
190
191 m = wsi->active_extensions[n]->callback(context,
192 wsi->active_extensions[n], wsi,
193 LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE,
194 wsi->active_extensions_user[n], NULL, 0);
195
196 /*
197 * if somebody vetoed actually closing him at this time....
198 * up to the extension to track the attempted close, let's
199 * just bail
200 */
201
202 if (m) {
Andy Green43db0452013-01-10 19:50:35 +0800203 lwsl_ext("extension vetoed close\n");
Andy Green68b45042011-05-25 21:41:57 +0100204 return;
205 }
206 }
207
Andy Green68b45042011-05-25 21:41:57 +0100208 /*
Andy Greenc44159f2011-03-07 07:08:18 +0000209 * flush any tx pending from extensions, since we may send close packet
210 * if there are problems with send, just nuke the connection
211 */
212
213 ret = 1;
214 while (ret == 1) {
215
216 /* default to nobody has more to spill */
217
218 ret = 0;
219 eff_buf.token = NULL;
220 eff_buf.token_len = 0;
221
222 /* show every extension the new incoming data */
223
224 for (n = 0; n < wsi->count_active_extensions; n++) {
225 m = wsi->active_extensions[n]->callback(
Andy Green46c2ea02011-03-22 09:04:01 +0000226 wsi->protocol->owning_server,
227 wsi->active_extensions[n], wsi,
Andy Greenc44159f2011-03-07 07:08:18 +0000228 LWS_EXT_CALLBACK_FLUSH_PENDING_TX,
229 wsi->active_extensions_user[n], &eff_buf, 0);
230 if (m < 0) {
Andy Green43db0452013-01-10 19:50:35 +0800231 lwsl_ext("Extension reports fatal error\n");
Andy Greenc44159f2011-03-07 07:08:18 +0000232 goto just_kill_connection;
233 }
234 if (m)
235 /*
236 * at least one extension told us he has more
237 * to spill, so we will go around again after
238 */
239 ret = 1;
240 }
241
242 /* assuming they left us something to send, send it */
243
244 if (eff_buf.token_len)
245 if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
Andy Green0303db42013-01-17 14:46:43 +0800246 eff_buf.token_len)) {
247 lwsl_debug("close: sending final extension spill had problems\n");
Andy Greenc44159f2011-03-07 07:08:18 +0000248 goto just_kill_connection;
Andy Green0303db42013-01-17 14:46:43 +0800249 }
Andy Greenc44159f2011-03-07 07:08:18 +0000250 }
Andy Green3182ece2013-01-20 17:08:31 +0800251#endif
Andy Greenc44159f2011-03-07 07:08:18 +0000252
253 /*
Andy Greenda527df2011-03-07 07:08:12 +0000254 * signal we are closing, libsocket_write will
255 * add any necessary version-specific stuff. If the write fails,
256 * no worries we are closing anyway. If we didn't initiate this
257 * close, then our state has been changed to
258 * WSI_STATE_RETURNED_CLOSE_ALREADY and we will skip this.
259 *
260 * Likewise if it's a second call to close this connection after we
261 * sent the close indication to the peer already, we are in state
262 * WSI_STATE_AWAITING_CLOSE_ACK and will skip doing this a second time.
263 */
264
265 if (old_state == WSI_STATE_ESTABLISHED &&
266 reason != LWS_CLOSE_STATUS_NOSTATUS) {
Andy Green66a16f32011-05-24 22:07:45 +0100267
Andy Green43db0452013-01-10 19:50:35 +0800268 lwsl_debug("sending close indication...\n");
Andy Green66a16f32011-05-24 22:07:45 +0100269
Andy Greenda527df2011-03-07 07:08:12 +0000270 n = libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING],
271 0, LWS_WRITE_CLOSE);
272 if (!n) {
273 /*
274 * we have sent a nice protocol level indication we
275 * now wish to close, we should not send anything more
276 */
277
278 wsi->state = WSI_STATE_AWAITING_CLOSE_ACK;
279
Andy Green0303db42013-01-17 14:46:43 +0800280 /* and we should wait for a reply for a bit out of politeness */
Andy Greenda527df2011-03-07 07:08:12 +0000281
282 libwebsocket_set_timeout(wsi,
Andy Green0303db42013-01-17 14:46:43 +0800283 PENDING_TIMEOUT_CLOSE_ACK, 1);
Andy Greenda527df2011-03-07 07:08:12 +0000284
Andy Green43db0452013-01-10 19:50:35 +0800285 lwsl_debug("sent close indication, awaiting ack\n");
Andy Greenda527df2011-03-07 07:08:12 +0000286
287 return;
288 }
289
Andy Green0303db42013-01-17 14:46:43 +0800290 lwsl_info("close: sending the close packet failed, hanging up\n");
291
Andy Greenda527df2011-03-07 07:08:12 +0000292 /* else, the send failed and we should just hang up */
293 }
294
Andy Green3182ece2013-01-20 17:08:31 +0800295#ifndef LWS_NO_EXTENSIONS
Andy Greenc44159f2011-03-07 07:08:18 +0000296just_kill_connection:
Andy Green3182ece2013-01-20 17:08:31 +0800297#endif
Andy Green66a16f32011-05-24 22:07:45 +0100298
Andy Green43db0452013-01-10 19:50:35 +0800299 lwsl_debug("libwebsocket_close_and_free_session: just_kill_connection\n");
Andy Green66a16f32011-05-24 22:07:45 +0100300
Andy Greenda527df2011-03-07 07:08:12 +0000301 /*
302 * we won't be servicing or receiving anything further from this guy
Andy Greendfb23042013-01-17 12:26:48 +0800303 * delete socket from the internal poll list if still present
Andy Greenda527df2011-03-07 07:08:12 +0000304 */
Andy Green4b6fbe12011-02-14 08:03:48 +0000305
Andy Greendfb23042013-01-17 12:26:48 +0800306 remove_wsi_socket_from_fds(context, wsi);
Andy Green4b6fbe12011-02-14 08:03:48 +0000307
Andy Green251f6fa2010-11-03 11:13:06 +0000308 wsi->state = WSI_STATE_DEAD_SOCKET;
309
Andy Green4b6fbe12011-02-14 08:03:48 +0000310 /* tell the user it's all over for this guy */
311
Andy Greend4302732011-02-28 07:45:29 +0000312 if (wsi->protocol && wsi->protocol->callback &&
Andy Green6ee372f2012-04-09 15:09:01 +0800313 ((old_state == WSI_STATE_ESTABLISHED) ||
314 (old_state == WSI_STATE_RETURNED_CLOSE_ALREADY) ||
315 (old_state == WSI_STATE_AWAITING_CLOSE_ACK))) {
Andy Green43db0452013-01-10 19:50:35 +0800316 lwsl_debug("calling back CLOSED\n");
Peter Hinz56885f32011-03-02 22:03:47 +0000317 wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLOSED,
Andy Greene77ddd82010-11-13 10:03:47 +0000318 wsi->user_space, NULL, 0);
Andy Greencc012472011-11-07 19:53:23 +0800319 } else
Andy Green43db0452013-01-10 19:50:35 +0800320 lwsl_debug("not calling back closed, old_state=%d\n", old_state);
Andy Green251f6fa2010-11-03 11:13:06 +0000321
Andy Green3182ece2013-01-20 17:08:31 +0800322#ifndef LWS_NO_EXTENSIONS
Andy Greenef660a92011-03-06 10:29:38 +0000323 /* deallocate any active extension contexts */
324
325 for (n = 0; n < wsi->count_active_extensions; n++) {
326 if (!wsi->active_extensions[n]->callback)
327 continue;
328
Andy Green46c2ea02011-03-22 09:04:01 +0000329 wsi->active_extensions[n]->callback(context,
330 wsi->active_extensions[n], wsi,
331 LWS_EXT_CALLBACK_DESTROY,
332 wsi->active_extensions_user[n], NULL, 0);
Andy Greenef660a92011-03-06 10:29:38 +0000333
334 free(wsi->active_extensions_user[n]);
335 }
336
Andy Greena41314f2011-05-23 10:00:03 +0100337 /*
338 * inform all extensions in case they tracked this guy out of band
339 * even though not active on him specifically
340 */
341
342 ext = context->extensions;
343 while (ext && ext->callback) {
344 ext->callback(context, ext, wsi,
345 LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING,
346 NULL, NULL, 0);
347 ext++;
348 }
Andy Green3182ece2013-01-20 17:08:31 +0800349#endif
Andy Greena41314f2011-05-23 10:00:03 +0100350
Andy Greena1ce6be2013-01-18 11:43:21 +0800351#ifndef LWS_NO_CLIENT
Andy Greena41314f2011-05-23 10:00:03 +0100352 if (wsi->c_address)
353 free(wsi->c_address);
Andy Greena1ce6be2013-01-18 11:43:21 +0800354#endif
Andy Green623a98d2013-01-21 11:04:23 +0800355 if (wsi->u.ws.rxflow_buffer)
356 free(wsi->u.ws.rxflow_buffer);
Andy Green706961d2013-01-17 16:50:35 +0800357
Andy Green43db0452013-01-10 19:50:35 +0800358/* lwsl_info("closing fd=%d\n", wsi->sock); */
Andy Green251f6fa2010-11-03 11:13:06 +0000359
Andy Green3faa9c72010-11-08 17:03:03 +0000360#ifdef LWS_OPENSSL_SUPPORT
Andy Green90c7cbc2011-01-27 06:26:52 +0000361 if (wsi->ssl) {
Andy Green3faa9c72010-11-08 17:03:03 +0000362 n = SSL_get_fd(wsi->ssl);
363 SSL_shutdown(wsi->ssl);
Andy Green3fc2c652013-01-14 15:35:02 +0800364 compatible_close(n);
Andy Green3faa9c72010-11-08 17:03:03 +0000365 SSL_free(wsi->ssl);
366 } else {
367#endif
Andy Green0303db42013-01-17 14:46:43 +0800368 if (wsi->sock) {
369 n = shutdown(wsi->sock, SHUT_RDWR);
370 if (n)
371 lwsl_debug("closing: shutdown returned %d\n", errno);
Andy Green3fc2c652013-01-14 15:35:02 +0800372
Andy Green0303db42013-01-17 14:46:43 +0800373 n = compatible_close(wsi->sock);
374 if (n)
375 lwsl_debug("closing: close returned %d\n", errno);
376 }
Andy Green3faa9c72010-11-08 17:03:03 +0000377#ifdef LWS_OPENSSL_SUPPORT
378 }
379#endif
David Brooks2c60d952012-04-20 12:19:01 +0800380 if (wsi->protocol && wsi->protocol->per_session_data_size && wsi->user_space) /* user code may own */
Andy Green4f3943a2010-11-12 10:44:16 +0000381 free(wsi->user_space);
382
Andy Green251f6fa2010-11-03 11:13:06 +0000383 free(wsi);
384}
385
Andy Green07034092011-02-13 08:37:12 +0000386/**
Andy Greenf7ee5492011-02-13 09:04:21 +0000387 * libwebsockets_hangup_on_client() - Server calls to terminate client
Andy Green6ee372f2012-04-09 15:09:01 +0800388 * connection
Peter Hinz56885f32011-03-02 22:03:47 +0000389 * @context: libwebsockets context
Andy Greenf7ee5492011-02-13 09:04:21 +0000390 * @fd: Connection socket descriptor
391 */
392
393void
Peter Hinz56885f32011-03-02 22:03:47 +0000394libwebsockets_hangup_on_client(struct libwebsocket_context *context, int fd)
Andy Greenf7ee5492011-02-13 09:04:21 +0000395{
Andy Greendfb23042013-01-17 12:26:48 +0800396 struct libwebsocket *wsi = context->lws_lookup[fd];
Andy Greenf7ee5492011-02-13 09:04:21 +0000397
Andy Greendfb23042013-01-17 12:26:48 +0800398 if (wsi) {
Andy Green467c7ef2013-01-30 12:28:34 +0800399 lwsl_info("closing connection at libwebsockets_hangup_on_client:\n");
Andy Greendfb23042013-01-17 12:26:48 +0800400 libwebsocket_close_and_free_session(context,
401 wsi, LWS_CLOSE_STATUS_NOSTATUS);
402 } else
403 close(fd);
Andy Greenf7ee5492011-02-13 09:04:21 +0000404}
405
406
407/**
Andy Green07034092011-02-13 08:37:12 +0000408 * libwebsockets_get_peer_addresses() - Get client address information
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800409 * @context: Libwebsockets context
410 * @wsi: Local struct libwebsocket associated with
Andy Green07034092011-02-13 08:37:12 +0000411 * @fd: Connection socket descriptor
412 * @name: Buffer to take client address name
413 * @name_len: Length of client address name buffer
414 * @rip: Buffer to take client address IP qotted quad
415 * @rip_len: Length of client address IP buffer
416 *
417 * This function fills in @name and @rip with the name and IP of
Andy Green6ee372f2012-04-09 15:09:01 +0800418 * the client connected with socket descriptor @fd. Names may be
419 * truncated if there is not enough room. If either cannot be
420 * determined, they will be returned as valid zero-length strings.
Andy Green07034092011-02-13 08:37:12 +0000421 */
422
423void
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800424libwebsockets_get_peer_addresses(struct libwebsocket_context *context,
425 struct libwebsocket *wsi, int fd, char *name, int name_len,
Andy Green07034092011-02-13 08:37:12 +0000426 char *rip, int rip_len)
427{
428 unsigned int len;
429 struct sockaddr_in sin;
430 struct hostent *host;
431 struct hostent *host1;
432 char ip[128];
Andy Greenf92def72011-03-09 15:02:20 +0000433 unsigned char *p;
Andy Green07034092011-02-13 08:37:12 +0000434 int n;
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800435 int ret = -1;
David Galeanocb193682013-01-09 15:29:00 +0800436#ifdef AF_LOCAL
437 struct sockaddr_un *un;
438#endif
Andy Green07034092011-02-13 08:37:12 +0000439
440 rip[0] = '\0';
441 name[0] = '\0';
442
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800443 lws_latency_pre(context, wsi);
444
Andy Green07034092011-02-13 08:37:12 +0000445 len = sizeof sin;
446 if (getpeername(fd, (struct sockaddr *) &sin, &len) < 0) {
447 perror("getpeername");
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800448 goto bail;
Andy Green07034092011-02-13 08:37:12 +0000449 }
Andy Green6ee372f2012-04-09 15:09:01 +0800450
Andy Green07034092011-02-13 08:37:12 +0000451 host = gethostbyaddr((char *) &sin.sin_addr, sizeof sin.sin_addr,
452 AF_INET);
453 if (host == NULL) {
454 perror("gethostbyaddr");
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800455 goto bail;
Andy Green07034092011-02-13 08:37:12 +0000456 }
457
458 strncpy(name, host->h_name, name_len);
459 name[name_len - 1] = '\0';
460
461 host1 = gethostbyname(host->h_name);
462 if (host1 == NULL)
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800463 goto bail;
Andy Greenf92def72011-03-09 15:02:20 +0000464 p = (unsigned char *)host1;
Andy Green07034092011-02-13 08:37:12 +0000465 n = 0;
466 while (p != NULL) {
Andy Greenf92def72011-03-09 15:02:20 +0000467 p = (unsigned char *)host1->h_addr_list[n++];
Andy Green07034092011-02-13 08:37:12 +0000468 if (p == NULL)
469 continue;
Peter Hinzbb45a902011-03-10 18:14:01 +0000470 if ((host1->h_addrtype != AF_INET)
471#ifdef AF_LOCAL
472 && (host1->h_addrtype != AF_LOCAL)
473#endif
474 )
Andy Green07034092011-02-13 08:37:12 +0000475 continue;
476
Andy Green7627af52011-03-09 15:13:52 +0000477 if (host1->h_addrtype == AF_INET)
478 sprintf(ip, "%u.%u.%u.%u", p[0], p[1], p[2], p[3]);
Peter Hinzbb45a902011-03-10 18:14:01 +0000479#ifdef AF_LOCAL
Andy Green7627af52011-03-09 15:13:52 +0000480 else {
481 un = (struct sockaddr_un *)p;
Andy Green6ee372f2012-04-09 15:09:01 +0800482 strncpy(ip, un->sun_path, sizeof(ip) - 1);
Andy Green7627af52011-03-09 15:13:52 +0000483 ip[sizeof(ip) - 1] = '\0';
484 }
Peter Hinzbb45a902011-03-10 18:14:01 +0000485#endif
Andy Green07034092011-02-13 08:37:12 +0000486 p = NULL;
487 strncpy(rip, ip, rip_len);
488 rip[rip_len - 1] = '\0';
489 }
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800490
491 ret = 0;
492bail:
493 lws_latency(context, wsi, "libwebsockets_get_peer_addresses", ret, 1);
Andy Green07034092011-02-13 08:37:12 +0000494}
Andy Green9f990342011-02-12 11:57:45 +0000495
Peter Hinz56885f32011-03-02 22:03:47 +0000496int libwebsockets_get_random(struct libwebsocket_context *context,
497 void *buf, int len)
498{
499 int n;
Aaron Zinman4550f1d2013-01-10 12:35:18 +0800500 char *p = (char *)buf;
Peter Hinz56885f32011-03-02 22:03:47 +0000501
502#ifdef WIN32
503 for (n = 0; n < len; n++)
504 p[n] = (unsigned char)rand();
505#else
506 n = read(context->fd_random, p, len);
507#endif
508
509 return n;
510}
511
Andy Green95a7b5d2011-03-06 10:29:39 +0000512int lws_send_pipe_choked(struct libwebsocket *wsi)
513{
514 struct pollfd fds;
515
516 fds.fd = wsi->sock;
517 fds.events = POLLOUT;
518 fds.revents = 0;
519
520 if (poll(&fds, 1, 0) != 1)
521 return 1;
522
523 if ((fds.revents & POLLOUT) == 0)
524 return 1;
525
526 /* okay to send another packet without blocking */
527
528 return 0;
529}
530
Andy Greena41314f2011-05-23 10:00:03 +0100531int
Andy Green3b84c002011-03-06 13:14:42 +0000532lws_handle_POLLOUT_event(struct libwebsocket_context *context,
533 struct libwebsocket *wsi, struct pollfd *pollfd)
534{
Andy Green3b84c002011-03-06 13:14:42 +0000535 int n;
Andy Green6f520a52013-01-29 17:57:39 +0800536
Andy Green3182ece2013-01-20 17:08:31 +0800537#ifndef LWS_NO_EXTENSIONS
538 struct lws_tokens eff_buf;
Andy Green3b84c002011-03-06 13:14:42 +0000539 int ret;
540 int m;
Andy Greena41314f2011-05-23 10:00:03 +0100541 int handled = 0;
Andy Green3b84c002011-03-06 13:14:42 +0000542
Andy Greena41314f2011-05-23 10:00:03 +0100543 for (n = 0; n < wsi->count_active_extensions; n++) {
544 if (!wsi->active_extensions[n]->callback)
545 continue;
546
547 m = wsi->active_extensions[n]->callback(context,
548 wsi->active_extensions[n], wsi,
549 LWS_EXT_CALLBACK_IS_WRITEABLE,
550 wsi->active_extensions_user[n], NULL, 0);
551 if (m > handled)
552 handled = m;
553 }
554
555 if (handled == 1)
556 goto notify_action;
557
558 if (!wsi->extension_data_pending || handled == 2)
Andy Green3b84c002011-03-06 13:14:42 +0000559 goto user_service;
560
561 /*
562 * check in on the active extensions, see if they
563 * had pending stuff to spill... they need to get the
564 * first look-in otherwise sequence will be disordered
565 *
566 * NULL, zero-length eff_buf means just spill pending
567 */
568
569 ret = 1;
570 while (ret == 1) {
571
572 /* default to nobody has more to spill */
573
574 ret = 0;
575 eff_buf.token = NULL;
576 eff_buf.token_len = 0;
577
578 /* give every extension a chance to spill */
579
580 for (n = 0; n < wsi->count_active_extensions; n++) {
581 m = wsi->active_extensions[n]->callback(
Andy Green46c2ea02011-03-22 09:04:01 +0000582 wsi->protocol->owning_server,
583 wsi->active_extensions[n], wsi,
Andy Green3b84c002011-03-06 13:14:42 +0000584 LWS_EXT_CALLBACK_PACKET_TX_PRESEND,
585 wsi->active_extensions_user[n], &eff_buf, 0);
586 if (m < 0) {
Andy Green43db0452013-01-10 19:50:35 +0800587 lwsl_err("ext reports fatal error\n");
Andy Green3b84c002011-03-06 13:14:42 +0000588 return -1;
589 }
590 if (m)
591 /*
592 * at least one extension told us he has more
593 * to spill, so we will go around again after
594 */
595 ret = 1;
596 }
597
598 /* assuming they gave us something to send, send it */
599
600 if (eff_buf.token_len) {
601 if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
602 eff_buf.token_len))
603 return -1;
604 } else
605 continue;
606
607 /* no extension has more to spill */
608
609 if (!ret)
610 continue;
611
612 /*
613 * There's more to spill from an extension, but we just sent
614 * something... did that leave the pipe choked?
615 */
616
617 if (!lws_send_pipe_choked(wsi))
618 /* no we could add more */
619 continue;
620
Andy Green43db0452013-01-10 19:50:35 +0800621 lwsl_info("choked in POLLOUT service\n");
Andy Green3b84c002011-03-06 13:14:42 +0000622
623 /*
624 * Yes, he's choked. Leave the POLLOUT masked on so we will
625 * come back here when he is unchoked. Don't call the user
626 * callback to enforce ordering of spilling, he'll get called
627 * when we come back here and there's nothing more to spill.
628 */
629
630 return 0;
631 }
632
633 wsi->extension_data_pending = 0;
634
635user_service:
Andy Green3182ece2013-01-20 17:08:31 +0800636#endif
Andy Green3b84c002011-03-06 13:14:42 +0000637 /* one shot */
638
Andy Greena41314f2011-05-23 10:00:03 +0100639 if (pollfd) {
640 pollfd->events &= ~POLLOUT;
Andy Green3b84c002011-03-06 13:14:42 +0000641
Andy Greena41314f2011-05-23 10:00:03 +0100642 /* external POLL support via protocol 0 */
643 context->protocols[0].callback(context, wsi,
644 LWS_CALLBACK_CLEAR_MODE_POLL_FD,
645 (void *)(long)wsi->sock, NULL, POLLOUT);
646 }
Andy Green3182ece2013-01-20 17:08:31 +0800647#ifndef LWS_NO_EXTENSIONS
Andy Greena41314f2011-05-23 10:00:03 +0100648notify_action:
Andy Green3182ece2013-01-20 17:08:31 +0800649#endif
Andy Green3b84c002011-03-06 13:14:42 +0000650
Andy Green9e4c2b62011-03-07 20:47:39 +0000651 if (wsi->mode == LWS_CONNMODE_WS_CLIENT)
652 n = LWS_CALLBACK_CLIENT_WRITEABLE;
653 else
654 n = LWS_CALLBACK_SERVER_WRITEABLE;
655
Andy Green706961d2013-01-17 16:50:35 +0800656 user_callback_handle_rxflow(wsi->protocol->callback, context,
657 wsi, (enum libwebsocket_callback_reasons) n, wsi->user_space, NULL, 0);
Andy Green3b84c002011-03-06 13:14:42 +0000658
659 return 0;
660}
661
662
663
Andy Greena41314f2011-05-23 10:00:03 +0100664void
665libwebsocket_service_timeout_check(struct libwebsocket_context *context,
666 struct libwebsocket *wsi, unsigned int sec)
667{
Andy Green3182ece2013-01-20 17:08:31 +0800668#ifndef LWS_NO_EXTENSIONS
Andy Greena41314f2011-05-23 10:00:03 +0100669 int n;
670
671 /*
672 * if extensions want in on it (eg, we are a mux parent)
673 * give them a chance to service child timeouts
674 */
675
676 for (n = 0; n < wsi->count_active_extensions; n++)
677 wsi->active_extensions[n]->callback(
678 context, wsi->active_extensions[n],
679 wsi, LWS_EXT_CALLBACK_1HZ,
680 wsi->active_extensions_user[n], NULL, sec);
681
Andy Green3182ece2013-01-20 17:08:31 +0800682#endif
Andy Greena41314f2011-05-23 10:00:03 +0100683 if (!wsi->pending_timeout)
684 return;
Andy Green6ee372f2012-04-09 15:09:01 +0800685
Andy Greena41314f2011-05-23 10:00:03 +0100686 /*
687 * if we went beyond the allowed time, kill the
688 * connection
689 */
690
691 if (sec > wsi->pending_timeout_limit) {
Andy Green43db0452013-01-10 19:50:35 +0800692 lwsl_info("TIMEDOUT WAITING\n");
Andy Greena41314f2011-05-23 10:00:03 +0100693 libwebsocket_close_and_free_session(context,
694 wsi, LWS_CLOSE_STATUS_NOSTATUS);
695 }
696}
697
Andy Green9f990342011-02-12 11:57:45 +0000698/**
699 * libwebsocket_service_fd() - Service polled socket with something waiting
Peter Hinz56885f32011-03-02 22:03:47 +0000700 * @context: Websocket context
Andy Green9f990342011-02-12 11:57:45 +0000701 * @pollfd: The pollfd entry describing the socket fd and which events
Andy Green6ee372f2012-04-09 15:09:01 +0800702 * happened.
Andy Green9f990342011-02-12 11:57:45 +0000703 *
Andy Green75006172013-01-22 12:32:11 +0800704 * This function takes a pollfd that has POLLIN or POLLOUT activity and
705 * services it according to the state of the associated struct libwebsocket.
706 *
707 * The one call deals with all "service" that might happen on a socket
708 * including listen accepts, http files as well as websocket protocol.
Andy Green9f990342011-02-12 11:57:45 +0000709 */
710
711int
Peter Hinz56885f32011-03-02 22:03:47 +0000712libwebsocket_service_fd(struct libwebsocket_context *context,
Andy Green0d338332011-02-12 11:57:43 +0000713 struct pollfd *pollfd)
Andy Greenb45993c2010-12-18 15:13:50 +0000714{
Andy Greena1ce6be2013-01-18 11:43:21 +0800715 struct libwebsocket *wsi;
Andy Greenb45993c2010-12-18 15:13:50 +0000716 int n;
Andy Green0d338332011-02-12 11:57:43 +0000717 int m;
Andy Greena71eafc2011-02-14 17:59:43 +0000718 struct timeval tv;
Andy Green6f520a52013-01-29 17:57:39 +0800719 unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 1 +
720 MAX_USER_RX_BUFFER + LWS_SEND_BUFFER_POST_PADDING];
Jack Mitchelldaed4fb2013-01-30 18:53:36 +0800721#ifdef LWS_OPENSSL_SUPPORT
Andy Green467c7ef2013-01-30 12:28:34 +0800722 char ssl_err_buf[512];
Jack Mitchelldaed4fb2013-01-30 18:53:36 +0800723#endif
Andy Green6f520a52013-01-29 17:57:39 +0800724
Andy Green3182ece2013-01-20 17:08:31 +0800725#ifndef LWS_NO_EXTENSIONS
Andy Green2366b1c2011-03-06 13:15:31 +0000726 int more = 1;
Andy Green3182ece2013-01-20 17:08:31 +0800727#endif
Andy Green98a717c2011-03-06 13:14:15 +0000728 struct lws_tokens eff_buf;
Andy Green03674a62013-01-16 11:47:40 +0800729#ifndef LWS_NO_CLIENT
Andy Green76f61e72013-01-16 11:53:05 +0800730 extern int lws_client_socket_service(struct libwebsocket_context *context, struct libwebsocket *wsi, struct pollfd *pollfd);
Andy Green03674a62013-01-16 11:47:40 +0800731#endif
Andy Greena1ce6be2013-01-18 11:43:21 +0800732#ifndef LWS_NO_SERVER
733 extern int lws_server_socket_service(struct libwebsocket_context *context, struct libwebsocket *wsi, struct pollfd *pollfd);
734#endif
Andy Greena71eafc2011-02-14 17:59:43 +0000735 /*
736 * you can call us with pollfd = NULL to just allow the once-per-second
737 * global timeout checks; if less than a second since the last check
738 * it returns immediately then.
739 */
740
741 gettimeofday(&tv, NULL);
742
Peter Hinz56885f32011-03-02 22:03:47 +0000743 if (context->last_timeout_check_s != tv.tv_sec) {
744 context->last_timeout_check_s = tv.tv_sec;
Andy Greena71eafc2011-02-14 17:59:43 +0000745
Joakim Soderberg4c531232013-02-06 15:26:58 +0900746 #ifndef WIN32
Andy Green24cba922013-01-19 13:56:10 +0800747 /* if our parent went down, don't linger around */
748 if (context->started_with_parent && kill(context->started_with_parent, 0) < 0)
749 kill(getpid(), SIGTERM);
Joakim Soderberg4c531232013-02-06 15:26:58 +0900750 #endif
Andy Green24cba922013-01-19 13:56:10 +0800751
Andy Greena71eafc2011-02-14 17:59:43 +0000752 /* global timeout check once per second */
753
Peter Hinz56885f32011-03-02 22:03:47 +0000754 for (n = 0; n < context->fds_count; n++) {
Andy Greendfb23042013-01-17 12:26:48 +0800755 struct libwebsocket *new_wsi = context->lws_lookup[context->fds[n].fd];
756 if (!new_wsi)
757 continue;
758 libwebsocket_service_timeout_check(context,
759 new_wsi, tv.tv_sec);
Andy Greena71eafc2011-02-14 17:59:43 +0000760 }
761 }
762
763 /* just here for timeout management? */
764
765 if (pollfd == NULL)
766 return 0;
767
768 /* no, here to service a socket descriptor */
769
Andy Green65b0e912013-01-16 07:59:47 +0800770 /*
771 * deal with listen service piggybacking
772 * every listen_service_modulo services of other fds, we
773 * sneak one in to service the listen socket if there's anything waiting
774 *
775 * To handle connection storms, as found in ab, if we previously saw a
776 * pending connection here, it causes us to check again next time.
777 */
778
779 if (context->listen_service_fd && pollfd->fd != context->listen_service_fd) {
780 context->listen_service_count++;
781 if (context->listen_service_extraseen ||
782 context->listen_service_count == context->listen_service_modulo) {
783 context->listen_service_count = 0;
784 m = 1;
785 if (context->listen_service_extraseen > 5)
786 m = 2;
787 while (m--) {
788 /* even with extpoll, we prepared this internal fds for listen */
789 n = poll(&context->fds[0], 1, 0);
790 if (n > 0) { /* there's a connection waiting for us */
791 libwebsocket_service_fd(context, &context->fds[0]);
792 context->listen_service_extraseen++;
793 } else {
794 if (context->listen_service_extraseen)
795 context->listen_service_extraseen--;
796 break;
797 }
798 }
799 }
800
801 }
802
803 /* okay, what we came here to do... */
804
Andy Greendfb23042013-01-17 12:26:48 +0800805 wsi = context->lws_lookup[pollfd->fd];
Andy Greend280b6e2013-01-15 13:40:23 +0800806 if (wsi == NULL) {
Andy Greendfb23042013-01-17 12:26:48 +0800807 if (pollfd->fd > 11)
808 lwsl_err("unexpected NULL wsi fd=%d fds_count=%d\n", pollfd->fd, context->fds_count);
Andy Greenfa3f4052012-10-07 20:40:35 +0800809 return 0;
Andy Greend280b6e2013-01-15 13:40:23 +0800810 }
Andy Green8f037e42010-12-19 22:13:26 +0000811
Andy Green0d338332011-02-12 11:57:43 +0000812 switch (wsi->mode) {
Andy Greend280b6e2013-01-15 13:40:23 +0800813
Andy Greena1ce6be2013-01-18 11:43:21 +0800814#ifndef LWS_NO_SERVER
Andy Greend280b6e2013-01-15 13:40:23 +0800815 case LWS_CONNMODE_HTTP_SERVING:
Andy Green0d338332011-02-12 11:57:43 +0000816 case LWS_CONNMODE_SERVER_LISTENER:
Andy Greene2160712013-01-28 12:19:10 +0800817 case LWS_CONNMODE_SSL_ACK_PENDING:
Andy Greena1ce6be2013-01-18 11:43:21 +0800818 return lws_server_socket_service(context, wsi, pollfd);
819#endif
Andy Greenbe93fef2011-02-14 20:25:43 +0000820
Andy Green0d338332011-02-12 11:57:43 +0000821 case LWS_CONNMODE_WS_SERVING:
822 case LWS_CONNMODE_WS_CLIENT:
823
824 /* handle session socket closed */
825
826 if (pollfd->revents & (POLLERR | POLLHUP)) {
827
Andy Green43db0452013-01-10 19:50:35 +0800828 lwsl_debug("Session Socket %p (fd=%d) dead\n",
Andy Green0d338332011-02-12 11:57:43 +0000829 (void *)wsi, pollfd->fd);
830
Peter Hinz56885f32011-03-02 22:03:47 +0000831 libwebsocket_close_and_free_session(context, wsi,
Andy Green687b0182011-02-26 11:04:01 +0000832 LWS_CLOSE_STATUS_NOSTATUS);
Andy Green040d2ef2013-01-16 13:40:43 +0800833 return 0;
Andy Greenb45993c2010-12-18 15:13:50 +0000834 }
835
Andy Green0d338332011-02-12 11:57:43 +0000836 /* the guy requested a callback when it was OK to write */
837
Andy Greenda527df2011-03-07 07:08:12 +0000838 if ((pollfd->revents & POLLOUT) &&
839 wsi->state == WSI_STATE_ESTABLISHED)
840 if (lws_handle_POLLOUT_event(context, wsi,
841 pollfd) < 0) {
842 libwebsocket_close_and_free_session(
843 context, wsi, LWS_CLOSE_STATUS_NORMAL);
Andy Green040d2ef2013-01-16 13:40:43 +0800844 return 0;
Andy Green3b84c002011-03-06 13:14:42 +0000845 }
Andy Green0d338332011-02-12 11:57:43 +0000846
Andy Green0d338332011-02-12 11:57:43 +0000847
848 /* any incoming data ready? */
849
850 if (!(pollfd->revents & POLLIN))
851 break;
852
Andy Greenb45993c2010-12-18 15:13:50 +0000853#ifdef LWS_OPENSSL_SUPPORT
David Galeano7ffbe1b2013-01-10 10:35:32 +0800854read_pending:
Andy Green467c7ef2013-01-30 12:28:34 +0800855 if (wsi->ssl) {
Andy Green98a717c2011-03-06 13:14:15 +0000856 eff_buf.token_len = SSL_read(wsi->ssl, buf, sizeof buf);
Andy Green467c7ef2013-01-30 12:28:34 +0800857 if (!eff_buf.token_len) {
858 n = SSL_get_error(wsi->ssl, eff_buf.token_len);
859 lwsl_err("SSL_read returned 0 with reason %s\n", ERR_error_string(n, ssl_err_buf));
860 }
861 } else
Andy Greenb45993c2010-12-18 15:13:50 +0000862#endif
Andy Green98a717c2011-03-06 13:14:15 +0000863 eff_buf.token_len =
Andy Green72c34322011-04-16 10:46:21 +0100864 recv(pollfd->fd, buf, sizeof buf, 0);
Andy Greenb45993c2010-12-18 15:13:50 +0000865
Andy Green98a717c2011-03-06 13:14:15 +0000866 if (eff_buf.token_len < 0) {
Andy Green43db0452013-01-10 19:50:35 +0800867 lwsl_debug("Socket read returned %d\n",
Andy Green98a717c2011-03-06 13:14:15 +0000868 eff_buf.token_len);
Alon Levydc93b7f2012-10-19 11:21:57 +0200869 if (errno != EINTR && errno != EAGAIN)
Andy Green6ee372f2012-04-09 15:09:01 +0800870 libwebsocket_close_and_free_session(context,
871 wsi, LWS_CLOSE_STATUS_NOSTATUS);
Andy Green040d2ef2013-01-16 13:40:43 +0800872 return 0;
Andy Greenb45993c2010-12-18 15:13:50 +0000873 }
Andy Green98a717c2011-03-06 13:14:15 +0000874 if (!eff_buf.token_len) {
Andy Green467c7ef2013-01-30 12:28:34 +0800875 lwsl_info("closing connection due to zero length read\n");
Peter Hinz56885f32011-03-02 22:03:47 +0000876 libwebsocket_close_and_free_session(context, wsi,
Andy Green6ee372f2012-04-09 15:09:01 +0800877 LWS_CLOSE_STATUS_NOSTATUS);
Andy Greenfa3f4052012-10-07 20:40:35 +0800878 return 0;
Andy Greenb45993c2010-12-18 15:13:50 +0000879 }
880
Andy Green98a717c2011-03-06 13:14:15 +0000881 /*
882 * give any active extensions a chance to munge the buffer
883 * before parse. We pass in a pointer to an lws_tokens struct
884 * prepared with the default buffer and content length that's in
885 * there. Rather than rewrite the default buffer, extensions
886 * that expect to grow the buffer can adapt .token to
887 * point to their own per-connection buffer in the extension
888 * user allocation. By default with no extensions or no
889 * extension callback handling, just the normal input buffer is
890 * used then so it is efficient.
891 */
Andy Greenb45993c2010-12-18 15:13:50 +0000892
Andy Green98a717c2011-03-06 13:14:15 +0000893 eff_buf.token = (char *)buf;
Andy Green3182ece2013-01-20 17:08:31 +0800894#ifndef LWS_NO_EXTENSIONS
Andy Green98a717c2011-03-06 13:14:15 +0000895 more = 1;
896 while (more) {
Andy Green0d338332011-02-12 11:57:43 +0000897
Andy Green98a717c2011-03-06 13:14:15 +0000898 more = 0;
899
900 for (n = 0; n < wsi->count_active_extensions; n++) {
Andy Green46c2ea02011-03-22 09:04:01 +0000901 m = wsi->active_extensions[n]->callback(context,
902 wsi->active_extensions[n], wsi,
Andy Green98a717c2011-03-06 13:14:15 +0000903 LWS_EXT_CALLBACK_PACKET_RX_PREPARSE,
Andy Green46c2ea02011-03-22 09:04:01 +0000904 wsi->active_extensions_user[n],
905 &eff_buf, 0);
Andy Green98a717c2011-03-06 13:14:15 +0000906 if (m < 0) {
Andy Green43db0452013-01-10 19:50:35 +0800907 lwsl_ext(
Andy Green6ee372f2012-04-09 15:09:01 +0800908 "Extension reports fatal error\n");
909 libwebsocket_close_and_free_session(
910 context, wsi,
911 LWS_CLOSE_STATUS_NOSTATUS);
Andy Green040d2ef2013-01-16 13:40:43 +0800912 return 0;
Andy Green98a717c2011-03-06 13:14:15 +0000913 }
914 if (m)
915 more = 1;
916 }
Andy Green3182ece2013-01-20 17:08:31 +0800917#endif
Andy Green98a717c2011-03-06 13:14:15 +0000918 /* service incoming data */
919
920 if (eff_buf.token_len) {
921 n = libwebsocket_read(context, wsi,
Andy Green6ee372f2012-04-09 15:09:01 +0800922 (unsigned char *)eff_buf.token,
923 eff_buf.token_len);
Andy Green98a717c2011-03-06 13:14:15 +0000924 if (n < 0)
925 /* we closed wsi */
Andy Green040d2ef2013-01-16 13:40:43 +0800926 return 0;
Andy Green98a717c2011-03-06 13:14:15 +0000927 }
Andy Green3182ece2013-01-20 17:08:31 +0800928#ifndef LWS_NO_EXTENSIONS
Andy Green98a717c2011-03-06 13:14:15 +0000929 eff_buf.token = NULL;
930 eff_buf.token_len = 0;
931 }
Andy Green3182ece2013-01-20 17:08:31 +0800932#endif
David Galeano7ffbe1b2013-01-10 10:35:32 +0800933
934#ifdef LWS_OPENSSL_SUPPORT
935 if (wsi->ssl && SSL_pending(wsi->ssl))
936 goto read_pending;
937#endif
Andy Green98a717c2011-03-06 13:14:15 +0000938 break;
Andy Green76f61e72013-01-16 11:53:05 +0800939
940 default:
Andy Green03674a62013-01-16 11:47:40 +0800941#ifdef LWS_NO_CLIENT
942 break;
943#else
Andy Green76f61e72013-01-16 11:53:05 +0800944 return lws_client_socket_service(context, wsi, pollfd);
Andy Green03674a62013-01-16 11:47:40 +0800945#endif
Andy Greenb45993c2010-12-18 15:13:50 +0000946 }
947
948 return 0;
949}
950
Andy Green0d338332011-02-12 11:57:43 +0000951
Andy Green6964bb52011-01-23 16:50:33 +0000952/**
953 * libwebsocket_context_destroy() - Destroy the websocket context
Peter Hinz56885f32011-03-02 22:03:47 +0000954 * @context: Websocket context
Andy Green6964bb52011-01-23 16:50:33 +0000955 *
956 * This function closes any active connections and then frees the
957 * context. After calling this, any further use of the context is
958 * undefined.
959 */
960void
Peter Hinz56885f32011-03-02 22:03:47 +0000961libwebsocket_context_destroy(struct libwebsocket_context *context)
Andy Green6964bb52011-01-23 16:50:33 +0000962{
Andy Green3182ece2013-01-20 17:08:31 +0800963#ifndef LWS_NO_EXTENSIONS
Andy Green0d338332011-02-12 11:57:43 +0000964 int n;
965 int m;
Andy Greena41314f2011-05-23 10:00:03 +0100966 struct libwebsocket_extension *ext;
Andy Green6964bb52011-01-23 16:50:33 +0000967
Andy Greend636e352013-01-29 12:36:17 +0800968#ifdef LWS_LATENCY
969 if (context->worst_latency_info[0])
970 lwsl_notice("Worst latency: %s\n", context->worst_latency_info);
971#endif
972
Andy Greendfb23042013-01-17 12:26:48 +0800973 for (n = 0; n < context->fds_count; n++) {
974 struct libwebsocket *wsi = context->lws_lookup[context->fds[n].fd];
975 libwebsocket_close_and_free_session(context,
976 wsi, LWS_CLOSE_STATUS_GOINGAWAY);
977 }
Andy Green6964bb52011-01-23 16:50:33 +0000978
Andy Greena41314f2011-05-23 10:00:03 +0100979 /*
980 * give all extensions a chance to clean up any per-context
981 * allocations they might have made
982 */
983
984 ext = context->extensions;
985 m = LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT;
986 if (context->listen_port)
987 m = LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT;
Paulo Roberto Urio1f680ab2012-06-04 08:40:28 +0800988 while (ext && ext->callback) {
Aaron Zinman4550f1d2013-01-10 12:35:18 +0800989 ext->callback(context, ext, NULL, (enum libwebsocket_extension_callback_reasons)m, NULL, NULL, 0);
Andy Greena41314f2011-05-23 10:00:03 +0100990 ext++;
991 }
Andy Green3182ece2013-01-20 17:08:31 +0800992#endif
Andy Greena41314f2011-05-23 10:00:03 +0100993
Peter Hinz56885f32011-03-02 22:03:47 +0000994#ifdef WIN32
995#else
996 close(context->fd_random);
Andy Green6964bb52011-01-23 16:50:33 +0000997#endif
998
Peter Hinz56885f32011-03-02 22:03:47 +0000999#ifdef LWS_OPENSSL_SUPPORT
1000 if (context->ssl_ctx)
1001 SSL_CTX_free(context->ssl_ctx);
1002 if (context->ssl_client_ctx)
1003 SSL_CTX_free(context->ssl_client_ctx);
1004#endif
1005
1006 free(context);
1007
1008#ifdef WIN32
1009 WSACleanup();
1010#endif
Andy Green6964bb52011-01-23 16:50:33 +00001011}
1012
Andy Greend88146d2013-01-22 12:40:35 +08001013/**
1014 * libwebsocket_context_user() - get the user data associated with the whole context
1015 * @context: Websocket context
1016 *
1017 * This returns the optional user allocation that can be attached to
1018 * the context the sockets live in at context_create time. It's a way
1019 * to let all sockets serviced in the same context share data without
1020 * using globals statics in the user code.
1021 */
1022
1023
Alon Levy0291eb32012-10-19 11:21:56 +02001024LWS_EXTERN void *
1025libwebsocket_context_user(struct libwebsocket_context *context)
1026{
1027 return context->user_space;
1028}
1029
Andy Green6964bb52011-01-23 16:50:33 +00001030/**
1031 * libwebsocket_service() - Service any pending websocket activity
Peter Hinz56885f32011-03-02 22:03:47 +00001032 * @context: Websocket context
Andy Green6964bb52011-01-23 16:50:33 +00001033 * @timeout_ms: Timeout for poll; 0 means return immediately if nothing needed
1034 * service otherwise block and service immediately, returning
1035 * after the timeout if nothing needed service.
1036 *
1037 * This function deals with any pending websocket traffic, for three
1038 * kinds of event. It handles these events on both server and client
1039 * types of connection the same.
1040 *
1041 * 1) Accept new connections to our context's server
1042 *
Andy Green6f520a52013-01-29 17:57:39 +08001043 * 2) Call the receive callback for incoming frame data received by
Andy Green6964bb52011-01-23 16:50:33 +00001044 * server or client connections.
1045 *
1046 * You need to call this service function periodically to all the above
1047 * functions to happen; if your application is single-threaded you can
1048 * just call it in your main event loop.
1049 *
1050 * Alternatively you can fork a new process that asynchronously handles
1051 * calling this service in a loop. In that case you are happy if this
1052 * call blocks your thread until it needs to take care of something and
1053 * would call it with a large nonzero timeout. Your loop then takes no
1054 * CPU while there is nothing happening.
1055 *
1056 * If you are calling it in a single-threaded app, you don't want it to
1057 * wait around blocking other things in your loop from happening, so you
1058 * would call it with a timeout_ms of 0, so it returns immediately if
1059 * nothing is pending, or as soon as it services whatever was pending.
1060 */
1061
Andy Greenb45993c2010-12-18 15:13:50 +00001062
Andy Greene92cd172011-01-19 13:11:55 +00001063int
Peter Hinz56885f32011-03-02 22:03:47 +00001064libwebsocket_service(struct libwebsocket_context *context, int timeout_ms)
Andy Greene92cd172011-01-19 13:11:55 +00001065{
1066 int n;
Andy Greene92cd172011-01-19 13:11:55 +00001067
1068 /* stay dead once we are dead */
1069
Peter Hinz56885f32011-03-02 22:03:47 +00001070 if (context == NULL)
Andy Greene92cd172011-01-19 13:11:55 +00001071 return 1;
1072
Andy Green0d338332011-02-12 11:57:43 +00001073 /* wait for something to need service */
Andy Green4739e5c2011-01-22 12:51:57 +00001074
Peter Hinz56885f32011-03-02 22:03:47 +00001075 n = poll(context->fds, context->fds_count, timeout_ms);
Andy Green3221f922011-02-12 13:14:11 +00001076 if (n == 0) /* poll timeout */
1077 return 0;
Andy Greene92cd172011-01-19 13:11:55 +00001078
Andy Greendfb23042013-01-17 12:26:48 +08001079 if (n < 0)
Andy Green3928f612012-07-20 12:58:38 +08001080 return -1;
Andy Greene92cd172011-01-19 13:11:55 +00001081
Andy Greendfb23042013-01-17 12:26:48 +08001082 /* any socket with events to service? */
Andy Greene92cd172011-01-19 13:11:55 +00001083
Peter Hinz56885f32011-03-02 22:03:47 +00001084 for (n = 0; n < context->fds_count; n++)
1085 if (context->fds[n].revents)
Andy Green3928f612012-07-20 12:58:38 +08001086 if (libwebsocket_service_fd(context,
1087 &context->fds[n]) < 0)
1088 return -1;
Andy Greene92cd172011-01-19 13:11:55 +00001089 return 0;
Andy Greene92cd172011-01-19 13:11:55 +00001090}
1091
Andy Green3182ece2013-01-20 17:08:31 +08001092#ifndef LWS_NO_EXTENSIONS
Andy Greena41314f2011-05-23 10:00:03 +01001093int
1094lws_any_extension_handled(struct libwebsocket_context *context,
Andy Green6ee372f2012-04-09 15:09:01 +08001095 struct libwebsocket *wsi,
1096 enum libwebsocket_extension_callback_reasons r,
Andy Greena41314f2011-05-23 10:00:03 +01001097 void *v, size_t len)
1098{
1099 int n;
1100 int handled = 0;
1101
1102 /* maybe an extension will take care of it for us */
1103
1104 for (n = 0; n < wsi->count_active_extensions && !handled; n++) {
1105 if (!wsi->active_extensions[n]->callback)
1106 continue;
1107
1108 handled |= wsi->active_extensions[n]->callback(context,
1109 wsi->active_extensions[n], wsi,
1110 r, wsi->active_extensions_user[n], v, len);
1111 }
1112
1113 return handled;
1114}
1115
1116
1117void *
1118lws_get_extension_user_matching_ext(struct libwebsocket *wsi,
Andy Green6ee372f2012-04-09 15:09:01 +08001119 struct libwebsocket_extension *ext)
Andy Greena41314f2011-05-23 10:00:03 +01001120{
1121 int n = 0;
1122
Andy Green68b45042011-05-25 21:41:57 +01001123 if (wsi == NULL)
1124 return NULL;
1125
Andy Greena41314f2011-05-23 10:00:03 +01001126 while (n < wsi->count_active_extensions) {
1127 if (wsi->active_extensions[n] != ext) {
1128 n++;
1129 continue;
1130 }
1131 return wsi->active_extensions_user[n];
1132 }
1133
1134 return NULL;
1135}
Andy Green3182ece2013-01-20 17:08:31 +08001136#endif
Andy Greena41314f2011-05-23 10:00:03 +01001137
Andy Green90c7cbc2011-01-27 06:26:52 +00001138/**
1139 * libwebsocket_callback_on_writable() - Request a callback when this socket
1140 * becomes able to be written to without
1141 * blocking
Andy Green32375b72011-02-19 08:32:53 +00001142 *
Peter Hinz56885f32011-03-02 22:03:47 +00001143 * @context: libwebsockets context
Andy Green90c7cbc2011-01-27 06:26:52 +00001144 * @wsi: Websocket connection instance to get callback for
1145 */
1146
1147int
Peter Hinz56885f32011-03-02 22:03:47 +00001148libwebsocket_callback_on_writable(struct libwebsocket_context *context,
Andy Green6ee372f2012-04-09 15:09:01 +08001149 struct libwebsocket *wsi)
Andy Green90c7cbc2011-01-27 06:26:52 +00001150{
Andy Green3182ece2013-01-20 17:08:31 +08001151#ifndef LWS_NO_EXTENSIONS
Andy Green90c7cbc2011-01-27 06:26:52 +00001152 int n;
Andy Greena41314f2011-05-23 10:00:03 +01001153 int handled = 0;
1154
1155 /* maybe an extension will take care of it for us */
1156
1157 for (n = 0; n < wsi->count_active_extensions; n++) {
1158 if (!wsi->active_extensions[n]->callback)
1159 continue;
1160
1161 handled |= wsi->active_extensions[n]->callback(context,
1162 wsi->active_extensions[n], wsi,
1163 LWS_EXT_CALLBACK_REQUEST_ON_WRITEABLE,
1164 wsi->active_extensions_user[n], NULL, 0);
1165 }
1166
1167 if (handled)
1168 return 1;
Andy Green3182ece2013-01-20 17:08:31 +08001169#endif
Andy Greendfb23042013-01-17 12:26:48 +08001170 if (wsi->position_in_fds_table < 0) {
Andy Green43db0452013-01-10 19:50:35 +08001171 lwsl_err("libwebsocket_callback_on_writable: "
Andy Green6ee372f2012-04-09 15:09:01 +08001172 "failed to find socket %d\n", wsi->sock);
Andy Greendfb23042013-01-17 12:26:48 +08001173 return -1;
1174 }
1175
1176 context->fds[wsi->position_in_fds_table].events |= POLLOUT;
Andy Greena41314f2011-05-23 10:00:03 +01001177
Andy Green3221f922011-02-12 13:14:11 +00001178 /* external POLL support via protocol 0 */
Peter Hinz56885f32011-03-02 22:03:47 +00001179 context->protocols[0].callback(context, wsi,
Andy Green3221f922011-02-12 13:14:11 +00001180 LWS_CALLBACK_SET_MODE_POLL_FD,
1181 (void *)(long)wsi->sock, NULL, POLLOUT);
1182
Andy Green90c7cbc2011-01-27 06:26:52 +00001183 return 1;
1184}
1185
1186/**
1187 * libwebsocket_callback_on_writable_all_protocol() - Request a callback for
1188 * all connections using the given protocol when it
1189 * becomes possible to write to each socket without
1190 * blocking in turn.
1191 *
1192 * @protocol: Protocol whose connections will get callbacks
1193 */
1194
1195int
1196libwebsocket_callback_on_writable_all_protocol(
1197 const struct libwebsocket_protocols *protocol)
1198{
Peter Hinz56885f32011-03-02 22:03:47 +00001199 struct libwebsocket_context *context = protocol->owning_server;
Andy Green90c7cbc2011-01-27 06:26:52 +00001200 int n;
Andy Green0d338332011-02-12 11:57:43 +00001201 struct libwebsocket *wsi;
Andy Green90c7cbc2011-01-27 06:26:52 +00001202
Andy Greendfb23042013-01-17 12:26:48 +08001203 for (n = 0; n < context->fds_count; n++) {
1204 wsi = context->lws_lookup[context->fds[n].fd];
1205 if (!wsi)
1206 continue;
1207 if (wsi->protocol == protocol)
1208 libwebsocket_callback_on_writable(context, wsi);
Andy Green0d338332011-02-12 11:57:43 +00001209 }
Andy Green90c7cbc2011-01-27 06:26:52 +00001210
1211 return 0;
1212}
1213
Andy Greenbe93fef2011-02-14 20:25:43 +00001214/**
1215 * libwebsocket_set_timeout() - marks the wsi as subject to a timeout
1216 *
1217 * You will not need this unless you are doing something special
1218 *
1219 * @wsi: Websocket connection instance
1220 * @reason: timeout reason
1221 * @secs: how many seconds
1222 */
1223
1224void
1225libwebsocket_set_timeout(struct libwebsocket *wsi,
1226 enum pending_timeout reason, int secs)
1227{
1228 struct timeval tv;
1229
1230 gettimeofday(&tv, NULL);
1231
1232 wsi->pending_timeout_limit = tv.tv_sec + secs;
1233 wsi->pending_timeout = reason;
1234}
1235
Andy Greena6cbece2011-01-27 20:06:03 +00001236
1237/**
1238 * libwebsocket_get_socket_fd() - returns the socket file descriptor
1239 *
1240 * You will not need this unless you are doing something special
1241 *
1242 * @wsi: Websocket connection instance
1243 */
1244
1245int
1246libwebsocket_get_socket_fd(struct libwebsocket *wsi)
1247{
1248 return wsi->sock;
1249}
1250
Andy Greend636e352013-01-29 12:36:17 +08001251#ifdef LWS_LATENCY
1252void
1253lws_latency(struct libwebsocket_context *context, struct libwebsocket *wsi, const char *action, int ret, int completed)
1254{
1255 struct timeval tv;
1256 unsigned long u;
1257 char buf[256];
1258
1259 gettimeofday(&tv, NULL);
1260
1261 u = (tv.tv_sec * 1000000) + tv.tv_usec;
1262
1263 if (action) {
1264 if (completed) {
1265 if (wsi->action_start == wsi->latency_start)
1266 sprintf(buf, "Completion first try lat %luus: %p: ret %d: %s\n", u - wsi->latency_start, (void *)wsi, ret, action);
1267 else
1268 sprintf(buf, "Completion %luus: lat %luus: %p: ret %d: %s\n", u - wsi->action_start, u - wsi->latency_start, (void *)wsi, ret, action);
1269 wsi->action_start = 0;
1270 } else
1271 sprintf(buf, "lat %luus: %p: ret %d: %s\n", u - wsi->latency_start, (void *)wsi, ret, action);
1272 if (u - wsi->latency_start > context->worst_latency) {
1273 context->worst_latency = u - wsi->latency_start;
1274 strcpy(context->worst_latency_info, buf);
1275 }
1276 lwsl_latency("%s", buf);
1277 } else {
1278 wsi->latency_start = u;
1279 if (!wsi->action_start)
1280 wsi->action_start = u;
1281 }
1282}
1283#endif
1284
Andy Greena1ce6be2013-01-18 11:43:21 +08001285#ifdef LWS_NO_SERVER
1286int
1287_libwebsocket_rx_flow_control(struct libwebsocket *wsi)
1288{
1289 return 0;
1290}
1291#else
Andy Green706961d2013-01-17 16:50:35 +08001292int
1293_libwebsocket_rx_flow_control(struct libwebsocket *wsi)
1294{
1295 struct libwebsocket_context *context = wsi->protocol->owning_server;
1296 int n;
1297
Andy Green623a98d2013-01-21 11:04:23 +08001298 if (!(wsi->u.ws.rxflow_change_to & 2))
Andy Green706961d2013-01-17 16:50:35 +08001299 return 0;
1300
Andy Green623a98d2013-01-21 11:04:23 +08001301 wsi->u.ws.rxflow_change_to &= ~2;
Andy Green706961d2013-01-17 16:50:35 +08001302
Andy Green623a98d2013-01-21 11:04:23 +08001303 lwsl_info("rxflow: wsi %p change_to %d\n", wsi, wsi->u.ws.rxflow_change_to);
Andy Green706961d2013-01-17 16:50:35 +08001304
1305 /* if we're letting it come again, did we interrupt anything? */
Andy Green623a98d2013-01-21 11:04:23 +08001306 if ((wsi->u.ws.rxflow_change_to & 1) && wsi->u.ws.rxflow_buffer) {
Andy Green706961d2013-01-17 16:50:35 +08001307 n = libwebsocket_interpret_incoming_packet(wsi, NULL, 0);
1308 if (n < 0) {
Andy Green467c7ef2013-01-30 12:28:34 +08001309 lwsl_info("closing connection at libwebsocket_rx_flow_control:\n");
Andy Green706961d2013-01-17 16:50:35 +08001310 libwebsocket_close_and_free_session(context, wsi, LWS_CLOSE_STATUS_NOSTATUS);
1311 return -1;
1312 }
1313 if (n)
1314 /* oh he stuck again, do nothing */
1315 return 0;
1316 }
1317
Andy Green623a98d2013-01-21 11:04:23 +08001318 if (wsi->u.ws.rxflow_change_to & 1)
Andy Green706961d2013-01-17 16:50:35 +08001319 context->fds[wsi->position_in_fds_table].events |= POLLIN;
1320 else
1321 context->fds[wsi->position_in_fds_table].events &= ~POLLIN;
1322
Andy Green623a98d2013-01-21 11:04:23 +08001323 if (wsi->u.ws.rxflow_change_to & 1)
Andy Green706961d2013-01-17 16:50:35 +08001324 /* external POLL support via protocol 0 */
1325 context->protocols[0].callback(context, wsi,
1326 LWS_CALLBACK_SET_MODE_POLL_FD,
1327 (void *)(long)wsi->sock, NULL, POLLIN);
1328 else
1329 /* external POLL support via protocol 0 */
1330 context->protocols[0].callback(context, wsi,
1331 LWS_CALLBACK_CLEAR_MODE_POLL_FD,
1332 (void *)(long)wsi->sock, NULL, POLLIN);
1333
1334 return 1;
1335}
Andy Greena1ce6be2013-01-18 11:43:21 +08001336#endif
Andy Green706961d2013-01-17 16:50:35 +08001337
Andy Green90c7cbc2011-01-27 06:26:52 +00001338/**
1339 * libwebsocket_rx_flow_control() - Enable and disable socket servicing for
1340 * receieved packets.
1341 *
1342 * If the output side of a server process becomes choked, this allows flow
1343 * control for the input side.
1344 *
1345 * @wsi: Websocket connection instance to get callback for
1346 * @enable: 0 = disable read servicing for this connection, 1 = enable
1347 */
1348
1349int
1350libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable)
1351{
Andy Green623a98d2013-01-21 11:04:23 +08001352 wsi->u.ws.rxflow_change_to = 2 | !!enable;
Andy Green90c7cbc2011-01-27 06:26:52 +00001353
Andy Green706961d2013-01-17 16:50:35 +08001354 return 0;
Andy Green90c7cbc2011-01-27 06:26:52 +00001355}
1356
Andy Green706961d2013-01-17 16:50:35 +08001357
Andy Green2ac5a6f2011-01-28 10:00:18 +00001358/**
1359 * libwebsocket_canonical_hostname() - returns this host's hostname
1360 *
1361 * This is typically used by client code to fill in the host parameter
1362 * when making a client connection. You can only call it after the context
1363 * has been created.
1364 *
Peter Hinz56885f32011-03-02 22:03:47 +00001365 * @context: Websocket context
Andy Green2ac5a6f2011-01-28 10:00:18 +00001366 */
1367
1368
1369extern const char *
Peter Hinz56885f32011-03-02 22:03:47 +00001370libwebsocket_canonical_hostname(struct libwebsocket_context *context)
Andy Green2ac5a6f2011-01-28 10:00:18 +00001371{
Peter Hinz56885f32011-03-02 22:03:47 +00001372 return (const char *)context->canonical_hostname;
Andy Green2ac5a6f2011-01-28 10:00:18 +00001373}
1374
1375
Andy Green90c7cbc2011-01-27 06:26:52 +00001376static void sigpipe_handler(int x)
1377{
1378}
1379
Andy Green6901cb32011-02-21 08:06:47 +00001380#ifdef LWS_OPENSSL_SUPPORT
1381static int
1382OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
1383{
1384
1385 SSL *ssl;
1386 int n;
Andy Green2e24da02011-03-05 16:12:04 +00001387 struct libwebsocket_context *context;
Andy Green6901cb32011-02-21 08:06:47 +00001388
1389 ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
1390 SSL_get_ex_data_X509_STORE_CTX_idx());
1391
1392 /*
Andy Green2e24da02011-03-05 16:12:04 +00001393 * !!! nasty openssl requires the index to come as a library-scope
1394 * static
Andy Green6901cb32011-02-21 08:06:47 +00001395 */
Andy Green2e24da02011-03-05 16:12:04 +00001396 context = SSL_get_ex_data(ssl, openssl_websocket_private_data_index);
Andy Green6ee372f2012-04-09 15:09:01 +08001397
Peter Hinz56885f32011-03-02 22:03:47 +00001398 n = context->protocols[0].callback(NULL, NULL,
Andy Green6901cb32011-02-21 08:06:47 +00001399 LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
1400 x509_ctx, ssl, preverify_ok);
1401
1402 /* convert return code from 0 = OK to 1 = OK */
1403
1404 if (!n)
1405 n = 1;
1406 else
1407 n = 0;
1408
1409 return n;
1410}
1411#endif
1412
Andy Green706961d2013-01-17 16:50:35 +08001413int user_callback_handle_rxflow(callback_function callback_function,
1414 struct libwebsocket_context * context,
1415 struct libwebsocket *wsi,
1416 enum libwebsocket_callback_reasons reason, void *user,
1417 void *in, size_t len)
1418{
1419 int n;
1420
1421 n = callback_function(context, wsi, reason, user, in, len);
1422 if (n < 0)
1423 return n;
1424
1425 _libwebsocket_rx_flow_control(wsi);
1426
1427 return 0;
1428}
1429
Andy Greenb45993c2010-12-18 15:13:50 +00001430
Andy Greenab990e42010-10-31 12:42:52 +00001431/**
Andy Green4739e5c2011-01-22 12:51:57 +00001432 * libwebsocket_create_context() - Create the websocket handler
1433 * @port: Port to listen on... you can use 0 to suppress listening on
Andy Green6964bb52011-01-23 16:50:33 +00001434 * any port, that's what you want if you are not running a
1435 * websocket server at all but just using it as a client
Peter Hinz56885f32011-03-02 22:03:47 +00001436 * @interf: NULL to bind the listen socket to all interfaces, or the
Andy Green32375b72011-02-19 08:32:53 +00001437 * interface name, eg, "eth2"
Andy Green4f3943a2010-11-12 10:44:16 +00001438 * @protocols: Array of structures listing supported protocols and a protocol-
Andy Green8f037e42010-12-19 22:13:26 +00001439 * specific callback for each one. The list is ended with an
1440 * entry that has a NULL callback pointer.
Andy Green6964bb52011-01-23 16:50:33 +00001441 * It's not const because we write the owning_server member
Andy Greenc5114822011-03-06 10:29:35 +00001442 * @extensions: NULL or array of libwebsocket_extension structs listing the
Andy Green3182ece2013-01-20 17:08:31 +08001443 * extensions this context supports. If you configured with
1444 * --without-extensions, you should give NULL here.
Andy Green3faa9c72010-11-08 17:03:03 +00001445 * @ssl_cert_filepath: If libwebsockets was compiled to use ssl, and you want
Andy Green8f037e42010-12-19 22:13:26 +00001446 * to listen using SSL, set to the filepath to fetch the
1447 * server cert from, otherwise NULL for unencrypted
Andy Green3faa9c72010-11-08 17:03:03 +00001448 * @ssl_private_key_filepath: filepath to private key if wanting SSL mode,
Andy Green8f037e42010-12-19 22:13:26 +00001449 * else ignored
David Galeano2f82be82013-01-09 16:25:54 +08001450 * @ssl_ca_filepath: CA certificate filepath or NULL
Andy Green3faa9c72010-11-08 17:03:03 +00001451 * @gid: group id to change to after setting listen socket, or -1.
1452 * @uid: user id to change to after setting listen socket, or -1.
Andy Greenbfb051f2011-02-09 08:49:14 +00001453 * @options: 0, or LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK
Andy Green15e31f32012-10-19 18:36:28 +08001454 * @user: optional user pointer that can be recovered via the context
1455 * pointer using libwebsocket_context_user
Andy Green05464c62010-11-12 10:44:18 +00001456 *
Andy Green8f037e42010-12-19 22:13:26 +00001457 * This function creates the listening socket and takes care
1458 * of all initialization in one step.
1459 *
Andy Greene92cd172011-01-19 13:11:55 +00001460 * After initialization, it returns a struct libwebsocket_context * that
1461 * represents this server. After calling, user code needs to take care
1462 * of calling libwebsocket_service() with the context pointer to get the
1463 * server's sockets serviced. This can be done in the same process context
1464 * or a forked process, or another thread,
Andy Green05464c62010-11-12 10:44:18 +00001465 *
Andy Green8f037e42010-12-19 22:13:26 +00001466 * The protocol callback functions are called for a handful of events
1467 * including http requests coming in, websocket connections becoming
1468 * established, and data arriving; it's also called periodically to allow
1469 * async transmission.
1470 *
1471 * HTTP requests are sent always to the FIRST protocol in @protocol, since
1472 * at that time websocket protocol has not been negotiated. Other
1473 * protocols after the first one never see any HTTP callack activity.
1474 *
1475 * The server created is a simple http server by default; part of the
1476 * websocket standard is upgrading this http connection to a websocket one.
1477 *
1478 * This allows the same server to provide files like scripts and favicon /
1479 * images or whatever over http and dynamic data over websockets all in
1480 * one place; they're all handled in the user callback.
Andy Greenab990e42010-10-31 12:42:52 +00001481 */
Andy Green4ea60062010-10-30 12:15:07 +01001482
Andy Greene92cd172011-01-19 13:11:55 +00001483struct libwebsocket_context *
Peter Hinz56885f32011-03-02 22:03:47 +00001484libwebsocket_create_context(int port, const char *interf,
Andy Greenb45993c2010-12-18 15:13:50 +00001485 struct libwebsocket_protocols *protocols,
Andy Greend6e09112011-03-05 16:12:15 +00001486 struct libwebsocket_extension *extensions,
Andy Green8f037e42010-12-19 22:13:26 +00001487 const char *ssl_cert_filepath,
1488 const char *ssl_private_key_filepath,
David Galeano2f82be82013-01-09 16:25:54 +08001489 const char *ssl_ca_filepath,
Alon Levy0291eb32012-10-19 11:21:56 +02001490 int gid, int uid, unsigned int options,
David Galeano2f82be82013-01-09 16:25:54 +08001491 void *user)
Andy Greenff95d7a2010-10-28 22:36:01 +01001492{
1493 int n;
Peter Hinz56885f32011-03-02 22:03:47 +00001494 struct libwebsocket_context *context = NULL;
Andy Green9659f372011-01-27 22:01:43 +00001495 char *p;
Andy Greencbb31222013-01-31 09:57:05 +08001496#ifndef LWS_NO_SERVER
1497 int opt = 1;
Andy Green0d338332011-02-12 11:57:43 +00001498 struct libwebsocket *wsi;
Andy Greencbb31222013-01-31 09:57:05 +08001499 struct sockaddr_in serv_addr;
1500#endif
Andy Green3182ece2013-01-20 17:08:31 +08001501#ifndef LWS_NO_EXTENSIONS
1502 int m;
1503#endif
Andy Greenff95d7a2010-10-28 22:36:01 +01001504
Andy Green3faa9c72010-11-08 17:03:03 +00001505#ifdef LWS_OPENSSL_SUPPORT
Andy Greenf2f54d52010-11-15 22:08:00 +00001506 SSL_METHOD *method;
Andy Green3faa9c72010-11-08 17:03:03 +00001507 char ssl_err_buf[512];
Andy Green3faa9c72010-11-08 17:03:03 +00001508#endif
1509
Joakim Soderberg4c531232013-02-06 15:26:58 +09001510#ifndef LWS_NO_DAEMONIZE
Joakim Söderberg68e8d732013-02-06 15:27:39 +09001511 extern int get_daemonize_pid();
1512 int pid_daemon = get_daemonize_pid();
Joakim Soderberg4c531232013-02-06 15:26:58 +09001513#endif
1514
Andy Greenb3a614a2013-01-19 13:08:17 +08001515 lwsl_notice("Initial logging level %d\n", log_level);
Andy Green7b405452013-02-01 10:50:15 +08001516 lwsl_notice("Library version: %s\n", library_version);
Andy Greenc0d6b632013-01-12 23:42:17 +08001517 lwsl_info(" LWS_MAX_HEADER_NAME_LENGTH: %u\n", LWS_MAX_HEADER_NAME_LENGTH);
1518 lwsl_info(" LWS_MAX_HEADER_LEN: %u\n", LWS_MAX_HEADER_LEN);
1519 lwsl_info(" LWS_INITIAL_HDR_ALLOC: %u\n", LWS_INITIAL_HDR_ALLOC);
1520 lwsl_info(" LWS_ADDITIONAL_HDR_ALLOC: %u\n", LWS_ADDITIONAL_HDR_ALLOC);
1521 lwsl_info(" MAX_USER_RX_BUFFER: %u\n", MAX_USER_RX_BUFFER);
Andy Greenc0d6b632013-01-12 23:42:17 +08001522 lwsl_info(" LWS_MAX_PROTOCOLS: %u\n", LWS_MAX_PROTOCOLS);
Andy Green3182ece2013-01-20 17:08:31 +08001523#ifndef LWS_NO_EXTENSIONS
Andy Greenc0d6b632013-01-12 23:42:17 +08001524 lwsl_info(" LWS_MAX_EXTENSIONS_ACTIVE: %u\n", LWS_MAX_EXTENSIONS_ACTIVE);
Andy Green3182ece2013-01-20 17:08:31 +08001525#else
1526 lwsl_notice(" Configured without extension support\n");
1527#endif
Andy Greenc0d6b632013-01-12 23:42:17 +08001528 lwsl_info(" SPEC_LATEST_SUPPORTED: %u\n", SPEC_LATEST_SUPPORTED);
1529 lwsl_info(" AWAITING_TIMEOUT: %u\n", AWAITING_TIMEOUT);
1530 lwsl_info(" CIPHERS_LIST_STRING: '%s'\n", CIPHERS_LIST_STRING);
1531 lwsl_info(" SYSTEM_RANDOM_FILEPATH: '%s'\n", SYSTEM_RANDOM_FILEPATH);
1532 lwsl_info(" LWS_MAX_ZLIB_CONN_BUFFER: %u\n", LWS_MAX_ZLIB_CONN_BUFFER);
Andy Green43db0452013-01-10 19:50:35 +08001533
Peter Hinz56885f32011-03-02 22:03:47 +00001534#ifdef _WIN32
1535 {
1536 WORD wVersionRequested;
1537 WSADATA wsaData;
1538 int err;
Andy Green6ee372f2012-04-09 15:09:01 +08001539 HMODULE wsdll;
Peter Hinz56885f32011-03-02 22:03:47 +00001540
1541 /* Use the MAKEWORD(lowbyte, highbyte) macro from Windef.h */
1542 wVersionRequested = MAKEWORD(2, 2);
1543
1544 err = WSAStartup(wVersionRequested, &wsaData);
1545 if (err != 0) {
1546 /* Tell the user that we could not find a usable */
1547 /* Winsock DLL. */
Andy Green43db0452013-01-10 19:50:35 +08001548 lwsl_err("WSAStartup failed with error: %d\n", err);
Peter Hinz56885f32011-03-02 22:03:47 +00001549 return NULL;
1550 }
David Galeano7b11fec2011-10-04 19:55:18 +08001551
Andy Green6ee372f2012-04-09 15:09:01 +08001552 /* default to a poll() made out of select() */
1553 poll = emulated_poll;
David Galeano7b11fec2011-10-04 19:55:18 +08001554
Andy Green6ee372f2012-04-09 15:09:01 +08001555 /* if windows socket lib available, use his WSAPoll */
David Galeanocb193682013-01-09 15:29:00 +08001556 wsdll = GetModuleHandle(_T("Ws2_32.dll"));
Andy Green6ee372f2012-04-09 15:09:01 +08001557 if (wsdll)
1558 poll = (PFNWSAPOLL)GetProcAddress(wsdll, "WSAPoll");
Joakim Soderberg4c531232013-02-06 15:26:58 +09001559
Joakim Söderberg68e8d732013-02-06 15:27:39 +09001560 /* Finally fall back to emulated poll if all else fails */
Joakim Soderberg4c531232013-02-06 15:26:58 +09001561 if (!poll)
1562 poll = emulated_poll;
Peter Hinz56885f32011-03-02 22:03:47 +00001563 }
1564#endif
1565
Aaron Zinman4550f1d2013-01-10 12:35:18 +08001566 context = (struct libwebsocket_context *) malloc(sizeof(struct libwebsocket_context));
Peter Hinz56885f32011-03-02 22:03:47 +00001567 if (!context) {
Andy Green43db0452013-01-10 19:50:35 +08001568 lwsl_err("No memory for websocket context\n");
Andy Green90c7cbc2011-01-27 06:26:52 +00001569 return NULL;
1570 }
Peter Pentchev3b233cb2013-02-07 16:31:19 +02001571 memset(context, 0, sizeof(*context));
Andy Green35f332b2013-01-21 13:06:38 +08001572#ifndef LWS_NO_DAEMONIZE
Andy Green24cba922013-01-19 13:56:10 +08001573 context->started_with_parent = pid_daemon;
1574 lwsl_notice(" Started with daemon pid %d\n", pid_daemon);
1575#endif
Joakim Soderberg4c531232013-02-06 15:26:58 +09001576
1577 context->listen_service_extraseen = 0;
Peter Hinz56885f32011-03-02 22:03:47 +00001578 context->protocols = protocols;
1579 context->listen_port = port;
1580 context->http_proxy_port = 0;
1581 context->http_proxy_address[0] = '\0';
1582 context->options = options;
Andy Greendfb23042013-01-17 12:26:48 +08001583 /* to reduce this allocation, */
1584 context->max_fds = getdtablesize();
Andy Greenb3a614a2013-01-19 13:08:17 +08001585 lwsl_notice(" max fd tracked: %u\n", context->max_fds);
Andy Greena17c6922013-01-20 20:21:54 +08001586 lwsl_notice(" static allocation: %u bytes\n",
1587 (sizeof(struct pollfd) * context->max_fds) +
1588 (sizeof(struct libwebsocket *) * context->max_fds));
Andy Greendfb23042013-01-17 12:26:48 +08001589
1590 context->fds = (struct pollfd *)malloc(sizeof(struct pollfd) * context->max_fds);
1591 if (context->fds == NULL) {
1592 lwsl_err("Unable to allocate fds array for %d connections\n", context->max_fds);
1593 free(context);
1594 return NULL;
1595 }
Edwin van den Oetelaarf6eeabc2013-01-19 20:01:01 +08001596 context->lws_lookup = (struct libwebsocket **)malloc(sizeof(struct libwebsocket *) * context->max_fds);
Andy Greendfb23042013-01-17 12:26:48 +08001597 if (context->lws_lookup == NULL) {
1598 lwsl_err("Unable to allocate lws_lookup array for %d connections\n", context->max_fds);
1599 free(context->fds);
1600 free(context);
1601 return NULL;
1602 }
Andy Greena17c6922013-01-20 20:21:54 +08001603
Peter Hinz56885f32011-03-02 22:03:47 +00001604 context->fds_count = 0;
Andy Green3182ece2013-01-20 17:08:31 +08001605#ifndef LWS_NO_EXTENSIONS
Andy Greend6e09112011-03-05 16:12:15 +00001606 context->extensions = extensions;
Andy Green3182ece2013-01-20 17:08:31 +08001607#endif
Paulo Roberto Urio1e326632012-06-04 10:52:19 +08001608 context->last_timeout_check_s = 0;
Andy Greendfb23042013-01-17 12:26:48 +08001609 context->user_space = user;
Andy Green9659f372011-01-27 22:01:43 +00001610
Peter Hinz56885f32011-03-02 22:03:47 +00001611#ifdef WIN32
1612 context->fd_random = 0;
1613#else
1614 context->fd_random = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY);
1615 if (context->fd_random < 0) {
Andy Green43db0452013-01-10 19:50:35 +08001616 lwsl_err("Unable to open random device %s %d\n",
Peter Hinz56885f32011-03-02 22:03:47 +00001617 SYSTEM_RANDOM_FILEPATH, context->fd_random);
Peter Pentchev3b233cb2013-02-07 16:31:19 +02001618 goto bail;
Andy Green44eee682011-02-10 09:32:24 +00001619 }
Peter Hinz56885f32011-03-02 22:03:47 +00001620#endif
Andy Green44eee682011-02-10 09:32:24 +00001621
Peter Hinz56885f32011-03-02 22:03:47 +00001622#ifdef LWS_OPENSSL_SUPPORT
1623 context->use_ssl = 0;
1624 context->ssl_ctx = NULL;
1625 context->ssl_client_ctx = NULL;
Andy Green2e24da02011-03-05 16:12:04 +00001626 openssl_websocket_private_data_index = 0;
Peter Hinz56885f32011-03-02 22:03:47 +00001627#endif
Andy Green2ac5a6f2011-01-28 10:00:18 +00001628
Andy Greena1ce6be2013-01-18 11:43:21 +08001629 strcpy(context->canonical_hostname, "unknown");
Andy Greena69f0512012-05-03 12:32:38 +08001630
Andy Greena1ce6be2013-01-18 11:43:21 +08001631#ifndef LWS_NO_SERVER
1632 if (!(options & LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME)) {
1633 struct sockaddr sa;
1634 char hostname[1024] = "";
Andy Green788c4a82012-10-22 12:29:57 +01001635
1636 /* find canonical hostname */
1637
1638 hostname[(sizeof hostname) - 1] = '\0';
1639 memset(&sa, 0, sizeof(sa));
1640 sa.sa_family = AF_INET;
1641 sa.sa_data[(sizeof sa.sa_data) - 1] = '\0';
1642 gethostname(hostname, (sizeof hostname) - 1);
1643
1644 n = 0;
1645
David Galeanoed3c8402013-01-10 10:45:24 +08001646 if (strlen(hostname) < sizeof(sa.sa_data) - 1) {
Andy Green788c4a82012-10-22 12:29:57 +01001647 strcpy(sa.sa_data, hostname);
Andy Greend09d7d42013-01-31 10:05:43 +08001648 lwsl_debug("my host name is %s\n", sa.sa_data);
Andy Green788c4a82012-10-22 12:29:57 +01001649 n = getnameinfo(&sa, sizeof(sa), hostname,
Andy Greend09d7d42013-01-31 10:05:43 +08001650 (sizeof hostname) - 1, NULL, 0, NI_NAMEREQD);
Andy Green788c4a82012-10-22 12:29:57 +01001651 }
1652
1653 if (!n) {
1654 strncpy(context->canonical_hostname, hostname,
1655 sizeof context->canonical_hostname - 1);
1656 context->canonical_hostname[
1657 sizeof context->canonical_hostname - 1] = '\0';
1658 } else
1659 strncpy(context->canonical_hostname, hostname,
1660 sizeof context->canonical_hostname - 1);
1661
Andy Greenb3a614a2013-01-19 13:08:17 +08001662 lwsl_notice(" canonical_hostname = %s\n", context->canonical_hostname);
Andy Greena69f0512012-05-03 12:32:38 +08001663 }
Andy Greena1ce6be2013-01-18 11:43:21 +08001664#endif
Andy Greena69f0512012-05-03 12:32:38 +08001665
Andy Green9659f372011-01-27 22:01:43 +00001666 /* split the proxy ads:port if given */
1667
1668 p = getenv("http_proxy");
1669 if (p) {
Peter Hinz56885f32011-03-02 22:03:47 +00001670 strncpy(context->http_proxy_address, p,
Andy Green6ee372f2012-04-09 15:09:01 +08001671 sizeof context->http_proxy_address - 1);
Peter Hinz56885f32011-03-02 22:03:47 +00001672 context->http_proxy_address[
1673 sizeof context->http_proxy_address - 1] = '\0';
Andy Green9659f372011-01-27 22:01:43 +00001674
Peter Hinz56885f32011-03-02 22:03:47 +00001675 p = strchr(context->http_proxy_address, ':');
Andy Green9659f372011-01-27 22:01:43 +00001676 if (p == NULL) {
Andy Green43db0452013-01-10 19:50:35 +08001677 lwsl_err("http_proxy needs to be ads:port\n");
Peter Pentchev3b233cb2013-02-07 16:31:19 +02001678 goto bail;
Andy Green9659f372011-01-27 22:01:43 +00001679 }
1680 *p = '\0';
Peter Hinz56885f32011-03-02 22:03:47 +00001681 context->http_proxy_port = atoi(p + 1);
Andy Green9659f372011-01-27 22:01:43 +00001682
Andy Greenb3a614a2013-01-19 13:08:17 +08001683 lwsl_notice(" Proxy %s:%u\n",
Peter Hinz56885f32011-03-02 22:03:47 +00001684 context->http_proxy_address,
1685 context->http_proxy_port);
Andy Green9659f372011-01-27 22:01:43 +00001686 }
Andy Green90c7cbc2011-01-27 06:26:52 +00001687
Andy Greena1ce6be2013-01-18 11:43:21 +08001688#ifndef LWS_NO_SERVER
Andy Green90c7cbc2011-01-27 06:26:52 +00001689 if (port) {
1690
Andy Green3faa9c72010-11-08 17:03:03 +00001691#ifdef LWS_OPENSSL_SUPPORT
Peter Hinz56885f32011-03-02 22:03:47 +00001692 context->use_ssl = ssl_cert_filepath != NULL &&
Andy Green90c7cbc2011-01-27 06:26:52 +00001693 ssl_private_key_filepath != NULL;
Andy Green23c5f2e2013-02-06 15:43:00 +09001694#ifdef USE_CYASSL
1695 lwsl_notice(" Compiled with CYASSL support\n");
1696#else
1697 lwsl_notice(" Compiled with OpenSSL support\n");
1698#endif
Peter Hinz56885f32011-03-02 22:03:47 +00001699 if (context->use_ssl)
Andy Green23c5f2e2013-02-06 15:43:00 +09001700 lwsl_notice(" Using SSL mode\n");
Andy Green90c7cbc2011-01-27 06:26:52 +00001701 else
Andy Green23c5f2e2013-02-06 15:43:00 +09001702 lwsl_notice(" Using non-SSL mode\n");
Andy Green3faa9c72010-11-08 17:03:03 +00001703
Andy Green90c7cbc2011-01-27 06:26:52 +00001704#else
1705 if (ssl_cert_filepath != NULL &&
1706 ssl_private_key_filepath != NULL) {
Andy Greenb3a614a2013-01-19 13:08:17 +08001707 lwsl_notice(" Not compiled for OpenSSl support!\n");
Peter Pentchev3b233cb2013-02-07 16:31:19 +02001708 goto bail;
Andy Green3faa9c72010-11-08 17:03:03 +00001709 }
Andy Greenb3a614a2013-01-19 13:08:17 +08001710 lwsl_notice(" Compiled without SSL support, "
Andy Green90c7cbc2011-01-27 06:26:52 +00001711 "serving unencrypted\n");
1712#endif
Andy Greena17c6922013-01-20 20:21:54 +08001713
1714 lwsl_notice(" per-connection allocation: %u + headers\n", sizeof(struct libwebsocket));
Andy Green90c7cbc2011-01-27 06:26:52 +00001715 }
Andy Greena1ce6be2013-01-18 11:43:21 +08001716#endif
Andy Green90c7cbc2011-01-27 06:26:52 +00001717
1718 /* ignore SIGPIPE */
Peter Hinz56885f32011-03-02 22:03:47 +00001719#ifdef WIN32
1720#else
Andy Green90c7cbc2011-01-27 06:26:52 +00001721 signal(SIGPIPE, sigpipe_handler);
Peter Hinz56885f32011-03-02 22:03:47 +00001722#endif
Andy Green90c7cbc2011-01-27 06:26:52 +00001723
1724
1725#ifdef LWS_OPENSSL_SUPPORT
1726
1727 /* basic openssl init */
1728
1729 SSL_library_init();
1730
1731 OpenSSL_add_all_algorithms();
1732 SSL_load_error_strings();
1733
Andy Green2e24da02011-03-05 16:12:04 +00001734 openssl_websocket_private_data_index =
Andy Green6901cb32011-02-21 08:06:47 +00001735 SSL_get_ex_new_index(0, "libwebsockets", NULL, NULL, NULL);
1736
Andy Green90c7cbc2011-01-27 06:26:52 +00001737 /*
1738 * Firefox insists on SSLv23 not SSLv3
1739 * Konq disables SSLv2 by default now, SSLv23 works
1740 */
1741
1742 method = (SSL_METHOD *)SSLv23_server_method();
1743 if (!method) {
Andy Green43db0452013-01-10 19:50:35 +08001744 lwsl_err("problem creating ssl method: %s\n",
Andy Green90c7cbc2011-01-27 06:26:52 +00001745 ERR_error_string(ERR_get_error(), ssl_err_buf));
Peter Pentchev3b233cb2013-02-07 16:31:19 +02001746 goto bail;
Andy Green90c7cbc2011-01-27 06:26:52 +00001747 }
Peter Hinz56885f32011-03-02 22:03:47 +00001748 context->ssl_ctx = SSL_CTX_new(method); /* create context */
1749 if (!context->ssl_ctx) {
Andy Green43db0452013-01-10 19:50:35 +08001750 lwsl_err("problem creating ssl context: %s\n",
Andy Green90c7cbc2011-01-27 06:26:52 +00001751 ERR_error_string(ERR_get_error(), ssl_err_buf));
Peter Pentchev3b233cb2013-02-07 16:31:19 +02001752 goto bail;
Andy Green90c7cbc2011-01-27 06:26:52 +00001753 }
1754
David Galeanocc148e42013-01-10 10:18:59 +08001755#ifdef SSL_OP_NO_COMPRESSION
David Galeanoc72f6f92013-01-10 10:11:57 +08001756 SSL_CTX_set_options(context->ssl_ctx, SSL_OP_NO_COMPRESSION);
David Galeanocc148e42013-01-10 10:18:59 +08001757#endif
David Galeano77a677c2013-01-10 10:14:12 +08001758 SSL_CTX_set_options(context->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
David Galeanof177f2a2013-01-10 10:15:19 +08001759 SSL_CTX_set_cipher_list(context->ssl_ctx, CIPHERS_LIST_STRING);
David Galeanoc72f6f92013-01-10 10:11:57 +08001760
Andy Greena1ce6be2013-01-18 11:43:21 +08001761#ifndef LWS_NO_CLIENT
1762
Andy Green90c7cbc2011-01-27 06:26:52 +00001763 /* client context */
Andy Green6ee372f2012-04-09 15:09:01 +08001764
1765 if (port == CONTEXT_PORT_NO_LISTEN) {
Peter Hinz56885f32011-03-02 22:03:47 +00001766 method = (SSL_METHOD *)SSLv23_client_method();
1767 if (!method) {
Andy Green43db0452013-01-10 19:50:35 +08001768 lwsl_err("problem creating ssl method: %s\n",
Peter Hinz56885f32011-03-02 22:03:47 +00001769 ERR_error_string(ERR_get_error(), ssl_err_buf));
Peter Pentchev3b233cb2013-02-07 16:31:19 +02001770 goto bail;
Peter Hinz56885f32011-03-02 22:03:47 +00001771 }
1772 /* create context */
1773 context->ssl_client_ctx = SSL_CTX_new(method);
1774 if (!context->ssl_client_ctx) {
Andy Green43db0452013-01-10 19:50:35 +08001775 lwsl_err("problem creating ssl context: %s\n",
Peter Hinz56885f32011-03-02 22:03:47 +00001776 ERR_error_string(ERR_get_error(), ssl_err_buf));
Peter Pentchev3b233cb2013-02-07 16:31:19 +02001777 goto bail;
Peter Hinz56885f32011-03-02 22:03:47 +00001778 }
Andy Green90c7cbc2011-01-27 06:26:52 +00001779
David Galeanocc148e42013-01-10 10:18:59 +08001780#ifdef SSL_OP_NO_COMPRESSION
David Galeanoc72f6f92013-01-10 10:11:57 +08001781 SSL_CTX_set_options(context->ssl_client_ctx, SSL_OP_NO_COMPRESSION);
David Galeanocc148e42013-01-10 10:18:59 +08001782#endif
David Galeano77a677c2013-01-10 10:14:12 +08001783 SSL_CTX_set_options(context->ssl_client_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
David Galeanof177f2a2013-01-10 10:15:19 +08001784 SSL_CTX_set_cipher_list(context->ssl_client_ctx, CIPHERS_LIST_STRING);
David Galeanoc72f6f92013-01-10 10:11:57 +08001785
Peter Hinz56885f32011-03-02 22:03:47 +00001786 /* openssl init for cert verification (for client sockets) */
David Galeano2f82be82013-01-09 16:25:54 +08001787 if (!ssl_ca_filepath) {
1788 if (!SSL_CTX_load_verify_locations(
1789 context->ssl_client_ctx, NULL,
1790 LWS_OPENSSL_CLIENT_CERTS))
Andy Green43db0452013-01-10 19:50:35 +08001791 lwsl_err(
David Galeano2f82be82013-01-09 16:25:54 +08001792 "Unable to load SSL Client certs from %s "
1793 "(set by --with-client-cert-dir= in configure) -- "
1794 " client ssl isn't going to work",
1795 LWS_OPENSSL_CLIENT_CERTS);
1796 } else
1797 if (!SSL_CTX_load_verify_locations(
1798 context->ssl_client_ctx, ssl_ca_filepath,
1799 NULL))
Andy Green43db0452013-01-10 19:50:35 +08001800 lwsl_err(
David Galeano2f82be82013-01-09 16:25:54 +08001801 "Unable to load SSL Client certs "
1802 "file from %s -- client ssl isn't "
1803 "going to work", ssl_ca_filepath);
Peter Hinz56885f32011-03-02 22:03:47 +00001804
1805 /*
1806 * callback allowing user code to load extra verification certs
1807 * helping the client to verify server identity
1808 */
1809
1810 context->protocols[0].callback(context, NULL,
1811 LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
1812 context->ssl_client_ctx, NULL, 0);
Andy Green90c7cbc2011-01-27 06:26:52 +00001813 }
Andy Greena1ce6be2013-01-18 11:43:21 +08001814#endif
Andy Green6ee372f2012-04-09 15:09:01 +08001815
Andy Greenc6bf2c22011-02-20 11:10:47 +00001816 /* as a server, are we requiring clients to identify themselves? */
1817
1818 if (options & LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT) {
1819
1820 /* absolutely require the client cert */
Andy Green6ee372f2012-04-09 15:09:01 +08001821
Peter Hinz56885f32011-03-02 22:03:47 +00001822 SSL_CTX_set_verify(context->ssl_ctx,
Andy Green6901cb32011-02-21 08:06:47 +00001823 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1824 OpenSSL_verify_callback);
Andy Greenc6bf2c22011-02-20 11:10:47 +00001825
1826 /*
1827 * give user code a chance to load certs into the server
1828 * allowing it to verify incoming client certs
1829 */
1830
Peter Hinz56885f32011-03-02 22:03:47 +00001831 context->protocols[0].callback(context, NULL,
Andy Greenc6bf2c22011-02-20 11:10:47 +00001832 LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
Peter Hinz56885f32011-03-02 22:03:47 +00001833 context->ssl_ctx, NULL, 0);
Andy Greenc6bf2c22011-02-20 11:10:47 +00001834 }
1835
Peter Hinz56885f32011-03-02 22:03:47 +00001836 if (context->use_ssl) {
Andy Green90c7cbc2011-01-27 06:26:52 +00001837
1838 /* openssl init for server sockets */
1839
Andy Green3faa9c72010-11-08 17:03:03 +00001840 /* set the local certificate from CertFile */
David Galeano9b3d4b22013-01-10 10:11:21 +08001841 n = SSL_CTX_use_certificate_chain_file(context->ssl_ctx,
1842 ssl_cert_filepath);
Andy Green3faa9c72010-11-08 17:03:03 +00001843 if (n != 1) {
Andy Green43db0452013-01-10 19:50:35 +08001844 lwsl_err("problem getting cert '%s': %s\n",
Andy Green3faa9c72010-11-08 17:03:03 +00001845 ssl_cert_filepath,
1846 ERR_error_string(ERR_get_error(), ssl_err_buf));
Peter Pentchev3b233cb2013-02-07 16:31:19 +02001847 goto bail;
Andy Green3faa9c72010-11-08 17:03:03 +00001848 }
1849 /* set the private key from KeyFile */
Peter Hinz56885f32011-03-02 22:03:47 +00001850 if (SSL_CTX_use_PrivateKey_file(context->ssl_ctx,
1851 ssl_private_key_filepath, SSL_FILETYPE_PEM) != 1) {
Andy Green43db0452013-01-10 19:50:35 +08001852 lwsl_err("ssl problem getting key '%s': %s\n",
Andy Green018d8eb2010-11-08 21:04:23 +00001853 ssl_private_key_filepath,
1854 ERR_error_string(ERR_get_error(), ssl_err_buf));
Peter Pentchev3b233cb2013-02-07 16:31:19 +02001855 goto bail;
Andy Green3faa9c72010-11-08 17:03:03 +00001856 }
1857 /* verify private key */
Peter Hinz56885f32011-03-02 22:03:47 +00001858 if (!SSL_CTX_check_private_key(context->ssl_ctx)) {
Andy Green43db0452013-01-10 19:50:35 +08001859 lwsl_err("Private SSL key doesn't match cert\n");
Peter Pentchev3b233cb2013-02-07 16:31:19 +02001860 goto bail;
Andy Green3faa9c72010-11-08 17:03:03 +00001861 }
1862
1863 /* SSL is happy and has a cert it's content with */
1864 }
1865#endif
Andy Greenb45993c2010-12-18 15:13:50 +00001866
Andy Greendf736162011-01-18 15:39:02 +00001867 /* selftest */
1868
1869 if (lws_b64_selftest())
Peter Pentchev3b233cb2013-02-07 16:31:19 +02001870 goto bail;
Andy Greendf736162011-01-18 15:39:02 +00001871
Andy Greena1ce6be2013-01-18 11:43:21 +08001872#ifndef LWS_NO_SERVER
Andy Greenb45993c2010-12-18 15:13:50 +00001873 /* set up our external listening socket we serve on */
Andy Green8f037e42010-12-19 22:13:26 +00001874
Andy Green4739e5c2011-01-22 12:51:57 +00001875 if (port) {
Andy Greena1ce6be2013-01-18 11:43:21 +08001876 extern int interface_to_sa(const char *ifname, struct sockaddr_in *addr, size_t addrlen);
1877 int sockfd;
Andy Green8f037e42010-12-19 22:13:26 +00001878
Andy Green4739e5c2011-01-22 12:51:57 +00001879 sockfd = socket(AF_INET, SOCK_STREAM, 0);
1880 if (sockfd < 0) {
Andy Greenf7609e92013-01-14 13:10:55 +08001881 lwsl_err("ERROR opening socket\n");
Peter Pentchev3b233cb2013-02-07 16:31:19 +02001882 goto bail;
Andy Green4739e5c2011-01-22 12:51:57 +00001883 }
Andy Green775c0dd2010-10-29 14:15:22 +01001884
Joakim Soderberg4c531232013-02-06 15:26:58 +09001885#ifndef WIN32
1886 /* allow us to restart even if old sockets in TIME_WAIT
1887 * (REUSEADDR on Unix means, "don't hang on to this address after the
1888 * listener is closed." On Windows, though, it means "don't keep other
1889 * processes from binding to this address while we're using it) */
Andy Green6ee372f2012-04-09 15:09:01 +08001890 setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
1891 (const void *)&opt, sizeof(opt));
Joakim Soderberg4c531232013-02-06 15:26:58 +09001892#endif
Andy Green6c939552011-03-08 08:56:57 +00001893
1894 /* Disable Nagle */
1895 opt = 1;
Andy Green6ee372f2012-04-09 15:09:01 +08001896 setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY,
1897 (const void *)&opt, sizeof(opt));
Andy Green6c939552011-03-08 08:56:57 +00001898
Joakim Soderberg4c531232013-02-06 15:26:58 +09001899 #ifdef WIN32
1900 opt = 0;
1901 ioctlsocket(sockfd, FIONBIO, (unsigned long *)&opt );
1902 #else
Andy Greene2160712013-01-28 12:19:10 +08001903 fcntl(sockfd, F_SETFL, O_NONBLOCK);
Joakim Soderberg4c531232013-02-06 15:26:58 +09001904 #endif
Andy Greene2160712013-01-28 12:19:10 +08001905
Andy Green4739e5c2011-01-22 12:51:57 +00001906 bzero((char *) &serv_addr, sizeof(serv_addr));
1907 serv_addr.sin_family = AF_INET;
Peter Hinz56885f32011-03-02 22:03:47 +00001908 if (interf == NULL)
Andy Green32375b72011-02-19 08:32:53 +00001909 serv_addr.sin_addr.s_addr = INADDR_ANY;
1910 else
Peter Hinz56885f32011-03-02 22:03:47 +00001911 interface_to_sa(interf, &serv_addr,
Andy Green32375b72011-02-19 08:32:53 +00001912 sizeof(serv_addr));
Andy Green4739e5c2011-01-22 12:51:57 +00001913 serv_addr.sin_port = htons(port);
1914
1915 n = bind(sockfd, (struct sockaddr *) &serv_addr,
1916 sizeof(serv_addr));
1917 if (n < 0) {
Andy Green43db0452013-01-10 19:50:35 +08001918 lwsl_err("ERROR on binding to port %d (%d %d)\n",
Andy Green8f037e42010-12-19 22:13:26 +00001919 port, n, errno);
Andy Green41c58032013-01-12 13:21:08 +08001920 close(sockfd);
Peter Pentchev3b233cb2013-02-07 16:31:19 +02001921 goto bail;
Andy Green4739e5c2011-01-22 12:51:57 +00001922 }
Andy Green0d338332011-02-12 11:57:43 +00001923
Aaron Zinman4550f1d2013-01-10 12:35:18 +08001924 wsi = (struct libwebsocket *)malloc(sizeof(struct libwebsocket));
Andy Green41c58032013-01-12 13:21:08 +08001925 if (wsi == NULL) {
1926 lwsl_err("Out of mem\n");
1927 close(sockfd);
Peter Pentchev3b233cb2013-02-07 16:31:19 +02001928 goto bail;
Andy Green41c58032013-01-12 13:21:08 +08001929 }
Aaron Zinman4550f1d2013-01-10 12:35:18 +08001930 memset(wsi, 0, sizeof (struct libwebsocket));
Andy Green0d338332011-02-12 11:57:43 +00001931 wsi->sock = sockfd;
Andy Green3182ece2013-01-20 17:08:31 +08001932#ifndef LWS_NO_EXTENSIONS
Andy Greend6e09112011-03-05 16:12:15 +00001933 wsi->count_active_extensions = 0;
Andy Green3182ece2013-01-20 17:08:31 +08001934#endif
Andy Green0d338332011-02-12 11:57:43 +00001935 wsi->mode = LWS_CONNMODE_SERVER_LISTENER;
Andy Greendfb23042013-01-17 12:26:48 +08001936
1937 insert_wsi_socket_into_fds(context, wsi);
Andy Green0d338332011-02-12 11:57:43 +00001938
Andy Green65b0e912013-01-16 07:59:47 +08001939 context->listen_service_modulo = LWS_LISTEN_SERVICE_MODULO;
1940 context->listen_service_count = 0;
1941 context->listen_service_fd = sockfd;
1942
Andy Greena824d182013-01-15 20:52:29 +08001943 listen(sockfd, LWS_SOMAXCONN);
Andy Greenb3a614a2013-01-19 13:08:17 +08001944 lwsl_notice(" Listening on port %d\n", port);
Andy Green8f037e42010-12-19 22:13:26 +00001945 }
Andy Greena1ce6be2013-01-18 11:43:21 +08001946#endif
Andy Greenb45993c2010-12-18 15:13:50 +00001947
Andy Green6ee372f2012-04-09 15:09:01 +08001948 /*
1949 * drop any root privs for this process
1950 * to listen on port < 1023 we would have needed root, but now we are
1951 * listening, we don't want the power for anything else
1952 */
Peter Hinz56885f32011-03-02 22:03:47 +00001953#ifdef WIN32
1954#else
Andy Green3faa9c72010-11-08 17:03:03 +00001955 if (gid != -1)
1956 if (setgid(gid))
Andy Green43db0452013-01-10 19:50:35 +08001957 lwsl_warn("setgid: %s\n", strerror(errno));
Andy Green3faa9c72010-11-08 17:03:03 +00001958 if (uid != -1)
1959 if (setuid(uid))
Andy Green43db0452013-01-10 19:50:35 +08001960 lwsl_warn("setuid: %s\n", strerror(errno));
Peter Hinz56885f32011-03-02 22:03:47 +00001961#endif
Andy Greenb45993c2010-12-18 15:13:50 +00001962
Andy Green6f520a52013-01-29 17:57:39 +08001963 /* initialize supported protocols */
Andy Greenb45993c2010-12-18 15:13:50 +00001964
Peter Hinz56885f32011-03-02 22:03:47 +00001965 for (context->count_protocols = 0;
1966 protocols[context->count_protocols].callback;
1967 context->count_protocols++) {
Andy Green2d1301e2011-05-24 10:14:41 +01001968
Andy Green43db0452013-01-10 19:50:35 +08001969 lwsl_parser(" Protocol: %s\n",
1970 protocols[context->count_protocols].name);
Andy Green2d1301e2011-05-24 10:14:41 +01001971
Peter Hinz56885f32011-03-02 22:03:47 +00001972 protocols[context->count_protocols].owning_server = context;
1973 protocols[context->count_protocols].protocol_index =
1974 context->count_protocols;
Andy Greenb45993c2010-12-18 15:13:50 +00001975 }
Andy Greenf5bc1302013-01-21 09:09:52 +08001976
Andy Green3182ece2013-01-20 17:08:31 +08001977#ifndef LWS_NO_EXTENSIONS
Andy Greena41314f2011-05-23 10:00:03 +01001978 /*
1979 * give all extensions a chance to create any per-context
1980 * allocations they need
1981 */
1982
1983 m = LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT;
1984 if (port)
1985 m = LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT;
Andrew Chambersd5512172012-05-20 08:17:09 +08001986
1987 if (extensions) {
1988 while (extensions->callback) {
Andy Green43db0452013-01-10 19:50:35 +08001989 lwsl_ext(" Extension: %s\n", extensions->name);
Aaron Zinman4550f1d2013-01-10 12:35:18 +08001990 extensions->callback(context, extensions, NULL,
1991 (enum libwebsocket_extension_callback_reasons)m,
1992 NULL, NULL, 0);
Andrew Chambersd5512172012-05-20 08:17:09 +08001993 extensions++;
1994 }
Andy Greena41314f2011-05-23 10:00:03 +01001995 }
Andy Green3182ece2013-01-20 17:08:31 +08001996#endif
Peter Hinz56885f32011-03-02 22:03:47 +00001997 return context;
Peter Pentchev3b233cb2013-02-07 16:31:19 +02001998
1999bail:
2000 libwebsocket_context_destroy(context);
2001 return NULL;
Andy Greene92cd172011-01-19 13:11:55 +00002002}
Andy Greenb45993c2010-12-18 15:13:50 +00002003
Andy Greenb45993c2010-12-18 15:13:50 +00002004/**
2005 * libwebsockets_get_protocol() - Returns a protocol pointer from a websocket
Andy Green8f037e42010-12-19 22:13:26 +00002006 * connection.
Andy Greenb45993c2010-12-18 15:13:50 +00002007 * @wsi: pointer to struct websocket you want to know the protocol of
2008 *
Andy Green8f037e42010-12-19 22:13:26 +00002009 *
Andy Green6f520a52013-01-29 17:57:39 +08002010 * Some apis can act on all live connections of a given protocol,
2011 * this is how you can get a pointer to the active protocol if needed.
Andy Greenb45993c2010-12-18 15:13:50 +00002012 */
Andy Greenab990e42010-10-31 12:42:52 +00002013
Andy Greenb45993c2010-12-18 15:13:50 +00002014const struct libwebsocket_protocols *
2015libwebsockets_get_protocol(struct libwebsocket *wsi)
2016{
2017 return wsi->protocol;
2018}
2019
Andy Green82c3d542011-03-07 21:16:31 +00002020int
2021libwebsocket_is_final_fragment(struct libwebsocket *wsi)
2022{
Andy Green623a98d2013-01-21 11:04:23 +08002023 return wsi->u.ws.final;
Andy Green82c3d542011-03-07 21:16:31 +00002024}
Alex Bligh49146db2011-11-07 17:19:25 +08002025
David Galeanoe2cf9922013-01-09 18:06:55 +08002026unsigned char
2027libwebsocket_get_reserved_bits(struct libwebsocket *wsi)
2028{
Andy Green623a98d2013-01-21 11:04:23 +08002029 return wsi->u.ws.rsv;
David Galeanoe2cf9922013-01-09 18:06:55 +08002030}
2031
Alex Bligh49146db2011-11-07 17:19:25 +08002032void *
2033libwebsocket_ensure_user_space(struct libwebsocket *wsi)
2034{
2035 /* allocate the per-connection user memory (if any) */
2036
2037 if (wsi->protocol->per_session_data_size && !wsi->user_space) {
2038 wsi->user_space = malloc(
2039 wsi->protocol->per_session_data_size);
2040 if (wsi->user_space == NULL) {
Andy Green43db0452013-01-10 19:50:35 +08002041 lwsl_err("Out of memory for conn user space\n");
Alex Bligh49146db2011-11-07 17:19:25 +08002042 return NULL;
2043 }
Andy Green6ee372f2012-04-09 15:09:01 +08002044 memset(wsi->user_space, 0,
2045 wsi->protocol->per_session_data_size);
Alex Bligh49146db2011-11-07 17:19:25 +08002046 }
2047 return wsi->user_space;
2048}
Andy Green43db0452013-01-10 19:50:35 +08002049
Andy Green0b319092013-01-19 11:17:56 +08002050static void lwsl_emit_stderr(int level, const char *line)
Andy Greende8f27a2013-01-12 09:17:42 +08002051{
Andy Green0b319092013-01-19 11:17:56 +08002052 char buf[300];
2053 struct timeval tv;
Andy Green0b319092013-01-19 11:17:56 +08002054 int n;
2055
2056 gettimeofday(&tv, NULL);
2057
2058 buf[0] = '\0';
2059 for (n = 0; n < LLL_COUNT; n++)
2060 if (level == (1 << n)) {
Andy Green058ba812013-01-19 11:32:18 +08002061 sprintf(buf, "[%ld:%04d] %s: ", tv.tv_sec,
Andy Green0b319092013-01-19 11:17:56 +08002062 (int)(tv.tv_usec / 100), log_level_names[n]);
2063 break;
2064 }
2065
2066 fprintf(stderr, "%s%s", buf, line);
Andy Greende8f27a2013-01-12 09:17:42 +08002067}
2068
Joakim Soderberg4c531232013-02-06 15:26:58 +09002069#ifdef WIN32
2070void lwsl_emit_syslog(int level, const char *line)
2071{
2072 lwsl_emit_stderr(level, line);
2073}
2074#else
Andy Greenc11db202013-01-19 11:12:16 +08002075void lwsl_emit_syslog(int level, const char *line)
2076{
2077 int syslog_level = LOG_DEBUG;
2078
2079 switch (level) {
2080 case LLL_ERR:
2081 syslog_level = LOG_ERR;
2082 break;
2083 case LLL_WARN:
2084 syslog_level = LOG_WARNING;
2085 break;
2086 case LLL_NOTICE:
2087 syslog_level = LOG_NOTICE;
2088 break;
2089 case LLL_INFO:
2090 syslog_level = LOG_INFO;
2091 break;
2092 }
Edwin van den Oetelaarf6eeabc2013-01-19 20:01:01 +08002093 syslog(syslog_level, "%s", line);
Andy Greenc11db202013-01-19 11:12:16 +08002094}
Joakim Soderberg4c531232013-02-06 15:26:58 +09002095#endif
Andy Greenc11db202013-01-19 11:12:16 +08002096
Andy Green43db0452013-01-10 19:50:35 +08002097void _lws_log(int filter, const char *format, ...)
2098{
Andy Greende8f27a2013-01-12 09:17:42 +08002099 char buf[256];
Andy Green43db0452013-01-10 19:50:35 +08002100 va_list ap;
Andy Green43db0452013-01-10 19:50:35 +08002101
2102 if (!(log_level & filter))
2103 return;
2104
Andy Green43db0452013-01-10 19:50:35 +08002105 va_start(ap, format);
Andy Green0b319092013-01-19 11:17:56 +08002106 vsnprintf(buf, (sizeof buf), format, ap);
Andy Greende8f27a2013-01-12 09:17:42 +08002107 buf[(sizeof buf) - 1] = '\0';
2108 va_end(ap);
2109
Andy Green0b319092013-01-19 11:17:56 +08002110 lwsl_emit(filter, buf);
Andy Green43db0452013-01-10 19:50:35 +08002111}
2112
2113/**
2114 * lws_set_log_level() - Set the logging bitfield
2115 * @level: OR together the LLL_ debug contexts you want output from
Andy Greende8f27a2013-01-12 09:17:42 +08002116 * @log_emit_function: NULL to leave it as it is, or a user-supplied
2117 * function to perform log string emission instead of
2118 * the default stderr one.
Andy Green43db0452013-01-10 19:50:35 +08002119 *
Andy Greende8f27a2013-01-12 09:17:42 +08002120 * log level defaults to "err" and "warn" contexts enabled only and
2121 * emission on stderr.
Andy Green43db0452013-01-10 19:50:35 +08002122 */
2123
Andy Green058ba812013-01-19 11:32:18 +08002124void lws_set_log_level(int level, void (*log_emit_function)(int level, const char *line))
Andy Green43db0452013-01-10 19:50:35 +08002125{
2126 log_level = level;
Andy Greende8f27a2013-01-12 09:17:42 +08002127 if (log_emit_function)
2128 lwsl_emit = log_emit_function;
Andy Green43db0452013-01-10 19:50:35 +08002129}