diff --git a/include/libwebsockets/lws-stats.h b/include/libwebsockets/lws-stats.h index 53a686d11..58d02dee3 100644 --- a/include/libwebsockets/lws-stats.h +++ b/include/libwebsockets/lws-stats.h @@ -55,8 +55,8 @@ enum { LWSSTATS_US_SSL_RX_DELAY_AVG, /**< aggregate delay between ssl accept complete and first RX */ LWSSTATS_C_PEER_LIMIT_AH_DENIED, /**< number of times we would have given an ah but for the peer limit */ LWSSTATS_C_PEER_LIMIT_WSI_DENIED, /**< number of times we would have given a wsi but for the peer limit */ - LWSSTATS_C_CONNECTIONS_CLIENT, /**< attempted client conns */ - LWSSTATS_C_CONNECTIONS_CLIENT_FAILED, /**< failed client conns */ + LWSSTATS_C_CONNS_CLIENT, /**< attempted client conns */ + LWSSTATS_C_CONNS_CLIENT_FAILED, /**< failed client conns */ /* Add new things just above here ---^ * This is part of the ABI, don't needlessly break compatibility diff --git a/lib/core-net/close.c b/lib/core-net/close.c index d5ac4aa2f..f561e94e7 100644 --- a/lib/core-net/close.c +++ b/lib/core-net/close.c @@ -127,6 +127,24 @@ lws_close_trans_q_leader(struct lws_dll2 *d, void *user) return 0; } + +void +lws_inform_client_conn_fail(struct lws *wsi, void *arg, size_t len) +{ + if (wsi->already_did_cce) + return; + + wsi->already_did_cce = 1; + lws_stats_bump(&wsi->context->pt[(int)wsi->tsi], + LWSSTATS_C_CONNS_CLIENT_FAILED, 1); + + if (!wsi->protocol) + return; + + wsi->protocol->callback(wsi, + LWS_CALLBACK_CLIENT_CONNECTION_ERROR, + wsi->user_space, arg, len); +} #endif void @@ -349,13 +367,13 @@ just_kill_connection: wsi->protocol_bind_balance = 0; } +#if !defined(LWS_NO_CLIENT) if ((lwsi_state(wsi) == LRS_WAITING_SERVER_REPLY || lwsi_state(wsi) == LRS_WAITING_CONNECT) && !wsi->already_did_cce && wsi->protocol) - wsi->protocol->callback(wsi, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - wsi->user_space, - (void *)"closed before established", 24); + lws_inform_client_conn_fail(wsi, + (void *)"closed before established", 24); +#endif /* * Testing with ab shows that we have to stage the socket close when diff --git a/lib/core-net/connect.c b/lib/core-net/connect.c index a3c34564c..8eacb8184 100644 --- a/lib/core-net/connect.c +++ b/lib/core-net/connect.c @@ -45,8 +45,9 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i) struct lws *wsi, *safe = NULL; const struct lws_protocols *p; const char *local = i->protocol; + int tid = 0; #if LWS_MAX_SMP > 1 - int n, tid; + int n; #endif if (i->context->requested_kill) @@ -56,6 +57,11 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i) if (lws_protocol_init(i->context)) return NULL; +#if LWS_MAX_SMP > 1 + tid = wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_GET_THREAD_ID, + NULL, NULL, 0); +#endif + /* * If we have .local_protocol_name, use it to select the local protocol * handler to bind to. Otherwise use .protocol if http[s]. @@ -63,6 +69,8 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i) if (i->local_protocol_name) local = i->local_protocol_name; + lws_stats_bump(&i->context->pt[tid], LWSSTATS_C_CONNS_CLIENT, 1); + /* PHASE 1: create a bare wsi */ wsi = lws_zalloc(sizeof(struct lws), "client wsi"); @@ -91,9 +99,6 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i) */ #if LWS_MAX_SMP > 1 - tid = wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_GET_THREAD_ID, - NULL, NULL, 0); - lws_context_lock(i->context, "client find tsi"); for (n = 0; n < i->context->count_threads; n++) @@ -110,10 +115,6 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i) */ lws_context_unlock(i->context); - - lws_stats_bump(&i->context->pt[tid], LWSSTATS_C_CONNECTIONS_CLIENT, 1); -#else - lws_stats_bump(&i->context->pt[0], LWSSTATS_C_CONNECTIONS_CLIENT, 1); #endif /* @@ -308,5 +309,7 @@ bail2: if (i->pwsi) *i->pwsi = NULL; + lws_stats_bump(&i->context->pt[tid], LWSSTATS_C_CONNS_CLIENT_FAILED, 1); + return NULL; } diff --git a/lib/core-net/private.h b/lib/core-net/private.h index 77789328b..37bf0668c 100644 --- a/lib/core-net/private.h +++ b/lib/core-net/private.h @@ -1121,6 +1121,9 @@ lws_buflist_aware_consume(struct lws *wsi, struct lws_tokens *ebuf, int used, extern const struct lws_protocols protocol_abs_client_raw_skt, protocol_abs_client_unit_test; +void +lws_inform_client_conn_fail(struct lws *wsi, void *arg, size_t len); + #ifdef __cplusplus }; #endif diff --git a/lib/core-net/wsi-timeout.c b/lib/core-net/wsi-timeout.c index 0e65c0129..88d0cb301 100644 --- a/lib/core-net/wsi-timeout.c +++ b/lib/core-net/wsi-timeout.c @@ -107,11 +107,11 @@ lws_sul_wsitimeout_cb(lws_sorted_usec_list_t *sul) * don't try to do protocol cleanup like flush partials. */ wsi->socket_is_permanently_unusable = 1; - if (lwsi_state(wsi) == LRS_WAITING_SSL && wsi->protocol) - wsi->protocol->callback(wsi, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - wsi->user_space, +#if !defined(LWS_NO_CLIENT) + if (lwsi_state(wsi) == LRS_WAITING_SSL) + lws_inform_client_conn_fail(wsi, (void *)"Timed out waiting SSL", 21); +#endif __lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "timeout"); } diff --git a/lib/roles/http/client/client-handshake.c b/lib/roles/http/client/client-handshake.c index a2767c53a..53498ec9d 100644 --- a/lib/roles/http/client/client-handshake.c +++ b/lib/roles/http/client/client-handshake.c @@ -198,10 +198,7 @@ send_hs: return wsi; failed: - wsi->protocol->callback(wsi, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - wsi->user_space, (void *)cce, strlen(cce)); - wsi->already_did_cce = 1; + lws_inform_client_conn_fail(wsi, (void *)cce, strlen(cce)); lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "client_connect2"); @@ -735,12 +732,9 @@ ads_known: oom4: - if (lwsi_role_client(wsi) && wsi->protocol /* && lwsi_state_est(wsi) */) { - wsi->protocol->callback(wsi, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - wsi->user_space, (void *)cce, strlen(cce)); - wsi->already_did_cce = 1; - } + if (lwsi_role_client(wsi) && wsi->protocol /* && lwsi_state_est(wsi) */) + lws_inform_client_conn_fail(wsi,(void *)cce, strlen(cce)); + /* take care that we might be inserted in fds already */ if (wsi->position_in_fds_table != LWS_NO_FDS_POS) goto failed1; @@ -763,10 +757,8 @@ oom4: return NULL; failed: - wsi->protocol->callback(wsi, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - wsi->user_space, (void *)cce, strlen(cce)); - wsi->already_did_cce = 1; + lws_inform_client_conn_fail(wsi, (void *)cce, strlen(cce)); + failed1: lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "client_connect2"); diff --git a/lib/roles/http/client/client.c b/lib/roles/http/client/client.c index dc9882814..65b7c548b 100644 --- a/lib/roles/http/client/client.c +++ b/lib/roles/http/client/client.c @@ -565,10 +565,8 @@ bail3: lwsl_info("closing conn at LWS_CONNMODE...SERVER_REPLY\n"); if (cce) lwsl_info("reason: %s\n", cce); - wsi->protocol->callback(wsi, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - wsi->user_space, (void *)cce, strlen(cce)); - wsi->already_did_cce = 1; + lws_inform_client_conn_fail(wsi, (void *)cce, strlen(cce)); + lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "cbail3"); return -1; @@ -1030,12 +1028,9 @@ bail2: n = 0; if (cce) n = (int)strlen(cce); - w->protocol->callback(w, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - w->user_space, (void *)cce, - (unsigned int)n); + + lws_inform_client_conn_fail(wsi, (void *)cce, (unsigned int)n); } - wsi->already_did_cce = 1; lwsl_info("closing connection (prot %s) " "due to bail2 connection error: %s\n", wsi->protocol ?