Skip to content

Commit

Permalink
feat(openthread): Replace netconn external resolve hook with dns exte…
Browse files Browse the repository at this point in the history
…rnal hook
  • Loading branch information
wqx6 committed Sep 11, 2024
1 parent a0e954b commit f62628d
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 19 deletions.
18 changes: 13 additions & 5 deletions components/lwip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1295,10 +1295,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
Expand All @@ -1313,11 +1312,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.

Expand Down
1 change: 1 addition & 0 deletions components/openthread/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ menu "OpenThread"
config OPENTHREAD_DNS64_CLIENT
bool "Use dns64 client"
depends on OPENTHREAD_ENABLED && LWIP_IPV4
select LWIP_HOOK_DNS_EXTERNAL_RESOLVE_SELECT_CUSTOM
default n
help
Select this option to acquire NAT64 address from dns servers.
Expand Down
89 changes: 75 additions & 14 deletions components/openthread/src/esp_openthread_dns64.c
Original file line number Diff line number Diff line change
@@ -1,26 +1,40 @@
/*
* 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_openthread_lock.h"
#include "esp_openthread_state.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;
}

Expand All @@ -41,11 +55,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));
Expand All @@ -55,9 +71,39 @@ 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)
{
dns_resolve_entry_t *resolve_entry = (dns_resolve_entry_t *)callback_arg;
if (resolve_entry && resolve_entry->found) {
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 == NETCONN_DNS_IPV4) {
if (addrtype == LWIP_DNS_ADDRTYPE_IPV4) {
return 0;
}

Expand All @@ -67,17 +113,32 @@ int lwip_hook_netconn_external_resolve(const char *name, ip_addr_t *addr, u8_t a
*err = ERR_ABRT;
return 1;
}

*err = netconn_gethostbyname_addrtype(name, addr, NETCONN_DNS_IPV4);
if (*err != ERR_OK) {
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;
}
if (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;

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) {
if (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;
}
}
return 1;
}

0 comments on commit f62628d

Please sign in to comment.