blob: 4ed528a33fe3ca01bd17acfbfde43d161c368026 [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 Greenc11db202013-01-19 11:12:16 +080023#include <syslog.h>
Andy Greenff95d7a2010-10-28 22:36:01 +010024
Peter Hinz56885f32011-03-02 22:03:47 +000025#ifdef WIN32
David Galeanocb193682013-01-09 15:29:00 +080026#include <tchar.h>
27#include <io.h>
Peter Hinz56885f32011-03-02 22:03:47 +000028#else
Davidc4ef7b12013-01-12 20:39:47 +080029#ifdef LWS_BUILTIN_GETIFADDRS
30#include <getifaddrs.h>
31#else
Peter Hinz56885f32011-03-02 22:03:47 +000032#include <ifaddrs.h>
Davidc4ef7b12013-01-12 20:39:47 +080033#endif
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 Greenef660a92011-03-06 10:29:38 +0000351 /* free up his parsing allocations */
Andy Green4b6fbe12011-02-14 08:03:48 +0000352
Andy Green251f6fa2010-11-03 11:13:06 +0000353 for (n = 0; n < WSI_TOKEN_COUNT; n++)
354 if (wsi->utf8_token[n].token)
355 free(wsi->utf8_token[n].token);
Andy Greena1ce6be2013-01-18 11:43:21 +0800356#ifndef LWS_NO_CLIENT
Andy Greena41314f2011-05-23 10:00:03 +0100357 if (wsi->c_address)
358 free(wsi->c_address);
Andy Greena1ce6be2013-01-18 11:43:21 +0800359#endif
Andy Green623a98d2013-01-21 11:04:23 +0800360 if (wsi->u.ws.rxflow_buffer)
361 free(wsi->u.ws.rxflow_buffer);
Andy Green706961d2013-01-17 16:50:35 +0800362
Andy Green43db0452013-01-10 19:50:35 +0800363/* lwsl_info("closing fd=%d\n", wsi->sock); */
Andy Green251f6fa2010-11-03 11:13:06 +0000364
Andy Green3faa9c72010-11-08 17:03:03 +0000365#ifdef LWS_OPENSSL_SUPPORT
Andy Green90c7cbc2011-01-27 06:26:52 +0000366 if (wsi->ssl) {
Andy Green3faa9c72010-11-08 17:03:03 +0000367 n = SSL_get_fd(wsi->ssl);
368 SSL_shutdown(wsi->ssl);
Andy Green3fc2c652013-01-14 15:35:02 +0800369 compatible_close(n);
Andy Green3faa9c72010-11-08 17:03:03 +0000370 SSL_free(wsi->ssl);
371 } else {
372#endif
Andy Green0303db42013-01-17 14:46:43 +0800373 if (wsi->sock) {
374 n = shutdown(wsi->sock, SHUT_RDWR);
375 if (n)
376 lwsl_debug("closing: shutdown returned %d\n", errno);
Andy Green3fc2c652013-01-14 15:35:02 +0800377
Andy Green0303db42013-01-17 14:46:43 +0800378 n = compatible_close(wsi->sock);
379 if (n)
380 lwsl_debug("closing: close returned %d\n", errno);
381 }
Andy Green3faa9c72010-11-08 17:03:03 +0000382#ifdef LWS_OPENSSL_SUPPORT
383 }
384#endif
David Brooks2c60d952012-04-20 12:19:01 +0800385 if (wsi->protocol && wsi->protocol->per_session_data_size && wsi->user_space) /* user code may own */
Andy Green4f3943a2010-11-12 10:44:16 +0000386 free(wsi->user_space);
387
Andy Green251f6fa2010-11-03 11:13:06 +0000388 free(wsi);
389}
390
Andy Green07034092011-02-13 08:37:12 +0000391/**
Andy Greenf7ee5492011-02-13 09:04:21 +0000392 * libwebsockets_hangup_on_client() - Server calls to terminate client
Andy Green6ee372f2012-04-09 15:09:01 +0800393 * connection
Peter Hinz56885f32011-03-02 22:03:47 +0000394 * @context: libwebsockets context
Andy Greenf7ee5492011-02-13 09:04:21 +0000395 * @fd: Connection socket descriptor
396 */
397
398void
Peter Hinz56885f32011-03-02 22:03:47 +0000399libwebsockets_hangup_on_client(struct libwebsocket_context *context, int fd)
Andy Greenf7ee5492011-02-13 09:04:21 +0000400{
Andy Greendfb23042013-01-17 12:26:48 +0800401 struct libwebsocket *wsi = context->lws_lookup[fd];
Andy Greenf7ee5492011-02-13 09:04:21 +0000402
Andy Greendfb23042013-01-17 12:26:48 +0800403 if (wsi) {
Andy Green467c7ef2013-01-30 12:28:34 +0800404 lwsl_info("closing connection at libwebsockets_hangup_on_client:\n");
Andy Greendfb23042013-01-17 12:26:48 +0800405 libwebsocket_close_and_free_session(context,
406 wsi, LWS_CLOSE_STATUS_NOSTATUS);
407 } else
408 close(fd);
Andy Greenf7ee5492011-02-13 09:04:21 +0000409}
410
411
412/**
Andy Green07034092011-02-13 08:37:12 +0000413 * libwebsockets_get_peer_addresses() - Get client address information
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800414 * @context: Libwebsockets context
415 * @wsi: Local struct libwebsocket associated with
Andy Green07034092011-02-13 08:37:12 +0000416 * @fd: Connection socket descriptor
417 * @name: Buffer to take client address name
418 * @name_len: Length of client address name buffer
419 * @rip: Buffer to take client address IP qotted quad
420 * @rip_len: Length of client address IP buffer
421 *
422 * This function fills in @name and @rip with the name and IP of
Andy Green6ee372f2012-04-09 15:09:01 +0800423 * the client connected with socket descriptor @fd. Names may be
424 * truncated if there is not enough room. If either cannot be
425 * determined, they will be returned as valid zero-length strings.
Andy Green07034092011-02-13 08:37:12 +0000426 */
427
428void
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800429libwebsockets_get_peer_addresses(struct libwebsocket_context *context,
430 struct libwebsocket *wsi, int fd, char *name, int name_len,
Andy Green07034092011-02-13 08:37:12 +0000431 char *rip, int rip_len)
432{
433 unsigned int len;
434 struct sockaddr_in sin;
435 struct hostent *host;
436 struct hostent *host1;
437 char ip[128];
Andy Greenf92def72011-03-09 15:02:20 +0000438 unsigned char *p;
Andy Green07034092011-02-13 08:37:12 +0000439 int n;
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800440 int ret = -1;
David Galeanocb193682013-01-09 15:29:00 +0800441#ifdef AF_LOCAL
442 struct sockaddr_un *un;
443#endif
Andy Green07034092011-02-13 08:37:12 +0000444
445 rip[0] = '\0';
446 name[0] = '\0';
447
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800448 lws_latency_pre(context, wsi);
449
Andy Green07034092011-02-13 08:37:12 +0000450 len = sizeof sin;
451 if (getpeername(fd, (struct sockaddr *) &sin, &len) < 0) {
452 perror("getpeername");
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800453 goto bail;
Andy Green07034092011-02-13 08:37:12 +0000454 }
Andy Green6ee372f2012-04-09 15:09:01 +0800455
Andy Green07034092011-02-13 08:37:12 +0000456 host = gethostbyaddr((char *) &sin.sin_addr, sizeof sin.sin_addr,
457 AF_INET);
458 if (host == NULL) {
459 perror("gethostbyaddr");
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800460 goto bail;
Andy Green07034092011-02-13 08:37:12 +0000461 }
462
463 strncpy(name, host->h_name, name_len);
464 name[name_len - 1] = '\0';
465
466 host1 = gethostbyname(host->h_name);
467 if (host1 == NULL)
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800468 goto bail;
Andy Greenf92def72011-03-09 15:02:20 +0000469 p = (unsigned char *)host1;
Andy Green07034092011-02-13 08:37:12 +0000470 n = 0;
471 while (p != NULL) {
Andy Greenf92def72011-03-09 15:02:20 +0000472 p = (unsigned char *)host1->h_addr_list[n++];
Andy Green07034092011-02-13 08:37:12 +0000473 if (p == NULL)
474 continue;
Peter Hinzbb45a902011-03-10 18:14:01 +0000475 if ((host1->h_addrtype != AF_INET)
476#ifdef AF_LOCAL
477 && (host1->h_addrtype != AF_LOCAL)
478#endif
479 )
Andy Green07034092011-02-13 08:37:12 +0000480 continue;
481
Andy Green7627af52011-03-09 15:13:52 +0000482 if (host1->h_addrtype == AF_INET)
483 sprintf(ip, "%u.%u.%u.%u", p[0], p[1], p[2], p[3]);
Peter Hinzbb45a902011-03-10 18:14:01 +0000484#ifdef AF_LOCAL
Andy Green7627af52011-03-09 15:13:52 +0000485 else {
486 un = (struct sockaddr_un *)p;
Andy Green6ee372f2012-04-09 15:09:01 +0800487 strncpy(ip, un->sun_path, sizeof(ip) - 1);
Andy Green7627af52011-03-09 15:13:52 +0000488 ip[sizeof(ip) - 1] = '\0';
489 }
Peter Hinzbb45a902011-03-10 18:14:01 +0000490#endif
Andy Green07034092011-02-13 08:37:12 +0000491 p = NULL;
492 strncpy(rip, ip, rip_len);
493 rip[rip_len - 1] = '\0';
494 }
Andy Greenaaf0b9f2013-01-30 08:12:20 +0800495
496 ret = 0;
497bail:
498 lws_latency(context, wsi, "libwebsockets_get_peer_addresses", ret, 1);
Andy Green07034092011-02-13 08:37:12 +0000499}
Andy Green9f990342011-02-12 11:57:45 +0000500
Peter Hinz56885f32011-03-02 22:03:47 +0000501int libwebsockets_get_random(struct libwebsocket_context *context,
502 void *buf, int len)
503{
504 int n;
Aaron Zinman4550f1d2013-01-10 12:35:18 +0800505 char *p = (char *)buf;
Peter Hinz56885f32011-03-02 22:03:47 +0000506
507#ifdef WIN32
508 for (n = 0; n < len; n++)
509 p[n] = (unsigned char)rand();
510#else
511 n = read(context->fd_random, p, len);
512#endif
513
514 return n;
515}
516
Andy Green95a7b5d2011-03-06 10:29:39 +0000517int lws_send_pipe_choked(struct libwebsocket *wsi)
518{
519 struct pollfd fds;
520
521 fds.fd = wsi->sock;
522 fds.events = POLLOUT;
523 fds.revents = 0;
524
525 if (poll(&fds, 1, 0) != 1)
526 return 1;
527
528 if ((fds.revents & POLLOUT) == 0)
529 return 1;
530
531 /* okay to send another packet without blocking */
532
533 return 0;
534}
535
Andy Greena41314f2011-05-23 10:00:03 +0100536int
Andy Green3b84c002011-03-06 13:14:42 +0000537lws_handle_POLLOUT_event(struct libwebsocket_context *context,
538 struct libwebsocket *wsi, struct pollfd *pollfd)
539{
Andy Green3b84c002011-03-06 13:14:42 +0000540 int n;
Andy Green6f520a52013-01-29 17:57:39 +0800541
Andy Green3182ece2013-01-20 17:08:31 +0800542#ifndef LWS_NO_EXTENSIONS
543 struct lws_tokens eff_buf;
Andy Green3b84c002011-03-06 13:14:42 +0000544 int ret;
545 int m;
Andy Greena41314f2011-05-23 10:00:03 +0100546 int handled = 0;
Andy Green3b84c002011-03-06 13:14:42 +0000547
Andy Greena41314f2011-05-23 10:00:03 +0100548 for (n = 0; n < wsi->count_active_extensions; n++) {
549 if (!wsi->active_extensions[n]->callback)
550 continue;
551
552 m = wsi->active_extensions[n]->callback(context,
553 wsi->active_extensions[n], wsi,
554 LWS_EXT_CALLBACK_IS_WRITEABLE,
555 wsi->active_extensions_user[n], NULL, 0);
556 if (m > handled)
557 handled = m;
558 }
559
560 if (handled == 1)
561 goto notify_action;
562
563 if (!wsi->extension_data_pending || handled == 2)
Andy Green3b84c002011-03-06 13:14:42 +0000564 goto user_service;
565
566 /*
567 * check in on the active extensions, see if they
568 * had pending stuff to spill... they need to get the
569 * first look-in otherwise sequence will be disordered
570 *
571 * NULL, zero-length eff_buf means just spill pending
572 */
573
574 ret = 1;
575 while (ret == 1) {
576
577 /* default to nobody has more to spill */
578
579 ret = 0;
580 eff_buf.token = NULL;
581 eff_buf.token_len = 0;
582
583 /* give every extension a chance to spill */
584
585 for (n = 0; n < wsi->count_active_extensions; n++) {
586 m = wsi->active_extensions[n]->callback(
Andy Green46c2ea02011-03-22 09:04:01 +0000587 wsi->protocol->owning_server,
588 wsi->active_extensions[n], wsi,
Andy Green3b84c002011-03-06 13:14:42 +0000589 LWS_EXT_CALLBACK_PACKET_TX_PRESEND,
590 wsi->active_extensions_user[n], &eff_buf, 0);
591 if (m < 0) {
Andy Green43db0452013-01-10 19:50:35 +0800592 lwsl_err("ext reports fatal error\n");
Andy Green3b84c002011-03-06 13:14:42 +0000593 return -1;
594 }
595 if (m)
596 /*
597 * at least one extension told us he has more
598 * to spill, so we will go around again after
599 */
600 ret = 1;
601 }
602
603 /* assuming they gave us something to send, send it */
604
605 if (eff_buf.token_len) {
606 if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
607 eff_buf.token_len))
608 return -1;
609 } else
610 continue;
611
612 /* no extension has more to spill */
613
614 if (!ret)
615 continue;
616
617 /*
618 * There's more to spill from an extension, but we just sent
619 * something... did that leave the pipe choked?
620 */
621
622 if (!lws_send_pipe_choked(wsi))
623 /* no we could add more */
624 continue;
625
Andy Green43db0452013-01-10 19:50:35 +0800626 lwsl_info("choked in POLLOUT service\n");
Andy Green3b84c002011-03-06 13:14:42 +0000627
628 /*
629 * Yes, he's choked. Leave the POLLOUT masked on so we will
630 * come back here when he is unchoked. Don't call the user
631 * callback to enforce ordering of spilling, he'll get called
632 * when we come back here and there's nothing more to spill.
633 */
634
635 return 0;
636 }
637
638 wsi->extension_data_pending = 0;
639
640user_service:
Andy Green3182ece2013-01-20 17:08:31 +0800641#endif
Andy Green3b84c002011-03-06 13:14:42 +0000642 /* one shot */
643
Andy Greena41314f2011-05-23 10:00:03 +0100644 if (pollfd) {
645 pollfd->events &= ~POLLOUT;
Andy Green3b84c002011-03-06 13:14:42 +0000646
Andy Greena41314f2011-05-23 10:00:03 +0100647 /* external POLL support via protocol 0 */
648 context->protocols[0].callback(context, wsi,
649 LWS_CALLBACK_CLEAR_MODE_POLL_FD,
650 (void *)(long)wsi->sock, NULL, POLLOUT);
651 }
Andy Green3182ece2013-01-20 17:08:31 +0800652#ifndef LWS_NO_EXTENSIONS
Andy Greena41314f2011-05-23 10:00:03 +0100653notify_action:
Andy Green3182ece2013-01-20 17:08:31 +0800654#endif
Andy Green3b84c002011-03-06 13:14:42 +0000655
Andy Green9e4c2b62011-03-07 20:47:39 +0000656 if (wsi->mode == LWS_CONNMODE_WS_CLIENT)
657 n = LWS_CALLBACK_CLIENT_WRITEABLE;
658 else
659 n = LWS_CALLBACK_SERVER_WRITEABLE;
660
Andy Green706961d2013-01-17 16:50:35 +0800661 user_callback_handle_rxflow(wsi->protocol->callback, context,
662 wsi, (enum libwebsocket_callback_reasons) n, wsi->user_space, NULL, 0);
Andy Green3b84c002011-03-06 13:14:42 +0000663
664 return 0;
665}
666
667
668
Andy Greena41314f2011-05-23 10:00:03 +0100669void
670libwebsocket_service_timeout_check(struct libwebsocket_context *context,
671 struct libwebsocket *wsi, unsigned int sec)
672{
Andy Green3182ece2013-01-20 17:08:31 +0800673#ifndef LWS_NO_EXTENSIONS
Andy Greena41314f2011-05-23 10:00:03 +0100674 int n;
675
676 /*
677 * if extensions want in on it (eg, we are a mux parent)
678 * give them a chance to service child timeouts
679 */
680
681 for (n = 0; n < wsi->count_active_extensions; n++)
682 wsi->active_extensions[n]->callback(
683 context, wsi->active_extensions[n],
684 wsi, LWS_EXT_CALLBACK_1HZ,
685 wsi->active_extensions_user[n], NULL, sec);
686
Andy Green3182ece2013-01-20 17:08:31 +0800687#endif
Andy Greena41314f2011-05-23 10:00:03 +0100688 if (!wsi->pending_timeout)
689 return;
Andy Green6ee372f2012-04-09 15:09:01 +0800690
Andy Greena41314f2011-05-23 10:00:03 +0100691 /*
692 * if we went beyond the allowed time, kill the
693 * connection
694 */
695
696 if (sec > wsi->pending_timeout_limit) {
Andy Green43db0452013-01-10 19:50:35 +0800697 lwsl_info("TIMEDOUT WAITING\n");
Andy Greena41314f2011-05-23 10:00:03 +0100698 libwebsocket_close_and_free_session(context,
699 wsi, LWS_CLOSE_STATUS_NOSTATUS);
700 }
701}
702
Andy Green9f990342011-02-12 11:57:45 +0000703/**
704 * libwebsocket_service_fd() - Service polled socket with something waiting
Peter Hinz56885f32011-03-02 22:03:47 +0000705 * @context: Websocket context
Andy Green9f990342011-02-12 11:57:45 +0000706 * @pollfd: The pollfd entry describing the socket fd and which events
Andy Green6ee372f2012-04-09 15:09:01 +0800707 * happened.
Andy Green9f990342011-02-12 11:57:45 +0000708 *
Andy Green75006172013-01-22 12:32:11 +0800709 * This function takes a pollfd that has POLLIN or POLLOUT activity and
710 * services it according to the state of the associated struct libwebsocket.
711 *
712 * The one call deals with all "service" that might happen on a socket
713 * including listen accepts, http files as well as websocket protocol.
Andy Green9f990342011-02-12 11:57:45 +0000714 */
715
716int
Peter Hinz56885f32011-03-02 22:03:47 +0000717libwebsocket_service_fd(struct libwebsocket_context *context,
Andy Green0d338332011-02-12 11:57:43 +0000718 struct pollfd *pollfd)
Andy Greenb45993c2010-12-18 15:13:50 +0000719{
Andy Greena1ce6be2013-01-18 11:43:21 +0800720 struct libwebsocket *wsi;
Andy Greenb45993c2010-12-18 15:13:50 +0000721 int n;
Andy Green0d338332011-02-12 11:57:43 +0000722 int m;
Andy Greena71eafc2011-02-14 17:59:43 +0000723 struct timeval tv;
Andy Green6f520a52013-01-29 17:57:39 +0800724 unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 1 +
725 MAX_USER_RX_BUFFER + LWS_SEND_BUFFER_POST_PADDING];
Jack Mitchelldaed4fb2013-01-30 18:53:36 +0800726#ifdef LWS_OPENSSL_SUPPORT
Andy Green467c7ef2013-01-30 12:28:34 +0800727 char ssl_err_buf[512];
Jack Mitchelldaed4fb2013-01-30 18:53:36 +0800728#endif
Andy Green6f520a52013-01-29 17:57:39 +0800729
Andy Green3182ece2013-01-20 17:08:31 +0800730#ifndef LWS_NO_EXTENSIONS
Andy Green2366b1c2011-03-06 13:15:31 +0000731 int more = 1;
Andy Green3182ece2013-01-20 17:08:31 +0800732#endif
Andy Green98a717c2011-03-06 13:14:15 +0000733 struct lws_tokens eff_buf;
Andy Green03674a62013-01-16 11:47:40 +0800734#ifndef LWS_NO_CLIENT
Andy Green76f61e72013-01-16 11:53:05 +0800735 extern int lws_client_socket_service(struct libwebsocket_context *context, struct libwebsocket *wsi, struct pollfd *pollfd);
Andy Green03674a62013-01-16 11:47:40 +0800736#endif
Andy Greena1ce6be2013-01-18 11:43:21 +0800737#ifndef LWS_NO_SERVER
738 extern int lws_server_socket_service(struct libwebsocket_context *context, struct libwebsocket *wsi, struct pollfd *pollfd);
739#endif
Andy Greena71eafc2011-02-14 17:59:43 +0000740 /*
741 * you can call us with pollfd = NULL to just allow the once-per-second
742 * global timeout checks; if less than a second since the last check
743 * it returns immediately then.
744 */
745
746 gettimeofday(&tv, NULL);
747
Peter Hinz56885f32011-03-02 22:03:47 +0000748 if (context->last_timeout_check_s != tv.tv_sec) {
749 context->last_timeout_check_s = tv.tv_sec;
Andy Greena71eafc2011-02-14 17:59:43 +0000750
Andy Green24cba922013-01-19 13:56:10 +0800751 /* if our parent went down, don't linger around */
752 if (context->started_with_parent && kill(context->started_with_parent, 0) < 0)
753 kill(getpid(), SIGTERM);
754
Andy Greena71eafc2011-02-14 17:59:43 +0000755 /* global timeout check once per second */
756
Peter Hinz56885f32011-03-02 22:03:47 +0000757 for (n = 0; n < context->fds_count; n++) {
Andy Greendfb23042013-01-17 12:26:48 +0800758 struct libwebsocket *new_wsi = context->lws_lookup[context->fds[n].fd];
759 if (!new_wsi)
760 continue;
761 libwebsocket_service_timeout_check(context,
762 new_wsi, tv.tv_sec);
Andy Greena71eafc2011-02-14 17:59:43 +0000763 }
764 }
765
766 /* just here for timeout management? */
767
768 if (pollfd == NULL)
769 return 0;
770
771 /* no, here to service a socket descriptor */
772
Andy Green65b0e912013-01-16 07:59:47 +0800773 /*
774 * deal with listen service piggybacking
775 * every listen_service_modulo services of other fds, we
776 * sneak one in to service the listen socket if there's anything waiting
777 *
778 * To handle connection storms, as found in ab, if we previously saw a
779 * pending connection here, it causes us to check again next time.
780 */
781
782 if (context->listen_service_fd && pollfd->fd != context->listen_service_fd) {
783 context->listen_service_count++;
784 if (context->listen_service_extraseen ||
785 context->listen_service_count == context->listen_service_modulo) {
786 context->listen_service_count = 0;
787 m = 1;
788 if (context->listen_service_extraseen > 5)
789 m = 2;
790 while (m--) {
791 /* even with extpoll, we prepared this internal fds for listen */
792 n = poll(&context->fds[0], 1, 0);
793 if (n > 0) { /* there's a connection waiting for us */
794 libwebsocket_service_fd(context, &context->fds[0]);
795 context->listen_service_extraseen++;
796 } else {
797 if (context->listen_service_extraseen)
798 context->listen_service_extraseen--;
799 break;
800 }
801 }
802 }
803
804 }
805
806 /* okay, what we came here to do... */
807
Andy Greendfb23042013-01-17 12:26:48 +0800808 wsi = context->lws_lookup[pollfd->fd];
Andy Greend280b6e2013-01-15 13:40:23 +0800809 if (wsi == NULL) {
Andy Greendfb23042013-01-17 12:26:48 +0800810 if (pollfd->fd > 11)
811 lwsl_err("unexpected NULL wsi fd=%d fds_count=%d\n", pollfd->fd, context->fds_count);
Andy Greenfa3f4052012-10-07 20:40:35 +0800812 return 0;
Andy Greend280b6e2013-01-15 13:40:23 +0800813 }
Andy Green8f037e42010-12-19 22:13:26 +0000814
Andy Green0d338332011-02-12 11:57:43 +0000815 switch (wsi->mode) {
Andy Greend280b6e2013-01-15 13:40:23 +0800816
Andy Greena1ce6be2013-01-18 11:43:21 +0800817#ifndef LWS_NO_SERVER
Andy Greend280b6e2013-01-15 13:40:23 +0800818 case LWS_CONNMODE_HTTP_SERVING:
Andy Green0d338332011-02-12 11:57:43 +0000819 case LWS_CONNMODE_SERVER_LISTENER:
Andy Greene2160712013-01-28 12:19:10 +0800820 case LWS_CONNMODE_SSL_ACK_PENDING:
Andy Greena1ce6be2013-01-18 11:43:21 +0800821 return lws_server_socket_service(context, wsi, pollfd);
822#endif
Andy Greenbe93fef2011-02-14 20:25:43 +0000823
Andy Green0d338332011-02-12 11:57:43 +0000824 case LWS_CONNMODE_WS_SERVING:
825 case LWS_CONNMODE_WS_CLIENT:
826
827 /* handle session socket closed */
828
829 if (pollfd->revents & (POLLERR | POLLHUP)) {
830
Andy Green43db0452013-01-10 19:50:35 +0800831 lwsl_debug("Session Socket %p (fd=%d) dead\n",
Andy Green0d338332011-02-12 11:57:43 +0000832 (void *)wsi, pollfd->fd);
833
Peter Hinz56885f32011-03-02 22:03:47 +0000834 libwebsocket_close_and_free_session(context, wsi,
Andy Green687b0182011-02-26 11:04:01 +0000835 LWS_CLOSE_STATUS_NOSTATUS);
Andy Green040d2ef2013-01-16 13:40:43 +0800836 return 0;
Andy Greenb45993c2010-12-18 15:13:50 +0000837 }
838
Andy Green0d338332011-02-12 11:57:43 +0000839 /* the guy requested a callback when it was OK to write */
840
Andy Greenda527df2011-03-07 07:08:12 +0000841 if ((pollfd->revents & POLLOUT) &&
842 wsi->state == WSI_STATE_ESTABLISHED)
843 if (lws_handle_POLLOUT_event(context, wsi,
844 pollfd) < 0) {
845 libwebsocket_close_and_free_session(
846 context, wsi, LWS_CLOSE_STATUS_NORMAL);
Andy Green040d2ef2013-01-16 13:40:43 +0800847 return 0;
Andy Green3b84c002011-03-06 13:14:42 +0000848 }
Andy Green0d338332011-02-12 11:57:43 +0000849
Andy Green0d338332011-02-12 11:57:43 +0000850
851 /* any incoming data ready? */
852
853 if (!(pollfd->revents & POLLIN))
854 break;
855
Andy Greenb45993c2010-12-18 15:13:50 +0000856#ifdef LWS_OPENSSL_SUPPORT
David Galeano7ffbe1b2013-01-10 10:35:32 +0800857read_pending:
Andy Green467c7ef2013-01-30 12:28:34 +0800858 if (wsi->ssl) {
Andy Green98a717c2011-03-06 13:14:15 +0000859 eff_buf.token_len = SSL_read(wsi->ssl, buf, sizeof buf);
Andy Green467c7ef2013-01-30 12:28:34 +0800860 if (!eff_buf.token_len) {
861 n = SSL_get_error(wsi->ssl, eff_buf.token_len);
862 lwsl_err("SSL_read returned 0 with reason %s\n", ERR_error_string(n, ssl_err_buf));
863 }
864 } else
Andy Greenb45993c2010-12-18 15:13:50 +0000865#endif
Andy Green98a717c2011-03-06 13:14:15 +0000866 eff_buf.token_len =
Andy Green72c34322011-04-16 10:46:21 +0100867 recv(pollfd->fd, buf, sizeof buf, 0);
Andy Greenb45993c2010-12-18 15:13:50 +0000868
Andy Green98a717c2011-03-06 13:14:15 +0000869 if (eff_buf.token_len < 0) {
Andy Green43db0452013-01-10 19:50:35 +0800870 lwsl_debug("Socket read returned %d\n",
Andy Green98a717c2011-03-06 13:14:15 +0000871 eff_buf.token_len);
Alon Levydc93b7f2012-10-19 11:21:57 +0200872 if (errno != EINTR && errno != EAGAIN)
Andy Green6ee372f2012-04-09 15:09:01 +0800873 libwebsocket_close_and_free_session(context,
874 wsi, LWS_CLOSE_STATUS_NOSTATUS);
Andy Green040d2ef2013-01-16 13:40:43 +0800875 return 0;
Andy Greenb45993c2010-12-18 15:13:50 +0000876 }
Andy Green98a717c2011-03-06 13:14:15 +0000877 if (!eff_buf.token_len) {
Andy Green467c7ef2013-01-30 12:28:34 +0800878 lwsl_info("closing connection due to zero length read\n");
Peter Hinz56885f32011-03-02 22:03:47 +0000879 libwebsocket_close_and_free_session(context, wsi,
Andy Green6ee372f2012-04-09 15:09:01 +0800880 LWS_CLOSE_STATUS_NOSTATUS);
Andy Greenfa3f4052012-10-07 20:40:35 +0800881 return 0;
Andy Greenb45993c2010-12-18 15:13:50 +0000882 }
883
Andy Green98a717c2011-03-06 13:14:15 +0000884 /*
885 * give any active extensions a chance to munge the buffer
886 * before parse. We pass in a pointer to an lws_tokens struct
887 * prepared with the default buffer and content length that's in
888 * there. Rather than rewrite the default buffer, extensions
889 * that expect to grow the buffer can adapt .token to
890 * point to their own per-connection buffer in the extension
891 * user allocation. By default with no extensions or no
892 * extension callback handling, just the normal input buffer is
893 * used then so it is efficient.
894 */
Andy Greenb45993c2010-12-18 15:13:50 +0000895
Andy Green98a717c2011-03-06 13:14:15 +0000896 eff_buf.token = (char *)buf;
Andy Green3182ece2013-01-20 17:08:31 +0800897#ifndef LWS_NO_EXTENSIONS
Andy Green98a717c2011-03-06 13:14:15 +0000898 more = 1;
899 while (more) {
Andy Green0d338332011-02-12 11:57:43 +0000900
Andy Green98a717c2011-03-06 13:14:15 +0000901 more = 0;
902
903 for (n = 0; n < wsi->count_active_extensions; n++) {
Andy Green46c2ea02011-03-22 09:04:01 +0000904 m = wsi->active_extensions[n]->callback(context,
905 wsi->active_extensions[n], wsi,
Andy Green98a717c2011-03-06 13:14:15 +0000906 LWS_EXT_CALLBACK_PACKET_RX_PREPARSE,
Andy Green46c2ea02011-03-22 09:04:01 +0000907 wsi->active_extensions_user[n],
908 &eff_buf, 0);
Andy Green98a717c2011-03-06 13:14:15 +0000909 if (m < 0) {
Andy Green43db0452013-01-10 19:50:35 +0800910 lwsl_ext(
Andy Green6ee372f2012-04-09 15:09:01 +0800911 "Extension reports fatal error\n");
912 libwebsocket_close_and_free_session(
913 context, wsi,
914 LWS_CLOSE_STATUS_NOSTATUS);
Andy Green040d2ef2013-01-16 13:40:43 +0800915 return 0;
Andy Green98a717c2011-03-06 13:14:15 +0000916 }
917 if (m)
918 more = 1;
919 }
Andy Green3182ece2013-01-20 17:08:31 +0800920#endif
Andy Green98a717c2011-03-06 13:14:15 +0000921 /* service incoming data */
922
923 if (eff_buf.token_len) {
924 n = libwebsocket_read(context, wsi,
Andy Green6ee372f2012-04-09 15:09:01 +0800925 (unsigned char *)eff_buf.token,
926 eff_buf.token_len);
Andy Green98a717c2011-03-06 13:14:15 +0000927 if (n < 0)
928 /* we closed wsi */
Andy Green040d2ef2013-01-16 13:40:43 +0800929 return 0;
Andy Green98a717c2011-03-06 13:14:15 +0000930 }
Andy Green3182ece2013-01-20 17:08:31 +0800931#ifndef LWS_NO_EXTENSIONS
Andy Green98a717c2011-03-06 13:14:15 +0000932 eff_buf.token = NULL;
933 eff_buf.token_len = 0;
934 }
Andy Green3182ece2013-01-20 17:08:31 +0800935#endif
David Galeano7ffbe1b2013-01-10 10:35:32 +0800936
937#ifdef LWS_OPENSSL_SUPPORT
938 if (wsi->ssl && SSL_pending(wsi->ssl))
939 goto read_pending;
940#endif
Andy Green98a717c2011-03-06 13:14:15 +0000941 break;
Andy Green76f61e72013-01-16 11:53:05 +0800942
943 default:
Andy Green03674a62013-01-16 11:47:40 +0800944#ifdef LWS_NO_CLIENT
945 break;
946#else
Andy Green76f61e72013-01-16 11:53:05 +0800947 return lws_client_socket_service(context, wsi, pollfd);
Andy Green03674a62013-01-16 11:47:40 +0800948#endif
Andy Greenb45993c2010-12-18 15:13:50 +0000949 }
950
951 return 0;
952}
953
Andy Green0d338332011-02-12 11:57:43 +0000954
Andy Green6964bb52011-01-23 16:50:33 +0000955/**
956 * libwebsocket_context_destroy() - Destroy the websocket context
Peter Hinz56885f32011-03-02 22:03:47 +0000957 * @context: Websocket context
Andy Green6964bb52011-01-23 16:50:33 +0000958 *
959 * This function closes any active connections and then frees the
960 * context. After calling this, any further use of the context is
961 * undefined.
962 */
963void
Peter Hinz56885f32011-03-02 22:03:47 +0000964libwebsocket_context_destroy(struct libwebsocket_context *context)
Andy Green6964bb52011-01-23 16:50:33 +0000965{
Andy Green3182ece2013-01-20 17:08:31 +0800966#ifndef LWS_NO_EXTENSIONS
Andy Green0d338332011-02-12 11:57:43 +0000967 int n;
968 int m;
Andy Greena41314f2011-05-23 10:00:03 +0100969 struct libwebsocket_extension *ext;
Andy Green6964bb52011-01-23 16:50:33 +0000970
Andy Greend636e352013-01-29 12:36:17 +0800971#ifdef LWS_LATENCY
972 if (context->worst_latency_info[0])
973 lwsl_notice("Worst latency: %s\n", context->worst_latency_info);
974#endif
975
Andy Greendfb23042013-01-17 12:26:48 +0800976 for (n = 0; n < context->fds_count; n++) {
977 struct libwebsocket *wsi = context->lws_lookup[context->fds[n].fd];
978 libwebsocket_close_and_free_session(context,
979 wsi, LWS_CLOSE_STATUS_GOINGAWAY);
980 }
Andy Green6964bb52011-01-23 16:50:33 +0000981
Andy Greena41314f2011-05-23 10:00:03 +0100982 /*
983 * give all extensions a chance to clean up any per-context
984 * allocations they might have made
985 */
986
987 ext = context->extensions;
988 m = LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT;
989 if (context->listen_port)
990 m = LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT;
Paulo Roberto Urio1f680ab2012-06-04 08:40:28 +0800991 while (ext && ext->callback) {
Aaron Zinman4550f1d2013-01-10 12:35:18 +0800992 ext->callback(context, ext, NULL, (enum libwebsocket_extension_callback_reasons)m, NULL, NULL, 0);
Andy Greena41314f2011-05-23 10:00:03 +0100993 ext++;
994 }
Andy Green3182ece2013-01-20 17:08:31 +0800995#endif
Andy Greena41314f2011-05-23 10:00:03 +0100996
Peter Hinz56885f32011-03-02 22:03:47 +0000997#ifdef WIN32
998#else
999 close(context->fd_random);
Andy Green6964bb52011-01-23 16:50:33 +00001000#endif
1001
Peter Hinz56885f32011-03-02 22:03:47 +00001002#ifdef LWS_OPENSSL_SUPPORT
1003 if (context->ssl_ctx)
1004 SSL_CTX_free(context->ssl_ctx);
1005 if (context->ssl_client_ctx)
1006 SSL_CTX_free(context->ssl_client_ctx);
1007#endif
1008
1009 free(context);
1010
1011#ifdef WIN32
1012 WSACleanup();
1013#endif
Andy Green6964bb52011-01-23 16:50:33 +00001014}
1015
Andy Greend88146d2013-01-22 12:40:35 +08001016/**
1017 * libwebsocket_context_user() - get the user data associated with the whole context
1018 * @context: Websocket context
1019 *
1020 * This returns the optional user allocation that can be attached to
1021 * the context the sockets live in at context_create time. It's a way
1022 * to let all sockets serviced in the same context share data without
1023 * using globals statics in the user code.
1024 */
1025
1026
Alon Levy0291eb32012-10-19 11:21:56 +02001027LWS_EXTERN void *
1028libwebsocket_context_user(struct libwebsocket_context *context)
1029{
1030 return context->user_space;
1031}
1032
Andy Green6964bb52011-01-23 16:50:33 +00001033/**
1034 * libwebsocket_service() - Service any pending websocket activity
Peter Hinz56885f32011-03-02 22:03:47 +00001035 * @context: Websocket context
Andy Green6964bb52011-01-23 16:50:33 +00001036 * @timeout_ms: Timeout for poll; 0 means return immediately if nothing needed
1037 * service otherwise block and service immediately, returning
1038 * after the timeout if nothing needed service.
1039 *
1040 * This function deals with any pending websocket traffic, for three
1041 * kinds of event. It handles these events on both server and client
1042 * types of connection the same.
1043 *
1044 * 1) Accept new connections to our context's server
1045 *
Andy Green6f520a52013-01-29 17:57:39 +08001046 * 2) Call the receive callback for incoming frame data received by
Andy Green6964bb52011-01-23 16:50:33 +00001047 * server or client connections.
1048 *
1049 * You need to call this service function periodically to all the above
1050 * functions to happen; if your application is single-threaded you can
1051 * just call it in your main event loop.
1052 *
1053 * Alternatively you can fork a new process that asynchronously handles
1054 * calling this service in a loop. In that case you are happy if this
1055 * call blocks your thread until it needs to take care of something and
1056 * would call it with a large nonzero timeout. Your loop then takes no
1057 * CPU while there is nothing happening.
1058 *
1059 * If you are calling it in a single-threaded app, you don't want it to
1060 * wait around blocking other things in your loop from happening, so you
1061 * would call it with a timeout_ms of 0, so it returns immediately if
1062 * nothing is pending, or as soon as it services whatever was pending.
1063 */
1064
Andy Greenb45993c2010-12-18 15:13:50 +00001065
Andy Greene92cd172011-01-19 13:11:55 +00001066int
Peter Hinz56885f32011-03-02 22:03:47 +00001067libwebsocket_service(struct libwebsocket_context *context, int timeout_ms)
Andy Greene92cd172011-01-19 13:11:55 +00001068{
1069 int n;
Andy Greene92cd172011-01-19 13:11:55 +00001070
1071 /* stay dead once we are dead */
1072
Peter Hinz56885f32011-03-02 22:03:47 +00001073 if (context == NULL)
Andy Greene92cd172011-01-19 13:11:55 +00001074 return 1;
1075
Andy Green0d338332011-02-12 11:57:43 +00001076 /* wait for something to need service */
Andy Green4739e5c2011-01-22 12:51:57 +00001077
Peter Hinz56885f32011-03-02 22:03:47 +00001078 n = poll(context->fds, context->fds_count, timeout_ms);
Andy Green3221f922011-02-12 13:14:11 +00001079 if (n == 0) /* poll timeout */
1080 return 0;
Andy Greene92cd172011-01-19 13:11:55 +00001081
Andy Greendfb23042013-01-17 12:26:48 +08001082 if (n < 0)
Andy Green3928f612012-07-20 12:58:38 +08001083 return -1;
Andy Greene92cd172011-01-19 13:11:55 +00001084
Andy Greendfb23042013-01-17 12:26:48 +08001085 /* any socket with events to service? */
Andy Greene92cd172011-01-19 13:11:55 +00001086
Peter Hinz56885f32011-03-02 22:03:47 +00001087 for (n = 0; n < context->fds_count; n++)
1088 if (context->fds[n].revents)
Andy Green3928f612012-07-20 12:58:38 +08001089 if (libwebsocket_service_fd(context,
1090 &context->fds[n]) < 0)
1091 return -1;
Andy Greene92cd172011-01-19 13:11:55 +00001092 return 0;
Andy Greene92cd172011-01-19 13:11:55 +00001093}
1094
Andy Green3182ece2013-01-20 17:08:31 +08001095#ifndef LWS_NO_EXTENSIONS
Andy Greena41314f2011-05-23 10:00:03 +01001096int
1097lws_any_extension_handled(struct libwebsocket_context *context,
Andy Green6ee372f2012-04-09 15:09:01 +08001098 struct libwebsocket *wsi,
1099 enum libwebsocket_extension_callback_reasons r,
Andy Greena41314f2011-05-23 10:00:03 +01001100 void *v, size_t len)
1101{
1102 int n;
1103 int handled = 0;
1104
1105 /* maybe an extension will take care of it for us */
1106
1107 for (n = 0; n < wsi->count_active_extensions && !handled; n++) {
1108 if (!wsi->active_extensions[n]->callback)
1109 continue;
1110
1111 handled |= wsi->active_extensions[n]->callback(context,
1112 wsi->active_extensions[n], wsi,
1113 r, wsi->active_extensions_user[n], v, len);
1114 }
1115
1116 return handled;
1117}
1118
1119
1120void *
1121lws_get_extension_user_matching_ext(struct libwebsocket *wsi,
Andy Green6ee372f2012-04-09 15:09:01 +08001122 struct libwebsocket_extension *ext)
Andy Greena41314f2011-05-23 10:00:03 +01001123{
1124 int n = 0;
1125
Andy Green68b45042011-05-25 21:41:57 +01001126 if (wsi == NULL)
1127 return NULL;
1128
Andy Greena41314f2011-05-23 10:00:03 +01001129 while (n < wsi->count_active_extensions) {
1130 if (wsi->active_extensions[n] != ext) {
1131 n++;
1132 continue;
1133 }
1134 return wsi->active_extensions_user[n];
1135 }
1136
1137 return NULL;
1138}
Andy Green3182ece2013-01-20 17:08:31 +08001139#endif
Andy Greena41314f2011-05-23 10:00:03 +01001140
Andy Green90c7cbc2011-01-27 06:26:52 +00001141/**
1142 * libwebsocket_callback_on_writable() - Request a callback when this socket
1143 * becomes able to be written to without
1144 * blocking
Andy Green32375b72011-02-19 08:32:53 +00001145 *
Peter Hinz56885f32011-03-02 22:03:47 +00001146 * @context: libwebsockets context
Andy Green90c7cbc2011-01-27 06:26:52 +00001147 * @wsi: Websocket connection instance to get callback for
1148 */
1149
1150int
Peter Hinz56885f32011-03-02 22:03:47 +00001151libwebsocket_callback_on_writable(struct libwebsocket_context *context,
Andy Green6ee372f2012-04-09 15:09:01 +08001152 struct libwebsocket *wsi)
Andy Green90c7cbc2011-01-27 06:26:52 +00001153{
Andy Green3182ece2013-01-20 17:08:31 +08001154#ifndef LWS_NO_EXTENSIONS
Andy Green90c7cbc2011-01-27 06:26:52 +00001155 int n;
Andy Greena41314f2011-05-23 10:00:03 +01001156 int handled = 0;
1157
1158 /* maybe an extension will take care of it for us */
1159
1160 for (n = 0; n < wsi->count_active_extensions; n++) {
1161 if (!wsi->active_extensions[n]->callback)
1162 continue;
1163
1164 handled |= wsi->active_extensions[n]->callback(context,
1165 wsi->active_extensions[n], wsi,
1166 LWS_EXT_CALLBACK_REQUEST_ON_WRITEABLE,
1167 wsi->active_extensions_user[n], NULL, 0);
1168 }
1169
1170 if (handled)
1171 return 1;
Andy Green3182ece2013-01-20 17:08:31 +08001172#endif
Andy Greendfb23042013-01-17 12:26:48 +08001173 if (wsi->position_in_fds_table < 0) {
Andy Green43db0452013-01-10 19:50:35 +08001174 lwsl_err("libwebsocket_callback_on_writable: "
Andy Green6ee372f2012-04-09 15:09:01 +08001175 "failed to find socket %d\n", wsi->sock);
Andy Greendfb23042013-01-17 12:26:48 +08001176 return -1;
1177 }
1178
1179 context->fds[wsi->position_in_fds_table].events |= POLLOUT;
Andy Greena41314f2011-05-23 10:00:03 +01001180
Andy Green3221f922011-02-12 13:14:11 +00001181 /* external POLL support via protocol 0 */
Peter Hinz56885f32011-03-02 22:03:47 +00001182 context->protocols[0].callback(context, wsi,
Andy Green3221f922011-02-12 13:14:11 +00001183 LWS_CALLBACK_SET_MODE_POLL_FD,
1184 (void *)(long)wsi->sock, NULL, POLLOUT);
1185
Andy Green90c7cbc2011-01-27 06:26:52 +00001186 return 1;
1187}
1188
1189/**
1190 * libwebsocket_callback_on_writable_all_protocol() - Request a callback for
1191 * all connections using the given protocol when it
1192 * becomes possible to write to each socket without
1193 * blocking in turn.
1194 *
1195 * @protocol: Protocol whose connections will get callbacks
1196 */
1197
1198int
1199libwebsocket_callback_on_writable_all_protocol(
1200 const struct libwebsocket_protocols *protocol)
1201{
Peter Hinz56885f32011-03-02 22:03:47 +00001202 struct libwebsocket_context *context = protocol->owning_server;
Andy Green90c7cbc2011-01-27 06:26:52 +00001203 int n;
Andy Green0d338332011-02-12 11:57:43 +00001204 struct libwebsocket *wsi;
Andy Green90c7cbc2011-01-27 06:26:52 +00001205
Andy Greendfb23042013-01-17 12:26:48 +08001206 for (n = 0; n < context->fds_count; n++) {
1207 wsi = context->lws_lookup[context->fds[n].fd];
1208 if (!wsi)
1209 continue;
1210 if (wsi->protocol == protocol)
1211 libwebsocket_callback_on_writable(context, wsi);
Andy Green0d338332011-02-12 11:57:43 +00001212 }
Andy Green90c7cbc2011-01-27 06:26:52 +00001213
1214 return 0;
1215}
1216
Andy Greenbe93fef2011-02-14 20:25:43 +00001217/**
1218 * libwebsocket_set_timeout() - marks the wsi as subject to a timeout
1219 *
1220 * You will not need this unless you are doing something special
1221 *
1222 * @wsi: Websocket connection instance
1223 * @reason: timeout reason
1224 * @secs: how many seconds
1225 */
1226
1227void
1228libwebsocket_set_timeout(struct libwebsocket *wsi,
1229 enum pending_timeout reason, int secs)
1230{
1231 struct timeval tv;
1232
1233 gettimeofday(&tv, NULL);
1234
1235 wsi->pending_timeout_limit = tv.tv_sec + secs;
1236 wsi->pending_timeout = reason;
1237}
1238
Andy Greena6cbece2011-01-27 20:06:03 +00001239
1240/**
1241 * libwebsocket_get_socket_fd() - returns the socket file descriptor
1242 *
1243 * You will not need this unless you are doing something special
1244 *
1245 * @wsi: Websocket connection instance
1246 */
1247
1248int
1249libwebsocket_get_socket_fd(struct libwebsocket *wsi)
1250{
1251 return wsi->sock;
1252}
1253
Andy Greend636e352013-01-29 12:36:17 +08001254#ifdef LWS_LATENCY
1255void
1256lws_latency(struct libwebsocket_context *context, struct libwebsocket *wsi, const char *action, int ret, int completed)
1257{
1258 struct timeval tv;
1259 unsigned long u;
1260 char buf[256];
1261
1262 gettimeofday(&tv, NULL);
1263
1264 u = (tv.tv_sec * 1000000) + tv.tv_usec;
1265
1266 if (action) {
1267 if (completed) {
1268 if (wsi->action_start == wsi->latency_start)
1269 sprintf(buf, "Completion first try lat %luus: %p: ret %d: %s\n", u - wsi->latency_start, (void *)wsi, ret, action);
1270 else
1271 sprintf(buf, "Completion %luus: lat %luus: %p: ret %d: %s\n", u - wsi->action_start, u - wsi->latency_start, (void *)wsi, ret, action);
1272 wsi->action_start = 0;
1273 } else
1274 sprintf(buf, "lat %luus: %p: ret %d: %s\n", u - wsi->latency_start, (void *)wsi, ret, action);
1275 if (u - wsi->latency_start > context->worst_latency) {
1276 context->worst_latency = u - wsi->latency_start;
1277 strcpy(context->worst_latency_info, buf);
1278 }
1279 lwsl_latency("%s", buf);
1280 } else {
1281 wsi->latency_start = u;
1282 if (!wsi->action_start)
1283 wsi->action_start = u;
1284 }
1285}
1286#endif
1287
Andy Greena1ce6be2013-01-18 11:43:21 +08001288#ifdef LWS_NO_SERVER
1289int
1290_libwebsocket_rx_flow_control(struct libwebsocket *wsi)
1291{
1292 return 0;
1293}
1294#else
Andy Green706961d2013-01-17 16:50:35 +08001295int
1296_libwebsocket_rx_flow_control(struct libwebsocket *wsi)
1297{
1298 struct libwebsocket_context *context = wsi->protocol->owning_server;
1299 int n;
1300
Andy Green623a98d2013-01-21 11:04:23 +08001301 if (!(wsi->u.ws.rxflow_change_to & 2))
Andy Green706961d2013-01-17 16:50:35 +08001302 return 0;
1303
Andy Green623a98d2013-01-21 11:04:23 +08001304 wsi->u.ws.rxflow_change_to &= ~2;
Andy Green706961d2013-01-17 16:50:35 +08001305
Andy Green623a98d2013-01-21 11:04:23 +08001306 lwsl_info("rxflow: wsi %p change_to %d\n", wsi, wsi->u.ws.rxflow_change_to);
Andy Green706961d2013-01-17 16:50:35 +08001307
1308 /* if we're letting it come again, did we interrupt anything? */
Andy Green623a98d2013-01-21 11:04:23 +08001309 if ((wsi->u.ws.rxflow_change_to & 1) && wsi->u.ws.rxflow_buffer) {
Andy Green706961d2013-01-17 16:50:35 +08001310 n = libwebsocket_interpret_incoming_packet(wsi, NULL, 0);
1311 if (n < 0) {
Andy Green467c7ef2013-01-30 12:28:34 +08001312 lwsl_info("closing connection at libwebsocket_rx_flow_control:\n");
Andy Green706961d2013-01-17 16:50:35 +08001313 libwebsocket_close_and_free_session(context, wsi, LWS_CLOSE_STATUS_NOSTATUS);
1314 return -1;
1315 }
1316 if (n)
1317 /* oh he stuck again, do nothing */
1318 return 0;
1319 }
1320
Andy Green623a98d2013-01-21 11:04:23 +08001321 if (wsi->u.ws.rxflow_change_to & 1)
Andy Green706961d2013-01-17 16:50:35 +08001322 context->fds[wsi->position_in_fds_table].events |= POLLIN;
1323 else
1324 context->fds[wsi->position_in_fds_table].events &= ~POLLIN;
1325
Andy Green623a98d2013-01-21 11:04:23 +08001326 if (wsi->u.ws.rxflow_change_to & 1)
Andy Green706961d2013-01-17 16:50:35 +08001327 /* external POLL support via protocol 0 */
1328 context->protocols[0].callback(context, wsi,
1329 LWS_CALLBACK_SET_MODE_POLL_FD,
1330 (void *)(long)wsi->sock, NULL, POLLIN);
1331 else
1332 /* external POLL support via protocol 0 */
1333 context->protocols[0].callback(context, wsi,
1334 LWS_CALLBACK_CLEAR_MODE_POLL_FD,
1335 (void *)(long)wsi->sock, NULL, POLLIN);
1336
1337 return 1;
1338}
Andy Greena1ce6be2013-01-18 11:43:21 +08001339#endif
Andy Green706961d2013-01-17 16:50:35 +08001340
Andy Green90c7cbc2011-01-27 06:26:52 +00001341/**
1342 * libwebsocket_rx_flow_control() - Enable and disable socket servicing for
1343 * receieved packets.
1344 *
1345 * If the output side of a server process becomes choked, this allows flow
1346 * control for the input side.
1347 *
1348 * @wsi: Websocket connection instance to get callback for
1349 * @enable: 0 = disable read servicing for this connection, 1 = enable
1350 */
1351
1352int
1353libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable)
1354{
Andy Green623a98d2013-01-21 11:04:23 +08001355 wsi->u.ws.rxflow_change_to = 2 | !!enable;
Andy Green90c7cbc2011-01-27 06:26:52 +00001356
Andy Green706961d2013-01-17 16:50:35 +08001357 return 0;
Andy Green90c7cbc2011-01-27 06:26:52 +00001358}
1359
Andy Green706961d2013-01-17 16:50:35 +08001360
Andy Green2ac5a6f2011-01-28 10:00:18 +00001361/**
1362 * libwebsocket_canonical_hostname() - returns this host's hostname
1363 *
1364 * This is typically used by client code to fill in the host parameter
1365 * when making a client connection. You can only call it after the context
1366 * has been created.
1367 *
Peter Hinz56885f32011-03-02 22:03:47 +00001368 * @context: Websocket context
Andy Green2ac5a6f2011-01-28 10:00:18 +00001369 */
1370
1371
1372extern const char *
Peter Hinz56885f32011-03-02 22:03:47 +00001373libwebsocket_canonical_hostname(struct libwebsocket_context *context)
Andy Green2ac5a6f2011-01-28 10:00:18 +00001374{
Peter Hinz56885f32011-03-02 22:03:47 +00001375 return (const char *)context->canonical_hostname;
Andy Green2ac5a6f2011-01-28 10:00:18 +00001376}
1377
1378
Andy Green90c7cbc2011-01-27 06:26:52 +00001379static void sigpipe_handler(int x)
1380{
1381}
1382
Andy Green6901cb32011-02-21 08:06:47 +00001383#ifdef LWS_OPENSSL_SUPPORT
1384static int
1385OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
1386{
1387
1388 SSL *ssl;
1389 int n;
Andy Green2e24da02011-03-05 16:12:04 +00001390 struct libwebsocket_context *context;
Andy Green6901cb32011-02-21 08:06:47 +00001391
1392 ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
1393 SSL_get_ex_data_X509_STORE_CTX_idx());
1394
1395 /*
Andy Green2e24da02011-03-05 16:12:04 +00001396 * !!! nasty openssl requires the index to come as a library-scope
1397 * static
Andy Green6901cb32011-02-21 08:06:47 +00001398 */
Andy Green2e24da02011-03-05 16:12:04 +00001399 context = SSL_get_ex_data(ssl, openssl_websocket_private_data_index);
Andy Green6ee372f2012-04-09 15:09:01 +08001400
Peter Hinz56885f32011-03-02 22:03:47 +00001401 n = context->protocols[0].callback(NULL, NULL,
Andy Green6901cb32011-02-21 08:06:47 +00001402 LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
1403 x509_ctx, ssl, preverify_ok);
1404
1405 /* convert return code from 0 = OK to 1 = OK */
1406
1407 if (!n)
1408 n = 1;
1409 else
1410 n = 0;
1411
1412 return n;
1413}
1414#endif
1415
Andy Green706961d2013-01-17 16:50:35 +08001416int user_callback_handle_rxflow(callback_function callback_function,
1417 struct libwebsocket_context * context,
1418 struct libwebsocket *wsi,
1419 enum libwebsocket_callback_reasons reason, void *user,
1420 void *in, size_t len)
1421{
1422 int n;
1423
1424 n = callback_function(context, wsi, reason, user, in, len);
1425 if (n < 0)
1426 return n;
1427
1428 _libwebsocket_rx_flow_control(wsi);
1429
1430 return 0;
1431}
1432
Andy Greenb45993c2010-12-18 15:13:50 +00001433
Andy Greenab990e42010-10-31 12:42:52 +00001434/**
Andy Green4739e5c2011-01-22 12:51:57 +00001435 * libwebsocket_create_context() - Create the websocket handler
1436 * @port: Port to listen on... you can use 0 to suppress listening on
Andy Green6964bb52011-01-23 16:50:33 +00001437 * any port, that's what you want if you are not running a
1438 * websocket server at all but just using it as a client
Peter Hinz56885f32011-03-02 22:03:47 +00001439 * @interf: NULL to bind the listen socket to all interfaces, or the
Andy Green32375b72011-02-19 08:32:53 +00001440 * interface name, eg, "eth2"
Andy Green4f3943a2010-11-12 10:44:16 +00001441 * @protocols: Array of structures listing supported protocols and a protocol-
Andy Green8f037e42010-12-19 22:13:26 +00001442 * specific callback for each one. The list is ended with an
1443 * entry that has a NULL callback pointer.
Andy Green6964bb52011-01-23 16:50:33 +00001444 * It's not const because we write the owning_server member
Andy Greenc5114822011-03-06 10:29:35 +00001445 * @extensions: NULL or array of libwebsocket_extension structs listing the
Andy Green3182ece2013-01-20 17:08:31 +08001446 * extensions this context supports. If you configured with
1447 * --without-extensions, you should give NULL here.
Andy Green3faa9c72010-11-08 17:03:03 +00001448 * @ssl_cert_filepath: If libwebsockets was compiled to use ssl, and you want
Andy Green8f037e42010-12-19 22:13:26 +00001449 * to listen using SSL, set to the filepath to fetch the
1450 * server cert from, otherwise NULL for unencrypted
Andy Green3faa9c72010-11-08 17:03:03 +00001451 * @ssl_private_key_filepath: filepath to private key if wanting SSL mode,
Andy Green8f037e42010-12-19 22:13:26 +00001452 * else ignored
David Galeano2f82be82013-01-09 16:25:54 +08001453 * @ssl_ca_filepath: CA certificate filepath or NULL
Andy Green3faa9c72010-11-08 17:03:03 +00001454 * @gid: group id to change to after setting listen socket, or -1.
1455 * @uid: user id to change to after setting listen socket, or -1.
Andy Greenbfb051f2011-02-09 08:49:14 +00001456 * @options: 0, or LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK
Andy Green15e31f32012-10-19 18:36:28 +08001457 * @user: optional user pointer that can be recovered via the context
1458 * pointer using libwebsocket_context_user
Andy Green05464c62010-11-12 10:44:18 +00001459 *
Andy Green8f037e42010-12-19 22:13:26 +00001460 * This function creates the listening socket and takes care
1461 * of all initialization in one step.
1462 *
Andy Greene92cd172011-01-19 13:11:55 +00001463 * After initialization, it returns a struct libwebsocket_context * that
1464 * represents this server. After calling, user code needs to take care
1465 * of calling libwebsocket_service() with the context pointer to get the
1466 * server's sockets serviced. This can be done in the same process context
1467 * or a forked process, or another thread,
Andy Green05464c62010-11-12 10:44:18 +00001468 *
Andy Green8f037e42010-12-19 22:13:26 +00001469 * The protocol callback functions are called for a handful of events
1470 * including http requests coming in, websocket connections becoming
1471 * established, and data arriving; it's also called periodically to allow
1472 * async transmission.
1473 *
1474 * HTTP requests are sent always to the FIRST protocol in @protocol, since
1475 * at that time websocket protocol has not been negotiated. Other
1476 * protocols after the first one never see any HTTP callack activity.
1477 *
1478 * The server created is a simple http server by default; part of the
1479 * websocket standard is upgrading this http connection to a websocket one.
1480 *
1481 * This allows the same server to provide files like scripts and favicon /
1482 * images or whatever over http and dynamic data over websockets all in
1483 * one place; they're all handled in the user callback.
Andy Greenab990e42010-10-31 12:42:52 +00001484 */
Andy Green4ea60062010-10-30 12:15:07 +01001485
Andy Greene92cd172011-01-19 13:11:55 +00001486struct libwebsocket_context *
Peter Hinz56885f32011-03-02 22:03:47 +00001487libwebsocket_create_context(int port, const char *interf,
Andy Greenb45993c2010-12-18 15:13:50 +00001488 struct libwebsocket_protocols *protocols,
Andy Greend6e09112011-03-05 16:12:15 +00001489 struct libwebsocket_extension *extensions,
Andy Green8f037e42010-12-19 22:13:26 +00001490 const char *ssl_cert_filepath,
1491 const char *ssl_private_key_filepath,
David Galeano2f82be82013-01-09 16:25:54 +08001492 const char *ssl_ca_filepath,
Alon Levy0291eb32012-10-19 11:21:56 +02001493 int gid, int uid, unsigned int options,
David Galeano2f82be82013-01-09 16:25:54 +08001494 void *user)
Andy Greenff95d7a2010-10-28 22:36:01 +01001495{
1496 int n;
Peter Hinz56885f32011-03-02 22:03:47 +00001497 struct libwebsocket_context *context = NULL;
Andy Green9659f372011-01-27 22:01:43 +00001498 char *p;
Andy Greencbb31222013-01-31 09:57:05 +08001499#ifndef LWS_NO_SERVER
1500 int opt = 1;
Andy Green0d338332011-02-12 11:57:43 +00001501 struct libwebsocket *wsi;
Andy Greencbb31222013-01-31 09:57:05 +08001502 struct sockaddr_in serv_addr;
1503#endif
Andy Green3182ece2013-01-20 17:08:31 +08001504#ifndef LWS_NO_EXTENSIONS
1505 int m;
1506#endif
Andy Greenff95d7a2010-10-28 22:36:01 +01001507
Andy Green3faa9c72010-11-08 17:03:03 +00001508#ifdef LWS_OPENSSL_SUPPORT
Andy Greenf2f54d52010-11-15 22:08:00 +00001509 SSL_METHOD *method;
Andy Green3faa9c72010-11-08 17:03:03 +00001510 char ssl_err_buf[512];
Andy Green3faa9c72010-11-08 17:03:03 +00001511#endif
1512
Andy Greenb3a614a2013-01-19 13:08:17 +08001513 lwsl_notice("Initial logging level %d\n", log_level);
Andy Green7b405452013-02-01 10:50:15 +08001514 lwsl_notice("Library version: %s\n", library_version);
Andy Greenc0d6b632013-01-12 23:42:17 +08001515 lwsl_info(" LWS_MAX_HEADER_NAME_LENGTH: %u\n", LWS_MAX_HEADER_NAME_LENGTH);
1516 lwsl_info(" LWS_MAX_HEADER_LEN: %u\n", LWS_MAX_HEADER_LEN);
1517 lwsl_info(" LWS_INITIAL_HDR_ALLOC: %u\n", LWS_INITIAL_HDR_ALLOC);
1518 lwsl_info(" LWS_ADDITIONAL_HDR_ALLOC: %u\n", LWS_ADDITIONAL_HDR_ALLOC);
1519 lwsl_info(" MAX_USER_RX_BUFFER: %u\n", MAX_USER_RX_BUFFER);
Andy Greenc0d6b632013-01-12 23:42:17 +08001520 lwsl_info(" LWS_MAX_PROTOCOLS: %u\n", LWS_MAX_PROTOCOLS);
Andy Green3182ece2013-01-20 17:08:31 +08001521#ifndef LWS_NO_EXTENSIONS
Andy Greenc0d6b632013-01-12 23:42:17 +08001522 lwsl_info(" LWS_MAX_EXTENSIONS_ACTIVE: %u\n", LWS_MAX_EXTENSIONS_ACTIVE);
Andy Green3182ece2013-01-20 17:08:31 +08001523#else
1524 lwsl_notice(" Configured without extension support\n");
1525#endif
Andy Greenc0d6b632013-01-12 23:42:17 +08001526 lwsl_info(" SPEC_LATEST_SUPPORTED: %u\n", SPEC_LATEST_SUPPORTED);
1527 lwsl_info(" AWAITING_TIMEOUT: %u\n", AWAITING_TIMEOUT);
1528 lwsl_info(" CIPHERS_LIST_STRING: '%s'\n", CIPHERS_LIST_STRING);
1529 lwsl_info(" SYSTEM_RANDOM_FILEPATH: '%s'\n", SYSTEM_RANDOM_FILEPATH);
1530 lwsl_info(" LWS_MAX_ZLIB_CONN_BUFFER: %u\n", LWS_MAX_ZLIB_CONN_BUFFER);
Andy Green43db0452013-01-10 19:50:35 +08001531
Peter Hinz56885f32011-03-02 22:03:47 +00001532#ifdef _WIN32
1533 {
1534 WORD wVersionRequested;
1535 WSADATA wsaData;
1536 int err;
Andy Green6ee372f2012-04-09 15:09:01 +08001537 HMODULE wsdll;
Peter Hinz56885f32011-03-02 22:03:47 +00001538
1539 /* Use the MAKEWORD(lowbyte, highbyte) macro from Windef.h */
1540 wVersionRequested = MAKEWORD(2, 2);
1541
1542 err = WSAStartup(wVersionRequested, &wsaData);
1543 if (err != 0) {
1544 /* Tell the user that we could not find a usable */
1545 /* Winsock DLL. */
Andy Green43db0452013-01-10 19:50:35 +08001546 lwsl_err("WSAStartup failed with error: %d\n", err);
Peter Hinz56885f32011-03-02 22:03:47 +00001547 return NULL;
1548 }
David Galeano7b11fec2011-10-04 19:55:18 +08001549
Andy Green6ee372f2012-04-09 15:09:01 +08001550 /* default to a poll() made out of select() */
1551 poll = emulated_poll;
David Galeano7b11fec2011-10-04 19:55:18 +08001552
Andy Green6ee372f2012-04-09 15:09:01 +08001553 /* if windows socket lib available, use his WSAPoll */
David Galeanocb193682013-01-09 15:29:00 +08001554 wsdll = GetModuleHandle(_T("Ws2_32.dll"));
Andy Green6ee372f2012-04-09 15:09:01 +08001555 if (wsdll)
1556 poll = (PFNWSAPOLL)GetProcAddress(wsdll, "WSAPoll");
Peter Hinz56885f32011-03-02 22:03:47 +00001557 }
1558#endif
1559
Aaron Zinman4550f1d2013-01-10 12:35:18 +08001560 context = (struct libwebsocket_context *) malloc(sizeof(struct libwebsocket_context));
Peter Hinz56885f32011-03-02 22:03:47 +00001561 if (!context) {
Andy Green43db0452013-01-10 19:50:35 +08001562 lwsl_err("No memory for websocket context\n");
Andy Green90c7cbc2011-01-27 06:26:52 +00001563 return NULL;
1564 }
Andy Green35f332b2013-01-21 13:06:38 +08001565#ifndef LWS_NO_DAEMONIZE
Andy Green24cba922013-01-19 13:56:10 +08001566 extern int pid_daemon;
1567 context->started_with_parent = pid_daemon;
1568 lwsl_notice(" Started with daemon pid %d\n", pid_daemon);
1569#endif
1570
Peter Hinz56885f32011-03-02 22:03:47 +00001571 context->protocols = protocols;
1572 context->listen_port = port;
1573 context->http_proxy_port = 0;
1574 context->http_proxy_address[0] = '\0';
1575 context->options = options;
Andy Greendfb23042013-01-17 12:26:48 +08001576 /* to reduce this allocation, */
1577 context->max_fds = getdtablesize();
Andy Greenb3a614a2013-01-19 13:08:17 +08001578 lwsl_notice(" max fd tracked: %u\n", context->max_fds);
Andy Greena17c6922013-01-20 20:21:54 +08001579 lwsl_notice(" static allocation: %u bytes\n",
1580 (sizeof(struct pollfd) * context->max_fds) +
1581 (sizeof(struct libwebsocket *) * context->max_fds));
Andy Greendfb23042013-01-17 12:26:48 +08001582
1583 context->fds = (struct pollfd *)malloc(sizeof(struct pollfd) * context->max_fds);
1584 if (context->fds == NULL) {
1585 lwsl_err("Unable to allocate fds array for %d connections\n", context->max_fds);
1586 free(context);
1587 return NULL;
1588 }
Edwin van den Oetelaarf6eeabc2013-01-19 20:01:01 +08001589 context->lws_lookup = (struct libwebsocket **)malloc(sizeof(struct libwebsocket *) * context->max_fds);
Andy Greendfb23042013-01-17 12:26:48 +08001590 if (context->lws_lookup == NULL) {
1591 lwsl_err("Unable to allocate lws_lookup array for %d connections\n", context->max_fds);
1592 free(context->fds);
1593 free(context);
1594 return NULL;
1595 }
Andy Greena17c6922013-01-20 20:21:54 +08001596
Peter Hinz56885f32011-03-02 22:03:47 +00001597 context->fds_count = 0;
Andy Green3182ece2013-01-20 17:08:31 +08001598#ifndef LWS_NO_EXTENSIONS
Andy Greend6e09112011-03-05 16:12:15 +00001599 context->extensions = extensions;
Andy Green3182ece2013-01-20 17:08:31 +08001600#endif
Paulo Roberto Urio1e326632012-06-04 10:52:19 +08001601 context->last_timeout_check_s = 0;
Andy Greendfb23042013-01-17 12:26:48 +08001602 context->user_space = user;
Andy Green9659f372011-01-27 22:01:43 +00001603
Peter Hinz56885f32011-03-02 22:03:47 +00001604#ifdef WIN32
1605 context->fd_random = 0;
1606#else
1607 context->fd_random = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY);
1608 if (context->fd_random < 0) {
Andy Greendfb23042013-01-17 12:26:48 +08001609 free(context);
Andy Green43db0452013-01-10 19:50:35 +08001610 lwsl_err("Unable to open random device %s %d\n",
Peter Hinz56885f32011-03-02 22:03:47 +00001611 SYSTEM_RANDOM_FILEPATH, context->fd_random);
Andy Green44eee682011-02-10 09:32:24 +00001612 return NULL;
1613 }
Peter Hinz56885f32011-03-02 22:03:47 +00001614#endif
Andy Green44eee682011-02-10 09:32:24 +00001615
Peter Hinz56885f32011-03-02 22:03:47 +00001616#ifdef LWS_OPENSSL_SUPPORT
1617 context->use_ssl = 0;
1618 context->ssl_ctx = NULL;
1619 context->ssl_client_ctx = NULL;
Andy Green2e24da02011-03-05 16:12:04 +00001620 openssl_websocket_private_data_index = 0;
Peter Hinz56885f32011-03-02 22:03:47 +00001621#endif
Andy Green2ac5a6f2011-01-28 10:00:18 +00001622
Andy Greena1ce6be2013-01-18 11:43:21 +08001623 strcpy(context->canonical_hostname, "unknown");
Andy Greena69f0512012-05-03 12:32:38 +08001624
Andy Greena1ce6be2013-01-18 11:43:21 +08001625#ifndef LWS_NO_SERVER
1626 if (!(options & LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME)) {
1627 struct sockaddr sa;
1628 char hostname[1024] = "";
Andy Green788c4a82012-10-22 12:29:57 +01001629
1630 /* find canonical hostname */
1631
1632 hostname[(sizeof hostname) - 1] = '\0';
1633 memset(&sa, 0, sizeof(sa));
1634 sa.sa_family = AF_INET;
1635 sa.sa_data[(sizeof sa.sa_data) - 1] = '\0';
1636 gethostname(hostname, (sizeof hostname) - 1);
1637
1638 n = 0;
1639
David Galeanoed3c8402013-01-10 10:45:24 +08001640 if (strlen(hostname) < sizeof(sa.sa_data) - 1) {
Andy Green788c4a82012-10-22 12:29:57 +01001641 strcpy(sa.sa_data, hostname);
Andy Greend09d7d42013-01-31 10:05:43 +08001642 lwsl_debug("my host name is %s\n", sa.sa_data);
Andy Green788c4a82012-10-22 12:29:57 +01001643 n = getnameinfo(&sa, sizeof(sa), hostname,
Andy Greend09d7d42013-01-31 10:05:43 +08001644 (sizeof hostname) - 1, NULL, 0, NI_NAMEREQD);
Andy Green788c4a82012-10-22 12:29:57 +01001645 }
1646
1647 if (!n) {
1648 strncpy(context->canonical_hostname, hostname,
1649 sizeof context->canonical_hostname - 1);
1650 context->canonical_hostname[
1651 sizeof context->canonical_hostname - 1] = '\0';
1652 } else
1653 strncpy(context->canonical_hostname, hostname,
1654 sizeof context->canonical_hostname - 1);
1655
Andy Greenb3a614a2013-01-19 13:08:17 +08001656 lwsl_notice(" canonical_hostname = %s\n", context->canonical_hostname);
Andy Greena69f0512012-05-03 12:32:38 +08001657 }
Andy Greena1ce6be2013-01-18 11:43:21 +08001658#endif
Andy Greena69f0512012-05-03 12:32:38 +08001659
Andy Green9659f372011-01-27 22:01:43 +00001660 /* split the proxy ads:port if given */
1661
1662 p = getenv("http_proxy");
1663 if (p) {
Peter Hinz56885f32011-03-02 22:03:47 +00001664 strncpy(context->http_proxy_address, p,
Andy Green6ee372f2012-04-09 15:09:01 +08001665 sizeof context->http_proxy_address - 1);
Peter Hinz56885f32011-03-02 22:03:47 +00001666 context->http_proxy_address[
1667 sizeof context->http_proxy_address - 1] = '\0';
Andy Green9659f372011-01-27 22:01:43 +00001668
Peter Hinz56885f32011-03-02 22:03:47 +00001669 p = strchr(context->http_proxy_address, ':');
Andy Green9659f372011-01-27 22:01:43 +00001670 if (p == NULL) {
Andy Green43db0452013-01-10 19:50:35 +08001671 lwsl_err("http_proxy needs to be ads:port\n");
Andy Green9659f372011-01-27 22:01:43 +00001672 return NULL;
1673 }
1674 *p = '\0';
Peter Hinz56885f32011-03-02 22:03:47 +00001675 context->http_proxy_port = atoi(p + 1);
Andy Green9659f372011-01-27 22:01:43 +00001676
Andy Greenb3a614a2013-01-19 13:08:17 +08001677 lwsl_notice(" Proxy %s:%u\n",
Peter Hinz56885f32011-03-02 22:03:47 +00001678 context->http_proxy_address,
1679 context->http_proxy_port);
Andy Green9659f372011-01-27 22:01:43 +00001680 }
Andy Green90c7cbc2011-01-27 06:26:52 +00001681
Andy Greena1ce6be2013-01-18 11:43:21 +08001682#ifndef LWS_NO_SERVER
Andy Green90c7cbc2011-01-27 06:26:52 +00001683 if (port) {
1684
Andy Green3faa9c72010-11-08 17:03:03 +00001685#ifdef LWS_OPENSSL_SUPPORT
Peter Hinz56885f32011-03-02 22:03:47 +00001686 context->use_ssl = ssl_cert_filepath != NULL &&
Andy Green90c7cbc2011-01-27 06:26:52 +00001687 ssl_private_key_filepath != NULL;
Peter Hinz56885f32011-03-02 22:03:47 +00001688 if (context->use_ssl)
Andy Greenb3a614a2013-01-19 13:08:17 +08001689 lwsl_notice(" Compiled with SSL support, using it\n");
Andy Green90c7cbc2011-01-27 06:26:52 +00001690 else
Andy Greenb3a614a2013-01-19 13:08:17 +08001691 lwsl_notice(" Compiled with SSL support, not using it\n");
Andy Green3faa9c72010-11-08 17:03:03 +00001692
Andy Green90c7cbc2011-01-27 06:26:52 +00001693#else
1694 if (ssl_cert_filepath != NULL &&
1695 ssl_private_key_filepath != NULL) {
Andy Greenb3a614a2013-01-19 13:08:17 +08001696 lwsl_notice(" Not compiled for OpenSSl support!\n");
Andy Greene92cd172011-01-19 13:11:55 +00001697 return NULL;
Andy Green3faa9c72010-11-08 17:03:03 +00001698 }
Andy Greenb3a614a2013-01-19 13:08:17 +08001699 lwsl_notice(" Compiled without SSL support, "
Andy Green90c7cbc2011-01-27 06:26:52 +00001700 "serving unencrypted\n");
1701#endif
Andy Greena17c6922013-01-20 20:21:54 +08001702
1703 lwsl_notice(" per-connection allocation: %u + headers\n", sizeof(struct libwebsocket));
Andy Green90c7cbc2011-01-27 06:26:52 +00001704 }
Andy Greena1ce6be2013-01-18 11:43:21 +08001705#endif
Andy Green90c7cbc2011-01-27 06:26:52 +00001706
1707 /* ignore SIGPIPE */
Peter Hinz56885f32011-03-02 22:03:47 +00001708#ifdef WIN32
1709#else
Andy Green90c7cbc2011-01-27 06:26:52 +00001710 signal(SIGPIPE, sigpipe_handler);
Peter Hinz56885f32011-03-02 22:03:47 +00001711#endif
Andy Green90c7cbc2011-01-27 06:26:52 +00001712
1713
1714#ifdef LWS_OPENSSL_SUPPORT
1715
1716 /* basic openssl init */
1717
1718 SSL_library_init();
1719
1720 OpenSSL_add_all_algorithms();
1721 SSL_load_error_strings();
1722
Andy Green2e24da02011-03-05 16:12:04 +00001723 openssl_websocket_private_data_index =
Andy Green6901cb32011-02-21 08:06:47 +00001724 SSL_get_ex_new_index(0, "libwebsockets", NULL, NULL, NULL);
1725
Andy Green90c7cbc2011-01-27 06:26:52 +00001726 /*
1727 * Firefox insists on SSLv23 not SSLv3
1728 * Konq disables SSLv2 by default now, SSLv23 works
1729 */
1730
1731 method = (SSL_METHOD *)SSLv23_server_method();
1732 if (!method) {
Andy Green43db0452013-01-10 19:50:35 +08001733 lwsl_err("problem creating ssl method: %s\n",
Andy Green90c7cbc2011-01-27 06:26:52 +00001734 ERR_error_string(ERR_get_error(), ssl_err_buf));
1735 return NULL;
1736 }
Peter Hinz56885f32011-03-02 22:03:47 +00001737 context->ssl_ctx = SSL_CTX_new(method); /* create context */
1738 if (!context->ssl_ctx) {
Andy Green43db0452013-01-10 19:50:35 +08001739 lwsl_err("problem creating ssl context: %s\n",
Andy Green90c7cbc2011-01-27 06:26:52 +00001740 ERR_error_string(ERR_get_error(), ssl_err_buf));
1741 return NULL;
1742 }
1743
David Galeanocc148e42013-01-10 10:18:59 +08001744#ifdef SSL_OP_NO_COMPRESSION
David Galeanoc72f6f92013-01-10 10:11:57 +08001745 SSL_CTX_set_options(context->ssl_ctx, SSL_OP_NO_COMPRESSION);
David Galeanocc148e42013-01-10 10:18:59 +08001746#endif
David Galeano77a677c2013-01-10 10:14:12 +08001747 SSL_CTX_set_options(context->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
David Galeanof177f2a2013-01-10 10:15:19 +08001748 SSL_CTX_set_cipher_list(context->ssl_ctx, CIPHERS_LIST_STRING);
David Galeanoc72f6f92013-01-10 10:11:57 +08001749
Andy Greena1ce6be2013-01-18 11:43:21 +08001750#ifndef LWS_NO_CLIENT
1751
Andy Green90c7cbc2011-01-27 06:26:52 +00001752 /* client context */
Andy Green6ee372f2012-04-09 15:09:01 +08001753
1754 if (port == CONTEXT_PORT_NO_LISTEN) {
Peter Hinz56885f32011-03-02 22:03:47 +00001755 method = (SSL_METHOD *)SSLv23_client_method();
1756 if (!method) {
Andy Green43db0452013-01-10 19:50:35 +08001757 lwsl_err("problem creating ssl method: %s\n",
Peter Hinz56885f32011-03-02 22:03:47 +00001758 ERR_error_string(ERR_get_error(), ssl_err_buf));
1759 return NULL;
1760 }
1761 /* create context */
1762 context->ssl_client_ctx = SSL_CTX_new(method);
1763 if (!context->ssl_client_ctx) {
Andy Green43db0452013-01-10 19:50:35 +08001764 lwsl_err("problem creating ssl context: %s\n",
Peter Hinz56885f32011-03-02 22:03:47 +00001765 ERR_error_string(ERR_get_error(), ssl_err_buf));
1766 return NULL;
1767 }
Andy Green90c7cbc2011-01-27 06:26:52 +00001768
David Galeanocc148e42013-01-10 10:18:59 +08001769#ifdef SSL_OP_NO_COMPRESSION
David Galeanoc72f6f92013-01-10 10:11:57 +08001770 SSL_CTX_set_options(context->ssl_client_ctx, SSL_OP_NO_COMPRESSION);
David Galeanocc148e42013-01-10 10:18:59 +08001771#endif
David Galeano77a677c2013-01-10 10:14:12 +08001772 SSL_CTX_set_options(context->ssl_client_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
David Galeanof177f2a2013-01-10 10:15:19 +08001773 SSL_CTX_set_cipher_list(context->ssl_client_ctx, CIPHERS_LIST_STRING);
David Galeanoc72f6f92013-01-10 10:11:57 +08001774
Peter Hinz56885f32011-03-02 22:03:47 +00001775 /* openssl init for cert verification (for client sockets) */
David Galeano2f82be82013-01-09 16:25:54 +08001776 if (!ssl_ca_filepath) {
1777 if (!SSL_CTX_load_verify_locations(
1778 context->ssl_client_ctx, NULL,
1779 LWS_OPENSSL_CLIENT_CERTS))
Andy Green43db0452013-01-10 19:50:35 +08001780 lwsl_err(
David Galeano2f82be82013-01-09 16:25:54 +08001781 "Unable to load SSL Client certs from %s "
1782 "(set by --with-client-cert-dir= in configure) -- "
1783 " client ssl isn't going to work",
1784 LWS_OPENSSL_CLIENT_CERTS);
1785 } else
1786 if (!SSL_CTX_load_verify_locations(
1787 context->ssl_client_ctx, ssl_ca_filepath,
1788 NULL))
Andy Green43db0452013-01-10 19:50:35 +08001789 lwsl_err(
David Galeano2f82be82013-01-09 16:25:54 +08001790 "Unable to load SSL Client certs "
1791 "file from %s -- client ssl isn't "
1792 "going to work", ssl_ca_filepath);
Peter Hinz56885f32011-03-02 22:03:47 +00001793
1794 /*
1795 * callback allowing user code to load extra verification certs
1796 * helping the client to verify server identity
1797 */
1798
1799 context->protocols[0].callback(context, NULL,
1800 LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
1801 context->ssl_client_ctx, NULL, 0);
Andy Green90c7cbc2011-01-27 06:26:52 +00001802 }
Andy Greena1ce6be2013-01-18 11:43:21 +08001803#endif
Andy Green6ee372f2012-04-09 15:09:01 +08001804
Andy Greenc6bf2c22011-02-20 11:10:47 +00001805 /* as a server, are we requiring clients to identify themselves? */
1806
1807 if (options & LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT) {
1808
1809 /* absolutely require the client cert */
Andy Green6ee372f2012-04-09 15:09:01 +08001810
Peter Hinz56885f32011-03-02 22:03:47 +00001811 SSL_CTX_set_verify(context->ssl_ctx,
Andy Green6901cb32011-02-21 08:06:47 +00001812 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1813 OpenSSL_verify_callback);
Andy Greenc6bf2c22011-02-20 11:10:47 +00001814
1815 /*
1816 * give user code a chance to load certs into the server
1817 * allowing it to verify incoming client certs
1818 */
1819
Peter Hinz56885f32011-03-02 22:03:47 +00001820 context->protocols[0].callback(context, NULL,
Andy Greenc6bf2c22011-02-20 11:10:47 +00001821 LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
Peter Hinz56885f32011-03-02 22:03:47 +00001822 context->ssl_ctx, NULL, 0);
Andy Greenc6bf2c22011-02-20 11:10:47 +00001823 }
1824
Peter Hinz56885f32011-03-02 22:03:47 +00001825 if (context->use_ssl) {
Andy Green90c7cbc2011-01-27 06:26:52 +00001826
1827 /* openssl init for server sockets */
1828
Andy Green3faa9c72010-11-08 17:03:03 +00001829 /* set the local certificate from CertFile */
David Galeano9b3d4b22013-01-10 10:11:21 +08001830 n = SSL_CTX_use_certificate_chain_file(context->ssl_ctx,
1831 ssl_cert_filepath);
Andy Green3faa9c72010-11-08 17:03:03 +00001832 if (n != 1) {
Andy Green43db0452013-01-10 19:50:35 +08001833 lwsl_err("problem getting cert '%s': %s\n",
Andy Green3faa9c72010-11-08 17:03:03 +00001834 ssl_cert_filepath,
1835 ERR_error_string(ERR_get_error(), ssl_err_buf));
Andy Greene92cd172011-01-19 13:11:55 +00001836 return NULL;
Andy Green3faa9c72010-11-08 17:03:03 +00001837 }
1838 /* set the private key from KeyFile */
Peter Hinz56885f32011-03-02 22:03:47 +00001839 if (SSL_CTX_use_PrivateKey_file(context->ssl_ctx,
1840 ssl_private_key_filepath, SSL_FILETYPE_PEM) != 1) {
Andy Green43db0452013-01-10 19:50:35 +08001841 lwsl_err("ssl problem getting key '%s': %s\n",
Andy Green018d8eb2010-11-08 21:04:23 +00001842 ssl_private_key_filepath,
1843 ERR_error_string(ERR_get_error(), ssl_err_buf));
Andy Greene92cd172011-01-19 13:11:55 +00001844 return NULL;
Andy Green3faa9c72010-11-08 17:03:03 +00001845 }
1846 /* verify private key */
Peter Hinz56885f32011-03-02 22:03:47 +00001847 if (!SSL_CTX_check_private_key(context->ssl_ctx)) {
Andy Green43db0452013-01-10 19:50:35 +08001848 lwsl_err("Private SSL key doesn't match cert\n");
Andy Greene92cd172011-01-19 13:11:55 +00001849 return NULL;
Andy Green3faa9c72010-11-08 17:03:03 +00001850 }
1851
1852 /* SSL is happy and has a cert it's content with */
1853 }
1854#endif
Andy Greenb45993c2010-12-18 15:13:50 +00001855
Andy Greendf736162011-01-18 15:39:02 +00001856 /* selftest */
1857
1858 if (lws_b64_selftest())
Andy Greene92cd172011-01-19 13:11:55 +00001859 return NULL;
Andy Greendf736162011-01-18 15:39:02 +00001860
Andy Greena1ce6be2013-01-18 11:43:21 +08001861#ifndef LWS_NO_SERVER
Andy Greenb45993c2010-12-18 15:13:50 +00001862 /* set up our external listening socket we serve on */
Andy Green8f037e42010-12-19 22:13:26 +00001863
Andy Green4739e5c2011-01-22 12:51:57 +00001864 if (port) {
Andy Greena1ce6be2013-01-18 11:43:21 +08001865 extern int interface_to_sa(const char *ifname, struct sockaddr_in *addr, size_t addrlen);
1866 int sockfd;
Andy Green8f037e42010-12-19 22:13:26 +00001867
Andy Green4739e5c2011-01-22 12:51:57 +00001868 sockfd = socket(AF_INET, SOCK_STREAM, 0);
1869 if (sockfd < 0) {
Andy Greenf7609e92013-01-14 13:10:55 +08001870 lwsl_err("ERROR opening socket\n");
Andy Green4739e5c2011-01-22 12:51:57 +00001871 return NULL;
1872 }
Andy Green775c0dd2010-10-29 14:15:22 +01001873
Andy Green4739e5c2011-01-22 12:51:57 +00001874 /* allow us to restart even if old sockets in TIME_WAIT */
Andy Green6ee372f2012-04-09 15:09:01 +08001875 setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
1876 (const void *)&opt, sizeof(opt));
Andy Green6c939552011-03-08 08:56:57 +00001877
1878 /* Disable Nagle */
1879 opt = 1;
Andy Green6ee372f2012-04-09 15:09:01 +08001880 setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY,
1881 (const void *)&opt, sizeof(opt));
Andy Green6c939552011-03-08 08:56:57 +00001882
Andy Greene2160712013-01-28 12:19:10 +08001883 fcntl(sockfd, F_SETFL, O_NONBLOCK);
1884
Andy Green4739e5c2011-01-22 12:51:57 +00001885 bzero((char *) &serv_addr, sizeof(serv_addr));
1886 serv_addr.sin_family = AF_INET;
Peter Hinz56885f32011-03-02 22:03:47 +00001887 if (interf == NULL)
Andy Green32375b72011-02-19 08:32:53 +00001888 serv_addr.sin_addr.s_addr = INADDR_ANY;
1889 else
Peter Hinz56885f32011-03-02 22:03:47 +00001890 interface_to_sa(interf, &serv_addr,
Andy Green32375b72011-02-19 08:32:53 +00001891 sizeof(serv_addr));
Andy Green4739e5c2011-01-22 12:51:57 +00001892 serv_addr.sin_port = htons(port);
1893
1894 n = bind(sockfd, (struct sockaddr *) &serv_addr,
1895 sizeof(serv_addr));
1896 if (n < 0) {
Andy Green43db0452013-01-10 19:50:35 +08001897 lwsl_err("ERROR on binding to port %d (%d %d)\n",
Andy Green8f037e42010-12-19 22:13:26 +00001898 port, n, errno);
Andy Green41c58032013-01-12 13:21:08 +08001899 close(sockfd);
Andy Green4739e5c2011-01-22 12:51:57 +00001900 return NULL;
1901 }
Andy Green0d338332011-02-12 11:57:43 +00001902
Aaron Zinman4550f1d2013-01-10 12:35:18 +08001903 wsi = (struct libwebsocket *)malloc(sizeof(struct libwebsocket));
Andy Green41c58032013-01-12 13:21:08 +08001904 if (wsi == NULL) {
1905 lwsl_err("Out of mem\n");
1906 close(sockfd);
1907 return NULL;
1908 }
Aaron Zinman4550f1d2013-01-10 12:35:18 +08001909 memset(wsi, 0, sizeof (struct libwebsocket));
Andy Green0d338332011-02-12 11:57:43 +00001910 wsi->sock = sockfd;
Andy Green3182ece2013-01-20 17:08:31 +08001911#ifndef LWS_NO_EXTENSIONS
Andy Greend6e09112011-03-05 16:12:15 +00001912 wsi->count_active_extensions = 0;
Andy Green3182ece2013-01-20 17:08:31 +08001913#endif
Andy Green0d338332011-02-12 11:57:43 +00001914 wsi->mode = LWS_CONNMODE_SERVER_LISTENER;
Andy Greendfb23042013-01-17 12:26:48 +08001915
1916 insert_wsi_socket_into_fds(context, wsi);
Andy Green0d338332011-02-12 11:57:43 +00001917
Andy Green65b0e912013-01-16 07:59:47 +08001918 context->listen_service_modulo = LWS_LISTEN_SERVICE_MODULO;
1919 context->listen_service_count = 0;
1920 context->listen_service_fd = sockfd;
1921
Andy Greena824d182013-01-15 20:52:29 +08001922 listen(sockfd, LWS_SOMAXCONN);
Andy Greenb3a614a2013-01-19 13:08:17 +08001923 lwsl_notice(" Listening on port %d\n", port);
Andy Green8f037e42010-12-19 22:13:26 +00001924 }
Andy Greena1ce6be2013-01-18 11:43:21 +08001925#endif
Andy Greenb45993c2010-12-18 15:13:50 +00001926
Andy Green6ee372f2012-04-09 15:09:01 +08001927 /*
1928 * drop any root privs for this process
1929 * to listen on port < 1023 we would have needed root, but now we are
1930 * listening, we don't want the power for anything else
1931 */
Peter Hinz56885f32011-03-02 22:03:47 +00001932#ifdef WIN32
1933#else
Andy Green3faa9c72010-11-08 17:03:03 +00001934 if (gid != -1)
1935 if (setgid(gid))
Andy Green43db0452013-01-10 19:50:35 +08001936 lwsl_warn("setgid: %s\n", strerror(errno));
Andy Green3faa9c72010-11-08 17:03:03 +00001937 if (uid != -1)
1938 if (setuid(uid))
Andy Green43db0452013-01-10 19:50:35 +08001939 lwsl_warn("setuid: %s\n", strerror(errno));
Peter Hinz56885f32011-03-02 22:03:47 +00001940#endif
Andy Greenb45993c2010-12-18 15:13:50 +00001941
Andy Green6f520a52013-01-29 17:57:39 +08001942 /* initialize supported protocols */
Andy Greenb45993c2010-12-18 15:13:50 +00001943
Peter Hinz56885f32011-03-02 22:03:47 +00001944 for (context->count_protocols = 0;
1945 protocols[context->count_protocols].callback;
1946 context->count_protocols++) {
Andy Green2d1301e2011-05-24 10:14:41 +01001947
Andy Green43db0452013-01-10 19:50:35 +08001948 lwsl_parser(" Protocol: %s\n",
1949 protocols[context->count_protocols].name);
Andy Green2d1301e2011-05-24 10:14:41 +01001950
Peter Hinz56885f32011-03-02 22:03:47 +00001951 protocols[context->count_protocols].owning_server = context;
1952 protocols[context->count_protocols].protocol_index =
1953 context->count_protocols;
Andy Greenb45993c2010-12-18 15:13:50 +00001954 }
Andy Greenf5bc1302013-01-21 09:09:52 +08001955
Andy Green3182ece2013-01-20 17:08:31 +08001956#ifndef LWS_NO_EXTENSIONS
Andy Greena41314f2011-05-23 10:00:03 +01001957 /*
1958 * give all extensions a chance to create any per-context
1959 * allocations they need
1960 */
1961
1962 m = LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT;
1963 if (port)
1964 m = LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT;
Andrew Chambersd5512172012-05-20 08:17:09 +08001965
1966 if (extensions) {
1967 while (extensions->callback) {
Andy Green43db0452013-01-10 19:50:35 +08001968 lwsl_ext(" Extension: %s\n", extensions->name);
Aaron Zinman4550f1d2013-01-10 12:35:18 +08001969 extensions->callback(context, extensions, NULL,
1970 (enum libwebsocket_extension_callback_reasons)m,
1971 NULL, NULL, 0);
Andrew Chambersd5512172012-05-20 08:17:09 +08001972 extensions++;
1973 }
Andy Greena41314f2011-05-23 10:00:03 +01001974 }
Andy Green3182ece2013-01-20 17:08:31 +08001975#endif
Peter Hinz56885f32011-03-02 22:03:47 +00001976 return context;
Andy Greene92cd172011-01-19 13:11:55 +00001977}
Andy Greenb45993c2010-12-18 15:13:50 +00001978
Andy Greenb45993c2010-12-18 15:13:50 +00001979/**
1980 * libwebsockets_get_protocol() - Returns a protocol pointer from a websocket
Andy Green8f037e42010-12-19 22:13:26 +00001981 * connection.
Andy Greenb45993c2010-12-18 15:13:50 +00001982 * @wsi: pointer to struct websocket you want to know the protocol of
1983 *
Andy Green8f037e42010-12-19 22:13:26 +00001984 *
Andy Green6f520a52013-01-29 17:57:39 +08001985 * Some apis can act on all live connections of a given protocol,
1986 * this is how you can get a pointer to the active protocol if needed.
Andy Greenb45993c2010-12-18 15:13:50 +00001987 */
Andy Greenab990e42010-10-31 12:42:52 +00001988
Andy Greenb45993c2010-12-18 15:13:50 +00001989const struct libwebsocket_protocols *
1990libwebsockets_get_protocol(struct libwebsocket *wsi)
1991{
1992 return wsi->protocol;
1993}
1994
Andy Green82c3d542011-03-07 21:16:31 +00001995int
1996libwebsocket_is_final_fragment(struct libwebsocket *wsi)
1997{
Andy Green623a98d2013-01-21 11:04:23 +08001998 return wsi->u.ws.final;
Andy Green82c3d542011-03-07 21:16:31 +00001999}
Alex Bligh49146db2011-11-07 17:19:25 +08002000
David Galeanoe2cf9922013-01-09 18:06:55 +08002001unsigned char
2002libwebsocket_get_reserved_bits(struct libwebsocket *wsi)
2003{
Andy Green623a98d2013-01-21 11:04:23 +08002004 return wsi->u.ws.rsv;
David Galeanoe2cf9922013-01-09 18:06:55 +08002005}
2006
Alex Bligh49146db2011-11-07 17:19:25 +08002007void *
2008libwebsocket_ensure_user_space(struct libwebsocket *wsi)
2009{
2010 /* allocate the per-connection user memory (if any) */
2011
2012 if (wsi->protocol->per_session_data_size && !wsi->user_space) {
2013 wsi->user_space = malloc(
2014 wsi->protocol->per_session_data_size);
2015 if (wsi->user_space == NULL) {
Andy Green43db0452013-01-10 19:50:35 +08002016 lwsl_err("Out of memory for conn user space\n");
Alex Bligh49146db2011-11-07 17:19:25 +08002017 return NULL;
2018 }
Andy Green6ee372f2012-04-09 15:09:01 +08002019 memset(wsi->user_space, 0,
2020 wsi->protocol->per_session_data_size);
Alex Bligh49146db2011-11-07 17:19:25 +08002021 }
2022 return wsi->user_space;
2023}
Andy Green43db0452013-01-10 19:50:35 +08002024
Andy Green0b319092013-01-19 11:17:56 +08002025static void lwsl_emit_stderr(int level, const char *line)
Andy Greende8f27a2013-01-12 09:17:42 +08002026{
Andy Green0b319092013-01-19 11:17:56 +08002027 char buf[300];
2028 struct timeval tv;
Andy Green0b319092013-01-19 11:17:56 +08002029 int n;
2030
2031 gettimeofday(&tv, NULL);
2032
2033 buf[0] = '\0';
2034 for (n = 0; n < LLL_COUNT; n++)
2035 if (level == (1 << n)) {
Andy Green058ba812013-01-19 11:32:18 +08002036 sprintf(buf, "[%ld:%04d] %s: ", tv.tv_sec,
Andy Green0b319092013-01-19 11:17:56 +08002037 (int)(tv.tv_usec / 100), log_level_names[n]);
2038 break;
2039 }
2040
2041 fprintf(stderr, "%s%s", buf, line);
Andy Greende8f27a2013-01-12 09:17:42 +08002042}
2043
Andy Greenc11db202013-01-19 11:12:16 +08002044void lwsl_emit_syslog(int level, const char *line)
2045{
2046 int syslog_level = LOG_DEBUG;
2047
2048 switch (level) {
2049 case LLL_ERR:
2050 syslog_level = LOG_ERR;
2051 break;
2052 case LLL_WARN:
2053 syslog_level = LOG_WARNING;
2054 break;
2055 case LLL_NOTICE:
2056 syslog_level = LOG_NOTICE;
2057 break;
2058 case LLL_INFO:
2059 syslog_level = LOG_INFO;
2060 break;
2061 }
Edwin van den Oetelaarf6eeabc2013-01-19 20:01:01 +08002062 syslog(syslog_level, "%s", line);
Andy Greenc11db202013-01-19 11:12:16 +08002063}
2064
Andy Green43db0452013-01-10 19:50:35 +08002065void _lws_log(int filter, const char *format, ...)
2066{
Andy Greende8f27a2013-01-12 09:17:42 +08002067 char buf[256];
Andy Green43db0452013-01-10 19:50:35 +08002068 va_list ap;
Andy Green43db0452013-01-10 19:50:35 +08002069
2070 if (!(log_level & filter))
2071 return;
2072
Andy Green43db0452013-01-10 19:50:35 +08002073 va_start(ap, format);
Andy Green0b319092013-01-19 11:17:56 +08002074 vsnprintf(buf, (sizeof buf), format, ap);
Andy Greende8f27a2013-01-12 09:17:42 +08002075 buf[(sizeof buf) - 1] = '\0';
2076 va_end(ap);
2077
Andy Green0b319092013-01-19 11:17:56 +08002078 lwsl_emit(filter, buf);
Andy Green43db0452013-01-10 19:50:35 +08002079}
2080
2081/**
2082 * lws_set_log_level() - Set the logging bitfield
2083 * @level: OR together the LLL_ debug contexts you want output from
Andy Greende8f27a2013-01-12 09:17:42 +08002084 * @log_emit_function: NULL to leave it as it is, or a user-supplied
2085 * function to perform log string emission instead of
2086 * the default stderr one.
Andy Green43db0452013-01-10 19:50:35 +08002087 *
Andy Greende8f27a2013-01-12 09:17:42 +08002088 * log level defaults to "err" and "warn" contexts enabled only and
2089 * emission on stderr.
Andy Green43db0452013-01-10 19:50:35 +08002090 */
2091
Andy Green058ba812013-01-19 11:32:18 +08002092void lws_set_log_level(int level, void (*log_emit_function)(int level, const char *line))
Andy Green43db0452013-01-10 19:50:35 +08002093{
2094 log_level = level;
Andy Greende8f27a2013-01-12 09:17:42 +08002095 if (log_emit_function)
2096 lwsl_emit = log_emit_function;
Andy Green43db0452013-01-10 19:50:35 +08002097}