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