Why does getaddrinfo return only one result?
Posted: Thu Jan 23, 2025 9:24 pm
I'm working on an IoT example using ESP-IDF, and I'm having trouble understanding why getaddrinfo() only returns a single result. Here is my DNS lookup function:
I call it with e.g.
The LOG shows only 1 IP address returned from the lookup:
nslookup on Linux, however, gives me the following:
My understanding is that getaddrinfo() should return all available DNS results. Is the ESP-IDF implementation of this function limiting the results to just one in some way? From what I can see in the source code: https://github.com/espressif/esp-idf/bl ... etdb.c#L10, it should be creating the full linked list of addresses.
Code: Select all
// Perform DNS lookup
esp_err_t dns_lookup(const char *host,
const char *port,
const int family,
struct addrinfo *ip_addr)
{
struct addrinfo *res;
char ip_str[INET6_ADDRSTRLEN] = {0};
int err;
// Check for supported address families
if ((family != AF_INET) && (family != AF_INET6) && (family != AF_UNSPEC)) {
ESP_LOGE(TAG, "Unsupported address family");
return ESP_ERR_INVALID_ARG;
}
// Set hints for DNS lookup
struct addrinfo hints = {
.ai_family = family,
.ai_socktype = SOCK_STREAM
};
// Perform DNS lookup
err = getaddrinfo(host, port, &hints, &res);
if (err != 0 || res == NULL) {
ESP_LOGE(TAG, "DNS lookup failed (%d) res: %p", err, res);
return ESP_FAIL;
}
// Print resolved IP addresses (linked list)
ESP_LOGI(TAG, "DNS lookup succeeded. IP addresses:");
for (struct addrinfo *addr = res; addr != NULL; addr = addr->ai_next) {
if (addr->ai_family == AF_INET) {
struct in_addr *ip = &((struct sockaddr_in *)addr->ai_addr)->sin_addr;
inet_ntop(AF_INET, ip, ip_str, INET_ADDRSTRLEN);
ESP_LOGI(TAG, " IPv4: %s", ip_str);
}
else if (addr->ai_family == AF_INET6) {
struct in6_addr *ip = &((struct sockaddr_in6 *)addr->ai_addr)->sin6_addr;
inet_ntop(AF_INET6, ip, ip_str, INET6_ADDRSTRLEN);
ESP_LOGI(TAG, " IPv6: %s", ip_str);
}
}
// Copy first resolved IP address to output struct
if (ip_addr && res) {
memcpy(ip_addr, res, sizeof(struct addrinfo));
}
// Free address info
freeaddrinfo(res);
return ESP_OK;
}
Code: Select all
struct addrinfo ip_addr;
dns_lookup("example.com", "80", AF_UNSPEC, &ip_addr);
Code: Select all
I (3856) http_request: DNS lookup succeeded. IP addresses:
I (3856) http_request: IPv4: 23.192.228.80
Code: Select all
nslookup example.com
Server: 10.255.255.254
Address: 10.255.255.254#53
Non-authoritative answer:
Name: example.com
Address: 23.192.228.84
Name: example.com
Address: 23.215.0.136
Name: example.com
Address: 23.215.0.138
Name: example.com
Address: 96.7.128.175
Name: example.com
Address: 96.7.128.198
Name: example.com
Address: 23.192.228.80
Name: example.com
Address: 2600:1406:3a00:21::173e:2e65
Name: example.com
Address: 2600:1406:3a00:21::173e:2e66
Name: example.com
Address: 2600:1406:bc00:53::b81e:94c8
Name: example.com
Address: 2600:1406:bc00:53::b81e:94ce
Name: example.com
Address: 2600:1408:ec00:36::1736:7f24
Name: example.com
Address: 2600:1408:ec00:36::1736:7f31