Add WifiPollDns to reduce blocking

Add WifiPollDns to reduce blocking resolving NTP and/or MQTT server names (#14398)
This commit is contained in:
Theo Arends 2022-06-12 14:29:15 +02:00
parent 42ab2c3f70
commit 940108c010
2 changed files with 76 additions and 18 deletions

View File

@ -729,6 +729,30 @@ void wifiKeepAlive(void) {
}
#endif // ESP8266
bool WifiPollDns(void) {
// WiFi.hostByName takes over ten seconds if no DNS server found
// This function checks to find the DNS server within 1 second
// This is an alternative for ping using less resources
WiFiClient DnsClient;
#ifdef ESP8266
DnsClient.setTimeout(1000);
#else
DnsClient.setTimeout(1);
#endif
uint32_t i = 3; // Check DNS1 only (to keep blocking to a minimum of 1 second)
// for (i = 3; i < 5; i++) { // Check DNS1 and DNS2
uint32_t dns_address = (!TasmotaGlobal.global_state.eth_down) ? Settings->eth_ipv4_address[i] : Settings->ipv4_address[i];
if (DnsClient.connect((IPAddress)dns_address, 53)) {
DnsClient.stop();
return true;
}
// AddLog(LOG_LEVEL_DEBUG, PSTR("DNS: Disconnected %_I"), dns_address);
AddLog(LOG_LEVEL_DEBUG, PSTR("DNS: Disconnected"));
// }
return false;
}
void WifiPollNtp() {
static uint8_t ntp_sync_minute = 0;
static uint32_t ntp_run_time = 0;
@ -775,24 +799,26 @@ uint32_t WifiGetNtp(void) {
char* ntp_server;
bool resolved_ip = false;
for (uint32_t i = 0; i <= MAX_NTP_SERVERS; i++) {
if (ntp_server_id > 2) { ntp_server_id = 0; }
if (i < MAX_NTP_SERVERS) {
ntp_server = SettingsText(SET_NTPSERVER1 + ntp_server_id);
} else {
ntp_server = fallback_ntp_server;
}
if (strlen(ntp_server)) {
resolved_ip = (WiFi.hostByName(ntp_server, time_server_ip) == 1); // DNS timeout set to (ESP8266) 10s / (ESP32) 14s
if ((255 == time_server_ip[0]) || // No valid name resolved (255.255.255.255)
((255 == time_server_ip[1]) && (255 == time_server_ip[2]) && (255 == time_server_ip[3]))) { // No valid name resolved (x.255.255.255)
resolved_ip = false;
if (WifiPollDns()) {
for (uint32_t i = 0; i <= MAX_NTP_SERVERS; i++) {
if (ntp_server_id > 2) { ntp_server_id = 0; }
if (i < MAX_NTP_SERVERS) {
ntp_server = SettingsText(SET_NTPSERVER1 + ntp_server_id);
} else {
ntp_server = fallback_ntp_server;
}
yield();
if (resolved_ip) { break; }
// AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: Unable to resolve '%s'"), ntp_server);
if (strlen(ntp_server)) {
resolved_ip = (WiFi.hostByName(ntp_server, time_server_ip) == 1); // DNS timeout set to (ESP8266) 10s / (ESP32) 14s
if ((255 == time_server_ip[0]) || // No valid name resolved (255.255.255.255)
((255 == time_server_ip[1]) && (255 == time_server_ip[2]) && (255 == time_server_ip[3]))) { // No valid name resolved (x.255.255.255)
resolved_ip = false;
}
yield();
if (resolved_ip) { break; }
// AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: Unable to resolve '%s'"), ntp_server);
}
ntp_server_id++;
}
ntp_server_id++;
}
if (!resolved_ip) {
AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: Unable to resolve IP address"));

View File

@ -193,6 +193,17 @@ void MqttDisableLogging(bool state) {
PubSubClient MqttClient;
void MqttSetClientTimeout(void) {
#ifdef ESP8266
// setTimeout in msecs
EspClient.setTimeout(Settings->mqtt_wifi_timeout * 100);
#else
// setTimeout in secs
uint32_t timeout = (Settings->mqtt_wifi_timeout < 10) ? 1 : Settings->mqtt_wifi_timeout / 10;
EspClient.setTimeout(timeout);
#endif
}
void MqttInit(void) {
// Force buffer size since the #define may not be visible from Arduino lib
MqttClient.setBufferSize(MQTT_MAX_PACKET_SIZE);
@ -860,6 +871,20 @@ uint16_t MqttConnectCount(void) {
}
void MqttDisconnected(int state) {
/*
// Possible values for state - PubSubClient.h
Tasmota MQTT_DNS_DISCONNECTED -5
#define MQTT_CONNECTION_TIMEOUT -4
#define MQTT_CONNECTION_LOST -3
#define MQTT_CONNECT_FAILED -2
#define MQTT_DISCONNECTED -1
#define MQTT_CONNECTED 0
#define MQTT_CONNECT_BAD_PROTOCOL 1
#define MQTT_CONNECT_BAD_CLIENT_ID 2
#define MQTT_CONNECT_UNAVAILABLE 3
#define MQTT_CONNECT_BAD_CREDENTIALS 4
#define MQTT_CONNECT_UNAUTHORIZED 5
*/
Mqtt.connected = false;
Mqtt.retry_counter = Settings->mqtt_retry * Mqtt.retry_counter_delay;
@ -1028,7 +1053,9 @@ void MqttReconnect(void) {
Response_P(S_LWT_OFFLINE);
if (MqttClient.connected()) { MqttClient.disconnect(); }
EspClient.setTimeout(Settings->mqtt_wifi_timeout * 100);
MqttSetClientTimeout();
#ifdef USE_MQTT_TLS
if (Mqtt.mqtt_tls) {
tlsClient->stop();
@ -1056,6 +1083,11 @@ void MqttReconnect(void) {
}
}
#endif
if (!WifiPollDns()) {
MqttDisconnected(-5); // MQTT_DNS_DISCONNECTED
return;
}
MqttClient.setServer(SettingsText(SET_MQTT_HOST), Settings->mqtt_port);
uint32_t mqtt_connect_time = millis();
@ -1363,7 +1395,7 @@ void CmndMqttWifiTimeout(void) {
// Set timeout between 100 and 20000 mSec
if ((XdrvMailbox.payload >= 100) && (XdrvMailbox.payload <= 20000)) {
Settings->mqtt_wifi_timeout = XdrvMailbox.payload / 100;
EspClient.setTimeout(Settings->mqtt_wifi_timeout * 100);
MqttSetClientTimeout();
}
ResponseCmndNumber(Settings->mqtt_wifi_timeout * 100);
}