1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-07-13 02:22:55 +03:00

Make DNS resolution order selectable during runtime or compile time (#6865)

* Make DNS resolution order selectable during runtime or compile time (only in dual stack mode).

* Extend IPv6 example to show usage of new hostByName function with selectable resolving order

* Fix function definition of fqdn_rt in IPv6.ino.

* Fix function call.

* Fix missing bracket...

* Only run if built with dual stack support

* Make DNS resolution order selectable during runtime or compile time (only in dual stack mode).

* Extend IPv6 example to show usage of new hostByName function with selectable resolving order

* Fix function definition of fqdn_rt in IPv6 example.

* Implement enum class for resolve type

* Fix example IPv6.ino

* Fix typedef in ESP8266WiFiGeneric.h function call

* Change enum class definition to not depend on lwip/dns.h

* Move err_t err definition outside switch. Fix typecast.

* Always define DNSResolveType as pio test otherwise failes even if the enum class isn't used.

Co-authored-by: altelch <heiko.krupp@rhrk.uni-kl.de>
Co-authored-by: david gauchard <gauchard@laas.fr>
This commit is contained in:
Heiko Krupp
2020-04-09 18:17:54 +02:00
committed by GitHub
parent bc170e6d63
commit fad056442d
3 changed files with 88 additions and 4 deletions

View File

@ -1,4 +1,3 @@
/* /*
arduino IPv6 example arduino IPv6 example
released to public domain released to public domain
@ -27,7 +26,8 @@
#define STAPSK "your-password" #define STAPSK "your-password"
#endif #endif
#define FQDN F("www.google.com") // with both IPv4 & IPv6 addresses #define FQDN F("www.google.com") // with both IPv4 & IPv6 addresses
#define FQDN2 F("www.yahoo.com") // with both IPv4 & IPv6 addresses
#define FQDN6 F("ipv6.google.com") // does not resolve in IPv4 #define FQDN6 F("ipv6.google.com") // does not resolve in IPv4
#define STATUSDELAY_MS 10000 #define STATUSDELAY_MS 10000
#define TCP_PORT 23 #define TCP_PORT 23
@ -50,6 +50,21 @@ void fqdn(Print& out, const String& fqdn) {
} }
} }
#if LWIP_IPV4 && LWIP_IPV6
void fqdn_rt(Print& out, const String& fqdn, DNSResolveType resolveType) {
out.print(F("resolving "));
out.print(fqdn);
out.print(F(": "));
IPAddress result;
if (WiFi.hostByName(fqdn.c_str(), result, 10000, resolveType)) {
result.printTo(out);
out.println();
} else {
out.println(F("timeout or not found"));
}
}
#endif
void status(Print& out) { void status(Print& out) {
out.println(F("------------------------------")); out.println(F("------------------------------"));
out.println(ESP.getFullVersion()); out.println(ESP.getFullVersion());
@ -85,7 +100,10 @@ void status(Print& out) {
// an example is provided with a fqdn which does not resolve with IPv4 // an example is provided with a fqdn which does not resolve with IPv4
fqdn(out, FQDN); fqdn(out, FQDN);
fqdn(out, FQDN6); fqdn(out, FQDN6);
#if LWIP_IPV4 && LWIP_IPV6
fqdn_rt(out, FQDN, DNSResolveType::DNS_AddrType_IPv4_IPv6); // IPv4 before IPv6
fqdn_rt(out, FQDN2, DNSResolveType::DNS_AddrType_IPv6_IPv4); // IPv6 before IPv4
#endif
out.println(F("------------------------------")); out.println(F("------------------------------"));
} }

View File

@ -608,7 +608,7 @@ int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResul
int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult, uint32_t timeout_ms) int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult, uint32_t timeout_ms)
{ {
ip_addr_t addr; ip_addr_t addr;
aResult = static_cast<uint32_t>(0); aResult = static_cast<uint32_t>(INADDR_NONE);
if(aResult.fromString(aHostname)) { if(aResult.fromString(aHostname)) {
// Host name is a IP address use it! // Host name is a IP address use it!
@ -617,7 +617,11 @@ int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResul
} }
DEBUG_WIFI_GENERIC("[hostByName] request IP for: %s\n", aHostname); DEBUG_WIFI_GENERIC("[hostByName] request IP for: %s\n", aHostname);
#if LWIP_IPV4 && LWIP_IPV6
err_t err = dns_gethostbyname_addrtype(aHostname, &addr, &wifi_dns_found_callback, &aResult,LWIP_DNS_ADDRTYPE_DEFAULT);
#else
err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult); err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult);
#endif
if(err == ERR_OK) { if(err == ERR_OK) {
aResult = IPAddress(&addr); aResult = IPAddress(&addr);
} else if(err == ERR_INPROGRESS) { } else if(err == ERR_INPROGRESS) {
@ -640,6 +644,57 @@ int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResul
return (err == ERR_OK) ? 1 : 0; return (err == ERR_OK) ? 1 : 0;
} }
#if LWIP_IPV4 && LWIP_IPV6
int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult, uint32_t timeout_ms, DNSResolveType resolveType)
{
ip_addr_t addr;
err_t err;
aResult = static_cast<uint32_t>(INADDR_NONE);
if(aResult.fromString(aHostname)) {
// Host name is a IP address use it!
DEBUG_WIFI_GENERIC("[hostByName] Host: %s is a IP!\n", aHostname);
return 1;
}
DEBUG_WIFI_GENERIC("[hostByName] request IP for: %s\n", aHostname);
switch(resolveType)
{
// Use selected addrtype
case DNSResolveType::DNS_AddrType_IPv4:
case DNSResolveType::DNS_AddrType_IPv6:
case DNSResolveType::DNS_AddrType_IPv4_IPv6:
case DNSResolveType::DNS_AddrType_IPv6_IPv4:
err = dns_gethostbyname_addrtype(aHostname, &addr, &wifi_dns_found_callback, &aResult, (uint8_t) resolveType);
break;
default:
err = dns_gethostbyname_addrtype(aHostname, &addr, &wifi_dns_found_callback, &aResult, LWIP_DNS_ADDRTYPE_DEFAULT); // If illegal type, use default.
break;
}
if(err == ERR_OK) {
aResult = IPAddress(&addr);
} else if(err == ERR_INPROGRESS) {
_dns_lookup_pending = true;
delay(timeout_ms);
// will resume on timeout or when wifi_dns_found_callback fires
_dns_lookup_pending = false;
// will return here when dns_found_callback fires
if(aResult.isSet()) {
err = ERR_OK;
}
}
if(err != 0) {
DEBUG_WIFI_GENERIC("[hostByName] Host: %s lookup error: %d!\n", aHostname, (int)err);
} else {
DEBUG_WIFI_GENERIC("[hostByName] Host: %s IP: %s\n", aHostname, aResult.toString().c_str());
}
return (err == ERR_OK) ? 1 : 0;
}
#endif
/** /**
* DNS callback * DNS callback
* @param name * @param name

View File

@ -42,6 +42,14 @@ typedef std::shared_ptr<WiFiEventHandlerOpaque> WiFiEventHandler;
typedef void (*WiFiEventCb)(WiFiEvent_t); typedef void (*WiFiEventCb)(WiFiEvent_t);
enum class DNSResolveType: uint8_t
{
DNS_AddrType_IPv4 = 0, // LWIP_DNS_ADDRTYPE_IPV4 = 0
DNS_AddrType_IPv6, // LWIP_DNS_ADDRTYPE_IPV6 = 1
DNS_AddrType_IPv4_IPv6, // LWIP_DNS_ADDRTYPE_IPV4_IPV6 = 2
DNS_AddrType_IPv6_IPv4 // LWIP_DNS_ADDRTYPE_IPV6_IPV4 = 3
};
struct WiFiState; struct WiFiState;
class ESP8266WiFiGenericClass { class ESP8266WiFiGenericClass {
@ -113,6 +121,9 @@ class ESP8266WiFiGenericClass {
public: public:
int hostByName(const char* aHostname, IPAddress& aResult); int hostByName(const char* aHostname, IPAddress& aResult);
int hostByName(const char* aHostname, IPAddress& aResult, uint32_t timeout_ms); int hostByName(const char* aHostname, IPAddress& aResult, uint32_t timeout_ms);
#if LWIP_IPV4 && LWIP_IPV6
int hostByName(const char* aHostname, IPAddress& aResult, uint32_t timeout_ms, DNSResolveType resolveType);
#endif
bool getPersistent(); bool getPersistent();
protected: protected: