1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker * libwebsockets - small server side websockets and web server implementation
3*1c60b9acSAndroid Build Coastguard Worker *
4*1c60b9acSAndroid Build Coastguard Worker * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker *
6*1c60b9acSAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker *
13*1c60b9acSAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker *
16*1c60b9acSAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker */
24*1c60b9acSAndroid Build Coastguard Worker
25*1c60b9acSAndroid Build Coastguard Worker #if !defined(_GNU_SOURCE)
26*1c60b9acSAndroid Build Coastguard Worker #define _GNU_SOURCE
27*1c60b9acSAndroid Build Coastguard Worker #endif
28*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-core.h"
29*1c60b9acSAndroid Build Coastguard Worker
30*1c60b9acSAndroid Build Coastguard Worker #include <pwd.h>
31*1c60b9acSAndroid Build Coastguard Worker #include <grp.h>
32*1c60b9acSAndroid Build Coastguard Worker
33*1c60b9acSAndroid Build Coastguard Worker #ifdef LWS_WITH_PLUGINS
34*1c60b9acSAndroid Build Coastguard Worker #include <dlfcn.h>
35*1c60b9acSAndroid Build Coastguard Worker #endif
36*1c60b9acSAndroid Build Coastguard Worker #include <dirent.h>
37*1c60b9acSAndroid Build Coastguard Worker
38*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_NETWORK)
39*1c60b9acSAndroid Build Coastguard Worker static void
lws_sul_plat_unix(lws_sorted_usec_list_t * sul)40*1c60b9acSAndroid Build Coastguard Worker lws_sul_plat_unix(lws_sorted_usec_list_t *sul)
41*1c60b9acSAndroid Build Coastguard Worker {
42*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt =
43*1c60b9acSAndroid Build Coastguard Worker lws_container_of(sul, struct lws_context_per_thread, sul_plat);
44*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context = pt->context;
45*1c60b9acSAndroid Build Coastguard Worker int n = 0, m = 0;
46*1c60b9acSAndroid Build Coastguard Worker
47*1c60b9acSAndroid Build Coastguard Worker #if !defined(LWS_NO_DAEMONIZE)
48*1c60b9acSAndroid Build Coastguard Worker /* if our parent went down, don't linger around */
49*1c60b9acSAndroid Build Coastguard Worker if (pt->context->started_with_parent &&
50*1c60b9acSAndroid Build Coastguard Worker kill(pt->context->started_with_parent, 0) < 0)
51*1c60b9acSAndroid Build Coastguard Worker kill(getpid(), SIGTERM);
52*1c60b9acSAndroid Build Coastguard Worker #endif
53*1c60b9acSAndroid Build Coastguard Worker
54*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < context->count_threads; n++)
55*1c60b9acSAndroid Build Coastguard Worker m = m | (int)pt->fds_count;
56*1c60b9acSAndroid Build Coastguard Worker
57*1c60b9acSAndroid Build Coastguard Worker if (context->deprecated && !m) {
58*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: ending deprecated context\n", __func__);
59*1c60b9acSAndroid Build Coastguard Worker kill(getpid(), SIGINT);
60*1c60b9acSAndroid Build Coastguard Worker return;
61*1c60b9acSAndroid Build Coastguard Worker }
62*1c60b9acSAndroid Build Coastguard Worker
63*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
64*1c60b9acSAndroid Build Coastguard Worker lws_context_lock(context, "periodic checks");
65*1c60b9acSAndroid Build Coastguard Worker lws_start_foreach_llp(struct lws_vhost **, pv,
66*1c60b9acSAndroid Build Coastguard Worker context->no_listener_vhost_list) {
67*1c60b9acSAndroid Build Coastguard Worker struct lws_vhost *v = *pv;
68*1c60b9acSAndroid Build Coastguard Worker lwsl_debug("deferred iface: checking if on vh %s\n", (*pv)->name);
69*1c60b9acSAndroid Build Coastguard Worker if (_lws_vhost_init_server(NULL, *pv) == 0) {
70*1c60b9acSAndroid Build Coastguard Worker /* became happy */
71*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("vh %s: became connected\n", v->name);
72*1c60b9acSAndroid Build Coastguard Worker *pv = v->no_listener_vhost_list;
73*1c60b9acSAndroid Build Coastguard Worker v->no_listener_vhost_list = NULL;
74*1c60b9acSAndroid Build Coastguard Worker break;
75*1c60b9acSAndroid Build Coastguard Worker }
76*1c60b9acSAndroid Build Coastguard Worker } lws_end_foreach_llp(pv, no_listener_vhost_list);
77*1c60b9acSAndroid Build Coastguard Worker lws_context_unlock(context);
78*1c60b9acSAndroid Build Coastguard Worker #endif
79*1c60b9acSAndroid Build Coastguard Worker
80*1c60b9acSAndroid Build Coastguard Worker __lws_sul_insert_us(&pt->pt_sul_owner[LWSSULLI_MISS_IF_SUSPENDED],
81*1c60b9acSAndroid Build Coastguard Worker &pt->sul_plat, 30 * LWS_US_PER_SEC);
82*1c60b9acSAndroid Build Coastguard Worker }
83*1c60b9acSAndroid Build Coastguard Worker #endif
84*1c60b9acSAndroid Build Coastguard Worker
85*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_PLUGINS)
86*1c60b9acSAndroid Build Coastguard Worker static int
protocol_plugin_cb(struct lws_plugin * pin,void * each_user)87*1c60b9acSAndroid Build Coastguard Worker protocol_plugin_cb(struct lws_plugin *pin, void *each_user)
88*1c60b9acSAndroid Build Coastguard Worker {
89*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context = (struct lws_context *)each_user;
90*1c60b9acSAndroid Build Coastguard Worker const lws_plugin_protocol_t *plpr =
91*1c60b9acSAndroid Build Coastguard Worker (const lws_plugin_protocol_t *)pin->hdr;
92*1c60b9acSAndroid Build Coastguard Worker
93*1c60b9acSAndroid Build Coastguard Worker context->plugin_protocol_count = (short)(context->plugin_protocol_count +
94*1c60b9acSAndroid Build Coastguard Worker plpr->count_protocols);
95*1c60b9acSAndroid Build Coastguard Worker context->plugin_extension_count = (short)(context->plugin_extension_count +
96*1c60b9acSAndroid Build Coastguard Worker plpr->count_extensions);
97*1c60b9acSAndroid Build Coastguard Worker
98*1c60b9acSAndroid Build Coastguard Worker return 0;
99*1c60b9acSAndroid Build Coastguard Worker }
100*1c60b9acSAndroid Build Coastguard Worker #endif
101*1c60b9acSAndroid Build Coastguard Worker
102*1c60b9acSAndroid Build Coastguard Worker int
lws_plat_init(struct lws_context * context,const struct lws_context_creation_info * info)103*1c60b9acSAndroid Build Coastguard Worker lws_plat_init(struct lws_context *context,
104*1c60b9acSAndroid Build Coastguard Worker const struct lws_context_creation_info *info)
105*1c60b9acSAndroid Build Coastguard Worker {
106*1c60b9acSAndroid Build Coastguard Worker int fd;
107*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_NETWORK)
108*1c60b9acSAndroid Build Coastguard Worker /*
109*1c60b9acSAndroid Build Coastguard Worker * context has the process-global fd lookup array. This can be
110*1c60b9acSAndroid Build Coastguard Worker * done two different ways now; one or the other is done depending on if
111*1c60b9acSAndroid Build Coastguard Worker * info->fd_limit_per_thread was snonzero
112*1c60b9acSAndroid Build Coastguard Worker *
113*1c60b9acSAndroid Build Coastguard Worker * - default: allocate a worst-case lookup array sized for ulimit -n
114*1c60b9acSAndroid Build Coastguard Worker * and use the fd directly as an index into it
115*1c60b9acSAndroid Build Coastguard Worker *
116*1c60b9acSAndroid Build Coastguard Worker * - slow: allocate context->max_fds entries only (which can be
117*1c60b9acSAndroid Build Coastguard Worker * forced at context creation time to be
118*1c60b9acSAndroid Build Coastguard Worker * info->fd_limit_per_thread * the number of threads)
119*1c60b9acSAndroid Build Coastguard Worker * and search the array to lookup fds
120*1c60b9acSAndroid Build Coastguard Worker *
121*1c60b9acSAndroid Build Coastguard Worker * the default way is optimized for server, if you only use one or two
122*1c60b9acSAndroid Build Coastguard Worker * client wsi the slow way may save a lot of memory.
123*1c60b9acSAndroid Build Coastguard Worker *
124*1c60b9acSAndroid Build Coastguard Worker * Both ways allocate an array of struct lws *... one allocates it for
125*1c60b9acSAndroid Build Coastguard Worker * all possible fd indexes the process could produce and uses it as a
126*1c60b9acSAndroid Build Coastguard Worker * map, the other allocates for an amount of wsi the lws context is
127*1c60b9acSAndroid Build Coastguard Worker * expected to use and searches through it to manipulate it.
128*1c60b9acSAndroid Build Coastguard Worker */
129*1c60b9acSAndroid Build Coastguard Worker
130*1c60b9acSAndroid Build Coastguard Worker context->lws_lookup = lws_zalloc(sizeof(struct lws *) *
131*1c60b9acSAndroid Build Coastguard Worker context->max_fds, "lws_lookup");
132*1c60b9acSAndroid Build Coastguard Worker
133*1c60b9acSAndroid Build Coastguard Worker if (!context->lws_lookup) {
134*1c60b9acSAndroid Build Coastguard Worker lwsl_cx_err(context, "OOM on alloc lws_lookup array for %d conn",
135*1c60b9acSAndroid Build Coastguard Worker context->max_fds);
136*1c60b9acSAndroid Build Coastguard Worker return 1;
137*1c60b9acSAndroid Build Coastguard Worker }
138*1c60b9acSAndroid Build Coastguard Worker
139*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_MBEDTLS)
140*1c60b9acSAndroid Build Coastguard Worker {
141*1c60b9acSAndroid Build Coastguard Worker int n;
142*1c60b9acSAndroid Build Coastguard Worker
143*1c60b9acSAndroid Build Coastguard Worker /* initialize platform random through mbedtls */
144*1c60b9acSAndroid Build Coastguard Worker mbedtls_entropy_init(&context->mec);
145*1c60b9acSAndroid Build Coastguard Worker mbedtls_ctr_drbg_init(&context->mcdc);
146*1c60b9acSAndroid Build Coastguard Worker
147*1c60b9acSAndroid Build Coastguard Worker n = mbedtls_ctr_drbg_seed(&context->mcdc, mbedtls_entropy_func,
148*1c60b9acSAndroid Build Coastguard Worker &context->mec, NULL, 0);
149*1c60b9acSAndroid Build Coastguard Worker if (n)
150*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: mbedtls_ctr_drbg_seed() returned 0x%x\n",
151*1c60b9acSAndroid Build Coastguard Worker __func__, n);
152*1c60b9acSAndroid Build Coastguard Worker #if 0
153*1c60b9acSAndroid Build Coastguard Worker else {
154*1c60b9acSAndroid Build Coastguard Worker uint8_t rtest[16];
155*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: started drbg\n", __func__);
156*1c60b9acSAndroid Build Coastguard Worker if (mbedtls_ctr_drbg_random(&context->mcdc, rtest,
157*1c60b9acSAndroid Build Coastguard Worker sizeof(rtest)))
158*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: get random failed\n", __func__);
159*1c60b9acSAndroid Build Coastguard Worker else
160*1c60b9acSAndroid Build Coastguard Worker lwsl_hexdump_notice(rtest, sizeof(rtest));
161*1c60b9acSAndroid Build Coastguard Worker }
162*1c60b9acSAndroid Build Coastguard Worker #endif
163*1c60b9acSAndroid Build Coastguard Worker }
164*1c60b9acSAndroid Build Coastguard Worker #endif
165*1c60b9acSAndroid Build Coastguard Worker
166*1c60b9acSAndroid Build Coastguard Worker lwsl_cx_info(context, " mem: platform fd map: %5lu B",
167*1c60b9acSAndroid Build Coastguard Worker (unsigned long)(sizeof(struct lws *) * context->max_fds));
168*1c60b9acSAndroid Build Coastguard Worker #endif
169*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_FILE_OPS)
170*1c60b9acSAndroid Build Coastguard Worker fd = lws_open(SYSTEM_RANDOM_FILEPATH, O_RDONLY);
171*1c60b9acSAndroid Build Coastguard Worker #else
172*1c60b9acSAndroid Build Coastguard Worker fd = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY);
173*1c60b9acSAndroid Build Coastguard Worker #endif
174*1c60b9acSAndroid Build Coastguard Worker context->fd_random = fd;
175*1c60b9acSAndroid Build Coastguard Worker if (context->fd_random < 0) {
176*1c60b9acSAndroid Build Coastguard Worker lwsl_err("Unable to open random device %s %d, errno %d\n",
177*1c60b9acSAndroid Build Coastguard Worker SYSTEM_RANDOM_FILEPATH, context->fd_random, errno);
178*1c60b9acSAndroid Build Coastguard Worker return 1;
179*1c60b9acSAndroid Build Coastguard Worker }
180*1c60b9acSAndroid Build Coastguard Worker
181*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_PLUGINS)
182*1c60b9acSAndroid Build Coastguard Worker {
183*1c60b9acSAndroid Build Coastguard Worker char *ld_env = getenv("LD_LIBRARY_PATH");
184*1c60b9acSAndroid Build Coastguard Worker
185*1c60b9acSAndroid Build Coastguard Worker if (ld_env) {
186*1c60b9acSAndroid Build Coastguard Worker const char *pp[2] = { ld_env, NULL };
187*1c60b9acSAndroid Build Coastguard Worker
188*1c60b9acSAndroid Build Coastguard Worker lws_plugins_init(&context->plugin_list, pp,
189*1c60b9acSAndroid Build Coastguard Worker "lws_protocol_plugin", NULL,
190*1c60b9acSAndroid Build Coastguard Worker protocol_plugin_cb, context);
191*1c60b9acSAndroid Build Coastguard Worker }
192*1c60b9acSAndroid Build Coastguard Worker
193*1c60b9acSAndroid Build Coastguard Worker if (info->plugin_dirs)
194*1c60b9acSAndroid Build Coastguard Worker lws_plugins_init(&context->plugin_list,
195*1c60b9acSAndroid Build Coastguard Worker info->plugin_dirs,
196*1c60b9acSAndroid Build Coastguard Worker "lws_protocol_plugin", NULL,
197*1c60b9acSAndroid Build Coastguard Worker protocol_plugin_cb, context);
198*1c60b9acSAndroid Build Coastguard Worker }
199*1c60b9acSAndroid Build Coastguard Worker #endif
200*1c60b9acSAndroid Build Coastguard Worker
201*1c60b9acSAndroid Build Coastguard Worker
202*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_NETWORK)
203*1c60b9acSAndroid Build Coastguard Worker /* we only need to do this on pt[0] */
204*1c60b9acSAndroid Build Coastguard Worker
205*1c60b9acSAndroid Build Coastguard Worker context->pt[0].sul_plat.cb = lws_sul_plat_unix;
206*1c60b9acSAndroid Build Coastguard Worker __lws_sul_insert_us(&context->pt[0].pt_sul_owner[LWSSULLI_MISS_IF_SUSPENDED],
207*1c60b9acSAndroid Build Coastguard Worker &context->pt[0].sul_plat, 30 * LWS_US_PER_SEC);
208*1c60b9acSAndroid Build Coastguard Worker #endif
209*1c60b9acSAndroid Build Coastguard Worker
210*1c60b9acSAndroid Build Coastguard Worker return 0;
211*1c60b9acSAndroid Build Coastguard Worker }
212*1c60b9acSAndroid Build Coastguard Worker
213*1c60b9acSAndroid Build Coastguard Worker int
lws_plat_context_early_init(void)214*1c60b9acSAndroid Build Coastguard Worker lws_plat_context_early_init(void)
215*1c60b9acSAndroid Build Coastguard Worker {
216*1c60b9acSAndroid Build Coastguard Worker #if !defined(LWS_AVOID_SIGPIPE_IGN)
217*1c60b9acSAndroid Build Coastguard Worker signal(SIGPIPE, SIG_IGN);
218*1c60b9acSAndroid Build Coastguard Worker #endif
219*1c60b9acSAndroid Build Coastguard Worker
220*1c60b9acSAndroid Build Coastguard Worker return 0;
221*1c60b9acSAndroid Build Coastguard Worker }
222*1c60b9acSAndroid Build Coastguard Worker
223*1c60b9acSAndroid Build Coastguard Worker void
lws_plat_context_early_destroy(struct lws_context * context)224*1c60b9acSAndroid Build Coastguard Worker lws_plat_context_early_destroy(struct lws_context *context)
225*1c60b9acSAndroid Build Coastguard Worker {
226*1c60b9acSAndroid Build Coastguard Worker }
227*1c60b9acSAndroid Build Coastguard Worker
228*1c60b9acSAndroid Build Coastguard Worker void
lws_plat_context_late_destroy(struct lws_context * context)229*1c60b9acSAndroid Build Coastguard Worker lws_plat_context_late_destroy(struct lws_context *context)
230*1c60b9acSAndroid Build Coastguard Worker {
231*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_PLUGINS)
232*1c60b9acSAndroid Build Coastguard Worker if (context->plugin_list)
233*1c60b9acSAndroid Build Coastguard Worker lws_plugins_destroy(&context->plugin_list, NULL, NULL);
234*1c60b9acSAndroid Build Coastguard Worker #endif
235*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_NETWORK)
236*1c60b9acSAndroid Build Coastguard Worker if (context->lws_lookup)
237*1c60b9acSAndroid Build Coastguard Worker lws_free_set_NULL(context->lws_lookup);
238*1c60b9acSAndroid Build Coastguard Worker #endif
239*1c60b9acSAndroid Build Coastguard Worker if (!context->fd_random)
240*1c60b9acSAndroid Build Coastguard Worker lwsl_err("ZERO RANDOM FD\n");
241*1c60b9acSAndroid Build Coastguard Worker if (context->fd_random != LWS_INVALID_FILE)
242*1c60b9acSAndroid Build Coastguard Worker close(context->fd_random);
243*1c60b9acSAndroid Build Coastguard Worker }
244