Add telegram DNS checks

This commit is contained in:
Theo Arends 2022-06-20 10:49:23 +02:00
parent b5dd23ae9f
commit 541be4a8ab
5 changed files with 28 additions and 23 deletions

View File

@ -51,23 +51,20 @@
#define htons(x) ( ((x)<< 8 & 0xFF00) | ((x)>> 8 & 0x00FF) ) #define htons(x) ( ((x)<< 8 & 0xFF00) | ((x)>> 8 & 0x00FF) )
#endif #endif
void DNSClient::begin(const IPAddress& aDNSServer) { void DNSClient::begin(const IPAddress& aDNSServer) {
iDNSServer = aDNSServer; iDNSServer = aDNSServer;
iRequestId = 0; iRequestId = 0;
} }
void DNSClient::setTimeout(uint16_t aTimeout) { void DNSClient::setTimeout(uint32_t aTimeout) {
iTimeout = aTimeout; iTimeout = aTimeout;
} }
int DNSClient::getHostByName(const char* aHostname, IPAddress& aResult) { int DNSClient::getHostByName(const char* aHostname, IPAddress& aResult) {
int ret =0;
// See if it's a numeric IP address // See if it's a numeric IP address
if (aResult.fromString(aHostname)) { if (aResult.fromString(aHostname)) {
// It is, our work here is done // It is, our work here is done
return 1; return SUCCESS;
} }
// Check we've got a valid DNS server to use // Check we've got a valid DNS server to use
@ -75,6 +72,7 @@ int DNSClient::getHostByName(const char* aHostname, IPAddress& aResult) {
return INVALID_SERVER; return INVALID_SERVER;
} }
int ret = 0;
// Find a socket to use // Find a socket to use
if (iUdp.begin(1024+(millis() & 0xF)) == 1) { if (iUdp.begin(1024+(millis() & 0xF)) == 1) {
// Try up to three times // Try up to three times
@ -107,10 +105,9 @@ int DNSClient::getHostByName(const char* aHostname, IPAddress& aResult) {
return ret; return ret;
} }
uint16_t DNSClient::BuildRequest(const char* aName) { int DNSClient::BuildRequest(const char* aName) {
// Build header // Build header
// 1 1 1 1 1 1 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
// | ID | // | ID |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
@ -178,10 +175,10 @@ uint16_t DNSClient::BuildRequest(const char* aName) {
twoByteBuffer = htons(CLASS_IN); // Internet class of question twoByteBuffer = htons(CLASS_IN); // Internet class of question
iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer)); iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
// Success! Everything buffered okay // Success! Everything buffered okay
return 1; return SUCCESS;
} }
uint16_t DNSClient::ProcessResponse(uint16_t aTimeout, IPAddress& aAddress) { int DNSClient::ProcessResponse(uint32_t aTimeout, IPAddress& aAddress) {
uint32_t startTime = millis(); uint32_t startTime = millis();
// Wait for a response packet // Wait for a response packet
@ -236,7 +233,7 @@ uint16_t DNSClient::ProcessResponse(uint16_t aTimeout, IPAddress& aAddress) {
// Skip over any questions // Skip over any questions
memcpy(&staging, &header[4], sizeof(uint16_t)); memcpy(&staging, &header[4], sizeof(uint16_t));
for (uint16_t i =0; i < htons(staging); i++) { for (uint32_t i = 0; i < htons(staging); i++) {
// Skip over the name // Skip over the name
uint8_t len; uint8_t len;
do { do {
@ -251,7 +248,7 @@ uint16_t DNSClient::ProcessResponse(uint16_t aTimeout, IPAddress& aAddress) {
} while (len != 0); } while (len != 0);
// Now jump over the type and class // Now jump over the type and class
for (int i =0; i < 4; i++) { for (uint32_t i = 0; i < 4; i++) {
iUdp.read(); // we don't care about the returned byte iUdp.read(); // we don't care about the returned byte
} }
} }
@ -261,7 +258,7 @@ uint16_t DNSClient::ProcessResponse(uint16_t aTimeout, IPAddress& aAddress) {
// type A answer) and some authority and additional resource records but // type A answer) and some authority and additional resource records but
// we're going to ignore all of them. // we're going to ignore all of them.
for (uint16_t i =0; i < answerCount; i++) { for (uint32_t i = 0; i < answerCount; i++) {
// Skip the name // Skip the name
uint8_t len; uint8_t len;
do { do {
@ -297,7 +294,7 @@ uint16_t DNSClient::ProcessResponse(uint16_t aTimeout, IPAddress& aAddress) {
iUdp.read((uint8_t*)&answerClass, sizeof(answerClass)); iUdp.read((uint8_t*)&answerClass, sizeof(answerClass));
// Ignore the Time-To-Live as we don't do any caching // Ignore the Time-To-Live as we don't do any caching
for (int i =0; i < TTL_SIZE; i++) { for (uint32_t i = 0; i < TTL_SIZE; i++) {
iUdp.read(); // We don't care about the returned byte iUdp.read(); // We don't care about the returned byte
} }
@ -323,7 +320,7 @@ uint16_t DNSClient::ProcessResponse(uint16_t aTimeout, IPAddress& aAddress) {
} }
} else { } else {
// This isn't an answer type we're after, move onto the next one // This isn't an answer type we're after, move onto the next one
for (uint16_t i =0; i < htons(header_flags); i++) { for (uint32_t i = 0; i < htons(header_flags); i++) {
iUdp.read(); // we don't care about the returned byte iUdp.read(); // we don't care about the returned byte
} }
} }

View File

@ -20,7 +20,7 @@
class DNSClient { class DNSClient {
public: public:
void begin(const IPAddress& aDNSServer); void begin(const IPAddress& aDNSServer);
void setTimeout(uint16_t aTimeout = 1000); void setTimeout(uint32_t aTimeout = 1000);
/* Resolve the given hostname to an IP address. /* Resolve the given hostname to an IP address.
@param aHostname Name to be resolved @param aHostname Name to be resolved
@ -30,8 +30,8 @@ public:
int getHostByName(const char* aHostname, IPAddress& aResult); int getHostByName(const char* aHostname, IPAddress& aResult);
protected: protected:
uint16_t BuildRequest(const char* aName); int BuildRequest(const char* aName);
uint16_t ProcessResponse(uint16_t aTimeout, IPAddress& aAddress); int ProcessResponse(uint32_t aTimeout, IPAddress& aAddress);
IPAddress iDNSServer; IPAddress iDNSServer;
uint16_t iRequestId; uint16_t iRequestId;

View File

@ -2455,7 +2455,7 @@ void SyslogAsync(bool refresh) {
if (!WifiHostByName(SettingsText(SET_SYSLOG_HOST), temp_syslog_host_addr)) { // If sleep enabled this might result in exception so try to do it once using hash if (!WifiHostByName(SettingsText(SET_SYSLOG_HOST), temp_syslog_host_addr)) { // If sleep enabled this might result in exception so try to do it once using hash
TasmotaGlobal.syslog_level = 0; TasmotaGlobal.syslog_level = 0;
TasmotaGlobal.syslog_timer = SYSLOG_TIMER; TasmotaGlobal.syslog_timer = SYSLOG_TIMER;
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION "Loghost DNS resolve failed (%s). " D_RETRY_IN " %d " D_UNIT_SECOND), SettingsText(SET_SYSLOG_HOST), SYSLOG_TIMER); AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_RETRY_IN " %d " D_UNIT_SECOND), SYSLOG_TIMER);
return; return;
} }
syslog_host_hash = current_hash; syslog_host_hash = current_hash;

View File

@ -733,7 +733,11 @@ bool WifiHostByName(const char* aHostname, IPAddress& aResult) {
// Use this instead of WiFi.hostByName or connect(host_name,.. to block less if DNS server is not found // Use this instead of WiFi.hostByName or connect(host_name,.. to block less if DNS server is not found
uint32_t dns_address = (!TasmotaGlobal.global_state.eth_down) ? Settings->eth_ipv4_address[3] : Settings->ipv4_address[3]; uint32_t dns_address = (!TasmotaGlobal.global_state.eth_down) ? Settings->eth_ipv4_address[3] : Settings->ipv4_address[3];
DnsClient.begin((IPAddress)dns_address); DnsClient.begin((IPAddress)dns_address);
return (1 == DnsClient.getHostByName(aHostname, aResult)); if (DnsClient.getHostByName(aHostname, aResult) != 1) {
AddLog(LOG_LEVEL_DEBUG, PSTR("DNS: Unable to resolve '%s'"), aHostname);
return false;
}
return true;
} }
void WifiPollNtp() { void WifiPollNtp() {
@ -793,7 +797,7 @@ uint32_t WifiGetNtp(void) {
} }
if (!WifiHostByName(ntp_server, time_server_ip)) { if (!WifiHostByName(ntp_server, time_server_ip)) {
ntp_server_id++; ntp_server_id++;
AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: Unable to resolve '%s'"), ntp_server); // AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: Unable to resolve '%s'"), ntp_server);
return 0; return 0;
} }

View File

@ -107,9 +107,13 @@ String TelegramConnectToTelegram(const String &command) {
String host = F("api.telegram.org"); String host = F("api.telegram.org");
String response = ""; String response = "";
IPAddress telegram_host_ip;
if (!WifiHostByName(host.c_str(), telegram_host_ip)) {
return response;
}
uint32_t tls_connect_time = millis(); uint32_t tls_connect_time = millis();
if (telegramClient->connect(host.c_str(), 443)) { // if (telegramClient->connect(host.c_str(), 443)) {
if (telegramClient->connect(telegram_host_ip, 443)) {
// AddLog(LOG_LEVEL_DEBUG, PSTR("TGM: Connected in %d ms, max ThunkStack used %d"), millis() - tls_connect_time, telegramClient->getMaxThunkStackUse()); // AddLog(LOG_LEVEL_DEBUG, PSTR("TGM: Connected in %d ms, max ThunkStack used %d"), millis() - tls_connect_time, telegramClient->getMaxThunkStackUse());
// telegramClient->println("GET /"+command); // Fails after 20210621 // telegramClient->println("GET /"+command); // Fails after 20210621