2574f222af6d8ad1f2ad10e9757521f593ad38c9
[platform/upstream/libwebsockets.git] / lib / context.c
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010-2015 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 "private-libwebsockets.h"
23
24 #ifndef LWS_BUILD_HASH
25 #define LWS_BUILD_HASH "unknown-build-hash"
26 #endif
27
28 static const char *library_version = LWS_LIBRARY_VERSION " " LWS_BUILD_HASH;
29
30 /**
31  * lws_get_library_version: get version and git hash library built from
32  *
33  *      returns a const char * to a string like "1.1 178d78c"
34  *      representing the library version followed by the git head hash it
35  *      was built from
36  */
37 LWS_VISIBLE const char *
38 lws_get_library_version(void)
39 {
40         return library_version;
41 }
42
43 /**
44  * lws_create_context() - Create the websocket handler
45  * @info:       pointer to struct with parameters
46  *
47  *      This function creates the listening socket (if serving) and takes care
48  *      of all initialization in one step.
49  *
50  *      After initialization, it returns a struct lws_context * that
51  *      represents this server.  After calling, user code needs to take care
52  *      of calling lws_service() with the context pointer to get the
53  *      server's sockets serviced.  This must be done in the same process
54  *      context as the initialization call.
55  *
56  *      The protocol callback functions are called for a handful of events
57  *      including http requests coming in, websocket connections becoming
58  *      established, and data arriving; it's also called periodically to allow
59  *      async transmission.
60  *
61  *      HTTP requests are sent always to the FIRST protocol in @protocol, since
62  *      at that time websocket protocol has not been negotiated.  Other
63  *      protocols after the first one never see any HTTP callack activity.
64  *
65  *      The server created is a simple http server by default; part of the
66  *      websocket standard is upgrading this http connection to a websocket one.
67  *
68  *      This allows the same server to provide files like scripts and favicon /
69  *      images or whatever over http and dynamic data over websockets all in
70  *      one place; they're all handled in the user callback.
71  */
72 LWS_VISIBLE struct lws_context *
73 lws_create_context(struct lws_context_creation_info *info)
74 {
75         struct lws_context *context = NULL;
76         struct lws wsi;
77 #ifndef LWS_NO_DAEMONIZE
78         int pid_daemon = get_daemonize_pid();
79 #endif
80         char *p;
81         int n, m;
82
83         lwsl_notice("Initial logging level %d\n", log_level);
84         lwsl_notice("Libwebsockets version: %s\n", library_version);
85 #if LWS_POSIX
86 #ifdef LWS_USE_IPV6
87         if (!(info->options & LWS_SERVER_OPTION_DISABLE_IPV6))
88                 lwsl_notice("IPV6 compiled in and enabled\n");
89         else
90                 lwsl_notice("IPV6 compiled in but disabled\n");
91 #else
92         lwsl_notice("IPV6 not compiled in\n");
93 #endif
94         lws_feature_status_libev(info);
95 #endif
96         lwsl_info(" LWS_DEF_HEADER_LEN    : %u\n", LWS_DEF_HEADER_LEN);
97         lwsl_info(" LWS_MAX_PROTOCOLS     : %u\n", LWS_MAX_PROTOCOLS);
98         lwsl_info(" LWS_MAX_SMP           : %u\n", LWS_MAX_SMP);
99         lwsl_info(" SPEC_LATEST_SUPPORTED : %u\n", SPEC_LATEST_SUPPORTED);
100         lwsl_info(" sizeof (*info)        : %u\n", sizeof(*info));
101 #if LWS_POSIX
102         lwsl_info(" SYSTEM_RANDOM_FILEPATH: '%s'\n", SYSTEM_RANDOM_FILEPATH);
103 #endif
104         if (lws_plat_context_early_init())
105                 return NULL;
106
107         context = lws_zalloc(sizeof(struct lws_context));
108         if (!context) {
109                 lwsl_err("No memory for websocket context\n");
110                 return NULL;
111         }
112 #ifndef LWS_NO_DAEMONIZE
113         if (pid_daemon) {
114                 context->started_with_parent = pid_daemon;
115                 lwsl_notice(" Started with daemon pid %d\n", pid_daemon);
116         }
117 #endif
118         context->max_fds = getdtablesize();
119
120         if (info->count_threads)
121                 context->count_threads = info->count_threads;
122         else
123                 context->count_threads = 1;
124
125         if (context->count_threads > LWS_MAX_SMP)
126                 context->count_threads = LWS_MAX_SMP;
127
128         context->protocols = info->protocols;
129         context->token_limits = info->token_limits;
130         context->listen_port = info->port;
131         context->http_proxy_port = 0;
132         context->http_proxy_address[0] = '\0';
133         context->options = info->options;
134         context->iface = info->iface;
135         context->ka_time = info->ka_time;
136         context->ka_interval = info->ka_interval;
137         context->ka_probes = info->ka_probes;
138         if (info->timeout_secs)
139                 context->timeout_secs = info->timeout_secs;
140         else
141                 context->timeout_secs = AWAITING_TIMEOUT;
142
143         lwsl_info(" default timeout (secs): %u\n", context->timeout_secs);
144
145         if (info->max_http_header_data)
146                 context->max_http_header_data = info->max_http_header_data;
147         else
148                 context->max_http_header_data = LWS_DEF_HEADER_LEN;
149         if (info->max_http_header_pool)
150                 context->max_http_header_pool = info->max_http_header_pool;
151         else
152                 context->max_http_header_pool = LWS_DEF_HEADER_POOL;
153
154         /*
155          * Allocate the per-thread storage for scratchpad buffers,
156          * and header data pool
157          */
158         for (n = 0; n < context->count_threads; n++) {
159                 context->pt[n].serv_buf = lws_zalloc(LWS_MAX_SOCKET_IO_BUF);
160                 if (!context->pt[n].serv_buf) {
161                         lwsl_err("OOM\n");
162                         return NULL;
163                 }
164
165                 context->pt[n].context = context;
166                 context->pt[n].tid = n;
167                 context->pt[n].http_header_data = lws_malloc(context->max_http_header_data *
168                                                        context->max_http_header_pool);
169                 if (!context->pt[n].http_header_data)
170                         goto bail;
171
172                 context->pt[n].ah_pool = lws_zalloc(sizeof(struct allocated_headers) *
173                                               context->max_http_header_pool);
174                 for (m = 0; m < context->max_http_header_pool; m++)
175                         context->pt[n].ah_pool[m].data =
176                                 (char *)context->pt[n].http_header_data +
177                                 (m * context->max_http_header_data);
178                 if (!context->pt[n].ah_pool)
179                         goto bail;
180
181                 lws_pt_mutex_init(&context->pt[n]);
182         }
183
184         if (info->fd_limit_per_thread)
185                 context->fd_limit_per_thread = info->fd_limit_per_thread;
186         else
187                 context->fd_limit_per_thread = context->max_fds /
188                                                context->count_threads;
189
190         lwsl_notice(" Threads: %d each %d fds\n", context->count_threads,
191                     context->fd_limit_per_thread);
192
193         memset(&wsi, 0, sizeof(wsi));
194         wsi.context = context;
195
196         if (!info->ka_interval && info->ka_time > 0) {
197                 lwsl_err("info->ka_interval can't be 0 if ka_time used\n");
198                 return NULL;
199         }
200
201 #ifdef LWS_USE_LIBEV
202         /* (Issue #264) In order to *avoid breaking backwards compatibility*, we
203          * enable libev mediated SIGINT handling with a default handler of
204          * lws_sigint_cb. The handler can be overridden or disabled
205          * by invoking lws_sigint_cfg after creating the context, but
206          * before invoking lws_initloop:
207          */
208         context->use_ev_sigint = 1;
209         context->lws_ev_sigint_cb = &lws_ev_sigint_cb;
210 #endif /* LWS_USE_LIBEV */
211 #ifdef LWS_USE_LIBUV
212         /* (Issue #264) In order to *avoid breaking backwards compatibility*, we
213          * enable libev mediated SIGINT handling with a default handler of
214          * lws_sigint_cb. The handler can be overridden or disabled
215          * by invoking lws_sigint_cfg after creating the context, but
216          * before invoking lws_initloop:
217          */
218         context->use_ev_sigint = 1;
219         context->lws_uv_sigint_cb = &lws_uv_sigint_cb;
220 #endif
221
222         lwsl_info(" mem: context:         %5u bytes (%d ctx + (%d thr x %d))\n",
223                   sizeof(struct lws_context) +
224                   (context->count_threads * LWS_MAX_SOCKET_IO_BUF),
225                   sizeof(struct lws_context),
226                   context->count_threads,
227                   LWS_MAX_SOCKET_IO_BUF);
228
229         lwsl_info(" mem: http hdr rsvd:   %5u bytes (%u thr x (%u + %u) x %u))\n",
230                     (context->max_http_header_data +
231                      sizeof(struct allocated_headers)) *
232                     context->max_http_header_pool * context->count_threads,
233                     context->count_threads,
234                     context->max_http_header_data,
235                     sizeof(struct allocated_headers),
236                     context->max_http_header_pool);
237         n = sizeof(struct lws_pollfd) * context->count_threads *
238             context->fd_limit_per_thread;
239         context->pt[0].fds = lws_zalloc(n);
240         if (context->pt[0].fds == NULL) {
241                 lwsl_err("OOM allocating %d fds\n", context->max_fds);
242                 goto bail;
243         }
244         lwsl_info(" mem: pollfd map:      %5u\n", n);
245
246 #if LWS_MAX_SMP > 1
247         /* each thread serves his own chunk of fds */
248         for (n = 1; n < (int)info->count_threads; n++)
249                 context->pt[n].fds = context->pt[n - 1].fds +
250                                      context->fd_limit_per_thread;
251 #endif
252
253         if (lws_plat_init(context, info))
254                 goto bail;
255
256         lws_context_init_extensions(info, context);
257
258         context->user_space = info->user;
259
260         lwsl_notice(" mem: per-conn:        %5u bytes + protocol rx buf\n",
261                     sizeof(struct lws));
262
263         strcpy(context->canonical_hostname, "unknown");
264         lws_server_get_canonical_hostname(context, info);
265
266         /* either use proxy from info, or try get it from env var */
267
268         if (info->http_proxy_address) {
269                 /* override for backwards compatibility */
270                 if (info->http_proxy_port)
271                         context->http_proxy_port = info->http_proxy_port;
272                 lws_set_proxy(context, info->http_proxy_address);
273         } else {
274 #ifdef LWS_HAVE_GETENV
275                 p = getenv("http_proxy");
276                 if (p)
277                         lws_set_proxy(context, p);
278 #endif
279         }
280
281         if (lws_context_init_server_ssl(info, context))
282                 goto bail;
283
284         if (lws_context_init_client_ssl(info, context))
285                 goto bail;
286
287         if (lws_context_init_server(info, context))
288                 goto bail;
289
290         /*
291          * drop any root privs for this process
292          * to listen on port < 1023 we would have needed root, but now we are
293          * listening, we don't want the power for anything else
294          */
295         lws_plat_drop_app_privileges(info);
296
297         /* initialize supported protocols */
298
299         for (context->count_protocols = 0;
300              info->protocols[context->count_protocols].callback;
301              context->count_protocols++)
302                 /*
303                  * inform all the protocols that they are doing their one-time
304                  * initialization if they want to.
305                  *
306                  * NOTE the wsi is all zeros except for the context pointer
307                  * so lws_get_context(wsi) can work in the callback.
308                  */
309                 info->protocols[context->count_protocols].callback(&wsi,
310                                 LWS_CALLBACK_PROTOCOL_INIT, NULL, NULL, 0);
311
312         /*
313          * give all extensions a chance to create any per-context
314          * allocations they need
315          */
316         if (info->port != CONTEXT_PORT_NO_LISTEN) {
317                 if (lws_ext_cb_all_exts(context, NULL,
318                         LWS_EXT_CB_SERVER_CONTEXT_CONSTRUCT, NULL, 0) < 0)
319                         goto bail;
320         } else
321                 if (lws_ext_cb_all_exts(context, NULL,
322                         LWS_EXT_CB_CLIENT_CONTEXT_CONSTRUCT, NULL, 0) < 0)
323                         goto bail;
324
325         return context;
326
327 bail:
328         lws_context_destroy(context);
329         return NULL;
330 }
331
332 /**
333  * lws_context_destroy() - Destroy the websocket context
334  * @context:    Websocket context
335  *
336  *      This function closes any active connections and then frees the
337  *      context.  After calling this, any further use of the context is
338  *      undefined.
339  */
340 LWS_VISIBLE void
341 lws_context_destroy(struct lws_context *context)
342 {
343         const struct lws_protocols *protocol = NULL;
344         struct lws_context_per_thread *pt;
345         struct lws wsi;
346         int n, m;
347
348         lwsl_notice("%s\n", __func__);
349
350         if (!context)
351                 return;
352
353         m = context->count_threads;
354         context->being_destroyed = 1;
355
356         memset(&wsi, 0, sizeof(wsi));
357         wsi.context = context;
358
359 #ifdef LWS_LATENCY
360         if (context->worst_latency_info[0])
361                 lwsl_notice("Worst latency: %s\n", context->worst_latency_info);
362 #endif
363
364         while (m--) {
365                 pt = &context->pt[m];
366
367                 for (n = 0; (unsigned int)n < context->pt[m].fds_count; n++) {
368                         struct lws *wsi = wsi_from_fd(context, pt->fds[n].fd);
369                         if (!wsi)
370                                 continue;
371
372                         lws_close_free_wsi(wsi,
373                                 LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY
374                                 /* no protocol close */);
375                         n--;
376                 }
377         }
378         /*
379          * give all extensions a chance to clean up any per-context
380          * allocations they might have made
381          */
382
383         n = lws_ext_cb_all_exts(context, NULL,
384                                 LWS_EXT_CB_SERVER_CONTEXT_DESTRUCT, NULL, 0);
385
386         n = lws_ext_cb_all_exts(context, NULL,
387                                 LWS_EXT_CB_CLIENT_CONTEXT_DESTRUCT, NULL, 0);
388
389         /*
390          * inform all the protocols that they are done and will have no more
391          * callbacks
392          */
393         protocol = context->protocols;
394         if (protocol)
395                 while (protocol->callback) {
396                         protocol->callback(&wsi, LWS_CALLBACK_PROTOCOL_DESTROY,
397                                            NULL, NULL, 0);
398                         protocol++;
399                 }
400
401         for (n = 0; n < context->count_threads; n++) {
402                 pt = &context->pt[n];
403
404                 lws_libev_destroyloop(context, n);
405                 lws_libuv_destroyloop(context, n);
406
407                 lws_free_set_NULL(context->pt[n].serv_buf);
408                 if (pt->ah_pool)
409                         lws_free(pt->ah_pool);
410                 if (pt->http_header_data)
411                         lws_free(pt->http_header_data);
412         }
413         lws_plat_context_early_destroy(context);
414         lws_ssl_context_destroy(context);
415         if (context->pt[0].fds)
416                 lws_free_set_NULL(context->pt[0].fds);
417
418         lws_plat_context_late_destroy(context);
419
420         lws_free(context);
421 }