f71f01da5fa34d7707b0fd26f7521eaa798016da
[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 #if !defined(LWS_WITH_NO_LOGS)
44 static const char * const mount_protocols[] = {
45         "http://",
46         "https://",
47         "file://",
48         "cgi://",
49         ">http://",
50         ">https://",
51         "callback://"
52 };
53 #endif
54
55 LWS_VISIBLE void *
56 lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost, const struct lws_protocols *prot,
57                             int size)
58 {
59         int n = 0;
60
61         /* allocate the vh priv array only on demand */
62         if (!vhost->protocol_vh_privs) {
63                 vhost->protocol_vh_privs = (void **)lws_zalloc(
64                                 vhost->count_protocols * sizeof(void *));
65                 if (!vhost->protocol_vh_privs)
66                         return NULL;
67         }
68
69         while (n < vhost->count_protocols && &vhost->protocols[n] != prot)
70                 n++;
71
72         if (n == vhost->count_protocols) {
73                 n = 0;
74                 while (n < vhost->count_protocols &&
75                        strcmp(vhost->protocols[n].name, prot->name))
76                         n++;
77
78                 if (n == vhost->count_protocols)
79                         return NULL;
80         }
81
82         vhost->protocol_vh_privs[n] = lws_zalloc(size);
83         return vhost->protocol_vh_privs[n];
84 }
85
86 LWS_VISIBLE void *
87 lws_protocol_vh_priv_get(struct lws_vhost *vhost, const struct lws_protocols *prot)
88 {
89         int n = 0;
90
91         if (!vhost->protocol_vh_privs)
92                 return NULL;
93
94         while (n < vhost->count_protocols && &vhost->protocols[n] != prot)
95                 n++;
96
97         if (n == vhost->count_protocols) {
98                 n = 0;
99                 while (n < vhost->count_protocols &&
100                        strcmp(vhost->protocols[n].name, prot->name))
101                         n++;
102
103                 if (n == vhost->count_protocols) {
104                         lwsl_err("%s: unknown protocol %p\n", __func__, prot);
105                         return NULL;
106                 }
107         }
108
109         return vhost->protocol_vh_privs[n];
110 }
111
112 static const struct lws_protocol_vhost_options *
113 lws_vhost_protocol_options(struct lws_vhost *vh, const char *name)
114 {
115         const struct lws_protocol_vhost_options *pvo = vh->pvo;
116
117         while (pvo) {
118                 // lwsl_notice("%s: '%s' '%s'\n", __func__, pvo->name, name);
119                 if (!strcmp(pvo->name, name))
120                         return pvo;
121                 pvo = pvo->next;
122         }
123
124         return NULL;
125 }
126
127 /*
128  * inform every vhost that hasn't already done it, that
129  * his protocols are initializing
130  */
131 LWS_VISIBLE int
132 lws_protocol_init(struct lws_context *context)
133 {
134         struct lws_vhost *vh = context->vhost_list;
135         const struct lws_protocol_vhost_options *pvo, *pvo1;
136         struct lws wsi;
137         int n;
138
139         memset(&wsi, 0, sizeof(wsi));
140         wsi.context = context;
141
142         lwsl_info("%s\n", __func__);
143
144         while (vh) {
145                 wsi.vhost = vh;
146
147                 /* only do the protocol init once for a given vhost */
148                 if (vh->created_vhost_protocols)
149                         goto next;
150
151                 /* initialize supported protocols on this vhost */
152
153                 for (n = 0; n < vh->count_protocols; n++) {
154                         wsi.protocol = &vh->protocols[n];
155                         if (!vh->protocols[n].name)
156                                 continue;
157                         pvo = lws_vhost_protocol_options(vh,
158                                                          vh->protocols[n].name);
159                         if (pvo) {
160                                 /*
161                                  * linked list of options specific to
162                                  * vh + protocol
163                                  */
164                                 pvo1 = pvo;
165                                 pvo = pvo1->options;
166
167                                 while (pvo) {
168                                         lwsl_notice("    vh %s prot %s opt %s\n",
169                                                         vh->name,
170                                                         vh->protocols[n].name,
171                                                         pvo->name);
172
173                                         if (!strcmp(pvo->name, "default")) {
174                                                 lwsl_notice("Setting default "
175                                                    "protocol for vh %s to %s\n",
176                                                    vh->name,
177                                                    vh->protocols[n].name);
178                                                 vh->default_protocol_index = n;
179                                         }
180                                         if (!strcmp(pvo->name, "raw")) {
181                                                 lwsl_notice("Setting raw "
182                                                    "protocol for vh %s to %s\n",
183                                                    vh->name,
184                                                    vh->protocols[n].name);
185                                                 vh->raw_protocol_index = n;
186                                         }
187                                         pvo = pvo->next;
188                                 }
189
190                                 pvo = pvo1->options;
191                         }
192
193                         /*
194                          * inform all the protocols that they are doing their one-time
195                          * initialization if they want to.
196                          *
197                          * NOTE the wsi is all zeros except for the context, vh and
198                          * protocol ptrs so lws_get_context(wsi) etc can work
199                          */
200                         if (vh->protocols[n].callback(&wsi,
201                                 LWS_CALLBACK_PROTOCOL_INIT, NULL,
202                                 (void *)pvo, 0))
203                                 return 1;
204                 }
205
206                 vh->created_vhost_protocols = 1;
207 next:
208                 vh = vh->vhost_next;
209         }
210
211         if (!context->protocol_init_done)
212                 lws_finalize_startup(context);
213
214         context->protocol_init_done = 1;
215
216         return 0;
217 }
218
219 LWS_VISIBLE int
220 lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
221                     void *user, void *in, size_t len)
222 {
223 #ifdef LWS_WITH_CGI
224         struct lws_cgi_args *args;
225         char buf[128];
226         int n;
227 #endif
228
229         switch (reason) {
230         case LWS_CALLBACK_HTTP:
231 #ifndef LWS_NO_SERVER
232                 if (lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL))
233                         return -1;
234
235                 if (lws_http_transaction_completed(wsi))
236 #endif
237                         return -1;
238                 break;
239
240         case LWS_CALLBACK_HTTP_WRITEABLE:
241 #ifdef LWS_WITH_CGI
242                 if (wsi->reason_bf & 1) {
243                         if (lws_cgi_write_split_stdout_headers(wsi) < 0)
244                                 return -1;
245
246                         if (wsi->reason_bf & 8)
247                                 wsi->reason_bf &= ~8;
248                         else
249                                 wsi->reason_bf &= ~1;
250                         break;
251                 }
252 #endif
253
254                 break;
255
256 #ifdef LWS_WITH_CGI
257         /* CGI IO events (POLLIN/OUT) appear here, our default policy is:
258          *
259          *  - POST data goes on subprocess stdin
260          *  - subprocess stdout goes on http via writeable callback
261          *  - subprocess stderr goes to the logs
262          */
263         case LWS_CALLBACK_CGI:
264                 args = (struct lws_cgi_args *)in;
265                 switch (args->ch) { /* which of stdin/out/err ? */
266                 case LWS_STDIN:
267                         /* TBD stdin rx flow control */
268                         break;
269                 case LWS_STDOUT:
270                         wsi->reason_bf |= 1;
271                         /* when writing to MASTER would not block */
272                         lws_callback_on_writable(wsi);
273                         break;
274                 case LWS_STDERR:
275                         n = read(lws_get_socket_fd(args->stdwsi[LWS_STDERR]),
276                                                    buf, sizeof(buf) - 2);
277                         if (n > 0) {
278                                 if (buf[n - 1] != '\n')
279                                         buf[n++] = '\n';
280                                 buf[n] = '\0';
281                                 lwsl_notice("CGI-stderr: %s\n", buf);
282                         }
283                         break;
284                 }
285                 break;
286
287         case LWS_CALLBACK_CGI_TERMINATED:
288                 return -1;
289
290         case LWS_CALLBACK_CGI_STDIN_DATA:  /* POST body for stdin */
291                 args = (struct lws_cgi_args *)in;
292                 args->data[args->len] = '\0';
293                 n = write(lws_get_socket_fd(args->stdwsi[LWS_STDIN]),
294                           args->data, args->len);
295                 if (n < args->len)
296                         lwsl_notice("LWS_CALLBACK_CGI_STDIN_DATA: "
297                                     "sent %d only %d went", n, args->len);
298                 return n;
299 #endif
300         default:
301                 break;
302         }
303
304         return 0;
305 }
306
307 /* list of supported protocols and callbacks */
308
309 static const struct lws_protocols protocols_dummy[] = {
310         /* first protocol must always be HTTP handler */
311
312         {
313                 "http-only",            /* name */
314                 lws_callback_http_dummy,                /* callback */
315                 0,      /* per_session_data_size */
316                 0,                      /* max frame size / rx buffer */
317                 0, NULL, 0
318         },
319         /*
320          * the other protocols are provided by lws plugins
321          */
322         { NULL, NULL, 0, 0, 0, NULL, 0} /* terminator */
323 };
324
325 #ifdef LWS_PLAT_OPTEE
326 #undef LWS_HAVE_GETENV
327 #endif
328
329 LWS_VISIBLE struct lws_vhost *
330 lws_create_vhost(struct lws_context *context,
331                  struct lws_context_creation_info *info)
332 {
333         struct lws_vhost *vh = lws_zalloc(sizeof(*vh)),
334                          **vh1 = &context->vhost_list;
335         const struct lws_http_mount *mounts;
336         const struct lws_protocol_vhost_options *pvo;
337 #ifdef LWS_WITH_PLUGINS
338         struct lws_plugin *plugin = context->plugin_list;
339 #endif
340         struct lws_protocols *lwsp;
341         int m, f = !info->pvo;
342 #ifdef LWS_HAVE_GETENV
343         char *p;
344 #endif
345         int n;
346
347         if (!vh)
348                 return NULL;
349
350         if (!info->protocols)
351                 info->protocols = &protocols_dummy[0];
352
353         vh->context = context;
354         if (!info->vhost_name)
355                 vh->name = "default";
356         else
357                 vh->name = info->vhost_name;
358
359         vh->iface = info->iface;
360 #if !defined(LWS_WITH_ESP8266) && !defined(LWS_WITH_ESP32) && !defined(OPTEE_TA) && !defined(WIN32)
361         vh->bind_iface = info->bind_iface;
362 #endif
363
364         for (vh->count_protocols = 0;
365              info->protocols[vh->count_protocols].callback;
366              vh->count_protocols++)
367                 ;
368
369         vh->options = info->options;
370         vh->pvo = info->pvo;
371         vh->headers = info->headers;
372         if (info->keepalive_timeout)
373                 vh->keepalive_timeout = info->keepalive_timeout;
374         else
375                 vh->keepalive_timeout = 5;
376
377         /*
378          * give the vhost a unified list of protocols including the
379          * ones that came from plugins
380          */
381         lwsp = lws_zalloc(sizeof(struct lws_protocols) *
382                                    (vh->count_protocols +
383                                    context->plugin_protocol_count + 1));
384         if (!lwsp) {
385                 lwsl_err("OOM\n");
386                 return NULL;
387         }
388
389         m = vh->count_protocols;
390         memcpy(lwsp, info->protocols, sizeof(struct lws_protocols) * m);
391
392         /* for compatibility, all protocols enabled on vhost if only
393          * the default vhost exists.  Otherwise only vhosts who ask
394          * for a protocol get it enabled.
395          */
396
397         if (info->options & LWS_SERVER_OPTION_EXPLICIT_VHOSTS)
398                 f = 0;
399         (void)f;
400 #ifdef LWS_WITH_PLUGINS
401         if (plugin) {
402
403                 while (plugin) {
404                         for (n = 0; n < plugin->caps.count_protocols; n++) {
405                                 /*
406                                  * for compatibility's sake, no pvo implies
407                                  * allow all protocols
408                                  */
409                                 if (f || lws_vhost_protocol_options(vh,
410                                     plugin->caps.protocols[n].name)) {
411                                         memcpy(&lwsp[m],
412                                                &plugin->caps.protocols[n],
413                                                sizeof(struct lws_protocols));
414                                         m++;
415                                         vh->count_protocols++;
416                                 }
417                         }
418                         plugin = plugin->list;
419                 }
420         }
421 #endif
422
423         if (
424 #ifdef LWS_WITH_PLUGINS
425             (context->plugin_list) ||
426 #endif
427             info->options & LWS_SERVER_OPTION_EXPLICIT_VHOSTS)
428                 vh->protocols = lwsp;
429         else {
430                 vh->protocols = info->protocols;
431                 free(lwsp);
432         }
433
434         vh->same_vh_protocol_list = (struct lws **)
435                         lws_zalloc(sizeof(struct lws *) * vh->count_protocols);
436
437         vh->mount_list = info->mounts;
438
439 #ifdef LWS_USE_UNIX_SOCK
440         if (LWS_UNIX_SOCK_ENABLED(context)) {
441                 lwsl_notice("Creating Vhost '%s' path \"%s\", %d protocols\n",
442                                 vh->name, info->iface, vh->count_protocols);
443         } else
444 #endif
445         lwsl_notice("Creating Vhost '%s' port %d, %d protocols, IPv6 %s\n",
446                         vh->name, info->port, vh->count_protocols, LWS_IPV6_ENABLED(vh) ? "on" : "off");
447
448         mounts = info->mounts;
449         while (mounts) {
450                 lwsl_notice("   mounting %s%s to %s\n",
451                                 mount_protocols[mounts->origin_protocol],
452                                 mounts->origin, mounts->mountpoint);
453
454                 /* convert interpreter protocol names to pointers */
455                 pvo = mounts->interpret;
456                 while (pvo) {
457                         for (n = 0; n < vh->count_protocols; n++)
458                                 if (!strcmp(pvo->value, vh->protocols[n].name)) {
459                                         ((struct lws_protocol_vhost_options *)pvo)->value =
460                                                         (const char *)(long)n;
461                                         break;
462                                 }
463                         if (n == vh->count_protocols)
464                                 lwsl_err("ignoring unknown interpret protocol %s\n", pvo->value);
465                         pvo = pvo->next;
466                 }
467
468                 mounts = mounts->mount_next;
469         }
470
471 #ifndef LWS_NO_EXTENSIONS
472 #ifdef LWS_WITH_PLUGINS
473         if (context->plugin_extension_count) {
474
475                 m = 0;
476                 while (info->extensions && info->extensions[m].callback)
477                         m++;
478
479                 /*
480                  * give the vhost a unified list of extensions including the
481                  * ones that came from plugins
482                  */
483                 vh->extensions = lws_zalloc(sizeof(struct lws_extension) *
484                                            (m +
485                                            context->plugin_extension_count + 1));
486                 if (!vh->extensions)
487                         return NULL;
488
489                 memcpy((struct lws_extension *)vh->extensions, info->extensions,
490                        sizeof(struct lws_extension) * m);
491                 plugin = context->plugin_list;
492                 while (plugin) {
493                         memcpy((struct lws_extension *)&vh->extensions[m],
494                                 plugin->caps.extensions,
495                                sizeof(struct lws_extension) *
496                                plugin->caps.count_extensions);
497                         m += plugin->caps.count_extensions;
498                         plugin = plugin->list;
499                 }
500         } else
501 #endif
502                 vh->extensions = info->extensions;
503 #endif
504
505         vh->listen_port = info->port;
506 #if !defined(LWS_WITH_ESP8266)
507         vh->http_proxy_port = 0;
508         vh->http_proxy_address[0] = '\0';
509 #if defined(LWS_WITH_SOCKS5)
510         vh->socks_proxy_port = 0;
511         vh->socks_proxy_address[0] = '\0';
512 #endif
513
514         /* either use proxy from info, or try get it from env var */
515
516         /* http proxy */
517         if (info->http_proxy_address) {
518                 /* override for backwards compatibility */
519                 if (info->http_proxy_port)
520                         vh->http_proxy_port = info->http_proxy_port;
521                 lws_set_proxy(vh, info->http_proxy_address);
522         } else {
523 #ifdef LWS_HAVE_GETENV
524                 p = getenv("http_proxy");
525                 if (p)
526                         lws_set_proxy(vh, p);
527 #endif
528         }
529 #if defined(LWS_WITH_SOCKS5)
530         /* socks proxy */
531         if (info->socks_proxy_address) {
532                 /* override for backwards compatibility */
533                 if (info->socks_proxy_port)
534                         vh->socks_proxy_port = info->socks_proxy_port;
535                 lws_set_socks(vh, info->socks_proxy_address);
536         } else {
537 #ifdef LWS_HAVE_GETENV
538                 p = getenv("socks_proxy");
539                 if (p)
540                         lws_set_socks(vh, p);
541 #endif
542         }
543 #endif
544 #endif
545
546         vh->ka_time = info->ka_time;
547         vh->ka_interval = info->ka_interval;
548         vh->ka_probes = info->ka_probes;
549
550         if (vh->options & LWS_SERVER_OPTION_STS)
551                 lwsl_notice("   STS enabled\n");
552
553 #ifdef LWS_WITH_ACCESS_LOG
554         if (info->log_filepath) {
555                 vh->log_fd = open(info->log_filepath, O_CREAT | O_APPEND | O_RDWR, 0600);
556                 if (vh->log_fd == (int)LWS_INVALID_FILE) {
557                         lwsl_err("unable to open log filepath %s\n",
558                                  info->log_filepath);
559                         goto bail;
560                 }
561 #ifndef WIN32
562                 if (context->uid != -1)
563                         if (chown(info->log_filepath, context->uid,
564                                   context->gid) == -1)
565                                 lwsl_err("unable to chown log file %s\n",
566                                                 info->log_filepath);
567 #endif
568         } else
569                 vh->log_fd = (int)LWS_INVALID_FILE;
570 #endif
571         if (lws_context_init_server_ssl(info, vh))
572                 goto bail;
573         if (lws_context_init_client_ssl(info, vh))
574                 goto bail;
575         if (lws_context_init_server(info, vh)) {
576                 lwsl_err("init server failed\n");
577                 goto bail;
578         }
579
580         while (1) {
581                 if (!(*vh1)) {
582                         *vh1 = vh;
583                         break;
584                 }
585                 vh1 = &(*vh1)->vhost_next;
586         };
587         /* for the case we are adding a vhost much later, after server init */
588
589         if (context->protocol_init_done)
590                 lws_protocol_init(context);
591
592         return vh;
593
594 bail:
595         lws_free(vh);
596
597         return NULL;
598 }
599
600 LWS_VISIBLE int
601 lws_init_vhost_client_ssl(const struct lws_context_creation_info *info,
602                           struct lws_vhost *vhost)
603 {
604         struct lws_context_creation_info i;
605
606         memcpy(&i, info, sizeof(i));
607         i.port = CONTEXT_PORT_NO_LISTEN;
608
609         return lws_context_init_client_ssl(&i, vhost);
610 }
611
612 LWS_VISIBLE struct lws_context *
613 lws_create_context(struct lws_context_creation_info *info)
614 {
615         struct lws_context *context = NULL;
616         struct lws_plat_file_ops *prev;
617 #ifndef LWS_NO_DAEMONIZE
618         int pid_daemon = get_daemonize_pid();
619 #endif
620         int n, m;
621 #if defined(__ANDROID__)
622         struct rlimit rt;
623 #endif
624
625         lwsl_notice("Initial logging level %d\n", log_level);
626         lwsl_notice("Libwebsockets version: %s\n", library_version);
627 #if defined(GCC_VER)
628         lwsl_notice("Compiled with  %s\n", GCC_VER);
629 #endif
630 #if LWS_POSIX
631 #ifdef LWS_USE_IPV6
632         if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DISABLE_IPV6))
633                 lwsl_notice("IPV6 compiled in and enabled\n");
634         else
635                 lwsl_notice("IPV6 compiled in but disabled\n");
636 #else
637         lwsl_notice("IPV6 not compiled in\n");
638 #endif
639 #if !defined(LWS_PLAT_OPTEE) && !defined(LWS_PLAT_ESP32)
640         lws_feature_status_libev(info);
641         lws_feature_status_libuv(info);
642 #endif
643 #endif
644         lwsl_info(" LWS_DEF_HEADER_LEN    : %u\n", LWS_DEF_HEADER_LEN);
645         lwsl_info(" LWS_MAX_PROTOCOLS     : %u\n", LWS_MAX_PROTOCOLS);
646         lwsl_info(" LWS_MAX_SMP           : %u\n", LWS_MAX_SMP);
647         lwsl_info(" SPEC_LATEST_SUPPORTED : %u\n", SPEC_LATEST_SUPPORTED);
648         lwsl_info(" sizeof (*info)        : %ld\n", (long)sizeof(*info));
649 #if defined(LWS_WITH_STATS)
650         lwsl_notice(" LWS_WITH_STATS        : on\n");
651 #endif
652 #if LWS_POSIX
653         lwsl_info(" SYSTEM_RANDOM_FILEPATH: '%s'\n", SYSTEM_RANDOM_FILEPATH);
654 #endif
655         if (lws_plat_context_early_init())
656                 return NULL;
657
658         context = lws_zalloc(sizeof(struct lws_context));
659         if (!context) {
660                 lwsl_err("No memory for websocket context\n");
661                 return NULL;
662         }
663         if (info->pt_serv_buf_size)
664                 context->pt_serv_buf_size = info->pt_serv_buf_size;
665         else
666                 context->pt_serv_buf_size = 4096;
667
668         /* default to just the platform fops implementation */
669
670         context->fops_platform.LWS_FOP_OPEN     = _lws_plat_file_open;
671         context->fops_platform.LWS_FOP_CLOSE    = _lws_plat_file_close;
672         context->fops_platform.LWS_FOP_SEEK_CUR = _lws_plat_file_seek_cur;
673         context->fops_platform.LWS_FOP_READ     = _lws_plat_file_read;
674         context->fops_platform.LWS_FOP_WRITE    = _lws_plat_file_write;
675         context->fops_platform.fi[0].sig        = NULL;
676
677         /*
678          *  arrange a linear linked-list of fops starting from context->fops
679          *
680          * platform fops
681          * [ -> fops_zip (copied into context so .next settable) ]
682          * [ -> info->fops ]
683          */
684
685         context->fops = &context->fops_platform;
686         prev = (struct lws_plat_file_ops *)context->fops;
687
688 #if defined(LWS_WITH_ZIP_FOPS)
689         /* make a soft copy so we can set .next */
690         context->fops_zip = fops_zip;
691         prev->next = &context->fops_zip;
692         prev = (struct lws_plat_file_ops *)prev->next;
693 #endif
694
695         /* if user provided fops, tack them on the end of the list */
696         if (info->fops)
697                 prev->next = info->fops;
698
699         context->reject_service_keywords = info->reject_service_keywords;
700         if (info->external_baggage_free_on_destroy)
701                 context->external_baggage_free_on_destroy =
702                         info->external_baggage_free_on_destroy;
703
704         context->time_up = time(NULL);
705
706         context->simultaneous_ssl_restriction = info->simultaneous_ssl_restriction;
707
708 #ifndef LWS_NO_DAEMONIZE
709         if (pid_daemon) {
710                 context->started_with_parent = pid_daemon;
711                 lwsl_notice(" Started with daemon pid %d\n", pid_daemon);
712         }
713 #endif
714 #if defined(__ANDROID__)
715                 n = getrlimit ( RLIMIT_NOFILE,&rt);
716                 if (-1 == n) {
717                         lwsl_err("Get RLIMIT_NOFILE failed!\n");
718                         return NULL;
719                 }
720                 context->max_fds = rt.rlim_cur;
721 #else
722                 context->max_fds = getdtablesize();
723 #endif
724
725         if (info->count_threads)
726                 context->count_threads = info->count_threads;
727         else
728                 context->count_threads = 1;
729
730         if (context->count_threads > LWS_MAX_SMP)
731                 context->count_threads = LWS_MAX_SMP;
732
733         context->token_limits = info->token_limits;
734
735         context->options = info->options;
736
737         if (info->timeout_secs)
738                 context->timeout_secs = info->timeout_secs;
739         else
740                 context->timeout_secs = AWAITING_TIMEOUT;
741
742         context->ws_ping_pong_interval = info->ws_ping_pong_interval;
743
744         lwsl_info(" default timeout (secs): %u\n", context->timeout_secs);
745
746         if (info->max_http_header_data)
747                 context->max_http_header_data = info->max_http_header_data;
748         else
749                 if (info->max_http_header_data2)
750                         context->max_http_header_data =
751                                         info->max_http_header_data2;
752                 else
753                         context->max_http_header_data = LWS_DEF_HEADER_LEN;
754         if (info->max_http_header_pool)
755                 context->max_http_header_pool = info->max_http_header_pool;
756         else
757                 context->max_http_header_pool = LWS_DEF_HEADER_POOL;
758
759         /*
760          * Allocate the per-thread storage for scratchpad buffers,
761          * and header data pool
762          */
763         for (n = 0; n < context->count_threads; n++) {
764                 context->pt[n].serv_buf = lws_zalloc(context->pt_serv_buf_size);
765                 if (!context->pt[n].serv_buf) {
766                         lwsl_err("OOM\n");
767                         return NULL;
768                 }
769
770 #ifdef LWS_USE_LIBUV
771                 context->pt[n].context = context;
772 #endif
773                 context->pt[n].tid = n;
774                 context->pt[n].http_header_data = lws_malloc(context->max_http_header_data *
775                                                        context->max_http_header_pool);
776                 if (!context->pt[n].http_header_data)
777                         goto bail;
778
779                 context->pt[n].ah_pool = lws_zalloc(sizeof(struct allocated_headers) *
780                                               context->max_http_header_pool);
781                 for (m = 0; m < context->max_http_header_pool; m++)
782                         context->pt[n].ah_pool[m].data =
783                                 (char *)context->pt[n].http_header_data +
784                                 (m * context->max_http_header_data);
785                 if (!context->pt[n].ah_pool)
786                         goto bail;
787
788                 lws_pt_mutex_init(&context->pt[n]);
789         }
790
791         if (info->fd_limit_per_thread)
792                 context->fd_limit_per_thread = info->fd_limit_per_thread;
793         else
794                 context->fd_limit_per_thread = context->max_fds /
795                                                context->count_threads;
796
797         lwsl_notice(" Threads: %d each %d fds\n", context->count_threads,
798                     context->fd_limit_per_thread);
799
800         if (!info->ka_interval && info->ka_time > 0) {
801                 lwsl_err("info->ka_interval can't be 0 if ka_time used\n");
802                 return NULL;
803         }
804
805 #ifdef LWS_USE_LIBEV
806         /* (Issue #264) In order to *avoid breaking backwards compatibility*, we
807          * enable libev mediated SIGINT handling with a default handler of
808          * lws_sigint_cb. The handler can be overridden or disabled
809          * by invoking lws_sigint_cfg after creating the context, but
810          * before invoking lws_initloop:
811          */
812         context->use_ev_sigint = 1;
813         context->lws_ev_sigint_cb = &lws_ev_sigint_cb;
814 #endif /* LWS_USE_LIBEV */
815 #ifdef LWS_USE_LIBUV
816         /* (Issue #264) In order to *avoid breaking backwards compatibility*, we
817          * enable libev mediated SIGINT handling with a default handler of
818          * lws_sigint_cb. The handler can be overridden or disabled
819          * by invoking lws_sigint_cfg after creating the context, but
820          * before invoking lws_initloop:
821          */
822         context->use_ev_sigint = 1;
823         context->lws_uv_sigint_cb = &lws_uv_sigint_cb;
824 #endif
825 #ifdef LWS_USE_LIBEVENT
826         /* (Issue #264) In order to *avoid breaking backwards compatibility*, we
827          * enable libev mediated SIGINT handling with a default handler of
828          * lws_sigint_cb. The handler can be overridden or disabled
829          * by invoking lws_sigint_cfg after creating the context, but
830          * before invoking lws_initloop:
831          */
832         context->use_ev_sigint = 1;
833         context->lws_event_sigint_cb = &lws_event_sigint_cb;
834 #endif /* LWS_USE_LIBEVENT */
835
836         lwsl_info(" mem: context:         %5lu bytes (%ld ctx + (%ld thr x %d))\n",
837                   (long)sizeof(struct lws_context) +
838                   (context->count_threads * context->pt_serv_buf_size),
839                   (long)sizeof(struct lws_context),
840                   (long)context->count_threads,
841                   context->pt_serv_buf_size);
842
843         lwsl_info(" mem: http hdr rsvd:   %5lu bytes (%u thr x (%u + %lu) x %u))\n",
844                     (long)(context->max_http_header_data +
845                      sizeof(struct allocated_headers)) *
846                     context->max_http_header_pool * context->count_threads,
847                     context->count_threads,
848                     context->max_http_header_data,
849                     (long)sizeof(struct allocated_headers),
850                     context->max_http_header_pool);
851         n = sizeof(struct lws_pollfd) * context->count_threads *
852             context->fd_limit_per_thread;
853         context->pt[0].fds = lws_zalloc(n);
854         if (context->pt[0].fds == NULL) {
855                 lwsl_err("OOM allocating %d fds\n", context->max_fds);
856                 goto bail;
857         }
858         lwsl_info(" mem: pollfd map:      %5u\n", n);
859
860         if (info->server_string) {
861                 context->server_string = info->server_string;
862                 context->server_string_len = (short)
863                                 strlen(context->server_string);
864         }
865
866 #if LWS_MAX_SMP > 1
867         /* each thread serves his own chunk of fds */
868         for (n = 1; n < (int)info->count_threads; n++)
869                 context->pt[n].fds = context->pt[n - 1].fds +
870                                      context->fd_limit_per_thread;
871 #endif
872
873         if (lws_plat_init(context, info))
874                 goto bail;
875
876         lws_context_init_ssl_library(info);
877
878         context->user_space = info->user;
879
880         /*
881          * if he's not saying he'll make his own vhosts later then act
882          * compatibly and make a default vhost using the data in the info
883          */
884         if (!lws_check_opt(info->options, LWS_SERVER_OPTION_EXPLICIT_VHOSTS))
885                 if (!lws_create_vhost(context, info)) {
886                         lwsl_err("Failed to create default vhost\n");
887                         return NULL;
888                 }
889
890         lws_context_init_extensions(info, context);
891
892         lwsl_notice(" mem: per-conn:        %5lu bytes + protocol rx buf\n",
893                     (unsigned long)sizeof(struct lws));
894
895         strcpy(context->canonical_hostname, "unknown");
896         lws_server_get_canonical_hostname(context, info);
897
898         context->uid = info->uid;
899         context->gid = info->gid;
900
901 #if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
902         memcpy(context->caps, info->caps, sizeof(context->caps));
903         context->count_caps = info->count_caps;
904 #endif
905
906         /*
907          * drop any root privs for this process
908          * to listen on port < 1023 we would have needed root, but now we are
909          * listening, we don't want the power for anything else
910          */
911         if (!lws_check_opt(info->options, LWS_SERVER_OPTION_EXPLICIT_VHOSTS))
912                 lws_plat_drop_app_privileges(info);
913
914         /*
915          * give all extensions a chance to create any per-context
916          * allocations they need
917          */
918         if (info->port != CONTEXT_PORT_NO_LISTEN) {
919                 if (lws_ext_cb_all_exts(context, NULL,
920                         LWS_EXT_CB_SERVER_CONTEXT_CONSTRUCT, NULL, 0) < 0)
921                         goto bail;
922         } else
923                 if (lws_ext_cb_all_exts(context, NULL,
924                         LWS_EXT_CB_CLIENT_CONTEXT_CONSTRUCT, NULL, 0) < 0)
925                         goto bail;
926
927         return context;
928
929 bail:
930         lws_context_destroy(context);
931         return NULL;
932 }
933
934 LWS_VISIBLE LWS_EXTERN void
935 lws_context_deprecate(struct lws_context *context, lws_reload_func cb)
936 {
937         struct lws_vhost *vh = context->vhost_list, *vh1;
938         struct lws *wsi;
939
940         /*
941          * "deprecation" means disable the context from accepting any new
942          * connections and free up listen sockets to be used by a replacement
943          * context.
944          *
945          * Otherwise the deprecated context remains operational, until its
946          * number of connected sockets falls to zero, when it is deleted.
947          */
948
949         /* for each vhost, close his listen socket */
950
951         while (vh) {
952                 wsi = vh->lserv_wsi;
953                 if (wsi) {
954                         wsi->socket_is_permanently_unusable = 1;
955                         lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
956                         wsi->context->deprecation_pending_listen_close_count++;
957                         /*
958                          * other vhosts can share the listen port, they
959                          * point to the same wsi.  So zap those too.
960                          */
961                         vh1 = context->vhost_list;
962                         while (vh1) {
963                                 if (vh1->lserv_wsi == wsi)
964                                         vh1->lserv_wsi = NULL;
965                                 vh1 = vh1->vhost_next;
966                         }
967                 }
968                 vh = vh->vhost_next;
969         }
970
971         context->deprecated = 1;
972         context->deprecation_cb = cb;
973 }
974
975 LWS_VISIBLE LWS_EXTERN int
976 lws_context_is_deprecated(struct lws_context *context)
977 {
978         return context->deprecated;
979 }
980
981 LWS_VISIBLE void
982 lws_context_destroy2(struct lws_context *context);
983
984 LWS_VISIBLE void
985 lws_context_destroy(struct lws_context *context)
986 {
987         const struct lws_protocols *protocol = NULL;
988         struct lws_context_per_thread *pt;
989         struct lws_vhost *vh = NULL;
990         struct lws wsi;
991         int n, m;
992
993         if (!context) {
994                 lwsl_notice("%s: ctx %p\n", __func__, context);
995                 return;
996         }
997         if (context->being_destroyed1) {
998                 lwsl_notice("%s: ctx %p: already being destroyed\n", __func__, context);
999                 return;
1000         }
1001
1002         lwsl_notice("%s: ctx %p\n", __func__, context);
1003
1004         m = context->count_threads;
1005         context->being_destroyed = 1;
1006         context->being_destroyed1 = 1;
1007
1008         memset(&wsi, 0, sizeof(wsi));
1009         wsi.context = context;
1010
1011 #ifdef LWS_LATENCY
1012         if (context->worst_latency_info[0])
1013                 lwsl_notice("Worst latency: %s\n", context->worst_latency_info);
1014 #endif
1015
1016         while (m--) {
1017                 pt = &context->pt[m];
1018
1019                 for (n = 0; (unsigned int)n < context->pt[m].fds_count; n++) {
1020                         struct lws *wsi = wsi_from_fd(context, pt->fds[n].fd);
1021                         if (!wsi)
1022                                 continue;
1023
1024                         lws_close_free_wsi(wsi,
1025                                 LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY
1026                                 /* no protocol close */);
1027                         n--;
1028                 }
1029                 lws_pt_mutex_destroy(pt);
1030         }
1031
1032         /*
1033          * give all extensions a chance to clean up any per-context
1034          * allocations they might have made
1035          */
1036
1037         n = lws_ext_cb_all_exts(context, NULL,
1038                                 LWS_EXT_CB_SERVER_CONTEXT_DESTRUCT, NULL, 0);
1039
1040         n = lws_ext_cb_all_exts(context, NULL,
1041                                 LWS_EXT_CB_CLIENT_CONTEXT_DESTRUCT, NULL, 0);
1042
1043         /*
1044          * inform all the protocols that they are done and will have no more
1045          * callbacks.
1046          *
1047          * We can't free things until after the event loop shuts down.
1048          */
1049         if (context->protocol_init_done)
1050                 vh = context->vhost_list;
1051         while (vh) {
1052                 wsi.vhost = vh;
1053                 protocol = vh->protocols;
1054                 if (protocol) {
1055                         n = 0;
1056                         while (n < vh->count_protocols) {
1057                                 wsi.protocol = protocol;
1058                                 protocol->callback(&wsi, LWS_CALLBACK_PROTOCOL_DESTROY,
1059                                                    NULL, NULL, 0);
1060                                 protocol++;
1061                                 n++;
1062                         }
1063                 }
1064
1065                 vh = vh->vhost_next;
1066         }
1067
1068         for (n = 0; n < context->count_threads; n++) {
1069                 pt = &context->pt[n];
1070
1071                 lws_libev_destroyloop(context, n);
1072                 lws_libuv_destroyloop(context, n);
1073                 lws_libevent_destroyloop(context, n);
1074
1075                 lws_free_set_NULL(context->pt[n].serv_buf);
1076                 if (pt->ah_pool)
1077                         lws_free(pt->ah_pool);
1078                 if (pt->http_header_data)
1079                         lws_free(pt->http_header_data);
1080         }
1081         lws_plat_context_early_destroy(context);
1082
1083         if (context->pt[0].fds)
1084                 lws_free_set_NULL(context->pt[0].fds);
1085
1086         if (!LWS_LIBUV_ENABLED(context))
1087                 lws_context_destroy2(context);
1088 }
1089
1090 /*
1091  * call the second one after the event loop has been shut down cleanly
1092  */
1093
1094 LWS_VISIBLE void
1095 lws_context_destroy2(struct lws_context *context)
1096 {
1097         const struct lws_protocols *protocol = NULL;
1098         struct lws_vhost *vh = NULL, *vh1;
1099         int n;
1100
1101         lwsl_notice("%s: ctx %p\n", __func__, context);
1102
1103         /*
1104          * free all the per-vhost allocations
1105          */
1106
1107         vh = context->vhost_list;
1108         while (vh) {
1109                 protocol = vh->protocols;
1110                 if (protocol) {
1111                         n = 0;
1112                         while (n < vh->count_protocols) {
1113                                 if (vh->protocol_vh_privs &&
1114                                     vh->protocol_vh_privs[n]) {
1115                                         // lwsl_notice("   %s: freeing per-vhost protocol data %p\n", __func__, vh->protocol_vh_privs[n]);
1116                                         lws_free(vh->protocol_vh_privs[n]);
1117                                         vh->protocol_vh_privs[n] = NULL;
1118                                 }
1119                                 protocol++;
1120                                 n++;
1121                         }
1122                 }
1123                 if (vh->protocol_vh_privs)
1124                         lws_free(vh->protocol_vh_privs);
1125                 lws_ssl_SSL_CTX_destroy(vh);
1126                 lws_free(vh->same_vh_protocol_list);
1127 #ifdef LWS_WITH_PLUGINS
1128                 if (context->plugin_list)
1129                         lws_free((void *)vh->protocols);
1130 #else
1131                 if (vh->options & LWS_SERVER_OPTION_EXPLICIT_VHOSTS)
1132                         lws_free((void *)vh->protocols);
1133 #endif
1134 #ifdef LWS_WITH_PLUGINS
1135 #ifndef LWS_NO_EXTENSIONS
1136                 if (context->plugin_extension_count)
1137                         lws_free((void *)vh->extensions);
1138 #endif
1139 #endif
1140 #ifdef LWS_WITH_ACCESS_LOG
1141                 if (vh->log_fd != (int)LWS_INVALID_FILE)
1142                         close(vh->log_fd);
1143 #endif
1144
1145                 vh1 = vh->vhost_next;
1146                 lws_free(vh);
1147                 vh = vh1;
1148         }
1149
1150         lws_stats_log_dump(context);
1151
1152         lws_ssl_context_destroy(context);
1153         lws_plat_context_late_destroy(context);
1154
1155         if (context->external_baggage_free_on_destroy)
1156                 free(context->external_baggage_free_on_destroy);
1157
1158         lws_free(context);
1159 }