From eeea000ced47ab9d0911980aaf97178ee66f454e Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 28 Jun 2021 05:06:38 +0100 Subject: [PATCH] dns: handle EAI_NONAME as fatal This causes the blocking dns lookup to treat EAI_NONAME as immediately fatal, this is usually caused by an assertive NXDOMAIN from the DNS server or similar. Not being able to reach the server should continue to retry. In order to make the problem visible, it reports the situation using CLIENT_CONNECTION_ERROR, even though it is still inside the outer client creation call. --- lib/core-net/client/connect2.c | 18 ++++++++++++++++++ lib/secure-streams/secure-streams.c | 19 +++++++++++++------ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/lib/core-net/client/connect2.c b/lib/core-net/client/connect2.c index d08f89818..af2611bc8 100644 --- a/lib/core-net/client/connect2.c +++ b/lib/core-net/client/connect2.c @@ -124,6 +124,10 @@ lws_getaddrinfo46(struct lws *wsi, const char *ads, struct addrinfo **result) } #endif +#if !defined(LWS_WITH_SYS_ASYNC_DNS) && defined(EAI_NONAME) +static const char * const dns_nxdomain = "DNS NXDOMAIN"; +#endif + struct lws * lws_client_connect_2_dnsreq(struct lws *wsi) { @@ -344,6 +348,20 @@ solo: * blocking dns resolution */ n = lws_getaddrinfo46(wsi, ads, &result); +#if defined(EAI_NONAME) + if (n == EAI_NONAME) { + /* + * The DNS server responded with NXDOMAIN... even + * though this is still in the client creation call, + * we need to make a CCE, otherwise there won't be + * any user indication of what went wrong + */ + wsi->client_suppress_CONNECTION_ERROR = 0; + lws_inform_client_conn_fail(wsi, (void *)dns_nxdomain, + sizeof(dns_nxdomain)); + goto failed1; + } +#endif } #else /* this is either FAILED, CONTINUING, or already called connect_4 */ diff --git a/lib/secure-streams/secure-streams.c b/lib/secure-streams/secure-streams.c index 0d067d71d..64938b20d 100644 --- a/lib/secure-streams/secure-streams.c +++ b/lib/secure-streams/secure-streams.c @@ -804,13 +804,20 @@ _lws_ss_client_connect(lws_ss_handle_t *h, int is_retry, void *conn_if_sspc_onw) * having to go around the event loop */ - r = lws_ss_event_helper(h, LWSSSCS_UNREACHABLE); - if (r) - return r; + if (h->prev_ss_state != LWSSSCS_UNREACHABLE && + h->prev_ss_state != LWSSSCS_ALL_RETRIES_FAILED) { + /* + * blocking DNS failure can get to unreachable via + * CCE, and unreachable can get to ALL_RETRIES_FAILED + */ + r = lws_ss_event_helper(h, LWSSSCS_UNREACHABLE); + if (r) + return r; - r = lws_ss_backoff(h); - if (r) - return r; + r = lws_ss_backoff(h); + if (r) + return r; + } return LWSSSSRET_TX_DONT_SEND; }