Why does getaddrinfo return only one result?

sgmustadio
Posts: 5
Joined: Thu Mar 04, 2021 4:33 am

Why does getaddrinfo return only one result?

Postby sgmustadio » 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:

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;
}
I call it with e.g.

Code: Select all

struct addrinfo ip_addr;
dns_lookup("example.com", "80", AF_UNSPEC, &ip_addr);
The LOG shows only 1 IP address returned from the lookup:

Code: Select all

I (3856) http_request: DNS lookup succeeded. IP addresses:
I (3856) http_request:   IPv4: 23.192.228.80
nslookup on Linux, however, gives me the following:

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
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.

Who is online

Users browsing this forum: No registered users and 69 guests