adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.12k stars 1.22k forks source link

socketpool getaddrinfo does not output the same as Python, Where is my List of multiple addresses. #9711

Open meeki007 opened 1 month ago

meeki007 commented 1 month ago

CircuitPython version

Adafruit CircuitPython 9.1.3 on 2024-08-30; Seeed Xiao ESP32-C6 4MB Flash 512KB SRAM with ESP32-C6FH4

Code/REPL

socketpool = socketpool.SocketPool(wifi.radio)
addressInfoTupple = socketpool.getaddrinfo("cats.com", 80)
for individual_addressInfo in addressInfoTupple:
        print(f"individual_addressInfo: {individual_addressInfo}")

Behavior

individual_addressInfo: (2, 1, 0, '', ('172.67.39.47', 80))

Description

I can see the host has multiple A records and addresses for the site.

$ host cats.com
cats.com has address 172.67.39.47
cats.com has address 104.22.47.85
cats.com has address 104.22.46.85
.....

In python I get a List of all the ip addresses, A records, from the host.

individual_addressInfo: (2, 1, 0, '', ('172.67.39.47', 80))
individual_addressInfo: (2, 1, 0, '', ('104.22.47.85', 80))
individual_addressInfo: (2, 1, 0, '', ('104.22.46.85', 80))

Additional information

See documentation ---> https://docs.circuitpython.org/en/latest/shared-bindings/socketpool/#socketpool.SocketPool.getaddrinfo It says I should be getting a List of Tuples.

Why is this important .... to me.

I am migrating my code from micropython to circuitpython and I noticed that my MQTT messages were not going through from the test device. I then found out one of my servers in my High Availability MQTT cluster was down. I was expecting it to just round robin my List of Tuples from getaddrinfo. Whats the point of outputting a List of Tuples if the list only ever contains 1 value ???

jepler commented 1 month ago

This is a limitation of lwip, the socket library that is used by Espressif devices (and RP2040 wifi devices, when it comes to that). Their source code .../lwip/src/api/netdb.c states:

 * Due to a limitation in dns_gethostbyname, only the first address of a
 * host is returned.
 * Also, service names are not supported (only port numbers)!

CircuitPython's implementation of getaddrinfo is prepared to return multiple addresses when you call socket.getaddrinfo but the underlying library doesn't provide multiple addresses yet.

meeki007 commented 1 month ago

CircuitPython's implementation of getaddrinfo is prepared to return multiple addresses when you call socket.getaddrinfo but the underlying library doesn't provide multiple addresses yet.

Good to know! I'll keep my for loop that tires connecting the mqtt client to each address so when this is implemented its waiting to work.