kopia lustrzana https://github.com/espressif/esp-idf
feat(example/protocols): Add DNS fuction to check IPv6 first if relevant
If we have an IPv6 global scope address (on any interface), then check IPv6 first, and if that fails fall back to IPv4. Global scope includes ULA (if ULA is configured, similar to private address ranges, DNS is expected). If we don't have a global IPv6, then only check IPv4.pull/13250/head
rodzic
be06a6f5ff
commit
7ffd2320a7
|
@ -18,6 +18,7 @@
|
|||
#include "freertos/event_groups.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/netdb.h"
|
||||
|
||||
static const char *TAG = "example_common";
|
||||
|
||||
|
@ -136,3 +137,46 @@ esp_err_t example_disconnect(void)
|
|||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t example_getaddrinfo(const char *nodename, const char *servname, struct addrinfo **res)
|
||||
{
|
||||
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||
// Iterate over active interfaces, and find if we have any global scope IPv6
|
||||
bool has_global_scope_ipv6 = false;
|
||||
esp_netif_t *netif = NULL;
|
||||
while ((netif = esp_netif_next_unsafe(netif)) != NULL) {
|
||||
esp_ip6_addr_t ip6[MAX_IP6_ADDRS_PER_NETIF];
|
||||
int ip6_addrs = esp_netif_get_all_ip6(netif, ip6);
|
||||
for (int j = 0; j < ip6_addrs; ++j) {
|
||||
// Both global and unique local addresses have global scope.
|
||||
// ULA assumes either private DNS or NAT66 (same assumpation as IPv4 private address ranges).
|
||||
esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&(ip6[j]));
|
||||
if (ipv6_type == ESP_IP6_ADDR_IS_GLOBAL || ipv6_type == ESP_IP6_ADDR_IS_UNIQUE_LOCAL) {
|
||||
has_global_scope_ipv6 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (has_global_scope_ipv6) break;
|
||||
}
|
||||
|
||||
if (has_global_scope_ipv6) {
|
||||
const struct addrinfo hints6 = {
|
||||
.ai_family = AF_INET6,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
};
|
||||
ESP_LOGI(TAG, "IPv6 DNS lookup");
|
||||
int err6 = getaddrinfo(nodename, servname, &hints6, res);
|
||||
if(err6 == 0) return err6;
|
||||
ESP_LOGI(TAG, "- IPv6 DNS lookup failed, trying IPv4 lookup");
|
||||
}
|
||||
#endif
|
||||
|
||||
const struct addrinfo hints4 = {
|
||||
.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
};
|
||||
ESP_LOGI(TAG, "IPv4 DNS lookup");
|
||||
int err4 = getaddrinfo(nodename, servname, &hints4, res);
|
||||
|
||||
return err4;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "esp_eth.h"
|
||||
#endif
|
||||
#endif // !CONFIG_IDF_TARGET_LINUX
|
||||
#include "lwip/netdb.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -77,6 +78,14 @@ esp_err_t example_disconnect(void);
|
|||
*/
|
||||
esp_err_t example_configure_stdin_stdout(void);
|
||||
|
||||
/**
|
||||
* @brief Resolve best destination address based on available source addresses
|
||||
*
|
||||
* If a global IPv6 address is available, this tries to get an IPv6 address,
|
||||
* otherwise it falls back to IPv4.
|
||||
*/
|
||||
esp_err_t example_getaddrinfo(const char *nodename, const char *servname, struct addrinfo **res);
|
||||
|
||||
/**
|
||||
* @brief Returns esp-netif pointer created by example_connect() described by
|
||||
* the supplied desc field
|
||||
|
|
Ładowanie…
Reference in New Issue