espressif / esp-lwip

Fork of lwIP (https://savannah.nongnu.org/projects/lwip/) with ESP-IDF specific patches
Other
85 stars 129 forks source link

Problem with PPPoS and DNS (IDFGH-3733) #1

Closed mapedraza closed 4 years ago

mapedraza commented 6 years ago

I just tested Loboris PPPoS example and it works fine: https://github.com/loboris/ESP32-PPPOS-EXAMPLE

But, trying to make a cleaner version of PPPoS test, i use the esp-idf example of PPPoS client: https://github.com/espressif/esp-idf/tree/master/examples/protocols/pppos_client

No problems, the module configure the modem and finally i get an IP. The problem come when i try to get some data from internet. I just adapt the http_get_task used in http-request ESP-IDF example

static void http_get_task(void *pvParameters)
{
    const struct addrinfo hints = {
        .ai_family = AF_INET,
        .ai_socktype = SOCK_STREAM,
    };
    struct addrinfo *res;
    struct in_addr *addr;
    int s, r;
    char recv_buf[64];

    while(1) {
        int err = getaddrinfo(WEB_SERVER, "80", &hints, &res);

        if(err != 0 || res == NULL) {
            ESP_LOGE(TAG, "DNS lookup failed err=%d res=%p", err, res);
            vTaskDelay(1000 / portTICK_PERIOD_MS);
            continue;
        }

        /* Code to print the resolved IP.
           Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */
        addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
        ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", inet_ntoa(*addr));

        s = socket(res->ai_family, res->ai_socktype, 0);
        if(s < 0) {
            ESP_LOGE(TAG, "... Failed to allocate socket.");
            freeaddrinfo(res);
            vTaskDelay(1000 / portTICK_PERIOD_MS);
            continue;
        }
        ESP_LOGI(TAG, "... allocated socket");

        if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
            ESP_LOGE(TAG, "... socket connect failed errno=%d", errno);
            close(s);
            freeaddrinfo(res);
            vTaskDelay(4000 / portTICK_PERIOD_MS);
            continue;
        }

        ESP_LOGI(TAG, "... connected");
        freeaddrinfo(res);

        if (write(s, REQUEST, strlen(REQUEST)) < 0) {
            ESP_LOGE(TAG, "... socket send failed");
            close(s);
            vTaskDelay(4000 / portTICK_PERIOD_MS);
            continue;
        }
        ESP_LOGI(TAG, "... socket send success");

        struct timeval receiving_timeout;
        receiving_timeout.tv_sec = 5;
        receiving_timeout.tv_usec = 0;
        if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &receiving_timeout,
                sizeof(receiving_timeout)) < 0) {
            ESP_LOGE(TAG, "... failed to set socket receiving timeout");
            close(s);
            vTaskDelay(4000 / portTICK_PERIOD_MS);
            continue;
        }
        ESP_LOGI(TAG, "... set socket receiving timeout success");

        /* Read HTTP response */
        do {
            bzero(recv_buf, sizeof(recv_buf));
            r = read(s, recv_buf, sizeof(recv_buf)-1);
            for(int i = 0; i < r; i++) {
                putchar(recv_buf[i]);
            }
        } while(r > 0);

        ESP_LOGI(TAG, "... done reading from socket. Last read return=%d errno=%d\r\n", r, errno);
        close(s);
        for(int countdown = 10; countdown >= 0; countdown--) {
            ESP_LOGI(TAG, "%d... ", countdown);
            vTaskDelay(1000 / portTICK_PERIOD_MS);
        }
        ESP_LOGI(TAG, "Starting again!");
    }
}

When compile and run I obtain the same issue E (55346) example: DNS lookup failed err=202 res=0x0 That means the getaddrinfo function doesn't work properly as a result of error code (202, EAI_FAIL)

I also tried to put the IP address of webserver and it works, so, the system has network from PPPoS (no Wifi or another interface enabled) and if possible to open a socked and send information (HTTP request) through it.

If I try to port the loboris example, i get the same issue, so i think it is something related with esp-idf v3 lwip stack (the major differences between codes)

mapedraza commented 6 years ago

Solved adding DNS Server configurations

ip_addr_t dnsserver;
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP");
inet_pton(AF_INET, "8.8.8.8", &dnsserver);
dns_setserver(0, &dnsserver);
inet_pton(AF_INET, "8.8.4.4", &dnsserver);
dns_setserver(1, &dnsserver);
mapedraza commented 6 years ago

Reopened again

If compiled without debug output, system cannot resolve DNS name (adding CONFIG_PPP_DEBUG_ON=n to sdkconfig file)

JcBernack commented 5 years ago

I just had the same problem you originally had. You can either solve it by setting DNS servers manually like you did, or you retrieve them via PPP from your peer by calling ppp_set_usepeerdns(ppp, 1); before pppapi_connect(ppp, 0), i.e. above this line: https://github.com/espressif/esp-idf/blob/master/examples/protocols/pppos_client/main/pppos_client_main.c#L276

JcBernack commented 5 years ago

About your other problem: I have no idea, I had PPP debugging off the whole time without issues. I just turned it on to see what happens and everything seems to work.

erfengwelink commented 5 years ago

@mapedraza

Hi, I just had the same problem you originally had.

I'm using the same code in different place. one issue happened just like following link:

details please see at: espressif/esp-aliyun#81

another one works well without DNS fail issue.

is there some bugs in lwip lib?

ans-hafeez-tekfocal commented 4 years ago

Solved adding DNS Server configurations

ip_addr_t dnsserver;
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP");
inet_pton(AF_INET, "8.8.8.8", &dnsserver);
dns_setserver(0, &dnsserver);
inet_pton(AF_INET, "8.8.4.4", &dnsserver);
dns_setserver(1, &dnsserver);

Thanks. Saved my a lot of time

david-cermak commented 4 years ago

Thanks for the update. To my best knowledge there's no longer any DNS issue in IDF PPPoS client as we set ppp_set_usepeerdns() before starting the ppp netif in lwip, so closing this for now. Feel free to reopen or raise a new one, preferably in IDF repo. Thanks