e706bf5bdbce050ee9958e796579880798128894
[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 #include <netdb.h>
32 #include <stdarg.h>
33
34 #include <sys/stat.h>
35
36 #ifdef WIN32
37
38 #include <time.h >
39 #include <winsock2.h>
40 #include <ws2ipdef.h>
41 #include <windows.h>
42
43 #else
44
45 #include <sys/types.h>
46 #include <sys/socket.h>
47 #ifndef LWS_NO_FORK
48 #include <sys/prctl.h>
49 #endif
50 #include <netinet/in.h>
51 #include <netinet/tcp.h>
52 #include <arpa/inet.h>
53
54 #include <poll.h>
55 #include <sys/mman.h>
56 #include <sys/time.h>
57
58 #endif
59
60 #ifdef LWS_OPENSSL_SUPPORT
61 #include <openssl/ssl.h>
62 #include <openssl/evp.h>
63 #include <openssl/err.h>
64 #include <openssl/md5.h>
65 #include <openssl/sha.h>
66 #endif
67
68
69 #include "libwebsockets.h"
70
71 #if 0
72 #define DEBUG
73 #endif
74
75 #ifdef DEBUG
76 #ifdef WIN32
77 static
78 #else
79 static inline
80 #endif
81 void debug(const char *format, ...)
82 {
83         va_list ap;
84         va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap);
85 }
86 #else
87 #ifdef WIN32
88 static
89 #else
90 static inline
91 #endif
92 void debug(const char *format, ...)
93 {
94 }
95 #endif
96
97
98 /*
99  * Mac OSX as well as iOS do not define the MSG_NOSIGNAL flag,
100  * but happily have something equivalent in the SO_NOSIGPIPE flag.
101  */
102 #ifdef __APPLE__
103 #define MSG_NOSIGNAL SO_NOSIGPIPE 
104 #endif
105
106
107 #define FD_HASHTABLE_MODULUS 32
108 #define MAX_CLIENTS 100
109 #define LWS_MAX_HEADER_NAME_LENGTH 64
110 #define LWS_MAX_HEADER_LEN 4096
111 #define LWS_INITIAL_HDR_ALLOC 256
112 #define LWS_ADDITIONAL_HDR_ALLOC 64
113 #define MAX_USER_RX_BUFFER 4096
114 #define MAX_BROADCAST_PAYLOAD 2048
115 #define LWS_MAX_PROTOCOLS 10
116 #define LWS_MAX_EXTENSIONS_ACTIVE 10
117 #define SPEC_LATEST_SUPPORTED 7
118
119 #define MAX_WEBSOCKET_04_KEY_LEN 128
120 #define SYSTEM_RANDOM_FILEPATH "/dev/urandom"
121
122 enum lws_websocket_opcodes_04 {
123         LWS_WS_OPCODE_04__CONTINUATION = 0,
124         LWS_WS_OPCODE_04__CLOSE = 1,
125         LWS_WS_OPCODE_04__PING = 2,
126         LWS_WS_OPCODE_04__PONG = 3,
127         LWS_WS_OPCODE_04__TEXT_FRAME = 4,
128         LWS_WS_OPCODE_04__BINARY_FRAME = 5,
129
130         LWS_WS_OPCODE_04__RESERVED_6 = 6,
131         LWS_WS_OPCODE_04__RESERVED_7 = 7,
132         LWS_WS_OPCODE_04__RESERVED_8 = 8,
133         LWS_WS_OPCODE_04__RESERVED_9 = 9,
134         LWS_WS_OPCODE_04__RESERVED_A = 0xa,
135         LWS_WS_OPCODE_04__RESERVED_B = 0xb,
136         LWS_WS_OPCODE_04__RESERVED_C = 0xc,
137         LWS_WS_OPCODE_04__RESERVED_D = 0xd,
138         LWS_WS_OPCODE_04__RESERVED_E = 0xe,
139         LWS_WS_OPCODE_04__RESERVED_F = 0xf,
140 };
141
142 enum lws_websocket_opcodes_07 {
143         LWS_WS_OPCODE_07__CONTINUATION = 0,
144         LWS_WS_OPCODE_07__TEXT_FRAME = 1,
145         LWS_WS_OPCODE_07__BINARY_FRAME = 2,
146
147         LWS_WS_OPCODE_07__NOSPEC__MUX = 7,
148
149         /* control extensions 8+ */
150
151         LWS_WS_OPCODE_07__CLOSE = 8,
152         LWS_WS_OPCODE_07__PING = 9,
153         LWS_WS_OPCODE_07__PONG = 0xa,
154 };
155
156
157 enum lws_connection_states {
158         WSI_STATE_HTTP,
159         WSI_STATE_HTTP_HEADERS,
160         WSI_STATE_DEAD_SOCKET,
161         WSI_STATE_ESTABLISHED,
162         WSI_STATE_CLIENT_UNCONNECTED,
163         WSI_STATE_RETURNED_CLOSE_ALREADY,
164         WSI_STATE_AWAITING_CLOSE_ACK,
165 };
166
167 enum lws_rx_parse_state {
168         LWS_RXPS_NEW,
169
170         LWS_RXPS_SEEN_76_FF,
171         LWS_RXPS_PULLING_76_LENGTH,
172         LWS_RXPS_EAT_UNTIL_76_FF,
173
174         LWS_RXPS_04_MASK_NONCE_1,
175         LWS_RXPS_04_MASK_NONCE_2,
176         LWS_RXPS_04_MASK_NONCE_3,
177
178         LWS_RXPS_04_FRAME_HDR_1,
179         LWS_RXPS_04_FRAME_HDR_LEN,
180         LWS_RXPS_04_FRAME_HDR_LEN16_2,
181         LWS_RXPS_04_FRAME_HDR_LEN16_1,
182         LWS_RXPS_04_FRAME_HDR_LEN64_8,
183         LWS_RXPS_04_FRAME_HDR_LEN64_7,
184         LWS_RXPS_04_FRAME_HDR_LEN64_6,
185         LWS_RXPS_04_FRAME_HDR_LEN64_5,
186         LWS_RXPS_04_FRAME_HDR_LEN64_4,
187         LWS_RXPS_04_FRAME_HDR_LEN64_3,
188         LWS_RXPS_04_FRAME_HDR_LEN64_2,
189         LWS_RXPS_04_FRAME_HDR_LEN64_1,
190
191         LWS_RXPS_07_COLLECT_FRAME_KEY_1,
192         LWS_RXPS_07_COLLECT_FRAME_KEY_2,
193         LWS_RXPS_07_COLLECT_FRAME_KEY_3,
194         LWS_RXPS_07_COLLECT_FRAME_KEY_4,
195
196         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED
197 };
198
199
200 enum connection_mode {
201         LWS_CONNMODE_WS_SERVING,
202         LWS_CONNMODE_WS_CLIENT,
203
204         /* transient modes */
205         LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY,
206         LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE,
207         LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY,
208         LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT,
209         LWS_CONNMODE_WS_CLIENT_PENDING_CANDIDATE_CHILD,
210
211         /* special internal types */
212         LWS_CONNMODE_SERVER_LISTENER,
213         LWS_CONNMODE_BROADCAST_PROXY_LISTENER,
214         LWS_CONNMODE_BROADCAST_PROXY
215 };
216
217
218 #define LWS_FD_HASH(fd) ((fd ^ (fd >> 8) ^ (fd >> 16)) % FD_HASHTABLE_MODULUS)
219
220 struct libwebsocket_fd_hashtable {
221         struct libwebsocket *wsi[MAX_CLIENTS + 1];
222         int length;
223 };
224
225 struct libwebsocket_protocols;
226
227 struct libwebsocket_context {
228         struct libwebsocket_fd_hashtable fd_hashtable[FD_HASHTABLE_MODULUS];
229         struct pollfd fds[MAX_CLIENTS * FD_HASHTABLE_MODULUS + 1];
230         int fds_count;
231         int listen_port;
232         char http_proxy_address[256];
233         char canonical_hostname[1024];
234         unsigned int http_proxy_port;
235         unsigned int options;
236         unsigned long last_timeout_check_s;
237
238         int fd_random;
239         
240 #ifdef LWS_OPENSSL_SUPPORT
241         int use_ssl;
242         SSL_CTX *ssl_ctx;
243         SSL_CTX *ssl_client_ctx;
244 #endif
245         struct libwebsocket_protocols *protocols;
246         int count_protocols;
247         struct libwebsocket_extension *extensions;
248 };
249
250
251 enum pending_timeout {
252         NO_PENDING_TIMEOUT = 0,
253         PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE,
254         PENDING_TIMEOUT_ESTABLISH_WITH_SERVER,
255         PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE,
256         PENDING_TIMEOUT_AWAITING_PING,
257         PENDING_TIMEOUT_CLOSE_ACK,
258         PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE,
259 };
260
261
262 /*
263  * This is totally opaque to code using the library.  It's exported as a
264  * forward-reference pointer-only declaration; the user can use the pointer with
265  * other APIs to get information out of it.
266  */
267
268 struct libwebsocket {
269         const struct libwebsocket_protocols *protocol;
270         struct libwebsocket_extension *
271                                    active_extensions[LWS_MAX_EXTENSIONS_ACTIVE];
272         void * active_extensions_user[LWS_MAX_EXTENSIONS_ACTIVE];
273         int count_active_extensions;
274
275         enum lws_connection_states state;
276
277         char name_buffer[LWS_MAX_HEADER_NAME_LENGTH];
278         int name_buffer_pos;
279         int current_alloc_len;
280         enum lws_token_indexes parser_state;
281         struct lws_tokens utf8_token[WSI_TOKEN_COUNT];
282         int ietf_spec_revision;
283         char rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + MAX_USER_RX_BUFFER +
284                                                   LWS_SEND_BUFFER_POST_PADDING];
285         int rx_user_buffer_head;
286         enum libwebsocket_write_protocol rx_frame_type;
287         int protocol_index_for_broadcast_proxy;
288         enum pending_timeout pending_timeout;
289         unsigned long pending_timeout_limit;
290
291         int sock;
292
293         enum lws_rx_parse_state lws_rx_parse_state;
294         char extension_data_pending;
295         struct libwebsocket *candidate_children_list;
296         struct libwebsocket *extension_handles;
297
298         /* 04 protocol specific */
299
300         char key_b64[150];
301         unsigned char masking_key_04[20];
302         unsigned char frame_masking_nonce_04[4];
303         unsigned char frame_mask_04[20];
304         unsigned char frame_mask_index;
305         size_t rx_packet_length;
306         unsigned char opcode;
307         unsigned char final;
308
309         int pings_vs_pongs;
310         unsigned char (*xor_mask)(struct libwebsocket *, unsigned char);
311         char all_zero_nonce;
312
313         enum lws_close_status close_reason;
314
315         /* 07 specific */
316         char this_frame_masked;
317
318         /* client support */
319         char initial_handshake_hash_base64[30];
320         enum connection_mode mode;
321         char *c_path;
322         char *c_host;
323         char *c_origin;
324         char *c_protocol;
325
326         char *c_address;
327         int c_port;
328
329
330 #ifdef LWS_OPENSSL_SUPPORT
331         SSL *ssl;
332         BIO *client_bio;
333         int use_ssl;
334 #endif
335
336         void *user_space;
337 };
338
339 extern int
340 libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c);
341
342 extern int
343 libwebsocket_parse(struct libwebsocket *wsi, unsigned char c);
344
345 extern int
346 libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi,
347                                                 unsigned char *buf, size_t len);
348
349 extern int
350 libwebsocket_read(struct libwebsocket_context *context, struct libwebsocket *wsi,
351                                                unsigned char * buf, size_t len);
352
353 extern int
354 lws_b64_selftest(void);
355
356 extern unsigned char
357 xor_no_mask(struct libwebsocket *wsi, unsigned char c);
358
359 extern unsigned char
360 xor_mask_04(struct libwebsocket *wsi, unsigned char c);
361
362 extern unsigned char
363 xor_mask_05(struct libwebsocket *wsi, unsigned char c);
364
365 extern struct libwebsocket *
366 wsi_from_fd(struct libwebsocket_context *context, int fd);
367
368 extern int
369 insert_wsi(struct libwebsocket_context *context, struct libwebsocket *wsi);
370
371 extern int
372 delete_from_fd(struct libwebsocket_context *context, int fd);
373
374 extern void
375 libwebsocket_set_timeout(struct libwebsocket *wsi,
376                                          enum pending_timeout reason, int secs);
377
378 extern int
379 lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len);
380
381
382 extern void
383 libwebsocket_service_timeout_check(struct libwebsocket_context *context,
384                                     struct libwebsocket *wsi, unsigned int sec);
385
386 extern struct libwebsocket * __libwebsocket_client_connect_2(
387         struct libwebsocket_context *context,
388         struct libwebsocket *wsi);
389
390 extern struct libwebsocket *
391 libwebsocket_create_new_server_wsi(struct libwebsocket_context *context);
392
393 extern char *
394 libwebsockets_generate_client_handshake(struct libwebsocket_context *context,
395                 struct libwebsocket *wsi, char *pkt);
396
397 extern int
398 lws_handle_POLLOUT_event(struct libwebsocket_context *context,
399                               struct libwebsocket *wsi, struct pollfd *pollfd);
400
401 extern int
402 lws_any_extension_handled(struct libwebsocket_context *context,
403                                                        struct libwebsocket *wsi,
404                                                        enum libwebsocket_extension_callback_reasons r,
405                                                        void *v, size_t len);
406
407 extern void *
408 lws_get_extension_user_matching_ext(struct libwebsocket *wsi,
409                                                         struct libwebsocket_extension * ext);
410
411 extern int
412 lws_client_interpret_server_handshake(struct libwebsocket_context *context,
413                 struct libwebsocket *wsi);
414
415 extern int
416 libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c);
417
418 extern int
419 lws_issue_raw_ext_access(struct libwebsocket *wsi,
420                                                 unsigned char *buf, size_t len);
421
422 #ifndef LWS_OPENSSL_SUPPORT
423
424 unsigned char *
425 SHA1(const unsigned char *d, size_t n, unsigned char *md);
426
427 void
428 MD5(const unsigned char *input, int ilen, unsigned char *output);
429
430 #endif