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