mirror of https://github.com/ARMmbed/mbed-os.git
Getaddrinfo interface for multiple DNS adresses added.
New members are added to the network interface -getaddrinfo -getaddrinfo_async gethostbyname is unchanged but gethostbyname_async result param now contains results od DNS records found. Test cases for sync/async added added to DNS test folder.pull/11653/head
parent
f77f4ea911
commit
8b2f4c2e7e
|
@ -22,6 +22,7 @@
|
|||
#include "utest.h"
|
||||
#include "dns_tests.h"
|
||||
|
||||
#define RESULTS_NUM 1
|
||||
using namespace utest::v1;
|
||||
|
||||
namespace {
|
||||
|
@ -53,7 +54,7 @@ void ASYNCHRONOUS_DNS_CACHE()
|
|||
|
||||
semaphore.acquire();
|
||||
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, data.result);
|
||||
TEST_ASSERT_EQUAL(RESULTS_NUM, data.result);
|
||||
TEST_ASSERT(strlen(data.addr.get_ip_address()) > 1);
|
||||
|
||||
int delay_ms = (ticker_us - started_us) / 1000;
|
||||
|
|
|
@ -37,9 +37,9 @@ void ASYNCHRONOUS_DNS_CANCEL()
|
|||
data[i].semaphore = &semaphore;
|
||||
data[i].req_result = get_interface()->gethostbyname_async(dns_test_hosts[i],
|
||||
mbed::Callback<void(nsapi_error_t, SocketAddress *)>(hostbyname_cb, (void *) &data[i]));
|
||||
TEST_ASSERT(data[i].req_result >= 0 || data[i].req_result == NSAPI_ERROR_NO_MEMORY || data[i].req_result == NSAPI_ERROR_BUSY);
|
||||
TEST_ASSERT(data[i].req_result > 0 || data[i].req_result == NSAPI_ERROR_NO_MEMORY || data[i].req_result == NSAPI_ERROR_BUSY);
|
||||
|
||||
if (data[i].req_result >= 0) {
|
||||
if (data[i].req_result > 0) {
|
||||
// Callback will be called
|
||||
count++;
|
||||
} else {
|
||||
|
@ -68,10 +68,10 @@ void ASYNCHRONOUS_DNS_CANCEL()
|
|||
tr_info("DNS: query \"%s\" => cancel", dns_test_hosts[i]);
|
||||
continue;
|
||||
}
|
||||
TEST_ASSERT(data[i].result == NSAPI_ERROR_OK || data[i].result == NSAPI_ERROR_NO_MEMORY || data[i].result == NSAPI_ERROR_BUSY || data[i].result == NSAPI_ERROR_DNS_FAILURE || data[i].result == NSAPI_ERROR_TIMEOUT);
|
||||
if (data[i].result == NSAPI_ERROR_OK) {
|
||||
tr_info("DNS: query \"%s\" => \"%s\"",
|
||||
dns_test_hosts[i], data[i].addr.get_ip_address());
|
||||
TEST_ASSERT(data[i].result == 1 || data[i].result == NSAPI_ERROR_NO_MEMORY || data[i].result == NSAPI_ERROR_BUSY || data[i].result == NSAPI_ERROR_DNS_FAILURE || data[i].result == NSAPI_ERROR_TIMEOUT);
|
||||
if (data[i].result == 1) {
|
||||
printf("DNS: query \"%s\" => \"%s\"\n",
|
||||
dns_test_hosts[i], data[i].addr.get_ip_address());
|
||||
} else if (data[i].result == NSAPI_ERROR_DNS_FAILURE) {
|
||||
tr_error("DNS: query \"%s\" => DNS failure", dns_test_hosts[i]);
|
||||
} else if (data[i].result == NSAPI_ERROR_TIMEOUT) {
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
#include "dns_tests.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
namespace {
|
||||
int result_number;
|
||||
int result_no_mem;
|
||||
int result_dns_failure;
|
||||
int result_exp_timeout;
|
||||
}
|
||||
|
||||
// Callback used for asynchronous DNS result
|
||||
void getaddrinfo_cb(void *data, nsapi_error_t result, SocketAddress *address)
|
||||
{
|
||||
dns_application_data_multi_ip *app_data = static_cast<dns_application_data_multi_ip *>(data);
|
||||
app_data->result = result;
|
||||
for (unsigned int i = 0; i < result; i++) {
|
||||
if (address) {
|
||||
app_data->addr[i] = address[i];
|
||||
}
|
||||
}
|
||||
app_data->semaphore->release();
|
||||
app_data->value_set = true;
|
||||
}
|
||||
|
||||
void do_getaddrinfo_async(const char hosts[][DNS_TEST_HOST_LEN], unsigned int op_count, int *exp_ok, int *exp_no_mem, int *exp_dns_failure, int *exp_timeout)
|
||||
{
|
||||
// Verify that there is enough hosts in the host list
|
||||
TEST_ASSERT(op_count <= MBED_CONF_APP_DNS_TEST_HOSTS_NUM)
|
||||
|
||||
// Reset counters
|
||||
(*exp_ok) = 0;
|
||||
(*exp_no_mem) = 0;
|
||||
(*exp_dns_failure) = 0;
|
||||
(*exp_timeout) = 0;
|
||||
|
||||
// Create callback semaphore and data
|
||||
rtos::Semaphore semaphore;
|
||||
dns_application_data_multi_ip *data = new dns_application_data_multi_ip[op_count];
|
||||
SocketAddress hints{{NSAPI_IPv4}, 80};
|
||||
|
||||
unsigned int count = 0;
|
||||
for (unsigned int i = 0; i < op_count; i++) {
|
||||
data[i].semaphore = &semaphore;
|
||||
nsapi_error_t err = NetworkInterface::get_default_instance()->getaddrinfo_async(hosts[i], &hints, mbed::Callback<void(nsapi_error_t, SocketAddress *)>(getaddrinfo_cb, (void *) &data[i]));
|
||||
TEST_ASSERT(err >= 0 || err == NSAPI_ERROR_NO_MEMORY || err == NSAPI_ERROR_BUSY);
|
||||
if (err >= 0) {
|
||||
// Callback will be called
|
||||
count++;
|
||||
} else {
|
||||
// No memory to initiate DNS query, callback will not be called
|
||||
data[i].result = err;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for callback(s) to complete
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
semaphore.acquire();
|
||||
}
|
||||
// Print result
|
||||
for (unsigned int i = 0; i < op_count; i++) {
|
||||
TEST_ASSERT(data[i].result > 0 || data[i].result == NSAPI_ERROR_NO_MEMORY || data[i].result == NSAPI_ERROR_BUSY
|
||||
|| data[i].result == NSAPI_ERROR_DNS_FAILURE || data[i].result == NSAPI_ERROR_TIMEOUT);
|
||||
if (data[i].result > 0) {
|
||||
(*exp_ok)++;
|
||||
for (unsigned int results = 0; results < data[i].result; results++) {
|
||||
printf("DNS: query \"%s\" => \"%s\"\n",
|
||||
hosts[i], data[i].addr[results].get_ip_address());
|
||||
}
|
||||
} else if (data[i].result == NSAPI_ERROR_DNS_FAILURE) {
|
||||
(*exp_dns_failure)++;
|
||||
printf("DNS: query \"%s\" => DNS failure\n", hosts[i]);
|
||||
} else if (data[i].result == NSAPI_ERROR_TIMEOUT) {
|
||||
(*exp_timeout)++;
|
||||
printf("DNS: query \"%s\" => timeout\n", hosts[i]);
|
||||
} else if (data[i].result == NSAPI_ERROR_NO_MEMORY) {
|
||||
(*exp_no_mem)++;
|
||||
printf("DNS: query \"%s\" => no memory\n", hosts[i]);
|
||||
} else if (data[i].result == NSAPI_ERROR_BUSY) {
|
||||
(*exp_no_mem)++;
|
||||
printf("DNS: query \"%s\" => busy\n", hosts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void ASYNCHRONOUS_DNS_MULTI_IP()
|
||||
{
|
||||
nsapi_dns_reset();
|
||||
do_getaddrinfo_async(dns_test_hosts_multi_ip, MBED_CONF_APP_DNS_SIMULT_QUERIES, &result_number, &result_no_mem, &result_dns_failure, &result_exp_timeout);
|
||||
|
||||
TEST_ASSERT_EQUAL(MBED_CONF_APP_DNS_SIMULT_QUERIES, result_number);
|
||||
TEST_ASSERT_EQUAL(0, result_no_mem);
|
||||
TEST_ASSERT_EQUAL(0, result_dns_failure);
|
||||
TEST_ASSERT_EQUAL(0, result_exp_timeout);
|
||||
}
|
|
@ -54,7 +54,7 @@ void ASYNCHRONOUS_DNS_NON_ASYNC_AND_ASYNC()
|
|||
get_interface()->gethostbyname_async_cancel(err);
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, data.result);
|
||||
TEST_ASSERT_EQUAL(1, data.result);
|
||||
|
||||
tr_info("DNS: query \"%s\" => \"%s\"",
|
||||
dns_test_hosts_second[0], data.addr.get_ip_address());
|
||||
|
|
|
@ -35,6 +35,10 @@
|
|||
#define MBED_CONF_NSAPI_DNS_CACHE_SIZE 3
|
||||
#endif
|
||||
|
||||
#ifndef MBED_CONF_APP_DNS_TEST_HOSTS_NUM
|
||||
#define MBED_CONF_APP_DNS_TEST_HOSTS_NUM 6
|
||||
#endif
|
||||
|
||||
// Hostnames for testing against
|
||||
// Both lists must have A and AAAA records
|
||||
#ifndef MBED_CONF_APP_DNS_TEST_HOSTS
|
||||
|
@ -45,8 +49,8 @@
|
|||
#define MBED_CONF_APP_DNS_TEST_HOSTS_SECOND {"ipv6ready.org", "wireshark.org", "bbc.co.uk", "cnn.com", "www.flickr.com", "www.mozilla.org"}
|
||||
#endif
|
||||
|
||||
#ifndef MBED_CONF_APP_DNS_TEST_HOSTS_NUM
|
||||
#define MBED_CONF_APP_DNS_TEST_HOSTS_NUM 6
|
||||
#ifndef MBED_CONF_APP_DNS_TEST_MULTI_IP_HOSTS
|
||||
#define MBED_CONF_APP_DNS_TEST_MULTI_IP_HOSTS {"google.com", "www.mozilla.org", "yahoo.com", "instagram.com","www.flickr.com"}
|
||||
#endif
|
||||
|
||||
#define DNS_TEST_HOST_LEN 40
|
||||
|
@ -59,8 +63,17 @@ struct dns_application_data {
|
|||
bool value_set;
|
||||
};
|
||||
|
||||
struct dns_application_data_multi_ip {
|
||||
rtos::Semaphore *semaphore;
|
||||
nsapi_error_t result;
|
||||
SocketAddress addr[MBED_CONF_NSAPI_DNS_ADDRESSES_LIMIT];
|
||||
nsapi_error_t req_result;
|
||||
bool value_set;
|
||||
};
|
||||
|
||||
extern const char dns_test_hosts[MBED_CONF_APP_DNS_TEST_HOSTS_NUM][DNS_TEST_HOST_LEN];
|
||||
extern const char dns_test_hosts_second[MBED_CONF_APP_DNS_TEST_HOSTS_NUM][DNS_TEST_HOST_LEN];
|
||||
extern const char dns_test_hosts_multi_ip[MBED_CONF_APP_DNS_SIMULT_QUERIES][DNS_TEST_HOST_LEN];
|
||||
|
||||
/*
|
||||
* Utility functions
|
||||
|
@ -95,4 +108,6 @@ void SYNCHRONOUS_DNS();
|
|||
void SYNCHRONOUS_DNS_MULTIPLE();
|
||||
void SYNCHRONOUS_DNS_CACHE();
|
||||
void SYNCHRONOUS_DNS_INVALID();
|
||||
void SYNCHRONOUS_DNS_MULTI_IP();
|
||||
void ASYNCHRONOUS_DNS_MULTI_IP();
|
||||
#endif
|
||||
|
|
|
@ -42,6 +42,7 @@ NetworkInterface *net;
|
|||
|
||||
const char dns_test_hosts[MBED_CONF_APP_DNS_TEST_HOSTS_NUM][DNS_TEST_HOST_LEN] = MBED_CONF_APP_DNS_TEST_HOSTS;
|
||||
const char dns_test_hosts_second[MBED_CONF_APP_DNS_TEST_HOSTS_NUM][DNS_TEST_HOST_LEN] = MBED_CONF_APP_DNS_TEST_HOSTS_SECOND;
|
||||
const char dns_test_hosts_multi_ip[MBED_CONF_APP_DNS_SIMULT_QUERIES][DNS_TEST_HOST_LEN] = MBED_CONF_APP_DNS_TEST_MULTI_IP_HOSTS;
|
||||
|
||||
// Callback used for asynchronous DNS result
|
||||
void hostbyname_cb(void *data, nsapi_error_t result, SocketAddress *address)
|
||||
|
@ -92,8 +93,8 @@ void do_asynchronous_gethostbyname(const char hosts[][DNS_TEST_HOST_LEN], unsign
|
|||
|
||||
// Print result
|
||||
for (unsigned int i = 0; i < op_count; i++) {
|
||||
TEST_ASSERT(data[i].result == NSAPI_ERROR_OK || data[i].result == NSAPI_ERROR_NO_MEMORY || data[i].result == NSAPI_ERROR_BUSY || data[i].result == NSAPI_ERROR_DNS_FAILURE || data[i].result == NSAPI_ERROR_TIMEOUT);
|
||||
if (data[i].result == NSAPI_ERROR_OK) {
|
||||
TEST_ASSERT(data[i].result > 0 || data[i].result == NSAPI_ERROR_NO_MEMORY || data[i].result == NSAPI_ERROR_BUSY || data[i].result == NSAPI_ERROR_DNS_FAILURE || data[i].result == NSAPI_ERROR_TIMEOUT);
|
||||
if (data[i].result > 0) {
|
||||
(*exp_ok)++;
|
||||
tr_info("DNS: query \"%s\" => \"%s\"",
|
||||
hosts[i], data[i].addr.get_ip_address());
|
||||
|
@ -220,6 +221,8 @@ Case cases[] = {
|
|||
Case("SYNCHRONOUS_DNS", SYNCHRONOUS_DNS),
|
||||
Case("SYNCHRONOUS_DNS_MULTIPLE", SYNCHRONOUS_DNS_MULTIPLE),
|
||||
Case("SYNCHRONOUS_DNS_INVALID", SYNCHRONOUS_DNS_INVALID),
|
||||
Case("SYNCHRONOUS_DNS_MULTI_IP", SYNCHRONOUS_DNS_MULTI_IP),
|
||||
Case("ASYNCHRONOUS_DNS_MULTI_IP", ASYNCHRONOUS_DNS_MULTI_IP),
|
||||
};
|
||||
|
||||
Specification specification(test_setup, cases, greentea_teardown, greentea_continue_handlers);
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
#include "dns_tests.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
namespace {
|
||||
int result_number;
|
||||
int result_no_mem;
|
||||
int result_dns_failure;
|
||||
int result_exp_timeout;
|
||||
}
|
||||
|
||||
|
||||
void do_getaddrinfo(const char hosts[][DNS_TEST_HOST_LEN], unsigned int op_count, int *exp_ok, int *exp_no_mem, int *exp_dns_failure, int *exp_timeout)
|
||||
{
|
||||
// Verify that there is enough hosts in the host list
|
||||
TEST_ASSERT(op_count <= MBED_CONF_APP_DNS_TEST_HOSTS_NUM)
|
||||
|
||||
// Reset counters
|
||||
(*exp_ok) = 0;
|
||||
(*exp_no_mem) = 0;
|
||||
(*exp_dns_failure) = 0;
|
||||
(*exp_timeout) = 0;
|
||||
|
||||
SocketAddress hints{{NSAPI_IPv4}, 80};
|
||||
for (unsigned int i = 0; i < op_count; i++) {
|
||||
SocketAddress *result;
|
||||
nsapi_error_t err = NetworkInterface::get_default_instance()->get_default_instance()->getaddrinfo(hosts[i], &hints, &result);
|
||||
|
||||
if (err == NSAPI_ERROR_DNS_FAILURE) {
|
||||
(*exp_dns_failure)++;
|
||||
printf("DNS: query \"%s\" => DNS failure\n", hosts[i]);
|
||||
} else if (err == NSAPI_ERROR_TIMEOUT) {
|
||||
(*exp_timeout)++;
|
||||
printf("DNS: query \"%s\" => timeout\n", hosts[i]);
|
||||
} else if (err == NSAPI_ERROR_NO_MEMORY) {
|
||||
(*exp_no_mem)++;
|
||||
printf("DNS: query \"%s\" => no memory\n", hosts[i]);
|
||||
} else if (err == NSAPI_ERROR_BUSY) {
|
||||
(*exp_no_mem)++;
|
||||
printf("DNS: query \"%s\" => busy\n", hosts[i]);
|
||||
} else if (err > NSAPI_ERROR_OK) {
|
||||
(*exp_ok)++;
|
||||
for (unsigned int results = 0; results < err; results++) {
|
||||
printf("DNS: query \"%s\" => \"%s\"\n", hosts[i], result[results].get_ip_address());
|
||||
}
|
||||
} else if (err == 0) {
|
||||
printf("DNS: query \"%s\", no results\n", hosts[i]);
|
||||
TEST_FAIL();
|
||||
} else if (err < 0) {
|
||||
printf("DNS: query \"%s\" => %d, unexpected answer\n", hosts[i], err);
|
||||
TEST_FAIL();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SYNCHRONOUS_DNS_MULTI_IP()
|
||||
{
|
||||
nsapi_dns_reset();
|
||||
do_getaddrinfo(dns_test_hosts_multi_ip, MBED_CONF_APP_DNS_SIMULT_QUERIES, &result_number, &result_no_mem, &result_dns_failure, &result_exp_timeout);
|
||||
|
||||
TEST_ASSERT_EQUAL(MBED_CONF_APP_DNS_SIMULT_QUERIES, result_number);
|
||||
TEST_ASSERT_EQUAL(0, result_no_mem);
|
||||
TEST_ASSERT_EQUAL(0, result_dns_failure);
|
||||
TEST_ASSERT_EQUAL(0, result_exp_timeout);
|
||||
}
|
|
@ -332,11 +332,14 @@ TEST_F(Test_IfaceDnsSocket, multiple_queries)
|
|||
|
||||
SocketAddress *addr_cache;
|
||||
// Cache will only raturn one address.
|
||||
EXPECT_EQ(Test_IfaceDnsSocket::query_id, getaddrinfo(&stackMock(), "www.google.com", hints, &addr_cache));
|
||||
EXPECT_EQ(3, getaddrinfo(&stackMock(), "www.google.com", hints, &addr_cache));
|
||||
|
||||
// This is a bug which will be fixed in
|
||||
EXPECT_EQ(addr_cache[0].get_ip_version(), NSAPI_IPv4);
|
||||
EXPECT_FALSE(strncmp(addr_cache[0].get_ip_address(), "216.58.207.238", sizeof("216.58.207.238")));
|
||||
EXPECT_EQ(addr_cache[1].get_ip_version(), NSAPI_IPv4);
|
||||
EXPECT_FALSE(strncmp(addr_cache[1].get_ip_address(), "222.173.190.239", sizeof("222.173.190.239")));
|
||||
EXPECT_EQ(addr_cache[2].get_ip_version(), NSAPI_IPv4);
|
||||
EXPECT_FALSE(strncmp(addr_cache[2].get_ip_address(), "1.2.3.4", sizeof("1.2.3.4")));
|
||||
delete[] addr_cache;
|
||||
}
|
||||
|
||||
|
@ -400,7 +403,7 @@ TEST_F(Test_IfaceDnsSocket, simultaneous_query_async)
|
|||
// Run again to execute response_handler
|
||||
executeEventQueueCallbacks();
|
||||
|
||||
EXPECT_EQ(NSAPI_ERROR_OK, Test_IfaceDnsSocket::hostname_cb_result);
|
||||
EXPECT_EQ(1, Test_IfaceDnsSocket::hostname_cb_result);
|
||||
EXPECT_EQ(Test_IfaceDnsSocket::hostname_cb_address[0].get_ip_version(), NSAPI_IPv4);
|
||||
EXPECT_FALSE(strncmp(Test_IfaceDnsSocket::hostname_cb_address[0].get_ip_address(), "216.58.207.238", sizeof("216.58.207.238")));
|
||||
|
||||
|
@ -473,11 +476,12 @@ TEST_F(Test_IfaceDnsSocket, single_query_async_multiple)
|
|||
Test_IfaceDnsSocket::hostname_cb_result = NSAPI_ERROR_DEVICE_ERROR;
|
||||
|
||||
// Do not set any return values. Second call should use cache.
|
||||
// Cache will only return one address!
|
||||
EXPECT_EQ(0, getaddrinfo_async(&stackMock(), "www.google.com", &Test_IfaceDnsSocket::hostbyname_cb));
|
||||
EXPECT_EQ(NSAPI_ERROR_OK, Test_IfaceDnsSocket::hostname_cb_result);
|
||||
EXPECT_EQ(3, getaddrinfo_async(&stackMock(), "www.google.com", &Test_IfaceDnsSocket::hostbyname_cb));
|
||||
EXPECT_EQ(3, Test_IfaceDnsSocket::hostname_cb_result);
|
||||
EXPECT_EQ(Test_IfaceDnsSocket::hostname_cb_address[0].get_ip_version(), NSAPI_IPv4);
|
||||
EXPECT_FALSE(strncmp(Test_IfaceDnsSocket::hostname_cb_address[0].get_ip_address(), "216.58.207.238", sizeof("216.58.207.238")));
|
||||
EXPECT_FALSE(strncmp(Test_IfaceDnsSocket::hostname_cb_address[1].get_ip_address(), "222.173.190.239", sizeof("222.173.190.239")));
|
||||
EXPECT_FALSE(strncmp(Test_IfaceDnsSocket::hostname_cb_address[2].get_ip_address(), "1.2.3.4", sizeof("1.2.3.4")));
|
||||
|
||||
delete[] Test_IfaceDnsSocket::hostname_cb_address;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
# UNIT TESTS
|
||||
####################
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMBED_CONF_NSAPI_DNS_ADDRESSES_LIMIT=10")
|
||||
|
||||
set(unittest-sources
|
||||
../features/netsocket/SocketAddress.cpp
|
||||
../features/netsocket/NetworkStack.cpp
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include "equeue_stub.h"
|
||||
|
||||
#define EXPECTED_DNS_RESULT 1
|
||||
|
||||
// Control nsapi stub return value. See stubs/nsapi_dns_stub.cpp
|
||||
extern nsapi_error_t nsapi_stub_return_value;
|
||||
|
||||
|
@ -219,7 +221,7 @@ TEST_F(TestNetworkStack, gethostbyname_async_eventqueue_simple_address)
|
|||
EXPECT_FALSE(callback_is_called);
|
||||
EXPECT_EQ(stack->gethostbyname_async("127.0.0.1", mbed::callback(my_callback), NSAPI_IPv4), NSAPI_ERROR_OK);
|
||||
EXPECT_TRUE(callback_is_called);
|
||||
EXPECT_EQ(result_received, NSAPI_ERROR_OK);
|
||||
EXPECT_EQ(result_received, EXPECTED_DNS_RESULT);
|
||||
EXPECT_EQ(std::string(address_received.get_ip_address()), stack->ip_address);
|
||||
}
|
||||
|
||||
|
|
|
@ -81,6 +81,11 @@ nsapi_error_t NetworkInterface::gethostbyname(const char *name, SocketAddress *a
|
|||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_value_or_error_t NetworkInterface::getaddrinfo(const char *hostname, SocketAddress *hints, SocketAddress **res, const char *interface_name)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_error_t NetworkInterface::add_dns_server(const SocketAddress &address, const char *interface_name)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
|
@ -106,6 +111,11 @@ nsapi_value_or_error_t NetworkInterface::gethostbyname_async(char const *, mbed:
|
|||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_value_or_error_t NetworkInterface::getaddrinfo_async(const char *hostname, SocketAddress *hints, hostbyname_cb_t callback, const char *interface_name)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_error_t NetworkInterface::gethostbyname_async_cancel(int id)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
|
|
|
@ -27,6 +27,11 @@ nsapi_error_t NetworkStack::gethostbyname(const char *name, SocketAddress *addre
|
|||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_value_or_error_t NetworkStack::getaddrinfo(const char *hostname, SocketAddress *hints, SocketAddress **res, const char *interface_name)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t NetworkStack::add_dns_server(const SocketAddress &address, const char *interface_name)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
|
@ -74,6 +79,11 @@ nsapi_value_or_error_t NetworkStack::gethostbyname_async(const char *host, hostb
|
|||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_value_or_error_t NetworkStack::getaddrinfo_async(const char *hostname, SocketAddress *hints, hostbyname_cb_t callback, const char *interface_name)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_error_t NetworkStack::gethostbyname_async_cancel(int id)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
|
|
|
@ -54,11 +54,19 @@ public:
|
|||
{
|
||||
return return_value;
|
||||
}
|
||||
virtual nsapi_value_or_error_t getaddrinfo(const char *hostname, SocketAddress *hints, SocketAddress **res, const char *interface_name)
|
||||
{
|
||||
return return_value;
|
||||
}
|
||||
virtual nsapi_value_or_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback, nsapi_version_t version,
|
||||
const char *interface_name)
|
||||
{
|
||||
return return_value;
|
||||
}
|
||||
virtual nsapi_value_or_error_t getaddrinfo_async(const char *hostname, SocketAddress *hints, hostbyname_cb_t callback, const char *interface_name)
|
||||
{
|
||||
return return_value;
|
||||
}
|
||||
virtual nsapi_error_t gethostbyname_async_cancel(int id)
|
||||
{
|
||||
return return_value;
|
||||
|
|
|
@ -28,6 +28,12 @@ nsapi_error_t nsapi_dns_query(NetworkStack *stack, const char *host,
|
|||
return nsapi_stub_return_value;
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const char *host,
|
||||
SocketAddress *addresses, nsapi_size_t addr_count, const char *interface_name, nsapi_version_t version)
|
||||
{
|
||||
return nsapi_stub_return_value;
|
||||
}
|
||||
|
||||
nsapi_error_t nsapi_dns_query_async(NetworkStack *stack, const char *host,
|
||||
NetworkStack::hostbyname_cb_t callback, call_in_callback_cb_t call_in_cb, const char *interface_name,
|
||||
nsapi_version_t version)
|
||||
|
@ -37,6 +43,15 @@ nsapi_error_t nsapi_dns_query_async(NetworkStack *stack, const char *host,
|
|||
return nsapi_stub_return_value;
|
||||
}
|
||||
|
||||
nsapi_value_or_error_t nsapi_dns_query_multiple_async(NetworkStack *stack, const char *host,
|
||||
NetworkStack::hostbyname_cb_t callback, nsapi_size_t addr_count,
|
||||
call_in_callback_cb_t call_in_cb, const char *interface_name, nsapi_version_t version)
|
||||
{
|
||||
query_callback = callback;
|
||||
callin_callback = call_in_cb;
|
||||
return nsapi_stub_return_value;
|
||||
}
|
||||
|
||||
nsapi_error_t nsapi_dns_query_async_cancel(nsapi_error_t id)
|
||||
{
|
||||
return nsapi_stub_return_value;
|
||||
|
|
|
@ -42,6 +42,23 @@ public:
|
|||
*/
|
||||
virtual nsapi_error_t gethostbyname(const char *host,
|
||||
SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC, const char *interface_name = NULL) = 0;
|
||||
|
||||
/** Translate a hostname to the multiple IP addresses 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.
|
||||
*
|
||||
* If no stack-specific DNS resolution is provided, the hostname
|
||||
* will be resolve using a UDP socket on the stack.
|
||||
*
|
||||
* @param hostname Hostname to resolve.
|
||||
* @param hints Pointer to a SocketAddress with query parameters.
|
||||
* @param res Pointer to a SocketAddress array to store the result..
|
||||
* @param interface_name Network interface name
|
||||
* @return number of results on success, negative error code on failure.
|
||||
*/
|
||||
virtual nsapi_value_or_error_t getaddrinfo(const char *hostname, SocketAddress *hints, SocketAddress **res, const char *interface_name = NULL) = 0;
|
||||
|
||||
/** Hostname translation callback for gethostbyname_async.
|
||||
*
|
||||
* The callback is called after DNS resolution completes, or a failure occurs.
|
||||
|
@ -52,10 +69,11 @@ public:
|
|||
* The callback should not perform expensive operations such as socket recv/send
|
||||
* calls or blocking operations.
|
||||
*
|
||||
* @param result NSAPI_ERROR_OK on success, negative error code on failure.
|
||||
* @param result Negative error code on failure or
|
||||
* value that represents the number of DNS records
|
||||
* @param address On success, destination for the host SocketAddress.
|
||||
*/
|
||||
typedef mbed::Callback<void (nsapi_error_t result, SocketAddress *address)> hostbyname_cb_t;
|
||||
typedef mbed::Callback<void (nsapi_value_or_error_t result, SocketAddress *address)> hostbyname_cb_t;
|
||||
|
||||
/** Translate a hostname to an IP address (asynchronous)
|
||||
*
|
||||
|
@ -83,6 +101,29 @@ public:
|
|||
virtual nsapi_value_or_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback, nsapi_version_t version = NSAPI_UNSPEC,
|
||||
const char *interface_name = NULL) = 0;
|
||||
|
||||
/** Translate a hostname to the multiple IP addresses (asynchronous)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* If no stack-specific DNS resolution is provided, the hostname
|
||||
* will be resolved using a UDP socket on the stack.
|
||||
*
|
||||
* The 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 that
|
||||
* IP addresses are found from DNS cache, callback will be called before function returns.
|
||||
*
|
||||
* @param hostname Hostname to resolve.
|
||||
* @param hints Pointer to a SocketAddress with query parameters.
|
||||
* @param callback Callback that is called to return the result.
|
||||
* @param interface_name Network interface name
|
||||
* @return NSAPI_ERROR_OK 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 getaddrinfo_async(const char *hostname, SocketAddress *hints, hostbyname_cb_t callback, const char *interface_name = NULL) = 0;
|
||||
|
||||
/** Cancel asynchronous hostname translation.
|
||||
*
|
||||
* When translation is canceled, callback is not called.
|
||||
|
|
|
@ -96,11 +96,21 @@ nsapi_error_t NetworkInterface::gethostbyname(const char *name, SocketAddress *a
|
|||
return get_stack()->gethostbyname(name, address, version, interface_name);
|
||||
}
|
||||
|
||||
nsapi_value_or_error_t NetworkInterface::getaddrinfo(const char *hostname, SocketAddress *hints, SocketAddress **res, const char *interface_name)
|
||||
{
|
||||
return get_stack()->getaddrinfo(hostname, hints, res, interface_name);
|
||||
}
|
||||
|
||||
nsapi_value_or_error_t NetworkInterface::gethostbyname_async(const char *host, hostbyname_cb_t callback, nsapi_version_t version, const char *interface_name)
|
||||
{
|
||||
return get_stack()->gethostbyname_async(host, callback, version, interface_name);
|
||||
}
|
||||
|
||||
nsapi_value_or_error_t NetworkInterface::getaddrinfo_async(const char *hostname, SocketAddress *hints, hostbyname_cb_t callback, const char *interface_name)
|
||||
{
|
||||
return get_stack()->getaddrinfo_async(hostname, hints, callback, interface_name);
|
||||
}
|
||||
|
||||
nsapi_error_t NetworkInterface::gethostbyname_async_cancel(int id)
|
||||
{
|
||||
return get_stack()->gethostbyname_async_cancel(id);
|
||||
|
|
|
@ -237,6 +237,22 @@ public:
|
|||
virtual nsapi_error_t gethostbyname(const char *host,
|
||||
SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC, const char *interface_name = NULL);
|
||||
|
||||
/** Translate a hostname to the multiple IP addresses 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.
|
||||
*
|
||||
* If no stack-specific DNS resolution is provided, the hostname
|
||||
* will be resolve using a UDP socket on the stack.
|
||||
*
|
||||
* @param hostname Hostname to resolve.
|
||||
* @param hints Pointer to a SocketAddress with query parameters.
|
||||
* @param res Pointer to a SocketAddress array to store the result..
|
||||
* @param interface_name Network interface name
|
||||
* @return number of results on success, negative error code on failure.
|
||||
*/
|
||||
virtual nsapi_value_or_error_t getaddrinfo(const char *hostname, SocketAddress *hints, SocketAddress **res, const char *interface_name = NULL);
|
||||
|
||||
/** Hostname translation callback (for use with gethostbyname_async()).
|
||||
*
|
||||
* Callback will be called after DNS resolution completes or a failure occurs.
|
||||
|
@ -247,10 +263,11 @@ public:
|
|||
* The callback should not perform expensive operations such as socket recv/send
|
||||
* calls or blocking operations.
|
||||
*
|
||||
* @param result NSAPI_ERROR_OK on success, negative error code on failure.
|
||||
* @param result Negative error code on failure or
|
||||
* value that represents the number of DNS records
|
||||
* @param address On success, destination for the host SocketAddress.
|
||||
*/
|
||||
typedef mbed::Callback<void (nsapi_error_t result, SocketAddress *address)> hostbyname_cb_t;
|
||||
typedef mbed::Callback<void (nsapi_value_or_error_t result, SocketAddress *address)> hostbyname_cb_t;
|
||||
|
||||
/** Translate a hostname to an IP address (asynchronous) using network interface name.
|
||||
*
|
||||
|
@ -278,6 +295,30 @@ public:
|
|||
virtual nsapi_value_or_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback, nsapi_version_t version = NSAPI_UNSPEC,
|
||||
const char *interface_name = NULL);
|
||||
|
||||
/** Translate a hostname to the multiple IP addresses (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.
|
||||
*
|
||||
* If no stack-specific DNS resolution is provided, the hostname
|
||||
* will be resolve using a UDP socket on the stack.
|
||||
*
|
||||
* 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 hostname Hostname to resolve.
|
||||
* @param hints Pointer to a SocketAddress with query parameters.
|
||||
* @param callback Callback that is called for result.
|
||||
* @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 getaddrinfo_async(const char *hostname, SocketAddress *hints, hostbyname_cb_t callback, const char *interface_name = NULL);
|
||||
|
||||
/** Cancel asynchronous hostname translation.
|
||||
*
|
||||
* When translation is cancelled, callback will not be called.
|
||||
|
|
|
@ -76,6 +76,40 @@ nsapi_error_t NetworkStack::gethostbyname(const char *name, SocketAddress *addre
|
|||
return nsapi_dns_query(this, name, address, interface_name, version);
|
||||
}
|
||||
|
||||
nsapi_value_or_error_t NetworkStack::getaddrinfo(const char *hostname, SocketAddress *hints, SocketAddress **res, const char *interface_name)
|
||||
{
|
||||
int i;
|
||||
if (hostname[0] == '\0') {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
nsapi_version_t version = hints->get_ip_version();
|
||||
// if the version is unspecified, try to guess the version from the
|
||||
// ip address of the underlying stack
|
||||
if (version == NSAPI_UNSPEC) {
|
||||
SocketAddress testaddress;
|
||||
if (testaddress.set_ip_address(this->get_ip_address())) {
|
||||
version = testaddress.get_ip_version();
|
||||
}
|
||||
}
|
||||
|
||||
SocketAddress *temp = new (std::nothrow) SocketAddress [MBED_CONF_NSAPI_DNS_ADDRESSES_LIMIT];
|
||||
|
||||
if (!temp) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
int adr_cnt = nsapi_dns_query_multiple(this, hostname, temp, MBED_CONF_NSAPI_DNS_ADDRESSES_LIMIT, interface_name, version);
|
||||
|
||||
if (adr_cnt > 0) {
|
||||
*res = new (std::nothrow) SocketAddress [adr_cnt];
|
||||
for (i = 0; i < adr_cnt; i++) {
|
||||
(*res)[i] = temp[i];
|
||||
}
|
||||
}
|
||||
delete[] temp;
|
||||
return adr_cnt;
|
||||
}
|
||||
|
||||
nsapi_value_or_error_t NetworkStack::gethostbyname_async(const char *name, hostbyname_cb_t callback, nsapi_version_t version, const char *interface_name)
|
||||
{
|
||||
SocketAddress address;
|
||||
|
@ -90,7 +124,7 @@ nsapi_value_or_error_t NetworkStack::gethostbyname_async(const char *name, hostb
|
|||
return NSAPI_ERROR_DNS_FAILURE;
|
||||
}
|
||||
|
||||
callback(NSAPI_ERROR_OK, &address);
|
||||
callback(1, &address);
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
|
@ -108,6 +142,27 @@ nsapi_value_or_error_t NetworkStack::gethostbyname_async(const char *name, hostb
|
|||
return nsapi_dns_query_async(this, name, callback, call_in_cb, interface_name, version);
|
||||
}
|
||||
|
||||
nsapi_value_or_error_t NetworkStack::getaddrinfo_async(const char *hostname, SocketAddress *hints, hostbyname_cb_t callback, const char *interface_name)
|
||||
{
|
||||
SocketAddress address;
|
||||
|
||||
if (hostname[0] == '\0') {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
nsapi_version_t version = hints->get_ip_version();
|
||||
// if the version is unspecified, try to guess the version from the
|
||||
// ip address of the underlying stack
|
||||
if (version == NSAPI_UNSPEC) {
|
||||
SocketAddress testaddress;
|
||||
if (testaddress.set_ip_address(this->get_ip_address())) {
|
||||
version = testaddress.get_ip_version();
|
||||
}
|
||||
}
|
||||
|
||||
call_in_callback_cb_t call_in_cb = get_call_in_callback();
|
||||
|
||||
return nsapi_dns_query_multiple_async(this, hostname, callback, MBED_CONF_NSAPI_DNS_ADDRESSES_LIMIT, call_in_cb, interface_name, version);
|
||||
}
|
||||
nsapi_error_t NetworkStack::gethostbyname_async_cancel(int id)
|
||||
{
|
||||
return nsapi_dns_query_async_cancel(id);
|
||||
|
|
|
@ -98,6 +98,22 @@ public:
|
|||
virtual nsapi_error_t gethostbyname(const char *host,
|
||||
SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC, const char *interface_name = NULL);
|
||||
|
||||
/** Translate a hostname to the multiple IP addresses 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.
|
||||
*
|
||||
* If no stack-specific DNS resolution is provided, the hostname
|
||||
* will be resolve using a UDP socket on the stack.
|
||||
*
|
||||
* @param hostname Hostname to resolve.
|
||||
* @param hints Pointer to a SocketAddress with query parameters.
|
||||
* @param res Pointer to a SocketAddress array to store the result..
|
||||
* @param interface_name Network interface name
|
||||
* @return number of results on success, negative error code on failure.
|
||||
*/
|
||||
virtual nsapi_value_or_error_t getaddrinfo(const char *hostname, SocketAddress *hints, SocketAddress **res, const char *interface_name = NULL);
|
||||
|
||||
/** Hostname translation callback (asynchronous)
|
||||
*
|
||||
* Callback will be called after DNS resolution completes or a failure occurs.
|
||||
|
@ -108,12 +124,13 @@ public:
|
|||
* The callback should not perform expensive operations such as socket recv/send
|
||||
* calls or blocking operations.
|
||||
*
|
||||
* @param status NSAPI_ERROR_OK on success, negative error code on failure
|
||||
* @param result Negative error code on failure or
|
||||
* value that represents the number of DNS records
|
||||
* @param address On success, destination for the host SocketAddress
|
||||
*/
|
||||
typedef mbed::Callback<void (nsapi_error_t result, SocketAddress *address)> hostbyname_cb_t;
|
||||
typedef mbed::Callback<void (nsapi_value_or_error_t result, SocketAddress *address)> hostbyname_cb_t;
|
||||
|
||||
/** Translates a hostname to an IP address (asynchronous)
|
||||
/** Translates a hostname to multiple IP addresses (asynchronous)
|
||||
*
|
||||
* 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.
|
||||
|
@ -139,6 +156,29 @@ public:
|
|||
virtual nsapi_value_or_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback, nsapi_version_t version = NSAPI_UNSPEC,
|
||||
const char *interface_name = NULL);
|
||||
|
||||
/** Translates a hostname to the multiple IP addresses (asynchronous)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* If no stack-specific DNS resolution is provided, the hostname
|
||||
* will be resolve using a UDP socket on the stack.
|
||||
*
|
||||
* The 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 that
|
||||
* IP addresses are found from DNS cache, callback will be called before function returns.
|
||||
*
|
||||
* @param hostname Hostname to resolve
|
||||
* @param hints Pointer to a SocketAddress with query parameters.
|
||||
* @param callback Callback that is called for result
|
||||
* @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 getaddrinfo_async(const char *hostname, SocketAddress *hints, hostbyname_cb_t callback, const char *interface_name = NULL);
|
||||
|
||||
/** Cancels asynchronous hostname translation
|
||||
*
|
||||
* When translation is cancelled, callback will not be called.
|
||||
|
|
|
@ -58,6 +58,10 @@
|
|||
"help": "Number of cached host name resolutions",
|
||||
"value": 3
|
||||
},
|
||||
"dns-addresses-limit": {
|
||||
"help": "Max number IP addresses returned by multiple DNS query",
|
||||
"value": 10
|
||||
},
|
||||
"socket-stats-enabled": {
|
||||
"help": "Enable network socket statistics",
|
||||
"value": false
|
||||
|
|
|
@ -44,12 +44,16 @@
|
|||
#define DNS_QUERY_QUEUE_SIZE 5
|
||||
#define DNS_HOST_NAME_MAX_LEN 255
|
||||
#define DNS_TIMER_TIMEOUT 100
|
||||
#if !defined(MIN)
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
struct DNS_CACHE {
|
||||
nsapi_addr_t address;
|
||||
nsapi_addr_t *address;
|
||||
char *host;
|
||||
uint64_t expires; /*!< time to live in milliseconds */
|
||||
uint64_t accessed; /*!< last accessed */
|
||||
uint8_t count; /*!< number of IP addresses */
|
||||
};
|
||||
|
||||
struct SOCKET_CB_DATA {
|
||||
|
@ -88,7 +92,7 @@ struct DNS_QUERY {
|
|||
dns_state state;
|
||||
};
|
||||
|
||||
static void nsapi_dns_cache_add(const char *host, nsapi_addr_t *address, uint32_t ttl);
|
||||
static void nsapi_dns_cache_add(const char *host, nsapi_addr_t *address, uint32_t ttl, uint8_t count);
|
||||
static nsapi_size_or_error_t nsapi_dns_cache_find(const char *host, nsapi_version_t version, nsapi_addr_t *address);
|
||||
static void nsapi_dns_cache_reset();
|
||||
|
||||
|
@ -319,7 +323,7 @@ static int dns_scan_response(const uint8_t *ptr, uint16_t exp_id, uint32_t *ttl,
|
|||
return count;
|
||||
}
|
||||
|
||||
static void nsapi_dns_cache_add(const char *host, nsapi_addr_t *address, uint32_t ttl)
|
||||
static void nsapi_dns_cache_add(const char *host, nsapi_addr_t *address, uint32_t ttl, uint8_t count)
|
||||
{
|
||||
#if (MBED_CONF_NSAPI_DNS_CACHE_SIZE > 0)
|
||||
// RFC 1034: if TTL is zero, entry is not added to cache
|
||||
|
@ -358,10 +362,15 @@ static void nsapi_dns_cache_add(const char *host, nsapi_addr_t *address, uint32_
|
|||
dns_cache[index] = new (std::nothrow) DNS_CACHE;
|
||||
} else {
|
||||
delete dns_cache[index]->host;
|
||||
delete dns_cache[index]->address;
|
||||
}
|
||||
|
||||
if (dns_cache[index]) {
|
||||
dns_cache[index]->address = *address;
|
||||
dns_cache[index]->address = new (std::nothrow) nsapi_addr_t[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
dns_cache[index]->address[i] = address[i];
|
||||
}
|
||||
dns_cache[index]->count = count;
|
||||
dns_cache[index]->host = new (std::nothrow) char[strlen(host) + 1];
|
||||
strcpy(dns_cache[index]->host, host);
|
||||
uint64_t ms_count = rtos::Kernel::get_ms_count();
|
||||
|
@ -373,7 +382,7 @@ static void nsapi_dns_cache_add(const char *host, nsapi_addr_t *address, uint32_
|
|||
#endif
|
||||
}
|
||||
|
||||
static nsapi_error_t nsapi_dns_cache_find(const char *host, nsapi_version_t version, nsapi_addr_t *address)
|
||||
static nsapi_size_or_error_t nsapi_dns_cache_find(const char *host, nsapi_version_t version, nsapi_addr_t *address)
|
||||
{
|
||||
nsapi_error_t ret_val = NSAPI_ERROR_NO_ADDRESS;
|
||||
|
||||
|
@ -388,13 +397,17 @@ static nsapi_error_t nsapi_dns_cache_find(const char *host, nsapi_version_t vers
|
|||
delete dns_cache[i]->host;
|
||||
delete dns_cache[i];
|
||||
dns_cache[i] = NULL;
|
||||
} else if ((version == NSAPI_UNSPEC || version == dns_cache[i]->address.version) &&
|
||||
} else if ((version == NSAPI_UNSPEC || version == dns_cache[i]->address[0].version) && //only first IP address version check, others have the same version
|
||||
strcmp(dns_cache[i]->host, host) == 0) {
|
||||
if (address) {
|
||||
*address = dns_cache[i]->address;
|
||||
ret_val = 0;
|
||||
for (int count = 0; count < dns_cache[i]->count; count++) {
|
||||
address[count] = dns_cache[i]->address[count];
|
||||
ret_val++;
|
||||
}
|
||||
}
|
||||
dns_cache[i]->accessed = ms_count;
|
||||
ret_val = NSAPI_ERROR_OK;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -413,6 +426,7 @@ static void nsapi_dns_cache_reset()
|
|||
if (dns_cache[i]) {
|
||||
delete[] dns_cache[i]->host;
|
||||
dns_cache[i]->host = NULL;
|
||||
delete[] dns_cache[i]->address;
|
||||
delete dns_cache[i];
|
||||
dns_cache[i] = NULL;
|
||||
}
|
||||
|
@ -468,10 +482,16 @@ static nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const
|
|||
}
|
||||
|
||||
// check cache
|
||||
if (nsapi_dns_cache_find(host, version, addr) == NSAPI_ERROR_OK) {
|
||||
return 1;
|
||||
nsapi_addr *tmp = new (std::nothrow) nsapi_addr_t [MBED_CONF_NSAPI_DNS_ADDRESSES_LIMIT];
|
||||
int cached = nsapi_dns_cache_find(host, version, tmp);
|
||||
if (cached > 0) {
|
||||
for (int i = 0; i < MIN(cached, addr_count); i++) {
|
||||
addr[i] = tmp[i];
|
||||
}
|
||||
delete [] tmp;
|
||||
return MIN(cached, addr_count);
|
||||
}
|
||||
|
||||
delete [] tmp;
|
||||
// create a udp socket
|
||||
UDPSocket socket;
|
||||
int err = socket.open(stack);
|
||||
|
@ -549,7 +569,7 @@ static nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const
|
|||
uint32_t ttl;
|
||||
int resp = dns_scan_response(response, 1, &ttl, addr, addr_count);
|
||||
if (resp > 0) {
|
||||
nsapi_dns_cache_add(host, addr, ttl);
|
||||
nsapi_dns_cache_add(host, addr, ttl, resp);
|
||||
result = resp;
|
||||
} else if (resp < 0) {
|
||||
continue;
|
||||
|
@ -584,6 +604,11 @@ nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const char *
|
|||
SocketAddress *addresses, nsapi_size_t addr_count, const char *interface_name, nsapi_version_t version)
|
||||
{
|
||||
nsapi_addr_t *addrs = new (std::nothrow) nsapi_addr_t[addr_count];
|
||||
|
||||
if (!addrs) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t result = nsapi_dns_query_multiple(stack, host, addrs, addr_count, interface_name, version);
|
||||
|
||||
if (result > 0) {
|
||||
|
@ -675,14 +700,32 @@ nsapi_value_or_error_t nsapi_dns_query_multiple_async(NetworkStack *stack, const
|
|||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
nsapi_addr address;
|
||||
if (nsapi_dns_cache_find(host, version, &address) == NSAPI_ERROR_OK) {
|
||||
SocketAddress addr(address);
|
||||
dns_mutex->unlock();
|
||||
callback(NSAPI_ERROR_OK, &addr);
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
nsapi_addr *address = new (std::nothrow) nsapi_addr_t [MBED_CONF_NSAPI_DNS_ADDRESSES_LIMIT];
|
||||
int cached = nsapi_dns_cache_find(host, version, address);
|
||||
if (!addr_count) {
|
||||
if (cached > 0) {
|
||||
SocketAddress addr(*address);
|
||||
dns_mutex->unlock();
|
||||
callback(1, &addr);
|
||||
delete[] address;
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (cached > 0) {
|
||||
SocketAddress *addr = new (std::nothrow) SocketAddress [cached];
|
||||
for (int i = 0; i < cached; i++) {
|
||||
addr[i].set_addr(address[i]);
|
||||
}
|
||||
dns_mutex->unlock();
|
||||
callback(cached, addr);
|
||||
delete[] address;
|
||||
delete[] addr;
|
||||
return cached;
|
||||
}
|
||||
}
|
||||
delete[] address;
|
||||
int index = -1;
|
||||
|
||||
for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) {
|
||||
|
@ -1197,12 +1240,8 @@ static void nsapi_dns_query_async_response(void *ptr)
|
|||
}
|
||||
|
||||
// Adds address to cache
|
||||
nsapi_dns_cache_add(query->host, &(query->addrs[0]), query->ttl);
|
||||
|
||||
status = NSAPI_ERROR_OK;
|
||||
if (query->addr_count > 0) {
|
||||
status = query->count;
|
||||
}
|
||||
nsapi_dns_cache_add(query->host, &(query->addrs[0]), query->ttl, query->count);
|
||||
status = query->count;
|
||||
}
|
||||
|
||||
nsapi_dns_query_async_resp(query, status, addresses);
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue