arduino / ArduinoCore-API

Hardware independent layer of the Arduino cores defining the official API
https://www.arduino.cc/reference/en/
GNU Lesser General Public License v2.1
216 stars 120 forks source link

IPv6 support needed #168

Closed sgryphon closed 2 years ago

sgryphon commented 2 years ago

Is there any roadmap for IPv6 support? Even just adding definitions into the Core API, even if they return "no implemented" by platforms?

According to Google, IPv6 is now getting over 40% https://www.google.com/intl/en/ipv6/statistics.html

In a few years, IPv4 will be in the minority.

Some network providers have already switched to IPv6-only, e.g. Telstra mobile users in Australia, as well as many providers in India, China, and other regions. https://www.sidn.nl/en/news-and-blogs/australias-telstra-switches-mobile-users-to-ipv6-only

Without a core API definition, different libraries are adding their own versions of IPv6 addresses, e.g.:

This results in a mix of standard API IPAddress and Client, along with custom IPv6 addresses, e.g.:

sgryphon commented 2 years ago

This should be designed so that IPv6 (which will be the majority in a few years) is on by default.

An approach similar to Wiznet seems best, changing the existing IPAddress.h class to represent both IPv4 and IPv6 addresses, so something like a DNS fetch can have a return type of IPAddress (or array of IPAddress).

This could be some kind of union type, or have separate IPv4Address and IPv6Address inherit from IPAddress, or simply structure a single IPAddress class that it supports both. (Simply having IPv6 inherit from is probably not the best future solution).

One drawback of any of the union approaches in increased memory, i.e. allocating 16 bytes per address (to handle both IPv4 and IPv6), but I still think the default should be IPv6. For libraries that want to continue and use an IPv4-only structure (less memory) that option could be added, with easy conversion to/from (but don't make it the default).

Note that any particular IPv4/IPv6 addresses may not be supported by particular underlying networks.

Currently it might be IPv6 that is not supported, but there are increasing numbers of networks where it is the reverse, where IPv4 is not supported. i.e. A stored configuration might be invalid for the current network, so applications need to handle "not supported" scenarios (for both directions).

mcspr commented 2 years ago

Since you mentioned various implementations, I would also note of non-ArduinoCore-API IPAddress for ESP32 & ESP8266 that wraps around the underlying lwip ip_addr_t that is a union type https://www.nongnu.org/lwip/2_0_x/group__ipaddr.html#ga16ef96d6cde029029bbf47fee35fd67a https://github.com/lwip-tcpip/lwip/blob/239918ccc173cb2c2a62f41a40fd893f57faf1d6/src/include/lwip/ip_addr.h#L63-L76

sgryphon commented 2 years ago

I'm actually glad to see the ESP8266 implementation, which, from what I can see, does it a nice way.

It extends IPAddress to support both v4 & v6, i.e. adding new features, whilst remaining backwards compatible (so in semantic versioning terms, a minor version change). It even has a compile flag so that the memory footprint (an internal implementation detail) is identical when IPv6 is disabled.

In comparison the Arduino-ESP32 library has added a separate IPv6Address class, which is used in the branch adding wider IPv6 support. The divergence has already started, even between the two Epressif chips. Example code on one will become more difficult to port to the other.

sgryphon commented 2 years ago

I did a bit of coding on the weekend and added a pull request for an implementation.

Similar to the ESP8266 approach, it simply adds IPv6 support to the existing class, with backwards compatibility.

The public interface changes are minimal:

All the existing tests pass with no changes.

Tests added for IPv6 support.

It does increases the footprint of the class from 4 bytes to 20 bytes.

aentinger commented 2 years ago

Closing, since implemented via #169 .