Skip to content

Commit 07dc0a6

Browse files
committed
fix(dns): Fix IPv6-only network, by checking IPv6 first if you have public address
Work around because AF_UNSPEC does not check available addresses when determining result. If you have a global scope IPv6 address, then first check for IPv6 DNS result; if you don't have an IPv6, or there is no IPv6 result, then check IPv4. This allows IPv6-only networks to connect to dual-stack destinations, as they will get the IPv6 address (rather than the unusable IPv4). It also means a dual-stack host to a dual-stack destination will preference IPv6. There is no effect if you are on an IPv4-only network, or it is an IPv4-only destination.
1 parent 8c75c35 commit 07dc0a6

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

Diff for: libraries/Network/src/NetworkManager.cpp

+28-4
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,36 @@ int NetworkManager::hostByName(const char* aHostname, IPAddress& aResult)
8686
log_d("Clearing DNS cache");
8787
}
8888

89-
struct addrinfo hints;
90-
memset(&hints, 0, sizeof(hints));
91-
hints.ai_family = AF_UNSPEC;
92-
hints.ai_socktype = SOCK_STREAM;
89+
// **Workaround**
90+
// LWIP AF_UNSPEC always prefers IPv4 and doesn't check what network is
91+
// available. See https://github.com/espressif/esp-idf/issues/13255
92+
// Until that is fixed, as a work around if we have a global scope IPv6,
93+
// then we check IPv6 only first.
94+
if (hasGlobalV6) {
95+
const struct addrinfo hints6 = {
96+
.ai_family = AF_INET6,
97+
.ai_socktype = SOCK_STREAM,
98+
};
99+
err = lwip_getaddrinfo(aHostname, servname, &hints6, &res);
100+
101+
if (err == ERR_OK)
102+
{
103+
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)res->ai_addr;
104+
// As an array of u8_t
105+
aResult = IPAddress(IPv6, ipv6->sin6_addr.s6_addr);
106+
log_d("DNS found IPv6 first %s", aResult.toString().c_str());
107+
lwip_freeaddrinfo(res);
108+
return 1;
109+
}
110+
}
111+
// **End Workaround**
93112

113+
const struct addrinfo hints = {
114+
.ai_family = AF_UNSPEC,
115+
.ai_socktype = SOCK_STREAM,
116+
};
94117
err = lwip_getaddrinfo(aHostname, servname, &hints, &res);
118+
95119
if (err == ERR_OK)
96120
{
97121
if (res->ai_family == AF_INET6)

0 commit comments

Comments
 (0)