secure-streams.c 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2019 - 2020 Andy Green <[email protected]>
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to
  8. * deal in the Software without restriction, including without limitation the
  9. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10. * sell copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  22. * IN THE SOFTWARE.
  23. */
  24. #include <private-lib-core.h>
  25. static const struct ss_pcols *ss_pcols[] = {
  26. #if defined(LWS_ROLE_H1)
  27. &ss_pcol_h1, /* LWSSSP_H1 */
  28. #else
  29. NULL,
  30. #endif
  31. #if defined(LWS_ROLE_H2)
  32. &ss_pcol_h2, /* LWSSSP_H2 */
  33. #else
  34. NULL,
  35. #endif
  36. #if defined(LWS_ROLE_WS)
  37. &ss_pcol_ws, /* LWSSSP_WS */
  38. #else
  39. NULL,
  40. #endif
  41. #if defined(LWS_ROLE_MQTT)
  42. &ss_pcol_mqtt, /* LWSSSP_MQTT */
  43. #else
  44. NULL,
  45. #endif
  46. &ss_pcol_raw, /* LWSSSP_RAW */
  47. NULL,
  48. };
  49. static const char *state_names[] = {
  50. "LWSSSCS_CREATING",
  51. "LWSSSCS_DISCONNECTED",
  52. "LWSSSCS_UNREACHABLE",
  53. "LWSSSCS_AUTH_FAILED",
  54. "LWSSSCS_CONNECTED",
  55. "LWSSSCS_CONNECTING",
  56. "LWSSSCS_DESTROYING",
  57. "LWSSSCS_POLL",
  58. "LWSSSCS_ALL_RETRIES_FAILED",
  59. "LWSSSCS_QOS_ACK_REMOTE",
  60. "LWSSSCS_QOS_NACK_REMOTE",
  61. "LWSSSCS_QOS_ACK_LOCAL",
  62. "LWSSSCS_QOS_NACK_LOCAL",
  63. "LWSSSCS_TIMEOUT",
  64. "LWSSSCS_SERVER_TXN",
  65. "LWSSSCS_SERVER_UPGRADE",
  66. };
  67. const char *
  68. lws_ss_state_name(int state)
  69. {
  70. if (state >= (int)LWS_ARRAY_SIZE(state_names))
  71. return "unknown";
  72. return state_names[state];
  73. }
  74. lws_ss_state_return_t
  75. lws_ss_event_helper(lws_ss_handle_t *h, lws_ss_constate_t cs)
  76. {
  77. lws_ss_state_return_t r;
  78. if (!h)
  79. return LWSSSSRET_OK;
  80. #if defined(LWS_WITH_SEQUENCER)
  81. /*
  82. * A parent sequencer for the ss is optional, if we have one, keep it
  83. * informed of state changes on the ss connection
  84. */
  85. if (h->seq && cs != LWSSSCS_DESTROYING)
  86. lws_seq_queue_event(h->seq, LWSSEQ_SS_STATE_BASE + cs,
  87. (void *)h, NULL);
  88. #endif
  89. if (h->info.state) {
  90. r = h->info.state(ss_to_userobj(h), NULL, cs, 0);
  91. #if defined(LWS_WITH_SERVER)
  92. if ((h->info.flags & LWSSSINFLAGS_ACCEPTED) &&
  93. cs == LWSSSCS_DISCONNECTED)
  94. r = LWSSSSRET_DESTROY_ME;
  95. #endif
  96. return r;
  97. }
  98. return LWSSSSRET_OK;
  99. }
  100. int
  101. _lws_ss_handle_state_ret(lws_ss_state_return_t r, struct lws *wsi,
  102. lws_ss_handle_t **ph)
  103. {
  104. if (r == LWSSSSRET_DESTROY_ME) {
  105. if (wsi)
  106. lws_set_opaque_user_data(wsi, NULL);
  107. (*ph)->wsi = NULL;
  108. lws_ss_destroy(ph);
  109. }
  110. return -1; /* close connection */
  111. }
  112. static void
  113. lws_ss_timeout_sul_check_cb(lws_sorted_usec_list_t *sul)
  114. {
  115. lws_ss_handle_t *h = lws_container_of(sul, lws_ss_handle_t, sul);
  116. lwsl_notice("%s: retrying ss h %p (%s) after backoff\n", __func__, h,
  117. h->policy->streamtype);
  118. /* we want to retry... */
  119. h->seqstate = SSSEQ_DO_RETRY;
  120. lws_ss_request_tx(h);
  121. }
  122. int
  123. lws_ss_exp_cb_metadata(void *priv, const char *name, char *out, size_t *pos,
  124. size_t olen, size_t *exp_ofs)
  125. {
  126. lws_ss_handle_t *h = (lws_ss_handle_t *)priv;
  127. const char *replace = NULL;
  128. size_t total, budget;
  129. lws_ss_metadata_t *md = lws_ss_policy_metadata(h->policy, name);
  130. if (!md) {
  131. lwsl_err("%s: Unknown metadata %s\n", __func__, name);
  132. return LSTRX_FATAL_NAME_UNKNOWN;
  133. }
  134. lwsl_info("%s %s %d\n", __func__, name, (int)md->length);
  135. replace = h->metadata[md->length].value;
  136. total = h->metadata[md->length].length;
  137. // lwsl_hexdump_err(replace, total);
  138. budget = olen - *pos;
  139. total -= *exp_ofs;
  140. if (total < budget)
  141. budget = total;
  142. if (out)
  143. memcpy(out + *pos, replace + (*exp_ofs), budget);
  144. *exp_ofs += budget;
  145. *pos += budget;
  146. if (budget == total)
  147. return LSTRX_DONE;
  148. return LSTRX_FILLED_OUT;
  149. }
  150. int
  151. lws_ss_set_timeout_us(lws_ss_handle_t *h, lws_usec_t us)
  152. {
  153. struct lws_context_per_thread *pt = &h->context->pt[h->tsi];
  154. h->sul.cb = lws_ss_timeout_sul_check_cb;
  155. __lws_sul_insert_us(&pt->pt_sul_owner[
  156. !!(h->policy->flags & LWSSSPOLF_WAKE_SUSPEND__VALIDITY)],
  157. &h->sul, us);
  158. return 0;
  159. }
  160. lws_ss_state_return_t
  161. lws_ss_backoff(lws_ss_handle_t *h)
  162. {
  163. uint64_t ms;
  164. char conceal;
  165. if (h->seqstate == SSSEQ_RECONNECT_WAIT)
  166. return LWSSSSRET_OK;
  167. /* figure out what we should do about another retry */
  168. lwsl_info("%s: ss %p: retry backoff after failure\n", __func__, h);
  169. ms = lws_retry_get_delay_ms(h->context, h->policy->retry_bo,
  170. &h->retry, &conceal);
  171. if (!conceal) {
  172. lwsl_info("%s: ss %p: abandon conn attempt \n",__func__, h);
  173. h->seqstate = SSSEQ_IDLE;
  174. return lws_ss_event_helper(h, LWSSSCS_ALL_RETRIES_FAILED);
  175. }
  176. h->seqstate = SSSEQ_RECONNECT_WAIT;
  177. lws_ss_set_timeout_us(h, ms * LWS_US_PER_MS);
  178. lwsl_info("%s: ss %p: retry wait %"PRIu64"ms\n", __func__, h, ms);
  179. return LWSSSSRET_OK;
  180. }
  181. #if defined(LWS_WITH_SYS_SMD)
  182. /*
  183. * Local SMD <-> SS
  184. *
  185. * We pass received messages through to the SS handler synchronously, using the
  186. * lws service thread context.
  187. *
  188. * After the SS is created and registered, still nothing is going to come here
  189. * until the peer sends us his rx_class_mask and we update his registration with
  190. * it, because from SS creation his rx_class_mask defaults to 0.
  191. */
  192. static int
  193. lws_smd_ss_cb(void *opaque, lws_smd_class_t _class,
  194. lws_usec_t timestamp, void *buf, size_t len)
  195. {
  196. lws_ss_handle_t *h = (lws_ss_handle_t *)opaque;
  197. uint8_t *p = (uint8_t *)buf - LWS_SMD_SS_RX_HEADER_LEN;
  198. /*
  199. * When configured with SS enabled, lws over-allocates
  200. * LWS_SMD_SS_RX_HEADER_LEN bytes behind the payload of the queued
  201. * message, for prepending serialized class and timestamp data in-band
  202. * with the payload.
  203. */
  204. lws_ser_wu64be(p, _class);
  205. lws_ser_wu64be(p + 8, timestamp);
  206. if (h->info.rx)
  207. h->info.rx((void *)&h[1], p, len + LWS_SMD_SS_RX_HEADER_LEN,
  208. LWSSS_FLAG_SOM | LWSSS_FLAG_EOM);
  209. return 0;
  210. }
  211. static void
  212. lws_ss_smd_tx_cb(lws_sorted_usec_list_t *sul)
  213. {
  214. lws_ss_handle_t *h = lws_container_of(sul, lws_ss_handle_t, u.smd.sul_write);
  215. uint8_t buf[LWS_SMD_SS_RX_HEADER_LEN + LWS_SMD_MAX_PAYLOAD], *p;
  216. size_t len = sizeof(buf);
  217. lws_smd_class_t _class;
  218. int flags = 0, n;
  219. if (!h->info.tx)
  220. return;
  221. n = h->info.tx(&h[1], h->txord++, buf, &len, &flags);
  222. if (n)
  223. /* nonzero return means don't want to send anything */
  224. return;
  225. // lwsl_notice("%s: (SS %p bound to _lws_smd creates message) tx len %d\n", __func__, h, (int)len);
  226. // lwsl_hexdump_notice(buf, len);
  227. assert(len >= LWS_SMD_SS_RX_HEADER_LEN);
  228. _class = (lws_smd_class_t)lws_ser_ru64be(buf);
  229. p = lws_smd_msg_alloc(h->context, _class, len - LWS_SMD_SS_RX_HEADER_LEN);
  230. if (!p) {
  231. // this can be rejected if nobody listening for this class
  232. //lwsl_notice("%s: failed to alloc\n", __func__);
  233. return;
  234. }
  235. memcpy(p, buf + LWS_SMD_SS_RX_HEADER_LEN, len - LWS_SMD_SS_RX_HEADER_LEN);
  236. if (lws_smd_msg_send(h->context, p)) {
  237. lwsl_notice("%s: failed to queue\n", __func__);
  238. return;
  239. }
  240. }
  241. #endif
  242. int
  243. _lws_ss_client_connect(lws_ss_handle_t *h, int is_retry)
  244. {
  245. const char *prot, *_prot, *ipath, *_ipath, *ads, *_ads;
  246. struct lws_client_connect_info i;
  247. const struct ss_pcols *ssp;
  248. size_t used_in, used_out;
  249. union lws_ss_contemp ct;
  250. char path[1024], ep[96];
  251. lws_ss_state_return_t r;
  252. int port, _port, tls;
  253. lws_strexp_t exp;
  254. if (!h->policy) {
  255. lwsl_err("%s: ss with no policy\n", __func__);
  256. return -1;
  257. }
  258. /*
  259. * We are already bound to a sink?
  260. */
  261. // if (h->h_sink)
  262. // return 0;
  263. if (!is_retry)
  264. h->retry = 0;
  265. #if defined(LWS_WITH_SYS_SMD)
  266. if (h->policy == &pol_smd) {
  267. if (h->u.smd.smd_peer)
  268. return 0;
  269. // lwsl_notice("%s: received connect for _lws_smd, registering for class mask 0x%x\n",
  270. // __func__, h->info.manual_initial_tx_credit);
  271. h->u.smd.smd_peer = lws_smd_register(h->context, h,
  272. (h->info.flags & LWSSSINFLAGS_PROXIED) ?
  273. LWSSMDREG_FLAG_PROXIED_SS : 0,
  274. h->info.manual_initial_tx_credit,
  275. lws_smd_ss_cb);
  276. if (!h->u.smd.smd_peer)
  277. return -1;
  278. if (lws_ss_event_helper(h, LWSSSCS_CONNECTING))
  279. return -1;
  280. // lwsl_err("%s: registered SS SMD\n", __func__);
  281. if (lws_ss_event_helper(h, LWSSSCS_CONNECTED))
  282. return -1;
  283. return 0;
  284. }
  285. #endif
  286. /*
  287. * We're going to substitute ${metadata} in the endpoint at connection-
  288. * time, so this can be set dynamically...
  289. */
  290. lws_strexp_init(&exp, (void *)h, lws_ss_exp_cb_metadata, ep, sizeof(ep));
  291. if (lws_strexp_expand(&exp, h->policy->endpoint,
  292. strlen(h->policy->endpoint),
  293. &used_in, &used_out) != LSTRX_DONE) {
  294. lwsl_err("%s: address strexp failed\n", __func__);
  295. return -1;
  296. }
  297. /*
  298. * ... in some cases, we might want the user to be able to override
  299. * some policy settings by what he provided in there. For example,
  300. * if he set the endpoint to "https://myendpoint.com:4443/mypath" it
  301. * might be quite convenient to override the policy to follow the info
  302. * that was given for at least server, port and the url path.
  303. */
  304. _port = port = h->policy->port;
  305. _prot = prot = NULL;
  306. _ipath = ipath = "";
  307. _ads = ads = ep;
  308. if (strchr(ep, ':') &&
  309. !lws_parse_uri(ep, &_prot, &_ads, &_port, &_ipath)) {
  310. lwsl_debug("%s: using uri parse results '%s' '%s' %d '%s'\n",
  311. __func__, _prot, _ads, _port, _ipath);
  312. prot = _prot;
  313. ads = _ads;
  314. port = _port;
  315. ipath = _ipath;
  316. }
  317. memset(&i, 0, sizeof i); /* otherwise uninitialized garbage */
  318. i.context = h->context;
  319. tls = !!(h->policy->flags & LWSSSPOLF_TLS);
  320. if (prot && (!strcmp(prot, "http") || !strcmp(prot, "ws") ||
  321. !strcmp(prot, "mqtt")))
  322. tls = 0;
  323. if (tls) {
  324. lwsl_info("%s: using tls\n", __func__);
  325. i.ssl_connection = LCCSCF_USE_SSL;
  326. if (!h->policy->trust.store)
  327. lwsl_info("%s: using platform trust store\n", __func__);
  328. else {
  329. i.vhost = lws_get_vhost_by_name(h->context,
  330. h->policy->trust.store->name);
  331. if (!i.vhost) {
  332. lwsl_err("%s: missing vh for policy %s\n",
  333. __func__,
  334. h->policy->trust.store->name);
  335. return -1;
  336. }
  337. }
  338. }
  339. if (h->policy->flags & LWSSSPOLF_WAKE_SUSPEND__VALIDITY)
  340. i.ssl_connection |= LCCSCF_WAKE_SUSPEND__VALIDITY;
  341. i.address = ads;
  342. i.port = port;
  343. i.host = i.address;
  344. i.origin = i.address;
  345. i.opaque_user_data = h;
  346. i.seq = h->seq;
  347. i.retry_and_idle_policy = h->policy->retry_bo;
  348. i.sys_tls_client_cert = h->policy->client_cert;
  349. i.path = ipath;
  350. /* if this is not "", munge should use it instead of policy
  351. * url path
  352. */
  353. ssp = ss_pcols[(int)h->policy->protocol];
  354. if (!ssp) {
  355. lwsl_err("%s: unsupported protocol\n", __func__);
  356. return -1;
  357. }
  358. i.alpn = ssp->alpn;
  359. /*
  360. * For http, we can get the method from the http object, override in
  361. * the protocol-specific munge callback below if not http
  362. */
  363. i.method = h->policy->u.http.method;
  364. i.protocol = ssp->protocol->name; /* lws protocol name */
  365. i.local_protocol_name = i.protocol;
  366. if (ssp->munge) /* eg, raw doesn't use; endpoint strexp already done */
  367. ssp->munge(h, path, sizeof(path), &i, &ct);
  368. i.pwsi = &h->wsi;
  369. #if defined(LWS_WITH_SSPLUGINS)
  370. if (h->policy->plugins[0] && h->policy->plugins[0]->munge)
  371. h->policy->plugins[0]->munge(h, path, sizeof(path));
  372. #endif
  373. lwsl_info("%s: connecting %s, '%s' '%s' %s\n", __func__, i.method,
  374. i.alpn, i.address, i.path);
  375. h->txn_ok = 0;
  376. r = lws_ss_event_helper(h, LWSSSCS_CONNECTING);
  377. if (r)
  378. return r;
  379. if (!lws_client_connect_via_info(&i)) {
  380. r = lws_ss_event_helper(h, LWSSSCS_UNREACHABLE);
  381. if (r)
  382. return r;
  383. r = lws_ss_backoff(h);
  384. if (r)
  385. return r;
  386. return 1;
  387. }
  388. return 0;
  389. }
  390. int
  391. lws_ss_client_connect(lws_ss_handle_t *h)
  392. {
  393. return _lws_ss_client_connect(h, 0);
  394. }
  395. /*
  396. * Public API
  397. */
  398. /*
  399. * Create either a stream or a sink
  400. */
  401. int
  402. lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi,
  403. void *opaque_user_data, lws_ss_handle_t **ppss,
  404. struct lws_sequencer *seq_owner, const char **ppayload_fmt)
  405. {
  406. struct lws_context_per_thread *pt = &context->pt[tsi];
  407. const lws_ss_policy_t *pol;
  408. lws_ss_metadata_t *smd;
  409. lws_ss_handle_t *h;
  410. size_t size;
  411. void **v;
  412. char *p;
  413. int n;
  414. pol = lws_ss_policy_lookup(context, ssi->streamtype);
  415. if (!pol) {
  416. lwsl_info("%s: unknown stream type %s\n", __func__,
  417. ssi->streamtype);
  418. return 1;
  419. }
  420. if (ssi->flags & LWSSSINFLAGS_REGISTER_SINK) {
  421. /*
  422. * This can register a secure streams sink as well as normal
  423. * secure streams connections. If that's what's happening,
  424. * confirm the policy agrees that this streamtype should be
  425. * directed to a sink.
  426. */
  427. if (!(pol->flags & LWSSSPOLF_LOCAL_SINK)) {
  428. /*
  429. * Caller wanted to create a sink for this streamtype,
  430. * but the policy does not agree the streamtype should
  431. * be routed to a local sink.
  432. */
  433. lwsl_err("%s: %s policy does not allow local sink\n",
  434. __func__, ssi->streamtype);
  435. return 1;
  436. }
  437. } else {
  438. if (!(pol->flags & LWSSSPOLF_LOCAL_SINK)) {
  439. }
  440. // lws_dll2_foreach_safe(&pt->ss_owner, NULL, lws_ss_destroy_dll);
  441. }
  442. /*
  443. * We overallocate and point to things in the overallocation...
  444. *
  445. * 1) the user_alloc from the stream info
  446. * 2) network auth plugin instantiation data
  447. * 3) stream auth plugin instantiation data
  448. * 4) as many metadata pointer structs as the policy tells
  449. * 5) the streamtype name (length is not aligned)
  450. *
  451. * ... when we come to destroy it, just one free to do.
  452. */
  453. size = sizeof(*h) + ssi->user_alloc + strlen(ssi->streamtype) + 1;
  454. #if defined(LWS_WITH_SSPLUGINS)
  455. if (pol->plugins[0])
  456. size += pol->plugins[0]->alloc;
  457. if (pol->plugins[1])
  458. size += pol->plugins[1]->alloc;
  459. #endif
  460. size += pol->metadata_count * sizeof(lws_ss_metadata_t);
  461. h = lws_zalloc(size, __func__);
  462. if (!h)
  463. return 2;
  464. h->info = *ssi;
  465. h->policy = pol;
  466. h->context = context;
  467. h->tsi = tsi;
  468. h->seq = seq_owner;
  469. /* start of overallocated area */
  470. p = (char *)&h[1];
  471. /* set the handle pointer in the user data struct */
  472. v = (void **)(p + ssi->handle_offset);
  473. *v = h;
  474. /* set the opaque user data in the user data struct */
  475. v = (void **)(p + ssi->opaque_user_data_offset);
  476. *v = opaque_user_data;
  477. p += ssi->user_alloc;
  478. #if defined(LWS_WITH_SSPLUGINS)
  479. if (pol->plugins[0]) {
  480. h->nauthi = p;
  481. p += pol->plugins[0]->alloc;
  482. }
  483. if (pol->plugins[1]) {
  484. h->sauthi = p;
  485. p += pol->plugins[1]->alloc;
  486. }
  487. #endif
  488. if (pol->metadata_count) {
  489. h->metadata = (lws_ss_metadata_t *)p;
  490. p += pol->metadata_count * sizeof(lws_ss_metadata_t);
  491. lwsl_info("%s: %s metadata count %d\n", __func__,
  492. pol->streamtype, pol->metadata_count);
  493. }
  494. smd = pol->metadata;
  495. for (n = 0; n < pol->metadata_count; n++) {
  496. h->metadata[n].name = smd->name;
  497. if (n + 1 == pol->metadata_count)
  498. h->metadata[n].next = NULL;
  499. else
  500. h->metadata[n].next = &h->metadata[n + 1];
  501. smd = smd->next;
  502. }
  503. memcpy(p, ssi->streamtype, strlen(ssi->streamtype) + 1);
  504. /* don't mark accepted ss as being the server */
  505. if (ssi->flags & LWSSSINFLAGS_SERVER)
  506. h->info.flags &= ~LWSSSINFLAGS_SERVER;
  507. h->info.streamtype = p;
  508. lws_pt_lock(pt, __func__);
  509. lws_dll2_add_head(&h->list, &pt->ss_owner);
  510. lws_pt_unlock(pt);
  511. if (ppss)
  512. *ppss = h;
  513. if (ppayload_fmt)
  514. *ppayload_fmt = pol->payload_fmt;
  515. if (ssi->flags & LWSSSINFLAGS_SERVER)
  516. /*
  517. * return early for accepted connection flow
  518. */
  519. return 0;
  520. #if defined(LWS_WITH_SYS_SMD)
  521. /*
  522. * For a local Secure Streams connection
  523. */
  524. if (!(ssi->flags & LWSSSINFLAGS_PROXIED) &&
  525. pol == &pol_smd) {
  526. lws_ss_state_return_t r;
  527. /*
  528. * So he has asked to be wired up to SMD over a SS link.
  529. * Register him as an smd participant in his own right.
  530. *
  531. * Just for this case, ssi->manual_initial_tx_credit is used
  532. * to set the rx class mask (this is part of the SS serialization
  533. * format as well)
  534. */
  535. h->u.smd.smd_peer = lws_smd_register(context, h, 0,
  536. ssi->manual_initial_tx_credit,
  537. lws_smd_ss_cb);
  538. if (!h->u.smd.smd_peer)
  539. goto late_bail;
  540. lwsl_info("%s: registered SS SMD\n", __func__);
  541. r = lws_ss_event_helper(h, LWSSSCS_CONNECTING);
  542. if (r)
  543. return r;
  544. r = lws_ss_event_helper(h, LWSSSCS_CONNECTED);
  545. if (r)
  546. return r;
  547. }
  548. #endif
  549. #if defined(LWS_WITH_SERVER)
  550. if (h->policy->flags & LWSSSPOLF_SERVER) {
  551. const struct lws_protocols *pprot[3], **ppp = &pprot[0];
  552. struct lws_context_creation_info i;
  553. struct lws_vhost *vho;
  554. lwsl_info("%s: creating server\n", __func__);
  555. /*
  556. * This streamtype represents a server, we're being asked to
  557. * instantiate a corresponding vhost for it
  558. */
  559. memset(&i, 0, sizeof i);
  560. i.iface = h->policy->endpoint;
  561. i.vhost_name = h->policy->streamtype;
  562. i.port = h->policy->port;
  563. if (!ss_pcols[h->policy->protocol]) {
  564. lwsl_err("%s: unsupp protocol", __func__);
  565. goto late_bail;
  566. }
  567. *ppp++ = ss_pcols[h->policy->protocol]->protocol;
  568. #if defined(LWS_ROLE_WS)
  569. if (h->policy->u.http.u.ws.subprotocol)
  570. /*
  571. * He names a ws subprotocol, ie, we want to support
  572. * ss-ws protocol in this vhost
  573. */
  574. *ppp++ = &protocol_secstream_ws;
  575. #endif
  576. *ppp = NULL;
  577. i.pprotocols = pprot;
  578. #if defined(LWS_WITH_TLS)
  579. if (h->policy->flags & LWSSSPOLF_TLS) {
  580. i.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
  581. i.server_ssl_cert_mem =
  582. h->policy->trust.server.cert->ca_der;
  583. i.server_ssl_cert_mem_len = (unsigned int)
  584. h->policy->trust.server.cert->ca_der_len;
  585. i.server_ssl_private_key_mem =
  586. h->policy->trust.server.key->ca_der;
  587. i.server_ssl_private_key_mem_len = (unsigned int)
  588. h->policy->trust.server.key->ca_der_len;
  589. }
  590. #endif
  591. vho = lws_create_vhost(context, &i);
  592. if (!vho) {
  593. lwsl_err("%s: failed to create vh", __func__);
  594. goto late_bail;
  595. }
  596. /*
  597. * Mark this vhost as having to apply ss server semantics to
  598. * any incoming accepted connection
  599. */
  600. vho->ss_handle = h;
  601. lwsl_notice("%s: created server %s\n", __func__,
  602. h->policy->streamtype);
  603. return 0;
  604. }
  605. #endif
  606. #if defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
  607. /*
  608. * For static policy case, dynamically ref / instantiate the related
  609. * trust store and vhost. We do it by logical ss rather than connection
  610. * because we don't want to expose the latency of creating the x.509
  611. * trust store at the first connection.
  612. *
  613. * But it might be given the tls linkup takes time anyway, it can move
  614. * to the ss connect code instead.
  615. */
  616. if (!lws_ss_policy_ref_trust_store(context, h->policy, 1 /* do the ref */)) {
  617. lwsl_err("%s: unable to get vhost / trust store\n", __func__);
  618. goto late_bail;
  619. }
  620. #endif
  621. if (lws_ss_event_helper(h, LWSSSCS_CREATING)) {
  622. late_bail:
  623. lws_pt_lock(pt, __func__);
  624. lws_dll2_remove(&h->list);
  625. lws_pt_unlock(pt);
  626. lws_free(h);
  627. return 1;
  628. }
  629. if (!(ssi->flags & LWSSSINFLAGS_REGISTER_SINK) &&
  630. ((h->policy->flags & LWSSSPOLF_NAILED_UP)
  631. #if defined(LWS_WITH_SYS_SMD)
  632. || ((h->policy == &pol_smd) //&&
  633. //(ssi->flags & LWSSSINFLAGS_PROXIED))
  634. )
  635. #endif
  636. ))
  637. if (_lws_ss_client_connect(h, 0)) {
  638. if (lws_ss_backoff(h))
  639. /* has been destroyed */
  640. return 1;
  641. }
  642. return 0;
  643. }
  644. void *
  645. lws_ss_to_user_object(struct lws_ss_handle *h)
  646. {
  647. return (void *)&h[1];
  648. }
  649. void
  650. lws_ss_destroy(lws_ss_handle_t **ppss)
  651. {
  652. struct lws_context_per_thread *pt;
  653. lws_ss_handle_t *h = *ppss;
  654. lws_ss_metadata_t *pmd;
  655. if (!h)
  656. return;
  657. if (h->destroying) {
  658. lwsl_info("%s: reentrant destroy\n", __func__);
  659. return;
  660. }
  661. h->destroying = 1;
  662. if (h->wsi) {
  663. /*
  664. * Don't let the wsi point to us any more,
  665. * we (the ss object bound to the wsi) are going away now
  666. */
  667. lws_set_opaque_user_data(h->wsi, NULL);
  668. lws_set_timeout(h->wsi, 1, LWS_TO_KILL_SYNC);
  669. }
  670. /*
  671. * if we bound an smd registration to the SS, unregister it
  672. */
  673. #if defined(LWS_WITH_SYS_SMD)
  674. if (h->policy == &pol_smd && h->u.smd.smd_peer) {
  675. lws_smd_unregister(h->u.smd.smd_peer);
  676. h->u.smd.smd_peer = NULL;
  677. }
  678. #endif
  679. pt = &h->context->pt[h->tsi];
  680. lws_pt_lock(pt, __func__);
  681. *ppss = NULL;
  682. lws_dll2_remove(&h->list);
  683. lws_dll2_remove(&h->to_list);
  684. lws_sul_cancel(&h->sul_timeout);
  685. (void)lws_ss_event_helper(h, LWSSSCS_DESTROYING);
  686. lws_pt_unlock(pt);
  687. /* in proxy case, metadata value on heap may need cleaning up */
  688. pmd = h->metadata;
  689. while (pmd) {
  690. lwsl_info("%s: pmd %p\n", __func__, pmd);
  691. if (pmd->value_on_lws_heap)
  692. lws_free_set_NULL(pmd->value);
  693. pmd = pmd->next;
  694. }
  695. lws_sul_cancel(&h->sul);
  696. #if defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
  697. /*
  698. * For static policy case, dynamically ref / instantiate the related
  699. * trust store and vhost. We do it by logical ss rather than connection
  700. * because we don't want to expose the latency of creating the x.509
  701. * trust store at the first connection.
  702. *
  703. * But it might be given the tls linkup takes time anyway, it can move
  704. * to the ss connect code instead.
  705. */
  706. lws_ss_policy_unref_trust_store(h->context, h->policy);
  707. #endif
  708. #if defined(LWS_WITH_SERVER)
  709. if (h->policy->flags & LWSSSPOLF_SERVER) {
  710. struct lws_vhost *v = lws_get_vhost_by_name(h->context,
  711. h->policy->streamtype);
  712. /*
  713. * For server, the policy describes a vhost that implements the
  714. * server, when we take down the ss, we take down the related
  715. * vhost (if it got that far)
  716. */
  717. if (v)
  718. lws_vhost_destroy(v);
  719. }
  720. #endif
  721. /* confirm no sul left scheduled in handle or user allocation object */
  722. lws_sul_debug_zombies(h->context, h, sizeof(*h) + h->info.user_alloc,
  723. __func__);
  724. lws_free_set_NULL(h);
  725. }
  726. void
  727. lws_ss_server_ack(struct lws_ss_handle *h, int nack)
  728. {
  729. h->txn_resp = nack;
  730. h->txn_resp_set = 1;
  731. }
  732. lws_ss_state_return_t
  733. lws_ss_request_tx(lws_ss_handle_t *h)
  734. {
  735. lws_ss_state_return_t r;
  736. // lwsl_notice("%s: h %p, wsi %p\n", __func__, h, h->wsi);
  737. if (h->wsi) {
  738. lws_callback_on_writable(h->wsi);
  739. return LWSSSSRET_OK;
  740. }
  741. if (h->policy->flags & LWSSSPOLF_SERVER)
  742. return LWSSSSRET_OK;
  743. /*
  744. * there's currently no wsi / connection associated with the ss handle
  745. */
  746. #if defined(LWS_WITH_SYS_SMD)
  747. if (h->policy == &pol_smd) {
  748. /*
  749. * He's an _lws_smd... and no wsi... since we're just going
  750. * to queue it, we could call his tx() right here, but rather
  751. * than surprise him let's set a sul to do it next time around
  752. * the event loop
  753. */
  754. lws_sul_schedule(h->context, 0, &h->u.smd.sul_write,
  755. lws_ss_smd_tx_cb, 1);
  756. return LWSSSSRET_OK;
  757. }
  758. #endif
  759. if (h->seqstate != SSSEQ_IDLE &&
  760. h->seqstate != SSSEQ_DO_RETRY)
  761. return LWSSSSRET_OK;
  762. h->seqstate = SSSEQ_TRY_CONNECT;
  763. r = lws_ss_event_helper(h, LWSSSCS_POLL);
  764. if (r)
  765. return r;
  766. /*
  767. * Retries operate via lws_ss_request_tx(), explicitly ask for a
  768. * reconnection to clear the retry limit
  769. */
  770. r = _lws_ss_client_connect(h, 1);
  771. if (r == LWSSSSRET_DESTROY_ME)
  772. return r;
  773. if (r)
  774. return lws_ss_backoff(h);
  775. return LWSSSSRET_OK;
  776. }
  777. lws_ss_state_return_t
  778. lws_ss_request_tx_len(lws_ss_handle_t *h, unsigned long len)
  779. {
  780. if (h->wsi &&
  781. (h->policy->protocol == LWSSSP_H1 ||
  782. h->policy->protocol == LWSSSP_H2 ||
  783. h->policy->protocol == LWSSSP_WS))
  784. h->wsi->http.writeable_len = len;
  785. else
  786. h->writeable_len = len;
  787. return lws_ss_request_tx(h);
  788. }
  789. /*
  790. * private helpers
  791. */
  792. /* used on context destroy when iterating listed lws_ss on a pt */
  793. int
  794. lws_ss_destroy_dll(struct lws_dll2 *d, void *user)
  795. {
  796. lws_ss_handle_t *h = lws_container_of(d, lws_ss_handle_t, list);
  797. lws_ss_destroy(&h);
  798. return 0;
  799. }
  800. struct lws_sequencer *
  801. lws_ss_get_sequencer(lws_ss_handle_t *h)
  802. {
  803. return h->seq;
  804. }
  805. struct lws_context *
  806. lws_ss_get_context(struct lws_ss_handle *h)
  807. {
  808. return h->context;
  809. }
  810. const char *
  811. lws_ss_rideshare(struct lws_ss_handle *h)
  812. {
  813. if (!h->rideshare)
  814. return h->policy->streamtype;
  815. return h->rideshare->streamtype;
  816. }
  817. int
  818. lws_ss_add_peer_tx_credit(struct lws_ss_handle *h, int32_t bump)
  819. {
  820. const struct ss_pcols *ssp;
  821. ssp = ss_pcols[(int)h->policy->protocol];
  822. if (h->wsi && ssp && ssp->tx_cr_add)
  823. return ssp->tx_cr_add(h, bump);
  824. return 0;
  825. }
  826. int
  827. lws_ss_get_est_peer_tx_credit(struct lws_ss_handle *h)
  828. {
  829. const struct ss_pcols *ssp;
  830. ssp = ss_pcols[(int)h->policy->protocol];
  831. if (h->wsi && ssp && ssp->tx_cr_add)
  832. return ssp->tx_cr_est(h);
  833. return 0;
  834. }
  835. /*
  836. * protocol-independent handler for ss timeout
  837. */
  838. static void
  839. lws_ss_to_cb(lws_sorted_usec_list_t *sul)
  840. {
  841. lws_ss_handle_t *h = lws_container_of(sul, lws_ss_handle_t, sul_timeout);
  842. lws_ss_state_return_t r;
  843. lwsl_info("%s: ss %p timeout fired\n", __func__, h);
  844. r = lws_ss_event_helper(h, LWSSSCS_TIMEOUT);
  845. if (r == LWSSSSRET_DESTROY_ME) {
  846. if (h->wsi)
  847. lws_set_timeout(h->wsi, 1, LWS_TO_KILL_ASYNC);
  848. _lws_ss_handle_state_ret(r, NULL, &h);
  849. }
  850. }
  851. void
  852. lws_ss_start_timeout(struct lws_ss_handle *h, unsigned int timeout_ms)
  853. {
  854. if (!timeout_ms && !h->policy->timeout_ms)
  855. return;
  856. lws_sul_schedule(h->context, 0, &h->sul_timeout, lws_ss_to_cb,
  857. (timeout_ms ? timeout_ms : h->policy->timeout_ms) *
  858. LWS_US_PER_MS);
  859. }
  860. void
  861. lws_ss_cancel_timeout(struct lws_ss_handle *h)
  862. {
  863. lws_sul_cancel(&h->sul_timeout);
  864. }
  865. void
  866. lws_ss_change_handlers(struct lws_ss_handle *h,
  867. lws_ss_state_return_t (*rx)(void *userobj, const uint8_t *buf,
  868. size_t len, int flags),
  869. lws_ss_state_return_t (*tx)(void *userobj, lws_ss_tx_ordinal_t ord,
  870. uint8_t *buf, size_t *len, int *flags),
  871. lws_ss_state_return_t (*state)(void *userobj, void *h_src /* ss handle type */,
  872. lws_ss_constate_t state,
  873. lws_ss_tx_ordinal_t ack))
  874. {
  875. if (rx)
  876. h->info.rx = rx;
  877. if (tx)
  878. h->info.tx = tx;
  879. if (state)
  880. h->info.state = state;
  881. }