context.c 28 KB

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