Merge branch 'feat/thread_dns_ext_resolve_v5_1' into 'release/v5.1'

feat(openthread): Replace netconn external resolve hook with dns external hook(v5.1)

See merge request espressif/esp-idf!36296
This commit is contained in:
Jiang Jiang Jian 2025-01-23 15:15:24 +08:00
commit 06efbeef3a
2 changed files with 83 additions and 12 deletions

View File

@ -1178,10 +1178,9 @@ menu "LWIP"
choice LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE
prompt "Netconn external resolve Hook"
default LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT if OPENTHREAD_DNS64_CLIENT
default LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE if !OPENTHREAD_DNS64_CLIENT
default LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE
help
Enables custom DNS resolve hook.
Enables custom DNS resolve hook (without callback).
Setting this to "default" provides weak implementation
stub that could be overwritten in application code.
Setting this to "custom" provides hook's declaration
@ -1196,11 +1195,20 @@ menu "LWIP"
endchoice
config LWIP_HOOK_DNS_EXTERNAL_RESOLVE_SELECT_CUSTOM
bool
default n
help
This hidden option helps configure the DNS external resolve
hook for external components like OpenThread. It ensures that
`LWIP_HOOK_DNS_EXT_RESOLVE_CUSTOM` is selected without directly
adding a dependency in the choice construct.
choice LWIP_HOOK_DNS_EXTERNAL_RESOLVE
prompt "DNS external resolve Hook"
default LWIP_HOOK_DNS_EXT_RESOLVE_NONE
default LWIP_HOOK_DNS_EXT_RESOLVE_CUSTOM if LWIP_HOOK_DNS_EXTERNAL_RESOLVE_SELECT_CUSTOM
help
Enables custom DNS resolve hook.
Enables custom DNS resolve hook (with callback).
Setting this to "custom" provides hook's declaration
only and expects the application to implement it.

View File

@ -1,28 +1,40 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_openthread_dns64.h"
#include "esp_netif.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 "openthread/instance.h"
#include "openthread/netdata.h"
#include "lwip_default_hooks.h"
#include "lwip/api.h"
#include "lwip/def.h"
#include "lwip/dns.h"
#include "lwip/opt.h"
#include "openthread/instance.h"
#include "openthread/netdata.h"
#define TAG "OT_DNS64"
typedef struct dns_resolve_entry {
char name[DNS_MAX_NAME_LENGTH];
dns_found_callback found;
void *callback_arg;
bool is_using;
} dns_resolve_entry_t;
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;
}
@ -73,11 +85,13 @@ esp_err_t esp_openthread_get_nat64_prefix(ip6_addr_t *nat64_prefix)
otExternalRouteConfig route;
memset(&route, 0, sizeof(route));
esp_openthread_task_switching_lock_acquire(portMAX_DELAY);
while (otNetDataGetNextRoute(instance, &iter, &route) == OT_ERROR_NONE) {
if (route.mNat64) {
break;
}
}
esp_openthread_task_switching_lock_release();
if (route.mNat64) {
memcpy(nat64_prefix->addr, route.mPrefix.mPrefix.mFields.m8, sizeof(nat64_prefix->addr));
@ -87,14 +101,63 @@ 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)
static void dns_found_handler(const char *name, const ip_addr_t *ipaddr, void *callback_arg)
{
if (addrtype == NETCONN_DNS_IPV4 || esp_netif_get_default_netif() != esp_openthread_get_netif()) {
dns_resolve_entry_t *resolve_entry = (dns_resolve_entry_t *)callback_arg;
if (resolve_entry && resolve_entry->found) {
if (!ipaddr) {
resolve_entry->found(name, NULL, resolve_entry->callback_arg);
} else if (lwip_strnicmp(name, resolve_entry->name, sizeof(resolve_entry->name)) == 0) {
ip_addr_t ipaddr_copy = *ipaddr;
ip6_addr_t nat64_prefix;
if (ipaddr_copy.type == IPADDR_TYPE_V4 && esp_openthread_get_nat64_prefix(&nat64_prefix) == ESP_OK) {
ipaddr_copy.type = IPADDR_TYPE_V6;
memcpy(ipaddr_copy.u_addr.ip6.addr, nat64_prefix.addr, sizeof(nat64_prefix.addr));
ipaddr_copy.u_addr.ip6.addr[3] = ipaddr->u_addr.ip4.addr;
ipaddr_copy.u_addr.ip6.zone = IP6_NO_ZONE;
}
resolve_entry->found(name, &ipaddr_copy, resolve_entry->callback_arg);
}
resolve_entry->is_using = false;
}
}
static dns_resolve_entry_t *find_free_dns_resolve_entry(void)
{
for (uint8_t i = 0; i < DNS_TABLE_SIZE; ++i) {
if (s_dns_resolve_entry[i].is_using == false) {
return &s_dns_resolve_entry[i];
}
}
return NULL;
}
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 || 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;
}
*err = netconn_gethostbyname_addrtype(name, addr, NETCONN_DNS_IPV4);
dns_resolve_entry_t *entry = find_free_dns_resolve_entry();
if (!entry) {
ESP_LOGE(TAG, "Cannot find free dns resolve entry");
*err = ERR_MEM;
return 1;
}
strncpy(entry->name, name, strnlen(name, sizeof(entry->name) - 1));
entry->name[strnlen(name, sizeof(entry->name) - 1)] = 0;
entry->found = found;
entry->callback_arg = callback_arg;
entry->is_using = true;
*err = dns_gethostbyname_addrtype(name, addr, dns_found_handler, entry, LWIP_DNS_ADDRTYPE_IPV4);
if (*err != ERR_INPROGRESS) {
// If dns query is not enqueued, mark the entry not being used.
entry->is_using = false;
}
if (*err == ERR_OK && addr->type == IPADDR_TYPE_V4) {
ip4_addr_t addr_copy = addr->u_addr.ip4;
ip6_addr_t nat64_prefix;