27b2049f0d0b9d889fb989606da724baa7c81970
[profile/ivi/libwebsockets.git] / lib / private-libwebsockets.h
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * 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
20  */
21
22 #include <unistd.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <strings.h>
27 #include <ctype.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <signal.h>
31 #ifdef  __MINGW64__
32 #else
33 #ifdef  __MINGW32__
34 #else
35 #include <netdb.h>
36 #endif
37 #endif
38 #include <stdarg.h>
39
40 #include <sys/stat.h>
41
42 #ifdef WIN32
43 #define compatible_close(fd) closesocket(fd);
44 #ifdef  __MINGW64__                                                             
45 #else                                                                           
46 #ifdef  __MINGW32__                                                             
47 #else
48 #include <time.h >
49 #endif
50 #endif
51 #include <winsock2.h>
52 #include <ws2ipdef.h>
53 #include <windows.h>
54 #else
55 #include <sys/types.h>
56 #include <sys/socket.h>
57 #ifndef LWS_NO_FORK
58 #ifdef HAVE_SYS_PRCTL_H
59 #include <sys/prctl.h>
60 #endif
61 #endif
62 #include <netinet/in.h>
63 #include <netinet/tcp.h>
64 #include <arpa/inet.h>
65
66 #include <poll.h>
67 #include <sys/mman.h>
68 #include <sys/time.h>
69
70 #define compatible_close(fd) close(fd);
71 #endif
72
73 #ifdef LWS_OPENSSL_SUPPORT
74 #include <openssl/ssl.h>
75 #include <openssl/evp.h>
76 #include <openssl/err.h>
77 #include <openssl/md5.h>
78 #include <openssl/sha.h>
79 #endif
80
81 /* some Linux toolchains don't have this from the above, some do */
82 #ifndef PATH_MAX
83 #include <linux/limits.h>
84 #endif
85
86 #include "libwebsockets.h"
87
88 extern void _lws_log(int filter, const char *format, ...);
89
90 /* warn and log are always compiled in */
91 #define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__)
92 #define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__)
93
94 /*
95  *  weaker logging can be deselected at configure time using disable_debug
96  *  that gets rid of the overhead of checking while keeping _warn and _err
97  *  active
98  */
99 #ifdef _DEBUG
100 #define lwsl_info(...) _lws_log(LLL_INFO, __VA_ARGS__)
101 #define lwsl_debug(...) _lws_log(LLL_DEBUG, __VA_ARGS__)
102 #define lwsl_parser(...) _lws_log(LLL_PARSER, __VA_ARGS__)
103 #define lwsl_header(...)  _lws_log(LLL_HEADER, __VA_ARGS__)
104 #define lwsl_ext(...)  _lws_log(LLL_HEADER, __VA_ARGS__)
105 #define lwsl_client(...) _lws_log(LLL_CLIENT, __VA_ARGS__)
106 #else /* no debug */
107 #define lwsl_info(...)
108 #define lwsl_debug(...)
109 #define lwsl_parser(...)
110 #define lwsl_header(...)
111 #define lwsl_ext(...)
112 #define lwsl_client(...)
113 #endif
114
115 /*
116  * Mac OSX as well as iOS do not define the MSG_NOSIGNAL flag,
117  * but happily have something equivalent in the SO_NOSIGPIPE flag.
118  */
119 #ifdef __APPLE__
120 #define MSG_NOSIGNAL SO_NOSIGPIPE
121 #endif
122
123
124 #ifndef FD_HASHTABLE_MODULUS
125 #define FD_HASHTABLE_MODULUS 32
126 #endif
127 #ifndef MAX_CLIENTS
128 #define MAX_CLIENTS 100
129 #endif
130 #ifndef LWS_MAX_HEADER_NAME_LENGTH
131 #define LWS_MAX_HEADER_NAME_LENGTH 64
132 #endif
133 #ifndef LWS_MAX_HEADER_LEN
134 #define LWS_MAX_HEADER_LEN 4096
135 #endif
136 #ifndef LWS_INITIAL_HDR_ALLOC
137 #define LWS_INITIAL_HDR_ALLOC 256
138 #endif
139 #ifndef LWS_ADDITIONAL_HDR_ALLOC
140 #define LWS_ADDITIONAL_HDR_ALLOC 64
141 #endif
142 #ifndef MAX_USER_RX_BUFFER
143 #define MAX_USER_RX_BUFFER 4096
144 #endif
145 #ifndef MAX_BROADCAST_PAYLOAD
146 #define MAX_BROADCAST_PAYLOAD 4096
147 #endif
148 #ifndef LWS_MAX_PROTOCOLS
149 #define LWS_MAX_PROTOCOLS 10
150 #endif
151 #ifndef LWS_MAX_EXTENSIONS_ACTIVE
152 #define LWS_MAX_EXTENSIONS_ACTIVE 10
153 #endif
154 #ifndef SPEC_LATEST_SUPPORTED
155 #define SPEC_LATEST_SUPPORTED 13
156 #endif
157 #ifndef AWAITING_TIMEOUT
158 #define AWAITING_TIMEOUT 5
159 #endif
160 #ifndef CIPHERS_LIST_STRING
161 #define CIPHERS_LIST_STRING "DEFAULT"
162 #endif
163 #ifndef LWS_SOMAXCONN
164 #define LWS_SOMAXCONN SOMAXCONN
165 #endif
166
167 #define MAX_WEBSOCKET_04_KEY_LEN 128
168
169 #ifndef SYSTEM_RANDOM_FILEPATH
170 #define SYSTEM_RANDOM_FILEPATH "/dev/urandom"
171 #endif
172 #ifndef LWS_MAX_ZLIB_CONN_BUFFER
173 #define LWS_MAX_ZLIB_CONN_BUFFER (64 * 1024)
174 #endif
175
176
177 enum lws_websocket_opcodes_04 {
178         LWS_WS_OPCODE_04__CONTINUATION = 0,
179         LWS_WS_OPCODE_04__CLOSE = 1,
180         LWS_WS_OPCODE_04__PING = 2,
181         LWS_WS_OPCODE_04__PONG = 3,
182         LWS_WS_OPCODE_04__TEXT_FRAME = 4,
183         LWS_WS_OPCODE_04__BINARY_FRAME = 5,
184
185         LWS_WS_OPCODE_04__RESERVED_6 = 6,
186         LWS_WS_OPCODE_04__RESERVED_7 = 7,
187         LWS_WS_OPCODE_04__RESERVED_8 = 8,
188         LWS_WS_OPCODE_04__RESERVED_9 = 9,
189         LWS_WS_OPCODE_04__RESERVED_A = 0xa,
190         LWS_WS_OPCODE_04__RESERVED_B = 0xb,
191         LWS_WS_OPCODE_04__RESERVED_C = 0xc,
192         LWS_WS_OPCODE_04__RESERVED_D = 0xd,
193         LWS_WS_OPCODE_04__RESERVED_E = 0xe,
194         LWS_WS_OPCODE_04__RESERVED_F = 0xf,
195 };
196
197 enum lws_websocket_opcodes_07 {
198         LWS_WS_OPCODE_07__CONTINUATION = 0,
199         LWS_WS_OPCODE_07__TEXT_FRAME = 1,
200         LWS_WS_OPCODE_07__BINARY_FRAME = 2,
201
202         LWS_WS_OPCODE_07__NOSPEC__MUX = 7,
203
204         /* control extensions 8+ */
205
206         LWS_WS_OPCODE_07__CLOSE = 8,
207         LWS_WS_OPCODE_07__PING = 9,
208         LWS_WS_OPCODE_07__PONG = 0xa,
209 };
210
211
212 enum lws_connection_states {
213         WSI_STATE_HTTP,
214         WSI_STATE_HTTP_ISSUING_FILE,
215         WSI_STATE_HTTP_HEADERS,
216         WSI_STATE_DEAD_SOCKET,
217         WSI_STATE_ESTABLISHED,
218         WSI_STATE_CLIENT_UNCONNECTED,
219         WSI_STATE_RETURNED_CLOSE_ALREADY,
220         WSI_STATE_AWAITING_CLOSE_ACK,
221 };
222
223 enum lws_rx_parse_state {
224         LWS_RXPS_NEW,
225
226         LWS_RXPS_SEEN_76_FF,
227         LWS_RXPS_PULLING_76_LENGTH,
228         LWS_RXPS_EAT_UNTIL_76_FF,
229
230         LWS_RXPS_04_MASK_NONCE_1,
231         LWS_RXPS_04_MASK_NONCE_2,
232         LWS_RXPS_04_MASK_NONCE_3,
233
234         LWS_RXPS_04_FRAME_HDR_1,
235         LWS_RXPS_04_FRAME_HDR_LEN,
236         LWS_RXPS_04_FRAME_HDR_LEN16_2,
237         LWS_RXPS_04_FRAME_HDR_LEN16_1,
238         LWS_RXPS_04_FRAME_HDR_LEN64_8,
239         LWS_RXPS_04_FRAME_HDR_LEN64_7,
240         LWS_RXPS_04_FRAME_HDR_LEN64_6,
241         LWS_RXPS_04_FRAME_HDR_LEN64_5,
242         LWS_RXPS_04_FRAME_HDR_LEN64_4,
243         LWS_RXPS_04_FRAME_HDR_LEN64_3,
244         LWS_RXPS_04_FRAME_HDR_LEN64_2,
245         LWS_RXPS_04_FRAME_HDR_LEN64_1,
246
247         LWS_RXPS_07_COLLECT_FRAME_KEY_1,
248         LWS_RXPS_07_COLLECT_FRAME_KEY_2,
249         LWS_RXPS_07_COLLECT_FRAME_KEY_3,
250         LWS_RXPS_07_COLLECT_FRAME_KEY_4,
251
252         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED
253 };
254
255
256 enum connection_mode {
257         LWS_CONNMODE_HTTP_SERVING,
258
259         LWS_CONNMODE_WS_SERVING,
260         LWS_CONNMODE_WS_CLIENT,
261
262         /* transient modes */
263         LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY,
264         LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE,
265         LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY,
266         LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT,
267         LWS_CONNMODE_WS_CLIENT_PENDING_CANDIDATE_CHILD,
268
269         /* special internal types */
270         LWS_CONNMODE_SERVER_LISTENER,
271         LWS_CONNMODE_BROADCAST_PROXY_LISTENER,
272         LWS_CONNMODE_BROADCAST_PROXY
273 };
274
275
276 #define LWS_FD_HASH(fd) ((fd ^ (fd >> 8) ^ (fd >> 16)) % FD_HASHTABLE_MODULUS)
277
278 struct libwebsocket_fd_hashtable {
279         struct libwebsocket *wsi[MAX_CLIENTS + 1];
280         int length;
281 };
282
283 struct libwebsocket_protocols;
284
285 struct libwebsocket_context {
286         struct libwebsocket_fd_hashtable fd_hashtable[FD_HASHTABLE_MODULUS];
287         struct pollfd fds[MAX_CLIENTS * FD_HASHTABLE_MODULUS + 1];
288         int fds_count;
289         int listen_port;
290         char http_proxy_address[256];
291         char canonical_hostname[1024];
292         unsigned int http_proxy_port;
293         unsigned int options;
294         unsigned long last_timeout_check_s;
295
296         int fd_random;
297
298 #ifdef LWS_OPENSSL_SUPPORT
299         int use_ssl;
300         SSL_CTX *ssl_ctx;
301         SSL_CTX *ssl_client_ctx;
302 #endif
303         struct libwebsocket_protocols *protocols;
304         int count_protocols;
305         struct libwebsocket_extension *extensions;
306
307     void *user_space;
308 };
309
310
311 enum pending_timeout {
312         NO_PENDING_TIMEOUT = 0,
313         PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE,
314         PENDING_TIMEOUT_ESTABLISH_WITH_SERVER,
315         PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE,
316         PENDING_TIMEOUT_AWAITING_PING,
317         PENDING_TIMEOUT_CLOSE_ACK,
318         PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE,
319         PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE,
320 };
321
322
323 /*
324  * This is totally opaque to code using the library.  It's exported as a
325  * forward-reference pointer-only declaration; the user can use the pointer with
326  * other APIs to get information out of it.
327  */
328
329 struct libwebsocket {
330         const struct libwebsocket_protocols *protocol;
331         struct libwebsocket_extension *
332                                    active_extensions[LWS_MAX_EXTENSIONS_ACTIVE];
333         void *active_extensions_user[LWS_MAX_EXTENSIONS_ACTIVE];
334         int count_active_extensions;
335
336         enum lws_connection_states state;
337
338         char name_buffer[LWS_MAX_HEADER_NAME_LENGTH];
339         int name_buffer_pos;
340         int current_alloc_len;
341         enum lws_token_indexes parser_state;
342         struct lws_tokens utf8_token[WSI_TOKEN_COUNT];
343         int ietf_spec_revision;
344         char rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + MAX_USER_RX_BUFFER +
345                                                   LWS_SEND_BUFFER_POST_PADDING];
346         int rx_user_buffer_head;
347         enum libwebsocket_write_protocol rx_frame_type;
348         int protocol_index_for_broadcast_proxy;
349         enum pending_timeout pending_timeout;
350         unsigned long pending_timeout_limit;
351
352         int sock;
353
354         enum lws_rx_parse_state lws_rx_parse_state;
355         char extension_data_pending;
356         struct libwebsocket *candidate_children_list;
357         struct libwebsocket *extension_handles;
358
359         /* 04 protocol specific */
360
361         char key_b64[150];
362         unsigned char masking_key_04[20];
363         unsigned char frame_masking_nonce_04[4];
364         unsigned char frame_mask_04[20];
365         unsigned char frame_mask_index;
366         size_t rx_packet_length;
367         unsigned char opcode;
368         unsigned char final;
369         unsigned char rsv;
370
371         int pings_vs_pongs;
372         unsigned char (*xor_mask)(struct libwebsocket *, unsigned char);
373         char all_zero_nonce;
374
375         enum lws_close_status close_reason;
376
377         /* 07 specific */
378         char this_frame_masked;
379
380         /* client support */
381         char initial_handshake_hash_base64[30];
382         enum connection_mode mode;
383         char *c_path;
384         char *c_host;
385         char *c_origin;
386         char *c_protocol;
387         callback_function *c_callback;
388
389         char *c_address;
390         int c_port;
391
392
393 #ifdef LWS_OPENSSL_SUPPORT
394         SSL *ssl;
395         BIO *client_bio;
396         int use_ssl;
397 #endif
398
399         /* http send file */
400         char filepath[PATH_MAX];
401         unsigned long filepos;
402         unsigned long filelen;
403
404         void *user_space;
405 };
406
407 extern int
408 libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c);
409
410 extern int
411 libwebsocket_parse(struct libwebsocket *wsi, unsigned char c);
412
413 extern int
414 libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi,
415                                                 unsigned char *buf, size_t len);
416
417 extern int
418 libwebsocket_read(struct libwebsocket_context *context,
419                                 struct libwebsocket *wsi,
420                                                unsigned char *buf, size_t len);
421
422 extern int
423 lws_b64_selftest(void);
424
425 extern unsigned char
426 xor_no_mask(struct libwebsocket *wsi, unsigned char c);
427
428 extern unsigned char
429 xor_mask_04(struct libwebsocket *wsi, unsigned char c);
430
431 extern unsigned char
432 xor_mask_05(struct libwebsocket *wsi, unsigned char c);
433
434 extern struct libwebsocket *
435 wsi_from_fd(struct libwebsocket_context *context, int fd);
436
437 extern int
438 insert_wsi(struct libwebsocket_context *context, struct libwebsocket *wsi);
439
440 extern int
441 delete_from_fd(struct libwebsocket_context *context, int fd);
442
443 extern void
444 libwebsocket_set_timeout(struct libwebsocket *wsi,
445                                          enum pending_timeout reason, int secs);
446
447 extern int
448 lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len);
449
450
451 extern void
452 libwebsocket_service_timeout_check(struct libwebsocket_context *context,
453                                     struct libwebsocket *wsi, unsigned int sec);
454
455 extern struct libwebsocket *
456 __libwebsocket_client_connect_2(struct libwebsocket_context *context,
457         struct libwebsocket *wsi);
458
459 extern struct libwebsocket *
460 libwebsocket_create_new_server_wsi(struct libwebsocket_context *context);
461
462 extern char *
463 libwebsockets_generate_client_handshake(struct libwebsocket_context *context,
464                 struct libwebsocket *wsi, char *pkt);
465
466 extern int
467 lws_handle_POLLOUT_event(struct libwebsocket_context *context,
468                               struct libwebsocket *wsi, struct pollfd *pollfd);
469
470 extern int
471 lws_any_extension_handled(struct libwebsocket_context *context,
472                           struct libwebsocket *wsi,
473                           enum libwebsocket_extension_callback_reasons r,
474                           void *v, size_t len);
475
476 extern void *
477 lws_get_extension_user_matching_ext(struct libwebsocket *wsi,
478                           struct libwebsocket_extension *ext);
479
480 extern int
481 lws_client_interpret_server_handshake(struct libwebsocket_context *context,
482                 struct libwebsocket *wsi);
483
484 extern int
485 libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c);
486
487 extern int
488 lws_issue_raw_ext_access(struct libwebsocket *wsi,
489                                                 unsigned char *buf, size_t len);
490
491 #ifndef LWS_OPENSSL_SUPPORT
492
493 unsigned char *
494 SHA1(const unsigned char *d, size_t n, unsigned char *md);
495
496 void
497 MD5(const unsigned char *input, int ilen, unsigned char *output);
498
499 #endif