From 901be1248777c0b635ae7f2746dd098a61d91686 Mon Sep 17 00:00:00 2001 From: Marko Puric Date: Wed, 3 Jan 2024 17:00:06 +0100 Subject: [PATCH] OpenThread: avoid hardcoded Golioth IPv6 address Leverage the OpenThread DNS to synthesize the Golioth System Server IPv6 address avoiding hardcoded IP address in applications. NAT64 prefix used by the Thred Border Router is set while synthesizing the address. Signed-off-by: Marko Puric --- net/golioth/CMakeLists.txt | 1 + net/golioth/ot_dns.c | 76 +++++++++++++++++++++++++++++++++++++ net/golioth/ot_dns.h | 24 ++++++++++++ net/golioth/system_client.c | 19 +++++++++- 4 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 net/golioth/ot_dns.c create mode 100644 net/golioth/ot_dns.h diff --git a/net/golioth/CMakeLists.txt b/net/golioth/CMakeLists.txt index 6ad0c372..6253c102 100644 --- a/net/golioth/CMakeLists.txt +++ b/net/golioth/CMakeLists.txt @@ -11,6 +11,7 @@ zephyr_library_sources_ifdef(CONFIG_GOLIOTH_RPC rpc.c) zephyr_library_sources_ifdef(CONFIG_GOLIOTH_SETTINGS settings.c) zephyr_library_sources_ifdef(CONFIG_GOLIOTH_SYSTEM_CLIENT system_client.c) zephyr_library_sources_ifdef(CONFIG_ZCBOR zcbor_utils.c) +zephyr_library_sources_ifdef(CONFIG_NET_L2_OPENTHREAD ot_dns.c) if(CONFIG_GOLIOTH_AUTH_METHOD_CERT) set(path ${CONFIG_GOLIOTH_SYSTEM_CLIENT_CA_PATH}) diff --git a/net/golioth/ot_dns.c b/net/golioth/ot_dns.c new file mode 100644 index 00000000..6cf0ee0d --- /dev/null +++ b/net/golioth/ot_dns.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2024 Golioth, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(golioth_openthread, CONFIG_GOLIOTH_SYSTEM_CLIENT_LOG_LEVEL); + +#include +#include +#include +#include + +static otDnsQueryConfig dns_query; +static char *golioth_ip6_addr; + +K_SEM_DEFINE(ot_dns_resolve, 0, 1); + +/* Callback for NAT64 IPv6 translated Golioth System Server address from the DNS query response */ +static void ot_dns_callback(otError aError, const otDnsAddressResponse *aResponse, void *aContext) +{ + otIp6Address golioth_addr; + + if (aError != OT_ERROR_NONE) { + LOG_ERR("Golioth System Server DNS resolving error: %d", aError); + return; + } + + if (otDnsAddressResponseGetAddress(aResponse, 0, &golioth_addr, NULL) == OT_ERROR_NONE) { + otIp6AddressToString(&golioth_addr, + golioth_ip6_addr, + OT_IP6_ADDRESS_STRING_SIZE); + } + + k_sem_give(&ot_dns_resolve); +} + +int synthesize_ip6_address(char *hostname, char *ip6_addr_buffer) +{ + int err = 0; + golioth_ip6_addr = ip6_addr_buffer; + + struct openthread_context *ot_context = openthread_get_default_context(); + + otIp4Address dns_server_addr; + + err = otIp4AddressFromString(CONFIG_DNS_SERVER1, &dns_server_addr); + if (err != OT_ERROR_NONE) { + LOG_ERR("DNS server IPv4 address error: %d", err); + return err; + } + + err = otNat64SynthesizeIp6Address(ot_context->instance, + &dns_server_addr, + &dns_query.mServerSockAddr.mAddress); + if (err != OT_ERROR_NONE) { + LOG_ERR("Synthesize DNS server IPv6 address error: %d", err); + return err; + } + + err = otDnsClientResolveIp4Address(ot_context->instance, + hostname, + ot_dns_callback, + ot_context, + &dns_query); + if (err != OT_ERROR_NONE) { + LOG_ERR("Golioth System Server address resolution DNS query error: %d", err); + return err; + } + + k_sem_take(&ot_dns_resolve, K_FOREVER); + + return 0; +} + diff --git a/net/golioth/ot_dns.h b/net/golioth/ot_dns.h new file mode 100644 index 00000000..03db3bbc --- /dev/null +++ b/net/golioth/ot_dns.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 Golioth, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __OT_DNS_H__ +#define __OT_DNS_H__ + +/** + * @brief Synthesize the IPv6 address from a given host name + * + * Get the IPv6 address of Golioth Server to avoid hardcoding it in applications. + * NAT64 prefix used by the Thread Border Router is set while synthesizing the address. + * + * @param[in] hostname A pointer to the host name for which to querry the address + * @param[out] ip6_addr_buffer A buffer to char array to output the synthesized IPv6 address + * + * @retval 0 On success + * @retval <0 On failure + */ +int synthesize_ip6_address(char *hostname, char *ip6_addr_buffer); + +#endif /* __OT_DNS_GOL_H__ */ diff --git a/net/golioth/system_client.c b/net/golioth/system_client.c index 13c6cb24..e56f4441 100644 --- a/net/golioth/system_client.c +++ b/net/golioth/system_client.c @@ -17,8 +17,12 @@ LOG_MODULE_REGISTER(golioth_system, CONFIG_GOLIOTH_SYSTEM_CLIENT_LOG_LEVEL); #include #include +#include "ot_dns.h" + #define RX_BUFFER_SIZE CONFIG_GOLIOTH_SYSTEM_CLIENT_RX_BUF_SIZE +static char golioth_system_server_host[40] = CONFIG_GOLIOTH_SYSTEM_SERVER_HOST; + static const uint8_t tls_ca_crt[] = { #if defined(CONFIG_GOLIOTH_SYSTEM_CLIENT_CA_PATH) #include "golioth-systemclient-ca.inc" @@ -244,11 +248,22 @@ SYS_INIT(golioth_system_init, APPLICATION, static int client_connect(struct golioth_client *client) { - int err; + int err = 0; + +#if defined(CONFIG_NET_L2_OPENTHREAD) + + err = synthesize_ip6_address(golioth_system_server_host, golioth_system_server_host); + if (err) { + LOG_ERR("Failed to synthesize Golioth Server IPv6 address: %d", err); + return err; + } + +#endif err = golioth_connect(client, - CONFIG_GOLIOTH_SYSTEM_SERVER_HOST, + golioth_system_server_host, CONFIG_GOLIOTH_SYSTEM_SERVER_PORT); + if (err) { LOG_ERR("Failed to connect: %d", err); return err;