xref: /aosp_15_r20/external/libwebsockets/lib/secure-streams/secure-streams.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker  * libwebsockets - small server side websockets and web server implementation
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Copyright (C) 2019 - 2021 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker  * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker  * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker  *
13*1c60b9acSAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker  *
16*1c60b9acSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker  * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker  */
24*1c60b9acSAndroid Build Coastguard Worker 
25*1c60b9acSAndroid Build Coastguard Worker #include <private-lib-core.h>
26*1c60b9acSAndroid Build Coastguard Worker 
27*1c60b9acSAndroid Build Coastguard Worker static const struct ss_pcols *ss_pcols[] = {
28*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_H1)
29*1c60b9acSAndroid Build Coastguard Worker 	&ss_pcol_h1,		/* LWSSSP_H1 */
30*1c60b9acSAndroid Build Coastguard Worker #else
31*1c60b9acSAndroid Build Coastguard Worker 	NULL,
32*1c60b9acSAndroid Build Coastguard Worker #endif
33*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_H2)
34*1c60b9acSAndroid Build Coastguard Worker 	&ss_pcol_h2,		/* LWSSSP_H2 */
35*1c60b9acSAndroid Build Coastguard Worker #else
36*1c60b9acSAndroid Build Coastguard Worker 	NULL,
37*1c60b9acSAndroid Build Coastguard Worker #endif
38*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_WS)
39*1c60b9acSAndroid Build Coastguard Worker 	&ss_pcol_ws,		/* LWSSSP_WS */
40*1c60b9acSAndroid Build Coastguard Worker #else
41*1c60b9acSAndroid Build Coastguard Worker 	NULL,
42*1c60b9acSAndroid Build Coastguard Worker #endif
43*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_MQTT)
44*1c60b9acSAndroid Build Coastguard Worker 	&ss_pcol_mqtt,		/* LWSSSP_MQTT */
45*1c60b9acSAndroid Build Coastguard Worker #else
46*1c60b9acSAndroid Build Coastguard Worker 	NULL,
47*1c60b9acSAndroid Build Coastguard Worker #endif
48*1c60b9acSAndroid Build Coastguard Worker 	&ss_pcol_raw,		/* LWSSSP_RAW */
49*1c60b9acSAndroid Build Coastguard Worker 	NULL,
50*1c60b9acSAndroid Build Coastguard Worker };
51*1c60b9acSAndroid Build Coastguard Worker 
52*1c60b9acSAndroid Build Coastguard Worker static const char *state_names[] = {
53*1c60b9acSAndroid Build Coastguard Worker 	"(unset)",
54*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_CREATING",
55*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_DISCONNECTED",
56*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_UNREACHABLE",
57*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_AUTH_FAILED",
58*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_CONNECTED",
59*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_CONNECTING",
60*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_DESTROYING",
61*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_POLL",
62*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_ALL_RETRIES_FAILED",
63*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_QOS_ACK_REMOTE",
64*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_QOS_NACK_REMOTE",
65*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_QOS_ACK_LOCAL",
66*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_QOS_NACK_LOCAL",
67*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_TIMEOUT",
68*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_SERVER_TXN",
69*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_SERVER_UPGRADE",
70*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_EVENT_WAIT_CANCELLED",
71*1c60b9acSAndroid Build Coastguard Worker 	"LWSSSCS_UPSTREAM_LINK_RETRY",
72*1c60b9acSAndroid Build Coastguard Worker };
73*1c60b9acSAndroid Build Coastguard Worker 
74*1c60b9acSAndroid Build Coastguard Worker /*
75*1c60b9acSAndroid Build Coastguard Worker  * For each "current state", set bit offsets for valid "next states".
76*1c60b9acSAndroid Build Coastguard Worker  *
77*1c60b9acSAndroid Build Coastguard Worker  * Since there are complicated ways to arrive at state transitions like proxying
78*1c60b9acSAndroid Build Coastguard Worker  * and asynchronous destruction etc, so we monitor the state transitions we are
79*1c60b9acSAndroid Build Coastguard Worker  * giving the ss user code to ensure we never deliver illegal state transitions
80*1c60b9acSAndroid Build Coastguard Worker  * (because we will assert if we have bugs that do it)
81*1c60b9acSAndroid Build Coastguard Worker  */
82*1c60b9acSAndroid Build Coastguard Worker 
83*1c60b9acSAndroid Build Coastguard Worker const uint32_t ss_state_txn_validity[] = {
84*1c60b9acSAndroid Build Coastguard Worker 
85*1c60b9acSAndroid Build Coastguard Worker 	/* if we was last in this state...  we can legally go to these states */
86*1c60b9acSAndroid Build Coastguard Worker 
87*1c60b9acSAndroid Build Coastguard Worker 	[0]				= (1 << LWSSSCS_CREATING) |
88*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DESTROYING),
89*1c60b9acSAndroid Build Coastguard Worker 
90*1c60b9acSAndroid Build Coastguard Worker 	[LWSSSCS_CREATING]		= (1 << LWSSSCS_CONNECTING) |
91*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_TIMEOUT) |
92*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_POLL) |
93*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_SERVER_UPGRADE) |
94*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DESTROYING),
95*1c60b9acSAndroid Build Coastguard Worker 
96*1c60b9acSAndroid Build Coastguard Worker 	[LWSSSCS_DISCONNECTED]		= (1 << LWSSSCS_CONNECTING) |
97*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_TIMEOUT) |
98*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_POLL) |
99*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DESTROYING),
100*1c60b9acSAndroid Build Coastguard Worker 
101*1c60b9acSAndroid Build Coastguard Worker 	[LWSSSCS_UNREACHABLE]		= (1 << LWSSSCS_ALL_RETRIES_FAILED) |
102*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_TIMEOUT) |
103*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_POLL) |
104*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_CONNECTING) |
105*1c60b9acSAndroid Build Coastguard Worker 					  /* win conn failure > retry > succ */
106*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_CONNECTED) |
107*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DESTROYING),
108*1c60b9acSAndroid Build Coastguard Worker 
109*1c60b9acSAndroid Build Coastguard Worker 	[LWSSSCS_AUTH_FAILED]		= (1 << LWSSSCS_ALL_RETRIES_FAILED) |
110*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_TIMEOUT) |
111*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_CONNECTING) |
112*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DESTROYING),
113*1c60b9acSAndroid Build Coastguard Worker 
114*1c60b9acSAndroid Build Coastguard Worker 	[LWSSSCS_CONNECTED]		= (1 << LWSSSCS_SERVER_UPGRADE) |
115*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_SERVER_TXN) |
116*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_AUTH_FAILED) |
117*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_QOS_ACK_REMOTE) |
118*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_QOS_NACK_REMOTE) |
119*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_QOS_ACK_LOCAL) |
120*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_QOS_NACK_LOCAL) |
121*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DISCONNECTED) |
122*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_TIMEOUT) |
123*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_POLL) | /* proxy retry */
124*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DESTROYING),
125*1c60b9acSAndroid Build Coastguard Worker 
126*1c60b9acSAndroid Build Coastguard Worker 	[LWSSSCS_CONNECTING]		= (1 << LWSSSCS_UNREACHABLE) |
127*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_AUTH_FAILED) |
128*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_CONNECTING) |
129*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_CONNECTED) |
130*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_TIMEOUT) |
131*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_POLL) |
132*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DISCONNECTED) | /* proxy retry */
133*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DESTROYING),
134*1c60b9acSAndroid Build Coastguard Worker 
135*1c60b9acSAndroid Build Coastguard Worker 	[LWSSSCS_DESTROYING]		= 0,
136*1c60b9acSAndroid Build Coastguard Worker 
137*1c60b9acSAndroid Build Coastguard Worker 	[LWSSSCS_POLL]			= (1 << LWSSSCS_CONNECTING) |
138*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_TIMEOUT) |
139*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DESTROYING),
140*1c60b9acSAndroid Build Coastguard Worker 
141*1c60b9acSAndroid Build Coastguard Worker 	[LWSSSCS_ALL_RETRIES_FAILED]	= (1 << LWSSSCS_CONNECTING) |
142*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_TIMEOUT) |
143*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DESTROYING),
144*1c60b9acSAndroid Build Coastguard Worker 
145*1c60b9acSAndroid Build Coastguard Worker 	[LWSSSCS_QOS_ACK_REMOTE]	= (1 << LWSSSCS_DISCONNECTED) |
146*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_TIMEOUT) |
147*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_MQTT)
148*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_QOS_ACK_REMOTE) |
149*1c60b9acSAndroid Build Coastguard Worker #endif
150*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DESTROYING),
151*1c60b9acSAndroid Build Coastguard Worker 
152*1c60b9acSAndroid Build Coastguard Worker 	[LWSSSCS_QOS_NACK_REMOTE]	= (1 << LWSSSCS_DISCONNECTED) |
153*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_TIMEOUT) |
154*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DESTROYING),
155*1c60b9acSAndroid Build Coastguard Worker 
156*1c60b9acSAndroid Build Coastguard Worker 	[LWSSSCS_QOS_ACK_LOCAL]		= (1 << LWSSSCS_DISCONNECTED) |
157*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_TIMEOUT) |
158*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DESTROYING),
159*1c60b9acSAndroid Build Coastguard Worker 
160*1c60b9acSAndroid Build Coastguard Worker 	[LWSSSCS_QOS_NACK_LOCAL]	= (1 << LWSSSCS_DESTROYING) |
161*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_TIMEOUT),
162*1c60b9acSAndroid Build Coastguard Worker 
163*1c60b9acSAndroid Build Coastguard Worker 	/* he can get the timeout at any point and take no action... */
164*1c60b9acSAndroid Build Coastguard Worker 	[LWSSSCS_TIMEOUT]		= (1 << LWSSSCS_CONNECTING) |
165*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_CONNECTED) |
166*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_QOS_ACK_REMOTE) |
167*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_QOS_NACK_REMOTE) |
168*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_POLL) |
169*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_TIMEOUT) |
170*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DISCONNECTED) |
171*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_UNREACHABLE) |
172*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DESTROYING),
173*1c60b9acSAndroid Build Coastguard Worker 
174*1c60b9acSAndroid Build Coastguard Worker 	[LWSSSCS_SERVER_TXN]		= (1 << LWSSSCS_DISCONNECTED) |
175*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_TIMEOUT) |
176*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DESTROYING),
177*1c60b9acSAndroid Build Coastguard Worker 
178*1c60b9acSAndroid Build Coastguard Worker 	[LWSSSCS_SERVER_UPGRADE]	= (1 << LWSSSCS_SERVER_TXN) |
179*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_TIMEOUT) |
180*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DISCONNECTED) |
181*1c60b9acSAndroid Build Coastguard Worker 					  (1 << LWSSSCS_DESTROYING),
182*1c60b9acSAndroid Build Coastguard Worker };
183*1c60b9acSAndroid Build Coastguard Worker 
184*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_CONMON)
185*1c60b9acSAndroid Build Coastguard Worker 
186*1c60b9acSAndroid Build Coastguard Worker /*
187*1c60b9acSAndroid Build Coastguard Worker  * Convert any conmon data to JSON and attach to the ss handle.
188*1c60b9acSAndroid Build Coastguard Worker  */
189*1c60b9acSAndroid Build Coastguard Worker 
190*1c60b9acSAndroid Build Coastguard Worker lws_ss_state_return_t
lws_conmon_ss_json(lws_ss_handle_t * h)191*1c60b9acSAndroid Build Coastguard Worker lws_conmon_ss_json(lws_ss_handle_t *h)
192*1c60b9acSAndroid Build Coastguard Worker {
193*1c60b9acSAndroid Build Coastguard Worker 	char ads[48], *end, *buf, *obuf;
194*1c60b9acSAndroid Build Coastguard Worker 	const struct addrinfo *ai;
195*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_state_return_t ret = LWSSSSRET_OK;
196*1c60b9acSAndroid Build Coastguard Worker 	struct lws_conmon cm;
197*1c60b9acSAndroid Build Coastguard Worker 	size_t len = 500;
198*1c60b9acSAndroid Build Coastguard Worker 
199*1c60b9acSAndroid Build Coastguard Worker 	if (!h->policy || !(h->policy->flags & LWSSSPOLF_PERF) || !h->wsi ||
200*1c60b9acSAndroid Build Coastguard Worker 	    h->wsi->perf_done)
201*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_OK;
202*1c60b9acSAndroid Build Coastguard Worker 
203*1c60b9acSAndroid Build Coastguard Worker 	if (h->conmon_json)
204*1c60b9acSAndroid Build Coastguard Worker 		lws_free_set_NULL(h->conmon_json);
205*1c60b9acSAndroid Build Coastguard Worker 
206*1c60b9acSAndroid Build Coastguard Worker 	h->conmon_json = lws_malloc(len, __func__);
207*1c60b9acSAndroid Build Coastguard Worker 	if (!h->conmon_json)
208*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_OK;
209*1c60b9acSAndroid Build Coastguard Worker 
210*1c60b9acSAndroid Build Coastguard Worker 	obuf = buf = h->conmon_json;
211*1c60b9acSAndroid Build Coastguard Worker 	end = buf + len - 1;
212*1c60b9acSAndroid Build Coastguard Worker 
213*1c60b9acSAndroid Build Coastguard Worker 	lws_conmon_wsi_take(h->wsi, &cm);
214*1c60b9acSAndroid Build Coastguard Worker 
215*1c60b9acSAndroid Build Coastguard Worker 	lws_sa46_write_numeric_address(&cm.peer46, ads, sizeof(ads));
216*1c60b9acSAndroid Build Coastguard Worker 	buf += lws_snprintf(buf, lws_ptr_diff_size_t(end, buf),
217*1c60b9acSAndroid Build Coastguard Worker 		     "{\"peer\":\"%s\","
218*1c60b9acSAndroid Build Coastguard Worker 		      "\"dns_us\":%u,"
219*1c60b9acSAndroid Build Coastguard Worker 		      "\"dns_disp\":%u,"
220*1c60b9acSAndroid Build Coastguard Worker 		      "\"sockconn_us\":%u,"
221*1c60b9acSAndroid Build Coastguard Worker 		      "\"tls_us\":%u,"
222*1c60b9acSAndroid Build Coastguard Worker 		      "\"txn_resp_us\":%u,"
223*1c60b9acSAndroid Build Coastguard Worker 		      "\"dns\":[",
224*1c60b9acSAndroid Build Coastguard Worker 		    ads,
225*1c60b9acSAndroid Build Coastguard Worker 		    (unsigned int)cm.ciu_dns,
226*1c60b9acSAndroid Build Coastguard Worker 		    (unsigned int)cm.dns_disposition,
227*1c60b9acSAndroid Build Coastguard Worker 		    (unsigned int)cm.ciu_sockconn,
228*1c60b9acSAndroid Build Coastguard Worker 		    (unsigned int)cm.ciu_tls,
229*1c60b9acSAndroid Build Coastguard Worker 		    (unsigned int)cm.ciu_txn_resp);
230*1c60b9acSAndroid Build Coastguard Worker 
231*1c60b9acSAndroid Build Coastguard Worker 	ai = cm.dns_results_copy;
232*1c60b9acSAndroid Build Coastguard Worker 	while (ai) {
233*1c60b9acSAndroid Build Coastguard Worker 		lws_sa46_write_numeric_address((lws_sockaddr46 *)ai->ai_addr, ads, sizeof(ads));
234*1c60b9acSAndroid Build Coastguard Worker 		buf += lws_snprintf(buf, lws_ptr_diff_size_t(end, buf), "\"%s\"", ads);
235*1c60b9acSAndroid Build Coastguard Worker 		if (ai->ai_next && buf < end - 2)
236*1c60b9acSAndroid Build Coastguard Worker 			*buf++ = ',';
237*1c60b9acSAndroid Build Coastguard Worker 		ai = ai->ai_next;
238*1c60b9acSAndroid Build Coastguard Worker 	}
239*1c60b9acSAndroid Build Coastguard Worker 
240*1c60b9acSAndroid Build Coastguard Worker 	buf += lws_snprintf(buf, lws_ptr_diff_size_t(end, buf), "]");
241*1c60b9acSAndroid Build Coastguard Worker 
242*1c60b9acSAndroid Build Coastguard Worker 	switch (cm.pcol) {
243*1c60b9acSAndroid Build Coastguard Worker 	case LWSCONMON_PCOL_HTTP:
244*1c60b9acSAndroid Build Coastguard Worker 		buf += lws_snprintf(buf, lws_ptr_diff_size_t(end, buf),
245*1c60b9acSAndroid Build Coastguard Worker 			   ",\"prot_specific\":{\"protocol\":\"http\",\"resp\":%u}",
246*1c60b9acSAndroid Build Coastguard Worker 			   (unsigned int)cm.protocol_specific.http.response);
247*1c60b9acSAndroid Build Coastguard Worker 		break;
248*1c60b9acSAndroid Build Coastguard Worker 	default:
249*1c60b9acSAndroid Build Coastguard Worker 		break;
250*1c60b9acSAndroid Build Coastguard Worker 	}
251*1c60b9acSAndroid Build Coastguard Worker 
252*1c60b9acSAndroid Build Coastguard Worker 	buf += lws_snprintf(buf, lws_ptr_diff_size_t(end, buf), "}");
253*1c60b9acSAndroid Build Coastguard Worker 
254*1c60b9acSAndroid Build Coastguard Worker 	/*
255*1c60b9acSAndroid Build Coastguard Worker 	 * This destroys the DNS list in the lws_conmon that we took
256*1c60b9acSAndroid Build Coastguard Worker 	 * responsibility for when we used lws_conmon_wsi_take()
257*1c60b9acSAndroid Build Coastguard Worker 	 */
258*1c60b9acSAndroid Build Coastguard Worker 
259*1c60b9acSAndroid Build Coastguard Worker 	lws_conmon_release(&cm);
260*1c60b9acSAndroid Build Coastguard Worker 
261*1c60b9acSAndroid Build Coastguard Worker 	h->conmon_len = (uint16_t)lws_ptr_diff(buf, obuf);
262*1c60b9acSAndroid Build Coastguard Worker 
263*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
264*1c60b9acSAndroid Build Coastguard Worker 	if (h->proxy_onward) {
265*1c60b9acSAndroid Build Coastguard Worker 
266*1c60b9acSAndroid Build Coastguard Worker 		/*
267*1c60b9acSAndroid Build Coastguard Worker 		 * ask to forward it on the proxy link
268*1c60b9acSAndroid Build Coastguard Worker 		 */
269*1c60b9acSAndroid Build Coastguard Worker 
270*1c60b9acSAndroid Build Coastguard Worker 		ss_proxy_onward_link_req_writeable(h);
271*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_OK;
272*1c60b9acSAndroid Build Coastguard Worker 	}
273*1c60b9acSAndroid Build Coastguard Worker #endif
274*1c60b9acSAndroid Build Coastguard Worker 
275*1c60b9acSAndroid Build Coastguard Worker 	/*
276*1c60b9acSAndroid Build Coastguard Worker 	 * We can deliver it directly
277*1c60b9acSAndroid Build Coastguard Worker 	 */
278*1c60b9acSAndroid Build Coastguard Worker 
279*1c60b9acSAndroid Build Coastguard Worker 	if (h->info.rx)
280*1c60b9acSAndroid Build Coastguard Worker 		ret = h->info.rx(ss_to_userobj(h), (uint8_t *)h->conmon_json,
281*1c60b9acSAndroid Build Coastguard Worker 				 (unsigned int)h->conmon_len,
282*1c60b9acSAndroid Build Coastguard Worker 				 (int)(LWSSS_FLAG_SOM | LWSSS_FLAG_EOM |
283*1c60b9acSAndroid Build Coastguard Worker 						 LWSSS_FLAG_PERF_JSON));
284*1c60b9acSAndroid Build Coastguard Worker 
285*1c60b9acSAndroid Build Coastguard Worker 	lws_free_set_NULL(h->conmon_json);
286*1c60b9acSAndroid Build Coastguard Worker 
287*1c60b9acSAndroid Build Coastguard Worker 	return ret;
288*1c60b9acSAndroid Build Coastguard Worker }
289*1c60b9acSAndroid Build Coastguard Worker #endif
290*1c60b9acSAndroid Build Coastguard Worker 
291*1c60b9acSAndroid Build Coastguard Worker int
lws_ss_check_next_state(lws_lifecycle_t * lc,uint8_t * prevstate,lws_ss_constate_t cs)292*1c60b9acSAndroid Build Coastguard Worker lws_ss_check_next_state(lws_lifecycle_t *lc, uint8_t *prevstate,
293*1c60b9acSAndroid Build Coastguard Worker 			lws_ss_constate_t cs)
294*1c60b9acSAndroid Build Coastguard Worker {
295*1c60b9acSAndroid Build Coastguard Worker 	if (cs >= LWSSSCS_USER_BASE ||
296*1c60b9acSAndroid Build Coastguard Worker 	    cs == LWSSSCS_EVENT_WAIT_CANCELLED ||
297*1c60b9acSAndroid Build Coastguard Worker 	    cs == LWSSSCS_SERVER_TXN ||
298*1c60b9acSAndroid Build Coastguard Worker 	    cs == LWSSSCS_UPSTREAM_LINK_RETRY)
299*1c60b9acSAndroid Build Coastguard Worker 		/*
300*1c60b9acSAndroid Build Coastguard Worker 		 * we can't judge user or transient states, leave the old state
301*1c60b9acSAndroid Build Coastguard Worker 		 * and just wave them through
302*1c60b9acSAndroid Build Coastguard Worker 		 */
303*1c60b9acSAndroid Build Coastguard Worker 		return 0;
304*1c60b9acSAndroid Build Coastguard Worker 
305*1c60b9acSAndroid Build Coastguard Worker 	if (cs >= LWS_ARRAY_SIZE(ss_state_txn_validity)) {
306*1c60b9acSAndroid Build Coastguard Worker 		/* we don't recognize this state as usable */
307*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: %s: bad new state %u\n", __func__, lc->gutag, cs);
308*1c60b9acSAndroid Build Coastguard Worker 		assert(0);
309*1c60b9acSAndroid Build Coastguard Worker 		return 1;
310*1c60b9acSAndroid Build Coastguard Worker 	}
311*1c60b9acSAndroid Build Coastguard Worker 
312*1c60b9acSAndroid Build Coastguard Worker 	if (*prevstate >= LWS_ARRAY_SIZE(ss_state_txn_validity)) {
313*1c60b9acSAndroid Build Coastguard Worker 		/* existing state is broken */
314*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: %s: bad existing state %u\n", __func__,
315*1c60b9acSAndroid Build Coastguard Worker 			 lc->gutag, (unsigned int)*prevstate);
316*1c60b9acSAndroid Build Coastguard Worker 		assert(0);
317*1c60b9acSAndroid Build Coastguard Worker 		return 1;
318*1c60b9acSAndroid Build Coastguard Worker 	}
319*1c60b9acSAndroid Build Coastguard Worker 
320*1c60b9acSAndroid Build Coastguard Worker 	if (ss_state_txn_validity[*prevstate] & (1u << cs)) {
321*1c60b9acSAndroid Build Coastguard Worker 
322*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: %s: %s -> %s\n", __func__, lc->gutag,
323*1c60b9acSAndroid Build Coastguard Worker 			    lws_ss_state_name((int)*prevstate),
324*1c60b9acSAndroid Build Coastguard Worker 			    lws_ss_state_name((int)cs));
325*1c60b9acSAndroid Build Coastguard Worker 
326*1c60b9acSAndroid Build Coastguard Worker 		/* this is explicitly allowed, update old state to new */
327*1c60b9acSAndroid Build Coastguard Worker 		*prevstate = (uint8_t)cs;
328*1c60b9acSAndroid Build Coastguard Worker 
329*1c60b9acSAndroid Build Coastguard Worker 		return 0;
330*1c60b9acSAndroid Build Coastguard Worker 	}
331*1c60b9acSAndroid Build Coastguard Worker 
332*1c60b9acSAndroid Build Coastguard Worker 	lwsl_err("%s: %s: transition from %s -> %s is illegal\n", __func__,
333*1c60b9acSAndroid Build Coastguard Worker 		 lc->gutag, lws_ss_state_name((int)*prevstate),
334*1c60b9acSAndroid Build Coastguard Worker 		 lws_ss_state_name((int)cs));
335*1c60b9acSAndroid Build Coastguard Worker 
336*1c60b9acSAndroid Build Coastguard Worker 	assert(0);
337*1c60b9acSAndroid Build Coastguard Worker 
338*1c60b9acSAndroid Build Coastguard Worker 	return 1;
339*1c60b9acSAndroid Build Coastguard Worker }
340*1c60b9acSAndroid Build Coastguard Worker 
341*1c60b9acSAndroid Build Coastguard Worker int
lws_ss_check_next_state_ss(lws_ss_handle_t * ss,uint8_t * prevstate,lws_ss_constate_t cs)342*1c60b9acSAndroid Build Coastguard Worker lws_ss_check_next_state_ss(lws_ss_handle_t *ss, uint8_t *prevstate,
343*1c60b9acSAndroid Build Coastguard Worker 			   lws_ss_constate_t cs)
344*1c60b9acSAndroid Build Coastguard Worker {
345*1c60b9acSAndroid Build Coastguard Worker 	if (cs >= LWSSSCS_USER_BASE ||
346*1c60b9acSAndroid Build Coastguard Worker 	    cs == LWSSSCS_EVENT_WAIT_CANCELLED ||
347*1c60b9acSAndroid Build Coastguard Worker 	    cs == LWSSSCS_UPSTREAM_LINK_RETRY)
348*1c60b9acSAndroid Build Coastguard Worker 		/*
349*1c60b9acSAndroid Build Coastguard Worker 		 * we can't judge user or transient states, leave the old state
350*1c60b9acSAndroid Build Coastguard Worker 		 * and just wave them through
351*1c60b9acSAndroid Build Coastguard Worker 		 */
352*1c60b9acSAndroid Build Coastguard Worker 		return 0;
353*1c60b9acSAndroid Build Coastguard Worker 
354*1c60b9acSAndroid Build Coastguard Worker 	if (cs >= LWS_ARRAY_SIZE(ss_state_txn_validity)) {
355*1c60b9acSAndroid Build Coastguard Worker 		/* we don't recognize this state as usable */
356*1c60b9acSAndroid Build Coastguard Worker 		lwsl_ss_err(ss, "bad new state %u", cs);
357*1c60b9acSAndroid Build Coastguard Worker 		assert(0);
358*1c60b9acSAndroid Build Coastguard Worker 		return 1;
359*1c60b9acSAndroid Build Coastguard Worker 	}
360*1c60b9acSAndroid Build Coastguard Worker 
361*1c60b9acSAndroid Build Coastguard Worker 	if (*prevstate >= LWS_ARRAY_SIZE(ss_state_txn_validity)) {
362*1c60b9acSAndroid Build Coastguard Worker 		/* existing state is broken */
363*1c60b9acSAndroid Build Coastguard Worker 		lwsl_ss_err(ss, "bad existing state %u",
364*1c60b9acSAndroid Build Coastguard Worker 				(unsigned int)*prevstate);
365*1c60b9acSAndroid Build Coastguard Worker 		assert(0);
366*1c60b9acSAndroid Build Coastguard Worker 		return 1;
367*1c60b9acSAndroid Build Coastguard Worker 	}
368*1c60b9acSAndroid Build Coastguard Worker 
369*1c60b9acSAndroid Build Coastguard Worker 	if (ss_state_txn_validity[*prevstate] & (1u << cs)) {
370*1c60b9acSAndroid Build Coastguard Worker 
371*1c60b9acSAndroid Build Coastguard Worker 		lwsl_ss_notice(ss, "%s -> %s",
372*1c60b9acSAndroid Build Coastguard Worker 			       lws_ss_state_name((int)*prevstate),
373*1c60b9acSAndroid Build Coastguard Worker 			       lws_ss_state_name((int)cs));
374*1c60b9acSAndroid Build Coastguard Worker 
375*1c60b9acSAndroid Build Coastguard Worker 		/* this is explicitly allowed, update old state to new */
376*1c60b9acSAndroid Build Coastguard Worker 		*prevstate = (uint8_t)cs;
377*1c60b9acSAndroid Build Coastguard Worker 
378*1c60b9acSAndroid Build Coastguard Worker 		return 0;
379*1c60b9acSAndroid Build Coastguard Worker 	}
380*1c60b9acSAndroid Build Coastguard Worker 
381*1c60b9acSAndroid Build Coastguard Worker 	lwsl_ss_err(ss, "transition from %s -> %s is illegal",
382*1c60b9acSAndroid Build Coastguard Worker 		    lws_ss_state_name((int)*prevstate),
383*1c60b9acSAndroid Build Coastguard Worker 		    lws_ss_state_name((int)cs));
384*1c60b9acSAndroid Build Coastguard Worker 
385*1c60b9acSAndroid Build Coastguard Worker 	assert(0);
386*1c60b9acSAndroid Build Coastguard Worker 
387*1c60b9acSAndroid Build Coastguard Worker 	return 1;
388*1c60b9acSAndroid Build Coastguard Worker }
389*1c60b9acSAndroid Build Coastguard Worker 
390*1c60b9acSAndroid Build Coastguard Worker const char *
lws_ss_state_name(int state)391*1c60b9acSAndroid Build Coastguard Worker lws_ss_state_name(int state)
392*1c60b9acSAndroid Build Coastguard Worker {
393*1c60b9acSAndroid Build Coastguard Worker 	if (state >= LWSSSCS_USER_BASE)
394*1c60b9acSAndroid Build Coastguard Worker 		return "user state";
395*1c60b9acSAndroid Build Coastguard Worker 
396*1c60b9acSAndroid Build Coastguard Worker 	if (state >= (int)LWS_ARRAY_SIZE(state_names))
397*1c60b9acSAndroid Build Coastguard Worker 		return "unknown";
398*1c60b9acSAndroid Build Coastguard Worker 
399*1c60b9acSAndroid Build Coastguard Worker 	return state_names[state];
400*1c60b9acSAndroid Build Coastguard Worker }
401*1c60b9acSAndroid Build Coastguard Worker 
402*1c60b9acSAndroid Build Coastguard Worker lws_ss_state_return_t
lws_ss_event_helper(lws_ss_handle_t * h,lws_ss_constate_t cs)403*1c60b9acSAndroid Build Coastguard Worker lws_ss_event_helper(lws_ss_handle_t *h, lws_ss_constate_t cs)
404*1c60b9acSAndroid Build Coastguard Worker {
405*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_state_return_t r;
406*1c60b9acSAndroid Build Coastguard Worker 
407*1c60b9acSAndroid Build Coastguard Worker 	if (!h)
408*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_OK;
409*1c60b9acSAndroid Build Coastguard Worker 
410*1c60b9acSAndroid Build Coastguard Worker 	if (lws_ss_check_next_state_ss(h, &h->prev_ss_state, cs))
411*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_DESTROY_ME;
412*1c60b9acSAndroid Build Coastguard Worker 
413*1c60b9acSAndroid Build Coastguard Worker 	if (cs == LWSSSCS_CONNECTED)
414*1c60b9acSAndroid Build Coastguard Worker 		h->ss_dangling_connected = 1;
415*1c60b9acSAndroid Build Coastguard Worker 	if (cs == LWSSSCS_DISCONNECTED)
416*1c60b9acSAndroid Build Coastguard Worker 		h->ss_dangling_connected = 0;
417*1c60b9acSAndroid Build Coastguard Worker 
418*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SEQUENCER)
419*1c60b9acSAndroid Build Coastguard Worker 	/*
420*1c60b9acSAndroid Build Coastguard Worker 	 * A parent sequencer for the ss is optional, if we have one, keep it
421*1c60b9acSAndroid Build Coastguard Worker 	 * informed of state changes on the ss connection
422*1c60b9acSAndroid Build Coastguard Worker 	 */
423*1c60b9acSAndroid Build Coastguard Worker 	if (h->seq && cs != LWSSSCS_DESTROYING)
424*1c60b9acSAndroid Build Coastguard Worker 		lws_seq_queue_event(h->seq, LWSSEQ_SS_STATE_BASE + cs,
425*1c60b9acSAndroid Build Coastguard Worker 				    (void *)h, NULL);
426*1c60b9acSAndroid Build Coastguard Worker #endif
427*1c60b9acSAndroid Build Coastguard Worker 
428*1c60b9acSAndroid Build Coastguard Worker 	if (h->info.state) {
429*1c60b9acSAndroid Build Coastguard Worker 		h->h_in_svc = h;
430*1c60b9acSAndroid Build Coastguard Worker 		r = h->info.state(ss_to_userobj(h), NULL, cs,
431*1c60b9acSAndroid Build Coastguard Worker 			cs == LWSSSCS_UNREACHABLE &&
432*1c60b9acSAndroid Build Coastguard Worker 			h->wsi && h->wsi->dns_reachability);
433*1c60b9acSAndroid Build Coastguard Worker 		h->h_in_svc = NULL;
434*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
435*1c60b9acSAndroid Build Coastguard Worker 		if ((h->info.flags & LWSSSINFLAGS_ACCEPTED) &&
436*1c60b9acSAndroid Build Coastguard Worker 		    cs == LWSSSCS_DISCONNECTED)
437*1c60b9acSAndroid Build Coastguard Worker 			r = LWSSSSRET_DESTROY_ME;
438*1c60b9acSAndroid Build Coastguard Worker #endif
439*1c60b9acSAndroid Build Coastguard Worker 		return r;
440*1c60b9acSAndroid Build Coastguard Worker 	}
441*1c60b9acSAndroid Build Coastguard Worker 
442*1c60b9acSAndroid Build Coastguard Worker 	return LWSSSSRET_OK;
443*1c60b9acSAndroid Build Coastguard Worker }
444*1c60b9acSAndroid Build Coastguard Worker 
445*1c60b9acSAndroid Build Coastguard Worker int
_lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(lws_ss_state_return_t r,struct lws * wsi,lws_ss_handle_t ** ph)446*1c60b9acSAndroid Build Coastguard Worker _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(lws_ss_state_return_t r, struct lws *wsi,
447*1c60b9acSAndroid Build Coastguard Worker 			 lws_ss_handle_t **ph)
448*1c60b9acSAndroid Build Coastguard Worker {
449*1c60b9acSAndroid Build Coastguard Worker 	if (r == LWSSSSRET_DESTROY_ME) {
450*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: DESTROY ME: %s, %s\n", __func__,
451*1c60b9acSAndroid Build Coastguard Worker 				lws_wsi_tag(wsi), lws_ss_tag(*ph));
452*1c60b9acSAndroid Build Coastguard Worker 		if (wsi) {
453*1c60b9acSAndroid Build Coastguard Worker 			lws_set_opaque_user_data(wsi, NULL);
454*1c60b9acSAndroid Build Coastguard Worker 			lws_set_timeout(wsi, 1, LWS_TO_KILL_ASYNC);
455*1c60b9acSAndroid Build Coastguard Worker 		} else {
456*1c60b9acSAndroid Build Coastguard Worker 			if ((*ph)->wsi) {
457*1c60b9acSAndroid Build Coastguard Worker 				lws_set_opaque_user_data((*ph)->wsi, NULL);
458*1c60b9acSAndroid Build Coastguard Worker 				lws_set_timeout((*ph)->wsi, 1, LWS_TO_KILL_ASYNC);
459*1c60b9acSAndroid Build Coastguard Worker 			}
460*1c60b9acSAndroid Build Coastguard Worker 		}
461*1c60b9acSAndroid Build Coastguard Worker 		(*ph)->wsi = NULL;
462*1c60b9acSAndroid Build Coastguard Worker 		lws_ss_destroy(ph);
463*1c60b9acSAndroid Build Coastguard Worker 	}
464*1c60b9acSAndroid Build Coastguard Worker 
465*1c60b9acSAndroid Build Coastguard Worker 	return -1; /* close connection */
466*1c60b9acSAndroid Build Coastguard Worker }
467*1c60b9acSAndroid Build Coastguard Worker 
468*1c60b9acSAndroid Build Coastguard Worker static void
lws_ss_timeout_sul_check_cb(lws_sorted_usec_list_t * sul)469*1c60b9acSAndroid Build Coastguard Worker lws_ss_timeout_sul_check_cb(lws_sorted_usec_list_t *sul)
470*1c60b9acSAndroid Build Coastguard Worker {
471*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_state_return_t r;
472*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_handle_t *h = lws_container_of(sul, lws_ss_handle_t, sul);
473*1c60b9acSAndroid Build Coastguard Worker 
474*1c60b9acSAndroid Build Coastguard Worker 	lwsl_info("%s: retrying %s after backoff\n", __func__, lws_ss_tag(h));
475*1c60b9acSAndroid Build Coastguard Worker 	/* we want to retry... */
476*1c60b9acSAndroid Build Coastguard Worker 	h->seqstate = SSSEQ_DO_RETRY;
477*1c60b9acSAndroid Build Coastguard Worker 
478*1c60b9acSAndroid Build Coastguard Worker 	r = _lws_ss_request_tx(h);
479*1c60b9acSAndroid Build Coastguard Worker 	_lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, NULL, &h);
480*1c60b9acSAndroid Build Coastguard Worker }
481*1c60b9acSAndroid Build Coastguard Worker 
482*1c60b9acSAndroid Build Coastguard Worker int
lws_ss_exp_cb_metadata(void * priv,const char * name,char * out,size_t * pos,size_t olen,size_t * exp_ofs)483*1c60b9acSAndroid Build Coastguard Worker lws_ss_exp_cb_metadata(void *priv, const char *name, char *out, size_t *pos,
484*1c60b9acSAndroid Build Coastguard Worker 			size_t olen, size_t *exp_ofs)
485*1c60b9acSAndroid Build Coastguard Worker {
486*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_handle_t *h = (lws_ss_handle_t *)priv;
487*1c60b9acSAndroid Build Coastguard Worker 	const char *replace = NULL;
488*1c60b9acSAndroid Build Coastguard Worker 	size_t total, budget;
489*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_metadata_t *md = lws_ss_policy_metadata(h->policy, name),
490*1c60b9acSAndroid Build Coastguard Worker 			  *hmd = lws_ss_get_handle_metadata(h, name);
491*1c60b9acSAndroid Build Coastguard Worker 
492*1c60b9acSAndroid Build Coastguard Worker 	if (!md) {
493*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: Unknown metadata %s\n", __func__, name);
494*1c60b9acSAndroid Build Coastguard Worker 
495*1c60b9acSAndroid Build Coastguard Worker 		return LSTRX_FATAL_NAME_UNKNOWN;
496*1c60b9acSAndroid Build Coastguard Worker 	}
497*1c60b9acSAndroid Build Coastguard Worker 
498*1c60b9acSAndroid Build Coastguard Worker 	if (!hmd)
499*1c60b9acSAndroid Build Coastguard Worker 		return LSTRX_FILLED_OUT;
500*1c60b9acSAndroid Build Coastguard Worker 
501*1c60b9acSAndroid Build Coastguard Worker 	replace = hmd->value__may_own_heap;
502*1c60b9acSAndroid Build Coastguard Worker 
503*1c60b9acSAndroid Build Coastguard Worker 	if (!replace)
504*1c60b9acSAndroid Build Coastguard Worker 		return LSTRX_DONE;
505*1c60b9acSAndroid Build Coastguard Worker 
506*1c60b9acSAndroid Build Coastguard Worker 	total = hmd->length;
507*1c60b9acSAndroid Build Coastguard Worker 
508*1c60b9acSAndroid Build Coastguard Worker 	budget = olen - *pos;
509*1c60b9acSAndroid Build Coastguard Worker 	total -= *exp_ofs;
510*1c60b9acSAndroid Build Coastguard Worker 	if (total < budget)
511*1c60b9acSAndroid Build Coastguard Worker 		budget = total;
512*1c60b9acSAndroid Build Coastguard Worker 
513*1c60b9acSAndroid Build Coastguard Worker 	if (out)
514*1c60b9acSAndroid Build Coastguard Worker 		memcpy(out + *pos, replace + (*exp_ofs), budget);
515*1c60b9acSAndroid Build Coastguard Worker 	*exp_ofs += budget;
516*1c60b9acSAndroid Build Coastguard Worker 	*pos += budget;
517*1c60b9acSAndroid Build Coastguard Worker 
518*1c60b9acSAndroid Build Coastguard Worker 	if (budget == total)
519*1c60b9acSAndroid Build Coastguard Worker 		return LSTRX_DONE;
520*1c60b9acSAndroid Build Coastguard Worker 
521*1c60b9acSAndroid Build Coastguard Worker 	return LSTRX_FILLED_OUT;
522*1c60b9acSAndroid Build Coastguard Worker }
523*1c60b9acSAndroid Build Coastguard Worker 
524*1c60b9acSAndroid Build Coastguard Worker int
lws_ss_set_timeout_us(lws_ss_handle_t * h,lws_usec_t us)525*1c60b9acSAndroid Build Coastguard Worker lws_ss_set_timeout_us(lws_ss_handle_t *h, lws_usec_t us)
526*1c60b9acSAndroid Build Coastguard Worker {
527*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_per_thread *pt = &h->context->pt[h->tsi];
528*1c60b9acSAndroid Build Coastguard Worker 
529*1c60b9acSAndroid Build Coastguard Worker 	h->sul.cb = lws_ss_timeout_sul_check_cb;
530*1c60b9acSAndroid Build Coastguard Worker 	__lws_sul_insert_us(&pt->pt_sul_owner[
531*1c60b9acSAndroid Build Coastguard Worker 	            !!(h->policy->flags & LWSSSPOLF_WAKE_SUSPEND__VALIDITY)],
532*1c60b9acSAndroid Build Coastguard Worker 		    &h->sul, us);
533*1c60b9acSAndroid Build Coastguard Worker 
534*1c60b9acSAndroid Build Coastguard Worker 	return 0;
535*1c60b9acSAndroid Build Coastguard Worker }
536*1c60b9acSAndroid Build Coastguard Worker 
537*1c60b9acSAndroid Build Coastguard Worker lws_ss_state_return_t
_lws_ss_backoff(lws_ss_handle_t * h,lws_usec_t us_override)538*1c60b9acSAndroid Build Coastguard Worker _lws_ss_backoff(lws_ss_handle_t *h, lws_usec_t us_override)
539*1c60b9acSAndroid Build Coastguard Worker {
540*1c60b9acSAndroid Build Coastguard Worker 	uint64_t ms;
541*1c60b9acSAndroid Build Coastguard Worker 	char conceal;
542*1c60b9acSAndroid Build Coastguard Worker 
543*1c60b9acSAndroid Build Coastguard Worker 	lws_service_assert_loop_thread(h->context, h->tsi);
544*1c60b9acSAndroid Build Coastguard Worker 
545*1c60b9acSAndroid Build Coastguard Worker 	if (h->seqstate == SSSEQ_RECONNECT_WAIT)
546*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_OK;
547*1c60b9acSAndroid Build Coastguard Worker 
548*1c60b9acSAndroid Build Coastguard Worker 	/* figure out what we should do about another retry */
549*1c60b9acSAndroid Build Coastguard Worker 
550*1c60b9acSAndroid Build Coastguard Worker 	lwsl_info("%s: %s: retry backoff after failure\n", __func__, lws_ss_tag(h));
551*1c60b9acSAndroid Build Coastguard Worker 	ms = lws_retry_get_delay_ms(h->context, h->policy->retry_bo,
552*1c60b9acSAndroid Build Coastguard Worker 				    &h->retry, &conceal);
553*1c60b9acSAndroid Build Coastguard Worker 	if (!conceal) {
554*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: %s: abandon conn attempt \n",__func__, lws_ss_tag(h));
555*1c60b9acSAndroid Build Coastguard Worker 
556*1c60b9acSAndroid Build Coastguard Worker 		if (h->seqstate == SSSEQ_IDLE) /* been here? */
557*1c60b9acSAndroid Build Coastguard Worker 			return LWSSSSRET_OK;
558*1c60b9acSAndroid Build Coastguard Worker 
559*1c60b9acSAndroid Build Coastguard Worker 		h->seqstate = SSSEQ_IDLE;
560*1c60b9acSAndroid Build Coastguard Worker 
561*1c60b9acSAndroid Build Coastguard Worker 		return lws_ss_event_helper(h, LWSSSCS_ALL_RETRIES_FAILED);
562*1c60b9acSAndroid Build Coastguard Worker 	}
563*1c60b9acSAndroid Build Coastguard Worker 
564*1c60b9acSAndroid Build Coastguard Worker 	/* Only increase our planned backoff, or go with it */
565*1c60b9acSAndroid Build Coastguard Worker 
566*1c60b9acSAndroid Build Coastguard Worker 	if (us_override < (lws_usec_t)ms * LWS_US_PER_MS)
567*1c60b9acSAndroid Build Coastguard Worker 		us_override = (lws_usec_t)(ms * LWS_US_PER_MS);
568*1c60b9acSAndroid Build Coastguard Worker 
569*1c60b9acSAndroid Build Coastguard Worker 	h->seqstate = SSSEQ_RECONNECT_WAIT;
570*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_set_timeout_us(h, us_override);
571*1c60b9acSAndroid Build Coastguard Worker 
572*1c60b9acSAndroid Build Coastguard Worker 	lwsl_info("%s: %s: retry wait %dms\n", __func__, lws_ss_tag(h),
573*1c60b9acSAndroid Build Coastguard Worker 						  (int)(us_override / 1000));
574*1c60b9acSAndroid Build Coastguard Worker 
575*1c60b9acSAndroid Build Coastguard Worker 	return LWSSSSRET_OK;
576*1c60b9acSAndroid Build Coastguard Worker }
577*1c60b9acSAndroid Build Coastguard Worker 
578*1c60b9acSAndroid Build Coastguard Worker lws_ss_state_return_t
lws_ss_backoff(lws_ss_handle_t * h)579*1c60b9acSAndroid Build Coastguard Worker lws_ss_backoff(lws_ss_handle_t *h)
580*1c60b9acSAndroid Build Coastguard Worker {
581*1c60b9acSAndroid Build Coastguard Worker 	return _lws_ss_backoff(h, 0);
582*1c60b9acSAndroid Build Coastguard Worker }
583*1c60b9acSAndroid Build Coastguard Worker 
584*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_SMD)
585*1c60b9acSAndroid Build Coastguard Worker 
586*1c60b9acSAndroid Build Coastguard Worker /*
587*1c60b9acSAndroid Build Coastguard Worker  * Local SMD <-> SS
588*1c60b9acSAndroid Build Coastguard Worker  *
589*1c60b9acSAndroid Build Coastguard Worker  * We pass received messages through to the SS handler synchronously, using the
590*1c60b9acSAndroid Build Coastguard Worker  * lws service thread context.
591*1c60b9acSAndroid Build Coastguard Worker  *
592*1c60b9acSAndroid Build Coastguard Worker  * After the SS is created and registered, still nothing is going to come here
593*1c60b9acSAndroid Build Coastguard Worker  * until the peer sends us his rx_class_mask and we update his registration with
594*1c60b9acSAndroid Build Coastguard Worker  * it, because from SS creation his rx_class_mask defaults to 0.
595*1c60b9acSAndroid Build Coastguard Worker  */
596*1c60b9acSAndroid Build Coastguard Worker 
597*1c60b9acSAndroid Build Coastguard Worker static int
lws_smd_ss_cb(void * opaque,lws_smd_class_t _class,lws_usec_t timestamp,void * buf,size_t len)598*1c60b9acSAndroid Build Coastguard Worker lws_smd_ss_cb(void *opaque, lws_smd_class_t _class,
599*1c60b9acSAndroid Build Coastguard Worker 	      lws_usec_t timestamp, void *buf, size_t len)
600*1c60b9acSAndroid Build Coastguard Worker {
601*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_handle_t *h = (lws_ss_handle_t *)opaque;
602*1c60b9acSAndroid Build Coastguard Worker 	uint8_t *p = (uint8_t *)buf - LWS_SMD_SS_RX_HEADER_LEN;
603*1c60b9acSAndroid Build Coastguard Worker 
604*1c60b9acSAndroid Build Coastguard Worker 	lws_service_assert_loop_thread(h->context, h->tsi);
605*1c60b9acSAndroid Build Coastguard Worker 
606*1c60b9acSAndroid Build Coastguard Worker 	/*
607*1c60b9acSAndroid Build Coastguard Worker 	 * When configured with SS enabled, lws over-allocates
608*1c60b9acSAndroid Build Coastguard Worker 	 * LWS_SMD_SS_RX_HEADER_LEN bytes behind the payload of the queued
609*1c60b9acSAndroid Build Coastguard Worker 	 * message, for prepending serialized class and timestamp data in-band
610*1c60b9acSAndroid Build Coastguard Worker 	 * with the payload.
611*1c60b9acSAndroid Build Coastguard Worker 	 */
612*1c60b9acSAndroid Build Coastguard Worker 
613*1c60b9acSAndroid Build Coastguard Worker 	lws_ser_wu64be(p, _class);
614*1c60b9acSAndroid Build Coastguard Worker 	lws_ser_wu64be(p + 8, (uint64_t)timestamp);
615*1c60b9acSAndroid Build Coastguard Worker 
616*1c60b9acSAndroid Build Coastguard Worker 	if (h->info.rx)
617*1c60b9acSAndroid Build Coastguard Worker 		h->info.rx((void *)&h[1], p, len + LWS_SMD_SS_RX_HEADER_LEN,
618*1c60b9acSAndroid Build Coastguard Worker 		      LWSSS_FLAG_SOM | LWSSS_FLAG_EOM);
619*1c60b9acSAndroid Build Coastguard Worker 
620*1c60b9acSAndroid Build Coastguard Worker 	return 0;
621*1c60b9acSAndroid Build Coastguard Worker }
622*1c60b9acSAndroid Build Coastguard Worker 
623*1c60b9acSAndroid Build Coastguard Worker static void
lws_ss_smd_tx_cb(lws_sorted_usec_list_t * sul)624*1c60b9acSAndroid Build Coastguard Worker lws_ss_smd_tx_cb(lws_sorted_usec_list_t *sul)
625*1c60b9acSAndroid Build Coastguard Worker {
626*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_handle_t *h = lws_container_of(sul, lws_ss_handle_t, u.smd.sul_write);
627*1c60b9acSAndroid Build Coastguard Worker 	uint8_t buf[LWS_SMD_SS_RX_HEADER_LEN + LWS_SMD_MAX_PAYLOAD], *p;
628*1c60b9acSAndroid Build Coastguard Worker 	size_t len = sizeof(buf);
629*1c60b9acSAndroid Build Coastguard Worker 	lws_smd_class_t _class;
630*1c60b9acSAndroid Build Coastguard Worker 	int flags = 0, n;
631*1c60b9acSAndroid Build Coastguard Worker 
632*1c60b9acSAndroid Build Coastguard Worker 	lws_service_assert_loop_thread(h->context, h->tsi);
633*1c60b9acSAndroid Build Coastguard Worker 
634*1c60b9acSAndroid Build Coastguard Worker 	if (!h->info.tx)
635*1c60b9acSAndroid Build Coastguard Worker 		return;
636*1c60b9acSAndroid Build Coastguard Worker 
637*1c60b9acSAndroid Build Coastguard Worker 	n = h->info.tx(&h[1], h->txord++, buf, &len, &flags);
638*1c60b9acSAndroid Build Coastguard Worker 	if (n)
639*1c60b9acSAndroid Build Coastguard Worker 		/* nonzero return means don't want to send anything */
640*1c60b9acSAndroid Build Coastguard Worker 		return;
641*1c60b9acSAndroid Build Coastguard Worker 
642*1c60b9acSAndroid Build Coastguard Worker 	// lwsl_notice("%s: (SS %p bound to _lws_smd creates message) tx len %d\n", __func__, h, (int)len);
643*1c60b9acSAndroid Build Coastguard Worker 	// lwsl_hexdump_notice(buf, len);
644*1c60b9acSAndroid Build Coastguard Worker 
645*1c60b9acSAndroid Build Coastguard Worker 	assert(len >= LWS_SMD_SS_RX_HEADER_LEN);
646*1c60b9acSAndroid Build Coastguard Worker 	_class = (lws_smd_class_t)lws_ser_ru64be(buf);
647*1c60b9acSAndroid Build Coastguard Worker 	p = lws_smd_msg_alloc(h->context, _class, len - LWS_SMD_SS_RX_HEADER_LEN);
648*1c60b9acSAndroid Build Coastguard Worker 	if (!p) {
649*1c60b9acSAndroid Build Coastguard Worker 		// this can be rejected if nobody listening for this class
650*1c60b9acSAndroid Build Coastguard Worker 		//lwsl_notice("%s: failed to alloc\n", __func__);
651*1c60b9acSAndroid Build Coastguard Worker 		return;
652*1c60b9acSAndroid Build Coastguard Worker 	}
653*1c60b9acSAndroid Build Coastguard Worker 
654*1c60b9acSAndroid Build Coastguard Worker 	memcpy(p, buf + LWS_SMD_SS_RX_HEADER_LEN, len - LWS_SMD_SS_RX_HEADER_LEN);
655*1c60b9acSAndroid Build Coastguard Worker 	if (lws_smd_msg_send(h->context, p)) {
656*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: failed to queue\n", __func__);
657*1c60b9acSAndroid Build Coastguard Worker 		return;
658*1c60b9acSAndroid Build Coastguard Worker 	}
659*1c60b9acSAndroid Build Coastguard Worker }
660*1c60b9acSAndroid Build Coastguard Worker 
661*1c60b9acSAndroid Build Coastguard Worker #endif
662*1c60b9acSAndroid Build Coastguard Worker 
663*1c60b9acSAndroid Build Coastguard Worker lws_ss_state_return_t
_lws_ss_client_connect(lws_ss_handle_t * h,int is_retry,void * conn_if_sspc_onw)664*1c60b9acSAndroid Build Coastguard Worker _lws_ss_client_connect(lws_ss_handle_t *h, int is_retry, void *conn_if_sspc_onw)
665*1c60b9acSAndroid Build Coastguard Worker {
666*1c60b9acSAndroid Build Coastguard Worker 	const char *prot, *_prot, *ipath, *_ipath, *ads, *_ads;
667*1c60b9acSAndroid Build Coastguard Worker 	struct lws_client_connect_info i;
668*1c60b9acSAndroid Build Coastguard Worker 	const struct ss_pcols *ssp;
669*1c60b9acSAndroid Build Coastguard Worker 	size_t used_in, used_out;
670*1c60b9acSAndroid Build Coastguard Worker 	union lws_ss_contemp ct;
671*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_state_return_t r;
672*1c60b9acSAndroid Build Coastguard Worker 	int port, _port, tls;
673*1c60b9acSAndroid Build Coastguard Worker 	char *path, ep[96];
674*1c60b9acSAndroid Build Coastguard Worker 	lws_strexp_t exp;
675*1c60b9acSAndroid Build Coastguard Worker 	struct lws *wsi;
676*1c60b9acSAndroid Build Coastguard Worker 
677*1c60b9acSAndroid Build Coastguard Worker 	lws_service_assert_loop_thread(h->context, h->tsi);
678*1c60b9acSAndroid Build Coastguard Worker 
679*1c60b9acSAndroid Build Coastguard Worker 	if (!h->policy) {
680*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: ss with no policy\n", __func__);
681*1c60b9acSAndroid Build Coastguard Worker 
682*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_OK;
683*1c60b9acSAndroid Build Coastguard Worker 	}
684*1c60b9acSAndroid Build Coastguard Worker 
685*1c60b9acSAndroid Build Coastguard Worker 	/*
686*1c60b9acSAndroid Build Coastguard Worker 	 * We are already bound to a sink?
687*1c60b9acSAndroid Build Coastguard Worker 	 */
688*1c60b9acSAndroid Build Coastguard Worker 
689*1c60b9acSAndroid Build Coastguard Worker //	if (h->h_sink)
690*1c60b9acSAndroid Build Coastguard Worker //		return 0;
691*1c60b9acSAndroid Build Coastguard Worker 
692*1c60b9acSAndroid Build Coastguard Worker 	if (!is_retry)
693*1c60b9acSAndroid Build Coastguard Worker 		h->retry = 0;
694*1c60b9acSAndroid Build Coastguard Worker 
695*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_SMD)
696*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy == &pol_smd) {
697*1c60b9acSAndroid Build Coastguard Worker 
698*1c60b9acSAndroid Build Coastguard Worker 		if (h->u.smd.smd_peer)
699*1c60b9acSAndroid Build Coastguard Worker 			return LWSSSSRET_OK;
700*1c60b9acSAndroid Build Coastguard Worker 
701*1c60b9acSAndroid Build Coastguard Worker 		// lwsl_notice("%s: received connect for _lws_smd, registering for class mask 0x%x\n",
702*1c60b9acSAndroid Build Coastguard Worker 		//		__func__, h->info.manual_initial_tx_credit);
703*1c60b9acSAndroid Build Coastguard Worker 
704*1c60b9acSAndroid Build Coastguard Worker 		h->u.smd.smd_peer = lws_smd_register(h->context, h,
705*1c60b9acSAndroid Build Coastguard Worker 					(h->info.flags & LWSSSINFLAGS_PROXIED) ?
706*1c60b9acSAndroid Build Coastguard Worker 						LWSSMDREG_FLAG_PROXIED_SS : 0,
707*1c60b9acSAndroid Build Coastguard Worker 					(lws_smd_class_t)h->info.manual_initial_tx_credit,
708*1c60b9acSAndroid Build Coastguard Worker 					lws_smd_ss_cb);
709*1c60b9acSAndroid Build Coastguard Worker 		if (!h->u.smd.smd_peer)
710*1c60b9acSAndroid Build Coastguard Worker 			return LWSSSSRET_TX_DONT_SEND;
711*1c60b9acSAndroid Build Coastguard Worker 
712*1c60b9acSAndroid Build Coastguard Worker 		if (lws_ss_event_helper(h, LWSSSCS_CONNECTING))
713*1c60b9acSAndroid Build Coastguard Worker 			return LWSSSSRET_TX_DONT_SEND;
714*1c60b9acSAndroid Build Coastguard Worker 
715*1c60b9acSAndroid Build Coastguard Worker 		if (lws_ss_event_helper(h, LWSSSCS_CONNECTED))
716*1c60b9acSAndroid Build Coastguard Worker 			return LWSSSSRET_TX_DONT_SEND;
717*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_OK;
718*1c60b9acSAndroid Build Coastguard Worker 	}
719*1c60b9acSAndroid Build Coastguard Worker #endif
720*1c60b9acSAndroid Build Coastguard Worker 
721*1c60b9acSAndroid Build Coastguard Worker 	/*
722*1c60b9acSAndroid Build Coastguard Worker 	 * We're going to substitute ${metadata} in the endpoint at connection-
723*1c60b9acSAndroid Build Coastguard Worker 	 * time, so this can be set dynamically...
724*1c60b9acSAndroid Build Coastguard Worker 	 */
725*1c60b9acSAndroid Build Coastguard Worker 
726*1c60b9acSAndroid Build Coastguard Worker 	lws_strexp_init(&exp, (void *)h, lws_ss_exp_cb_metadata, ep, sizeof(ep));
727*1c60b9acSAndroid Build Coastguard Worker 
728*1c60b9acSAndroid Build Coastguard Worker 	if (lws_strexp_expand(&exp, h->policy->endpoint,
729*1c60b9acSAndroid Build Coastguard Worker 			      strlen(h->policy->endpoint),
730*1c60b9acSAndroid Build Coastguard Worker 			      &used_in, &used_out) != LSTRX_DONE) {
731*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: address strexp failed\n", __func__);
732*1c60b9acSAndroid Build Coastguard Worker 
733*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_TX_DONT_SEND;
734*1c60b9acSAndroid Build Coastguard Worker 	}
735*1c60b9acSAndroid Build Coastguard Worker 
736*1c60b9acSAndroid Build Coastguard Worker 	/*
737*1c60b9acSAndroid Build Coastguard Worker 	 * ... in some cases, we might want the user to be able to override
738*1c60b9acSAndroid Build Coastguard Worker 	 * some policy settings by what he provided in there.  For example,
739*1c60b9acSAndroid Build Coastguard Worker 	 * if he set the endpoint to "https://myendpoint.com:4443/mypath" it
740*1c60b9acSAndroid Build Coastguard Worker 	 * might be quite convenient to override the policy to follow the info
741*1c60b9acSAndroid Build Coastguard Worker 	 * that was given for at least server, port and the url path.
742*1c60b9acSAndroid Build Coastguard Worker 	 */
743*1c60b9acSAndroid Build Coastguard Worker 
744*1c60b9acSAndroid Build Coastguard Worker 	_port = port = h->policy->port;
745*1c60b9acSAndroid Build Coastguard Worker 	_prot = prot = NULL;
746*1c60b9acSAndroid Build Coastguard Worker 	_ipath = ipath = "";
747*1c60b9acSAndroid Build Coastguard Worker 	_ads = ads = ep;
748*1c60b9acSAndroid Build Coastguard Worker 
749*1c60b9acSAndroid Build Coastguard Worker 	if (strchr(ep, ':') &&
750*1c60b9acSAndroid Build Coastguard Worker 	    !lws_parse_uri(ep, &_prot, &_ads, &_port, &_ipath)) {
751*1c60b9acSAndroid Build Coastguard Worker 		lwsl_debug("%s: using uri parse results '%s' '%s' %d '%s'\n",
752*1c60b9acSAndroid Build Coastguard Worker 				__func__, _prot, _ads, _port, _ipath);
753*1c60b9acSAndroid Build Coastguard Worker 		prot = _prot;
754*1c60b9acSAndroid Build Coastguard Worker 		ads = _ads;
755*1c60b9acSAndroid Build Coastguard Worker 		port = _port;
756*1c60b9acSAndroid Build Coastguard Worker 		ipath = _ipath;
757*1c60b9acSAndroid Build Coastguard Worker 	}
758*1c60b9acSAndroid Build Coastguard Worker 
759*1c60b9acSAndroid Build Coastguard Worker 	memset(&i, 0, sizeof i); /* otherwise uninitialized garbage */
760*1c60b9acSAndroid Build Coastguard Worker 	i.context = h->context;
761*1c60b9acSAndroid Build Coastguard Worker 	tls = !!(h->policy->flags & LWSSSPOLF_TLS);
762*1c60b9acSAndroid Build Coastguard Worker 
763*1c60b9acSAndroid Build Coastguard Worker 	if (prot && (!strcmp(prot, "http") || !strcmp(prot, "ws") ||
764*1c60b9acSAndroid Build Coastguard Worker 		     !strcmp(prot, "mqtt")))
765*1c60b9acSAndroid Build Coastguard Worker 		tls = 0;
766*1c60b9acSAndroid Build Coastguard Worker 
767*1c60b9acSAndroid Build Coastguard Worker 	if (tls) {
768*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: using tls\n", __func__);
769*1c60b9acSAndroid Build Coastguard Worker 		i.ssl_connection = LCCSCF_USE_SSL;
770*1c60b9acSAndroid Build Coastguard Worker 
771*1c60b9acSAndroid Build Coastguard Worker 		if (!h->policy->trust.store)
772*1c60b9acSAndroid Build Coastguard Worker 			lwsl_info("%s: using platform trust store\n", __func__);
773*1c60b9acSAndroid Build Coastguard Worker 		else {
774*1c60b9acSAndroid Build Coastguard Worker 
775*1c60b9acSAndroid Build Coastguard Worker 			i.vhost = lws_get_vhost_by_name(h->context,
776*1c60b9acSAndroid Build Coastguard Worker 					h->policy->trust.store->name);
777*1c60b9acSAndroid Build Coastguard Worker 			if (!i.vhost) {
778*1c60b9acSAndroid Build Coastguard Worker 				lwsl_err("%s: missing vh for policy %s\n",
779*1c60b9acSAndroid Build Coastguard Worker 					 __func__,
780*1c60b9acSAndroid Build Coastguard Worker 					 h->policy->trust.store->name);
781*1c60b9acSAndroid Build Coastguard Worker 
782*1c60b9acSAndroid Build Coastguard Worker 				return -1;
783*1c60b9acSAndroid Build Coastguard Worker 			}
784*1c60b9acSAndroid Build Coastguard Worker 		}
785*1c60b9acSAndroid Build Coastguard Worker 	}
786*1c60b9acSAndroid Build Coastguard Worker 
787*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy->flags & LWSSSPOLF_WAKE_SUSPEND__VALIDITY)
788*1c60b9acSAndroid Build Coastguard Worker 		i.ssl_connection |= LCCSCF_WAKE_SUSPEND__VALIDITY;
789*1c60b9acSAndroid Build Coastguard Worker 
790*1c60b9acSAndroid Build Coastguard Worker 	/* translate policy attributes to IP ToS flags */
791*1c60b9acSAndroid Build Coastguard Worker 
792*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy->flags & LWSSSPOLF_ATTR_LOW_LATENCY)
793*1c60b9acSAndroid Build Coastguard Worker 		i.ssl_connection |= LCCSCF_IP_LOW_LATENCY;
794*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy->flags & LWSSSPOLF_ATTR_HIGH_THROUGHPUT)
795*1c60b9acSAndroid Build Coastguard Worker 		i.ssl_connection |= LCCSCF_IP_HIGH_THROUGHPUT;
796*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy->flags & LWSSSPOLF_ATTR_HIGH_RELIABILITY)
797*1c60b9acSAndroid Build Coastguard Worker 		i.ssl_connection |= LCCSCF_IP_HIGH_RELIABILITY;
798*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy->flags & LWSSSPOLF_ATTR_LOW_COST)
799*1c60b9acSAndroid Build Coastguard Worker 		i.ssl_connection |= LCCSCF_IP_LOW_COST;
800*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy->flags & LWSSSPOLF_PERF) /* collect conmon stats on this */
801*1c60b9acSAndroid Build Coastguard Worker 		i.ssl_connection |= LCCSCF_CONMON;
802*1c60b9acSAndroid Build Coastguard Worker 
803*1c60b9acSAndroid Build Coastguard Worker 	/* mark the connection with the streamtype priority from the policy */
804*1c60b9acSAndroid Build Coastguard Worker 
805*1c60b9acSAndroid Build Coastguard Worker 	i.priority = h->policy->priority;
806*1c60b9acSAndroid Build Coastguard Worker 
807*1c60b9acSAndroid Build Coastguard Worker 	i.ssl_connection |= LCCSCF_SECSTREAM_CLIENT;
808*1c60b9acSAndroid Build Coastguard Worker 
809*1c60b9acSAndroid Build Coastguard Worker 	if (conn_if_sspc_onw) {
810*1c60b9acSAndroid Build Coastguard Worker 		i.ssl_connection |= LCCSCF_SECSTREAM_PROXY_ONWARD;
811*1c60b9acSAndroid Build Coastguard Worker 		h->conn_if_sspc_onw = conn_if_sspc_onw;
812*1c60b9acSAndroid Build Coastguard Worker 	}
813*1c60b9acSAndroid Build Coastguard Worker 
814*1c60b9acSAndroid Build Coastguard Worker 
815*1c60b9acSAndroid Build Coastguard Worker 	i.address		= ads;
816*1c60b9acSAndroid Build Coastguard Worker 	i.port			= port;
817*1c60b9acSAndroid Build Coastguard Worker 	i.host			= i.address;
818*1c60b9acSAndroid Build Coastguard Worker 	i.origin		= i.address;
819*1c60b9acSAndroid Build Coastguard Worker 	i.opaque_user_data	= h;
820*1c60b9acSAndroid Build Coastguard Worker 	i.seq			= h->seq;
821*1c60b9acSAndroid Build Coastguard Worker 	i.retry_and_idle_policy	= h->policy->retry_bo;
822*1c60b9acSAndroid Build Coastguard Worker 	i.sys_tls_client_cert	= h->policy->client_cert;
823*1c60b9acSAndroid Build Coastguard Worker 
824*1c60b9acSAndroid Build Coastguard Worker 	i.path			= ipath;
825*1c60b9acSAndroid Build Coastguard Worker 		/* if this is not "", munge should use it instead of policy
826*1c60b9acSAndroid Build Coastguard Worker 		 * url path
827*1c60b9acSAndroid Build Coastguard Worker 		 */
828*1c60b9acSAndroid Build Coastguard Worker 
829*1c60b9acSAndroid Build Coastguard Worker 	ssp = ss_pcols[(int)h->policy->protocol];
830*1c60b9acSAndroid Build Coastguard Worker 	if (!ssp) {
831*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: unsupported protocol\n", __func__);
832*1c60b9acSAndroid Build Coastguard Worker 
833*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_TX_DONT_SEND;
834*1c60b9acSAndroid Build Coastguard Worker 	}
835*1c60b9acSAndroid Build Coastguard Worker 	i.alpn = ssp->alpn;
836*1c60b9acSAndroid Build Coastguard Worker 
837*1c60b9acSAndroid Build Coastguard Worker 	/*
838*1c60b9acSAndroid Build Coastguard Worker 	 * For http, we can get the method from the http object, override in
839*1c60b9acSAndroid Build Coastguard Worker 	 * the protocol-specific munge callback below if not http
840*1c60b9acSAndroid Build Coastguard Worker 	 */
841*1c60b9acSAndroid Build Coastguard Worker 	i.method = h->policy->u.http.method;
842*1c60b9acSAndroid Build Coastguard Worker 	i.protocol = ssp->protocol->name; /* lws protocol name */
843*1c60b9acSAndroid Build Coastguard Worker 	i.local_protocol_name = i.protocol;
844*1c60b9acSAndroid Build Coastguard Worker 
845*1c60b9acSAndroid Build Coastguard Worker 	path = lws_malloc(h->context->max_http_header_data, __func__);
846*1c60b9acSAndroid Build Coastguard Worker 	if (!path) {
847*1c60b9acSAndroid Build Coastguard Worker 		lwsl_warn("%s: OOM on path prealloc\n", __func__);
848*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_TX_DONT_SEND;
849*1c60b9acSAndroid Build Coastguard Worker 	}
850*1c60b9acSAndroid Build Coastguard Worker 
851*1c60b9acSAndroid Build Coastguard Worker 	if (ssp->munge) /* eg, raw doesn't use; endpoint strexp already done */
852*1c60b9acSAndroid Build Coastguard Worker 		ssp->munge(h, path, h->context->max_http_header_data, &i, &ct);
853*1c60b9acSAndroid Build Coastguard Worker 
854*1c60b9acSAndroid Build Coastguard Worker 	i.pwsi = &h->wsi;
855*1c60b9acSAndroid Build Coastguard Worker 
856*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SSPLUGINS)
857*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy->plugins[0] && h->policy->plugins[0]->munge)
858*1c60b9acSAndroid Build Coastguard Worker 		h->policy->plugins[0]->munge(h, path, h->context->max_http_header_data);
859*1c60b9acSAndroid Build Coastguard Worker #endif
860*1c60b9acSAndroid Build Coastguard Worker 
861*1c60b9acSAndroid Build Coastguard Worker 	lwsl_info("%s: connecting %s, '%s' '%s' %s\n", __func__, i.method,
862*1c60b9acSAndroid Build Coastguard Worker 			i.alpn, i.address, i.path);
863*1c60b9acSAndroid Build Coastguard Worker 
864*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_METRICS)
865*1c60b9acSAndroid Build Coastguard Worker 	/* possibly already hanging connect retry... */
866*1c60b9acSAndroid Build Coastguard Worker 	if (!h->cal_txn.mt)
867*1c60b9acSAndroid Build Coastguard Worker 		lws_metrics_caliper_bind(h->cal_txn, h->context->mth_ss_conn);
868*1c60b9acSAndroid Build Coastguard Worker 
869*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy->streamtype)
870*1c60b9acSAndroid Build Coastguard Worker 		lws_metrics_tag_add(&h->cal_txn.mtags_owner, "ss",
871*1c60b9acSAndroid Build Coastguard Worker 				    h->policy->streamtype);
872*1c60b9acSAndroid Build Coastguard Worker #endif
873*1c60b9acSAndroid Build Coastguard Worker 
874*1c60b9acSAndroid Build Coastguard Worker 	h->txn_ok = 0;
875*1c60b9acSAndroid Build Coastguard Worker 	r = lws_ss_event_helper(h, LWSSSCS_CONNECTING);
876*1c60b9acSAndroid Build Coastguard Worker 	if (r) {
877*1c60b9acSAndroid Build Coastguard Worker 		lws_free(path);
878*1c60b9acSAndroid Build Coastguard Worker 		return r;
879*1c60b9acSAndroid Build Coastguard Worker 	}
880*1c60b9acSAndroid Build Coastguard Worker 
881*1c60b9acSAndroid Build Coastguard Worker 	h->inside_connect = 1;
882*1c60b9acSAndroid Build Coastguard Worker 	h->pending_ret = LWSSSSRET_OK;
883*1c60b9acSAndroid Build Coastguard Worker 	wsi = lws_client_connect_via_info(&i);
884*1c60b9acSAndroid Build Coastguard Worker 	h->inside_connect = 0;
885*1c60b9acSAndroid Build Coastguard Worker 	lws_free(path);
886*1c60b9acSAndroid Build Coastguard Worker 	if (!wsi) {
887*1c60b9acSAndroid Build Coastguard Worker 		/*
888*1c60b9acSAndroid Build Coastguard Worker 		 * We already found that we could not connect, without even
889*1c60b9acSAndroid Build Coastguard Worker 		 * having to go around the event loop
890*1c60b9acSAndroid Build Coastguard Worker 		 */
891*1c60b9acSAndroid Build Coastguard Worker 
892*1c60b9acSAndroid Build Coastguard Worker 		if (h->pending_ret)
893*1c60b9acSAndroid Build Coastguard Worker 			return h->pending_ret;
894*1c60b9acSAndroid Build Coastguard Worker 
895*1c60b9acSAndroid Build Coastguard Worker 		if (h->prev_ss_state != LWSSSCS_UNREACHABLE &&
896*1c60b9acSAndroid Build Coastguard Worker 		    h->prev_ss_state != LWSSSCS_ALL_RETRIES_FAILED) {
897*1c60b9acSAndroid Build Coastguard Worker 			/*
898*1c60b9acSAndroid Build Coastguard Worker 			 * blocking DNS failure can get to unreachable via
899*1c60b9acSAndroid Build Coastguard Worker 			 * CCE, and unreachable can get to ALL_RETRIES_FAILED
900*1c60b9acSAndroid Build Coastguard Worker 			 */
901*1c60b9acSAndroid Build Coastguard Worker 			r = lws_ss_event_helper(h, LWSSSCS_UNREACHABLE);
902*1c60b9acSAndroid Build Coastguard Worker 			if (r)
903*1c60b9acSAndroid Build Coastguard Worker 				return r;
904*1c60b9acSAndroid Build Coastguard Worker 
905*1c60b9acSAndroid Build Coastguard Worker 			r = lws_ss_backoff(h);
906*1c60b9acSAndroid Build Coastguard Worker 			if (r)
907*1c60b9acSAndroid Build Coastguard Worker 				return r;
908*1c60b9acSAndroid Build Coastguard Worker 		}
909*1c60b9acSAndroid Build Coastguard Worker 
910*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_TX_DONT_SEND;
911*1c60b9acSAndroid Build Coastguard Worker 	}
912*1c60b9acSAndroid Build Coastguard Worker 
913*1c60b9acSAndroid Build Coastguard Worker 	return LWSSSSRET_OK;
914*1c60b9acSAndroid Build Coastguard Worker }
915*1c60b9acSAndroid Build Coastguard Worker 
916*1c60b9acSAndroid Build Coastguard Worker lws_ss_state_return_t
lws_ss_client_connect(lws_ss_handle_t * h)917*1c60b9acSAndroid Build Coastguard Worker lws_ss_client_connect(lws_ss_handle_t *h)
918*1c60b9acSAndroid Build Coastguard Worker {
919*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_state_return_t r;
920*1c60b9acSAndroid Build Coastguard Worker 
921*1c60b9acSAndroid Build Coastguard Worker 	lws_service_assert_loop_thread(h->context, h->tsi);
922*1c60b9acSAndroid Build Coastguard Worker 
923*1c60b9acSAndroid Build Coastguard Worker 	r = _lws_ss_client_connect(h, 0, 0);
924*1c60b9acSAndroid Build Coastguard Worker 
925*1c60b9acSAndroid Build Coastguard Worker 	return r;
926*1c60b9acSAndroid Build Coastguard Worker }
927*1c60b9acSAndroid Build Coastguard Worker 
928*1c60b9acSAndroid Build Coastguard Worker /*
929*1c60b9acSAndroid Build Coastguard Worker  * Public API
930*1c60b9acSAndroid Build Coastguard Worker  */
931*1c60b9acSAndroid Build Coastguard Worker 
932*1c60b9acSAndroid Build Coastguard Worker /*
933*1c60b9acSAndroid Build Coastguard Worker  * Create either a stream or a sink
934*1c60b9acSAndroid Build Coastguard Worker  */
935*1c60b9acSAndroid Build Coastguard Worker 
936*1c60b9acSAndroid Build Coastguard Worker int
lws_ss_create(struct lws_context * context,int tsi,const lws_ss_info_t * ssi,void * opaque_user_data,lws_ss_handle_t ** ppss,struct lws_sequencer * seq_owner,const char ** ppayload_fmt)937*1c60b9acSAndroid Build Coastguard Worker lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi,
938*1c60b9acSAndroid Build Coastguard Worker 	      void *opaque_user_data, lws_ss_handle_t **ppss,
939*1c60b9acSAndroid Build Coastguard Worker 	      struct lws_sequencer *seq_owner, const char **ppayload_fmt)
940*1c60b9acSAndroid Build Coastguard Worker {
941*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_per_thread *pt = &context->pt[tsi];
942*1c60b9acSAndroid Build Coastguard Worker 	const lws_ss_policy_t *pol;
943*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_state_return_t r;
944*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_metadata_t *smd;
945*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_handle_t *h;
946*1c60b9acSAndroid Build Coastguard Worker 	size_t size;
947*1c60b9acSAndroid Build Coastguard Worker 	void **v;
948*1c60b9acSAndroid Build Coastguard Worker 	char *p;
949*1c60b9acSAndroid Build Coastguard Worker 	int n;
950*1c60b9acSAndroid Build Coastguard Worker 
951*1c60b9acSAndroid Build Coastguard Worker 	lws_service_assert_loop_thread(context, tsi);
952*1c60b9acSAndroid Build Coastguard Worker 
953*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SECURE_STREAMS_CPP)
954*1c60b9acSAndroid Build Coastguard Worker 	pol = ssi->policy;
955*1c60b9acSAndroid Build Coastguard Worker 	if (!pol) {
956*1c60b9acSAndroid Build Coastguard Worker #endif
957*1c60b9acSAndroid Build Coastguard Worker 
958*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_FAULT_INJECTION)
959*1c60b9acSAndroid Build Coastguard Worker 		lws_fi_ctx_t temp_fic;
960*1c60b9acSAndroid Build Coastguard Worker 
961*1c60b9acSAndroid Build Coastguard Worker 		/*
962*1c60b9acSAndroid Build Coastguard Worker 		 * We have to do a temp inherit from context to find out
963*1c60b9acSAndroid Build Coastguard Worker 		 * early if we are supposed to inject a fault concealing
964*1c60b9acSAndroid Build Coastguard Worker 		 * the policy
965*1c60b9acSAndroid Build Coastguard Worker 		 */
966*1c60b9acSAndroid Build Coastguard Worker 
967*1c60b9acSAndroid Build Coastguard Worker 		memset(&temp_fic, 0, sizeof(temp_fic));
968*1c60b9acSAndroid Build Coastguard Worker 		lws_xos_init(&temp_fic.xos, lws_xos(&context->fic.xos));
969*1c60b9acSAndroid Build Coastguard Worker 		lws_fi_inherit_copy(&temp_fic, &context->fic, "ss", ssi->streamtype);
970*1c60b9acSAndroid Build Coastguard Worker 
971*1c60b9acSAndroid Build Coastguard Worker 		if (lws_fi(&temp_fic, "ss_no_streamtype_policy"))
972*1c60b9acSAndroid Build Coastguard Worker 			pol = NULL;
973*1c60b9acSAndroid Build Coastguard Worker 		else
974*1c60b9acSAndroid Build Coastguard Worker 			pol = lws_ss_policy_lookup(context, ssi->streamtype);
975*1c60b9acSAndroid Build Coastguard Worker 
976*1c60b9acSAndroid Build Coastguard Worker 		lws_fi_destroy(&temp_fic);
977*1c60b9acSAndroid Build Coastguard Worker #else
978*1c60b9acSAndroid Build Coastguard Worker 		pol = lws_ss_policy_lookup(context, ssi->streamtype);
979*1c60b9acSAndroid Build Coastguard Worker #endif
980*1c60b9acSAndroid Build Coastguard Worker 		if (!pol) {
981*1c60b9acSAndroid Build Coastguard Worker 			lwsl_cx_info(context, "unknown stream type %s",
982*1c60b9acSAndroid Build Coastguard Worker 				  ssi->streamtype);
983*1c60b9acSAndroid Build Coastguard Worker 			return 1;
984*1c60b9acSAndroid Build Coastguard Worker 		}
985*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SECURE_STREAMS_CPP)
986*1c60b9acSAndroid Build Coastguard Worker 	}
987*1c60b9acSAndroid Build Coastguard Worker #endif
988*1c60b9acSAndroid Build Coastguard Worker 
989*1c60b9acSAndroid Build Coastguard Worker #if 0
990*1c60b9acSAndroid Build Coastguard Worker 	if (ssi->flags & LWSSSINFLAGS_REGISTER_SINK) {
991*1c60b9acSAndroid Build Coastguard Worker 		/*
992*1c60b9acSAndroid Build Coastguard Worker 		 * This can register a secure streams sink as well as normal
993*1c60b9acSAndroid Build Coastguard Worker 		 * secure streams connections.  If that's what's happening,
994*1c60b9acSAndroid Build Coastguard Worker 		 * confirm the policy agrees that this streamtype should be
995*1c60b9acSAndroid Build Coastguard Worker 		 * directed to a sink.
996*1c60b9acSAndroid Build Coastguard Worker 		 */
997*1c60b9acSAndroid Build Coastguard Worker 		if (!(pol->flags & LWSSSPOLF_LOCAL_SINK)) {
998*1c60b9acSAndroid Build Coastguard Worker 			/*
999*1c60b9acSAndroid Build Coastguard Worker 			 * Caller wanted to create a sink for this streamtype,
1000*1c60b9acSAndroid Build Coastguard Worker 			 * but the policy does not agree the streamtype should
1001*1c60b9acSAndroid Build Coastguard Worker 			 * be routed to a local sink.
1002*1c60b9acSAndroid Build Coastguard Worker 			 */
1003*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: %s policy does not allow local sink\n",
1004*1c60b9acSAndroid Build Coastguard Worker 				 __func__, ssi->streamtype);
1005*1c60b9acSAndroid Build Coastguard Worker 
1006*1c60b9acSAndroid Build Coastguard Worker 			return 1;
1007*1c60b9acSAndroid Build Coastguard Worker 		}
1008*1c60b9acSAndroid Build Coastguard Worker 	} else {
1009*1c60b9acSAndroid Build Coastguard Worker 
1010*1c60b9acSAndroid Build Coastguard Worker 		if (!(pol->flags & LWSSSPOLF_LOCAL_SINK)) {
1011*1c60b9acSAndroid Build Coastguard Worker 
1012*1c60b9acSAndroid Build Coastguard Worker 		}
1013*1c60b9acSAndroid Build Coastguard Worker //		lws_dll2_foreach_safe(&pt->ss_owner, NULL, lws_ss_destroy_dll);
1014*1c60b9acSAndroid Build Coastguard Worker 	}
1015*1c60b9acSAndroid Build Coastguard Worker #endif
1016*1c60b9acSAndroid Build Coastguard Worker 
1017*1c60b9acSAndroid Build Coastguard Worker 	/*
1018*1c60b9acSAndroid Build Coastguard Worker 	 * We overallocate and point to things in the overallocation...
1019*1c60b9acSAndroid Build Coastguard Worker 	 *
1020*1c60b9acSAndroid Build Coastguard Worker 	 * 1) the user_alloc from the stream info
1021*1c60b9acSAndroid Build Coastguard Worker 	 * 2) network auth plugin instantiation data
1022*1c60b9acSAndroid Build Coastguard Worker 	 * 3) stream auth plugin instantiation data
1023*1c60b9acSAndroid Build Coastguard Worker 	 * 4) as many metadata pointer structs as the policy tells
1024*1c60b9acSAndroid Build Coastguard Worker 	 * 5) the streamtype name (length is not aligned)
1025*1c60b9acSAndroid Build Coastguard Worker 	 *
1026*1c60b9acSAndroid Build Coastguard Worker 	 * ... when we come to destroy it, just one free to do.
1027*1c60b9acSAndroid Build Coastguard Worker 	 */
1028*1c60b9acSAndroid Build Coastguard Worker 
1029*1c60b9acSAndroid Build Coastguard Worker 	size = sizeof(*h) + ssi->user_alloc +
1030*1c60b9acSAndroid Build Coastguard Worker 			(ssi->streamtype ? strlen(ssi->streamtype): 0) + 1;
1031*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SSPLUGINS)
1032*1c60b9acSAndroid Build Coastguard Worker 	if (pol->plugins[0])
1033*1c60b9acSAndroid Build Coastguard Worker 		size += pol->plugins[0]->alloc;
1034*1c60b9acSAndroid Build Coastguard Worker 	if (pol->plugins[1])
1035*1c60b9acSAndroid Build Coastguard Worker 		size += pol->plugins[1]->alloc;
1036*1c60b9acSAndroid Build Coastguard Worker #endif
1037*1c60b9acSAndroid Build Coastguard Worker 	size += pol->metadata_count * sizeof(lws_ss_metadata_t);
1038*1c60b9acSAndroid Build Coastguard Worker 
1039*1c60b9acSAndroid Build Coastguard Worker 	h = lws_zalloc(size, __func__);
1040*1c60b9acSAndroid Build Coastguard Worker 	if (!h)
1041*1c60b9acSAndroid Build Coastguard Worker 		return 2;
1042*1c60b9acSAndroid Build Coastguard Worker 
1043*1c60b9acSAndroid Build Coastguard Worker 	h->lc.log_cx = context->log_cx;
1044*1c60b9acSAndroid Build Coastguard Worker 
1045*1c60b9acSAndroid Build Coastguard Worker 	if (ssi->sss_protocol_version)
1046*1c60b9acSAndroid Build Coastguard Worker 		__lws_lc_tag(context, &context->lcg[LWSLCG_WSI_SS_CLIENT],
1047*1c60b9acSAndroid Build Coastguard Worker 			     &h->lc, "%s|v%u|%u",
1048*1c60b9acSAndroid Build Coastguard Worker 			     ssi->streamtype ? ssi->streamtype : "nostreamtype",
1049*1c60b9acSAndroid Build Coastguard Worker 			     (unsigned int)ssi->sss_protocol_version,
1050*1c60b9acSAndroid Build Coastguard Worker 			     (unsigned int)ssi->client_pid);
1051*1c60b9acSAndroid Build Coastguard Worker 	else
1052*1c60b9acSAndroid Build Coastguard Worker 		__lws_lc_tag(context, &context->lcg[LWSLCG_WSI_SS_CLIENT],
1053*1c60b9acSAndroid Build Coastguard Worker 			     &h->lc, "%s",
1054*1c60b9acSAndroid Build Coastguard Worker 			     ssi->streamtype ? ssi->streamtype : "nostreamtype");
1055*1c60b9acSAndroid Build Coastguard Worker 
1056*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_FAULT_INJECTION)
1057*1c60b9acSAndroid Build Coastguard Worker 	h->fic.name = "ss";
1058*1c60b9acSAndroid Build Coastguard Worker 	lws_xos_init(&h->fic.xos, lws_xos(&context->fic.xos));
1059*1c60b9acSAndroid Build Coastguard Worker 	if (ssi->fic.fi_owner.count)
1060*1c60b9acSAndroid Build Coastguard Worker 		lws_fi_import(&h->fic, &ssi->fic);
1061*1c60b9acSAndroid Build Coastguard Worker 
1062*1c60b9acSAndroid Build Coastguard Worker 	lws_fi_inherit_copy(&h->fic, &context->fic, "ss", ssi->streamtype);
1063*1c60b9acSAndroid Build Coastguard Worker #endif
1064*1c60b9acSAndroid Build Coastguard Worker 
1065*1c60b9acSAndroid Build Coastguard Worker 	h->info = *ssi;
1066*1c60b9acSAndroid Build Coastguard Worker 	h->policy = pol;
1067*1c60b9acSAndroid Build Coastguard Worker 	h->context = context;
1068*1c60b9acSAndroid Build Coastguard Worker 	h->tsi = (uint8_t)tsi;
1069*1c60b9acSAndroid Build Coastguard Worker 	h->seq = seq_owner;
1070*1c60b9acSAndroid Build Coastguard Worker 
1071*1c60b9acSAndroid Build Coastguard Worker 	if (h->info.flags & LWSSSINFLAGS_PROXIED)
1072*1c60b9acSAndroid Build Coastguard Worker 		h->proxy_onward = 1;
1073*1c60b9acSAndroid Build Coastguard Worker 
1074*1c60b9acSAndroid Build Coastguard Worker 	/* start of overallocated area */
1075*1c60b9acSAndroid Build Coastguard Worker 	p = (char *)&h[1];
1076*1c60b9acSAndroid Build Coastguard Worker 
1077*1c60b9acSAndroid Build Coastguard Worker 	/* set the handle pointer in the user data struct */
1078*1c60b9acSAndroid Build Coastguard Worker 	v = (void **)(p + ssi->handle_offset);
1079*1c60b9acSAndroid Build Coastguard Worker 	*v = h;
1080*1c60b9acSAndroid Build Coastguard Worker 
1081*1c60b9acSAndroid Build Coastguard Worker 	/* set the opaque user data in the user data struct */
1082*1c60b9acSAndroid Build Coastguard Worker 	v = (void **)(p + ssi->opaque_user_data_offset);
1083*1c60b9acSAndroid Build Coastguard Worker 	*v = opaque_user_data;
1084*1c60b9acSAndroid Build Coastguard Worker 
1085*1c60b9acSAndroid Build Coastguard Worker 	p += ssi->user_alloc;
1086*1c60b9acSAndroid Build Coastguard Worker 
1087*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SSPLUGINS)
1088*1c60b9acSAndroid Build Coastguard Worker 	if (pol->plugins[0]) {
1089*1c60b9acSAndroid Build Coastguard Worker 		h->nauthi = p;
1090*1c60b9acSAndroid Build Coastguard Worker 		p += pol->plugins[0]->alloc;
1091*1c60b9acSAndroid Build Coastguard Worker 	}
1092*1c60b9acSAndroid Build Coastguard Worker 	if (pol->plugins[1]) {
1093*1c60b9acSAndroid Build Coastguard Worker 		h->sauthi = p;
1094*1c60b9acSAndroid Build Coastguard Worker 		p += pol->plugins[1]->alloc;
1095*1c60b9acSAndroid Build Coastguard Worker 	}
1096*1c60b9acSAndroid Build Coastguard Worker #endif
1097*1c60b9acSAndroid Build Coastguard Worker 
1098*1c60b9acSAndroid Build Coastguard Worker 	if (pol->metadata_count) {
1099*1c60b9acSAndroid Build Coastguard Worker 		h->metadata = (lws_ss_metadata_t *)p;
1100*1c60b9acSAndroid Build Coastguard Worker 		p += pol->metadata_count * sizeof(lws_ss_metadata_t);
1101*1c60b9acSAndroid Build Coastguard Worker 
1102*1c60b9acSAndroid Build Coastguard Worker 		lwsl_cx_info(context, "%s metadata count %d",
1103*1c60b9acSAndroid Build Coastguard Worker 			  pol->streamtype, pol->metadata_count);
1104*1c60b9acSAndroid Build Coastguard Worker 	}
1105*1c60b9acSAndroid Build Coastguard Worker 
1106*1c60b9acSAndroid Build Coastguard Worker 	smd = pol->metadata;
1107*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < pol->metadata_count; n++) {
1108*1c60b9acSAndroid Build Coastguard Worker 		h->metadata[n].name = smd->name;
1109*1c60b9acSAndroid Build Coastguard Worker 		if (n + 1 == pol->metadata_count)
1110*1c60b9acSAndroid Build Coastguard Worker 			h->metadata[n].next = NULL;
1111*1c60b9acSAndroid Build Coastguard Worker 		else
1112*1c60b9acSAndroid Build Coastguard Worker 			h->metadata[n].next = &h->metadata[n + 1];
1113*1c60b9acSAndroid Build Coastguard Worker 		smd = smd->next;
1114*1c60b9acSAndroid Build Coastguard Worker 	}
1115*1c60b9acSAndroid Build Coastguard Worker 
1116*1c60b9acSAndroid Build Coastguard Worker 	if (ssi->streamtype)
1117*1c60b9acSAndroid Build Coastguard Worker 		memcpy(p, ssi->streamtype, strlen(ssi->streamtype) + 1);
1118*1c60b9acSAndroid Build Coastguard Worker 	/* don't mark accepted ss as being the server */
1119*1c60b9acSAndroid Build Coastguard Worker 	if (ssi->flags & LWSSSINFLAGS_SERVER)
1120*1c60b9acSAndroid Build Coastguard Worker 		h->info.flags &= (uint8_t)~LWSSSINFLAGS_SERVER;
1121*1c60b9acSAndroid Build Coastguard Worker 	h->info.streamtype = p;
1122*1c60b9acSAndroid Build Coastguard Worker 
1123*1c60b9acSAndroid Build Coastguard Worker 	lws_pt_lock(pt, __func__);
1124*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_add_head(&h->list, &pt->ss_owner);
1125*1c60b9acSAndroid Build Coastguard Worker 	lws_pt_unlock(pt);
1126*1c60b9acSAndroid Build Coastguard Worker 
1127*1c60b9acSAndroid Build Coastguard Worker 	if (ppss)
1128*1c60b9acSAndroid Build Coastguard Worker 		*ppss = h;
1129*1c60b9acSAndroid Build Coastguard Worker 
1130*1c60b9acSAndroid Build Coastguard Worker 	if (ppayload_fmt)
1131*1c60b9acSAndroid Build Coastguard Worker 		*ppayload_fmt = pol->payload_fmt;
1132*1c60b9acSAndroid Build Coastguard Worker 
1133*1c60b9acSAndroid Build Coastguard Worker 	if (ssi->flags & LWSSSINFLAGS_SERVER)
1134*1c60b9acSAndroid Build Coastguard Worker 		/*
1135*1c60b9acSAndroid Build Coastguard Worker 		 * return early for accepted connection flow
1136*1c60b9acSAndroid Build Coastguard Worker 		 */
1137*1c60b9acSAndroid Build Coastguard Worker 		return 0;
1138*1c60b9acSAndroid Build Coastguard Worker 
1139*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_SMD)
1140*1c60b9acSAndroid Build Coastguard Worker 	/*
1141*1c60b9acSAndroid Build Coastguard Worker 	 * For a local Secure Streams connection
1142*1c60b9acSAndroid Build Coastguard Worker 	 */
1143*1c60b9acSAndroid Build Coastguard Worker 	if (!(ssi->flags & LWSSSINFLAGS_PROXIED) &&
1144*1c60b9acSAndroid Build Coastguard Worker 	    pol == &pol_smd) {
1145*1c60b9acSAndroid Build Coastguard Worker 
1146*1c60b9acSAndroid Build Coastguard Worker 		/*
1147*1c60b9acSAndroid Build Coastguard Worker 		 * So he has asked to be wired up to SMD over a SS link.
1148*1c60b9acSAndroid Build Coastguard Worker 		 * Register him as an smd participant in his own right.
1149*1c60b9acSAndroid Build Coastguard Worker 		 *
1150*1c60b9acSAndroid Build Coastguard Worker 		 * Just for this case, ssi->manual_initial_tx_credit is used
1151*1c60b9acSAndroid Build Coastguard Worker 		 * to set the rx class mask (this is part of the SS serialization
1152*1c60b9acSAndroid Build Coastguard Worker 		 * format as well)
1153*1c60b9acSAndroid Build Coastguard Worker 		 */
1154*1c60b9acSAndroid Build Coastguard Worker 		h->u.smd.smd_peer = lws_smd_register(context, h, 0,
1155*1c60b9acSAndroid Build Coastguard Worker 						     (lws_smd_class_t)ssi->manual_initial_tx_credit,
1156*1c60b9acSAndroid Build Coastguard Worker 						     lws_smd_ss_cb);
1157*1c60b9acSAndroid Build Coastguard Worker 		if (!h->u.smd.smd_peer || lws_fi(&h->fic, "ss_create_smd"))
1158*1c60b9acSAndroid Build Coastguard Worker 			goto fail_creation;
1159*1c60b9acSAndroid Build Coastguard Worker 		lwsl_cx_info(context, "registered SS SMD");
1160*1c60b9acSAndroid Build Coastguard Worker 	}
1161*1c60b9acSAndroid Build Coastguard Worker #endif
1162*1c60b9acSAndroid Build Coastguard Worker 
1163*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
1164*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy->flags & LWSSSPOLF_SERVER) {
1165*1c60b9acSAndroid Build Coastguard Worker 		const struct lws_protocols *pprot[3], **ppp = &pprot[0];
1166*1c60b9acSAndroid Build Coastguard Worker 		struct lws_context_creation_info i;
1167*1c60b9acSAndroid Build Coastguard Worker 		struct lws_vhost *vho = NULL;
1168*1c60b9acSAndroid Build Coastguard Worker 
1169*1c60b9acSAndroid Build Coastguard Worker 		lwsl_cx_info(context, "creating server");
1170*1c60b9acSAndroid Build Coastguard Worker 
1171*1c60b9acSAndroid Build Coastguard Worker 		if (h->policy->endpoint &&
1172*1c60b9acSAndroid Build Coastguard Worker 		    h->policy->endpoint[0] == '!') {
1173*1c60b9acSAndroid Build Coastguard Worker 			/*
1174*1c60b9acSAndroid Build Coastguard Worker 			 * There's already a vhost existing that we want to
1175*1c60b9acSAndroid Build Coastguard Worker 			 * bind to, we don't have to specify and create one.
1176*1c60b9acSAndroid Build Coastguard Worker 			 *
1177*1c60b9acSAndroid Build Coastguard Worker 			 * The vhost must enable any protocols that we want.
1178*1c60b9acSAndroid Build Coastguard Worker 			 */
1179*1c60b9acSAndroid Build Coastguard Worker 
1180*1c60b9acSAndroid Build Coastguard Worker 			vho = lws_get_vhost_by_name(context,
1181*1c60b9acSAndroid Build Coastguard Worker 						    &h->policy->endpoint[1]);
1182*1c60b9acSAndroid Build Coastguard Worker 			if (!vho || lws_fi(&h->fic, "ss_create_vhost")) {
1183*1c60b9acSAndroid Build Coastguard Worker 				lwsl_err("%s: no vhost %s\n", __func__,
1184*1c60b9acSAndroid Build Coastguard Worker 						&h->policy->endpoint[1]);
1185*1c60b9acSAndroid Build Coastguard Worker 				goto fail_creation;
1186*1c60b9acSAndroid Build Coastguard Worker 			}
1187*1c60b9acSAndroid Build Coastguard Worker 
1188*1c60b9acSAndroid Build Coastguard Worker 			goto extant;
1189*1c60b9acSAndroid Build Coastguard Worker 		}
1190*1c60b9acSAndroid Build Coastguard Worker 
1191*1c60b9acSAndroid Build Coastguard Worker 		/*
1192*1c60b9acSAndroid Build Coastguard Worker 		 * This streamtype represents a server, we're being asked to
1193*1c60b9acSAndroid Build Coastguard Worker 		 * instantiate a corresponding vhost for it
1194*1c60b9acSAndroid Build Coastguard Worker 		 */
1195*1c60b9acSAndroid Build Coastguard Worker 
1196*1c60b9acSAndroid Build Coastguard Worker 		memset(&i, 0, sizeof i);
1197*1c60b9acSAndroid Build Coastguard Worker 
1198*1c60b9acSAndroid Build Coastguard Worker 		i.iface		= h->policy->endpoint;
1199*1c60b9acSAndroid Build Coastguard Worker 		i.vhost_name	= h->policy->streamtype;
1200*1c60b9acSAndroid Build Coastguard Worker 		i.port		= h->policy->port;
1201*1c60b9acSAndroid Build Coastguard Worker 
1202*1c60b9acSAndroid Build Coastguard Worker 		if (i.iface && i.iface[0] == '+') {
1203*1c60b9acSAndroid Build Coastguard Worker 			i.iface++;
1204*1c60b9acSAndroid Build Coastguard Worker 			i.options |= LWS_SERVER_OPTION_UNIX_SOCK;
1205*1c60b9acSAndroid Build Coastguard Worker 		}
1206*1c60b9acSAndroid Build Coastguard Worker 
1207*1c60b9acSAndroid Build Coastguard Worker 		if (!ss_pcols[h->policy->protocol] ||
1208*1c60b9acSAndroid Build Coastguard Worker 		    lws_fi(&h->fic, "ss_create_pcol")) {
1209*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: unsupp protocol", __func__);
1210*1c60b9acSAndroid Build Coastguard Worker 			goto fail_creation;
1211*1c60b9acSAndroid Build Coastguard Worker 		}
1212*1c60b9acSAndroid Build Coastguard Worker 
1213*1c60b9acSAndroid Build Coastguard Worker 		*ppp++ = ss_pcols[h->policy->protocol]->protocol;
1214*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_WS)
1215*1c60b9acSAndroid Build Coastguard Worker 		if (h->policy->u.http.u.ws.subprotocol)
1216*1c60b9acSAndroid Build Coastguard Worker 			/*
1217*1c60b9acSAndroid Build Coastguard Worker 			 * He names a ws subprotocol, ie, we want to support
1218*1c60b9acSAndroid Build Coastguard Worker 			 * ss-ws protocol in this vhost
1219*1c60b9acSAndroid Build Coastguard Worker 			 */
1220*1c60b9acSAndroid Build Coastguard Worker 			*ppp++ = &protocol_secstream_ws;
1221*1c60b9acSAndroid Build Coastguard Worker #endif
1222*1c60b9acSAndroid Build Coastguard Worker 		*ppp = NULL;
1223*1c60b9acSAndroid Build Coastguard Worker 		i.pprotocols = pprot;
1224*1c60b9acSAndroid Build Coastguard Worker 
1225*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_TLS)
1226*1c60b9acSAndroid Build Coastguard Worker 		if (h->policy->flags & LWSSSPOLF_TLS) {
1227*1c60b9acSAndroid Build Coastguard Worker 			i.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
1228*1c60b9acSAndroid Build Coastguard Worker 			i.server_ssl_cert_mem =
1229*1c60b9acSAndroid Build Coastguard Worker 				h->policy->trust.server.cert->ca_der;
1230*1c60b9acSAndroid Build Coastguard Worker 			i.server_ssl_cert_mem_len = (unsigned int)
1231*1c60b9acSAndroid Build Coastguard Worker 				h->policy->trust.server.cert->ca_der_len;
1232*1c60b9acSAndroid Build Coastguard Worker 			i.server_ssl_private_key_mem =
1233*1c60b9acSAndroid Build Coastguard Worker 				h->policy->trust.server.key->ca_der;
1234*1c60b9acSAndroid Build Coastguard Worker 			i.server_ssl_private_key_mem_len = (unsigned int)
1235*1c60b9acSAndroid Build Coastguard Worker 				h->policy->trust.server.key->ca_der_len;
1236*1c60b9acSAndroid Build Coastguard Worker 		}
1237*1c60b9acSAndroid Build Coastguard Worker #endif
1238*1c60b9acSAndroid Build Coastguard Worker 
1239*1c60b9acSAndroid Build Coastguard Worker 		if (!lws_fi(&h->fic, "ss_srv_vh_fail"))
1240*1c60b9acSAndroid Build Coastguard Worker 			vho = lws_create_vhost(context, &i);
1241*1c60b9acSAndroid Build Coastguard Worker 		else
1242*1c60b9acSAndroid Build Coastguard Worker 			vho = NULL;
1243*1c60b9acSAndroid Build Coastguard Worker 		if (!vho) {
1244*1c60b9acSAndroid Build Coastguard Worker 			lwsl_cx_err(context, "failed to create vh");
1245*1c60b9acSAndroid Build Coastguard Worker 			goto fail_creation;
1246*1c60b9acSAndroid Build Coastguard Worker 		}
1247*1c60b9acSAndroid Build Coastguard Worker 
1248*1c60b9acSAndroid Build Coastguard Worker extant:
1249*1c60b9acSAndroid Build Coastguard Worker 
1250*1c60b9acSAndroid Build Coastguard Worker 		/*
1251*1c60b9acSAndroid Build Coastguard Worker 		 * Mark this vhost as having to apply ss server semantics to
1252*1c60b9acSAndroid Build Coastguard Worker 		 * any incoming accepted connection
1253*1c60b9acSAndroid Build Coastguard Worker 		 */
1254*1c60b9acSAndroid Build Coastguard Worker 		vho->ss_handle = h;
1255*1c60b9acSAndroid Build Coastguard Worker 
1256*1c60b9acSAndroid Build Coastguard Worker 		r = lws_ss_event_helper(h, LWSSSCS_CREATING);
1257*1c60b9acSAndroid Build Coastguard Worker 		lwsl_cx_info(context, "CREATING returned status %d", (int)r);
1258*1c60b9acSAndroid Build Coastguard Worker 		if (r == LWSSSSRET_DESTROY_ME ||
1259*1c60b9acSAndroid Build Coastguard Worker 		    lws_fi(&h->fic, "ss_create_destroy_me"))
1260*1c60b9acSAndroid Build Coastguard Worker 			goto fail_creation;
1261*1c60b9acSAndroid Build Coastguard Worker 
1262*1c60b9acSAndroid Build Coastguard Worker 		lwsl_cx_notice(context, "created server %s",
1263*1c60b9acSAndroid Build Coastguard Worker 				h->policy->streamtype);
1264*1c60b9acSAndroid Build Coastguard Worker 
1265*1c60b9acSAndroid Build Coastguard Worker 		return 0;
1266*1c60b9acSAndroid Build Coastguard Worker 	}
1267*1c60b9acSAndroid Build Coastguard Worker #endif
1268*1c60b9acSAndroid Build Coastguard Worker 
1269*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
1270*1c60b9acSAndroid Build Coastguard Worker 
1271*1c60b9acSAndroid Build Coastguard Worker 	/*
1272*1c60b9acSAndroid Build Coastguard Worker 	 * For static policy case, dynamically ref / instantiate the related
1273*1c60b9acSAndroid Build Coastguard Worker 	 * trust store and vhost.  We do it by logical ss rather than connection
1274*1c60b9acSAndroid Build Coastguard Worker 	 * because we don't want to expose the latency of creating the x.509
1275*1c60b9acSAndroid Build Coastguard Worker 	 * trust store at the first connection.
1276*1c60b9acSAndroid Build Coastguard Worker 	 *
1277*1c60b9acSAndroid Build Coastguard Worker 	 * But it might be given the tls linkup takes time anyway, it can move
1278*1c60b9acSAndroid Build Coastguard Worker 	 * to the ss connect code instead.
1279*1c60b9acSAndroid Build Coastguard Worker 	 */
1280*1c60b9acSAndroid Build Coastguard Worker 
1281*1c60b9acSAndroid Build Coastguard Worker 	if (!lws_ss_policy_ref_trust_store(context, h->policy, 1 /* do the ref */) ||
1282*1c60b9acSAndroid Build Coastguard Worker 	    lws_fi(&h->fic, "ss_create_no_ts")) {
1283*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: unable to get vhost / trust store\n", __func__);
1284*1c60b9acSAndroid Build Coastguard Worker 		goto fail_creation;
1285*1c60b9acSAndroid Build Coastguard Worker 	}
1286*1c60b9acSAndroid Build Coastguard Worker #else
1287*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SECURE_STREAMS_CPP)
1288*1c60b9acSAndroid Build Coastguard Worker         if (!ssi->streamtype &&
1289*1c60b9acSAndroid Build Coastguard Worker 	    !lws_ss_policy_ref_trust_store(context, h->policy, 1 /* do the ref */)) {
1290*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: unable to get vhost / trust store\n", __func__);
1291*1c60b9acSAndroid Build Coastguard Worker 		goto fail_creation;
1292*1c60b9acSAndroid Build Coastguard Worker 	}
1293*1c60b9acSAndroid Build Coastguard Worker #endif
1294*1c60b9acSAndroid Build Coastguard Worker #endif
1295*1c60b9acSAndroid Build Coastguard Worker 
1296*1c60b9acSAndroid Build Coastguard Worker 	r = lws_ss_event_helper(h, LWSSSCS_CREATING);
1297*1c60b9acSAndroid Build Coastguard Worker 	lwsl_ss_info(h, "CREATING returned status %d", (int)r);
1298*1c60b9acSAndroid Build Coastguard Worker 	if (r == LWSSSSRET_DESTROY_ME ||
1299*1c60b9acSAndroid Build Coastguard Worker 	    lws_fi(&h->fic, "ss_create_destroy_me"))
1300*1c60b9acSAndroid Build Coastguard Worker 		goto fail_creation;
1301*1c60b9acSAndroid Build Coastguard Worker 
1302*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_SMD)
1303*1c60b9acSAndroid Build Coastguard Worker 	if (!(ssi->flags & LWSSSINFLAGS_PROXIED) &&
1304*1c60b9acSAndroid Build Coastguard Worker 	    pol == &pol_smd) {
1305*1c60b9acSAndroid Build Coastguard Worker 		r = lws_ss_event_helper(h, LWSSSCS_CONNECTING);
1306*1c60b9acSAndroid Build Coastguard Worker 		if (r || lws_fi(&h->fic, "ss_create_smd_1"))
1307*1c60b9acSAndroid Build Coastguard Worker 			goto fail_creation;
1308*1c60b9acSAndroid Build Coastguard Worker 		r = lws_ss_event_helper(h, LWSSSCS_CONNECTED);
1309*1c60b9acSAndroid Build Coastguard Worker 		if (r || lws_fi(&h->fic, "ss_create_smd_2"))
1310*1c60b9acSAndroid Build Coastguard Worker 			goto fail_creation;
1311*1c60b9acSAndroid Build Coastguard Worker 	}
1312*1c60b9acSAndroid Build Coastguard Worker #endif
1313*1c60b9acSAndroid Build Coastguard Worker 
1314*1c60b9acSAndroid Build Coastguard Worker 	if (!(ssi->flags & LWSSSINFLAGS_REGISTER_SINK) &&
1315*1c60b9acSAndroid Build Coastguard Worker 	    ((h->policy->flags & LWSSSPOLF_NAILED_UP)
1316*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_SMD)
1317*1c60b9acSAndroid Build Coastguard Worker 		|| ((h->policy == &pol_smd) //&&
1318*1c60b9acSAndroid Build Coastguard Worker 		    //(ssi->flags & LWSSSINFLAGS_PROXIED))
1319*1c60b9acSAndroid Build Coastguard Worker 				)
1320*1c60b9acSAndroid Build Coastguard Worker #endif
1321*1c60b9acSAndroid Build Coastguard Worker 			    )) {
1322*1c60b9acSAndroid Build Coastguard Worker 		r = _lws_ss_client_connect(h, 0, 0);
1323*1c60b9acSAndroid Build Coastguard Worker 		if (lws_fi(&h->fic, "ss_create_conn"))
1324*1c60b9acSAndroid Build Coastguard Worker 			r = LWSSSSRET_DESTROY_ME;
1325*1c60b9acSAndroid Build Coastguard Worker 		switch (r) {
1326*1c60b9acSAndroid Build Coastguard Worker 		case LWSSSSRET_OK:
1327*1c60b9acSAndroid Build Coastguard Worker 			break;
1328*1c60b9acSAndroid Build Coastguard Worker 		case LWSSSSRET_TX_DONT_SEND:
1329*1c60b9acSAndroid Build Coastguard Worker 		case LWSSSSRET_DISCONNECT_ME:
1330*1c60b9acSAndroid Build Coastguard Worker 			if (lws_ss_backoff(h) == LWSSSSRET_DESTROY_ME)
1331*1c60b9acSAndroid Build Coastguard Worker 				goto fail_creation;
1332*1c60b9acSAndroid Build Coastguard Worker 			break;
1333*1c60b9acSAndroid Build Coastguard Worker 		case LWSSSSRET_DESTROY_ME:
1334*1c60b9acSAndroid Build Coastguard Worker 			goto fail_creation;
1335*1c60b9acSAndroid Build Coastguard Worker 		}
1336*1c60b9acSAndroid Build Coastguard Worker 	}
1337*1c60b9acSAndroid Build Coastguard Worker 
1338*1c60b9acSAndroid Build Coastguard Worker 	return 0;
1339*1c60b9acSAndroid Build Coastguard Worker 
1340*1c60b9acSAndroid Build Coastguard Worker fail_creation:
1341*1c60b9acSAndroid Build Coastguard Worker 
1342*1c60b9acSAndroid Build Coastguard Worker 	if (ppss)
1343*1c60b9acSAndroid Build Coastguard Worker 		*ppss = NULL;
1344*1c60b9acSAndroid Build Coastguard Worker 
1345*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_destroy(&h);
1346*1c60b9acSAndroid Build Coastguard Worker 
1347*1c60b9acSAndroid Build Coastguard Worker 	return 1;
1348*1c60b9acSAndroid Build Coastguard Worker }
1349*1c60b9acSAndroid Build Coastguard Worker 
1350*1c60b9acSAndroid Build Coastguard Worker void *
lws_ss_to_user_object(struct lws_ss_handle * h)1351*1c60b9acSAndroid Build Coastguard Worker lws_ss_to_user_object(struct lws_ss_handle *h)
1352*1c60b9acSAndroid Build Coastguard Worker {
1353*1c60b9acSAndroid Build Coastguard Worker 	return (void *)&h[1];
1354*1c60b9acSAndroid Build Coastguard Worker }
1355*1c60b9acSAndroid Build Coastguard Worker 
1356*1c60b9acSAndroid Build Coastguard Worker void
lws_ss_destroy(lws_ss_handle_t ** ppss)1357*1c60b9acSAndroid Build Coastguard Worker lws_ss_destroy(lws_ss_handle_t **ppss)
1358*1c60b9acSAndroid Build Coastguard Worker {
1359*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_per_thread *pt;
1360*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
1361*1c60b9acSAndroid Build Coastguard Worker 	struct lws_vhost *v = NULL;
1362*1c60b9acSAndroid Build Coastguard Worker #endif
1363*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_handle_t *h = *ppss;
1364*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_metadata_t *pmd;
1365*1c60b9acSAndroid Build Coastguard Worker 
1366*1c60b9acSAndroid Build Coastguard Worker 	if (!h)
1367*1c60b9acSAndroid Build Coastguard Worker 		return;
1368*1c60b9acSAndroid Build Coastguard Worker 
1369*1c60b9acSAndroid Build Coastguard Worker 	lws_service_assert_loop_thread(h->context, h->tsi);
1370*1c60b9acSAndroid Build Coastguard Worker 
1371*1c60b9acSAndroid Build Coastguard Worker 	if (h == h->h_in_svc) {
1372*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: illegal destroy, return LWSSSSRET_DESTROY_ME instead\n",
1373*1c60b9acSAndroid Build Coastguard Worker 				__func__);
1374*1c60b9acSAndroid Build Coastguard Worker 		assert(0);
1375*1c60b9acSAndroid Build Coastguard Worker 		return;
1376*1c60b9acSAndroid Build Coastguard Worker 	}
1377*1c60b9acSAndroid Build Coastguard Worker 
1378*1c60b9acSAndroid Build Coastguard Worker 	if (h->destroying) {
1379*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: reentrant destroy\n", __func__);
1380*1c60b9acSAndroid Build Coastguard Worker 		return;
1381*1c60b9acSAndroid Build Coastguard Worker 	}
1382*1c60b9acSAndroid Build Coastguard Worker 	h->destroying = 1;
1383*1c60b9acSAndroid Build Coastguard Worker 
1384*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_CONMON)
1385*1c60b9acSAndroid Build Coastguard Worker 	if (h->conmon_json)
1386*1c60b9acSAndroid Build Coastguard Worker 		lws_free_set_NULL(h->conmon_json);
1387*1c60b9acSAndroid Build Coastguard Worker #endif
1388*1c60b9acSAndroid Build Coastguard Worker 
1389*1c60b9acSAndroid Build Coastguard Worker 	if (h->wsi) {
1390*1c60b9acSAndroid Build Coastguard Worker 		/*
1391*1c60b9acSAndroid Build Coastguard Worker 		 * Don't let the wsi point to us any more,
1392*1c60b9acSAndroid Build Coastguard Worker 		 * we (the ss object bound to the wsi) are going away now
1393*1c60b9acSAndroid Build Coastguard Worker 		 */
1394*1c60b9acSAndroid Build Coastguard Worker 		lws_set_opaque_user_data(h->wsi, NULL);
1395*1c60b9acSAndroid Build Coastguard Worker 		lws_set_timeout(h->wsi, 1, LWS_TO_KILL_SYNC);
1396*1c60b9acSAndroid Build Coastguard Worker 	}
1397*1c60b9acSAndroid Build Coastguard Worker 
1398*1c60b9acSAndroid Build Coastguard Worker 	/*
1399*1c60b9acSAndroid Build Coastguard Worker 	 * if we bound an smd registration to the SS, unregister it
1400*1c60b9acSAndroid Build Coastguard Worker 	 */
1401*1c60b9acSAndroid Build Coastguard Worker 
1402*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_SMD)
1403*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy == &pol_smd) {
1404*1c60b9acSAndroid Build Coastguard Worker 		lws_sul_cancel(&h->u.smd.sul_write);
1405*1c60b9acSAndroid Build Coastguard Worker 
1406*1c60b9acSAndroid Build Coastguard Worker 		if (h->u.smd.smd_peer) {
1407*1c60b9acSAndroid Build Coastguard Worker 			lws_smd_unregister(h->u.smd.smd_peer);
1408*1c60b9acSAndroid Build Coastguard Worker 			h->u.smd.smd_peer = NULL;
1409*1c60b9acSAndroid Build Coastguard Worker 		}
1410*1c60b9acSAndroid Build Coastguard Worker 	}
1411*1c60b9acSAndroid Build Coastguard Worker #endif
1412*1c60b9acSAndroid Build Coastguard Worker 
1413*1c60b9acSAndroid Build Coastguard Worker 	pt = &h->context->pt[h->tsi];
1414*1c60b9acSAndroid Build Coastguard Worker 
1415*1c60b9acSAndroid Build Coastguard Worker 	lws_pt_lock(pt, __func__);
1416*1c60b9acSAndroid Build Coastguard Worker 	*ppss = NULL;
1417*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_remove(&h->list);
1418*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
1419*1c60b9acSAndroid Build Coastguard Worker 		lws_dll2_remove(&h->cli_list);
1420*1c60b9acSAndroid Build Coastguard Worker #endif
1421*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_remove(&h->to_list);
1422*1c60b9acSAndroid Build Coastguard Worker 	lws_sul_cancel(&h->sul_timeout);
1423*1c60b9acSAndroid Build Coastguard Worker 
1424*1c60b9acSAndroid Build Coastguard Worker 	/*
1425*1c60b9acSAndroid Build Coastguard Worker 	 * for lss, DESTROYING deletes the C++ lss object, making the
1426*1c60b9acSAndroid Build Coastguard Worker 	 * self-defined h->policy radioactive
1427*1c60b9acSAndroid Build Coastguard Worker 	 */
1428*1c60b9acSAndroid Build Coastguard Worker 
1429*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
1430*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy && (h->policy->flags & LWSSSPOLF_SERVER))
1431*1c60b9acSAndroid Build Coastguard Worker 		v = lws_get_vhost_by_name(h->context, h->policy->streamtype);
1432*1c60b9acSAndroid Build Coastguard Worker #endif
1433*1c60b9acSAndroid Build Coastguard Worker 
1434*1c60b9acSAndroid Build Coastguard Worker 	/*
1435*1c60b9acSAndroid Build Coastguard Worker 	 * Since we also come here to unpick create, it's possible we failed
1436*1c60b9acSAndroid Build Coastguard Worker 	 * the creation before issuing any states, even CREATING.  We should
1437*1c60b9acSAndroid Build Coastguard Worker 	 * only issue cleanup states on destroy if we previously got as far as
1438*1c60b9acSAndroid Build Coastguard Worker 	 * issuing CREATING.
1439*1c60b9acSAndroid Build Coastguard Worker 	 */
1440*1c60b9acSAndroid Build Coastguard Worker 
1441*1c60b9acSAndroid Build Coastguard Worker 	if (h->prev_ss_state) {
1442*1c60b9acSAndroid Build Coastguard Worker 		if (h->ss_dangling_connected)
1443*1c60b9acSAndroid Build Coastguard Worker 			(void)lws_ss_event_helper(h, LWSSSCS_DISCONNECTED);
1444*1c60b9acSAndroid Build Coastguard Worker 
1445*1c60b9acSAndroid Build Coastguard Worker 		(void)lws_ss_event_helper(h, LWSSSCS_DESTROYING);
1446*1c60b9acSAndroid Build Coastguard Worker 	}
1447*1c60b9acSAndroid Build Coastguard Worker 
1448*1c60b9acSAndroid Build Coastguard Worker 	lws_pt_unlock(pt);
1449*1c60b9acSAndroid Build Coastguard Worker 
1450*1c60b9acSAndroid Build Coastguard Worker 	/* in proxy case, metadata value on heap may need cleaning up */
1451*1c60b9acSAndroid Build Coastguard Worker 
1452*1c60b9acSAndroid Build Coastguard Worker 	pmd = h->metadata;
1453*1c60b9acSAndroid Build Coastguard Worker 	while (pmd) {
1454*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: pmd %p\n", __func__, pmd);
1455*1c60b9acSAndroid Build Coastguard Worker 		if (pmd->value_on_lws_heap)
1456*1c60b9acSAndroid Build Coastguard Worker 			lws_free_set_NULL(pmd->value__may_own_heap);
1457*1c60b9acSAndroid Build Coastguard Worker 
1458*1c60b9acSAndroid Build Coastguard Worker 		pmd = pmd->next;
1459*1c60b9acSAndroid Build Coastguard Worker 	}
1460*1c60b9acSAndroid Build Coastguard Worker 
1461*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SS_DIRECT_PROTOCOL_STR)
1462*1c60b9acSAndroid Build Coastguard Worker 	{
1463*1c60b9acSAndroid Build Coastguard Worker 
1464*1c60b9acSAndroid Build Coastguard Worker 		lws_ss_metadata_t *imd;
1465*1c60b9acSAndroid Build Coastguard Worker 
1466*1c60b9acSAndroid Build Coastguard Worker 		pmd = h->instant_metadata;
1467*1c60b9acSAndroid Build Coastguard Worker 
1468*1c60b9acSAndroid Build Coastguard Worker 		while (pmd) {
1469*1c60b9acSAndroid Build Coastguard Worker 			imd = pmd;
1470*1c60b9acSAndroid Build Coastguard Worker 			pmd = pmd->next;
1471*1c60b9acSAndroid Build Coastguard Worker 
1472*1c60b9acSAndroid Build Coastguard Worker 			lwsl_info("%s: instant md %p\n", __func__, imd);
1473*1c60b9acSAndroid Build Coastguard Worker 			lws_free(imd);
1474*1c60b9acSAndroid Build Coastguard Worker 		}
1475*1c60b9acSAndroid Build Coastguard Worker 		h->instant_metadata = NULL;
1476*1c60b9acSAndroid Build Coastguard Worker 
1477*1c60b9acSAndroid Build Coastguard Worker 		if (h->imd_ac)
1478*1c60b9acSAndroid Build Coastguard Worker 			lwsac_free(&h->imd_ac);
1479*1c60b9acSAndroid Build Coastguard Worker 	}
1480*1c60b9acSAndroid Build Coastguard Worker #endif
1481*1c60b9acSAndroid Build Coastguard Worker 
1482*1c60b9acSAndroid Build Coastguard Worker 	lws_sul_cancel(&h->sul);
1483*1c60b9acSAndroid Build Coastguard Worker 
1484*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
1485*1c60b9acSAndroid Build Coastguard Worker 
1486*1c60b9acSAndroid Build Coastguard Worker 	/*
1487*1c60b9acSAndroid Build Coastguard Worker 	 * For static policy case, dynamically ref / instantiate the related
1488*1c60b9acSAndroid Build Coastguard Worker 	 * trust store and vhost.  We do it by logical ss rather than connection
1489*1c60b9acSAndroid Build Coastguard Worker 	 * because we don't want to expose the latency of creating the x.509
1490*1c60b9acSAndroid Build Coastguard Worker 	 * trust store at the first connection.
1491*1c60b9acSAndroid Build Coastguard Worker 	 *
1492*1c60b9acSAndroid Build Coastguard Worker 	 * But it might be given the tls linkup takes time anyway, it can move
1493*1c60b9acSAndroid Build Coastguard Worker 	 * to the ss connect code instead.
1494*1c60b9acSAndroid Build Coastguard Worker 	 */
1495*1c60b9acSAndroid Build Coastguard Worker 
1496*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy)
1497*1c60b9acSAndroid Build Coastguard Worker 		lws_ss_policy_unref_trust_store(h->context, h->policy);
1498*1c60b9acSAndroid Build Coastguard Worker #else
1499*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SECURE_STREAMS_CPP)
1500*1c60b9acSAndroid Build Coastguard Worker 	if (!h->info.streamtype || !*(h->info.streamtype))
1501*1c60b9acSAndroid Build Coastguard Worker 		lws_ss_policy_unref_trust_store(h->context, h->policy);
1502*1c60b9acSAndroid Build Coastguard Worker #endif
1503*1c60b9acSAndroid Build Coastguard Worker #endif
1504*1c60b9acSAndroid Build Coastguard Worker 
1505*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
1506*1c60b9acSAndroid Build Coastguard Worker 	if (v)
1507*1c60b9acSAndroid Build Coastguard Worker 		/*
1508*1c60b9acSAndroid Build Coastguard Worker 		 * For server, the policy describes a vhost that implements the
1509*1c60b9acSAndroid Build Coastguard Worker 		 * server, when we take down the ss, we take down the related
1510*1c60b9acSAndroid Build Coastguard Worker 		 * vhost (if it got that far)
1511*1c60b9acSAndroid Build Coastguard Worker 		 */
1512*1c60b9acSAndroid Build Coastguard Worker 		lws_vhost_destroy(v);
1513*1c60b9acSAndroid Build Coastguard Worker #endif
1514*1c60b9acSAndroid Build Coastguard Worker 
1515*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_FAULT_INJECTION)
1516*1c60b9acSAndroid Build Coastguard Worker 	lws_fi_destroy(&h->fic);
1517*1c60b9acSAndroid Build Coastguard Worker #endif
1518*1c60b9acSAndroid Build Coastguard Worker 
1519*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_METRICS)
1520*1c60b9acSAndroid Build Coastguard Worker 	/*
1521*1c60b9acSAndroid Build Coastguard Worker 	 * If any hanging caliper measurement, dump it, and free any tags
1522*1c60b9acSAndroid Build Coastguard Worker 	 */
1523*1c60b9acSAndroid Build Coastguard Worker 	lws_metrics_caliper_report_hist(h->cal_txn, (struct lws *)NULL);
1524*1c60b9acSAndroid Build Coastguard Worker #endif
1525*1c60b9acSAndroid Build Coastguard Worker 
1526*1c60b9acSAndroid Build Coastguard Worker 	lws_sul_cancel(&h->sul_timeout);
1527*1c60b9acSAndroid Build Coastguard Worker 
1528*1c60b9acSAndroid Build Coastguard Worker 	/* confirm no sul left scheduled in handle or user allocation object */
1529*1c60b9acSAndroid Build Coastguard Worker 	lws_sul_debug_zombies(h->context, h, sizeof(*h) + h->info.user_alloc,
1530*1c60b9acSAndroid Build Coastguard Worker 			      __func__);
1531*1c60b9acSAndroid Build Coastguard Worker 
1532*1c60b9acSAndroid Build Coastguard Worker 	__lws_lc_untag(h->context, &h->lc);
1533*1c60b9acSAndroid Build Coastguard Worker 
1534*1c60b9acSAndroid Build Coastguard Worker 	lws_explicit_bzero((void *)h, sizeof(*h) + h->info.user_alloc);
1535*1c60b9acSAndroid Build Coastguard Worker 
1536*1c60b9acSAndroid Build Coastguard Worker 	lws_free_set_NULL(h);
1537*1c60b9acSAndroid Build Coastguard Worker }
1538*1c60b9acSAndroid Build Coastguard Worker 
1539*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SERVER)
1540*1c60b9acSAndroid Build Coastguard Worker void
lws_ss_server_ack(struct lws_ss_handle * h,int nack)1541*1c60b9acSAndroid Build Coastguard Worker lws_ss_server_ack(struct lws_ss_handle *h, int nack)
1542*1c60b9acSAndroid Build Coastguard Worker {
1543*1c60b9acSAndroid Build Coastguard Worker 	h->txn_resp = nack;
1544*1c60b9acSAndroid Build Coastguard Worker 	h->txn_resp_set = 1;
1545*1c60b9acSAndroid Build Coastguard Worker }
1546*1c60b9acSAndroid Build Coastguard Worker 
1547*1c60b9acSAndroid Build Coastguard Worker void
lws_ss_server_foreach_client(struct lws_ss_handle * h,lws_sssfec_cb cb,void * arg)1548*1c60b9acSAndroid Build Coastguard Worker lws_ss_server_foreach_client(struct lws_ss_handle *h, lws_sssfec_cb cb,
1549*1c60b9acSAndroid Build Coastguard Worker 			     void *arg)
1550*1c60b9acSAndroid Build Coastguard Worker {
1551*1c60b9acSAndroid Build Coastguard Worker 	lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1, h->src_list.head) {
1552*1c60b9acSAndroid Build Coastguard Worker 		struct lws_ss_handle *h =
1553*1c60b9acSAndroid Build Coastguard Worker 			lws_container_of(d, struct lws_ss_handle, cli_list);
1554*1c60b9acSAndroid Build Coastguard Worker 
1555*1c60b9acSAndroid Build Coastguard Worker 		cb(h, arg);
1556*1c60b9acSAndroid Build Coastguard Worker 
1557*1c60b9acSAndroid Build Coastguard Worker 	} lws_end_foreach_dll_safe(d, d1);
1558*1c60b9acSAndroid Build Coastguard Worker }
1559*1c60b9acSAndroid Build Coastguard Worker #endif
1560*1c60b9acSAndroid Build Coastguard Worker 
1561*1c60b9acSAndroid Build Coastguard Worker lws_ss_state_return_t
lws_ss_request_tx(lws_ss_handle_t * h)1562*1c60b9acSAndroid Build Coastguard Worker lws_ss_request_tx(lws_ss_handle_t *h)
1563*1c60b9acSAndroid Build Coastguard Worker {
1564*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_state_return_t r;
1565*1c60b9acSAndroid Build Coastguard Worker 
1566*1c60b9acSAndroid Build Coastguard Worker 	r = _lws_ss_request_tx(h);
1567*1c60b9acSAndroid Build Coastguard Worker 
1568*1c60b9acSAndroid Build Coastguard Worker 	return r;
1569*1c60b9acSAndroid Build Coastguard Worker }
1570*1c60b9acSAndroid Build Coastguard Worker 
1571*1c60b9acSAndroid Build Coastguard Worker lws_ss_state_return_t
_lws_ss_request_tx(lws_ss_handle_t * h)1572*1c60b9acSAndroid Build Coastguard Worker _lws_ss_request_tx(lws_ss_handle_t *h)
1573*1c60b9acSAndroid Build Coastguard Worker {
1574*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_state_return_t r;
1575*1c60b9acSAndroid Build Coastguard Worker 
1576*1c60b9acSAndroid Build Coastguard Worker 	// lwsl_notice("%s: h %p, wsi %p\n", __func__, h, h->wsi);
1577*1c60b9acSAndroid Build Coastguard Worker 
1578*1c60b9acSAndroid Build Coastguard Worker 	lws_service_assert_loop_thread(h->context, h->tsi);
1579*1c60b9acSAndroid Build Coastguard Worker 
1580*1c60b9acSAndroid Build Coastguard Worker 	if (h->wsi) {
1581*1c60b9acSAndroid Build Coastguard Worker 		lws_callback_on_writable(h->wsi);
1582*1c60b9acSAndroid Build Coastguard Worker 
1583*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_OK;
1584*1c60b9acSAndroid Build Coastguard Worker 	}
1585*1c60b9acSAndroid Build Coastguard Worker 
1586*1c60b9acSAndroid Build Coastguard Worker 	if (!h->policy) {
1587*1c60b9acSAndroid Build Coastguard Worker 		/* avoid crash */
1588*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: null policy\n", __func__);
1589*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_OK;
1590*1c60b9acSAndroid Build Coastguard Worker 	}
1591*1c60b9acSAndroid Build Coastguard Worker 
1592*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy->flags & LWSSSPOLF_SERVER)
1593*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_OK;
1594*1c60b9acSAndroid Build Coastguard Worker 
1595*1c60b9acSAndroid Build Coastguard Worker 	/*
1596*1c60b9acSAndroid Build Coastguard Worker 	 * there's currently no wsi / connection associated with the ss handle
1597*1c60b9acSAndroid Build Coastguard Worker 	 */
1598*1c60b9acSAndroid Build Coastguard Worker 
1599*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_SMD)
1600*1c60b9acSAndroid Build Coastguard Worker 	if (h->policy == &pol_smd) {
1601*1c60b9acSAndroid Build Coastguard Worker 		/*
1602*1c60b9acSAndroid Build Coastguard Worker 		 * He's an _lws_smd... and no wsi... since we're just going
1603*1c60b9acSAndroid Build Coastguard Worker 		 * to queue it, we could call his tx() right here, but rather
1604*1c60b9acSAndroid Build Coastguard Worker 		 * than surprise him let's set a sul to do it next time around
1605*1c60b9acSAndroid Build Coastguard Worker 		 * the event loop
1606*1c60b9acSAndroid Build Coastguard Worker 		 */
1607*1c60b9acSAndroid Build Coastguard Worker 
1608*1c60b9acSAndroid Build Coastguard Worker 		lws_sul_schedule(h->context, 0, &h->u.smd.sul_write,
1609*1c60b9acSAndroid Build Coastguard Worker 				 lws_ss_smd_tx_cb, 1);
1610*1c60b9acSAndroid Build Coastguard Worker 
1611*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_OK;
1612*1c60b9acSAndroid Build Coastguard Worker 	}
1613*1c60b9acSAndroid Build Coastguard Worker #endif
1614*1c60b9acSAndroid Build Coastguard Worker 
1615*1c60b9acSAndroid Build Coastguard Worker 	if (h->seqstate != SSSEQ_IDLE &&
1616*1c60b9acSAndroid Build Coastguard Worker 	    h->seqstate != SSSEQ_DO_RETRY)
1617*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_OK;
1618*1c60b9acSAndroid Build Coastguard Worker 
1619*1c60b9acSAndroid Build Coastguard Worker 	h->seqstate = SSSEQ_TRY_CONNECT;
1620*1c60b9acSAndroid Build Coastguard Worker 	r = lws_ss_event_helper(h, LWSSSCS_POLL);
1621*1c60b9acSAndroid Build Coastguard Worker 	if (r)
1622*1c60b9acSAndroid Build Coastguard Worker 		return r;
1623*1c60b9acSAndroid Build Coastguard Worker 
1624*1c60b9acSAndroid Build Coastguard Worker 	/*
1625*1c60b9acSAndroid Build Coastguard Worker 	 * Retries operate via lws_ss_request_tx(), explicitly ask for a
1626*1c60b9acSAndroid Build Coastguard Worker 	 * reconnection to clear the retry limit
1627*1c60b9acSAndroid Build Coastguard Worker 	 */
1628*1c60b9acSAndroid Build Coastguard Worker 	r = _lws_ss_client_connect(h, 1, 0);
1629*1c60b9acSAndroid Build Coastguard Worker 	if (r == LWSSSSRET_DESTROY_ME)
1630*1c60b9acSAndroid Build Coastguard Worker 		return r;
1631*1c60b9acSAndroid Build Coastguard Worker 
1632*1c60b9acSAndroid Build Coastguard Worker 	if (r)
1633*1c60b9acSAndroid Build Coastguard Worker 		return lws_ss_backoff(h);
1634*1c60b9acSAndroid Build Coastguard Worker 
1635*1c60b9acSAndroid Build Coastguard Worker 	return LWSSSSRET_OK;
1636*1c60b9acSAndroid Build Coastguard Worker }
1637*1c60b9acSAndroid Build Coastguard Worker 
1638*1c60b9acSAndroid Build Coastguard Worker lws_ss_state_return_t
lws_ss_request_tx_len(lws_ss_handle_t * h,unsigned long len)1639*1c60b9acSAndroid Build Coastguard Worker lws_ss_request_tx_len(lws_ss_handle_t *h, unsigned long len)
1640*1c60b9acSAndroid Build Coastguard Worker {
1641*1c60b9acSAndroid Build Coastguard Worker 	lws_service_assert_loop_thread(h->context, h->tsi);
1642*1c60b9acSAndroid Build Coastguard Worker 
1643*1c60b9acSAndroid Build Coastguard Worker 	if (h->wsi && h->policy &&
1644*1c60b9acSAndroid Build Coastguard Worker 	    (h->policy->protocol == LWSSSP_H1 ||
1645*1c60b9acSAndroid Build Coastguard Worker 	     h->policy->protocol == LWSSSP_H2 ||
1646*1c60b9acSAndroid Build Coastguard Worker 	     h->policy->protocol == LWSSSP_WS))
1647*1c60b9acSAndroid Build Coastguard Worker 		h->wsi->http.writeable_len = len;
1648*1c60b9acSAndroid Build Coastguard Worker 	else
1649*1c60b9acSAndroid Build Coastguard Worker 		h->writeable_len = len;
1650*1c60b9acSAndroid Build Coastguard Worker 
1651*1c60b9acSAndroid Build Coastguard Worker 	return lws_ss_request_tx(h);
1652*1c60b9acSAndroid Build Coastguard Worker }
1653*1c60b9acSAndroid Build Coastguard Worker 
1654*1c60b9acSAndroid Build Coastguard Worker /*
1655*1c60b9acSAndroid Build Coastguard Worker  * private helpers
1656*1c60b9acSAndroid Build Coastguard Worker  */
1657*1c60b9acSAndroid Build Coastguard Worker 
1658*1c60b9acSAndroid Build Coastguard Worker /* used on context destroy when iterating listed lws_ss on a pt */
1659*1c60b9acSAndroid Build Coastguard Worker 
1660*1c60b9acSAndroid Build Coastguard Worker int
lws_ss_destroy_dll(struct lws_dll2 * d,void * user)1661*1c60b9acSAndroid Build Coastguard Worker lws_ss_destroy_dll(struct lws_dll2 *d, void *user)
1662*1c60b9acSAndroid Build Coastguard Worker {
1663*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_handle_t *h = lws_container_of(d, lws_ss_handle_t, list);
1664*1c60b9acSAndroid Build Coastguard Worker 
1665*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_destroy(&h);
1666*1c60b9acSAndroid Build Coastguard Worker 
1667*1c60b9acSAndroid Build Coastguard Worker 	return 0;
1668*1c60b9acSAndroid Build Coastguard Worker }
1669*1c60b9acSAndroid Build Coastguard Worker 
1670*1c60b9acSAndroid Build Coastguard Worker int
lws_ss_cancel_notify_dll(struct lws_dll2 * d,void * user)1671*1c60b9acSAndroid Build Coastguard Worker lws_ss_cancel_notify_dll(struct lws_dll2 *d, void *user)
1672*1c60b9acSAndroid Build Coastguard Worker {
1673*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_handle_t *h = lws_container_of(d, lws_ss_handle_t, list);
1674*1c60b9acSAndroid Build Coastguard Worker 
1675*1c60b9acSAndroid Build Coastguard Worker 	if (lws_ss_event_helper(h, LWSSSCS_EVENT_WAIT_CANCELLED))
1676*1c60b9acSAndroid Build Coastguard Worker 		lwsl_warn("%s: cancel event ignores return\n", __func__);
1677*1c60b9acSAndroid Build Coastguard Worker 
1678*1c60b9acSAndroid Build Coastguard Worker 	return 0;
1679*1c60b9acSAndroid Build Coastguard Worker }
1680*1c60b9acSAndroid Build Coastguard Worker 
1681*1c60b9acSAndroid Build Coastguard Worker struct lws_sequencer *
lws_ss_get_sequencer(lws_ss_handle_t * h)1682*1c60b9acSAndroid Build Coastguard Worker lws_ss_get_sequencer(lws_ss_handle_t *h)
1683*1c60b9acSAndroid Build Coastguard Worker {
1684*1c60b9acSAndroid Build Coastguard Worker 	return h->seq;
1685*1c60b9acSAndroid Build Coastguard Worker }
1686*1c60b9acSAndroid Build Coastguard Worker 
1687*1c60b9acSAndroid Build Coastguard Worker struct lws_context *
lws_ss_get_context(struct lws_ss_handle * h)1688*1c60b9acSAndroid Build Coastguard Worker lws_ss_get_context(struct lws_ss_handle *h)
1689*1c60b9acSAndroid Build Coastguard Worker {
1690*1c60b9acSAndroid Build Coastguard Worker 	return h->context;
1691*1c60b9acSAndroid Build Coastguard Worker }
1692*1c60b9acSAndroid Build Coastguard Worker 
1693*1c60b9acSAndroid Build Coastguard Worker const char *
lws_ss_rideshare(struct lws_ss_handle * h)1694*1c60b9acSAndroid Build Coastguard Worker lws_ss_rideshare(struct lws_ss_handle *h)
1695*1c60b9acSAndroid Build Coastguard Worker {
1696*1c60b9acSAndroid Build Coastguard Worker 	if (!h->rideshare)
1697*1c60b9acSAndroid Build Coastguard Worker 		return h->policy->streamtype;
1698*1c60b9acSAndroid Build Coastguard Worker 
1699*1c60b9acSAndroid Build Coastguard Worker 	return h->rideshare->streamtype;
1700*1c60b9acSAndroid Build Coastguard Worker }
1701*1c60b9acSAndroid Build Coastguard Worker 
1702*1c60b9acSAndroid Build Coastguard Worker int
lws_ss_add_peer_tx_credit(struct lws_ss_handle * h,int32_t bump)1703*1c60b9acSAndroid Build Coastguard Worker lws_ss_add_peer_tx_credit(struct lws_ss_handle *h, int32_t bump)
1704*1c60b9acSAndroid Build Coastguard Worker {
1705*1c60b9acSAndroid Build Coastguard Worker 	const struct ss_pcols *ssp;
1706*1c60b9acSAndroid Build Coastguard Worker 
1707*1c60b9acSAndroid Build Coastguard Worker 	lws_service_assert_loop_thread(h->context, h->tsi);
1708*1c60b9acSAndroid Build Coastguard Worker 
1709*1c60b9acSAndroid Build Coastguard Worker 	ssp = ss_pcols[(int)h->policy->protocol];
1710*1c60b9acSAndroid Build Coastguard Worker 
1711*1c60b9acSAndroid Build Coastguard Worker 	if (h->wsi && ssp && ssp->tx_cr_add)
1712*1c60b9acSAndroid Build Coastguard Worker 		return ssp->tx_cr_add(h, bump);
1713*1c60b9acSAndroid Build Coastguard Worker 
1714*1c60b9acSAndroid Build Coastguard Worker 	return 0;
1715*1c60b9acSAndroid Build Coastguard Worker }
1716*1c60b9acSAndroid Build Coastguard Worker 
1717*1c60b9acSAndroid Build Coastguard Worker int
lws_ss_get_est_peer_tx_credit(struct lws_ss_handle * h)1718*1c60b9acSAndroid Build Coastguard Worker lws_ss_get_est_peer_tx_credit(struct lws_ss_handle *h)
1719*1c60b9acSAndroid Build Coastguard Worker {
1720*1c60b9acSAndroid Build Coastguard Worker 	const struct ss_pcols *ssp;
1721*1c60b9acSAndroid Build Coastguard Worker 
1722*1c60b9acSAndroid Build Coastguard Worker 	lws_service_assert_loop_thread(h->context, h->tsi);
1723*1c60b9acSAndroid Build Coastguard Worker 
1724*1c60b9acSAndroid Build Coastguard Worker 	ssp = ss_pcols[(int)h->policy->protocol];
1725*1c60b9acSAndroid Build Coastguard Worker 
1726*1c60b9acSAndroid Build Coastguard Worker 	if (h->wsi && ssp && ssp->tx_cr_add)
1727*1c60b9acSAndroid Build Coastguard Worker 		return ssp->tx_cr_est(h);
1728*1c60b9acSAndroid Build Coastguard Worker 
1729*1c60b9acSAndroid Build Coastguard Worker 	return 0;
1730*1c60b9acSAndroid Build Coastguard Worker }
1731*1c60b9acSAndroid Build Coastguard Worker 
1732*1c60b9acSAndroid Build Coastguard Worker /*
1733*1c60b9acSAndroid Build Coastguard Worker  * protocol-independent handler for ss timeout
1734*1c60b9acSAndroid Build Coastguard Worker  */
1735*1c60b9acSAndroid Build Coastguard Worker 
1736*1c60b9acSAndroid Build Coastguard Worker static void
lws_ss_to_cb(lws_sorted_usec_list_t * sul)1737*1c60b9acSAndroid Build Coastguard Worker lws_ss_to_cb(lws_sorted_usec_list_t *sul)
1738*1c60b9acSAndroid Build Coastguard Worker {
1739*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_handle_t *h = lws_container_of(sul, lws_ss_handle_t, sul_timeout);
1740*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_state_return_t r;
1741*1c60b9acSAndroid Build Coastguard Worker 
1742*1c60b9acSAndroid Build Coastguard Worker 	lwsl_info("%s: %s timeout fired\n", __func__, lws_ss_tag(h));
1743*1c60b9acSAndroid Build Coastguard Worker 
1744*1c60b9acSAndroid Build Coastguard Worker 	r = lws_ss_event_helper(h, LWSSSCS_TIMEOUT);
1745*1c60b9acSAndroid Build Coastguard Worker 	if (r != LWSSSSRET_DISCONNECT_ME && r != LWSSSSRET_DESTROY_ME)
1746*1c60b9acSAndroid Build Coastguard Worker 		return;
1747*1c60b9acSAndroid Build Coastguard Worker 
1748*1c60b9acSAndroid Build Coastguard Worker 	if (h->wsi)
1749*1c60b9acSAndroid Build Coastguard Worker 		lws_set_timeout(h->wsi, 1, LWS_TO_KILL_ASYNC);
1750*1c60b9acSAndroid Build Coastguard Worker 
1751*1c60b9acSAndroid Build Coastguard Worker 	_lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, h->wsi, &h);
1752*1c60b9acSAndroid Build Coastguard Worker }
1753*1c60b9acSAndroid Build Coastguard Worker 
1754*1c60b9acSAndroid Build Coastguard Worker void
lws_ss_start_timeout(struct lws_ss_handle * h,unsigned int timeout_ms)1755*1c60b9acSAndroid Build Coastguard Worker lws_ss_start_timeout(struct lws_ss_handle *h, unsigned int timeout_ms)
1756*1c60b9acSAndroid Build Coastguard Worker {
1757*1c60b9acSAndroid Build Coastguard Worker 	lws_service_assert_loop_thread(h->context, h->tsi);
1758*1c60b9acSAndroid Build Coastguard Worker 
1759*1c60b9acSAndroid Build Coastguard Worker 	if (!timeout_ms && !h->policy->timeout_ms)
1760*1c60b9acSAndroid Build Coastguard Worker 		return;
1761*1c60b9acSAndroid Build Coastguard Worker 
1762*1c60b9acSAndroid Build Coastguard Worker 	lws_sul_schedule(h->context, 0, &h->sul_timeout, lws_ss_to_cb,
1763*1c60b9acSAndroid Build Coastguard Worker 			 (timeout_ms ? timeout_ms : h->policy->timeout_ms) *
1764*1c60b9acSAndroid Build Coastguard Worker 			 LWS_US_PER_MS);
1765*1c60b9acSAndroid Build Coastguard Worker }
1766*1c60b9acSAndroid Build Coastguard Worker 
1767*1c60b9acSAndroid Build Coastguard Worker void
lws_ss_cancel_timeout(struct lws_ss_handle * h)1768*1c60b9acSAndroid Build Coastguard Worker lws_ss_cancel_timeout(struct lws_ss_handle *h)
1769*1c60b9acSAndroid Build Coastguard Worker {
1770*1c60b9acSAndroid Build Coastguard Worker 	lws_service_assert_loop_thread(h->context, h->tsi);
1771*1c60b9acSAndroid Build Coastguard Worker 	lws_sul_cancel(&h->sul_timeout);
1772*1c60b9acSAndroid Build Coastguard Worker }
1773*1c60b9acSAndroid Build Coastguard Worker 
1774*1c60b9acSAndroid Build Coastguard Worker void
lws_ss_change_handlers(struct lws_ss_handle * h,lws_ss_state_return_t (* rx)(void * userobj,const uint8_t * buf,size_t len,int flags),lws_ss_state_return_t (* tx)(void * userobj,lws_ss_tx_ordinal_t ord,uint8_t * buf,size_t * len,int * flags),lws_ss_state_return_t (* state)(void * userobj,void * h_src,lws_ss_constate_t state,lws_ss_tx_ordinal_t ack))1775*1c60b9acSAndroid Build Coastguard Worker lws_ss_change_handlers(struct lws_ss_handle *h,
1776*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_state_return_t (*rx)(void *userobj, const uint8_t *buf,
1777*1c60b9acSAndroid Build Coastguard Worker 				    size_t len, int flags),
1778*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_state_return_t (*tx)(void *userobj, lws_ss_tx_ordinal_t ord,
1779*1c60b9acSAndroid Build Coastguard Worker 				    uint8_t *buf, size_t *len, int *flags),
1780*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_state_return_t (*state)(void *userobj, void *h_src /* ss handle type */,
1781*1c60b9acSAndroid Build Coastguard Worker 				       lws_ss_constate_t state,
1782*1c60b9acSAndroid Build Coastguard Worker 				       lws_ss_tx_ordinal_t ack))
1783*1c60b9acSAndroid Build Coastguard Worker {
1784*1c60b9acSAndroid Build Coastguard Worker 	if (rx)
1785*1c60b9acSAndroid Build Coastguard Worker 		h->info.rx = rx;
1786*1c60b9acSAndroid Build Coastguard Worker 	if (tx)
1787*1c60b9acSAndroid Build Coastguard Worker 		h->info.tx = tx;
1788*1c60b9acSAndroid Build Coastguard Worker 	if (state)
1789*1c60b9acSAndroid Build Coastguard Worker 		h->info.state = state;
1790*1c60b9acSAndroid Build Coastguard Worker }
1791*1c60b9acSAndroid Build Coastguard Worker 
1792*1c60b9acSAndroid Build Coastguard Worker const char *
lws_ss_tag(struct lws_ss_handle * h)1793*1c60b9acSAndroid Build Coastguard Worker lws_ss_tag(struct lws_ss_handle *h)
1794*1c60b9acSAndroid Build Coastguard Worker {
1795*1c60b9acSAndroid Build Coastguard Worker 	if (!h)
1796*1c60b9acSAndroid Build Coastguard Worker 		return "[null ss]";
1797*1c60b9acSAndroid Build Coastguard Worker 	return lws_lc_tag(&h->lc);
1798*1c60b9acSAndroid Build Coastguard Worker }
1799*1c60b9acSAndroid Build Coastguard Worker 
1800*1c60b9acSAndroid Build Coastguard Worker struct lws_log_cx *
lwsl_ss_get_cx(struct lws_ss_handle * ss)1801*1c60b9acSAndroid Build Coastguard Worker lwsl_ss_get_cx(struct lws_ss_handle *ss)
1802*1c60b9acSAndroid Build Coastguard Worker {
1803*1c60b9acSAndroid Build Coastguard Worker 	if (!ss)
1804*1c60b9acSAndroid Build Coastguard Worker 		return NULL;
1805*1c60b9acSAndroid Build Coastguard Worker 
1806*1c60b9acSAndroid Build Coastguard Worker 	return ss->lc.log_cx;
1807*1c60b9acSAndroid Build Coastguard Worker }
1808*1c60b9acSAndroid Build Coastguard Worker 
1809*1c60b9acSAndroid Build Coastguard Worker void
lws_log_prepend_ss(struct lws_log_cx * cx,void * obj,char ** p,char * e)1810*1c60b9acSAndroid Build Coastguard Worker lws_log_prepend_ss(struct lws_log_cx *cx, void *obj, char **p, char *e)
1811*1c60b9acSAndroid Build Coastguard Worker {
1812*1c60b9acSAndroid Build Coastguard Worker 	struct lws_ss_handle *h = (struct lws_ss_handle *)obj;
1813*1c60b9acSAndroid Build Coastguard Worker 
1814*1c60b9acSAndroid Build Coastguard Worker 	*p += lws_snprintf(*p, lws_ptr_diff_size_t(e, (*p)), "%s: ",
1815*1c60b9acSAndroid Build Coastguard Worker 			lws_ss_tag(h));
1816*1c60b9acSAndroid Build Coastguard Worker }
1817*1c60b9acSAndroid Build Coastguard Worker 
1818*1c60b9acSAndroid Build Coastguard Worker #if defined(_DEBUG)
1819*1c60b9acSAndroid Build Coastguard Worker void
lws_ss_assert_extant(struct lws_context * cx,int tsi,struct lws_ss_handle * h)1820*1c60b9acSAndroid Build Coastguard Worker lws_ss_assert_extant(struct lws_context *cx, int tsi, struct lws_ss_handle *h)
1821*1c60b9acSAndroid Build Coastguard Worker {
1822*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_per_thread *pt = &cx->pt[tsi];
1823*1c60b9acSAndroid Build Coastguard Worker 
1824*1c60b9acSAndroid Build Coastguard Worker 	lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1, pt->ss_owner.head) {
1825*1c60b9acSAndroid Build Coastguard Worker 		struct lws_ss_handle *h1 = lws_container_of(d,
1826*1c60b9acSAndroid Build Coastguard Worker 						struct lws_ss_handle, list);
1827*1c60b9acSAndroid Build Coastguard Worker 
1828*1c60b9acSAndroid Build Coastguard Worker 		if (h == h1)
1829*1c60b9acSAndroid Build Coastguard Worker 			return; /* okay */
1830*1c60b9acSAndroid Build Coastguard Worker 
1831*1c60b9acSAndroid Build Coastguard Worker 	} lws_end_foreach_dll_safe(d, d1);
1832*1c60b9acSAndroid Build Coastguard Worker 
1833*1c60b9acSAndroid Build Coastguard Worker 	/*
1834*1c60b9acSAndroid Build Coastguard Worker 	 * The ss handle is not listed in the pt ss handle owner...
1835*1c60b9acSAndroid Build Coastguard Worker 	 */
1836*1c60b9acSAndroid Build Coastguard Worker 
1837*1c60b9acSAndroid Build Coastguard Worker 	assert(0);
1838*1c60b9acSAndroid Build Coastguard Worker }
1839*1c60b9acSAndroid Build Coastguard Worker #endif
1840