From 0fb8504b20952905d050e3c37a071a53eea939e0 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 26 Jun 2020 09:58:20 +0100 Subject: [PATCH] client: suppress CONNECTION_ERROR if still in client_connect_via_info If the client connection attempt fails early, we report it will a NULL return from the client connection api. If it fails later, perhaps after more times around the event loop, we report it as a CONNECTION_ERROR. This patch makes sure we don't do CONNECTION_ERROR flow if in fact we are still in the client_connect_via_info() and in a position to report the failure by returning NULL from there, without it under some conditions we will do both a CONNECTION_ERROR and return NULL. --- lib/core-net/close.c | 7 ++++--- lib/core-net/connect.c | 15 ++++++++++++++- lib/core-net/private-lib-core-net.h | 3 +++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/lib/core-net/close.c b/lib/core-net/close.c index f10cea428..a92f258fe 100644 --- a/lib/core-net/close.c +++ b/lib/core-net/close.c @@ -214,9 +214,10 @@ lws_inform_client_conn_fail(struct lws *wsi, void *arg, size_t len) if (!wsi->protocol) return; - wsi->protocol->callback(wsi, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - wsi->user_space, arg, len); + if (!wsi->client_suppress_CONNECTION_ERROR) + wsi->protocol->callback(wsi, + LWS_CALLBACK_CLIENT_CONNECTION_ERROR, + wsi->user_space, arg, len); } #endif diff --git a/lib/core-net/connect.c b/lib/core-net/connect.c index af5c9a9d2..1fae6c799 100644 --- a/lib/core-net/connect.c +++ b/lib/core-net/connect.c @@ -58,6 +58,12 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i) if (wsi == NULL) goto bail; + /* + * Until we exit, we can report connection failure directly to the + * caller without needing to call through to protocol CONNECTION_ERROR. + */ + wsi->client_suppress_CONNECTION_ERROR = 1; + if (i->keep_warm_secs) wsi->keep_warm_secs = i->keep_warm_secs; else @@ -356,9 +362,16 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i) /* fallthru */ - lws_http_client_connect_via_info2(wsi); + wsi = lws_http_client_connect_via_info2(wsi); } + if (wsi) + /* + * If it subsequently fails, report CONNECTION_ERROR, + * because we're going to return a non-error return now. + */ + wsi->client_suppress_CONNECTION_ERROR = 0; + return wsi; #if defined(LWS_WITH_TLS) diff --git a/lib/core-net/private-lib-core-net.h b/lib/core-net/private-lib-core-net.h index 065b25264..a688e03b5 100644 --- a/lib/core-net/private-lib-core-net.h +++ b/lib/core-net/private-lib-core-net.h @@ -823,6 +823,9 @@ struct lws { unsigned int client_mux_migrated:1; unsigned int client_subsequent_mime_part:1; unsigned int client_no_follow_redirect:1; + unsigned int client_suppress_CONNECTION_ERROR:1; + /**< because the client connection creation api is still the parent of + * this activity, and will report the failure */ #endif #ifdef _WIN32