diff --git a/components/openthread/include/esp_openthread_dns64.h b/components/openthread/include/esp_openthread_dns64.h index 22809b8560..fe8db0b4d8 100644 --- a/components/openthread/include/esp_openthread_dns64.h +++ b/components/openthread/include/esp_openthread_dns64.h @@ -1,11 +1,12 @@ /* - * 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" @@ -26,17 +27,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 77be398886..252bc3d12e 100644 --- a/components/openthread/src/esp_openthread_dns64.c +++ b/components/openthread/src/esp_openthread_dns64.c @@ -1,11 +1,13 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "esp_openthread_dns64.h" +#include "esp_netif.h" #include "esp_openthread_state.h" +#include "esp_openthread_netif_glue.h" #include "esp_check.h" #include "esp_event.h" @@ -24,16 +26,46 @@ esp_err_t esp_openthread_dns64_client_init(void) 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; @@ -57,27 +89,21 @@ esp_err_t esp_openthread_get_nat64_prefix(ip6_addr_t *nat64_prefix) int lwip_hook_netconn_external_resolve(const char *name, ip_addr_t *addr, u8_t addrtype, err_t *err) { - if (addrtype == NETCONN_DNS_IPV4) { + if (addrtype == NETCONN_DNS_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\n"); - *err = ERR_ABRT; - return 1; - } - *err = netconn_gethostbyname_addrtype(name, addr, NETCONN_DNS_IPV4); - if (*err != ERR_OK) { - return 1; - } - if (addr->type == IPADDR_TYPE_V4) { + if (*err == ERR_OK && addr->type == IPADDR_TYPE_V4) { ip4_addr_t addr_copy = addr->u_addr.ip4; - 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; - addr->u_addr.ip6.zone = IP6_NO_ZONE; + 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; + addr->u_addr.ip6.zone = IP6_NO_ZONE; + } } return 1; } diff --git a/components/openthread/src/port/esp_openthread_state.c b/components/openthread/src/port/esp_openthread_state.c index 7d04cba9f5..3db4c146fc 100644 --- a/components/openthread/src/port/esp_openthread_state.c +++ b/components/openthread/src/port/esp_openthread_state.c @@ -7,7 +7,9 @@ #include #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"); }