Skip to content

Commit 0af9d04

Browse files
author
Arto Kinnunen
committed
Mesh: Enable Nanostack DNS cache usage
Inherit methods gethostbyname, gethostbyname_async and get_dns_server to Nanostack class. Methods will try to find DNS server address or DNS query results from Nanostack DNS cache.
1 parent 3a86360 commit 0af9d04

File tree

2 files changed

+172
-0
lines changed

2 files changed

+172
-0
lines changed

features/nanostack/nanostack-interface/Nanostack.cpp

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,20 @@
3030
#include "mesh_system.h" // from inside mbed-mesh-api
3131
#include "socket_api.h"
3232
#include "net_interface.h"
33+
#include "nsapi_dns.h"
3334

3435
// Uncomment to enable trace
3536
//#define HAVE_DEBUG
3637
#include "ns_trace.h"
3738
#define TRACE_GROUP "nsif"
3839

40+
#define NSIF_DEEP_TRACE
41+
#ifdef NSIF_DEEP_TRACE
42+
#define TRACE_DEEP tr_debug
43+
#else
44+
#define TRACE_DEP(...)
45+
#endif
46+
3947
#define NS_INTERFACE_SOCKETS_MAX 16 //same as NanoStack SOCKET_MAX
4048

4149
#define MALLOC ns_dyn_mem_alloc
@@ -150,6 +158,50 @@ static int8_t find_interface_by_address(const uint8_t target_addr[16])
150158
return -1;
151159
}
152160

161+
static int8_t nanostack_interface_id_parse(const char* interface_name)
162+
{
163+
int8_t interface_id = -1;
164+
165+
TRACE_DEEP("nanostack_interface_id_parse() %s", interface_name ? interface_name : "null");
166+
167+
if (!interface_name) {
168+
return -1;
169+
}
170+
171+
// parse interface ID from the interface_name
172+
if (strlen(interface_name) < 4) {
173+
return -1;
174+
}
175+
176+
interface_id = atoi(&interface_name[3]);
177+
if (interface_id < 0) {
178+
return -1;
179+
}
180+
181+
TRACE_DEEP("parsed interfaceID = %d", interface_id);
182+
return interface_id;
183+
}
184+
185+
static int8_t nanostack_dns_query_result_check(const char *domain_name, SocketAddress *address, const char *interface_name)
186+
{
187+
uint8_t dns_query_addr[16] = {0};
188+
int8_t interface_id, ns_query_result;
189+
190+
interface_id = nanostack_interface_id_parse(interface_name);
191+
192+
ns_query_result = arm_net_dns_query_result_get(interface_id, dns_query_addr, (char*)domain_name);
193+
194+
TRACE_DEEP("nanostack_dns_query_result_check(): interface_id=%d, ret=%d, resolved %s to %s",
195+
interface_id, ns_query_result, domain_name, trace_ipv6(dns_query_addr));
196+
197+
if (ns_query_result == 0) {
198+
address->set_ip_bytes(dns_query_addr, NSAPI_IPv6);
199+
return 0;
200+
}
201+
202+
return -1;
203+
}
204+
153205
void *NanostackSocket::operator new (std::size_t sz)
154206
{
155207
return MALLOC(sz);
@@ -534,6 +586,74 @@ const char *Nanostack::get_ip_address()
534586
return "::";
535587
}
536588

589+
nsapi_error_t Nanostack::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version, const char *interface_name)
590+
{
591+
if (name[0] == '\0') {
592+
return NSAPI_ERROR_PARAMETER;
593+
}
594+
// check for simple ip addresses
595+
if (address->set_ip_address(name)) {
596+
if (version != NSAPI_UNSPEC && address->get_ip_version() != version) {
597+
return NSAPI_ERROR_DNS_FAILURE;
598+
}
599+
return NSAPI_ERROR_OK;
600+
}
601+
602+
// try nanostack DNS cache, if not found then fallback to dns query
603+
if (nanostack_dns_query_result_check(name, address, interface_name) == 0) {
604+
return 0;
605+
}
606+
607+
return nsapi_dns_query(this, name, address, interface_name, version);
608+
}
609+
610+
nsapi_value_or_error_t Nanostack::gethostbyname_async(const char *name, hostbyname_cb_t callback, nsapi_version_t version, const char *interface_name)
611+
{
612+
SocketAddress address;
613+
614+
if (name[0] == '\0') {
615+
return NSAPI_ERROR_PARAMETER;
616+
}
617+
618+
// check for simple ip addresses
619+
if (address.set_ip_address(name)) {
620+
if (version != NSAPI_UNSPEC && address.get_ip_version() != version) {
621+
return NSAPI_ERROR_DNS_FAILURE;
622+
}
623+
callback(NSAPI_ERROR_OK, &address);
624+
return NSAPI_ERROR_OK;
625+
}
626+
627+
// try nanostack DNS cache, if not found then fallback to dns query
628+
if (nanostack_dns_query_result_check(name, &address, interface_name) == 0) {
629+
// hit found, return result immediately
630+
callback(NSAPI_ERROR_OK, &address);
631+
return NSAPI_ERROR_OK;
632+
}
633+
634+
call_in_callback_cb_t call_in_cb = get_call_in_callback();
635+
return nsapi_dns_query_async(this, name, callback, call_in_cb, interface_name, version);
636+
}
637+
638+
nsapi_error_t Nanostack::get_dns_server(int index, SocketAddress *address, const char *interface_name)
639+
{
640+
uint8_t dns_srv_address[16];
641+
int8_t interface_id;
642+
int8_t ret;
643+
644+
interface_id = nanostack_interface_id_parse(interface_name);
645+
646+
ret = arm_net_dns_server_get(interface_id, dns_srv_address, NULL, 0, index);
647+
648+
if (ret == 0) {
649+
address->set_ip_bytes(dns_srv_address, NSAPI_IPv6);
650+
TRACE_DEEP("get_dns_server(), index=%d, ret=%d, address=%s", index, ret, trace_ipv6((uint8_t*)address->get_ip_bytes()));
651+
return NSAPI_ERROR_OK;
652+
}
653+
654+
return NSAPI_ERROR_NO_ADDRESS;
655+
}
656+
537657
nsapi_error_t Nanostack::socket_open(void **handle, nsapi_protocol_t protocol)
538658
{
539659
// Validate parameters

features/nanostack/nanostack-interface/Nanostack.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,58 @@ class Nanostack : public OnboardNetworkStack, private mbed::NonCopyable<Nanostac
6363
*/
6464
virtual const char *get_ip_address();
6565

66+
/** Translate a hostname to an IP address with specific version using network interface name.
67+
*
68+
* The hostname may be either a domain name or an IP address. If the
69+
* hostname is an IP address, no network transactions will be performed.
70+
*
71+
* Method first checks Nanostack DNS query result cache. If match is found, then the result is returned immediately.
72+
* Otherwise method calls DNS resolver to find a match.
73+
*
74+
* @param host Hostname to resolve.
75+
* @param address Pointer to a SocketAddress to store the result.
76+
* @param version IP version of address to resolve, NSAPI_UNSPEC indicates
77+
* version is chosen by the stack (defaults to NSAPI_UNSPEC).
78+
* @param interface_name Network interface name
79+
* @return NSAPI_ERROR_OK on success, negative error code on failure.
80+
*/
81+
virtual nsapi_error_t gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version, const char *interface_name);
82+
83+
/** Translate a hostname to an IP address (asynchronous) using network interface name.
84+
*
85+
* The hostname may be either a domain name or a dotted IP address. If the
86+
* hostname is an IP address, no network transactions will be performed.
87+
*
88+
* Method first checks Nanostack DNS query result cache. If match is found, then the result is returned immediately.
89+
*
90+
* Call is non-blocking. Result of the DNS operation is returned by the callback.
91+
* If this function returns failure, callback will not be called. In case result
92+
* is success (IP address was found from DNS cache), callback will be called
93+
* before function returns.
94+
*
95+
* @param host Hostname to resolve.
96+
* @param callback Callback that is called for result.
97+
* @param version IP version of address to resolve, NSAPI_UNSPEC indicates
98+
* version is chosen by the stack (defaults to NSAPI_UNSPEC).
99+
* @param interface_name Network interface name
100+
* @return 0 on immediate success,
101+
* negative error code on immediate failure or
102+
* a positive unique id that represents the hostname translation operation
103+
* and can be passed to cancel.
104+
*/
105+
virtual nsapi_value_or_error_t gethostbyname_async(const char *name, hostbyname_cb_t callback, nsapi_version_t version, const char *interface_name);
106+
107+
/** Get a domain name server from a list of servers to query
108+
*
109+
* Returns a DNS server address for a index. DNS servers are queried from Nanostack DNS cache.
110+
* If returns error no more DNS servers to read.
111+
*
112+
* @param index Index of the DNS server, starts from zero
113+
* @param address Destination for the host address
114+
* @return 0 on success, negative error code on failure
115+
*/
116+
virtual nsapi_error_t get_dns_server(int index, SocketAddress *address, const char *interface_name);
117+
66118
/** Opens a socket
67119
*
68120
* Creates a network socket and stores it in the specified handle.

0 commit comments

Comments
 (0)