Skip to content

Commit fad0564

Browse files
altelchaltelchd-a-v
authored
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 <[email protected]> Co-authored-by: david gauchard <[email protected]>
1 parent bc170e6 commit fad0564

File tree

3 files changed

+88
-4
lines changed

3 files changed

+88
-4
lines changed

libraries/ESP8266WiFi/examples/IPv6/IPv6.ino

+21-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
/*
32
arduino IPv6 example
43
released to public domain
@@ -27,7 +26,8 @@
2726
#define STAPSK "your-password"
2827
#endif
2928

30-
#define FQDN F("www.google.com") // with both IPv4 & IPv6 addresses
29+
#define FQDN F("www.google.com") // with both IPv4 & IPv6 addresses
30+
#define FQDN2 F("www.yahoo.com") // with both IPv4 & IPv6 addresses
3131
#define FQDN6 F("ipv6.google.com") // does not resolve in IPv4
3232
#define STATUSDELAY_MS 10000
3333
#define TCP_PORT 23
@@ -50,6 +50,21 @@ void fqdn(Print& out, const String& fqdn) {
5050
}
5151
}
5252

53+
#if LWIP_IPV4 && LWIP_IPV6
54+
void fqdn_rt(Print& out, const String& fqdn, DNSResolveType resolveType) {
55+
out.print(F("resolving "));
56+
out.print(fqdn);
57+
out.print(F(": "));
58+
IPAddress result;
59+
if (WiFi.hostByName(fqdn.c_str(), result, 10000, resolveType)) {
60+
result.printTo(out);
61+
out.println();
62+
} else {
63+
out.println(F("timeout or not found"));
64+
}
65+
}
66+
#endif
67+
5368
void status(Print& out) {
5469
out.println(F("------------------------------"));
5570
out.println(ESP.getFullVersion());
@@ -85,7 +100,10 @@ void status(Print& out) {
85100
// an example is provided with a fqdn which does not resolve with IPv4
86101
fqdn(out, FQDN);
87102
fqdn(out, FQDN6);
88-
103+
#if LWIP_IPV4 && LWIP_IPV6
104+
fqdn_rt(out, FQDN, DNSResolveType::DNS_AddrType_IPv4_IPv6); // IPv4 before IPv6
105+
fqdn_rt(out, FQDN2, DNSResolveType::DNS_AddrType_IPv6_IPv4); // IPv6 before IPv4
106+
#endif
89107
out.println(F("------------------------------"));
90108
}
91109

libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp

+56-1
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResul
608608
int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult, uint32_t timeout_ms)
609609
{
610610
ip_addr_t addr;
611-
aResult = static_cast<uint32_t>(0);
611+
aResult = static_cast<uint32_t>(INADDR_NONE);
612612

613613
if(aResult.fromString(aHostname)) {
614614
// Host name is a IP address use it!
@@ -617,7 +617,61 @@ int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResul
617617
}
618618

619619
DEBUG_WIFI_GENERIC("[hostByName] request IP for: %s\n", aHostname);
620+
#if LWIP_IPV4 && LWIP_IPV6
621+
err_t err = dns_gethostbyname_addrtype(aHostname, &addr, &wifi_dns_found_callback, &aResult,LWIP_DNS_ADDRTYPE_DEFAULT);
622+
#else
620623
err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult);
624+
#endif
625+
if(err == ERR_OK) {
626+
aResult = IPAddress(&addr);
627+
} else if(err == ERR_INPROGRESS) {
628+
_dns_lookup_pending = true;
629+
delay(timeout_ms);
630+
// will resume on timeout or when wifi_dns_found_callback fires
631+
_dns_lookup_pending = false;
632+
// will return here when dns_found_callback fires
633+
if(aResult.isSet()) {
634+
err = ERR_OK;
635+
}
636+
}
637+
638+
if(err != 0) {
639+
DEBUG_WIFI_GENERIC("[hostByName] Host: %s lookup error: %d!\n", aHostname, (int)err);
640+
} else {
641+
DEBUG_WIFI_GENERIC("[hostByName] Host: %s IP: %s\n", aHostname, aResult.toString().c_str());
642+
}
643+
644+
return (err == ERR_OK) ? 1 : 0;
645+
}
646+
647+
#if LWIP_IPV4 && LWIP_IPV6
648+
int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult, uint32_t timeout_ms, DNSResolveType resolveType)
649+
{
650+
ip_addr_t addr;
651+
err_t err;
652+
aResult = static_cast<uint32_t>(INADDR_NONE);
653+
654+
if(aResult.fromString(aHostname)) {
655+
// Host name is a IP address use it!
656+
DEBUG_WIFI_GENERIC("[hostByName] Host: %s is a IP!\n", aHostname);
657+
return 1;
658+
}
659+
660+
DEBUG_WIFI_GENERIC("[hostByName] request IP for: %s\n", aHostname);
661+
switch(resolveType)
662+
{
663+
// Use selected addrtype
664+
case DNSResolveType::DNS_AddrType_IPv4:
665+
case DNSResolveType::DNS_AddrType_IPv6:
666+
case DNSResolveType::DNS_AddrType_IPv4_IPv6:
667+
case DNSResolveType::DNS_AddrType_IPv6_IPv4:
668+
err = dns_gethostbyname_addrtype(aHostname, &addr, &wifi_dns_found_callback, &aResult, (uint8_t) resolveType);
669+
break;
670+
default:
671+
err = dns_gethostbyname_addrtype(aHostname, &addr, &wifi_dns_found_callback, &aResult, LWIP_DNS_ADDRTYPE_DEFAULT); // If illegal type, use default.
672+
break;
673+
}
674+
621675
if(err == ERR_OK) {
622676
aResult = IPAddress(&addr);
623677
} else if(err == ERR_INPROGRESS) {
@@ -639,6 +693,7 @@ int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResul
639693

640694
return (err == ERR_OK) ? 1 : 0;
641695
}
696+
#endif
642697

643698
/**
644699
* DNS callback

libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h

+11
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ typedef std::shared_ptr<WiFiEventHandlerOpaque> WiFiEventHandler;
4242

4343
typedef void (*WiFiEventCb)(WiFiEvent_t);
4444

45+
enum class DNSResolveType: uint8_t
46+
{
47+
DNS_AddrType_IPv4 = 0, // LWIP_DNS_ADDRTYPE_IPV4 = 0
48+
DNS_AddrType_IPv6, // LWIP_DNS_ADDRTYPE_IPV6 = 1
49+
DNS_AddrType_IPv4_IPv6, // LWIP_DNS_ADDRTYPE_IPV4_IPV6 = 2
50+
DNS_AddrType_IPv6_IPv4 // LWIP_DNS_ADDRTYPE_IPV6_IPV4 = 3
51+
};
52+
4553
struct WiFiState;
4654

4755
class ESP8266WiFiGenericClass {
@@ -113,6 +121,9 @@ class ESP8266WiFiGenericClass {
113121
public:
114122
int hostByName(const char* aHostname, IPAddress& aResult);
115123
int hostByName(const char* aHostname, IPAddress& aResult, uint32_t timeout_ms);
124+
#if LWIP_IPV4 && LWIP_IPV6
125+
int hostByName(const char* aHostname, IPAddress& aResult, uint32_t timeout_ms, DNSResolveType resolveType);
126+
#endif
116127
bool getPersistent();
117128

118129
protected:

0 commit comments

Comments
 (0)