1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * libwebsockets - small server side websockets and web server implementation 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Copyright (C) 2010 - 2020 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 27d4afb5ceSopenharmony_ci#if !defined(WIN32) 28d4afb5ceSopenharmony_ci#include <netdb.h> 29d4afb5ceSopenharmony_ci#endif 30d4afb5ceSopenharmony_ci 31d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_SYS_ASYNC_DNS) 32d4afb5ceSopenharmony_cistatic int 33d4afb5ceSopenharmony_cilws_getaddrinfo46(struct lws *wsi, const char *ads, struct addrinfo **result) 34d4afb5ceSopenharmony_ci{ 35d4afb5ceSopenharmony_ci lws_metrics_caliper_declare(cal, wsi->a.context->mt_conn_dns); 36d4afb5ceSopenharmony_ci struct addrinfo hints; 37d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_METRICS) 38d4afb5ceSopenharmony_ci char buckname[32]; 39d4afb5ceSopenharmony_ci#endif 40d4afb5ceSopenharmony_ci int n; 41d4afb5ceSopenharmony_ci 42d4afb5ceSopenharmony_ci memset(&hints, 0, sizeof(hints)); 43d4afb5ceSopenharmony_ci *result = NULL; 44d4afb5ceSopenharmony_ci 45d4afb5ceSopenharmony_ci hints.ai_socktype = SOCK_STREAM; 46d4afb5ceSopenharmony_ci 47d4afb5ceSopenharmony_ci#ifdef LWS_WITH_IPV6 48d4afb5ceSopenharmony_ci if (wsi->ipv6) { 49d4afb5ceSopenharmony_ci 50d4afb5ceSopenharmony_ci#if !defined(__ANDROID__) 51d4afb5ceSopenharmony_ci hints.ai_family = AF_UNSPEC; 52d4afb5ceSopenharmony_ci#if !defined(__OpenBSD__) && !defined(__OPENBSD) 53d4afb5ceSopenharmony_ci hints.ai_flags = AI_V4MAPPED; 54d4afb5ceSopenharmony_ci#endif 55d4afb5ceSopenharmony_ci#endif 56d4afb5ceSopenharmony_ci } else 57d4afb5ceSopenharmony_ci#endif 58d4afb5ceSopenharmony_ci { 59d4afb5ceSopenharmony_ci hints.ai_family = PF_UNSPEC; 60d4afb5ceSopenharmony_ci } 61d4afb5ceSopenharmony_ci 62d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CONMON) 63d4afb5ceSopenharmony_ci wsi->conmon_datum = lws_now_usecs(); 64d4afb5ceSopenharmony_ci#endif 65d4afb5ceSopenharmony_ci 66d4afb5ceSopenharmony_ci wsi->dns_reachability = 0; 67d4afb5ceSopenharmony_ci if (lws_fi(&wsi->fic, "dnsfail")) 68d4afb5ceSopenharmony_ci n = EAI_FAIL; 69d4afb5ceSopenharmony_ci else 70d4afb5ceSopenharmony_ci n = getaddrinfo(ads, NULL, &hints, result); 71d4afb5ceSopenharmony_ci 72d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CONMON) 73d4afb5ceSopenharmony_ci wsi->conmon.ciu_dns = (lws_conmon_interval_us_t) 74d4afb5ceSopenharmony_ci (lws_now_usecs() - wsi->conmon_datum); 75d4afb5ceSopenharmony_ci#endif 76d4afb5ceSopenharmony_ci 77d4afb5ceSopenharmony_ci /* 78d4afb5ceSopenharmony_ci * Which EAI_* are available and the meanings are highly platform- 79d4afb5ceSopenharmony_ci * dependent, even different linux distros differ. 80d4afb5ceSopenharmony_ci */ 81d4afb5ceSopenharmony_ci 82d4afb5ceSopenharmony_ci if (0 83d4afb5ceSopenharmony_ci#if defined(EAI_SYSTEM) 84d4afb5ceSopenharmony_ci || n == EAI_SYSTEM 85d4afb5ceSopenharmony_ci#endif 86d4afb5ceSopenharmony_ci#if defined(EAI_NODATA) 87d4afb5ceSopenharmony_ci || n == EAI_NODATA 88d4afb5ceSopenharmony_ci#endif 89d4afb5ceSopenharmony_ci#if defined(EAI_FAIL) 90d4afb5ceSopenharmony_ci || n == EAI_FAIL 91d4afb5ceSopenharmony_ci#endif 92d4afb5ceSopenharmony_ci#if defined(EAI_AGAIN) 93d4afb5ceSopenharmony_ci || n == EAI_AGAIN 94d4afb5ceSopenharmony_ci#endif 95d4afb5ceSopenharmony_ci ) { 96d4afb5ceSopenharmony_ci wsi->dns_reachability = 1; 97d4afb5ceSopenharmony_ci lws_metrics_caliper_report(cal, METRES_NOGO); 98d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_METRICS) 99d4afb5ceSopenharmony_ci lws_snprintf(buckname, sizeof(buckname), "dns=\"unreachable %d\"", n); 100d4afb5ceSopenharmony_ci lws_metrics_hist_bump_priv_wsi(wsi, mth_conn_failures, buckname); 101d4afb5ceSopenharmony_ci#endif 102d4afb5ceSopenharmony_ci 103d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CONMON) 104d4afb5ceSopenharmony_ci wsi->conmon.dns_disposition = LWSCONMON_DNS_SERVER_UNREACHABLE; 105d4afb5ceSopenharmony_ci#endif 106d4afb5ceSopenharmony_ci 107d4afb5ceSopenharmony_ci#if 0 108d4afb5ceSopenharmony_ci lwsl_wsi_debug(wsi, "asking to recheck CPD in 1s"); 109d4afb5ceSopenharmony_ci lws_system_cpd_start_defer(wsi->a.context, LWS_US_PER_SEC); 110d4afb5ceSopenharmony_ci#endif 111d4afb5ceSopenharmony_ci } 112d4afb5ceSopenharmony_ci 113d4afb5ceSopenharmony_ci lwsl_wsi_info(wsi, "getaddrinfo '%s' says %d", ads, n); 114d4afb5ceSopenharmony_ci 115d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_METRICS) 116d4afb5ceSopenharmony_ci if (n < 0) { 117d4afb5ceSopenharmony_ci lws_snprintf(buckname, sizeof(buckname), "dns=\"nores %d\"", n); 118d4afb5ceSopenharmony_ci lws_metrics_hist_bump_priv_wsi(wsi, mth_conn_failures, buckname); 119d4afb5ceSopenharmony_ci } 120d4afb5ceSopenharmony_ci#endif 121d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CONMON) 122d4afb5ceSopenharmony_ci wsi->conmon.dns_disposition = n < 0 ? LWSCONMON_DNS_NO_RESULT : 123d4afb5ceSopenharmony_ci LWSCONMON_DNS_OK; 124d4afb5ceSopenharmony_ci#endif 125d4afb5ceSopenharmony_ci 126d4afb5ceSopenharmony_ci lws_metrics_caliper_report(cal, n >= 0 ? METRES_GO : METRES_NOGO); 127d4afb5ceSopenharmony_ci 128d4afb5ceSopenharmony_ci return n; 129d4afb5ceSopenharmony_ci} 130d4afb5ceSopenharmony_ci#endif 131d4afb5ceSopenharmony_ci 132d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_SYS_ASYNC_DNS) && defined(EAI_NONAME) 133d4afb5ceSopenharmony_cistatic const char * const dns_nxdomain = "DNS NXDOMAIN"; 134d4afb5ceSopenharmony_ci#endif 135d4afb5ceSopenharmony_ci 136d4afb5ceSopenharmony_cistruct lws * 137d4afb5ceSopenharmony_cilws_client_connect_2_dnsreq(struct lws *wsi) 138d4afb5ceSopenharmony_ci{ 139d4afb5ceSopenharmony_ci struct addrinfo *result = NULL; 140d4afb5ceSopenharmony_ci const char *meth = NULL; 141d4afb5ceSopenharmony_ci#if defined(LWS_WITH_IPV6) 142d4afb5ceSopenharmony_ci struct sockaddr_in addr; 143d4afb5ceSopenharmony_ci const char *iface; 144d4afb5ceSopenharmony_ci#endif 145d4afb5ceSopenharmony_ci const char *adsin; 146d4afb5ceSopenharmony_ci int n, port = 0; 147d4afb5ceSopenharmony_ci struct lws *w; 148d4afb5ceSopenharmony_ci 149d4afb5ceSopenharmony_ci if (lwsi_state(wsi) == LRS_WAITING_DNS || 150d4afb5ceSopenharmony_ci lwsi_state(wsi) == LRS_WAITING_CONNECT) { 151d4afb5ceSopenharmony_ci lwsl_wsi_info(wsi, "LRS_WAITING_DNS / CONNECT"); 152d4afb5ceSopenharmony_ci 153d4afb5ceSopenharmony_ci return wsi; 154d4afb5ceSopenharmony_ci } 155d4afb5ceSopenharmony_ci 156d4afb5ceSopenharmony_ci /* 157d4afb5ceSopenharmony_ci * clients who will create their own fresh connection keep a copy of 158d4afb5ceSopenharmony_ci * the hostname they originally connected to, in case other connections 159d4afb5ceSopenharmony_ci * want to use it too 160d4afb5ceSopenharmony_ci */ 161d4afb5ceSopenharmony_ci 162d4afb5ceSopenharmony_ci if (!wsi->cli_hostname_copy) { 163d4afb5ceSopenharmony_ci const char *pa = lws_wsi_client_stash_item(wsi, CIS_HOST, 164d4afb5ceSopenharmony_ci _WSI_TOKEN_CLIENT_PEER_ADDRESS); 165d4afb5ceSopenharmony_ci 166d4afb5ceSopenharmony_ci if (pa) 167d4afb5ceSopenharmony_ci wsi->cli_hostname_copy = lws_strdup(pa); 168d4afb5ceSopenharmony_ci } 169d4afb5ceSopenharmony_ci 170d4afb5ceSopenharmony_ci /* 171d4afb5ceSopenharmony_ci * The first job is figure out if we want to pipeline on or just join 172d4afb5ceSopenharmony_ci * an existing "active connection" to the same place 173d4afb5ceSopenharmony_ci */ 174d4afb5ceSopenharmony_ci 175d4afb5ceSopenharmony_ci meth = lws_wsi_client_stash_item(wsi, CIS_METHOD, 176d4afb5ceSopenharmony_ci _WSI_TOKEN_CLIENT_METHOD); 177d4afb5ceSopenharmony_ci /* consult active connections to find out disposition */ 178d4afb5ceSopenharmony_ci 179d4afb5ceSopenharmony_ci adsin = lws_wsi_client_stash_item(wsi, CIS_ADDRESS, 180d4afb5ceSopenharmony_ci _WSI_TOKEN_CLIENT_PEER_ADDRESS); 181d4afb5ceSopenharmony_ci 182d4afb5ceSopenharmony_ci /* we only pipeline connections that said it was okay */ 183d4afb5ceSopenharmony_ci 184d4afb5ceSopenharmony_ci if (!wsi->client_pipeline) { 185d4afb5ceSopenharmony_ci lwsl_wsi_debug(wsi, "new conn on no pipeline flag"); 186d4afb5ceSopenharmony_ci 187d4afb5ceSopenharmony_ci goto solo; 188d4afb5ceSopenharmony_ci } 189d4afb5ceSopenharmony_ci 190d4afb5ceSopenharmony_ci /* only pipeline things we associate with being a stream */ 191d4afb5ceSopenharmony_ci 192d4afb5ceSopenharmony_ci if (meth && strcmp(meth, "RAW") && strcmp(meth, "GET") && 193d4afb5ceSopenharmony_ci strcmp(meth, "POST") && strcmp(meth, "PUT") && 194d4afb5ceSopenharmony_ci strcmp(meth, "UDP") && strcmp(meth, "MQTT")) 195d4afb5ceSopenharmony_ci goto solo; 196d4afb5ceSopenharmony_ci 197d4afb5ceSopenharmony_ci if (!adsin) 198d4afb5ceSopenharmony_ci /* 199d4afb5ceSopenharmony_ci * This cannot happen since user code must provide the client 200d4afb5ceSopenharmony_ci * address to get this far, it's here to satisfy Coverity 201d4afb5ceSopenharmony_ci */ 202d4afb5ceSopenharmony_ci return NULL; 203d4afb5ceSopenharmony_ci 204d4afb5ceSopenharmony_ci switch (lws_vhost_active_conns(wsi, &w, adsin)) { 205d4afb5ceSopenharmony_ci case ACTIVE_CONNS_SOLO: 206d4afb5ceSopenharmony_ci break; 207d4afb5ceSopenharmony_ci case ACTIVE_CONNS_MUXED: 208d4afb5ceSopenharmony_ci lwsl_wsi_notice(wsi, "ACTIVE_CONNS_MUXED"); 209d4afb5ceSopenharmony_ci if (lwsi_role_h2(wsi)) { 210d4afb5ceSopenharmony_ci 211d4afb5ceSopenharmony_ci if (wsi->a.protocol->callback(wsi, 212d4afb5ceSopenharmony_ci LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP, 213d4afb5ceSopenharmony_ci wsi->user_space, NULL, 0)) 214d4afb5ceSopenharmony_ci goto failed1; 215d4afb5ceSopenharmony_ci 216d4afb5ceSopenharmony_ci //lwsi_set_state(wsi, LRS_H1C_ISSUE_HANDSHAKE2); 217d4afb5ceSopenharmony_ci //lwsi_set_state(w, LRS_ESTABLISHED); 218d4afb5ceSopenharmony_ci lws_callback_on_writable(wsi); 219d4afb5ceSopenharmony_ci } 220d4afb5ceSopenharmony_ci 221d4afb5ceSopenharmony_ci return wsi; 222d4afb5ceSopenharmony_ci case ACTIVE_CONNS_QUEUED: 223d4afb5ceSopenharmony_ci lwsl_wsi_debug(wsi, "ACTIVE_CONNS_QUEUED st 0x%x: ", 224d4afb5ceSopenharmony_ci lwsi_state(wsi)); 225d4afb5ceSopenharmony_ci 226d4afb5ceSopenharmony_ci if (lwsi_state(wsi) == LRS_UNCONNECTED) { 227d4afb5ceSopenharmony_ci if (lwsi_role_h2(w)) 228d4afb5ceSopenharmony_ci lwsi_set_state(wsi, 229d4afb5ceSopenharmony_ci LRS_H2_WAITING_TO_SEND_HEADERS); 230d4afb5ceSopenharmony_ci else 231d4afb5ceSopenharmony_ci lwsi_set_state(wsi, LRS_H1C_ISSUE_HANDSHAKE2); 232d4afb5ceSopenharmony_ci } 233d4afb5ceSopenharmony_ci 234d4afb5ceSopenharmony_ci return lws_client_connect_4_established(wsi, w, 0); 235d4afb5ceSopenharmony_ci } 236d4afb5ceSopenharmony_ci 237d4afb5ceSopenharmony_cisolo: 238d4afb5ceSopenharmony_ci 239d4afb5ceSopenharmony_ci /* 240d4afb5ceSopenharmony_ci * If we made our own connection, and we're doing a method that can 241d4afb5ceSopenharmony_ci * take a pipeline, we are an "active client connection". 242d4afb5ceSopenharmony_ci * 243d4afb5ceSopenharmony_ci * Add ourselves to the vhost list of those so that others can 244d4afb5ceSopenharmony_ci * piggyback on our transaction queue 245d4afb5ceSopenharmony_ci */ 246d4afb5ceSopenharmony_ci 247d4afb5ceSopenharmony_ci if (meth && (!strcmp(meth, "RAW") || !strcmp(meth, "GET") || 248d4afb5ceSopenharmony_ci !strcmp(meth, "POST") || !strcmp(meth, "PUT") || 249d4afb5ceSopenharmony_ci !strcmp(meth, "MQTT")) && 250d4afb5ceSopenharmony_ci lws_dll2_is_detached(&wsi->dll2_cli_txn_queue) && 251d4afb5ceSopenharmony_ci lws_dll2_is_detached(&wsi->dll_cli_active_conns)) { 252d4afb5ceSopenharmony_ci lws_context_lock(wsi->a.context, __func__); 253d4afb5ceSopenharmony_ci lws_vhost_lock(wsi->a.vhost); 254d4afb5ceSopenharmony_ci lwsl_wsi_info(wsi, "adding as active conn"); 255d4afb5ceSopenharmony_ci /* caution... we will have to unpick this on oom4 path */ 256d4afb5ceSopenharmony_ci lws_dll2_add_head(&wsi->dll_cli_active_conns, 257d4afb5ceSopenharmony_ci &wsi->a.vhost->dll_cli_active_conns_owner); 258d4afb5ceSopenharmony_ci lws_vhost_unlock(wsi->a.vhost); 259d4afb5ceSopenharmony_ci lws_context_unlock(wsi->a.context); 260d4afb5ceSopenharmony_ci } 261d4afb5ceSopenharmony_ci 262d4afb5ceSopenharmony_ci /* 263d4afb5ceSopenharmony_ci * Since address must be given at client creation, should not be 264d4afb5ceSopenharmony_ci * possible, but necessary to satisfy coverity 265d4afb5ceSopenharmony_ci */ 266d4afb5ceSopenharmony_ci if (!adsin) 267d4afb5ceSopenharmony_ci return NULL; 268d4afb5ceSopenharmony_ci 269d4afb5ceSopenharmony_ci#if defined(LWS_WITH_UNIX_SOCK) 270d4afb5ceSopenharmony_ci /* 271d4afb5ceSopenharmony_ci * unix socket destination? 272d4afb5ceSopenharmony_ci */ 273d4afb5ceSopenharmony_ci 274d4afb5ceSopenharmony_ci if (*adsin == '+') { 275d4afb5ceSopenharmony_ci wsi->unix_skt = 1; 276d4afb5ceSopenharmony_ci n = 0; 277d4afb5ceSopenharmony_ci goto next_step; 278d4afb5ceSopenharmony_ci } 279d4afb5ceSopenharmony_ci#endif 280d4afb5ceSopenharmony_ci 281d4afb5ceSopenharmony_ci /* 282d4afb5ceSopenharmony_ci * start off allowing ipv6 on connection if vhost allows it 283d4afb5ceSopenharmony_ci */ 284d4afb5ceSopenharmony_ci wsi->ipv6 = LWS_IPV6_ENABLED(wsi->a.vhost); 285d4afb5ceSopenharmony_ci#ifdef LWS_WITH_IPV6 286d4afb5ceSopenharmony_ci if (wsi->stash) 287d4afb5ceSopenharmony_ci iface = wsi->stash->cis[CIS_IFACE]; 288d4afb5ceSopenharmony_ci else 289d4afb5ceSopenharmony_ci iface = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_IFACE); 290d4afb5ceSopenharmony_ci 291d4afb5ceSopenharmony_ci if (wsi->ipv6 && iface && 292d4afb5ceSopenharmony_ci inet_pton(AF_INET, iface, &addr.sin_addr) == 1) { 293d4afb5ceSopenharmony_ci lwsl_wsi_notice(wsi, "client connection forced to IPv4"); 294d4afb5ceSopenharmony_ci wsi->ipv6 = 0; 295d4afb5ceSopenharmony_ci } 296d4afb5ceSopenharmony_ci#endif 297d4afb5ceSopenharmony_ci 298d4afb5ceSopenharmony_ci#if defined(LWS_CLIENT_HTTP_PROXYING) && \ 299d4afb5ceSopenharmony_ci (defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)) 300d4afb5ceSopenharmony_ci 301d4afb5ceSopenharmony_ci /* Decide what it is we need to connect to: 302d4afb5ceSopenharmony_ci * 303d4afb5ceSopenharmony_ci * Priority 1: connect to http proxy */ 304d4afb5ceSopenharmony_ci 305d4afb5ceSopenharmony_ci if (wsi->a.vhost->http.http_proxy_port) { 306d4afb5ceSopenharmony_ci adsin = wsi->a.vhost->http.http_proxy_address; 307d4afb5ceSopenharmony_ci port = (int)wsi->a.vhost->http.http_proxy_port; 308d4afb5ceSopenharmony_ci#else 309d4afb5ceSopenharmony_ci if (0) { 310d4afb5ceSopenharmony_ci#endif 311d4afb5ceSopenharmony_ci 312d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SOCKS5) 313d4afb5ceSopenharmony_ci 314d4afb5ceSopenharmony_ci /* Priority 2: Connect to SOCK5 Proxy */ 315d4afb5ceSopenharmony_ci 316d4afb5ceSopenharmony_ci } else if (wsi->a.vhost->socks_proxy_port) { 317d4afb5ceSopenharmony_ci lwsl_wsi_client(wsi, "Sending SOCKS Greeting"); 318d4afb5ceSopenharmony_ci adsin = wsi->a.vhost->socks_proxy_address; 319d4afb5ceSopenharmony_ci port = (int)wsi->a.vhost->socks_proxy_port; 320d4afb5ceSopenharmony_ci#endif 321d4afb5ceSopenharmony_ci } else { 322d4afb5ceSopenharmony_ci 323d4afb5ceSopenharmony_ci /* Priority 3: Connect directly */ 324d4afb5ceSopenharmony_ci 325d4afb5ceSopenharmony_ci /* ads already set */ 326d4afb5ceSopenharmony_ci port = wsi->c_port; 327d4afb5ceSopenharmony_ci } 328d4afb5ceSopenharmony_ci 329d4afb5ceSopenharmony_ci /* 330d4afb5ceSopenharmony_ci * prepare the actual connection 331d4afb5ceSopenharmony_ci * to whatever we decided to connect to 332d4afb5ceSopenharmony_ci */ 333d4afb5ceSopenharmony_ci lwsi_set_state(wsi, LRS_WAITING_DNS); 334d4afb5ceSopenharmony_ci 335d4afb5ceSopenharmony_ci lwsl_wsi_info(wsi, "lookup %s:%u", adsin, port); 336d4afb5ceSopenharmony_ci wsi->conn_port = (uint16_t)port; 337d4afb5ceSopenharmony_ci 338d4afb5ceSopenharmony_ci#if !defined(LWS_WITH_SYS_ASYNC_DNS) 339d4afb5ceSopenharmony_ci n = 0; 340d4afb5ceSopenharmony_ci if (!wsi->dns_sorted_list.count) { 341d4afb5ceSopenharmony_ci /* 342d4afb5ceSopenharmony_ci * blocking dns resolution 343d4afb5ceSopenharmony_ci */ 344d4afb5ceSopenharmony_ci n = lws_getaddrinfo46(wsi, adsin, &result); 345d4afb5ceSopenharmony_ci#if defined(EAI_NONAME) 346d4afb5ceSopenharmony_ci if (n == EAI_NONAME) { 347d4afb5ceSopenharmony_ci /* 348d4afb5ceSopenharmony_ci * The DNS server responded with NXDOMAIN... even 349d4afb5ceSopenharmony_ci * though this is still in the client creation call, 350d4afb5ceSopenharmony_ci * we need to make a CCE, otherwise there won't be 351d4afb5ceSopenharmony_ci * any user indication of what went wrong 352d4afb5ceSopenharmony_ci */ 353d4afb5ceSopenharmony_ci wsi->client_suppress_CONNECTION_ERROR = 0; 354d4afb5ceSopenharmony_ci lws_inform_client_conn_fail(wsi, (void *)dns_nxdomain, 355d4afb5ceSopenharmony_ci strlen(dns_nxdomain)); 356d4afb5ceSopenharmony_ci goto failed1; 357d4afb5ceSopenharmony_ci } 358d4afb5ceSopenharmony_ci#endif 359d4afb5ceSopenharmony_ci } 360d4afb5ceSopenharmony_ci#else 361d4afb5ceSopenharmony_ci /* this is either FAILED, CONTINUING, or already called connect_4 */ 362d4afb5ceSopenharmony_ci 363d4afb5ceSopenharmony_ci if (lws_fi(&wsi->fic, "dnsfail")) 364d4afb5ceSopenharmony_ci return lws_client_connect_3_connect(wsi, NULL, NULL, -4, NULL); 365d4afb5ceSopenharmony_ci else 366d4afb5ceSopenharmony_ci n = lws_async_dns_query(wsi->a.context, wsi->tsi, adsin, 367d4afb5ceSopenharmony_ci LWS_ADNS_RECORD_A, lws_client_connect_3_connect, 368d4afb5ceSopenharmony_ci wsi, NULL); 369d4afb5ceSopenharmony_ci 370d4afb5ceSopenharmony_ci if (n == LADNS_RET_FAILED_WSI_CLOSED) 371d4afb5ceSopenharmony_ci return NULL; 372d4afb5ceSopenharmony_ci 373d4afb5ceSopenharmony_ci if (n == LADNS_RET_FAILED) 374d4afb5ceSopenharmony_ci goto failed1; 375d4afb5ceSopenharmony_ci 376d4afb5ceSopenharmony_ci return wsi; 377d4afb5ceSopenharmony_ci#endif 378d4afb5ceSopenharmony_ci 379d4afb5ceSopenharmony_ci#if defined(LWS_WITH_UNIX_SOCK) 380d4afb5ceSopenharmony_cinext_step: 381d4afb5ceSopenharmony_ci#endif 382d4afb5ceSopenharmony_ci return lws_client_connect_3_connect(wsi, adsin, result, n, NULL); 383d4afb5ceSopenharmony_ci 384d4afb5ceSopenharmony_ci//#if defined(LWS_WITH_SYS_ASYNC_DNS) 385d4afb5ceSopenharmony_cifailed1: 386d4afb5ceSopenharmony_ci lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "client_connect2"); 387d4afb5ceSopenharmony_ci 388d4afb5ceSopenharmony_ci return NULL; 389d4afb5ceSopenharmony_ci//#endif 390d4afb5ceSopenharmony_ci} 391