diff options
Diffstat (limited to 'lib/core-net')
-rw-r--r-- | lib/core-net/client/connect.c | 109 | ||||
-rw-r--r-- | lib/core-net/client/connect2.c | 40 | ||||
-rw-r--r-- | lib/core-net/client/connect3.c | 2 | ||||
-rw-r--r-- | lib/core-net/client/connect4.c | 49 | ||||
-rw-r--r-- | lib/core-net/close.c | 139 | ||||
-rw-r--r-- | lib/core-net/private-lib-core-net.h | 10 | ||||
-rw-r--r-- | lib/core-net/vhost.c | 15 | ||||
-rw-r--r-- | lib/core-net/wsi.c | 10 |
8 files changed, 265 insertions, 109 deletions
diff --git a/lib/core-net/client/connect.c b/lib/core-net/client/connect.c index 1e18cbbe..2298fa21 100644 --- a/lib/core-net/client/connect.c +++ b/lib/core-net/client/connect.c @@ -60,7 +60,7 @@ lws_http_client_connect_via_info2(struct lws *wsi) for (n = 0; n < (int)LWS_ARRAY_SIZE(hnames); n++) if (hnames[n] && stash->cis[n] && lws_hdr_simple_create(wsi, hnames[n], stash->cis[n])) - goto bail1; + goto bail; #if defined(LWS_WITH_SOCKS5) if (!wsi->a.vhost->socks_proxy_port) @@ -70,15 +70,58 @@ lws_http_client_connect_via_info2(struct lws *wsi) no_ah: return lws_client_connect_2_dnsreq(wsi); -bail1: +bail: #if defined(LWS_WITH_SOCKS5) if (!wsi->a.vhost->socks_proxy_port) lws_free_set_NULL(wsi->stash); #endif + lws_free_set_NULL(wsi->stash); + return NULL; } +int +lws_client_stash_create(struct lws *wsi, const char **cisin) +{ + size_t size; + char *pc; + int n; + + size = sizeof(*wsi->stash); + + /* + * Let's overallocate the stash object with space for all the args + * in one hit. + */ + for (n = 0; n < CIS_COUNT; n++) + if (cisin[n]) + size += strlen(cisin[n]) + 1; + + if (wsi->stash) + lws_free_set_NULL(wsi->stash); + + wsi->stash = lws_malloc(size, "client stash"); + if (!wsi->stash) + return 1; + + /* all the pointers default to NULL, but no need to zero the args */ + memset(wsi->stash, 0, sizeof(*wsi->stash)); + + pc = (char *)&wsi->stash[1]; + + for (n = 0; n < CIS_COUNT; n++) + if (cisin[n]) { + size_t mm; + wsi->stash->cis[n] = pc; + mm = strlen(cisin[n]) + 1; + memcpy(pc, cisin[n], mm); + pc += mm; + } + + return 0; +} + struct lws * lws_client_connect_via_info(const struct lws_client_connect_info *i) { @@ -86,10 +129,8 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i) struct lws *wsi, *safe = NULL; const struct lws_protocols *p; const char *cisin[CIS_COUNT]; - struct lws_vhost *vh, *v; - size_t size; - int n, tsi; - char *pc; + struct lws_vhost *vh; + int tsi; if (i->context->requested_stop_internal_loops) return NULL; @@ -118,11 +159,10 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i) wsi = __lws_wsi_create_with_role(i->context, tsi, NULL); lws_context_unlock(i->context); if (wsi == NULL) - goto bail; + return NULL; vh = i->vhost; if (!vh) { - #if defined(LWS_WITH_TLS_JIT_TRUST) if (lws_tls_jit_trust_vhost_bind(i->context, i->address, &vh)) #endif @@ -199,23 +239,11 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i) if (i->ssl_connection & LCCSCF_WAKE_SUSPEND__VALIDITY) wsi->conn_validity_wakesuspend = 1; - if (!i->vhost) { - v = i->context->vhost_list; - - if (!v) { /* coverity */ - lwsl_err("%s: no vhost\n", __func__); - goto bail; - } - if (!strcmp(v->name, "system")) - v = v->vhost_next; - } else - v = i->vhost; - - lws_vhost_bind_wsi(v, wsi); + lws_vhost_bind_wsi(vh, wsi); #if defined(LWS_WITH_SYS_FAULT_INJECTION) /* additionally inerit from vhost we bound to */ - lws_fi_inherit_copy(&wsi->fic, &v->fic, "wsi", i->fi_wsi_name); + lws_fi_inherit_copy(&wsi->fic, &vh->fic, "wsi", i->fi_wsi_name); #endif if (!wsi->a.vhost) { @@ -324,23 +352,13 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i) cisin[CIS_IFACE] = i->iface; cisin[CIS_ALPN] = i->alpn; - size = sizeof(*wsi->stash); - - /* - * Let's overallocate the stash object with space for all the args - * in one hit. - */ - for (n = 0; n < CIS_COUNT; n++) - if (cisin[n]) - size += strlen(cisin[n]) + 1; + if (lws_client_stash_create(wsi, cisin)) + goto bail; - wsi->stash = lws_malloc(size, "client stash"); - if (!wsi->stash) { - lwsl_err("%s: OOM\n", __func__); - goto bail1; - } - /* all the pointers default to NULL, but no need to zero the args */ - memset(wsi->stash, 0, sizeof(*wsi->stash)); +#if defined(LWS_WITH_TLS) + if (i->alpn) + lws_strncpy(wsi->alpn, i->alpn, sizeof(wsi->alpn)); +#endif wsi->a.opaque_user_data = wsi->stash->opaque_user_data = i->opaque_user_data; @@ -382,17 +400,6 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i) lws_metrics_tag_wsi_add(wsi, "vh", wsi->a.vhost->name); - pc = (char *)&wsi->stash[1]; - - for (n = 0; n < CIS_COUNT; n++) - if (cisin[n]) { - size_t mm; - wsi->stash->cis[n] = pc; - mm = strlen(cisin[n]) + 1; - memcpy(pc, cisin[n], mm); - pc += mm; - } - /* * at this point user callbacks like * LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER will be interested to @@ -519,10 +526,8 @@ bail3: return NULL; #endif -bail1: - lws_free_set_NULL(wsi->stash); - bail: + lws_free_set_NULL(wsi->stash); lws_fi_destroy(&wsi->fic); lws_free(wsi); #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) diff --git a/lib/core-net/client/connect2.c b/lib/core-net/client/connect2.c index d08f8981..39428353 100644 --- a/lib/core-net/client/connect2.c +++ b/lib/core-net/client/connect2.c @@ -145,6 +145,26 @@ lws_client_connect_2_dnsreq(struct lws *wsi) } /* + * clients who will create their own fresh connection keep a copy of + * the hostname they originally connected to, in case other connections + * want to use it too + */ + + if (!wsi->cli_hostname_copy) { + if (wsi->stash && wsi->stash->cis[CIS_HOST]) + wsi->cli_hostname_copy = + lws_strdup(wsi->stash->cis[CIS_HOST]); +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) + else { + char *pa = lws_hdr_simple_ptr(wsi, + _WSI_TOKEN_CLIENT_PEER_ADDRESS); + if (pa) + wsi->cli_hostname_copy = lws_strdup(pa); + } +#endif + } + + /* * The first job is figure out if we want to pipeline on or just join * an existing "active connection" to the same place */ @@ -214,26 +234,6 @@ lws_client_connect_2_dnsreq(struct lws *wsi) solo: /* - * clients who will create their own fresh connection keep a copy of - * the hostname they originally connected to, in case other connections - * want to use it too - */ - - if (!wsi->cli_hostname_copy) { - if (wsi->stash && wsi->stash->cis[CIS_HOST]) - wsi->cli_hostname_copy = - lws_strdup(wsi->stash->cis[CIS_HOST]); -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - else { - char *pa = lws_hdr_simple_ptr(wsi, - _WSI_TOKEN_CLIENT_PEER_ADDRESS); - if (pa) - wsi->cli_hostname_copy = lws_strdup(pa); - } -#endif - } - - /* * If we made our own connection, and we're doing a method that can * take a pipeline, we are an "active client connection". * diff --git a/lib/core-net/client/connect3.c b/lib/core-net/client/connect3.c index 0f6b901b..98fff5ba 100644 --- a/lib/core-net/client/connect3.c +++ b/lib/core-net/client/connect3.c @@ -475,7 +475,7 @@ ads_known: errno_copy = 999; #endif - lwsl_debug("%s: connect: errno: %d\n", __func__, errno_copy); + lwsl_debug("%s: connect: fd %d errno: %d\n", __func__, wsi->desc.sockfd, errno_copy); if (errno_copy && errno_copy != LWS_EALREADY && diff --git a/lib/core-net/client/connect4.c b/lib/core-net/client/connect4.c index 89611202..8e13dc03 100644 --- a/lib/core-net/client/connect4.c +++ b/lib/core-net/client/connect4.c @@ -1,7 +1,7 @@ /* * libwebsockets - small server side websockets and web server implementation * - * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com> + * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -95,7 +95,8 @@ lws_client_connect_4_established(struct lws *wsi, struct lws *wsi_piggyback, goto failed; wsi->c_port = (uint16_t)wsi->a.vhost->http.http_proxy_port; - n = (int)send(wsi->desc.sockfd, (char *)pt->serv_buf, (unsigned int)plen, + n = (int)send(wsi->desc.sockfd, (char *)pt->serv_buf, + (unsigned int)plen, MSG_NOSIGNAL); if (n < 0) { lwsl_debug("ERROR writing to proxy socket\n"); @@ -161,14 +162,18 @@ send_hs: __func__, wsi->lc.gutag, lwsi_state(wsi_piggyback)); } else { lwsl_info("%s: %s: %s %s client created own conn " - "(raw %d) vh %sm st 0x%x\n", - __func__, wsi->lc.gutag, wsi->role_ops->name, - wsi->a.protocol->name, rawish, wsi->a.vhost->name, - lwsi_state(wsi)); + "(raw %d) vh %sm st 0x%x\n", __func__, wsi->lc.gutag, + wsi->role_ops->name, wsi->a.protocol->name, rawish, + wsi->a.vhost->name, lwsi_state(wsi)); /* we are making our own connection */ - if (!rawish) { + if (!rawish +#if defined(LWS_WITH_TLS) + // && (!(wsi->tls.use_ssl & LCCSCF_USE_SSL) || wsi->tls.ssl) +#endif + ) { + if (lwsi_state(wsi) != LRS_H1C_ISSUE_HANDSHAKE2) lwsi_set_state(wsi, LRS_H1C_ISSUE_HANDSHAKE); } else { @@ -183,20 +188,24 @@ send_hs: (wsi->tls.use_ssl & LCCSCF_USE_SSL)) { int result; + //lwsi_set_state(wsi, LRS_WAITING_SSL); + /* * We can retry this... just cook the SSL BIO * the first time */ result = lws_client_create_tls(wsi, &cce, 1); - lwsl_debug("%s: create_tls said %d\n", - __func__, result); switch (result) { case CCTLS_RETURN_DONE: break; case CCTLS_RETURN_RETRY: + lwsl_debug("%s: create_tls RETRY\n", + __func__); return wsi; default: + lwsl_debug("%s: create_tls FAIL\n", + __func__); goto failed; } @@ -207,9 +216,10 @@ send_hs: * LRS_H2_WAITING_TO_SEND_HEADERS already. */ - lwsl_notice("%s: %s: " - "tls established st 0x%x\n", - __func__, wsi->lc.gutag, lwsi_state(wsi)); + lwsl_notice("%s: %s: tls established st 0x%x, " + "client_h2_alpn %d\n", __func__, + wsi->lc.gutag, lwsi_state(wsi), + wsi->client_h2_alpn); if (lwsi_state(wsi) != LRS_H2_WAITING_TO_SEND_HEADERS) @@ -217,7 +227,13 @@ send_hs: LRS_H1C_ISSUE_HANDSHAKE2); lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND, - (int)wsi->a.context->timeout_secs); + (int)wsi->a.context->timeout_secs); +#if 0 + /* ensure pollin enabled */ + if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) + lwsl_notice("%s: unable to set POLLIN\n", + __func__); +#endif goto provoke_service; } @@ -230,7 +246,8 @@ send_hs: if (m) { n = user_callback_handle_rxflow( wsi->a.protocol->callback, wsi, - (enum lws_callback_reasons)m, wsi->user_space, NULL, 0); + (enum lws_callback_reasons)m, + wsi->user_space, NULL, 0); if (n < 0) { lwsl_info("RAW_PROXY_CLI_ADOPT err\n"); goto failed; @@ -240,7 +257,7 @@ send_hs: /* service.c pollout processing wants this */ wsi->hdr_parsing_completed = 1; #if defined(LWS_ROLE_MQTT) - if (!strcmp(meth, "MQTT")) { + if (meth && !strcmp(meth, "MQTT")) { #if defined(LWS_WITH_TLS) if (wsi->tls.use_ssl & LCCSCF_USE_SSL) { lwsi_set_state(wsi, LRS_WAITING_SSL); @@ -320,7 +337,7 @@ provoke_service: failed: lws_inform_client_conn_fail(wsi, (void *)cce, strlen(cce)); - lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "client_connect2"); + lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "client_connect4"); return NULL; } diff --git a/lib/core-net/close.c b/lib/core-net/close.c index 06e1266b..45c88c9e 100644 --- a/lib/core-net/close.c +++ b/lib/core-net/close.c @@ -123,6 +123,8 @@ __lws_reset_wsi(struct lws *wsi) #if defined(LWS_WITH_CLIENT) lws_dll2_remove(&wsi->dll2_cli_txn_queue); lws_dll2_remove(&wsi->dll_cli_active_conns); + if (wsi->cli_hostname_copy) + lws_free_set_NULL(wsi->cli_hostname_copy); #endif #if defined(LWS_WITH_SYS_ASYNC_DNS) @@ -143,7 +145,7 @@ __lws_reset_wsi(struct lws *wsi) __lws_same_vh_protocol_remove(wsi); #if defined(LWS_WITH_CLIENT) - lws_free_set_NULL(wsi->stash); + //lws_free_set_NULL(wsi->stash); lws_free_set_NULL(wsi->cli_hostname_copy); #endif @@ -166,6 +168,34 @@ __lws_reset_wsi(struct lws *wsi) #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) __lws_header_table_detach(wsi, 0); #endif + +#if defined(LWS_ROLE_H2) + /* + * Let's try to clean out the h2-ness of the wsi + */ + + memset(&wsi->h2, 0, sizeof(wsi->h2)); + + wsi->hdr_parsing_completed = wsi->mux_substream = + wsi->upgraded_to_http2 = wsi->mux_stream_immortal = + wsi->h2_acked_settings = wsi->seen_nonpseudoheader = + wsi->socket_is_permanently_unusable = wsi->favoured_pollin = + wsi->already_did_cce = wsi->told_user_closed = + wsi->waiting_to_send_close_frame = wsi->close_needs_ack = + wsi->parent_pending_cb_on_writable = wsi->seen_zero_length_recv = + wsi->close_when_buffered_out_drained = wsi->could_have_pending = 0; +#endif + +#if defined(LWS_WITH_CLIENT) + wsi->do_ws = wsi->chunked = wsi->client_rx_avail = + wsi->client_http_body_pending = wsi->transaction_from_pipeline_queue = + wsi->keepalive_active = wsi->keepalive_rejected = + wsi->redirected_to_get = wsi->client_pipeline = wsi->client_h2_alpn = + wsi->client_mux_substream = wsi->client_mux_migrated = + wsi->tls_session_reused = wsi->perf_done = 0; + + wsi->immortal_substream_count = 0; +#endif } /* req cx lock */ @@ -194,17 +224,23 @@ __lws_free_wsi(struct lws *wsi) } #endif + vh = wsi->a.vhost; + __lws_reset_wsi(wsi); __lws_wsi_remove_from_sul(wsi); - vh = wsi->a.vhost; + if (vh) + /* this may destroy vh */ + __lws_vhost_unbind_wsi(wsi); /* req cx + vh lock */ + +#if defined(LWS_WITH_CLIENT) + if (wsi->stash) + lws_free_set_NULL(wsi->stash); +#endif if (wsi->a.context->event_loop_ops->destroy_wsi) wsi->a.context->event_loop_ops->destroy_wsi(wsi); - if (vh) - __lws_vhost_unbind_wsi(wsi); /* req cx + vh lock */ - lwsl_debug("%s: %s, tsi fds count %d\n", __func__, lws_wsi_tag(wsi), wsi->a.context->pt[(int)wsi->tsi].fds_count); @@ -339,6 +375,7 @@ __lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason, #if defined(LWS_WITH_CLIENT) lws_free_set_NULL(wsi->cli_hostname_copy); + wsi->client_mux_substream_was = wsi->client_mux_substream; lws_addrinfo_clean(wsi); #endif @@ -407,7 +444,8 @@ __lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason, #endif #if defined(LWS_WITH_CLIENT) - lws_free_set_NULL(wsi->stash); + if (!wsi->close_is_redirect) + lws_free_set_NULL(wsi->stash); #endif if (wsi->role_ops == &role_ops_raw_skt) { @@ -565,7 +603,8 @@ just_kill_connection: #endif lwsi_state(wsi) == LRS_WAITING_DNS || lwsi_state(wsi) == LRS_WAITING_CONNECT) && - !wsi->already_did_cce && wsi->a.protocol) { + !wsi->already_did_cce && wsi->a.protocol && + !wsi->close_is_redirect) { static const char _reason[] = "closed before established"; lwsl_debug("%s: closing in unestablished state 0x%x\n", @@ -624,6 +663,9 @@ just_kill_connection: #if !defined(_WIN32_WCE) && !defined(LWS_PLAT_FREERTOS) /* libuv: no event available to guarantee completion */ if (!wsi->socket_is_permanently_unusable && +#if defined(LWS_WITH_CLIENT) + !wsi->close_is_redirect && +#endif lws_socket_is_valid(wsi->desc.sockfd) && lwsi_state(wsi) != LRS_SHUTDOWN && (context->event_loop_ops->flags & LELOF_ISPOLL)) { @@ -696,7 +738,7 @@ just_kill_connection: /* * He's a guy who go started with dns, but failed or is * caught with a shutdown before he got the result. We have - * to issue him a close cb + * to issclient_mux_substream_wasue him a close cb */ ccb = 1; @@ -712,12 +754,17 @@ just_kill_connection: ccb = 0; #if defined(LWS_WITH_CLIENT) - if (!ccb && (lwsi_state_PRE_CLOSE(wsi) & LWSIFS_NOT_EST) && + if (!wsi->close_is_redirect && !ccb && + (lwsi_state_PRE_CLOSE(wsi) & LWSIFS_NOT_EST) && lwsi_role_client(wsi)) { lws_inform_client_conn_fail(wsi, "Closed before conn", 18); } #endif - if (ccb) { + if (ccb +#if defined(LWS_WITH_CLIENT) + && !wsi->close_is_redirect +#endif + ) { if (!wsi->a.protocol && wsi->a.vhost && wsi->a.vhost->protocols) pro = &wsi->a.vhost->protocols[0]; @@ -831,9 +878,79 @@ __lws_close_free_wsi_final(struct lws *wsi) #endif sanity_assert_no_sockfd_traces(wsi->a.context, wsi->desc.sockfd); + } + + wsi->desc.sockfd = LWS_SOCK_INVALID; + +#if defined(LWS_WITH_CLIENT) + if (wsi->close_is_redirect) { + + wsi->close_is_redirect = 0; + + lwsl_info("%s: picking up redirection %s\n", __func__, + wsi->lc.gutag); + + lws_role_transition(wsi, LWSIFR_CLIENT, LRS_UNCONNECTED, + &role_ops_h1); + +#if defined(LWS_WITH_HTTP2) + if (wsi->client_mux_substream_was) + wsi->h2.END_STREAM = wsi->h2.END_HEADERS = 0; +#endif +#if defined(LWS_ROLE_H2) || defined(LWS_ROLE_MQTT) + if (wsi->mux.parent_wsi) { + lws_wsi_mux_sibling_disconnect(wsi); + wsi->mux.parent_wsi = NULL; + } +#endif + +#if defined(LWS_WITH_TLS) + memset(&wsi->tls, 0, sizeof(wsi->tls)); +#endif + + // wsi->a.protocol = NULL; + if (wsi->a.protocol) + lws_bind_protocol(wsi, wsi->a.protocol, "client_reset"); + wsi->pending_timeout = NO_PENDING_TIMEOUT; + wsi->hdr_parsing_completed = 0; - wsi->desc.sockfd = LWS_SOCK_INVALID; +#if defined(LWS_WITH_TLS) + if (wsi->stash->cis[CIS_ALPN]) + lws_strncpy(wsi->alpn, wsi->stash->cis[CIS_ALPN], + sizeof(wsi->alpn)); +#endif + + if (lws_header_table_attach(wsi, 0)) { + lwsl_err("%s: failed to get ah\n", __func__); + return; + } +// } + //_lws_header_table_reset(wsi->http.ah); + +#if defined(LWS_WITH_TLS) + wsi->tls.use_ssl = wsi->flags & LCCSCF_USE_SSL; +#endif + +#if defined(LWS_WITH_TLS_JIT_TRUST) + if (wsi->stash && wsi->stash->cis[CIS_ADDRESS]) { + struct lws_vhost *vh = NULL; + lws_tls_jit_trust_vhost_bind(wsi->a.context, + wsi->stash->cis[CIS_ADDRESS], + &vh); + if (vh) { + if (!vh->count_bound_wsi && vh->grace_after_unref) { + lwsl_info("%s: %s: in use\n", __func__, vh->lc.gutag); + lws_sul_cancel(&vh->sul_unref); + } + vh->count_bound_wsi++; + wsi->a.vhost = vh; + } + } +#endif + + return; } +#endif /* outermost destroy notification for wsi (user_space still intact) */ if (wsi->a.vhost) diff --git a/lib/core-net/private-lib-core-net.h b/lib/core-net/private-lib-core-net.h index eec38e60..38073bae 100644 --- a/lib/core-net/private-lib-core-net.h +++ b/lib/core-net/private-lib-core-net.h @@ -540,7 +540,7 @@ struct lws_vhost { #endif #if defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY) - int8_t ss_refcount; + int8_t ss_refcount; /**< refcount of number of ss connections with streamtypes using this * trust store */ #endif @@ -742,6 +742,7 @@ struct lws { #if defined(LWS_WITH_TLS) struct lws_lws_tls tls; + char alpn[24]; #endif lws_sock_file_fd_type desc; /* .filefd / .sockfd */ @@ -759,6 +760,8 @@ struct lws { #endif unsigned int cache_secs; + short bugcatcher; + unsigned int hdr_parsing_completed:1; unsigned int mux_substream:1; unsigned int upgraded_to_http2:1; @@ -837,6 +840,8 @@ struct lws { * this activity, and will report the failure */ unsigned int tls_session_reused:1; unsigned int perf_done:1; + unsigned int close_is_redirect:1; + unsigned int client_mux_substream_was:1; #endif #ifdef _WIN32 @@ -1351,6 +1356,9 @@ __lws_same_vh_protocol_remove(struct lws *wsi); void lws_same_vh_protocol_insert(struct lws *wsi, int n); +int +lws_client_stash_create(struct lws *wsi, const char **cisin); + void lws_seq_destroy_all_on_pt(struct lws_context_per_thread *pt); diff --git a/lib/core-net/vhost.c b/lib/core-net/vhost.c index 5e751a21..7654faaf 100644 --- a/lib/core-net/vhost.c +++ b/lib/core-net/vhost.c @@ -557,6 +557,7 @@ lws_create_vhost(struct lws_context *context, #endif struct lws_protocols *lwsp; int m, f = !info->pvo, fx = 0, abs_pcol_count = 0, sec_pcol_count = 0; + const char *name = "default"; char buf[96]; char *p; #if defined(LWS_WITH_SYS_ASYNC_DNS) @@ -564,10 +565,13 @@ lws_create_vhost(struct lws_context *context, #endif int n; + if (info->vhost_name) + name = info->vhost_name; + if (lws_fi(&info->fic, "vh_create_oom")) vh = NULL; else - vh = lws_zalloc(sizeof(*vh) + vh = lws_zalloc(sizeof(*vh) + strlen(name) + 1 #if defined(LWS_WITH_EVENT_LIBS) + context->event_loop_ops->evlib_size_vh #endif @@ -577,7 +581,12 @@ lws_create_vhost(struct lws_context *context, #if defined(LWS_WITH_EVENT_LIBS) vh->evlib_vh = (void *)&vh[1]; + vh->name = (const char *)vh->evlib_vh + + context->event_loop_ops->evlib_size_vh; +#else + vh->name = (const char *)&vh[1]; #endif + memcpy((char *)vh->name, name, strlen(name) + 1); #if LWS_MAX_SMP > 1 lws_mutex_refcount_init(&vh->mr); @@ -587,10 +596,6 @@ lws_create_vhost(struct lws_context *context, pcols = &protocols_dummy[0]; vh->context = context; - if (!info->vhost_name) - vh->name = "default"; - else - vh->name = info->vhost_name; { char *end = buf + sizeof(buf) - 1; p = buf; diff --git a/lib/core-net/wsi.c b/lib/core-net/wsi.c index e67a98be..07d60554 100644 --- a/lib/core-net/wsi.c +++ b/lib/core-net/wsi.c @@ -43,10 +43,12 @@ void lwsi_set_role(struct lws *wsi, lws_wsi_state_t role) void lwsi_set_state(struct lws *wsi, lws_wsi_state_t lrs) { - wsi->wsistate = (wsi->wsistate & (unsigned int)(~LRS_MASK)) | lrs; + lws_wsi_state_t old = wsi->wsistate; - lwsl_debug("lwsi_set_state(%s, 0x%lx)\n", lws_wsi_tag(wsi), - (unsigned long)wsi->wsistate); + wsi->wsistate = (old & (unsigned int)(~LRS_MASK)) | lrs; + + lwsl_debug("lwsi_set_state(%s): 0x%lx -> 0x%lx)\n", lws_wsi_tag(wsi), + (unsigned long)old, (unsigned long)wsi->wsistate); } #endif @@ -56,6 +58,7 @@ lws_vhost_bind_wsi(struct lws_vhost *vh, struct lws *wsi) { if (wsi->a.vhost == vh) return; + lws_context_lock(vh->context, __func__); /* ---------- context { */ wsi->a.vhost = vh; @@ -68,6 +71,7 @@ lws_vhost_bind_wsi(struct lws_vhost *vh, struct lws *wsi) vh->count_bound_wsi++; lws_context_unlock(vh->context); /* } context ---------- */ + lwsl_debug("%s: vh %s: wsi %s/%s, count_bound_wsi %d\n", __func__, vh->name, wsi->role_ops ? wsi->role_ops->name : "none", wsi->a.protocol ? wsi->a.protocol->name : "none", |