micropython icon indicating copy to clipboard operation
micropython copied to clipboard

RPI PICO W Regression: Setting DNS results in address resolution failure

Open vshymanskyy opened this issue 1 year ago • 10 comments

Port, board and/or hardware

RPI PICO W

MicroPython version

MicroPython v1.24.0-preview.224.g6c3dc0c0b on 2024-08-22; Raspberry Pi Pico W with RP2040

Reproduction

import socket
import network
import asyncio

async def test():
    print("Connecting to WiFi...")
    sta_if = network.WLAN(network.STA_IF)
    sta_if.active(True)
    sta_if.connect("---", "---")
    while not sta_if.isconnected():
        await asyncio.sleep_ms(100)

    print("Setting DNS...")
    cfg = list(sta_if.ifconfig())
    cfg[-1] = "8.8.8.8"
    sta_if.ifconfig(cfg)

    server, port = "blynk.cloud", 443

    print("Resolving IP...")
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    addr = socket.getaddrinfo(server, port)[0][-1]

    print("Connecting...")
    sock.connect(addr)

    print("OK")

asyncio.run(test())

Expected behaviour

MicroPython v1.23.0 on 2024-06-02; Raspberry Pi Pico W with RP2040:
MPY: soft reboot
Connecting to WiFi...
Setting DNS...
Resolving IP...
Connecting...
OK

Observed behaviour

MicroPython v1.24.0-preview.224.g6c3dc0c0b on 2024-08-22; Raspberry Pi Pico W with RP2040:
MPY: soft reboot
Connecting to WiFi...
Setting DNS...
Resolving IP...
Traceback (most recent call last):
  File "main.py", line 22, in test       # socket.getaddrinfo
OSError: -2

Additional Information

No response

Code of Conduct

Yes, I agree

vshymanskyy avatar Aug 23 '24 00:08 vshymanskyy

I cannot reproduce the problem using the supplied code, and the referenced commit version. It works fine, does a DNS lookup and connects to the remote host.

But I do notice that the DNS lookup takes longer than expected. With 8.8.8.8 it takes around 6-9 seconds. With the default DNS it takes about 1-2 seconds, sometimes less.

So maybe in your case it's just timing out because it's taking to long?

Note that Pico W now supports IPv6, but DNS lookups still prefer IPv4 by default. You can check this with network.ipconfig('prefer'), and also see if you have an IPv6 address with sta_if.ipconfig('addr6').

dpgeorge avatar Aug 23 '24 02:08 dpgeorge

I see. Is there any way to change the DNS timeout, so I can confirm? Interestingly, I don't observe the long DNS lookup on 1.23.0, it's as fast as usual.

addr6: [('FE80::2ACD:C1FF:FE0F:1EAA', 48, 0, 0), ('FD73:C90F:6670:0:2ACD:C1FF:FE0F:1EAA', 48, -1, -1)]
prefer: 4

vshymanskyy avatar Aug 23 '24 14:08 vshymanskyy

+1, just experienced the -2 error on getaddrinfo when compiling the firmware from master. I also used 8.8.8.8, and it also works fine for me on 1.23.0.

TPReal avatar Oct 01 '24 10:10 TPReal

FWIW, the doc says that ifconfig() is deprecated and to use ipconfig(), but ipconfig('dns') does not work on Pico-W.

n1kdo avatar Oct 01 '24 16:10 n1kdo

As for ifconfig, it is marked as deprecated in AbstractNIC, but in implementations, e.g. WLAN, it is not, and the ipconfig isn't even documented there (even though other methods are repeated), which makes the whole deprecation information very easy to miss.

TPReal avatar Oct 01 '24 19:10 TPReal

but ipconfig('dns') does not work on Pico-W.

@n1kdo ipconfig.('dns') is available as method of the network class: network.ipconfig(). That's in addition to the ipconfig method of the NIC, like WLAN.ipconfig() and somwhat confusing.

robert-hh avatar Oct 10 '24 08:10 robert-hh

Looks like I cannot reproduce the issue by setting DNS server via:

network.ipconfig(dns='8.8.8.8')

Also, I'm now developing a asyncio-based DNS client to mitigate the blocking nature of socket.getaddrinfo. Looks working so far on ESP32, Pi Pico W and WM W600. It should also provide a solution for https://github.com/micropython/micropython/issues/15777

vshymanskyy avatar Oct 11 '24 16:10 vshymanskyy

aiodns has been published: https://github.com/vshymanskyy/aiodns

vshymanskyy avatar Oct 16 '24 21:10 vshymanskyy

aiodns has been published

That looks good! We do need a proper solution for DNS lookup in asyncio, it should not be blocking.

dpgeorge avatar Oct 17 '24 00:10 dpgeorge

@dpgeorge glad you liked it. Maybe you can comment on this please? https://github.com/vshymanskyy/aiodns/issues/3

vshymanskyy avatar Oct 17 '24 10:10 vshymanskyy

Got it ! :) it's dev issue, i made same error: do not use ifconfig but ipconfig to handle network conf.

replace your line : sta_if.ifconfig(cfg)

by something like:
sta_if.ipconfig(addr4=(cfg[0],cfg[1])) sta_if.ipconfig(gw4=cfg[2]) network.ipconfig(dns='8.8.8.8')

-> wlan.ipconfig do not handle dns but network.ipconfig do it.

Nethrandir avatar Oct 24 '25 06:10 Nethrandir