espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.33k stars 7.2k forks source link

Basic network examples should support all networks by default (IPv6-only, dual-stack, and IPv4-only) (IDFGH-12195) #13249

Open sgryphon opened 6 months ago

sgryphon commented 6 months ago

Answers checklist.

General issue report

The basic network examples are configured to only support IPv4 by default. Multiple steps are required to fully support IPv6, such as IPv6-only networks, which include having to turn off IPv4.

Such complex re-configuration for the specific network type should not be required for a basic example.

The examples should by default support all network configurations simultaneously, without needing reconfiguration, i.e. similar how a phone or laptop works, with all network types enabled and available, but optional.

If IPv6 is available then an IPv6 address should be acquired, and if IPv4 is available then an IPv4 address should be acquired,without either of them becoming mandatory. The appropriate network should then be used to simultaneously be able to connect to IPv6, IPv4, and dual stack destinations, if possible. (Some combinations are not possible, e.g. an IPv4 only network can't reach an IPv6 only destination, see the table below)

Supporting IPv6 does not mean making it mandatory, only available to used if needed.

Destination address selection, e.g. in DNS resolution, should be based on the source addresses available. (e.g. following RFC 6724)

Expected behaviour by network type and destination server (with default configuration):

Network / Destination IPv6 server Dual-stack IPv4 only
IPv6 with DNS64 IPv6 IPv6 NAT64
IPv6 only IPv6 IPv6 unreachable
Dual stack with DNS64 IPv6 IPv6 NAT64
Dual stack (1) IPv6 IPv6 IPv4 (3)
IPv4 only (2) unreachable IPv4 (3) IPv4 (3)

IPv6 (and IPv4) refer to (generally) public addresses (including IPv6 ULA)

(1) Typical configurations are dual stack without DNS64/NAT64 (2) In an IPv4 only network, an endpoint will still have a link-local IPv6 address (3) For many networks IPv4 connectivity will be via NAT44.

Endpoints will usually have a single IPv4 address, and multiple IPv6 addresses with both link-local and one (or more) public IPv6 addresses. The public IPv6 address of a destination is only used if the source has a public IPv6 address available.

Consequences

Lack of a simple example, that works like normal devices, i.e. supports IPv6 if available but does not make it mandatory, creates a barrier to then building upon examples to create real-world applications with IPv6 support.

e.g. Having a basic example that works out of the box with all networking configurations would help avoid issues like #12275 and #13173 where people cannot get alternative configurations working.

Additional details -- Connection - HTTP request example

Specific issues where the existing example fails:

Because turning on an option (IPv4 or IPv6) also makes that option mandatory, there is no generic configuration that can be used across all network types.

It should be possible to turn options on but have them all optional, and they should be on by default, so that one example (with default config) works with all network types. i.e. both IPv4 and IPv6 should be on, but optional.

sgryphon commented 6 months ago

The http_request example has been updated to supported all network types by checking the currently available addresses and then looking up both IPv6 and IPv4 as needed.

However HTTP is not secure, and so real world applications will usually want to use HTTPS.

The same solution can not be used for the https_request example, as thehost name needs to be passed into the TLS handling code. It can't pass in an IP address, as the name is needed to validate the certificate.

Resolution of the name to address is then handled inside the TLS components, and does not take into account available address so does not work for all network types.

Additional issue has been raised for this library (not example) problem, https://github.com/espressif/esp-idf/issues/13255

sgryphon commented 6 months ago

A fix for the basic HTTP example has been provided in pull request: https://github.com/espressif/esp-idf/pull/13250

This fix only changes example code (no library change), so is limited in scope. The example also configures the default settings to support all 5 network types and all 3 destination server types, i.e. all 13 of the reachable examples work with the default example configuration.