From 1f6a927e3385771e9686e5c14cbfafd6448b844c Mon Sep 17 00:00:00 2001 From: David Cermak Date: Mon, 13 Nov 2023 11:46:04 +0100 Subject: [PATCH] fix(lwip): Document DNS limitation in lwIP * Add a note that DNS server config is global in lwIP * Add a section about defining LWIP config macros from CMake * Mention the DNS limitation in ESP-IDF additions to lwIP * Update CN for lwIP DNS limitation Co-Authored-By: Wang Ziyan --- docs/en/api-guides/lwip.rst | 25 +++++++++++++++++++++++++ docs/zh_CN/api-guides/lwip.rst | 25 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/docs/en/api-guides/lwip.rst b/docs/en/api-guides/lwip.rst index 2464e48af9..43055ed2ba 100644 --- a/docs/en/api-guides/lwip.rst +++ b/docs/en/api-guides/lwip.rst @@ -13,6 +13,8 @@ ESP-IDF supports the following lwIP TCP/IP stack functions: - `BSD Sockets API`_ - `Netconn API`_ is enabled but not officially supported for ESP-IDF applications +.. _lwip-dns-limitation: + Adapted APIs ^^^^^^^^^^^^ @@ -23,6 +25,12 @@ Adapted APIs Some common lwIP app APIs are supported indirectly by ESP-IDF: - Dynamic Host Configuration Protocol (DHCP) Server & Client are supported indirectly via the :doc:`/api-reference/network/esp_netif` functionality. +- Domain Name System (DNS) is supported in lwIP; DNS servers could be assigned automatically when acquiring a DHCP address, or manually configured using the :doc:`/api-reference/network/esp_netif` API. + +.. note:: + + DNS server configuration in lwIP is global, not interface-specific. If you are using multiple network interfaces with distinct DNS servers, exercise caution to prevent inadvertent overwrites of one interface's DNS settings when acquiring a DHCP lease from another interface. + - Simple Network Time Protocol (SNTP) is also supported via the :doc:`/api-reference/network/esp_netif`, or directly via the :component_file:`lwip/include/apps/esp_sntp.h` functions, which also provide thread-safe API to :component_file:`lwip/lwip/src/include/lwip/apps/sntp.h` functions, see also :ref:`system-time-sntp-sync`. - ICMP Ping is supported using a variation on the lwIP ping API, see :doc:`/api-reference/protocols/icmp_echo`. - ICMPv6 Ping, supported by lwIP's ICMPv6 Echo API, is used to test IPv6 network connectivity. For more information, see :example:`protocols/sockets/icmpv6_ping`. @@ -411,6 +419,8 @@ IP Layer Features - IPV4-mapped IPV6 addresses are supported +.. _lwip-custom-hooks: + Customized lwIP Hooks +++++++++++++++++++++ @@ -422,10 +432,25 @@ The original lwIP supports implementing custom compile-time modifications via `` target_compile_options(${lwip} PRIVATE "-I${PROJECT_DIR}/main") target_compile_definitions(${lwip} PRIVATE "-DESP_IDF_LWIP_HOOK_FILENAME=\"my_hook.h\"") +Customized lwIP Options From ESP-IDF Build System +++++++++++++++++++++++++++++++++++++++++++++++++++ + +The most common lwIP options are configurable through the component configuration menu. However, certain definitions need to be injected from the command line. The CMake function ``target_compile_definitions()`` can be employed to define macros, as illustrated below: + +.. code-block:: cmake + + idf_component_get_property(lwip lwip COMPONENT_LIB) + target_compile_definitions(${lwip} PRIVATE "-DETHARP_SUPPORT_VLAN=1") + +This approach may not work for function-like macros, as there is no guarantee that the definition will be accepted by all compilers, although it is supported in GCC. To address this limitation, the ``add_definitions()`` function can be utilized to define the macro for the entire project, for example: ``add_definitions("-DFALLBACK_DNS_SERVER_ADDRESS(addr)=\"IP_ADDR4((addr), 8,8,8,8)\"")``. + +Alternatively, you can define your function-like macro in a header file which will be pre-included as an lwIP hook file, see :ref:`lwip-custom-hooks`. Limitations ^^^^^^^^^^^ +ESP-IDF additions to lwIP still suffer from the global DNS limitation, described in :ref:`lwip-dns-limitation`. To address this limitation from application code, the ``FALLBACK_DNS_SERVER_ADDRESS()`` macro can be utilized to define a global DNS fallback server accessible from all interfaces. Alternatively, you have the option to maintain per-interface DNS servers and reconfigure them whenever the default interface changes. + Calling ``send()`` or ``sendto()`` repeatedly on a UDP socket may eventually fail with ``errno`` equal to ``ENOMEM``. This failure occurs due to the limitations of buffer sizes in the lower-layer network interface drivers. If all driver transmit buffers are full, the UDP transmission will fail. For applications that transmit a high volume of UDP datagrams and aim to avoid any dropped datagrams by the sender, it is advisable to implement error code checking and employ a retransmission mechanism with a short delay. .. only:: esp32 diff --git a/docs/zh_CN/api-guides/lwip.rst b/docs/zh_CN/api-guides/lwip.rst index 3351164d65..192e3e5e8d 100644 --- a/docs/zh_CN/api-guides/lwip.rst +++ b/docs/zh_CN/api-guides/lwip.rst @@ -13,6 +13,8 @@ ESP-IDF 支持以下 lwIP TCP/IP 协议栈功能: - `BSD 套接字 API`_ - `Netconn API`_ 已启用,但暂无对 ESP-IDF 应用程序的官方支持 +.. _lwip-dns-limitation: + 适配的 API ^^^^^^^^^^^^ @@ -23,6 +25,12 @@ ESP-IDF 支持以下 lwIP TCP/IP 协议栈功能: ESP-IDF 间接支持以下常见的 lwIP 应用程序 API: - 动态主机设置协议 (DHCP) 服务器和客户端,由 :doc:`/api-reference/network/esp_netif` 功能间接支持。 +- 域名系统 (DNS);获取 DHCP 地址时,可以自动分配 DNS 服务器,也可以通过 :doc:`/api-reference/network/esp_netif` API 手动配置。 + +.. note:: + + lwIP 中的 DNS 服务器配置为全局配置,而非针对特定接口的配置。如需同时使用不同 DNS 服务器的多个网络接口,在从一个接口获取 DHCP 租约时,请注意避免意外覆盖另一个接口的 DNS 设置。 + - 简单网络时间协议 (SNTP),由 :doc:`/api-reference/network/esp_netif` 功能间接支持,或通过 :component_file:`lwip/include/apps/esp_sntp.h` 中的函数直接支持。该函数还为 :component_file:`lwip/lwip/src/include/lwip/apps/sntp.h` 函数提供了线程安全的 API,请参阅 :ref:`system-time-sntp-sync`。 - ICMP Ping,由 lwIP ping API 的变体支持,请参阅 :doc:`/api-reference/protocols/icmp_echo`。 - ICMPv6 Ping,由 lwIP 的 ICMPv6 Echo API 支持,用于测试 IPv6 网络连接情况。有关详细信息,请参阅 :example:`protocols/sockets/icmpv6_ping`。 @@ -411,6 +419,8 @@ IP 层特性 - 支持 IPV4 映射 IPV6 地址 +.. _lwip-custom-hooks: + 自定义 lwIP 钩子 +++++++++++++++++++++ @@ -422,10 +432,25 @@ IP 层特性 target_compile_options(${lwip} PRIVATE "-I${PROJECT_DIR}/main") target_compile_definitions(${lwip} PRIVATE "-DESP_IDF_LWIP_HOOK_FILENAME=\"my_hook.h\"") +使用 ESP-IDF 构建系统自定义 lwIP 选项 +++++++++++++++++++++++++++++++++++++++++++++++++++ + +组件配置菜单可以配置常见的 lwIP 选项,但是一些自定义选项需要通过命令行添加。CMake 函数 ``target_compile_definitions()`` 可以用于定义宏,示例如下: + +.. code-block:: cmake + + idf_component_get_property(lwip lwip COMPONENT_LIB) + target_compile_definitions(${lwip} PRIVATE "-DETHARP_SUPPORT_VLAN=1") + +使用这种方法可能无法定义函数式宏。虽然 GCC 支持此类定义,但是未必所有编译器都会接受。为了解决这一限制,可以使用 ``add_definitions()`` 函数为整个项目定义宏,例如 ``add_definitions("-DFALLBACK_DNS_SERVER_ADDRESS(addr)=\"IP_ADDR4((addr), 8,8,8,8)\"")``。 + +另一种方法是在头文件中定义函数式宏,该头文件将预先包含在 lwIP 钩子文件中,请参考 :ref:`lwip-custom-hooks`。 限制 ^^^^^^^^^^^ +如 :ref:`lwip-dns-limitation` 所述,ESP-IDF 中的 lwIP 扩展功能仍然受到全局 DNS 限制的影响。为了在应用程序代码中解决这一限制,可以使用 ``FALLBACK_DNS_SERVER_ADDRESS()`` 宏定义所有接口能够访问的全局 DNS 备用服务器,或者单独维护每个接口的 DNS 服务器,并在默认接口更改时重新配置。 + 在 UDP 套接字上重复调用 ``send()`` 或 ``sendto()`` 最终可能会导致错误。此时 ``errno`` 报错为 ``ENOMEM``,错误原因是底层网络接口驱动程序中的 buffer 大小有限。当所有驱动程序的传输 buffer 已满时,UDP 传输事务失败。如果应用程序需要发送大量 UDP 数据报,且不希望发送方丢弃数据报,建议检查错误代码,采用短延迟的重传机制。 .. only:: esp32