|
30 | 30 | #include "mesh_system.h" // from inside mbed-mesh-api
|
31 | 31 | #include "socket_api.h"
|
32 | 32 | #include "net_interface.h"
|
| 33 | +#include "nsapi_dns.h" |
33 | 34 |
|
34 | 35 | // Uncomment to enable trace
|
35 | 36 | //#define HAVE_DEBUG
|
36 | 37 | #include "ns_trace.h"
|
37 | 38 | #define TRACE_GROUP "nsif"
|
38 | 39 |
|
| 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 | + |
39 | 47 | #define NS_INTERFACE_SOCKETS_MAX 16 //same as NanoStack SOCKET_MAX
|
40 | 48 |
|
41 | 49 | #define MALLOC ns_dyn_mem_alloc
|
@@ -150,6 +158,50 @@ static int8_t find_interface_by_address(const uint8_t target_addr[16])
|
150 | 158 | return -1;
|
151 | 159 | }
|
152 | 160 |
|
| 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 | + |
153 | 205 | void *NanostackSocket::operator new (std::size_t sz)
|
154 | 206 | {
|
155 | 207 | return MALLOC(sz);
|
@@ -532,6 +584,74 @@ nsapi_error_t Nanostack::get_ip_address(SocketAddress *sockAddr)
|
532 | 584 | return NSAPI_ERROR_NO_ADDRESS;
|
533 | 585 | }
|
534 | 586 |
|
| 587 | +nsapi_error_t Nanostack::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version, const char *interface_name) |
| 588 | +{ |
| 589 | + if (name[0] == '\0') { |
| 590 | + return NSAPI_ERROR_PARAMETER; |
| 591 | + } |
| 592 | + // check for simple ip addresses |
| 593 | + if (address->set_ip_address(name)) { |
| 594 | + if (version != NSAPI_UNSPEC && address->get_ip_version() != version) { |
| 595 | + return NSAPI_ERROR_DNS_FAILURE; |
| 596 | + } |
| 597 | + return NSAPI_ERROR_OK; |
| 598 | + } |
| 599 | + |
| 600 | + // try nanostack DNS cache, if not found then fallback to dns query |
| 601 | + if (nanostack_dns_query_result_check(name, address, interface_name) == 0) { |
| 602 | + return 0; |
| 603 | + } |
| 604 | + |
| 605 | + return nsapi_dns_query(this, name, address, interface_name, version); |
| 606 | +} |
| 607 | + |
| 608 | +nsapi_value_or_error_t Nanostack::gethostbyname_async(const char *name, hostbyname_cb_t callback, nsapi_version_t version, const char *interface_name) |
| 609 | +{ |
| 610 | + SocketAddress address; |
| 611 | + |
| 612 | + if (name[0] == '\0') { |
| 613 | + return NSAPI_ERROR_PARAMETER; |
| 614 | + } |
| 615 | + |
| 616 | + // check for simple ip addresses |
| 617 | + if (address.set_ip_address(name)) { |
| 618 | + if (version != NSAPI_UNSPEC && address.get_ip_version() != version) { |
| 619 | + return NSAPI_ERROR_DNS_FAILURE; |
| 620 | + } |
| 621 | + callback(NSAPI_ERROR_OK, &address); |
| 622 | + return NSAPI_ERROR_OK; |
| 623 | + } |
| 624 | + |
| 625 | + // try nanostack DNS cache, if not found then fallback to dns query |
| 626 | + if (nanostack_dns_query_result_check(name, &address, interface_name) == 0) { |
| 627 | + // hit found, return result immediately |
| 628 | + callback(NSAPI_ERROR_OK, &address); |
| 629 | + return NSAPI_ERROR_OK; |
| 630 | + } |
| 631 | + |
| 632 | + call_in_callback_cb_t call_in_cb = get_call_in_callback(); |
| 633 | + return nsapi_dns_query_async(this, name, callback, call_in_cb, interface_name, version); |
| 634 | +} |
| 635 | + |
| 636 | +nsapi_error_t Nanostack::get_dns_server(int index, SocketAddress *address, const char *interface_name) |
| 637 | +{ |
| 638 | + uint8_t dns_srv_address[16]; |
| 639 | + int8_t interface_id; |
| 640 | + int8_t ret; |
| 641 | + |
| 642 | + interface_id = nanostack_interface_id_parse(interface_name); |
| 643 | + |
| 644 | + ret = arm_net_dns_server_get(interface_id, dns_srv_address, NULL, 0, index); |
| 645 | + |
| 646 | + if (ret == 0) { |
| 647 | + address->set_ip_bytes(dns_srv_address, NSAPI_IPv6); |
| 648 | + TRACE_DEEP("get_dns_server(), index=%d, ret=%d, address=%s", index, ret, trace_ipv6((uint8_t*)address->get_ip_bytes())); |
| 649 | + return NSAPI_ERROR_OK; |
| 650 | + } |
| 651 | + |
| 652 | + return NSAPI_ERROR_NO_ADDRESS; |
| 653 | +} |
| 654 | + |
535 | 655 | nsapi_error_t Nanostack::socket_open(void **handle, nsapi_protocol_t protocol)
|
536 | 656 | {
|
537 | 657 | // Validate parameters
|
|
0 commit comments