From 8af82e8a224dde3527515a5f0121745235b5b783 Mon Sep 17 00:00:00 2001 From: WanqQixiang Date: Thu, 5 Dec 2024 16:10:44 +0800 Subject: [PATCH] fix(openthread): Fix external DNS resolve hook for DNS64 client --- .../openthread/include/esp_openthread_dns64.h | 56 ++++++++++++++-- .../openthread/src/esp_openthread_dns64.c | 67 +++++++++++++------ .../src/port/esp_openthread_state.c | 28 +++++--- 3 files changed, 114 insertions(+), 37 deletions(-) diff --git a/components/openthread/include/esp_openthread_dns64.h b/components/openthread/include/esp_openthread_dns64.h index 22809b8560..9b65cdcd6e 100644 --- a/components/openthread/include/esp_openthread_dns64.h +++ b/components/openthread/include/esp_openthread_dns64.h @@ -1,20 +1,18 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once +#include "esp_netif_types.h" #include "esp_openthread.h" #include "lwip/netdb.h" #ifdef __cplusplus extern "C" { #endif -// The network data change callback sets the dns server address of index 0, while the CLI sets the dns server address of index 1. -#define OPENTHREAD_DNS_SERVER_INDEX 0 - /** * @brief This function initiizes the dns64 client. * @@ -26,17 +24,61 @@ extern "C" { esp_err_t esp_openthread_dns64_client_init(void); /** - * @brief This function acquires the DNS server address. + * @brief This function acquires the main DNS server address for OpenThread netif. * * @param[out] dnsserver_addr The dns server address. * * @return * - ESP_OK on sussess - * - ESP_ERR_INVALID_ARG if dnsserver_addr is NULL - * - ESP_ERR_INVALID_STATE if dns sever address not available + * - ESP_ERR_INVALID_ARG if dnsserver_addr is NULL or obtained DNS server address is invalid + * - ESP_ERR_ESP_NETIF_IF_NOT_READY if openthread network interface is not initialized + * - ESP_ERR_ESP_NETIF_INVALID_PARAMS if failed to call esp_netif APIs getting dns info */ esp_err_t esp_openthread_get_dnsserver_addr(ip6_addr_t *dnsserver_addr); +/** + * @brief This function acquires the DNS server address for OpenThread netif. + * + * @param[out] dnsserver_addr The dns server address. + * @param[in] dns_type The type of DNS server + * + * @return + * - ESP_OK on sussess + * - ESP_ERR_INVALID_ARG if dnsserver_addr is NULL or obtained DNS server address is invalid + * - ESP_ERR_ESP_NETIF_IF_NOT_READY if openthread network interface is not initialized + * - ESP_ERR_ESP_NETIF_INVALID_PARAMS if failed to call esp_netif APIs getting dns info + */ +esp_err_t esp_openthread_get_dnsserver_addr_with_type(ip6_addr_t *dnsserver_addr, + esp_netif_dns_type_t dns_type); + +/** + * @brief This function configures the main DNS server address for OpenThread netif. + * + * @param[in] dnsserver_addr The dns server address. + * + * @return + * - ESP_OK on sussess + * - ESP_ERR_INVALID_ARG if dnsserver_addr is invalid + * - ESP_ERR_ESP_NETIF_IF_NOT_READY if openthread network interface is not initialized + * - ESP_ERR_ESP_NETIF_INVALID_PARAMS if failed to call esp_netif APIs setting dns info + */ +esp_err_t esp_openthread_set_dnsserver_addr(const ip6_addr_t dnsserver_addr); + +/** + * @brief This function configures the DNS server address for OpenThread netif. + * + * @param[in] dnsserver_addr The dns server address. + * @param[in] dns_type The type of DNS server + * + * @return + * - ESP_OK on sussess + * - ESP_ERR_INVALID_ARG if dnsserver_addr is invalid + * - ESP_ERR_ESP_NETIF_IF_NOT_READY if openthread network interface is not initialized + * - ESP_ERR_ESP_NETIF_INVALID_PARAMS if failed to call esp_netif APIs setting dns info + */ +esp_err_t esp_openthread_set_dnsserver_addr_with_type(const ip6_addr_t dnsserver_addr, + esp_netif_dns_type_t dns_type); + /** * @brief This function acquires the NAT64 prefix in the Thread network. * diff --git a/components/openthread/src/esp_openthread_dns64.c b/components/openthread/src/esp_openthread_dns64.c index 332e20f049..442ec4308f 100644 --- a/components/openthread/src/esp_openthread_dns64.c +++ b/components/openthread/src/esp_openthread_dns64.c @@ -5,14 +5,16 @@ */ #include "esp_openthread_dns64.h" +#include "esp_netif.h" +#include "esp_netif_types.h" #include "esp_openthread_lock.h" -#include "esp_openthread_state.h" +#include "esp_openthread_netif_glue.h" #include "esp_check.h" -#include "esp_event.h" #include "esp_log.h" +#include "lwip/ip6_addr.h" +#include "lwip/ip_addr.h" #include "lwip_default_hooks.h" -#include "lwip/api.h" #include "lwip/def.h" #include "lwip/dns.h" #include "lwip/opt.h" @@ -21,7 +23,6 @@ #define TAG "OT_DNS64" - typedef struct dns_resolve_entry { char name[DNS_MAX_NAME_LENGTH]; dns_found_callback found; @@ -33,21 +34,50 @@ static dns_resolve_entry_t s_dns_resolve_entry[DNS_TABLE_SIZE]; esp_err_t esp_openthread_dns64_client_init(void) { - dns_setserver(OPENTHREAD_DNS_SERVER_INDEX, NULL); memset(s_dns_resolve_entry, 0, sizeof(s_dns_resolve_entry)); return ESP_OK; } +esp_err_t esp_openthread_get_dnsserver_addr_with_type(ip6_addr_t *dnsserver_addr, + esp_netif_dns_type_t dns_type) +{ + ESP_RETURN_ON_FALSE(dns_type < ESP_NETIF_DNS_MAX, ESP_ERR_INVALID_ARG, TAG, "Invalid DNS type"); + ESP_RETURN_ON_FALSE(dnsserver_addr, ESP_ERR_INVALID_ARG, TAG, "dnsserver_addr cannot be NULL"); + esp_netif_t *openthread_netif = esp_openthread_get_netif(); + ESP_RETURN_ON_FALSE(openthread_netif, ESP_ERR_ESP_NETIF_IF_NOT_READY, TAG, "openthread netif is not initializd"); + esp_netif_dns_info_t dns; + ESP_RETURN_ON_ERROR(esp_netif_get_dns_info(openthread_netif, dns_type, &dns), TAG, "Failed to get dns info"); + if (dns.ip.type == ESP_IPADDR_TYPE_V6) { + memcpy(dnsserver_addr->addr, dns.ip.u_addr.ip6.addr, sizeof(dnsserver_addr->addr)); + dnsserver_addr->zone = dns.ip.u_addr.ip6.zone; + } + return ESP_OK; +} + esp_err_t esp_openthread_get_dnsserver_addr(ip6_addr_t *dnsserver_addr) { - const ip_addr_t *dnsserver = dns_getserver(OPENTHREAD_DNS_SERVER_INDEX); - ESP_RETURN_ON_FALSE(dnsserver_addr, ESP_ERR_INVALID_ARG, TAG, "dnsserver_addr cannot be NULL"); - ESP_RETURN_ON_FALSE(!ip_addr_isany(dnsserver), ESP_ERR_INVALID_STATE, TAG, - "DNS server address is not set"); - memcpy(dnsserver_addr, &dnsserver->u_addr.ip6, sizeof(ip6_addr_t)); + return esp_openthread_get_dnsserver_addr_with_type(dnsserver_addr, ESP_NETIF_DNS_MAIN); +} + +esp_err_t esp_openthread_set_dnsserver_addr_with_type(const ip6_addr_t dnsserver_addr, esp_netif_dns_type_t dns_type) +{ + ESP_RETURN_ON_FALSE(dns_type < ESP_NETIF_DNS_MAX, ESP_ERR_INVALID_ARG, TAG, "Invalid DNS type"); + ESP_RETURN_ON_FALSE(!ip6_addr_isany(&dnsserver_addr), ESP_ERR_INVALID_ARG, TAG, "dnsserver_addr cannot be any"); + esp_netif_t *openthread_netif = esp_openthread_get_netif(); + ESP_RETURN_ON_FALSE(openthread_netif, ESP_ERR_ESP_NETIF_IF_NOT_READY, TAG, "openthread netif is not initializd"); + esp_netif_dns_info_t dns; + dns.ip.type = ESP_IPADDR_TYPE_V6; + dns.ip.u_addr.ip6.zone = dnsserver_addr.zone; + memcpy(dns.ip.u_addr.ip6.addr, dnsserver_addr.addr, sizeof(dns.ip.u_addr.ip6.addr)); + ESP_RETURN_ON_ERROR(esp_netif_set_dns_info(openthread_netif, dns_type, &dns), TAG, "Failed to get dns info"); return ESP_OK; } +esp_err_t esp_openthread_set_dnsserver_addr(const ip6_addr_t dnsserver_addr) +{ + return esp_openthread_set_dnsserver_addr_with_type(dnsserver_addr, ESP_NETIF_DNS_MAIN); +} + esp_err_t esp_openthread_get_nat64_prefix(ip6_addr_t *nat64_prefix) { otNetworkDataIterator iter = OT_NETWORK_DATA_ITERATOR_INIT; @@ -105,16 +135,10 @@ static dns_resolve_entry_t *find_free_dns_resolve_entry(void) int lwip_hook_dns_external_resolve(const char *name, ip_addr_t *addr, dns_found_callback found, void *callback_arg, u8_t addrtype, err_t *err) { - if (addrtype == LWIP_DNS_ADDRTYPE_IPV4) { + if (addrtype == LWIP_DNS_ADDRTYPE_IPV4 || esp_netif_get_default_netif() != esp_openthread_get_netif()) { + // If the DNS address type is IPv4 or the openthread netif is not the default netif, skip this hook. return 0; } - - ip6_addr_t nat64_prefix; - if (esp_openthread_get_nat64_prefix(&nat64_prefix) != ESP_OK) { - ESP_LOGE(TAG, "Cannot find NAT64 prefix"); - *err = ERR_ABRT; - return 1; - } dns_resolve_entry_t *entry = find_free_dns_resolve_entry(); if (!entry) { ESP_LOGE(TAG, "Cannot find free dns resolve entry"); @@ -133,9 +157,10 @@ int lwip_hook_dns_external_resolve(const char *name, ip_addr_t *addr, dns_found_ // If dns query is not enqueued, mark the entry not being used. entry->is_using = false; } - if (*err == ERR_OK) { - if (addr->type == IPADDR_TYPE_V4) { - ip4_addr_t addr_copy = addr->u_addr.ip4; + if (*err == ERR_OK && addr->type == IPADDR_TYPE_V4) { + ip4_addr_t addr_copy = addr->u_addr.ip4; + ip6_addr_t nat64_prefix; + if (esp_openthread_get_nat64_prefix(&nat64_prefix) == ESP_OK) { addr->type = IPADDR_TYPE_V6; memcpy(addr->u_addr.ip6.addr, nat64_prefix.addr, sizeof(nat64_prefix.addr)); addr->u_addr.ip6.addr[3] = addr_copy.addr; diff --git a/components/openthread/src/port/esp_openthread_state.c b/components/openthread/src/port/esp_openthread_state.c index 7d04cba9f5..33d1c70ad4 100644 --- a/components/openthread/src/port/esp_openthread_state.c +++ b/components/openthread/src/port/esp_openthread_state.c @@ -4,13 +4,15 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "esp_netif.h" +#include "esp_netif_types.h" +#include "esp_openthread_lock.h" #include #include #include #include #include #include -#include #include @@ -34,14 +36,22 @@ static void handle_ot_netif_state_change(otInstance* instance) static void handle_ot_netdata_change(void) { #if CONFIG_OPENTHREAD_DNS64_CLIENT - ip_addr_t dns_server_addr = *IP_ADDR_ANY; - if (esp_openthread_get_nat64_prefix(&dns_server_addr.u_addr.ip6) == ESP_OK) { - dns_server_addr.type = IPADDR_TYPE_V6; - dns_server_addr.u_addr.ip6.addr[3] = ipaddr_addr(CONFIG_OPENTHREAD_DNS_SERVER_ADDR); - const ip_addr_t* dnsserver = dns_getserver(OPENTHREAD_DNS_SERVER_INDEX); - if (memcmp(dnsserver, &dns_server_addr, sizeof(ip_addr_t)) != 0) { - ESP_LOGI(TAG, "Set dns server address: %s", ipaddr_ntoa(&dns_server_addr)); - dns_setserver(OPENTHREAD_DNS_SERVER_INDEX, &dns_server_addr); + ip6_addr_t dns_server_addr = *IP6_ADDR_ANY6; + if (esp_openthread_get_nat64_prefix(&dns_server_addr) == ESP_OK) { + dns_server_addr.addr[3] = ipaddr_addr(CONFIG_OPENTHREAD_DNS_SERVER_ADDR); + ip6_addr_t current_dns_server_addr = *IP6_ADDR_ANY6; + esp_openthread_task_switching_lock_release(); + esp_openthread_get_dnsserver_addr(¤t_dns_server_addr); + esp_openthread_task_switching_lock_acquire(portMAX_DELAY); + if (memcmp(¤t_dns_server_addr, &dns_server_addr, sizeof(ip6_addr_t)) != 0) { + ESP_LOGI(TAG, "Set dns server address: %s", ip6addr_ntoa(&dns_server_addr)); + esp_openthread_task_switching_lock_release(); + if (esp_openthread_set_dnsserver_addr(dns_server_addr) != ESP_OK) { + ESP_LOGE(TAG, "Failed to set dns info for openthread netif"); + esp_openthread_task_switching_lock_acquire(portMAX_DELAY); + return; + } + esp_openthread_task_switching_lock_acquire(portMAX_DELAY); if (esp_event_post(OPENTHREAD_EVENT, OPENTHREAD_EVENT_SET_DNS_SERVER, NULL, 0, 0) != ESP_OK) { ESP_LOGE(TAG, "Failed to post OpenThread set DNS server event"); }