mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #13507 from artokin/enable_nanostack_dns_cache
[feature-wisun] Enable Nanostack DNS cache usagepull/13530/head
commit
e46dd971df
|
@ -260,6 +260,19 @@ public:
|
|||
* */
|
||||
mesh_error_t get_radius_shared_secret(uint16_t *shared_secret_len, uint8_t *shared_secret);
|
||||
|
||||
/**
|
||||
* \brief Set DNS query result to Nanostack cache.
|
||||
*
|
||||
* Function sets DNS query result to Nanostack cache to get distributed to the devices in the Wi-SUN network.
|
||||
* Function must be called for a running Wi-SUN Border Router instance.
|
||||
*
|
||||
* \param address resolved address of domain_name.
|
||||
* \param domain_name name of the domain. Must be non-NULL.
|
||||
* \return MESH_ERROR_NONE on success.
|
||||
* \return error value in case of failure.
|
||||
* */
|
||||
mesh_error_t set_dns_query_result(SocketAddress *address, char *domain_name);
|
||||
|
||||
private:
|
||||
mesh_error_t configure();
|
||||
mesh_error_t apply_configuration(int8_t mesh_if_id);
|
||||
|
|
|
@ -355,3 +355,20 @@ mesh_error_t WisunBorderRouter::get_radius_shared_secret(uint16_t *shared_secret
|
|||
|
||||
return MESH_ERROR_NONE;
|
||||
}
|
||||
|
||||
mesh_error_t WisunBorderRouter::set_dns_query_result(SocketAddress *address, char *domain_name)
|
||||
{
|
||||
if (!domain_name || !address) {
|
||||
return MESH_ERROR_PARAM;
|
||||
}
|
||||
|
||||
if (_mesh_if_id < 0) {
|
||||
return MESH_ERROR_STATE;
|
||||
}
|
||||
|
||||
if (ws_bbr_dns_query_result_set(_mesh_if_id, (const uint8_t *)address->get_ip_bytes(), domain_name) >= 0) {
|
||||
return MESH_ERROR_NONE;
|
||||
}
|
||||
|
||||
return MESH_ERROR_UNKNOWN;
|
||||
}
|
||||
|
|
|
@ -30,12 +30,22 @@
|
|||
#include "mesh_system.h" // from inside mbed-mesh-api
|
||||
#include "socket_api.h"
|
||||
#include "net_interface.h"
|
||||
#include "nsapi_dns.h"
|
||||
|
||||
// Uncomment to enable trace
|
||||
//#define HAVE_DEBUG
|
||||
#include "ns_trace.h"
|
||||
#define TRACE_GROUP "nsif"
|
||||
|
||||
//#define NSIF_DEEP_TRACE
|
||||
#ifdef NSIF_DEEP_TRACE
|
||||
#define TRACE_DEEP tr_debug
|
||||
#else
|
||||
#define TRACE_DEEP(...)
|
||||
#endif
|
||||
|
||||
#define NANOSTACK_ISDIGIT(c) ((c) >= '0' && (c) <= '9')
|
||||
|
||||
#define NS_INTERFACE_SOCKETS_MAX 16 //same as NanoStack SOCKET_MAX
|
||||
|
||||
#define MALLOC ns_dyn_mem_alloc
|
||||
|
@ -150,6 +160,51 @@ static int8_t find_interface_by_address(const uint8_t target_addr[16])
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int8_t nanostack_interface_id_parse(const char *interface_name)
|
||||
{
|
||||
int namelen;
|
||||
int8_t interface_id = -1;
|
||||
|
||||
TRACE_DEEP("nanostack_interface_id_parse() %s", interface_name ? interface_name : "null");
|
||||
|
||||
if (!interface_name) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// parse interface ID from the interface_name
|
||||
namelen = strlen(interface_name);
|
||||
if (namelen < 4 || namelen > 5) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((strncmp("MES", interface_name, 3) == 0) && NANOSTACK_ISDIGIT(interface_name[3])) {
|
||||
interface_id = atoi(&interface_name[3]);
|
||||
}
|
||||
|
||||
TRACE_DEEP("parsed interfaceID = %d", interface_id);
|
||||
return interface_id;
|
||||
}
|
||||
|
||||
static int nanostack_dns_query_result_check(const char *domain_name, SocketAddress *address, const char *interface_name)
|
||||
{
|
||||
uint8_t dns_query_addr[16] = {0};
|
||||
int8_t interface_id, ns_query_result;
|
||||
|
||||
interface_id = nanostack_interface_id_parse(interface_name);
|
||||
|
||||
ns_query_result = arm_net_dns_query_result_get(interface_id, dns_query_addr, (char *)domain_name);
|
||||
|
||||
TRACE_DEEP("nanostack_dns_query_result_check(): interface_id=%d, ret=%d, resolved %s to %s",
|
||||
interface_id, ns_query_result, domain_name, trace_ipv6(dns_query_addr));
|
||||
|
||||
if (ns_query_result == 0) {
|
||||
address->set_ip_bytes(dns_query_addr, NSAPI_IPv6);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *NanostackSocket::operator new (std::size_t sz)
|
||||
{
|
||||
return MALLOC(sz);
|
||||
|
@ -534,6 +589,84 @@ const char *Nanostack::get_ip_address()
|
|||
return "::";
|
||||
}
|
||||
|
||||
nsapi_error_t Nanostack::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version, const char *interface_name)
|
||||
{
|
||||
if (name[0] == '\0') {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
// check for simple ip addresses
|
||||
if (address->set_ip_address(name)) {
|
||||
if (version != NSAPI_UNSPEC && address->get_ip_version() != version) {
|
||||
return NSAPI_ERROR_DNS_FAILURE;
|
||||
}
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
// Nanostack is IPv6 stack
|
||||
if (version == NSAPI_UNSPEC) {
|
||||
version = NSAPI_IPv6;
|
||||
}
|
||||
|
||||
// try nanostack DNS cache, if not found then fallback to dns query
|
||||
if (nanostack_dns_query_result_check(name, address, interface_name) == 0) {
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
return nsapi_dns_query(this, name, address, interface_name, version);
|
||||
}
|
||||
|
||||
nsapi_value_or_error_t Nanostack::gethostbyname_async(const char *name, hostbyname_cb_t callback, nsapi_version_t version, const char *interface_name)
|
||||
{
|
||||
SocketAddress address;
|
||||
|
||||
if (name[0] == '\0') {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
// check for simple ip addresses
|
||||
if (address.set_ip_address(name)) {
|
||||
if (version != NSAPI_UNSPEC && address.get_ip_version() != version) {
|
||||
return NSAPI_ERROR_DNS_FAILURE;
|
||||
}
|
||||
callback(NSAPI_ERROR_OK, &address);
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
// Nanostack is IPv6 stack
|
||||
if (version == NSAPI_UNSPEC) {
|
||||
version = NSAPI_IPv6;
|
||||
}
|
||||
|
||||
// try nanostack DNS cache, if not found then fallback to dns query
|
||||
if (nanostack_dns_query_result_check(name, &address, interface_name) == 0) {
|
||||
// hit found, return result immediately
|
||||
callback(NSAPI_ERROR_OK, &address);
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
call_in_callback_cb_t call_in_cb = get_call_in_callback();
|
||||
return nsapi_dns_query_async(this, name, callback, call_in_cb, interface_name, version);
|
||||
}
|
||||
|
||||
nsapi_error_t Nanostack::get_dns_server(int index, SocketAddress *address, const char *interface_name)
|
||||
{
|
||||
uint8_t dns_srv_address[16];
|
||||
int8_t interface_id;
|
||||
int8_t ret;
|
||||
|
||||
interface_id = nanostack_interface_id_parse(interface_name);
|
||||
|
||||
ret = arm_net_dns_server_get(interface_id, dns_srv_address, NULL, 0, index);
|
||||
|
||||
if (ret == 0) {
|
||||
address->set_ip_bytes(dns_srv_address, NSAPI_IPv6);
|
||||
TRACE_DEEP("get_dns_server(), index=%d, ret=%d, address=%s", index, ret, trace_ipv6((uint8_t *)address->get_ip_bytes()));
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_NO_ADDRESS;
|
||||
}
|
||||
|
||||
nsapi_error_t Nanostack::socket_open(void **handle, nsapi_protocol_t protocol)
|
||||
{
|
||||
// Validate parameters
|
||||
|
|
|
@ -63,6 +63,58 @@ protected:
|
|||
*/
|
||||
virtual const char *get_ip_address();
|
||||
|
||||
/** Translate a hostname to an IP address with specific version using network interface name.
|
||||
*
|
||||
* The hostname may be either a domain name or an IP address. If the
|
||||
* hostname is an IP address, no network transactions will be performed.
|
||||
*
|
||||
* Method first checks Nanostack DNS query result cache. If match is found, then the result is returned immediately.
|
||||
* Otherwise method calls DNS resolver to find a match.
|
||||
*
|
||||
* @param host Hostname to resolve.
|
||||
* @param address Pointer to a SocketAddress to store the result.
|
||||
* @param version IP version of address to resolve, NSAPI_UNSPEC indicates
|
||||
* version is chosen by the stack (defaults to NSAPI_UNSPEC).
|
||||
* @param interface_name Network interface name
|
||||
* @return NSAPI_ERROR_OK on success, negative error code on failure.
|
||||
*/
|
||||
virtual nsapi_error_t gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version, const char *interface_name);
|
||||
|
||||
/** Translate a hostname to an IP address (asynchronous) using network interface name.
|
||||
*
|
||||
* The hostname may be either a domain name or a dotted IP address. If the
|
||||
* hostname is an IP address, no network transactions will be performed.
|
||||
*
|
||||
* Method first checks Nanostack DNS query result cache. If match is found, then the result is returned immediately.
|
||||
*
|
||||
* Call is non-blocking. Result of the DNS operation is returned by the callback.
|
||||
* If this function returns failure, callback will not be called. In case result
|
||||
* is success (IP address was found from DNS cache), callback will be called
|
||||
* before function returns.
|
||||
*
|
||||
* @param host Hostname to resolve.
|
||||
* @param callback Callback that is called for result.
|
||||
* @param version IP version of address to resolve, NSAPI_UNSPEC indicates
|
||||
* version is chosen by the stack (defaults to NSAPI_UNSPEC).
|
||||
* @param interface_name Network interface name
|
||||
* @return 0 on immediate success,
|
||||
* negative error code on immediate failure or
|
||||
* a positive unique id that represents the hostname translation operation
|
||||
* and can be passed to cancel.
|
||||
*/
|
||||
virtual nsapi_value_or_error_t gethostbyname_async(const char *name, hostbyname_cb_t callback, nsapi_version_t version, const char *interface_name);
|
||||
|
||||
/** Get a domain name server from a list of servers to query
|
||||
*
|
||||
* Returns a DNS server address for a index. DNS servers are queried from Nanostack DNS cache.
|
||||
* If returns error no more DNS servers to read.
|
||||
*
|
||||
* @param index Index of the DNS server, starts from zero
|
||||
* @param address Destination for the host address
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t get_dns_server(int index, SocketAddress *address, const char *interface_name);
|
||||
|
||||
/** Opens a socket
|
||||
*
|
||||
* Creates a network socket and stores it in the specified handle.
|
||||
|
|
Loading…
Reference in New Issue