1d4afb5ceSopenharmony_ci/*
2d4afb5ceSopenharmony_ci * libwebsockets - small server side websockets and web server implementation
3d4afb5ceSopenharmony_ci *
4d4afb5ceSopenharmony_ci * Copyright (C) 2019 - 2021 Andy Green <andy@warmcat.com>
5d4afb5ceSopenharmony_ci *
6d4afb5ceSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy
7d4afb5ceSopenharmony_ci * of this software and associated documentation files (the "Software"), to
8d4afb5ceSopenharmony_ci * deal in the Software without restriction, including without limitation the
9d4afb5ceSopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10d4afb5ceSopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is
11d4afb5ceSopenharmony_ci * furnished to do so, subject to the following conditions:
12d4afb5ceSopenharmony_ci *
13d4afb5ceSopenharmony_ci * The above copyright notice and this permission notice shall be included in
14d4afb5ceSopenharmony_ci * all copies or substantial portions of the Software.
15d4afb5ceSopenharmony_ci *
16d4afb5ceSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17d4afb5ceSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18d4afb5ceSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19d4afb5ceSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20d4afb5ceSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21d4afb5ceSopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22d4afb5ceSopenharmony_ci * IN THE SOFTWARE.
23d4afb5ceSopenharmony_ci */
24d4afb5ceSopenharmony_ci
25d4afb5ceSopenharmony_ci/* current SS Serialization protocol version */
26d4afb5ceSopenharmony_ci#define LWS_SSS_CLIENT_PROTOCOL_VERSION 1
27d4afb5ceSopenharmony_ci
28d4afb5ceSopenharmony_ci/*
29d4afb5ceSopenharmony_ci * Secure Stream state
30d4afb5ceSopenharmony_ci */
31d4afb5ceSopenharmony_ci
32d4afb5ceSopenharmony_citypedef enum {
33d4afb5ceSopenharmony_ci	SSSEQ_IDLE,
34d4afb5ceSopenharmony_ci	SSSEQ_TRY_CONNECT,
35d4afb5ceSopenharmony_ci	SSSEQ_TRY_CONNECT_NAUTH,
36d4afb5ceSopenharmony_ci	SSSEQ_TRY_CONNECT_SAUTH,
37d4afb5ceSopenharmony_ci	SSSEQ_RECONNECT_WAIT,
38d4afb5ceSopenharmony_ci	SSSEQ_DO_RETRY,
39d4afb5ceSopenharmony_ci	SSSEQ_CONNECTED,
40d4afb5ceSopenharmony_ci} lws_ss_seq_state_t;
41d4afb5ceSopenharmony_ci
42d4afb5ceSopenharmony_cistruct conn;
43d4afb5ceSopenharmony_ci
44d4afb5ceSopenharmony_ci/**
45d4afb5ceSopenharmony_ci * lws_ss_handle_t: publicly-opaque secure stream object implementation
46d4afb5ceSopenharmony_ci */
47d4afb5ceSopenharmony_ci
48d4afb5ceSopenharmony_citypedef struct lws_ss_handle {
49d4afb5ceSopenharmony_ci	lws_ss_info_t		info;	  /**< copy of stream creation info */
50d4afb5ceSopenharmony_ci
51d4afb5ceSopenharmony_ci	lws_lifecycle_t		lc;
52d4afb5ceSopenharmony_ci
53d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_METRICS)
54d4afb5ceSopenharmony_ci	lws_metrics_caliper_compose(cal_txn)
55d4afb5ceSopenharmony_ci#endif
56d4afb5ceSopenharmony_ci
57d4afb5ceSopenharmony_ci	struct lws_dll2		list;	  /**< pt lists active ss */
58d4afb5ceSopenharmony_ci	struct lws_dll2		to_list;  /**< pt lists ss with pending to-s */
59d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SERVER)
60d4afb5ceSopenharmony_ci	struct lws_dll2		cli_list;  /**< same server clients list */
61d4afb5ceSopenharmony_ci#endif
62d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_FAULT_INJECTION)
63d4afb5ceSopenharmony_ci	lws_fi_ctx_t		fic;	/**< Fault Injection context */
64d4afb5ceSopenharmony_ci#endif
65d4afb5ceSopenharmony_ci
66d4afb5ceSopenharmony_ci	struct lws_dll2_owner	src_list; /**< sink's list of bound sources */
67d4afb5ceSopenharmony_ci
68d4afb5ceSopenharmony_ci	struct lws_context      *context; /**< lws context we are created on */
69d4afb5ceSopenharmony_ci	const lws_ss_policy_t	*policy;  /**< system policy for stream */
70d4afb5ceSopenharmony_ci
71d4afb5ceSopenharmony_ci	struct lws_sequencer	*seq;	  /**< owning sequencer if any */
72d4afb5ceSopenharmony_ci	struct lws		*wsi;	  /**< the stream wsi if any */
73d4afb5ceSopenharmony_ci
74d4afb5ceSopenharmony_ci	struct conn		*conn_if_sspc_onw;
75d4afb5ceSopenharmony_ci
76d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SSPLUGINS)
77d4afb5ceSopenharmony_ci	void			*nauthi;  /**< the nauth plugin instance data */
78d4afb5ceSopenharmony_ci	void			*sauthi;  /**< the sauth plugin instance data */
79d4afb5ceSopenharmony_ci#endif
80d4afb5ceSopenharmony_ci
81d4afb5ceSopenharmony_ci	lws_ss_metadata_t	*metadata;
82d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SS_DIRECT_PROTOCOL_STR)
83d4afb5ceSopenharmony_ci	lws_ss_metadata_t	*instant_metadata; /**< for set instant metadata */
84d4afb5ceSopenharmony_ci	struct lwsac            *imd_ac;           /**< for get custom header */
85d4afb5ceSopenharmony_ci#endif
86d4afb5ceSopenharmony_ci	const lws_ss_policy_t	*rideshare;
87d4afb5ceSopenharmony_ci	struct lws_ss_handle	*h_in_svc;
88d4afb5ceSopenharmony_ci
89d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CONMON)
90d4afb5ceSopenharmony_ci	char			*conmon_json;
91d4afb5ceSopenharmony_ci#endif
92d4afb5ceSopenharmony_ci
93d4afb5ceSopenharmony_ci	//struct lws_ss_handle	*h_sink;  /**< sink we are bound to, or NULL */
94d4afb5ceSopenharmony_ci	//void 			*sink_obj;/**< sink's private object representing us */
95d4afb5ceSopenharmony_ci
96d4afb5ceSopenharmony_ci	lws_sorted_usec_list_t	sul_timeout;
97d4afb5ceSopenharmony_ci	lws_sorted_usec_list_t	sul;
98d4afb5ceSopenharmony_ci	lws_ss_tx_ordinal_t	txord;
99d4afb5ceSopenharmony_ci
100d4afb5ceSopenharmony_ci	/* protocol-specific connection helpers */
101d4afb5ceSopenharmony_ci
102d4afb5ceSopenharmony_ci	union {
103d4afb5ceSopenharmony_ci
104d4afb5ceSopenharmony_ci		/* ...for http-related protocols... */
105d4afb5ceSopenharmony_ci
106d4afb5ceSopenharmony_ci		struct {
107d4afb5ceSopenharmony_ci
108d4afb5ceSopenharmony_ci			/* common to all http-related protocols */
109d4afb5ceSopenharmony_ci
110d4afb5ceSopenharmony_ci			/* incoming multipart parsing */
111d4afb5ceSopenharmony_ci
112d4afb5ceSopenharmony_ci			char boundary[24];	/* --boundary from headers */
113d4afb5ceSopenharmony_ci			uint8_t boundary_len;	/* length of --boundary */
114d4afb5ceSopenharmony_ci			uint8_t boundary_seq;	/* current match amount */
115d4afb5ceSopenharmony_ci			uint8_t boundary_dashes; /* check for -- after */
116d4afb5ceSopenharmony_ci			uint8_t boundary_post; /* swallow post CRLF */
117d4afb5ceSopenharmony_ci
118d4afb5ceSopenharmony_ci			uint8_t som:1;	/* SOM has been sent */
119d4afb5ceSopenharmony_ci			uint8_t eom:1;  /* EOM has been sent */
120d4afb5ceSopenharmony_ci			uint8_t any:1;	/* any content has been sent */
121d4afb5ceSopenharmony_ci
122d4afb5ceSopenharmony_ci
123d4afb5ceSopenharmony_ci			uint8_t good_respcode:1; /* 200 type response code */
124d4afb5ceSopenharmony_ci
125d4afb5ceSopenharmony_ci			union {
126d4afb5ceSopenharmony_ci				struct { /* LWSSSP_H1 */
127d4afb5ceSopenharmony_ci#if defined(WIN32)
128d4afb5ceSopenharmony_ci					uint8_t dummy;
129d4afb5ceSopenharmony_ci#endif
130d4afb5ceSopenharmony_ci				} h1;
131d4afb5ceSopenharmony_ci				struct { /* LWSSSP_H2 */
132d4afb5ceSopenharmony_ci#if defined(WIN32)
133d4afb5ceSopenharmony_ci					uint8_t dummy;
134d4afb5ceSopenharmony_ci#endif
135d4afb5ceSopenharmony_ci				} h2;
136d4afb5ceSopenharmony_ci				struct { /* LWSSSP_WS */
137d4afb5ceSopenharmony_ci#if defined(WIN32)
138d4afb5ceSopenharmony_ci					uint8_t dummy;
139d4afb5ceSopenharmony_ci#endif
140d4afb5ceSopenharmony_ci				} ws;
141d4afb5ceSopenharmony_ci			} u;
142d4afb5ceSopenharmony_ci		} http;
143d4afb5ceSopenharmony_ci
144d4afb5ceSopenharmony_ci		/* details for non-http related protocols... */
145d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_MQTT)
146d4afb5ceSopenharmony_ci		struct {
147d4afb5ceSopenharmony_ci			lws_mqtt_topic_elem_t		topic_qos;
148d4afb5ceSopenharmony_ci			lws_mqtt_topic_elem_t		sub_top;
149d4afb5ceSopenharmony_ci			lws_mqtt_subscribe_param_t 	sub_info;
150d4afb5ceSopenharmony_ci			lws_mqtt_subscribe_param_t 	shadow_sub;
151d4afb5ceSopenharmony_ci			/* allocation that must be destroyed with conn */
152d4afb5ceSopenharmony_ci			void				*heap_baggage;
153d4afb5ceSopenharmony_ci			const char			*subscribe_to;
154d4afb5ceSopenharmony_ci			size_t				subscribe_to_len;
155d4afb5ceSopenharmony_ci			struct lws_buflist		*buflist_unacked;
156d4afb5ceSopenharmony_ci			uint32_t			unacked_size;
157d4afb5ceSopenharmony_ci			uint8_t				retry_count;
158d4afb5ceSopenharmony_ci			uint8_t				send_unacked:1;
159d4afb5ceSopenharmony_ci		} mqtt;
160d4afb5ceSopenharmony_ci#endif
161d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_SMD)
162d4afb5ceSopenharmony_ci		struct {
163d4afb5ceSopenharmony_ci			struct lws_smd_peer		*smd_peer;
164d4afb5ceSopenharmony_ci			lws_sorted_usec_list_t		sul_write;
165d4afb5ceSopenharmony_ci		} smd;
166d4afb5ceSopenharmony_ci#endif
167d4afb5ceSopenharmony_ci	} u;
168d4afb5ceSopenharmony_ci
169d4afb5ceSopenharmony_ci	unsigned long		writeable_len;
170d4afb5ceSopenharmony_ci
171d4afb5ceSopenharmony_ci	lws_ss_constate_t	connstate;/**< public connection state */
172d4afb5ceSopenharmony_ci	lws_ss_seq_state_t	seqstate; /**< private connection state */
173d4afb5ceSopenharmony_ci	lws_ss_state_return_t	pending_ret; /**< holds desired disposition
174d4afb5ceSopenharmony_ci						* for ss during CCE */
175d4afb5ceSopenharmony_ci
176d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SERVER)
177d4afb5ceSopenharmony_ci	int			txn_resp;
178d4afb5ceSopenharmony_ci#endif
179d4afb5ceSopenharmony_ci
180d4afb5ceSopenharmony_ci	uint16_t		retry;	  /**< retry / backoff tracking */
181d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CONMON)
182d4afb5ceSopenharmony_ci	uint16_t		conmon_len;
183d4afb5ceSopenharmony_ci#endif
184d4afb5ceSopenharmony_ci	int16_t			temp16;
185d4afb5ceSopenharmony_ci
186d4afb5ceSopenharmony_ci	uint8_t			tsi;	  /**< service thread idx, usually 0 */
187d4afb5ceSopenharmony_ci	uint8_t			subseq;	  /**< emulate SOM tracking */
188d4afb5ceSopenharmony_ci	uint8_t			txn_ok;	  /**< 1 = transaction was OK */
189d4afb5ceSopenharmony_ci	uint8_t			prev_ss_state;
190d4afb5ceSopenharmony_ci
191d4afb5ceSopenharmony_ci	uint8_t			txn_resp_set:1; /**< user code set one */
192d4afb5ceSopenharmony_ci	uint8_t			txn_resp_pending:1; /**< we have yet to send */
193d4afb5ceSopenharmony_ci	uint8_t			hanging_som:1;
194d4afb5ceSopenharmony_ci	uint8_t			inside_msg:1;
195d4afb5ceSopenharmony_ci	uint8_t			being_serialized:1; /* we are not the consumer */
196d4afb5ceSopenharmony_ci	uint8_t			destroying:1;
197d4afb5ceSopenharmony_ci	uint8_t			ss_dangling_connected:1;
198d4afb5ceSopenharmony_ci	uint8_t			proxy_onward:1; /* opaque is conn */
199d4afb5ceSopenharmony_ci	uint8_t			inside_connect:1; /* set if we are currently
200d4afb5ceSopenharmony_ci						   * creating the onward
201d4afb5ceSopenharmony_ci						   * connect */
202d4afb5ceSopenharmony_ci} lws_ss_handle_t;
203d4afb5ceSopenharmony_ci
204d4afb5ceSopenharmony_ci/* connection helper that doesn't need to hang around after connection starts */
205d4afb5ceSopenharmony_ci
206d4afb5ceSopenharmony_ciunion lws_ss_contemp {
207d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_MQTT)
208d4afb5ceSopenharmony_ci	lws_mqtt_client_connect_param_t ccp;
209d4afb5ceSopenharmony_ci#else
210d4afb5ceSopenharmony_ci#if defined(WIN32)
211d4afb5ceSopenharmony_ci	uint8_t	dummy;
212d4afb5ceSopenharmony_ci#endif
213d4afb5ceSopenharmony_ci#endif
214d4afb5ceSopenharmony_ci};
215d4afb5ceSopenharmony_ci
216d4afb5ceSopenharmony_ci/*
217d4afb5ceSopenharmony_ci * When allocating the opaque handle, we overallocate for:
218d4afb5ceSopenharmony_ci *
219d4afb5ceSopenharmony_ci *  1) policy->nauth_plugin->alloc (.nauthi) if any
220d4afb5ceSopenharmony_ci *  2) policy->sauth_plugin->alloc (.sauthi) if any
221d4afb5ceSopenharmony_ci *  3) copy of creation info stream type pointed to by info.streamtype... this
222d4afb5ceSopenharmony_ci *     may be arbitrarily long and since it may be coming from socket ipc and be
223d4afb5ceSopenharmony_ci *     temporary at creation time, we need a place for the copy to stay in scope
224d4afb5ceSopenharmony_ci *  4) copy of info->streamtype contents
225d4afb5ceSopenharmony_ci */
226d4afb5ceSopenharmony_ci
227d4afb5ceSopenharmony_ci
228d4afb5ceSopenharmony_ci/* the user object allocation is immediately after the ss object allocation */
229d4afb5ceSopenharmony_ci#define ss_to_userobj(ss) ((void *)&(ss)[1])
230d4afb5ceSopenharmony_ci
231d4afb5ceSopenharmony_ci/*
232d4afb5ceSopenharmony_ci * serialization parser state
233d4afb5ceSopenharmony_ci */
234d4afb5ceSopenharmony_ci
235d4afb5ceSopenharmony_cienum {
236d4afb5ceSopenharmony_ci	KIND_C_TO_P,
237d4afb5ceSopenharmony_ci	KIND_SS_TO_P,
238d4afb5ceSopenharmony_ci};
239d4afb5ceSopenharmony_ci
240d4afb5ceSopenharmony_cistruct lws_ss_serialization_parser {
241d4afb5ceSopenharmony_ci	char			streamtype[32];
242d4afb5ceSopenharmony_ci	char			rideshare[32];
243d4afb5ceSopenharmony_ci	char			metadata_name[32];
244d4afb5ceSopenharmony_ci
245d4afb5ceSopenharmony_ci	uint64_t		ust_pwait;
246d4afb5ceSopenharmony_ci
247d4afb5ceSopenharmony_ci	lws_ss_metadata_t	*ssmd;
248d4afb5ceSopenharmony_ci	uint8_t			*rxmetaval;
249d4afb5ceSopenharmony_ci
250d4afb5ceSopenharmony_ci	int			ps;
251d4afb5ceSopenharmony_ci	int			ctr;
252d4afb5ceSopenharmony_ci
253d4afb5ceSopenharmony_ci	uint32_t		usd_phandling;
254d4afb5ceSopenharmony_ci	uint32_t		flags;
255d4afb5ceSopenharmony_ci	uint32_t		client_pid;
256d4afb5ceSopenharmony_ci	int32_t			temp32;
257d4afb5ceSopenharmony_ci
258d4afb5ceSopenharmony_ci	int32_t			txcr_out;
259d4afb5ceSopenharmony_ci	int32_t			txcr_in;
260d4afb5ceSopenharmony_ci	uint16_t		rem;
261d4afb5ceSopenharmony_ci
262d4afb5ceSopenharmony_ci	uint8_t			type;
263d4afb5ceSopenharmony_ci	uint8_t			frag1;
264d4afb5ceSopenharmony_ci	uint8_t			slen;
265d4afb5ceSopenharmony_ci	uint8_t			rsl_pos;
266d4afb5ceSopenharmony_ci	uint8_t			rsl_idx;
267d4afb5ceSopenharmony_ci	uint8_t			protocol_version;
268d4afb5ceSopenharmony_ci};
269d4afb5ceSopenharmony_ci
270d4afb5ceSopenharmony_ci/*
271d4afb5ceSopenharmony_ci * Unlike locally-fulfilled SS, SSS doesn't have to hold metadata on client side
272d4afb5ceSopenharmony_ci * but pass it through to the proxy.  The client side doesn't know the real
273d4afb5ceSopenharmony_ci * metadata names that are available in the policy (since it's hardcoded in code
274d4afb5ceSopenharmony_ci * no point passing them back to the client from the policy).  Because of that,
275d4afb5ceSopenharmony_ci * it doesn't know how many to allocate when we create the sspc_handle either.
276d4afb5ceSopenharmony_ci *
277d4afb5ceSopenharmony_ci * So we use a linked-list of changed-but-not-yet-proxied metadata allocated
278d4afb5ceSopenharmony_ci * on the heap and items removed as they are proxied out.  Anything on the list
279d4afb5ceSopenharmony_ci * is sent to the proxy before any requested tx is handled.
280d4afb5ceSopenharmony_ci *
281d4afb5ceSopenharmony_ci * This is also used to queue tx credit changes
282d4afb5ceSopenharmony_ci */
283d4afb5ceSopenharmony_ci
284d4afb5ceSopenharmony_citypedef struct lws_sspc_metadata {
285d4afb5ceSopenharmony_ci	lws_dll2_t	list;
286d4afb5ceSopenharmony_ci	char		name[32];  /* empty string, then actually TCXR */
287d4afb5ceSopenharmony_ci	size_t		len;
288d4afb5ceSopenharmony_ci	int		tx_cr_adjust;
289d4afb5ceSopenharmony_ci
290d4afb5ceSopenharmony_ci	/* the value of length .len is overallocated after this */
291d4afb5ceSopenharmony_ci} lws_sspc_metadata_t;
292d4afb5ceSopenharmony_ci
293d4afb5ceSopenharmony_ci/* state of the upstream proxy onward connection */
294d4afb5ceSopenharmony_ci
295d4afb5ceSopenharmony_cienum {
296d4afb5ceSopenharmony_ci	LWSSSPC_ONW_NONE,
297d4afb5ceSopenharmony_ci	LWSSSPC_ONW_REQ,
298d4afb5ceSopenharmony_ci	LWSSSPC_ONW_ONGOING,
299d4afb5ceSopenharmony_ci	LWSSSPC_ONW_CONN,
300d4afb5ceSopenharmony_ci};
301d4afb5ceSopenharmony_ci
302d4afb5ceSopenharmony_citypedef struct lws_sspc_handle {
303d4afb5ceSopenharmony_ci	char			rideshare_list[128];
304d4afb5ceSopenharmony_ci
305d4afb5ceSopenharmony_ci	lws_lifecycle_t		lc;
306d4afb5ceSopenharmony_ci
307d4afb5ceSopenharmony_ci	lws_ss_info_t		ssi;
308d4afb5ceSopenharmony_ci	lws_sorted_usec_list_t	sul_retry;
309d4afb5ceSopenharmony_ci
310d4afb5ceSopenharmony_ci	struct lws_ss_serialization_parser parser;
311d4afb5ceSopenharmony_ci
312d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_FAULT_INJECTION)
313d4afb5ceSopenharmony_ci	lws_fi_ctx_t		fic;	/**< Fault Injection context */
314d4afb5ceSopenharmony_ci#endif
315d4afb5ceSopenharmony_ci
316d4afb5ceSopenharmony_ci	lws_dll2_owner_t	metadata_owner;
317d4afb5ceSopenharmony_ci	lws_dll2_owner_t	metadata_owner_rx;
318d4afb5ceSopenharmony_ci
319d4afb5ceSopenharmony_ci	struct lws_dll2		client_list;
320d4afb5ceSopenharmony_ci	struct lws_tx_credit	txc;
321d4afb5ceSopenharmony_ci
322d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_METRICS)
323d4afb5ceSopenharmony_ci	lws_metrics_caliper_compose(cal_txn)
324d4afb5ceSopenharmony_ci#endif
325d4afb5ceSopenharmony_ci
326d4afb5ceSopenharmony_ci	struct lws		*cwsi;
327d4afb5ceSopenharmony_ci
328d4afb5ceSopenharmony_ci	struct lws_dsh		*dsh;
329d4afb5ceSopenharmony_ci	struct lws_context	*context;
330d4afb5ceSopenharmony_ci
331d4afb5ceSopenharmony_ci	struct lws_sspc_handle	*h_in_svc;
332d4afb5ceSopenharmony_ci	/*
333d4afb5ceSopenharmony_ci	 * Used to detect illegal lws_sspc_destroy() calls while still
334d4afb5ceSopenharmony_ci	 * being serviced
335d4afb5ceSopenharmony_ci	 */
336d4afb5ceSopenharmony_ci
337d4afb5ceSopenharmony_ci	lws_usec_t		us_earliest_write_req;
338d4afb5ceSopenharmony_ci	lws_usec_t		us_start_upstream;
339d4afb5ceSopenharmony_ci
340d4afb5ceSopenharmony_ci	unsigned long		writeable_len;
341d4afb5ceSopenharmony_ci
342d4afb5ceSopenharmony_ci	lws_ss_conn_states_t	state;
343d4afb5ceSopenharmony_ci
344d4afb5ceSopenharmony_ci	uint32_t		timeout_ms;
345d4afb5ceSopenharmony_ci	uint32_t		ord;
346d4afb5ceSopenharmony_ci
347d4afb5ceSopenharmony_ci	int16_t			temp16;
348d4afb5ceSopenharmony_ci
349d4afb5ceSopenharmony_ci	uint8_t			rideshare_ofs[4];
350d4afb5ceSopenharmony_ci	uint8_t			rsidx;
351d4afb5ceSopenharmony_ci
352d4afb5ceSopenharmony_ci	uint8_t			prev_ss_state;
353d4afb5ceSopenharmony_ci
354d4afb5ceSopenharmony_ci	uint8_t			conn_req_state:2;
355d4afb5ceSopenharmony_ci	uint8_t			destroying:1;
356d4afb5ceSopenharmony_ci	uint8_t			non_wsi:1;
357d4afb5ceSopenharmony_ci	uint8_t			ignore_txc:1;
358d4afb5ceSopenharmony_ci	uint8_t			pending_timeout_update:1;
359d4afb5ceSopenharmony_ci	uint8_t			pending_writeable_len:1;
360d4afb5ceSopenharmony_ci	uint8_t			creating_cb_done:1;
361d4afb5ceSopenharmony_ci	uint8_t			ss_dangling_connected:1;
362d4afb5ceSopenharmony_ci} lws_sspc_handle_t;
363d4afb5ceSopenharmony_ci
364d4afb5ceSopenharmony_citypedef struct backoffs {
365d4afb5ceSopenharmony_ci	struct backoffs *next;
366d4afb5ceSopenharmony_ci	const char *name;
367d4afb5ceSopenharmony_ci	lws_retry_bo_t r;
368d4afb5ceSopenharmony_ci} backoff_t;
369d4afb5ceSopenharmony_ci
370d4afb5ceSopenharmony_ciunion u {
371d4afb5ceSopenharmony_ci	backoff_t		*b;
372d4afb5ceSopenharmony_ci	lws_ss_x509_t		*x;
373d4afb5ceSopenharmony_ci	lws_ss_trust_store_t	*t;
374d4afb5ceSopenharmony_ci	lws_ss_policy_t		*p;
375d4afb5ceSopenharmony_ci	lws_ss_auth_t		*a;
376d4afb5ceSopenharmony_ci	lws_metric_policy_t	*m;
377d4afb5ceSopenharmony_ci};
378d4afb5ceSopenharmony_ci
379d4afb5ceSopenharmony_cienum {
380d4afb5ceSopenharmony_ci	LTY_BACKOFF,
381d4afb5ceSopenharmony_ci	LTY_X509,
382d4afb5ceSopenharmony_ci	LTY_TRUSTSTORE,
383d4afb5ceSopenharmony_ci	LTY_POLICY,
384d4afb5ceSopenharmony_ci	LTY_AUTH,
385d4afb5ceSopenharmony_ci	LTY_METRICS,
386d4afb5ceSopenharmony_ci
387d4afb5ceSopenharmony_ci	_LTY_COUNT /* always last */
388d4afb5ceSopenharmony_ci};
389d4afb5ceSopenharmony_ci
390d4afb5ceSopenharmony_ci
391d4afb5ceSopenharmony_cistruct policy_cb_args {
392d4afb5ceSopenharmony_ci	struct lejp_ctx jctx;
393d4afb5ceSopenharmony_ci	struct lws_context *context;
394d4afb5ceSopenharmony_ci	struct lwsac *ac;
395d4afb5ceSopenharmony_ci
396d4afb5ceSopenharmony_ci	const char *socks5_proxy;
397d4afb5ceSopenharmony_ci
398d4afb5ceSopenharmony_ci	struct lws_b64state b64;
399d4afb5ceSopenharmony_ci
400d4afb5ceSopenharmony_ci	lws_ss_http_respmap_t respmap[16];
401d4afb5ceSopenharmony_ci
402d4afb5ceSopenharmony_ci	union u heads[_LTY_COUNT];
403d4afb5ceSopenharmony_ci	union u curr[_LTY_COUNT];
404d4afb5ceSopenharmony_ci
405d4afb5ceSopenharmony_ci	uint8_t *p;
406d4afb5ceSopenharmony_ci
407d4afb5ceSopenharmony_ci	int count;
408d4afb5ceSopenharmony_ci	char pending_respmap;
409d4afb5ceSopenharmony_ci
410d4afb5ceSopenharmony_ci	uint8_t parse_data:1;
411d4afb5ceSopenharmony_ci};
412d4afb5ceSopenharmony_ci
413d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_SMD)
414d4afb5ceSopenharmony_ciextern const lws_ss_policy_t pol_smd;
415d4afb5ceSopenharmony_ci#endif
416d4afb5ceSopenharmony_ci
417d4afb5ceSopenharmony_ci
418d4afb5ceSopenharmony_ci/*
419d4afb5ceSopenharmony_ci * returns one of
420d4afb5ceSopenharmony_ci *
421d4afb5ceSopenharmony_ci * 	LWSSSSRET_OK
422d4afb5ceSopenharmony_ci *	LWSSSSRET_DISCONNECT_ME
423d4afb5ceSopenharmony_ci *	LWSSSSRET_DESTROY_ME
424d4afb5ceSopenharmony_ci */
425d4afb5ceSopenharmony_ciint
426d4afb5ceSopenharmony_cilws_ss_deserialize_parse(struct lws_ss_serialization_parser *par,
427d4afb5ceSopenharmony_ci			 struct lws_context *context,
428d4afb5ceSopenharmony_ci			 struct lws_dsh *dsh, const uint8_t *cp, size_t len,
429d4afb5ceSopenharmony_ci			 lws_ss_conn_states_t *state, void *parconn,
430d4afb5ceSopenharmony_ci			 lws_ss_handle_t **pss, lws_ss_info_t *ssi, char client);
431d4afb5ceSopenharmony_ciint
432d4afb5ceSopenharmony_cilws_ss_serialize_rx_payload(struct lws_dsh *dsh, const uint8_t *buf,
433d4afb5ceSopenharmony_ci			    size_t len, int flags, const char *rsp);
434d4afb5ceSopenharmony_ciint
435d4afb5ceSopenharmony_cilws_ss_deserialize_tx_payload(struct lws_dsh *dsh, struct lws *wsi,
436d4afb5ceSopenharmony_ci			      lws_ss_tx_ordinal_t ord, uint8_t *buf,
437d4afb5ceSopenharmony_ci			      size_t *len, int *flags);
438d4afb5ceSopenharmony_ciint
439d4afb5ceSopenharmony_cilws_ss_serialize_state(struct lws *wsi, struct lws_dsh *dsh, lws_ss_constate_t state,
440d4afb5ceSopenharmony_ci		       lws_ss_tx_ordinal_t ack);
441d4afb5ceSopenharmony_ci
442d4afb5ceSopenharmony_ciconst lws_ss_policy_t *
443d4afb5ceSopenharmony_cilws_ss_policy_lookup(const struct lws_context *context, const char *streamtype);
444d4afb5ceSopenharmony_ci
445d4afb5ceSopenharmony_ci/* can be used as a cb from lws_dll2_foreach_safe() to destroy ss */
446d4afb5ceSopenharmony_ciint
447d4afb5ceSopenharmony_cilws_ss_destroy_dll(struct lws_dll2 *d, void *user);
448d4afb5ceSopenharmony_ci
449d4afb5ceSopenharmony_ciint
450d4afb5ceSopenharmony_cilws_sspc_destroy_dll(struct lws_dll2 *d, void *user);
451d4afb5ceSopenharmony_ci
452d4afb5ceSopenharmony_civoid
453d4afb5ceSopenharmony_cilws_sspc_rxmetadata_destroy(lws_sspc_handle_t *h);
454d4afb5ceSopenharmony_ci
455d4afb5ceSopenharmony_ciint
456d4afb5ceSopenharmony_cilws_ss_policy_set(struct lws_context *context, const char *name);
457d4afb5ceSopenharmony_ci
458d4afb5ceSopenharmony_ciint
459d4afb5ceSopenharmony_cilws_ss_sys_fetch_policy(struct lws_context *context);
460d4afb5ceSopenharmony_ci
461d4afb5ceSopenharmony_cilws_ss_state_return_t
462d4afb5ceSopenharmony_cilws_ss_event_helper(lws_ss_handle_t *h, lws_ss_constate_t cs);
463d4afb5ceSopenharmony_ci
464d4afb5ceSopenharmony_cilws_ss_state_return_t
465d4afb5ceSopenharmony_ci_lws_ss_backoff(lws_ss_handle_t *h, lws_usec_t us_override);
466d4afb5ceSopenharmony_ci
467d4afb5ceSopenharmony_cilws_ss_state_return_t
468d4afb5ceSopenharmony_cilws_ss_backoff(lws_ss_handle_t *h);
469d4afb5ceSopenharmony_ci
470d4afb5ceSopenharmony_ciint
471d4afb5ceSopenharmony_ci_lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(lws_ss_state_return_t r, struct lws *wsi,
472d4afb5ceSopenharmony_ci			 lws_ss_handle_t **ph);
473d4afb5ceSopenharmony_ci
474d4afb5ceSopenharmony_ciint
475d4afb5ceSopenharmony_cilws_ss_set_timeout_us(lws_ss_handle_t *h, lws_usec_t us);
476d4afb5ceSopenharmony_ci
477d4afb5ceSopenharmony_civoid
478d4afb5ceSopenharmony_ciss_proxy_onward_txcr(void *userobj, int bump);
479d4afb5ceSopenharmony_ci
480d4afb5ceSopenharmony_ciint
481d4afb5ceSopenharmony_cilws_ss_serialize_txcr(struct lws_dsh *dsh, int txcr);
482d4afb5ceSopenharmony_ci
483d4afb5ceSopenharmony_ciint
484d4afb5ceSopenharmony_cilws_ss_sys_auth_api_amazon_com(struct lws_context *context);
485d4afb5ceSopenharmony_ci
486d4afb5ceSopenharmony_cilws_ss_metadata_t *
487d4afb5ceSopenharmony_cilws_ss_get_handle_metadata(struct lws_ss_handle *h, const char *name);
488d4afb5ceSopenharmony_cilws_ss_metadata_t *
489d4afb5ceSopenharmony_cilws_ss_policy_metadata_index(const lws_ss_policy_t *p, size_t index);
490d4afb5ceSopenharmony_ci
491d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SS_DIRECT_PROTOCOL_STR)
492d4afb5ceSopenharmony_cilws_ss_metadata_t *
493d4afb5ceSopenharmony_cilws_ss_get_handle_instant_metadata(struct lws_ss_handle *h, const char *name);
494d4afb5ceSopenharmony_ci#endif
495d4afb5ceSopenharmony_ci
496d4afb5ceSopenharmony_cilws_ss_metadata_t *
497d4afb5ceSopenharmony_cilws_ss_policy_metadata(const lws_ss_policy_t *p, const char *name);
498d4afb5ceSopenharmony_ci
499d4afb5ceSopenharmony_ciint
500d4afb5ceSopenharmony_cilws_ss_exp_cb_metadata(void *priv, const char *name, char *out, size_t *pos,
501d4afb5ceSopenharmony_ci			size_t olen, size_t *exp_ofs);
502d4afb5ceSopenharmony_ci
503d4afb5ceSopenharmony_ciint
504d4afb5ceSopenharmony_ci_lws_ss_set_metadata(lws_ss_metadata_t *omd, const char *name,
505d4afb5ceSopenharmony_ci		     const void *value, size_t len);
506d4afb5ceSopenharmony_ci
507d4afb5ceSopenharmony_ciint
508d4afb5ceSopenharmony_ci_lws_ss_alloc_set_metadata(lws_ss_metadata_t *omd, const char *name,
509d4afb5ceSopenharmony_ci			   const void *value, size_t len);
510d4afb5ceSopenharmony_ci
511d4afb5ceSopenharmony_cilws_ss_state_return_t
512d4afb5ceSopenharmony_ci_lws_ss_client_connect(lws_ss_handle_t *h, int is_retry, void *conn_if_sspc_onw);
513d4afb5ceSopenharmony_ci
514d4afb5ceSopenharmony_cilws_ss_state_return_t
515d4afb5ceSopenharmony_ci_lws_ss_request_tx(lws_ss_handle_t *h);
516d4afb5ceSopenharmony_ci
517d4afb5ceSopenharmony_ciint
518d4afb5ceSopenharmony_ci__lws_ss_proxy_bind_ss_to_conn_wsi(void *parconn, size_t dsh_size);
519d4afb5ceSopenharmony_ci
520d4afb5ceSopenharmony_cistruct lws_vhost *
521d4afb5ceSopenharmony_cilws_ss_policy_ref_trust_store(struct lws_context *context,
522d4afb5ceSopenharmony_ci			      const lws_ss_policy_t *pol, char doref);
523d4afb5ceSopenharmony_ci
524d4afb5ceSopenharmony_cilws_ss_state_return_t
525d4afb5ceSopenharmony_cilws_sspc_event_helper(lws_sspc_handle_t *h, lws_ss_constate_t cs,
526d4afb5ceSopenharmony_ci		      lws_ss_tx_ordinal_t flags);
527d4afb5ceSopenharmony_ci
528d4afb5ceSopenharmony_ciint
529d4afb5ceSopenharmony_cilws_ss_check_next_state(lws_lifecycle_t *lc, uint8_t *prevstate,
530d4afb5ceSopenharmony_ci			lws_ss_constate_t cs);
531d4afb5ceSopenharmony_ci
532d4afb5ceSopenharmony_ciint
533d4afb5ceSopenharmony_cilws_ss_check_next_state_ss(lws_ss_handle_t *ss, uint8_t *prevstate,
534d4afb5ceSopenharmony_ci			   lws_ss_constate_t cs);
535d4afb5ceSopenharmony_ci
536d4afb5ceSopenharmony_ciint
537d4afb5ceSopenharmony_cilws_ss_check_next_state_sspc(lws_sspc_handle_t *ss, uint8_t *prevstate,
538d4afb5ceSopenharmony_ci			     lws_ss_constate_t cs);
539d4afb5ceSopenharmony_ci
540d4afb5ceSopenharmony_civoid
541d4afb5ceSopenharmony_cilws_proxy_clean_conn_ss(struct lws *wsi);
542d4afb5ceSopenharmony_ci
543d4afb5ceSopenharmony_ciint
544d4afb5ceSopenharmony_cilws_ss_cancel_notify_dll(struct lws_dll2 *d, void *user);
545d4afb5ceSopenharmony_ci
546d4afb5ceSopenharmony_ciint
547d4afb5ceSopenharmony_cilws_sspc_cancel_notify_dll(struct lws_dll2 *d, void *user);
548d4afb5ceSopenharmony_ci
549d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY) || defined(LWS_WITH_SECURE_STREAMS_CPP)
550d4afb5ceSopenharmony_ciint
551d4afb5ceSopenharmony_cilws_ss_policy_unref_trust_store(struct lws_context *context,
552d4afb5ceSopenharmony_ci				const lws_ss_policy_t *pol);
553d4afb5ceSopenharmony_ci#endif
554d4afb5ceSopenharmony_ci
555d4afb5ceSopenharmony_ciint
556d4afb5ceSopenharmony_cilws_ss_sys_cpd(struct lws_context *cx);
557d4afb5ceSopenharmony_ci
558d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS_AUTH_SIGV4)
559d4afb5ceSopenharmony_ciint lws_ss_apply_sigv4(struct lws *wsi, struct lws_ss_handle *h,
560d4afb5ceSopenharmony_ci		       unsigned char **p, unsigned char *end);
561d4afb5ceSopenharmony_ci#endif
562d4afb5ceSopenharmony_ci
563d4afb5ceSopenharmony_ci#if defined(_DEBUG)
564d4afb5ceSopenharmony_civoid
565d4afb5ceSopenharmony_cilws_ss_assert_extant(struct lws_context *cx, int tsi, struct lws_ss_handle *h);
566d4afb5ceSopenharmony_ci#else
567d4afb5ceSopenharmony_ci#define lws_ss_assert_extant(_a, _b, _c)
568d4afb5ceSopenharmony_ci#endif
569d4afb5ceSopenharmony_ci
570d4afb5ceSopenharmony_citypedef int (* const secstream_protocol_connect_munge_t)(lws_ss_handle_t *h,
571d4afb5ceSopenharmony_ci		char *buf, size_t len, struct lws_client_connect_info *i,
572d4afb5ceSopenharmony_ci		union lws_ss_contemp *ct);
573d4afb5ceSopenharmony_ci
574d4afb5ceSopenharmony_citypedef int (* const secstream_protocol_add_txcr_t)(lws_ss_handle_t *h, int add);
575d4afb5ceSopenharmony_ci
576d4afb5ceSopenharmony_citypedef int (* const secstream_protocol_get_txcr_t)(lws_ss_handle_t *h);
577d4afb5ceSopenharmony_ci
578d4afb5ceSopenharmony_cistruct ss_pcols {
579d4afb5ceSopenharmony_ci	const char					*name;
580d4afb5ceSopenharmony_ci	const char					*alpn;
581d4afb5ceSopenharmony_ci	const struct lws_protocols			*protocol;
582d4afb5ceSopenharmony_ci	secstream_protocol_connect_munge_t		munge;
583d4afb5ceSopenharmony_ci	secstream_protocol_add_txcr_t			tx_cr_add;
584d4afb5ceSopenharmony_ci	secstream_protocol_get_txcr_t			tx_cr_est;
585d4afb5ceSopenharmony_ci};
586d4afb5ceSopenharmony_ci
587d4afb5ceSopenharmony_ci/*
588d4afb5ceSopenharmony_ci * Because both sides of the connection share the conn, we allocate it
589d4afb5ceSopenharmony_ci * during accepted adoption, and both sides point to it.
590d4afb5ceSopenharmony_ci *
591d4afb5ceSopenharmony_ci * When .ss or .wsi close, they must NULL their entry here so no dangling
592d4afb5ceSopenharmony_ci * refereneces.
593d4afb5ceSopenharmony_ci *
594d4afb5ceSopenharmony_ci * The last one of the accepted side and the onward side to close frees it.
595d4afb5ceSopenharmony_ci */
596d4afb5ceSopenharmony_ci
597d4afb5ceSopenharmony_cilws_ss_state_return_t
598d4afb5ceSopenharmony_cilws_conmon_ss_json(lws_ss_handle_t *h);
599d4afb5ceSopenharmony_ci
600d4afb5ceSopenharmony_civoid
601d4afb5ceSopenharmony_ciss_proxy_onward_link_req_writeable(lws_ss_handle_t *h_onward);
602d4afb5ceSopenharmony_ci
603d4afb5ceSopenharmony_cistruct conn {
604d4afb5ceSopenharmony_ci	struct lws_ss_serialization_parser parser;
605d4afb5ceSopenharmony_ci
606d4afb5ceSopenharmony_ci	lws_dsh_t		*dsh;	/* unified buffer for both sides */
607d4afb5ceSopenharmony_ci	struct lws		*wsi;	/* the proxy's client side */
608d4afb5ceSopenharmony_ci	lws_ss_handle_t		*ss;	/* the onward, ss side */
609d4afb5ceSopenharmony_ci
610d4afb5ceSopenharmony_ci	lws_ss_conn_states_t	state;
611d4afb5ceSopenharmony_ci
612d4afb5ceSopenharmony_ci	char			onward_in_flow_control;
613d4afb5ceSopenharmony_ci};
614d4afb5ceSopenharmony_ci
615d4afb5ceSopenharmony_ciextern const struct ss_pcols ss_pcol_h1;
616d4afb5ceSopenharmony_ciextern const struct ss_pcols ss_pcol_h2;
617d4afb5ceSopenharmony_ciextern const struct ss_pcols ss_pcol_ws;
618d4afb5ceSopenharmony_ciextern const struct ss_pcols ss_pcol_mqtt;
619d4afb5ceSopenharmony_ciextern const struct ss_pcols ss_pcol_raw;
620d4afb5ceSopenharmony_ci
621d4afb5ceSopenharmony_ciextern const struct lws_protocols protocol_secstream_h1;
622d4afb5ceSopenharmony_ciextern const struct lws_protocols protocol_secstream_h2;
623d4afb5ceSopenharmony_ciextern const struct lws_protocols protocol_secstream_ws;
624d4afb5ceSopenharmony_ciextern const struct lws_protocols protocol_secstream_mqtt;
625d4afb5ceSopenharmony_ciextern const struct lws_protocols protocol_secstream_raw;
626d4afb5ceSopenharmony_ci
627