-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add IPv6 support for Espressif #9436
base: main
Are you sure you want to change the base?
Conversation
Otherwise, it was not possible to interact with a v6 address, as `lwip_getaddrinfo` wouldn't resolve it.
* metro esp32s2 only, because that's what I had handy * nothing is started at boot; I hung it on `start_dhcp()` which is dubious * I get a stateless address (which doesn't seem to work) and a dhcpv6 address (which does) ``` >>> wifi.radio.ipv6_addresses ('FE80::7EDF:A1FF:FE00:518C', 'FD5F:3F5C:FE50:0:7EDF:A1FF:FE00:518C') ``` * depending whether a v4 or v6 dns server is configured, DNS resolution breaks wrong ipv4_dns is first 4 bytes of the v6 dns server address: ``` >>> wifi.radio.ipv4_dns 253.95.63.92 ``` * I can connect to a v4 or v6 SSH server on the local network and read its banner >>> s.close(); s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM); s.connect(("fd5f:3f5c:fe50:0:6d9:f5ff:fe1f:ce10", 22)) *** len[0]=28 *** len=28 family=10 port=5632 >>> s.recv_into(buf) 40 >>> bytes(buf) b'SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u3\r\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
only tested recvfrom_into as can't bind() v6 addresses yet wifi workflow may be broken by this or maybe it was broken before
.. & make web workflow bind to v6 if available. Binding v6 "any" address also allows v4 connections
to accomodate multiple servers some day
* v6 on by default * dhcp can start v4 & v6 separately * self documenting property for v4 & v6 support * v4 support is always on .. for now
|
Other modules & libraries may need to be updated in order to support v6. For instance, do adafruit_requests & adafruit_ntp work properly with v6 addresses & names? Since our focus is on v6 for matter support, I did not investigate this or file issues. |
good news! this does seem to set ipv6 mdns records:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few questions. It all looks pretty good. Thanks for figuring this out!
@@ -142,6 +142,16 @@ static mp_obj_t socketpool_socketpool_getaddrinfo(size_t n_args, const mp_obj_t | |||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; | |||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); | |||
|
|||
#if CIRCUITPY_SOCKETPOOL_IPV6 | |||
return common_hal_socketpool_getaddrinfo_raise( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use this all of the time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point. will revise.
|
||
{ MP_ROM_QSTR(MP_QSTR_supports_ipv6), MP_ROM_PTR(CIRCUITPY_SOCKETPOOL_IPV6 ? MP_ROM_TRUE : MP_ROM_FALSE) }, | ||
{ MP_ROM_QSTR(MP_QSTR_supports_ipv4), MP_ROM_TRUE }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would you determine this in CPython? Should it be on Radio or SocketPool (if CPython's socket
has a way to detect it.) I'm thinking ahead to having a thread network interface that is ipv6-only (I think.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good question. I don't think there's a look-before-you-leap "is there working ipv6" check in CPython.. However, in CPython with no ipv6 global connectivity, a v6 connect() to an internet address will promptly fail:
>>> s.connect(("ipv6.google.com", 80))
OSError: [Errno 101] Network is unreachable
If the OS lacked even support compile-time for V6 sockets at all then the socket module can lack the AF_INET6 definition:
#ifdef AF_INET6
ADD_INT_MACRO(m, AF_INET6); /* IP version 6 */
#endif
and creating a socket with an unsupported family will raise an exception:
>>> socket.socket(socket.AF_UNSPEC, socket.SOCK_STREAM)
OSError: [Errno 97] Address family not supported by protocol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can drop these properties if they're not useful. I really only added them so that the documentation could show a "correct" default parameter for start_dhcp_server
, by showing the constant supports_ipv6
instead of a literal True
or False
which would be incorrect
I don't have an in-depth understanding of IPv6, so I could be off-base on this. Do we know if the It could be that the DHCP server will take care of this, but's that's dependent on the DHCP server implementation (https://media.defense.gov/2023/Jan/18/2003145994/-1/-1/1/CSI_IPv6_security_guidance_.PDF, p.2). |
I'm happy to change this to default v6 off until we understand the ramifications better. @tannewt say the word |
Found this:
This is probably the original SLAAC mechanism, and may be a permanent address embedding the hardware MAC address (could be verified with testing). |
What works:
presently you have tostart_dhcp
to get v6 addressesAddresses & ping:
I added name resolution to wifi ping (espressif only):
NTP manually:
http manually:
Todo (some may end up as subsequent PRs):
wifi.radio.start_dhcp()
but not on wifi workflow. not sure where dhcp4 is started{start,stop}_dhcp_client
to gain 2 kwarg-only arguments, defaulting to trueFuture PRs: