blob: a5b447683039d5624960e33e6158fb7ff31fbbca [file] [log] [blame]
Andy Green7c212cc2010-11-08 20:20:42 +00001/*
2 * libwebsockets - small server side websockets and web server implementation
Andy Greene77ddd82010-11-13 10:03:47 +00003 *
Andy Greene2160712013-01-28 12:19:10 +08004 * Copyright (C) 2010 - 2013 Andy Green <andy@warmcat.com>
Andy Green7c212cc2010-11-08 20:20:42 +00005 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation:
9 * version 2.1 of the License.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301 USA
20 */
Joakim Soderberg91de9332013-02-06 15:30:33 +090021
Andy Greenb5b23192013-02-11 17:13:32 +080022/* System introspection configs */
Joakim Soderberg4c531232013-02-06 15:26:58 +090023#ifdef CMAKE_BUILD
24#include "lws_config.h"
Joakim Soderberg4f4a38b2013-02-06 15:28:07 +090025#else
Andreas Pakulat68bd4bd2013-10-28 15:18:04 +010026#if defined(WIN32) || defined(_WIN32)
Joakim Soderberg91de9332013-02-06 15:30:33 +090027#define inline __inline
Andy Green158e8042014-04-02 14:25:10 +080028#include <tchar.h>
Andy Greene40aa9b2014-04-02 21:02:54 +080029#include <mstcpip.h>
30#ifdef _WIN32_WCE
31#define vsnprintf _vsnprintf
32#endif
33
34#else /* not WIN32 */
Joakim Soderberg4f4a38b2013-02-06 15:28:07 +090035#include "config.h"
Andy Greene40aa9b2014-04-02 21:02:54 +080036
37#endif /* not WIN32 */
38#endif /* not CMAKE */
39
40#ifdef HAVE_SYS_TYPES_H
41#include <sys/types.h>
Joakim Soderberg91de9332013-02-06 15:30:33 +090042#endif
Joakim Soderberg4c531232013-02-06 15:26:58 +090043
Andy Green7c212cc2010-11-08 20:20:42 +000044#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
Patrick Ganstererb13eed42014-03-30 10:19:23 +020047#include <time.h>
Andy Green7c212cc2010-11-08 20:20:42 +000048#include <ctype.h>
Peter Young26757a72013-01-17 10:08:16 +080049#include <limits.h>
Peter Hinz56885f32011-03-02 22:03:47 +000050#include <stdarg.h>
51
Patrick Gansterere5720a32014-02-28 00:57:19 +010052#ifdef HAVE_SYS_STAT_H
Peter Hinz56885f32011-03-02 22:03:47 +000053#include <sys/stat.h>
Patrick Gansterere5720a32014-02-28 00:57:19 +010054#endif
Peter Hinz56885f32011-03-02 22:03:47 +000055
Andreas Pakulat68bd4bd2013-10-28 15:18:04 +010056#if defined(WIN32) || defined(_WIN32)
Joakim Soderberg4c531232013-02-06 15:26:58 +090057#define LWS_NO_DAEMONIZE
Patrick Gansterer2dbd8372014-02-28 12:37:52 +010058#define LWS_ERRNO WSAGetLastError()
59#define LWS_EAGAIN WSAEWOULDBLOCK
60#define LWS_EALREADY WSAEALREADY
61#define LWS_EINPROGRESS WSAEINPROGRESS
62#define LWS_EINTR WSAEINTR
63#define LWS_EISCONN WSAEISCONN
64#define LWS_EWOULDBLOCK WSAEWOULDBLOCK
Patrick Ganstererb47f87b2014-03-30 09:18:05 +020065#define LWS_POLLHUP (FD_CLOSE)
Patrick Gansterer0fc37b62014-03-28 15:44:56 +010066#define LWS_POLLIN (FD_READ | FD_ACCEPT)
67#define LWS_POLLOUT (FD_WRITE)
Patrick Gansterer73882e42014-03-29 08:25:58 +010068#define MSG_NOSIGNAL 0
69#define SHUT_RDWR SD_BOTH
70#define SOL_TCP IPPROTO_TCP
Joakim Soderberg4c531232013-02-06 15:26:58 +090071
Andy Green158e8042014-04-02 14:25:10 +080072#define compatible_close(fd) closesocket(fd)
73#define compatible_file_close(fd) CloseHandle(fd)
74#define compatible_file_seek_cur(fd, offset) SetFilePointer(fd, offset, FILE_CURRENT)
75#define compatible_file_read(amount, fd, buf, len) {\
76 DWORD _amount; \
77 if (!ReadFile(fd, buf, len, &amount, NULL)) \
78 amount = -1; \
79 else \
80 amount = _amount; \
81 }
82#define lws_set_blocking_send(wsi) wsi->sock_send_blocking = TRUE
Peter Hinz56885f32011-03-02 22:03:47 +000083#include <winsock2.h>
Peter Hinz56885f32011-03-02 22:03:47 +000084#include <windows.h>
Patrick Gansterer81338aa2014-02-27 03:21:50 +010085#define LWS_INVALID_FILE INVALID_HANDLE_VALUE
Andy Green5266f662014-04-02 21:31:07 +080086const char *inet_ntop(int af, const void *src, char *dst, int cnt);
Andy Green158e8042014-04-02 14:25:10 +080087#else /* not windows --> */
Patrick Ganstererb13eed42014-03-30 10:19:23 +020088#include <errno.h>
89#include <fcntl.h>
90#include <netdb.h>
91#include <signal.h>
92#include <strings.h>
93#include <unistd.h>
Andy Greene77ddd82010-11-13 10:03:47 +000094#include <sys/types.h>
Andy Green7c212cc2010-11-08 20:20:42 +000095#include <sys/socket.h>
Andy Greene40aa9b2014-04-02 21:02:54 +080096#ifdef LWS_BUILTIN_GETIFADDRS
97 #include <getifaddrs.h>
98#else
99 #include <ifaddrs.h>
100#endif
101#include <sys/syslog.h>
102#include <sys/un.h>
103#include <sys/socket.h>
104#include <netdb.h>
Andy Greened11a022011-01-20 10:23:50 +0000105#ifndef LWS_NO_FORK
Artem Baguinski91531662011-12-14 22:14:03 +0100106#ifdef HAVE_SYS_PRCTL_H
Andy Greenb45993c2010-12-18 15:13:50 +0000107#include <sys/prctl.h>
Andy Greened11a022011-01-20 10:23:50 +0000108#endif
Artem Baguinski91531662011-12-14 22:14:03 +0100109#endif
Andy Green7c212cc2010-11-08 20:20:42 +0000110#include <netinet/in.h>
Andy Green6c939552011-03-08 08:56:57 +0000111#include <netinet/tcp.h>
Andy Greenb45993c2010-12-18 15:13:50 +0000112#include <arpa/inet.h>
Andy Green7c212cc2010-11-08 20:20:42 +0000113#include <poll.h>
Andrew Canaday9769f4f2014-03-23 13:25:07 +0800114#ifdef LWS_USE_LIBEV
115#include <ev.h>
116#endif /* LWS_USE_LIBEV */
117
Andy Green7c212cc2010-11-08 20:20:42 +0000118#include <sys/mman.h>
Andy Green038d5822011-02-14 20:58:26 +0000119#include <sys/time.h>
Andy Green7c212cc2010-11-08 20:20:42 +0000120
Patrick Gansterer2dbd8372014-02-28 12:37:52 +0100121#define LWS_ERRNO errno
122#define LWS_EAGAIN EAGAIN
123#define LWS_EALREADY EALREADY
124#define LWS_EINPROGRESS EINPROGRESS
125#define LWS_EINTR EINTR
126#define LWS_EISCONN EISCONN
127#define LWS_EWOULDBLOCK EWOULDBLOCK
Patrick Gansterer81338aa2014-02-27 03:21:50 +0100128#define LWS_INVALID_FILE -1
Patrick Ganstererb47f87b2014-03-30 09:18:05 +0200129#define LWS_POLLHUP (POLLHUP|POLLERR)
130#define LWS_POLLIN (POLLIN)
131#define LWS_POLLOUT (POLLOUT)
Andy Green158e8042014-04-02 14:25:10 +0800132#define compatible_close(fd) close(fd)
133#define compatible_file_close(fd) close(fd)
134#define compatible_file_seek_cur(fd, offset) lseek(fd, offset, SEEK_CUR)
135#define compatible_file_read(amount, fd, buf, len) \
136 amount = read(fd, buf, len);
137#define lws_set_blocking_send(wsi)
Peter Hinz56885f32011-03-02 22:03:47 +0000138#endif
139
Patrick Gansterer4a837272014-02-28 13:17:49 +0100140#ifndef HAVE_BZERO
141#define bzero(b, len) (memset((b), '\0', (len)), (void) 0)
142#endif
143
Patrick Gansterer9d614912014-02-28 00:59:53 +0100144#ifndef HAVE_STRERROR
145#define strerror(x) ""
146#endif
147
Andy Green7c212cc2010-11-08 20:20:42 +0000148#ifdef LWS_OPENSSL_SUPPORT
Andy Green23c5f2e2013-02-06 15:43:00 +0900149#ifdef USE_CYASSL
150#include <cyassl/openssl/ssl.h>
151#include <cyassl/error.h>
152unsigned char *
153SHA1(const unsigned char *d, size_t n, unsigned char *md);
154#else
Andy Green7c212cc2010-11-08 20:20:42 +0000155#include <openssl/ssl.h>
156#include <openssl/evp.h>
157#include <openssl/err.h>
Andy Green70dfebd2010-12-20 09:35:03 +0000158#include <openssl/md5.h>
Andy Greene2522172011-01-18 17:14:03 +0000159#include <openssl/sha.h>
Andy Green23c5f2e2013-02-06 15:43:00 +0900160#endif /* not USE_CYASSL */
Darin Willitsdb9ba422011-02-14 20:56:24 +0000161#endif
162
Andy Green7c212cc2010-11-08 20:20:42 +0000163#include "libwebsockets.h"
164
Andy Green158e8042014-04-02 14:25:10 +0800165#if defined(WIN32) || defined(_WIN32)
166
167#ifndef BIG_ENDIAN
168#define BIG_ENDIAN 4321 /* to show byte order (taken from gcc) */
169#endif
170#ifndef LITTLE_ENDIAN
171#define LITTLE_ENDIAN 1234
172#endif
173#ifndef BYTE_ORDER
174#define BYTE_ORDER LITTLE_ENDIAN
175#endif
176typedef unsigned __int64 u_int64_t;
177
178#undef __P
179#ifndef __P
180#if __STDC__
181#define __P(protos) protos
182#else
183#define __P(protos) ()
184#endif
185#endif
186
187#else
188
189#include <sys/stat.h>
190#include <sys/cdefs.h>
191#include <sys/time.h>
192
193#if defined(__APPLE__)
194#include <machine/endian.h>
195#elif defined(__FreeBSD__)
196#include <sys/endian.h>
197#elif defined(__linux__)
198#include <endian.h>
199#endif
200
201#if !defined(BYTE_ORDER)
202# define BYTE_ORDER __BYTE_ORDER
203#endif
204#if !defined(LITTLE_ENDIAN)
205# define LITTLE_ENDIAN __LITTLE_ENDIAN
206#endif
207#if !defined(BIG_ENDIAN)
208# define BIG_ENDIAN __BIG_ENDIAN
209#endif
210
211#endif
212
Darin Willitsc19456f2011-02-14 17:52:39 +0000213/*
214 * Mac OSX as well as iOS do not define the MSG_NOSIGNAL flag,
215 * but happily have something equivalent in the SO_NOSIGPIPE flag.
216 */
217#ifdef __APPLE__
Andy Green6ee372f2012-04-09 15:09:01 +0800218#define MSG_NOSIGNAL SO_NOSIGPIPE
Darin Willitsc19456f2011-02-14 17:52:39 +0000219#endif
220
Andy Greenc0d6b632013-01-12 23:42:17 +0800221#ifndef LWS_MAX_HEADER_LEN
Andy Green16ab3182013-02-10 18:02:31 +0800222#define LWS_MAX_HEADER_LEN 1024
Andy Greenc0d6b632013-01-12 23:42:17 +0800223#endif
Andy Greenc0d6b632013-01-12 23:42:17 +0800224#ifndef LWS_MAX_PROTOCOLS
Andy Greend91d5e82013-02-10 16:00:47 +0800225#define LWS_MAX_PROTOCOLS 5
Andy Greenc0d6b632013-01-12 23:42:17 +0800226#endif
227#ifndef LWS_MAX_EXTENSIONS_ACTIVE
Andy Greend91d5e82013-02-10 16:00:47 +0800228#define LWS_MAX_EXTENSIONS_ACTIVE 3
Andy Greenc0d6b632013-01-12 23:42:17 +0800229#endif
230#ifndef SPEC_LATEST_SUPPORTED
Andy Greend85cb202011-09-25 09:32:54 +0100231#define SPEC_LATEST_SUPPORTED 13
Andy Greenc0d6b632013-01-12 23:42:17 +0800232#endif
233#ifndef AWAITING_TIMEOUT
David Galeanoc9f1ff82013-01-09 18:01:23 +0800234#define AWAITING_TIMEOUT 5
Andy Greenc0d6b632013-01-12 23:42:17 +0800235#endif
236#ifndef CIPHERS_LIST_STRING
David Galeanof177f2a2013-01-10 10:15:19 +0800237#define CIPHERS_LIST_STRING "DEFAULT"
Andy Greenc0d6b632013-01-12 23:42:17 +0800238#endif
Andy Greena824d182013-01-15 20:52:29 +0800239#ifndef LWS_SOMAXCONN
240#define LWS_SOMAXCONN SOMAXCONN
241#endif
Andy Green7c212cc2010-11-08 20:20:42 +0000242
Andy Greene2522172011-01-18 17:14:03 +0000243#define MAX_WEBSOCKET_04_KEY_LEN 128
Andy Green54495112013-02-06 21:10:16 +0900244#define LWS_MAX_SOCKET_IO_BUF 4096
Andy Greenc0d6b632013-01-12 23:42:17 +0800245
246#ifndef SYSTEM_RANDOM_FILEPATH
Andy Green4739e5c2011-01-22 12:51:57 +0000247#define SYSTEM_RANDOM_FILEPATH "/dev/urandom"
Andy Greenc0d6b632013-01-12 23:42:17 +0800248#endif
249#ifndef LWS_MAX_ZLIB_CONN_BUFFER
250#define LWS_MAX_ZLIB_CONN_BUFFER (64 * 1024)
251#endif
252
Andy Green65b0e912013-01-16 07:59:47 +0800253/*
254 * if not in a connection storm, check for incoming
255 * connections this many normal connection services
256 */
257#define LWS_LISTEN_SERVICE_MODULO 10
Andy Greene2522172011-01-18 17:14:03 +0000258
Andy Green5fd55cd2011-04-23 10:54:53 +0100259enum lws_websocket_opcodes_07 {
260 LWS_WS_OPCODE_07__CONTINUATION = 0,
261 LWS_WS_OPCODE_07__TEXT_FRAME = 1,
262 LWS_WS_OPCODE_07__BINARY_FRAME = 2,
Andy Greena41314f2011-05-23 10:00:03 +0100263
264 LWS_WS_OPCODE_07__NOSPEC__MUX = 7,
265
266 /* control extensions 8+ */
267
Andy Green5fd55cd2011-04-23 10:54:53 +0100268 LWS_WS_OPCODE_07__CLOSE = 8,
269 LWS_WS_OPCODE_07__PING = 9,
270 LWS_WS_OPCODE_07__PONG = 0xa,
271};
272
Andy Greena41314f2011-05-23 10:00:03 +0100273
Andy Green7c212cc2010-11-08 20:20:42 +0000274enum lws_connection_states {
275 WSI_STATE_HTTP,
Andy Greend280b6e2013-01-15 13:40:23 +0800276 WSI_STATE_HTTP_ISSUING_FILE,
Andy Green7c212cc2010-11-08 20:20:42 +0000277 WSI_STATE_HTTP_HEADERS,
kapejodce64fb02013-11-19 13:38:16 +0100278 WSI_STATE_HTTP_BODY,
Andy Green7c212cc2010-11-08 20:20:42 +0000279 WSI_STATE_DEAD_SOCKET,
Andy Green4739e5c2011-01-22 12:51:57 +0000280 WSI_STATE_ESTABLISHED,
Andy Green5e1fa172011-02-10 09:07:05 +0000281 WSI_STATE_CLIENT_UNCONNECTED,
Andy Greenbe93fef2011-02-14 20:25:43 +0000282 WSI_STATE_RETURNED_CLOSE_ALREADY,
Andy Greena41314f2011-05-23 10:00:03 +0100283 WSI_STATE_AWAITING_CLOSE_ACK,
Andy Green7c212cc2010-11-08 20:20:42 +0000284};
285
Andy Green7c212cc2010-11-08 20:20:42 +0000286enum lws_rx_parse_state {
287 LWS_RXPS_NEW,
Andy Greene77ddd82010-11-13 10:03:47 +0000288
Andy Green3e5eb782011-01-18 18:14:26 +0000289 LWS_RXPS_04_MASK_NONCE_1,
290 LWS_RXPS_04_MASK_NONCE_2,
291 LWS_RXPS_04_MASK_NONCE_3,
292
293 LWS_RXPS_04_FRAME_HDR_1,
Andy Green38e57bb2011-01-19 12:20:27 +0000294 LWS_RXPS_04_FRAME_HDR_LEN,
295 LWS_RXPS_04_FRAME_HDR_LEN16_2,
296 LWS_RXPS_04_FRAME_HDR_LEN16_1,
297 LWS_RXPS_04_FRAME_HDR_LEN64_8,
298 LWS_RXPS_04_FRAME_HDR_LEN64_7,
299 LWS_RXPS_04_FRAME_HDR_LEN64_6,
300 LWS_RXPS_04_FRAME_HDR_LEN64_5,
301 LWS_RXPS_04_FRAME_HDR_LEN64_4,
302 LWS_RXPS_04_FRAME_HDR_LEN64_3,
303 LWS_RXPS_04_FRAME_HDR_LEN64_2,
304 LWS_RXPS_04_FRAME_HDR_LEN64_1,
Andy Green3e5eb782011-01-18 18:14:26 +0000305
Andy Green283d0a22011-04-24 05:46:23 +0100306 LWS_RXPS_07_COLLECT_FRAME_KEY_1,
307 LWS_RXPS_07_COLLECT_FRAME_KEY_2,
308 LWS_RXPS_07_COLLECT_FRAME_KEY_3,
309 LWS_RXPS_07_COLLECT_FRAME_KEY_4,
310
Andy Green7c212cc2010-11-08 20:20:42 +0000311 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED
312};
313
314
Andy Green0d338332011-02-12 11:57:43 +0000315enum connection_mode {
Andy Greend280b6e2013-01-15 13:40:23 +0800316 LWS_CONNMODE_HTTP_SERVING,
Andy Green7cf6cb02013-05-19 14:04:10 +0800317 LWS_CONNMODE_HTTP_SERVING_ACCEPTED, /* actual HTTP service going on */
Andy Green38c570c2013-03-09 11:52:18 +0800318 LWS_CONNMODE_PRE_WS_SERVING_ACCEPT,
Andy Greend280b6e2013-01-15 13:40:23 +0800319
Andy Green0d338332011-02-12 11:57:43 +0000320 LWS_CONNMODE_WS_SERVING,
321 LWS_CONNMODE_WS_CLIENT,
322
Andy Greene2160712013-01-28 12:19:10 +0800323 /* transient, ssl delay hiding */
324 LWS_CONNMODE_SSL_ACK_PENDING,
325
Andy Greenbe93fef2011-02-14 20:25:43 +0000326 /* transient modes */
Andy Green5dc62ea2013-09-20 20:26:12 +0800327 LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT,
Andy Greenbe93fef2011-02-14 20:25:43 +0000328 LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY,
329 LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE,
shys24f4eb62013-10-24 22:27:08 +0800330 LWS_CONNMODE_WS_CLIENT_WAITING_SSL,
Andy Greenbe93fef2011-02-14 20:25:43 +0000331 LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY,
Andy Greena41314f2011-05-23 10:00:03 +0100332 LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT,
333 LWS_CONNMODE_WS_CLIENT_PENDING_CANDIDATE_CHILD,
Andy Greenbe93fef2011-02-14 20:25:43 +0000334
Andy Green0d338332011-02-12 11:57:43 +0000335 /* special internal types */
336 LWS_CONNMODE_SERVER_LISTENER,
Andy Green0d338332011-02-12 11:57:43 +0000337};
338
Andy Greenca0a1292013-03-16 11:24:23 +0800339enum {
340 LWS_RXFLOW_ALLOW = (1 << 0),
341 LWS_RXFLOW_PENDING_CHANGE = (1 << 1),
342};
343
Andy Greene92cd172011-01-19 13:11:55 +0000344struct libwebsocket_protocols;
Andy Greendfb23042013-01-17 12:26:48 +0800345struct libwebsocket;
Andy Greene92cd172011-01-19 13:11:55 +0000346
Andrew Canaday9769f4f2014-03-23 13:25:07 +0800347#ifdef LWS_USE_LIBEV
348struct lws_io_watcher {
349 struct ev_io watcher;
350 struct libwebsocket_context* context;
351};
352
353struct lws_signal_watcher {
354 struct ev_signal watcher;
355 struct libwebsocket_context* context;
356};
357#endif /* LWS_USE_LIBEV */
358
Andy Greenb45993c2010-12-18 15:13:50 +0000359struct libwebsocket_context {
Patrick Gansterer0fc37b62014-03-28 15:44:56 +0100360#ifdef _WIN32
361 WSAEVENT *events;
362#endif
Patrick Gansterer73882e42014-03-29 08:25:58 +0100363 struct libwebsocket_pollfd *fds;
Andy Greendfb23042013-01-17 12:26:48 +0800364 struct libwebsocket **lws_lookup; /* fd to wsi */
Andy Greenb45993c2010-12-18 15:13:50 +0000365 int fds_count;
Andrew Canaday9769f4f2014-03-23 13:25:07 +0800366#ifdef LWS_USE_LIBEV
367 struct ev_loop* io_loop;
368 struct lws_io_watcher w_accept;
369 struct lws_signal_watcher w_sigint;
370#endif /* LWS_USE_LIBEV */
Andy Greendfb23042013-01-17 12:26:48 +0800371 int max_fds;
Andy Green4739e5c2011-01-22 12:51:57 +0000372 int listen_port;
Mattias Lundberg03bb8f92014-02-18 10:06:57 +0100373 const char *iface;
Andy Green8dac94d2013-02-18 12:02:18 +0800374 char http_proxy_address[128];
375 char canonical_hostname[128];
Andy Green9659f372011-01-27 22:01:43 +0000376 unsigned int http_proxy_port;
Andy Green8014b292011-01-30 20:57:25 +0000377 unsigned int options;
Patrick Gansterer92792b42014-02-26 21:37:31 +0100378 time_t last_timeout_check_s;
Andy Green44eee682011-02-10 09:32:24 +0000379
Andy Greenb8b247d2013-01-22 07:20:08 +0800380 /*
381 * usable by anything in the service code, but only if the scope
382 * does not last longer than the service action (since next service
383 * of any socket can likewise use it and overwrite)
384 */
Andy Green54495112013-02-06 21:10:16 +0900385 unsigned char service_buffer[LWS_MAX_SOCKET_IO_BUF];
Andy Greenb8b247d2013-01-22 07:20:08 +0800386
Andy Green24cba922013-01-19 13:56:10 +0800387 int started_with_parent;
388
Andy Green44eee682011-02-10 09:32:24 +0000389 int fd_random;
Andy Green65b0e912013-01-16 07:59:47 +0800390 int listen_service_modulo;
391 int listen_service_count;
392 int listen_service_fd;
393 int listen_service_extraseen;
Andy Green6ee372f2012-04-09 15:09:01 +0800394
Patrick Gansterer1ee57f62014-03-06 11:57:50 +0100395 /*
396 * set to the Thread ID that's doing the service loop just before entry
397 * to poll indicates service thread likely idling in poll()
398 * volatile because other threads may check it as part of processing
399 * for pollfd event change.
400 */
401 volatile int service_tid;
402#ifndef _WIN32
403 int dummy_pipe_fds[2];
404#endif
405
Andy Greena690cd02013-02-09 12:25:31 +0800406 int ka_time;
407 int ka_probes;
408 int ka_interval;
409
Andy Greend636e352013-01-29 12:36:17 +0800410#ifdef LWS_LATENCY
411 unsigned long worst_latency;
412 char worst_latency_info[256];
413#endif
414
Andy Greenb45993c2010-12-18 15:13:50 +0000415#ifdef LWS_OPENSSL_SUPPORT
416 int use_ssl;
James Devine5b34c972013-12-14 11:41:29 +0800417 int allow_non_ssl_on_ssl_port;
Andy Green90c7cbc2011-01-27 06:26:52 +0000418 SSL_CTX *ssl_ctx;
419 SSL_CTX *ssl_client_ctx;
Andy Greenb45993c2010-12-18 15:13:50 +0000420#endif
Andy Greene92cd172011-01-19 13:11:55 +0000421 struct libwebsocket_protocols *protocols;
Andy Greenb45993c2010-12-18 15:13:50 +0000422 int count_protocols;
Andy Green3182ece2013-01-20 17:08:31 +0800423#ifndef LWS_NO_EXTENSIONS
Andy Greend6e09112011-03-05 16:12:15 +0000424 struct libwebsocket_extension *extensions;
Andy Green3182ece2013-01-20 17:08:31 +0800425#endif
Andy Greenb5b23192013-02-11 17:13:32 +0800426 void *user_space;
Andy Greenb45993c2010-12-18 15:13:50 +0000427};
428
Andrew Canaday9769f4f2014-03-23 13:25:07 +0800429#ifdef LWS_USE_LIBEV
430#define LWS_LIBEV_ENABLED(context) (context->options & LWS_SERVER_OPTION_LIBEV)
431#else
432#define LWS_LIBEV_ENABLED(context) (0)
433#endif
434
Andy Green055f2972014-03-24 16:09:25 +0800435#ifdef LWS_USE_IPV6
436#define LWS_IPV6_ENABLED(context) (!(context->options & LWS_SERVER_OPTION_DISABLE_IPV6))
James Devine3f13ea22014-03-24 16:09:25 +0800437#else
438#define LWS_IPV6_ENABLED(context) (0)
439#endif
Andrew Canaday9769f4f2014-03-23 13:25:07 +0800440
Andy Greenb1a9e502013-11-10 15:15:21 +0800441enum uri_path_states {
442 URIPS_IDLE,
443 URIPS_SEEN_SLASH,
444 URIPS_SEEN_SLASH_DOT,
445 URIPS_SEEN_SLASH_DOT_DOT,
Andy Green1e3f7b82013-11-13 07:45:17 +0800446 URIPS_ARGUMENTS,
Andy Greenb1a9e502013-11-10 15:15:21 +0800447};
448
449enum uri_esc_states {
450 URIES_IDLE,
451 URIES_SEEN_PERCENT,
452 URIES_SEEN_PERCENT_H1,
453};
Andy Greenf3d3b402011-02-09 07:16:34 +0000454
Andy Green7c212cc2010-11-08 20:20:42 +0000455/*
456 * This is totally opaque to code using the library. It's exported as a
457 * forward-reference pointer-only declaration; the user can use the pointer with
458 * other APIs to get information out of it.
459 */
460
Andy Green16ab3182013-02-10 18:02:31 +0800461struct lws_fragments {
462 unsigned short offset;
463 unsigned short len;
464 unsigned char next_frag_index;
465};
466
467struct allocated_headers {
468 unsigned short next_frag_index;
469 unsigned short pos;
470 unsigned char frag_index[WSI_TOKEN_COUNT];
471 struct lws_fragments frags[WSI_TOKEN_COUNT * 2];
472 char data[LWS_MAX_HEADER_LEN];
Andy Greena7521de2013-02-18 10:38:45 +0800473#ifndef LWS_NO_CLIENT
474 char initial_handshake_hash_base64[30];
475 unsigned short c_port;
476#endif
Andy Green16ab3182013-02-10 18:02:31 +0800477};
478
Andy Green84fd9492013-11-09 11:40:32 +0800479struct _lws_http_mode_related {
480 struct allocated_headers *ah; /* mirroring _lws_header_related */
Patrick Gansterer81338aa2014-02-27 03:21:50 +0100481#if defined(WIN32) || defined(_WIN32)
482 HANDLE fd;
483#else
Andy Green84fd9492013-11-09 11:40:32 +0800484 int fd;
Patrick Gansterer81338aa2014-02-27 03:21:50 +0100485#endif
Andy Green84fd9492013-11-09 11:40:32 +0800486 unsigned long filepos;
487 unsigned long filelen;
kapejodce64fb02013-11-19 13:38:16 +0100488
489 int content_length;
490 int content_length_seen;
491 int body_index;
492 unsigned char *post_buffer;
Andy Green84fd9492013-11-09 11:40:32 +0800493};
494
Andy Green623a98d2013-01-21 11:04:23 +0800495struct _lws_header_related {
Andy Green16ab3182013-02-10 18:02:31 +0800496 struct allocated_headers *ah;
Andy Green6636eec2013-02-18 10:34:25 +0800497 short lextable_pos;
Andy Greend91d5e82013-02-10 16:00:47 +0800498 unsigned char parser_state; /* enum lws_token_indexes */
Andy Greenb1a9e502013-11-10 15:15:21 +0800499 enum uri_path_states ups;
500 enum uri_esc_states ues;
501 char esc_stash;
Andy Green623a98d2013-01-21 11:04:23 +0800502};
503
504struct _lws_websocket_related {
Andy Green54495112013-02-06 21:10:16 +0900505 char *rx_user_buffer;
Andy Green623a98d2013-01-21 11:04:23 +0800506 int rx_user_buffer_head;
Andy Green623a98d2013-01-21 11:04:23 +0800507 unsigned char frame_masking_nonce_04[4];
Andy Green623a98d2013-01-21 11:04:23 +0800508 unsigned char frame_mask_index;
509 size_t rx_packet_length;
510 unsigned char opcode;
Andy Greend91d5e82013-02-10 16:00:47 +0800511 unsigned int final:1;
Andy Green623a98d2013-01-21 11:04:23 +0800512 unsigned char rsv;
Andy Greend91d5e82013-02-10 16:00:47 +0800513 unsigned int frame_is_binary:1;
Andy Greend91d5e82013-02-10 16:00:47 +0800514 unsigned int all_zero_nonce:1;
Andy Green6636eec2013-02-18 10:34:25 +0800515 short close_reason; /* enum lws_close_status */
Andy Green623a98d2013-01-21 11:04:23 +0800516 unsigned char *rxflow_buffer;
517 int rxflow_len;
518 int rxflow_pos;
Andy Green6636eec2013-02-18 10:34:25 +0800519 unsigned int rxflow_change_to:2;
Andy Greend91d5e82013-02-10 16:00:47 +0800520 unsigned int this_frame_masked:1;
Andy Green1f4267b2013-10-17 08:09:19 +0800521 unsigned int inside_frame:1; /* next write will be more of frame */
522 unsigned int clean_buffer:1; /* buffer not rewritten by extension */
Andy Green623a98d2013-01-21 11:04:23 +0800523};
524
Andy Green7c212cc2010-11-08 20:20:42 +0000525struct libwebsocket {
Andy Green623a98d2013-01-21 11:04:23 +0800526
527 /* lifetime members */
528
Andrew Canaday9769f4f2014-03-23 13:25:07 +0800529#ifdef LWS_USE_LIBEV
530 struct lws_io_watcher w_read;
531 struct lws_io_watcher w_write;
532#endif /* LWS_USE_LIBEV */
Andy Green4f3943a2010-11-12 10:44:16 +0000533 const struct libwebsocket_protocols *protocol;
Andy Green3182ece2013-01-20 17:08:31 +0800534#ifndef LWS_NO_EXTENSIONS
Andy Green46c2ea02011-03-22 09:04:01 +0000535 struct libwebsocket_extension *
Andy Greend6e09112011-03-05 16:12:15 +0000536 active_extensions[LWS_MAX_EXTENSIONS_ACTIVE];
Andy Green6ee372f2012-04-09 15:09:01 +0800537 void *active_extensions_user[LWS_MAX_EXTENSIONS_ACTIVE];
Andy Greend91d5e82013-02-10 16:00:47 +0800538 unsigned char count_active_extensions;
539 unsigned int extension_data_pending:1;
Andy Green3182ece2013-01-20 17:08:31 +0800540#endif
Andy Greend91d5e82013-02-10 16:00:47 +0800541 unsigned char ietf_spec_revision;
Andy Green623a98d2013-01-21 11:04:23 +0800542
Andy Greend91d5e82013-02-10 16:00:47 +0800543 char mode; /* enum connection_mode */
544 char state; /* enum lws_connection_states */
545 char lws_rx_parse_state; /* enum lws_rx_parse_state */
546 char rx_frame_type; /* enum libwebsocket_write_protocol */
Andy Green623a98d2013-01-21 11:04:23 +0800547
Andy Green224149a2013-02-11 21:43:41 +0800548 unsigned int hdr_parsing_completed:1;
549
Andy Greend91d5e82013-02-10 16:00:47 +0800550 char pending_timeout; /* enum pending_timeout */
Patrick Gansterer92792b42014-02-26 21:37:31 +0100551 time_t pending_timeout_limit;
Andy Green6452f1e2010-11-11 09:22:22 +0000552
Andy Green7c212cc2010-11-08 20:20:42 +0000553 int sock;
Andy Greendfb23042013-01-17 12:26:48 +0800554 int position_in_fds_table;
Andy Greend636e352013-01-29 12:36:17 +0800555#ifdef LWS_LATENCY
556 unsigned long action_start;
557 unsigned long latency_start;
558#endif
Andy Green7c212cc2010-11-08 20:20:42 +0000559
Andy Green2764eba2013-12-09 14:16:17 +0800560 /* truncated send handling */
561 unsigned char *truncated_send_malloc; /* non-NULL means buffering in progress */
Andy Greene254d952014-03-23 11:41:15 +0800562 unsigned int truncated_send_allocation; /* size of malloc */
Andy Green2764eba2013-12-09 14:16:17 +0800563 unsigned int truncated_send_offset; /* where we are in terms of spilling */
564 unsigned int truncated_send_len; /* how much is buffered */
565
Andy Green623a98d2013-01-21 11:04:23 +0800566 void *user_space;
Andy Green38e57bb2011-01-19 12:20:27 +0000567
Andy Green623a98d2013-01-21 11:04:23 +0800568 /* members with mutually exclusive lifetimes are unionized */
Andy Green38e57bb2011-01-19 12:20:27 +0000569
Andy Green623a98d2013-01-21 11:04:23 +0800570 union u {
571 struct _lws_http_mode_related http;
572 struct _lws_header_related hdr;
573 struct _lws_websocket_related ws;
574 } u;
Andy Greena1ce6be2013-01-18 11:43:21 +0800575
Andy Green7c212cc2010-11-08 20:20:42 +0000576#ifdef LWS_OPENSSL_SUPPORT
577 SSL *ssl;
Andy Green90c7cbc2011-01-27 06:26:52 +0000578 BIO *client_bio;
Andy Greend91d5e82013-02-10 16:00:47 +0800579 unsigned int use_ssl:2;
Andy Greenb5b23192013-02-11 17:13:32 +0800580#endif
Patrick Gansterer0fc37b62014-03-28 15:44:56 +0100581
582#ifdef _WIN32
583 BOOL sock_send_blocking;
584#endif
Andy Green7c212cc2010-11-08 20:20:42 +0000585};
586
Andy Green3d67f512014-04-03 07:29:50 +0800587LWS_EXTERN int log_level;
588
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800589LWS_EXTERN void
Andy Green508946c2013-02-12 10:19:08 +0800590libwebsocket_close_and_free_session(struct libwebsocket_context *context,
591 struct libwebsocket *wsi, enum lws_close_status);
592
Andy Greend636e352013-01-29 12:36:17 +0800593#ifndef LWS_LATENCY
Andy Greenb5b23192013-02-11 17:13:32 +0800594static inline void lws_latency(struct libwebsocket_context *context,
595 struct libwebsocket *wsi, const char *action,
596 int ret, int completion) { while (0); }
597static inline void lws_latency_pre(struct libwebsocket_context *context,
598 struct libwebsocket *wsi) { while (0); }
Andy Greend636e352013-01-29 12:36:17 +0800599#else
600#define lws_latency_pre(_context, _wsi) lws_latency(_context, _wsi, NULL, 0, 0)
601extern void
Andy Greenb5b23192013-02-11 17:13:32 +0800602lws_latency(struct libwebsocket_context *context,
603 struct libwebsocket *wsi, const char *action,
604 int ret, int completion);
Andy Greend636e352013-01-29 12:36:17 +0800605#endif
606
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800607LWS_EXTERN int
Andy Green4739e5c2011-01-22 12:51:57 +0000608libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c);
609
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800610LWS_EXTERN int
Andy Greenb45993c2010-12-18 15:13:50 +0000611libwebsocket_parse(struct libwebsocket *wsi, unsigned char c);
612
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800613LWS_EXTERN int
Andy Greenb45993c2010-12-18 15:13:50 +0000614libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi,
615 unsigned char *buf, size_t len);
Andy Green8f037e42010-12-19 22:13:26 +0000616
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800617LWS_EXTERN int
Andy Greendf736162011-01-18 15:39:02 +0000618lws_b64_selftest(void);
Andy Greenbfb051f2011-02-09 08:49:14 +0000619
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800620LWS_EXTERN struct libwebsocket *
Peter Hinz56885f32011-03-02 22:03:47 +0000621wsi_from_fd(struct libwebsocket_context *context, int fd);
Andy Green0d338332011-02-12 11:57:43 +0000622
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800623LWS_EXTERN int
Andy Greenb5b23192013-02-11 17:13:32 +0800624insert_wsi_socket_into_fds(struct libwebsocket_context *context,
625 struct libwebsocket *wsi);
Darin Willitsc19456f2011-02-14 17:52:39 +0000626
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800627LWS_EXTERN int
Andy Greend44bf7f2011-03-06 10:29:38 +0000628lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len);
629
Andy Green95a7b5d2011-03-06 10:29:39 +0000630
Andy Green1c6e1422013-02-20 19:11:31 +0800631LWS_EXTERN int
Andy Greena41314f2011-05-23 10:00:03 +0100632libwebsocket_service_timeout_check(struct libwebsocket_context *context,
633 struct libwebsocket *wsi, unsigned int sec);
634
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800635LWS_EXTERN struct libwebsocket *
Markus Elfring75212332013-10-26 20:23:00 +0800636libwebsocket_client_connect_2(struct libwebsocket_context *context,
Andy Greena41314f2011-05-23 10:00:03 +0100637 struct libwebsocket *wsi);
638
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800639LWS_EXTERN struct libwebsocket *
Andy Greena41314f2011-05-23 10:00:03 +0100640libwebsocket_create_new_server_wsi(struct libwebsocket_context *context);
641
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800642LWS_EXTERN char *
Andy Greena41314f2011-05-23 10:00:03 +0100643libwebsockets_generate_client_handshake(struct libwebsocket_context *context,
644 struct libwebsocket *wsi, char *pkt);
645
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800646LWS_EXTERN int
Andy Greena41314f2011-05-23 10:00:03 +0100647lws_handle_POLLOUT_event(struct libwebsocket_context *context,
Patrick Gansterer73882e42014-03-29 08:25:58 +0100648 struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd);
Andy Green3182ece2013-01-20 17:08:31 +0800649#ifndef LWS_NO_EXTENSIONS
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800650LWS_EXTERN int
Andy Greena41314f2011-05-23 10:00:03 +0100651lws_any_extension_handled(struct libwebsocket_context *context,
Andy Green6ee372f2012-04-09 15:09:01 +0800652 struct libwebsocket *wsi,
653 enum libwebsocket_extension_callback_reasons r,
654 void *v, size_t len);
Andy Greena41314f2011-05-23 10:00:03 +0100655
Andy Green2c24ec02014-04-02 19:45:42 +0800656LWS_EXTERN int
657lws_ext_callback_for_each_active(struct libwebsocket *wsi, int reason,
658 void *buf, int len);
659LWS_EXTERN int
660lws_ext_callback_for_each_extension_type(
661 struct libwebsocket_context *context, struct libwebsocket *wsi,
662 int reason, void *arg, int len);
663#else
664#define lws_any_extension_handled(_a, _b, _c, _d, _e) (0)
665#define lws_ext_callback_for_each_active(_a, _b, _c, _d) (0)
666#define lws_ext_callback_for_each_extension_type(_a, _b, _c, _d, _e) (0)
Andy Green3182ece2013-01-20 17:08:31 +0800667#endif
Andy Greena41314f2011-05-23 10:00:03 +0100668
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800669LWS_EXTERN int
Andy Greena41314f2011-05-23 10:00:03 +0100670lws_client_interpret_server_handshake(struct libwebsocket_context *context,
671 struct libwebsocket *wsi);
672
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800673LWS_EXTERN int
Andy Greena41314f2011-05-23 10:00:03 +0100674libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c);
675
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800676LWS_EXTERN int
Andy Green09226502011-05-28 10:19:19 +0100677lws_issue_raw_ext_access(struct libwebsocket *wsi,
678 unsigned char *buf, size_t len);
679
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800680LWS_EXTERN int
Andy Green706961d2013-01-17 16:50:35 +0800681_libwebsocket_rx_flow_control(struct libwebsocket *wsi);
682
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800683LWS_EXTERN int
Andy Greenb5b23192013-02-11 17:13:32 +0800684user_callback_handle_rxflow(callback_function,
685 struct libwebsocket_context *context,
Andy Green706961d2013-01-17 16:50:35 +0800686 struct libwebsocket *wsi,
687 enum libwebsocket_callback_reasons reason, void *user,
688 void *in, size_t len);
689
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800690LWS_EXTERN int
Andy Green158e8042014-04-02 14:25:10 +0800691lws_plat_set_socket_options(struct libwebsocket_context *context, int fd);
Andy Greena690cd02013-02-09 12:25:31 +0800692
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800693LWS_EXTERN int
Andy Green16ab3182013-02-10 18:02:31 +0800694lws_allocate_header_table(struct libwebsocket *wsi);
695
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800696LWS_EXTERN char *
Andy Green16ab3182013-02-10 18:02:31 +0800697lws_hdr_simple_ptr(struct libwebsocket *wsi, enum lws_token_indexes h);
698
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800699LWS_EXTERN int
Andy Greenb5b23192013-02-11 17:13:32 +0800700lws_hdr_simple_create(struct libwebsocket *wsi,
701 enum lws_token_indexes h, const char *s);
702
Andy Green2af4d5b2013-02-18 16:30:10 +0800703LWS_EXTERN int
704libwebsocket_ensure_user_space(struct libwebsocket *wsi);
705
Andy Green158e8042014-04-02 14:25:10 +0800706LWS_EXTERN int
Andy Green91f19d82013-12-21 11:18:34 +0800707lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or);
708
Andy Greenb5b23192013-02-11 17:13:32 +0800709#ifndef LWS_NO_SERVER
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800710LWS_EXTERN int handshake_0405(struct libwebsocket_context *context,
Andy Greenb5b23192013-02-11 17:13:32 +0800711 struct libwebsocket *wsi);
712#endif
713
714#ifndef LWS_NO_DAEMONIZE
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800715LWS_EXTERN int get_daemonize_pid();
Andy Greenb5b23192013-02-11 17:13:32 +0800716#endif
717
Andy Greena654fc02014-04-03 07:16:40 +0800718LWS_EXTERN int interface_to_sa(struct libwebsocket_context *context,
James Devine3f13ea22014-03-24 16:09:25 +0800719 const char *ifname, struct sockaddr_in *addr, size_t addrlen);
Andy Greene77fb802013-02-11 13:04:45 +0800720
Andy Green158e8042014-04-02 14:25:10 +0800721#ifdef _WIN32
722LWS_EXTERN HANDLE lws_plat_open_file(const char* filename, unsigned long* filelen);
723#else
724LWS_EXTERN int lws_plat_open_file(const char* filename, unsigned long* filelen);
725#endif
726
Darin Willitsc19456f2011-02-14 17:52:39 +0000727#ifndef LWS_OPENSSL_SUPPORT
728
729unsigned char *
730SHA1(const unsigned char *d, size_t n, unsigned char *md);
731
Andy Greenb5b23192013-02-11 17:13:32 +0800732#else
733
Joakim Soderbergf272cb02013-02-13 09:29:26 +0800734LWS_EXTERN int openssl_websocket_private_data_index;
Andy Greenb5b23192013-02-11 17:13:32 +0800735
Darin Willitsc19456f2011-02-14 17:52:39 +0000736#endif
Andy Greena654fc02014-04-03 07:16:40 +0800737
738#ifndef LWS_NO_CLIENT
739 LWS_EXTERN int lws_client_socket_service(
740 struct libwebsocket_context *context,
741 struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd);
742#endif
743#ifndef LWS_NO_SERVER
744 LWS_EXTERN int lws_server_socket_service(
745 struct libwebsocket_context *context,
746 struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd);
747#endif
748
749/*
750 * lws_plat_
751 */
752LWS_EXTERN void
753lws_plat_delete_socket_from_fds(struct libwebsocket_context *context,
754 struct libwebsocket *wsi, int m);
755LWS_EXTERN void
756lws_plat_insert_socket_into_fds(struct libwebsocket_context *context,
757 struct libwebsocket *wsi);
758LWS_EXTERN void
759lws_plat_service_periodic(struct libwebsocket_context *context);
760
761LWS_EXTERN int
762lws_plat_change_pollfd(struct libwebsocket_context *context,
763 struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd);
764LWS_EXTERN int
765lws_plat_context_early_init(void);
766LWS_EXTERN void
767lws_plat_context_early_destroy(struct libwebsocket_context *context);
768LWS_EXTERN void
769lws_plat_context_late_destroy(struct libwebsocket_context *context);
770LWS_EXTERN int
771lws_poll_listen_fd(struct libwebsocket_pollfd *fd);
772LWS_EXTERN int
773lws_plat_service(struct libwebsocket_context *context, int timeout_ms);
774LWS_EXTERN int
775lws_plat_init_fd_tables(struct libwebsocket_context *context);
776LWS_EXTERN void
777lws_plat_drop_app_privileges(struct lws_context_creation_info *info);
778LWS_EXTERN unsigned long long
779time_in_microseconds(void);
780LWS_EXTERN const char *
781lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt);