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