1d4afb5ceSopenharmony_ci/*
2d4afb5ceSopenharmony_ci * libwebsockets - small server side websockets and web server implementation
3d4afb5ceSopenharmony_ci *
4d4afb5ceSopenharmony_ci * Copyright (C) 2010 - 2019 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#include "private-lib-core.h"
26d4afb5ceSopenharmony_ci#include "private-lib-abstract.h"
27d4afb5ceSopenharmony_ci
28d4afb5ceSopenharmony_citypedef struct lws_abstxp_raw_skt_priv {
29d4afb5ceSopenharmony_ci	struct lws_abs *abs;
30d4afb5ceSopenharmony_ci	struct lws *wsi;
31d4afb5ceSopenharmony_ci
32d4afb5ceSopenharmony_ci	lws_dll2_t same_abs_transport_list;
33d4afb5ceSopenharmony_ci
34d4afb5ceSopenharmony_ci	uint8_t established:1;
35d4afb5ceSopenharmony_ci	uint8_t connecting:1;
36d4afb5ceSopenharmony_ci} abs_raw_skt_priv_t;
37d4afb5ceSopenharmony_ci
38d4afb5ceSopenharmony_cistruct vhd {
39d4afb5ceSopenharmony_ci	lws_dll2_owner_t owner;
40d4afb5ceSopenharmony_ci};
41d4afb5ceSopenharmony_ci
42d4afb5ceSopenharmony_cistatic int
43d4afb5ceSopenharmony_ciheartbeat_cb(struct lws_dll2 *d, void *user)
44d4afb5ceSopenharmony_ci{
45d4afb5ceSopenharmony_ci	abs_raw_skt_priv_t *priv = lws_container_of(d, abs_raw_skt_priv_t,
46d4afb5ceSopenharmony_ci						    same_abs_transport_list);
47d4afb5ceSopenharmony_ci
48d4afb5ceSopenharmony_ci	if (priv->abs->ap->heartbeat)
49d4afb5ceSopenharmony_ci		priv->abs->ap->heartbeat(priv->abs->api);
50d4afb5ceSopenharmony_ci
51d4afb5ceSopenharmony_ci	return 0;
52d4afb5ceSopenharmony_ci}
53d4afb5ceSopenharmony_ci
54d4afb5ceSopenharmony_cistatic int
55d4afb5ceSopenharmony_cicallback_abs_client_raw_skt(struct lws *wsi, enum lws_callback_reasons reason,
56d4afb5ceSopenharmony_ci			    void *user, void *in, size_t len)
57d4afb5ceSopenharmony_ci{
58d4afb5ceSopenharmony_ci	abs_raw_skt_priv_t *priv = (abs_raw_skt_priv_t *)user;
59d4afb5ceSopenharmony_ci	struct vhd *vhd = (struct vhd *)
60d4afb5ceSopenharmony_ci		lws_protocol_vh_priv_get(lws_get_vhost(wsi),
61d4afb5ceSopenharmony_ci					 lws_get_protocol(wsi));
62d4afb5ceSopenharmony_ci
63d4afb5ceSopenharmony_ci	switch (reason) {
64d4afb5ceSopenharmony_ci	case LWS_CALLBACK_PROTOCOL_INIT:
65d4afb5ceSopenharmony_ci		vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
66d4afb5ceSopenharmony_ci				lws_get_protocol(wsi), sizeof(struct vhd));
67d4afb5ceSopenharmony_ci		if (!vhd)
68d4afb5ceSopenharmony_ci			return 1;
69d4afb5ceSopenharmony_ci		lws_timed_callback_vh_protocol(lws_get_vhost(wsi),
70d4afb5ceSopenharmony_ci					       lws_get_protocol(wsi),
71d4afb5ceSopenharmony_ci					       LWS_CALLBACK_USER, 1);
72d4afb5ceSopenharmony_ci		break;
73d4afb5ceSopenharmony_ci
74d4afb5ceSopenharmony_ci	case LWS_CALLBACK_USER:
75d4afb5ceSopenharmony_ci		/*
76d4afb5ceSopenharmony_ci		 * This comes at 1Hz without a wsi context, so there is no
77d4afb5ceSopenharmony_ci		 * valid priv.  We need to track the live abstract objects that
78d4afb5ceSopenharmony_ci		 * are using our abstract protocol, and pass the heartbeat
79d4afb5ceSopenharmony_ci		 * through to the ones that care.
80d4afb5ceSopenharmony_ci		 */
81d4afb5ceSopenharmony_ci		if (!vhd)
82d4afb5ceSopenharmony_ci			break;
83d4afb5ceSopenharmony_ci
84d4afb5ceSopenharmony_ci		lws_dll2_foreach_safe(&vhd->owner, NULL, heartbeat_cb);
85d4afb5ceSopenharmony_ci
86d4afb5ceSopenharmony_ci		lws_timed_callback_vh_protocol(lws_get_vhost(wsi),
87d4afb5ceSopenharmony_ci					       lws_get_protocol(wsi),
88d4afb5ceSopenharmony_ci					       LWS_CALLBACK_USER, 1);
89d4afb5ceSopenharmony_ci		break;
90d4afb5ceSopenharmony_ci
91d4afb5ceSopenharmony_ci        case LWS_CALLBACK_RAW_CONNECTED:
92d4afb5ceSopenharmony_ci		lwsl_debug("LWS_CALLBACK_RAW_CONNECTED\n");
93d4afb5ceSopenharmony_ci		priv->connecting = 0;
94d4afb5ceSopenharmony_ci		priv->established = 1;
95d4afb5ceSopenharmony_ci		if (priv->abs->ap->accept)
96d4afb5ceSopenharmony_ci			priv->abs->ap->accept(priv->abs->api);
97d4afb5ceSopenharmony_ci		if (wsi->seq)
98d4afb5ceSopenharmony_ci			/*
99d4afb5ceSopenharmony_ci			 * we are bound to a sequencer who wants to know about
100d4afb5ceSopenharmony_ci			 * our lifecycle events
101d4afb5ceSopenharmony_ci			 */
102d4afb5ceSopenharmony_ci
103d4afb5ceSopenharmony_ci			lws_seq_queue_event(wsi->seq, LWSSEQ_WSI_CONNECTED,
104d4afb5ceSopenharmony_ci						  wsi, NULL);
105d4afb5ceSopenharmony_ci                break;
106d4afb5ceSopenharmony_ci
107d4afb5ceSopenharmony_ci	case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
108d4afb5ceSopenharmony_ci		lwsl_user("CONNECTION_ERROR\n");
109d4afb5ceSopenharmony_ci		if (in)
110d4afb5ceSopenharmony_ci			lwsl_user("   %s\n", (const char *)in);
111d4afb5ceSopenharmony_ci
112d4afb5ceSopenharmony_ci		if (wsi->seq)
113d4afb5ceSopenharmony_ci			/*
114d4afb5ceSopenharmony_ci			 * we are bound to a sequencer who wants to know about
115d4afb5ceSopenharmony_ci			 * our lifecycle events
116d4afb5ceSopenharmony_ci			 */
117d4afb5ceSopenharmony_ci
118d4afb5ceSopenharmony_ci			lws_seq_queue_event(wsi->seq, LWSSEQ_WSI_CONN_FAIL,
119d4afb5ceSopenharmony_ci					    wsi, NULL);
120d4afb5ceSopenharmony_ci
121d4afb5ceSopenharmony_ci		goto close_path;
122d4afb5ceSopenharmony_ci
123d4afb5ceSopenharmony_ci		/* fallthru */
124d4afb5ceSopenharmony_ci	case LWS_CALLBACK_RAW_CLOSE:
125d4afb5ceSopenharmony_ci		if (!user)
126d4afb5ceSopenharmony_ci			break;
127d4afb5ceSopenharmony_ci
128d4afb5ceSopenharmony_ci		if (wsi->seq)
129d4afb5ceSopenharmony_ci			/*
130d4afb5ceSopenharmony_ci			 * we are bound to a sequencer who wants to know about
131d4afb5ceSopenharmony_ci			 * our lifecycle events
132d4afb5ceSopenharmony_ci			 */
133d4afb5ceSopenharmony_ci
134d4afb5ceSopenharmony_ci			lws_seq_queue_event(wsi->seq, LWSSEQ_WSI_CONN_CLOSE,
135d4afb5ceSopenharmony_ci					    wsi, NULL);
136d4afb5ceSopenharmony_ci
137d4afb5ceSopenharmony_ciclose_path:
138d4afb5ceSopenharmony_ci		lwsl_debug("LWS_CALLBACK_RAW_CLOSE\n");
139d4afb5ceSopenharmony_ci		priv->established = 0;
140d4afb5ceSopenharmony_ci		priv->connecting = 0;
141d4afb5ceSopenharmony_ci		if (priv->abs && priv->abs->ap->closed)
142d4afb5ceSopenharmony_ci			priv->abs->ap->closed(priv->abs->api);
143d4afb5ceSopenharmony_ci		lws_set_wsi_user(wsi, NULL);
144d4afb5ceSopenharmony_ci		break;
145d4afb5ceSopenharmony_ci
146d4afb5ceSopenharmony_ci	case LWS_CALLBACK_RAW_RX:
147d4afb5ceSopenharmony_ci		lwsl_debug("LWS_CALLBACK_RAW_RX (%d)\n", (int)len);
148d4afb5ceSopenharmony_ci		return !!priv->abs->ap->rx(priv->abs->api, in, len);
149d4afb5ceSopenharmony_ci
150d4afb5ceSopenharmony_ci	case LWS_CALLBACK_RAW_WRITEABLE:
151d4afb5ceSopenharmony_ci		lwsl_debug("LWS_CALLBACK_RAW_WRITEABLE\n");
152d4afb5ceSopenharmony_ci		priv->abs->ap->writeable(priv->abs->api,
153d4afb5ceSopenharmony_ci				lws_get_peer_write_allowance(priv->wsi));
154d4afb5ceSopenharmony_ci		break;
155d4afb5ceSopenharmony_ci
156d4afb5ceSopenharmony_ci	case LWS_CALLBACK_RAW_SKT_BIND_PROTOCOL:
157d4afb5ceSopenharmony_ci		lws_dll2_add_tail(&priv->same_abs_transport_list, &vhd->owner);
158d4afb5ceSopenharmony_ci		break;
159d4afb5ceSopenharmony_ci
160d4afb5ceSopenharmony_ci	case LWS_CALLBACK_RAW_SKT_DROP_PROTOCOL:
161d4afb5ceSopenharmony_ci		lws_dll2_remove(&priv->same_abs_transport_list);
162d4afb5ceSopenharmony_ci		break;
163d4afb5ceSopenharmony_ci
164d4afb5ceSopenharmony_ci	default:
165d4afb5ceSopenharmony_ci		break;
166d4afb5ceSopenharmony_ci	}
167d4afb5ceSopenharmony_ci
168d4afb5ceSopenharmony_ci	return 0;
169d4afb5ceSopenharmony_ci}
170d4afb5ceSopenharmony_ci
171d4afb5ceSopenharmony_cistatic int
172d4afb5ceSopenharmony_cilws_atcrs_close(lws_abs_transport_inst_t *ati)
173d4afb5ceSopenharmony_ci{
174d4afb5ceSopenharmony_ci	abs_raw_skt_priv_t *priv = (abs_raw_skt_priv_t *)ati;
175d4afb5ceSopenharmony_ci	struct lws *wsi = priv->wsi;
176d4afb5ceSopenharmony_ci
177d4afb5ceSopenharmony_ci	if (!priv->wsi)
178d4afb5ceSopenharmony_ci		return 0;
179d4afb5ceSopenharmony_ci
180d4afb5ceSopenharmony_ci	if (!lws_raw_transaction_completed(priv->wsi))
181d4afb5ceSopenharmony_ci		return 0;
182d4afb5ceSopenharmony_ci
183d4afb5ceSopenharmony_ci	priv->wsi = NULL;
184d4afb5ceSopenharmony_ci	lws_set_timeout(wsi, 1, LWS_TO_KILL_SYNC);
185d4afb5ceSopenharmony_ci
186d4afb5ceSopenharmony_ci	/* priv is destroyed in the CLOSE callback */
187d4afb5ceSopenharmony_ci
188d4afb5ceSopenharmony_ci	return 0;
189d4afb5ceSopenharmony_ci}
190d4afb5ceSopenharmony_ci
191d4afb5ceSopenharmony_ci
192d4afb5ceSopenharmony_ciconst struct lws_protocols protocol_abs_client_raw_skt = {
193d4afb5ceSopenharmony_ci	"lws-abs-cli-raw-skt", callback_abs_client_raw_skt,
194d4afb5ceSopenharmony_ci	0, 1024, 1024, NULL, 0
195d4afb5ceSopenharmony_ci};
196d4afb5ceSopenharmony_ci
197d4afb5ceSopenharmony_cistatic int
198d4afb5ceSopenharmony_cilws_atcrs_tx(lws_abs_transport_inst_t *ati, uint8_t *buf, size_t len)
199d4afb5ceSopenharmony_ci{
200d4afb5ceSopenharmony_ci	abs_raw_skt_priv_t *priv = (abs_raw_skt_priv_t *)ati;
201d4afb5ceSopenharmony_ci
202d4afb5ceSopenharmony_ci	if (!priv->wsi) {
203d4afb5ceSopenharmony_ci		lwsl_err("%s: NULL priv->wsi\n", __func__);
204d4afb5ceSopenharmony_ci		return 1;
205d4afb5ceSopenharmony_ci	}
206d4afb5ceSopenharmony_ci
207d4afb5ceSopenharmony_ci	lwsl_debug("%s: priv %p, wsi %p, ro %p\n", __func__,
208d4afb5ceSopenharmony_ci			priv, priv->wsi, priv->wsi->role_ops);
209d4afb5ceSopenharmony_ci
210d4afb5ceSopenharmony_ci	if (lws_write(priv->wsi, buf, len, LWS_WRITE_RAW) < 0)
211d4afb5ceSopenharmony_ci		lws_atcrs_close(ati);
212d4afb5ceSopenharmony_ci
213d4afb5ceSopenharmony_ci	return 0;
214d4afb5ceSopenharmony_ci}
215d4afb5ceSopenharmony_ci
216d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CLIENT)
217d4afb5ceSopenharmony_cistatic int
218d4afb5ceSopenharmony_cilws_atcrs_client_conn(const lws_abs_t *abs)
219d4afb5ceSopenharmony_ci{
220d4afb5ceSopenharmony_ci	abs_raw_skt_priv_t *priv = (abs_raw_skt_priv_t *)abs->ati;
221d4afb5ceSopenharmony_ci	struct lws_client_connect_info i;
222d4afb5ceSopenharmony_ci	const lws_token_map_t *tm;
223d4afb5ceSopenharmony_ci
224d4afb5ceSopenharmony_ci	if (priv->connecting)
225d4afb5ceSopenharmony_ci		return 0;
226d4afb5ceSopenharmony_ci
227d4afb5ceSopenharmony_ci	if (priv->established) {
228d4afb5ceSopenharmony_ci		lws_set_timeout(priv->wsi, PENDING_TIMEOUT_CLIENT_CONN_IDLE, 5);
229d4afb5ceSopenharmony_ci
230d4afb5ceSopenharmony_ci		return 0;
231d4afb5ceSopenharmony_ci	}
232d4afb5ceSopenharmony_ci
233d4afb5ceSopenharmony_ci	memset(&i, 0, sizeof(i));
234d4afb5ceSopenharmony_ci
235d4afb5ceSopenharmony_ci	/* address and port are passed-in using the abstract transport tokens */
236d4afb5ceSopenharmony_ci
237d4afb5ceSopenharmony_ci	tm = lws_abs_get_token(abs->at_tokens, LTMI_PEER_V_DNS_ADDRESS);
238d4afb5ceSopenharmony_ci	if (!tm) {
239d4afb5ceSopenharmony_ci		lwsl_notice("%s: raw_skt needs LTMI_PEER_V_DNS_ADDRESS\n",
240d4afb5ceSopenharmony_ci			    __func__);
241d4afb5ceSopenharmony_ci
242d4afb5ceSopenharmony_ci		return 1;
243d4afb5ceSopenharmony_ci	}
244d4afb5ceSopenharmony_ci	i.address = tm->u.value;
245d4afb5ceSopenharmony_ci
246d4afb5ceSopenharmony_ci	tm = lws_abs_get_token(abs->at_tokens, LTMI_PEER_LV_PORT);
247d4afb5ceSopenharmony_ci	if (!tm) {
248d4afb5ceSopenharmony_ci		lwsl_notice("%s: raw_skt needs LTMI_PEER_LV_PORT\n", __func__);
249d4afb5ceSopenharmony_ci
250d4afb5ceSopenharmony_ci		return 1;
251d4afb5ceSopenharmony_ci	}
252d4afb5ceSopenharmony_ci	i.port = tm->u.lvalue;
253d4afb5ceSopenharmony_ci
254d4afb5ceSopenharmony_ci	/* optional */
255d4afb5ceSopenharmony_ci	i.ssl_connection = 0;
256d4afb5ceSopenharmony_ci	tm = lws_abs_get_token(abs->at_tokens, LTMI_PEER_LV_TLS_FLAGS);
257d4afb5ceSopenharmony_ci	if (tm)
258d4afb5ceSopenharmony_ci		i.ssl_connection = tm->u.lvalue;
259d4afb5ceSopenharmony_ci
260d4afb5ceSopenharmony_ci
261d4afb5ceSopenharmony_ci	lwsl_debug("%s: raw_skt priv %p connecting to %s:%u %p\n",
262d4afb5ceSopenharmony_ci		   __func__, priv, i.address, i.port, abs->vh->context);
263d4afb5ceSopenharmony_ci
264d4afb5ceSopenharmony_ci	i.path = "";
265d4afb5ceSopenharmony_ci	i.method = "RAW";
266d4afb5ceSopenharmony_ci	i.vhost = abs->vh;
267d4afb5ceSopenharmony_ci	i.userdata = priv;
268d4afb5ceSopenharmony_ci	i.host = i.address;
269d4afb5ceSopenharmony_ci	i.pwsi = &priv->wsi;
270d4afb5ceSopenharmony_ci	i.origin = i.address;
271d4afb5ceSopenharmony_ci	i.context = abs->vh->context;
272d4afb5ceSopenharmony_ci	i.local_protocol_name = "lws-abs-cli-raw-skt";
273d4afb5ceSopenharmony_ci	i.seq = abs->seq;
274d4afb5ceSopenharmony_ci	i.opaque_user_data = abs->opaque_user_data;
275d4afb5ceSopenharmony_ci
276d4afb5ceSopenharmony_ci	/*
277d4afb5ceSopenharmony_ci	 * the protocol itself has some natural attributes we should pass on
278d4afb5ceSopenharmony_ci	 */
279d4afb5ceSopenharmony_ci
280d4afb5ceSopenharmony_ci	if (abs->ap->flags & LWS_AP_FLAG_PIPELINE_TRANSACTIONS)
281d4afb5ceSopenharmony_ci		i.ssl_connection |= LCCSCF_PIPELINE;
282d4afb5ceSopenharmony_ci
283d4afb5ceSopenharmony_ci	if (abs->ap->flags & LWS_AP_FLAG_MUXABLE_STREAM)
284d4afb5ceSopenharmony_ci		i.ssl_connection |= LCCSCF_MUXABLE_STREAM;
285d4afb5ceSopenharmony_ci
286d4afb5ceSopenharmony_ci	priv->wsi = lws_client_connect_via_info(&i);
287d4afb5ceSopenharmony_ci	if (!priv->wsi)
288d4afb5ceSopenharmony_ci		return 1;
289d4afb5ceSopenharmony_ci
290d4afb5ceSopenharmony_ci	priv->connecting = 1;
291d4afb5ceSopenharmony_ci
292d4afb5ceSopenharmony_ci	return 0;
293d4afb5ceSopenharmony_ci}
294d4afb5ceSopenharmony_ci#endif
295d4afb5ceSopenharmony_ci
296d4afb5ceSopenharmony_cistatic int
297d4afb5ceSopenharmony_cilws_atcrs_ask_for_writeable(lws_abs_transport_inst_t *ati)
298d4afb5ceSopenharmony_ci{
299d4afb5ceSopenharmony_ci	abs_raw_skt_priv_t *priv = (abs_raw_skt_priv_t *)ati;
300d4afb5ceSopenharmony_ci
301d4afb5ceSopenharmony_ci	if (!priv->wsi || !priv->established)
302d4afb5ceSopenharmony_ci		return 1;
303d4afb5ceSopenharmony_ci
304d4afb5ceSopenharmony_ci	lws_callback_on_writable(priv->wsi);
305d4afb5ceSopenharmony_ci
306d4afb5ceSopenharmony_ci	return 0;
307d4afb5ceSopenharmony_ci}
308d4afb5ceSopenharmony_ci
309d4afb5ceSopenharmony_cistatic int
310d4afb5ceSopenharmony_cilws_atcrs_create(struct lws_abs *ai)
311d4afb5ceSopenharmony_ci{
312d4afb5ceSopenharmony_ci	abs_raw_skt_priv_t *at = (abs_raw_skt_priv_t *)ai->ati;
313d4afb5ceSopenharmony_ci
314d4afb5ceSopenharmony_ci	memset(at, 0, sizeof(*at));
315d4afb5ceSopenharmony_ci	at->abs = ai;
316d4afb5ceSopenharmony_ci
317d4afb5ceSopenharmony_ci	return 0;
318d4afb5ceSopenharmony_ci}
319d4afb5ceSopenharmony_ci
320d4afb5ceSopenharmony_cistatic void
321d4afb5ceSopenharmony_cilws_atcrs_destroy(lws_abs_transport_inst_t **pati)
322d4afb5ceSopenharmony_ci{
323d4afb5ceSopenharmony_ci	/*
324d4afb5ceSopenharmony_ci	 * For ourselves, we don't free anything because the abstract layer
325d4afb5ceSopenharmony_ci	 * combined our allocation with that of the abs instance, and it will
326d4afb5ceSopenharmony_ci	 * free the whole thing after this.
327d4afb5ceSopenharmony_ci	 */
328d4afb5ceSopenharmony_ci	*pati = NULL;
329d4afb5ceSopenharmony_ci}
330d4afb5ceSopenharmony_ci
331d4afb5ceSopenharmony_cistatic int
332d4afb5ceSopenharmony_cilws_atcrs_set_timeout(lws_abs_transport_inst_t *ati, int reason, int secs)
333d4afb5ceSopenharmony_ci{
334d4afb5ceSopenharmony_ci	abs_raw_skt_priv_t *priv = (abs_raw_skt_priv_t *)ati;
335d4afb5ceSopenharmony_ci
336d4afb5ceSopenharmony_ci	lws_set_timeout(priv->wsi, reason, secs);
337d4afb5ceSopenharmony_ci
338d4afb5ceSopenharmony_ci	return 0;
339d4afb5ceSopenharmony_ci}
340d4afb5ceSopenharmony_ci
341d4afb5ceSopenharmony_cistatic int
342d4afb5ceSopenharmony_cilws_atcrs_state(lws_abs_transport_inst_t *ati)
343d4afb5ceSopenharmony_ci{
344d4afb5ceSopenharmony_ci	abs_raw_skt_priv_t *priv = (abs_raw_skt_priv_t *)ati;
345d4afb5ceSopenharmony_ci
346d4afb5ceSopenharmony_ci	if (!priv || !priv->wsi || (!priv->established && !priv->connecting))
347d4afb5ceSopenharmony_ci		return 0;
348d4afb5ceSopenharmony_ci
349d4afb5ceSopenharmony_ci	return 1;
350d4afb5ceSopenharmony_ci}
351d4afb5ceSopenharmony_ci
352d4afb5ceSopenharmony_cistatic int
353d4afb5ceSopenharmony_cilws_atcrs_compare(lws_abs_t *abs1, lws_abs_t *abs2)
354d4afb5ceSopenharmony_ci{
355d4afb5ceSopenharmony_ci	const lws_token_map_t *tm1, *tm2;
356d4afb5ceSopenharmony_ci
357d4afb5ceSopenharmony_ci	tm1 = lws_abs_get_token(abs1->at_tokens, LTMI_PEER_V_DNS_ADDRESS);
358d4afb5ceSopenharmony_ci	tm2 = lws_abs_get_token(abs2->at_tokens, LTMI_PEER_V_DNS_ADDRESS);
359d4afb5ceSopenharmony_ci
360d4afb5ceSopenharmony_ci	/* Address token is mandatory and must match */
361d4afb5ceSopenharmony_ci	if (!tm1 || !tm2 || strcmp(tm1->u.value, tm2->u.value))
362d4afb5ceSopenharmony_ci		return 1;
363d4afb5ceSopenharmony_ci
364d4afb5ceSopenharmony_ci	/* Port token is mandatory and must match */
365d4afb5ceSopenharmony_ci	tm1 = lws_abs_get_token(abs1->at_tokens, LTMI_PEER_LV_PORT);
366d4afb5ceSopenharmony_ci	tm2 = lws_abs_get_token(abs2->at_tokens, LTMI_PEER_LV_PORT);
367d4afb5ceSopenharmony_ci	if (!tm1 || !tm2 || tm1->u.lvalue != tm2->u.lvalue)
368d4afb5ceSopenharmony_ci		return 1;
369d4afb5ceSopenharmony_ci
370d4afb5ceSopenharmony_ci	/* TLS is optional... */
371d4afb5ceSopenharmony_ci	tm1 = lws_abs_get_token(abs1->at_tokens, LTMI_PEER_LV_TLS_FLAGS);
372d4afb5ceSopenharmony_ci	tm2 = lws_abs_get_token(abs2->at_tokens, LTMI_PEER_LV_TLS_FLAGS);
373d4afb5ceSopenharmony_ci
374d4afb5ceSopenharmony_ci	/* ... but both must have the same situation with it given or not... */
375d4afb5ceSopenharmony_ci	if (!!tm1 != !!tm2)
376d4afb5ceSopenharmony_ci		return 1;
377d4afb5ceSopenharmony_ci
378d4afb5ceSopenharmony_ci	/* if not using TLS, then that's enough to call it */
379d4afb5ceSopenharmony_ci	if (!tm1)
380d4afb5ceSopenharmony_ci		return 0;
381d4afb5ceSopenharmony_ci
382d4afb5ceSopenharmony_ci	/* ...and if there are tls flags, both must have the same tls flags */
383d4afb5ceSopenharmony_ci	if (tm1->u.lvalue != tm2->u.lvalue)
384d4afb5ceSopenharmony_ci		return 1;
385d4afb5ceSopenharmony_ci
386d4afb5ceSopenharmony_ci	/* ... and both must use the same client tls ctx / vhost */
387d4afb5ceSopenharmony_ci	return abs1->vh != abs2->vh;
388d4afb5ceSopenharmony_ci}
389d4afb5ceSopenharmony_ci
390d4afb5ceSopenharmony_ciconst lws_abs_transport_t lws_abs_transport_cli_raw_skt = {
391d4afb5ceSopenharmony_ci	.name			= "raw_skt",
392d4afb5ceSopenharmony_ci	.alloc			= sizeof(abs_raw_skt_priv_t),
393d4afb5ceSopenharmony_ci
394d4afb5ceSopenharmony_ci	.create			= lws_atcrs_create,
395d4afb5ceSopenharmony_ci	.destroy		= lws_atcrs_destroy,
396d4afb5ceSopenharmony_ci	.compare		= lws_atcrs_compare,
397d4afb5ceSopenharmony_ci
398d4afb5ceSopenharmony_ci	.tx			= lws_atcrs_tx,
399d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_CLIENT)
400d4afb5ceSopenharmony_ci	.client_conn		= NULL,
401d4afb5ceSopenharmony_ci#else
402d4afb5ceSopenharmony_ci	.client_conn		= lws_atcrs_client_conn,
403d4afb5ceSopenharmony_ci#endif
404d4afb5ceSopenharmony_ci	.close			= lws_atcrs_close,
405d4afb5ceSopenharmony_ci	.ask_for_writeable	= lws_atcrs_ask_for_writeable,
406d4afb5ceSopenharmony_ci	.set_timeout		= lws_atcrs_set_timeout,
407d4afb5ceSopenharmony_ci	.state			= lws_atcrs_state,
408d4afb5ceSopenharmony_ci};
409