mirror of https://github.com/ARMmbed/mbed-os.git
Corrected more defects
- Serialized the sending of multiple async DNS queries since limits on event message box sizes - Added timer function that supervises the total time used to make DNS query and triggers socket timeouts - Changed nsapi_error_t to new nsapi_value_or_error_t on interface headers - Corrected wording of gethostbyname_async return values - Clarified .json options - Added a new data type for socket callback that can be used from interrupts - Corrected variable limits to use INT32_MAX etc. defines - Changed mallocs to new - Optimized variable sizes on DNS_QUERY definitionpull/6847/head
parent
1c01f5dda4
commit
c4424ff0a1
|
@ -69,11 +69,12 @@ public:
|
|||
* @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)
|
||||
* @return 0 on success, negative error code on failure or an unique id that
|
||||
* represents the hostname translation operation and can be passed to
|
||||
* cancel
|
||||
* @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_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback,
|
||||
virtual nsapi_value_or_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback,
|
||||
nsapi_version_t version = NSAPI_UNSPEC) = 0;
|
||||
|
||||
/** Cancels asynchronous hostname translation
|
||||
|
@ -83,7 +84,7 @@ public:
|
|||
* @param id Unique id of the hostname translation operation
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t gethostbyname_async_cancel(nsapi_error_t id) = 0;
|
||||
virtual nsapi_error_t gethostbyname_async_cancel(int id) = 0;
|
||||
|
||||
/** Add a domain name server to list of servers to query
|
||||
*
|
||||
|
|
|
@ -60,14 +60,14 @@ nsapi_error_t NetworkInterface::gethostbyname(const char *name, SocketAddress *a
|
|||
return get_stack()->gethostbyname(name, address, version);
|
||||
}
|
||||
|
||||
nsapi_error_t NetworkInterface::gethostbyname_async(const char *host, hostbyname_cb_t callback, nsapi_version_t version)
|
||||
nsapi_value_or_error_t NetworkInterface::gethostbyname_async(const char *host, hostbyname_cb_t callback, nsapi_version_t version)
|
||||
{
|
||||
return get_stack()->gethostbyname_async(host, callback, version);
|
||||
}
|
||||
|
||||
nsapi_error_t NetworkInterface::gethostbyname_async_cancel(nsapi_error_t handle)
|
||||
nsapi_error_t NetworkInterface::gethostbyname_async_cancel(int id)
|
||||
{
|
||||
return get_stack()->gethostbyname_async_cancel(handle);
|
||||
return get_stack()->gethostbyname_async_cancel(id);
|
||||
}
|
||||
|
||||
nsapi_error_t NetworkInterface::add_dns_server(const SocketAddress &address)
|
||||
|
|
|
@ -161,11 +161,12 @@ public:
|
|||
* @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)
|
||||
* @return 0 on success, negative error code on failure or an unique id that
|
||||
* represents the hostname translation operation and can be passed to
|
||||
* cancel
|
||||
* @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_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback,
|
||||
virtual nsapi_value_or_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback,
|
||||
nsapi_version_t version = NSAPI_UNSPEC);
|
||||
|
||||
/** Cancels asynchronous hostname translation
|
||||
|
@ -175,7 +176,7 @@ public:
|
|||
* @param id Unique id of the hostname translation operation
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t gethostbyname_async_cancel(nsapi_error_t id);
|
||||
virtual nsapi_error_t gethostbyname_async_cancel(int id);
|
||||
|
||||
/** Add a domain name server to list of servers to query
|
||||
*
|
||||
|
|
|
@ -49,7 +49,7 @@ nsapi_error_t NetworkStack::gethostbyname(const char *name, SocketAddress *addre
|
|||
return nsapi_dns_query(this, name, address, version);
|
||||
}
|
||||
|
||||
nsapi_error_t NetworkStack::gethostbyname_async(const char *name, hostbyname_cb_t callback, nsapi_version_t version)
|
||||
nsapi_value_or_error_t NetworkStack::gethostbyname_async(const char *name, hostbyname_cb_t callback, nsapi_version_t version)
|
||||
{
|
||||
SocketAddress address;
|
||||
|
||||
|
@ -77,9 +77,9 @@ nsapi_error_t NetworkStack::gethostbyname_async(const char *name, hostbyname_cb_
|
|||
return nsapi_dns_query_async(this, name, callback, call_in_cb, version);
|
||||
}
|
||||
|
||||
nsapi_error_t NetworkStack::gethostbyname_async_cancel(nsapi_error_t handle)
|
||||
nsapi_error_t NetworkStack::gethostbyname_async_cancel(int id)
|
||||
{
|
||||
return nsapi_dns_query_async_cancel(handle);
|
||||
return nsapi_dns_query_async_cancel(id);
|
||||
}
|
||||
|
||||
nsapi_error_t NetworkStack::add_dns_server(const SocketAddress &address)
|
||||
|
@ -115,6 +115,7 @@ nsapi_error_t NetworkStack::getsockopt(void *handle, int level, int optname, voi
|
|||
nsapi_error_t NetworkStack::call_in(int delay, mbed::Callback<void()> func)
|
||||
{
|
||||
events::EventQueue *event_queue = mbed::mbed_event_queue();
|
||||
|
||||
if (!event_queue) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
@ -132,20 +133,12 @@ nsapi_error_t NetworkStack::call_in(int delay, mbed::Callback<void()> func)
|
|||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
typedef mbed::Callback<nsapi_error_t (int delay_ms, mbed::Callback<void()> user_cb)> call_in_callback_cb_t;
|
||||
|
||||
call_in_callback_cb_t NetworkStack::get_call_in_callback()
|
||||
{
|
||||
events::EventQueue *event_queue = mbed::mbed_event_queue();
|
||||
if (!event_queue) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
call_in_callback_cb_t cb(this, &NetworkStack::call_in);
|
||||
return cb;
|
||||
}
|
||||
|
||||
|
||||
// NetworkStackWrapper class for encapsulating the raw nsapi_stack structure
|
||||
class NetworkStackWrapper : public NetworkStack
|
||||
{
|
||||
|
|
|
@ -95,11 +95,12 @@ public:
|
|||
* @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)
|
||||
* @return 0 on success, negative error code on failure or an unique id that
|
||||
* represents the hostname translation operation and can be passed to
|
||||
* cancel
|
||||
* @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_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback,
|
||||
virtual nsapi_value_or_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback,
|
||||
nsapi_version_t version = NSAPI_UNSPEC);
|
||||
|
||||
/** Cancels asynchronous hostname translation
|
||||
|
@ -109,7 +110,7 @@ public:
|
|||
* @param id Unique id of the hostname translation operation
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t gethostbyname_async_cancel(nsapi_error_t id);
|
||||
virtual nsapi_error_t gethostbyname_async_cancel(int id);
|
||||
|
||||
/** Add a domain name server to list of servers to query
|
||||
*
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
"present": 1,
|
||||
"default-stack": "LWIP",
|
||||
"dns-response-wait-time": {
|
||||
"help": "How long the DNS translator waits for a reply from a server",
|
||||
"help": "How long the DNS translator waits for a reply from a server in milliseconds",
|
||||
"value": 5000
|
||||
},
|
||||
"dns-total-retries": {
|
||||
"help": "Number of total DNS query retries that the DNS translator makes",
|
||||
"dns-total-attempts": {
|
||||
"help": "Number of total DNS query attempts that the DNS translator makes",
|
||||
"value": 3
|
||||
},
|
||||
"dns-retries": {
|
||||
"help": "Number of DNS query retries that the DNS translator makes per server",
|
||||
"help": "Number of DNS query retries that the DNS translator makes per server, before moving on to the next server. Total retries/attempts is always limited by dns-total-attempts.",
|
||||
"value": 0
|
||||
},
|
||||
"dns-cache-size": {
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* Declare __STDC_LIMIT_MACROS so stdint.h defines INT32_MAX when using C++ */
|
||||
#define __STDC_LIMIT_MACROS
|
||||
|
||||
#include "nsapi_dns.h"
|
||||
#include "netsocket/UDPSocket.h"
|
||||
#include <string.h>
|
||||
|
@ -33,26 +37,10 @@
|
|||
#define DNS_BUFFER_SIZE 512
|
||||
#define DNS_SERVERS_SIZE 5
|
||||
#define DNS_RESPONSE_MIN_SIZE 12
|
||||
#define DNS_MAX_TTL 604800
|
||||
#define DNS_STACK_SERVERS_NUM 5
|
||||
#define DNS_QUERY_QUEUE_SIZE 5
|
||||
#define DNS_HOST_NAME_MAX_LEN 255
|
||||
|
||||
#ifndef MBED_CONF_NSAPI_DNS_RESPONSE_WAIT_TIME
|
||||
#define MBED_CONF_NSAPI_DNS_RESPONSE_WAIT_TIME 5000
|
||||
#endif
|
||||
|
||||
#ifndef MBED_CONF_NSAPI_DNS_TOTAL_RETRIES
|
||||
#define MBED_CONF_NSAPI_DNS_TOTAL_RETRIES 3
|
||||
#endif
|
||||
|
||||
#ifndef MBED_CONF_NSAPI_DNS_RETRIES
|
||||
#define MBED_CONF_NSAPI_DNS_RETRIES 0
|
||||
#endif
|
||||
|
||||
#ifndef MBED_CONF_NSAPI_DNS_CACHE_SIZE
|
||||
#define MBED_CONF_NSAPI_DNS_CACHE_SIZE 3
|
||||
#endif
|
||||
#define DNS_TIMER_TIMEOUT 100
|
||||
|
||||
struct DNS_CACHE {
|
||||
nsapi_addr_t address;
|
||||
|
@ -61,8 +49,14 @@ struct DNS_CACHE {
|
|||
uint64_t accessed; /*!< last accessed */
|
||||
};
|
||||
|
||||
struct SOCKET_CB_DATA {
|
||||
call_in_callback_cb_t call_in_cb;
|
||||
NetworkStack *stack;
|
||||
};
|
||||
|
||||
struct DNS_QUERY {
|
||||
int unique_id;
|
||||
nsapi_error_t status;
|
||||
NetworkStack *stack;
|
||||
char *host;
|
||||
NetworkStack::hostbyname_cb_t callback;
|
||||
|
@ -70,13 +64,16 @@ struct DNS_QUERY {
|
|||
nsapi_size_t addr_count;
|
||||
nsapi_version_t version;
|
||||
UDPSocket *socket;
|
||||
SOCKET_CB_DATA *socket_cb_data;
|
||||
nsapi_addr_t *addrs;
|
||||
int dns_server;
|
||||
int retries;
|
||||
int total_retries;
|
||||
int dns_message_id;
|
||||
int count;
|
||||
uint32_t ttl;
|
||||
uint32_t total_timeout;
|
||||
uint32_t socket_timeout;
|
||||
uint16_t dns_message_id;
|
||||
uint8_t dns_server;
|
||||
uint8_t retries;
|
||||
uint8_t total_attempts;
|
||||
uint8_t count;
|
||||
};
|
||||
|
||||
typedef nsapi_error_t (*nsapi_dns_call_t)(mbed::Callback<void()> func);
|
||||
|
@ -85,13 +82,14 @@ typedef nsapi_error_t (*nsapi_dns_call_in_t)(int delay, mbed::Callback<void()> f
|
|||
static void nsapi_dns_cache_add(const char *host, nsapi_addr_t *address, uint32_t ttl);
|
||||
static nsapi_size_or_error_t nsapi_dns_cache_find(const char *host, nsapi_version_t version, nsapi_addr_t *address);
|
||||
|
||||
static nsapi_error_t nsapi_dns_get_server_addr(NetworkStack *stack, int *index, int *total_retries, SocketAddress *dns_addr);
|
||||
static nsapi_error_t nsapi_dns_get_server_addr(NetworkStack *stack, uint8_t *index, uint8_t *total_attempts, SocketAddress *dns_addr);
|
||||
|
||||
static void nsapi_dns_query_async_create(void *ptr);
|
||||
static nsapi_error_t nsapi_dns_query_async_delete(int unique_id);
|
||||
static void nsapi_dns_query_async_send(void *ptr);
|
||||
static void nsapi_dns_query_async_resp(DNS_QUERY *query, nsapi_error_t status, SocketAddress *address);
|
||||
static void nsapi_dns_query_async_socket_callback(NetworkStack *stack);
|
||||
static void nsapi_dns_query_async_socket_callback(void *ptr);
|
||||
static void nsapi_dns_query_async_socket_callback_handle(NetworkStack *stack);
|
||||
static void nsapi_dns_query_async_response(void *ptr);
|
||||
|
||||
static nsapi_addr_t dns_servers[DNS_SERVERS_SIZE] = {
|
||||
|
@ -105,7 +103,7 @@ static nsapi_addr_t dns_servers[DNS_SERVERS_SIZE] = {
|
|||
};
|
||||
|
||||
static DNS_CACHE *dns_cache[MBED_CONF_NSAPI_DNS_CACHE_SIZE];
|
||||
static uint16_t dns_message_id = 0;
|
||||
static uint16_t dns_message_id = 1;
|
||||
static int dns_unique_id = 1;
|
||||
static DNS_QUERY *dns_query_queue[DNS_QUERY_QUEUE_SIZE];
|
||||
// Protects cache shared between blocking and asynchronous calls
|
||||
|
@ -259,8 +257,8 @@ static int dns_scan_response(const uint8_t *ptr, uint16_t exp_id, uint32_t *ttl,
|
|||
|
||||
if (i == 0) {
|
||||
// Is interested only on first address that is stored to cache
|
||||
if (ttl_val > DNS_MAX_TTL) {
|
||||
ttl_val = DNS_MAX_TTL;
|
||||
if (ttl_val > INT32_MAX) {
|
||||
ttl_val = INT32_MAX;
|
||||
}
|
||||
*ttl = ttl_val;
|
||||
}
|
||||
|
@ -295,7 +293,7 @@ static int dns_scan_response(const uint8_t *ptr, uint16_t exp_id, uint32_t *ttl,
|
|||
static void nsapi_dns_cache_add(const char *host, nsapi_addr_t *address, uint32_t ttl)
|
||||
{
|
||||
// RFC 1034: if TTL is zero, entry is not added to cache
|
||||
if (!ttl) {
|
||||
if (ttl == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -307,7 +305,7 @@ static void nsapi_dns_cache_add(const char *host, nsapi_addr_t *address, uint32_
|
|||
dns_cache_mutex.lock();
|
||||
|
||||
int index = -1;
|
||||
uint64_t accessed = ~0;
|
||||
uint64_t accessed = UINT64_MAX;
|
||||
|
||||
// Finds free or last accessed entry
|
||||
for (int i = 0; i < MBED_CONF_NSAPI_DNS_CACHE_SIZE; i++) {
|
||||
|
@ -329,15 +327,15 @@ static void nsapi_dns_cache_add(const char *host, nsapi_addr_t *address, uint32_
|
|||
if (!dns_cache[index]) {
|
||||
dns_cache[index] = new (std::nothrow) DNS_CACHE;
|
||||
} else {
|
||||
free(dns_cache[index]->host);
|
||||
delete dns_cache[index]->host;
|
||||
}
|
||||
|
||||
if (dns_cache[index]) {
|
||||
dns_cache[index]->address = *address;
|
||||
dns_cache[index]->host = (char *) malloc(strlen(host) + 1);
|
||||
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();
|
||||
dns_cache[index]->expires = ms_count + ttl * 1000;
|
||||
dns_cache[index]->expires = ms_count + (uint64_t) ttl * 1000;
|
||||
dns_cache[index]->accessed = ms_count;
|
||||
}
|
||||
|
||||
|
@ -355,7 +353,7 @@ static nsapi_error_t nsapi_dns_cache_find(const char *host, nsapi_version_t vers
|
|||
uint64_t ms_count = rtos::Kernel::get_ms_count();
|
||||
// Checks all entries for expired entries
|
||||
if (ms_count > dns_cache[i]->expires) {
|
||||
free(dns_cache[i]->host);
|
||||
delete dns_cache[i]->host;
|
||||
delete dns_cache[i];
|
||||
dns_cache[i] = NULL;
|
||||
} else if ((version == NSAPI_UNSPEC || version == dns_cache[i]->address.version) &&
|
||||
|
@ -374,16 +372,16 @@ static nsapi_error_t nsapi_dns_cache_find(const char *host, nsapi_version_t vers
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
static nsapi_error_t nsapi_dns_get_server_addr(NetworkStack *stack, int *index, int *total_retries, SocketAddress *dns_addr)
|
||||
static nsapi_error_t nsapi_dns_get_server_addr(NetworkStack *stack, uint8_t *index, uint8_t *total_attempts, SocketAddress *dns_addr)
|
||||
{
|
||||
bool dns_addr_set = false;
|
||||
|
||||
if (*total_retries == 0) {
|
||||
if (*total_attempts == 0) {
|
||||
return NSAPI_ERROR_NO_ADDRESS;
|
||||
}
|
||||
|
||||
if (*index >= DNS_SERVERS_SIZE + DNS_STACK_SERVERS_NUM) {
|
||||
if (*total_retries) {
|
||||
if (*total_attempts) {
|
||||
*index = 0;
|
||||
} else {
|
||||
return NSAPI_ERROR_NO_ADDRESS;
|
||||
|
@ -440,15 +438,14 @@ static nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const
|
|||
|
||||
nsapi_size_or_error_t result = NSAPI_ERROR_DNS_FAILURE;
|
||||
|
||||
int retries = MBED_CONF_NSAPI_DNS_RETRIES;
|
||||
|
||||
int index = 0;
|
||||
int total_retries = MBED_CONF_NSAPI_DNS_TOTAL_RETRIES;
|
||||
uint8_t retries = MBED_CONF_NSAPI_DNS_RETRIES;
|
||||
uint8_t index = 0;
|
||||
uint8_t total_attempts = MBED_CONF_NSAPI_DNS_TOTAL_ATTEMPTS;
|
||||
|
||||
// check against each dns server
|
||||
while (true) {
|
||||
SocketAddress dns_addr;
|
||||
err = nsapi_dns_get_server_addr(stack, &index, &total_retries, &dns_addr);
|
||||
err = nsapi_dns_get_server_addr(stack, &index, &total_attempts, &dns_addr);
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
break;
|
||||
}
|
||||
|
@ -465,8 +462,8 @@ static nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const
|
|||
continue;
|
||||
}
|
||||
|
||||
if (total_retries) {
|
||||
total_retries--;
|
||||
if (total_attempts) {
|
||||
total_attempts--;
|
||||
}
|
||||
|
||||
// recv the response
|
||||
|
@ -554,7 +551,7 @@ nsapi_error_t nsapi_dns_query(NetworkStack *stack, const char *host,
|
|||
return (nsapi_error_t)((result > 0) ? 0 : result);
|
||||
}
|
||||
|
||||
nsapi_error_t nsapi_dns_query_async(NetworkStack *stack, const char *host,
|
||||
nsapi_value_or_error_t nsapi_dns_query_async(NetworkStack *stack, const char *host,
|
||||
NetworkStack::hostbyname_cb_t callback, call_in_callback_cb_t call_in_cb,
|
||||
nsapi_version_t version)
|
||||
{
|
||||
|
@ -576,7 +573,9 @@ nsapi_error_t nsapi_dns_call_in(call_in_callback_cb_t cb, int delay, mbed::Callb
|
|||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t nsapi_dns_query_multiple_async(NetworkStack *stack, const char *host,
|
||||
void nsapi_dns_query_async_timeout(void);
|
||||
|
||||
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, nsapi_version_t version)
|
||||
{
|
||||
|
@ -620,31 +619,60 @@ nsapi_error_t nsapi_dns_query_multiple_async(NetworkStack *stack, const char *ho
|
|||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
query->host = (char *) malloc(host_len + 1);
|
||||
query->host = new (std::nothrow) char[host_len + 1];
|
||||
strcpy(query->host, host);
|
||||
query->status = NSAPI_ERROR_DEVICE_ERROR;
|
||||
query->callback = callback;
|
||||
query->call_in_cb = call_in_cb;
|
||||
query->stack = stack;
|
||||
query->addr_count = addr_count;
|
||||
query->version = version;
|
||||
query->socket = NULL;
|
||||
query->socket_cb_data = NULL;
|
||||
query->addrs = NULL;
|
||||
query->dns_server = 0;
|
||||
query->retries = MBED_CONF_NSAPI_DNS_RETRIES + 1;
|
||||
query->total_retries = MBED_CONF_NSAPI_DNS_TOTAL_RETRIES;
|
||||
query->dns_message_id = -1;
|
||||
query->total_attempts = MBED_CONF_NSAPI_DNS_TOTAL_ATTEMPTS;
|
||||
query->dns_message_id = 0;
|
||||
query->socket_timeout = 0;
|
||||
query->total_timeout = MBED_CONF_NSAPI_DNS_TOTAL_ATTEMPTS * MBED_CONF_NSAPI_DNS_RESPONSE_WAIT_TIME + 500;
|
||||
|
||||
query->unique_id = dns_unique_id++;
|
||||
if (query->unique_id > 0x7FFF) {
|
||||
query->unique_id = 1;
|
||||
}
|
||||
|
||||
int ongoing_queries = 0;
|
||||
|
||||
for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) {
|
||||
if (dns_query_queue[i]) {
|
||||
if (!query->socket && dns_query_queue[i]->socket && dns_query_queue[i]->stack == query->stack) {
|
||||
query->socket = dns_query_queue[i]->socket;
|
||||
query->socket_cb_data = dns_query_queue[i]->socket_cb_data;
|
||||
}
|
||||
ongoing_queries++;
|
||||
}
|
||||
}
|
||||
|
||||
dns_query_queue[index] = query;
|
||||
|
||||
if (nsapi_dns_call_in(query->call_in_cb, 0, mbed::callback(nsapi_dns_query_async_create, reinterpret_cast<void *>(query->unique_id))) != NSAPI_ERROR_OK) {
|
||||
delete query;
|
||||
dns_mutex.unlock();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
// Add some overhead based on number of ongoing queries
|
||||
query->total_timeout += ongoing_queries * 500;
|
||||
|
||||
if (ongoing_queries == 0) {
|
||||
if (nsapi_dns_call_in(query->call_in_cb, DNS_TIMER_TIMEOUT, mbed::callback(nsapi_dns_query_async_timeout)) != NSAPI_ERROR_OK) {
|
||||
delete query->host;
|
||||
delete query;
|
||||
dns_mutex.unlock();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (nsapi_dns_call_in(query->call_in_cb, 0, mbed::callback(nsapi_dns_query_async_create, reinterpret_cast<void *>(query->unique_id))) != NSAPI_ERROR_OK) {
|
||||
delete query->host;
|
||||
delete query;
|
||||
dns_mutex.unlock();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
dns_mutex.unlock();
|
||||
|
@ -652,7 +680,51 @@ nsapi_error_t nsapi_dns_query_multiple_async(NetworkStack *stack, const char *ho
|
|||
return query->unique_id;
|
||||
}
|
||||
|
||||
nsapi_error_t nsapi_dns_query_async_cancel(nsapi_error_t id)
|
||||
void nsapi_dns_query_async_timeout(void)
|
||||
{
|
||||
dns_mutex.lock();
|
||||
|
||||
DNS_QUERY *query = NULL;
|
||||
|
||||
for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) {
|
||||
if (dns_query_queue[i]) {
|
||||
|
||||
if (dns_query_queue[i]->total_timeout > DNS_TIMER_TIMEOUT) {
|
||||
dns_query_queue[i]->total_timeout -= DNS_TIMER_TIMEOUT;
|
||||
} else {
|
||||
// If does not already have response, fails
|
||||
if (query->status == NSAPI_ERROR_DEVICE_ERROR) {
|
||||
query->socket_timeout = 0;
|
||||
nsapi_dns_call_in(dns_query_queue[i]->call_in_cb, 0, mbed::callback(nsapi_dns_query_async_response, reinterpret_cast<void *>(dns_query_queue[i]->unique_id)));
|
||||
}
|
||||
}
|
||||
|
||||
if (dns_query_queue[i]->socket_timeout > 0) {
|
||||
if (dns_query_queue[i]->socket_timeout > DNS_TIMER_TIMEOUT) {
|
||||
dns_query_queue[i]->socket_timeout -= DNS_TIMER_TIMEOUT;
|
||||
} else {
|
||||
// Retries
|
||||
dns_query_queue[i]->socket_timeout = 0;
|
||||
nsapi_dns_call_in(dns_query_queue[i]->call_in_cb, 0,
|
||||
mbed::callback(nsapi_dns_query_async_send, reinterpret_cast<void *>(dns_query_queue[i]->unique_id)));
|
||||
}
|
||||
}
|
||||
|
||||
if (!query) {
|
||||
query = dns_query_queue[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Starts timer again
|
||||
if (query) {
|
||||
nsapi_dns_call_in(query->call_in_cb, DNS_TIMER_TIMEOUT, mbed::callback(nsapi_dns_query_async_timeout));
|
||||
}
|
||||
|
||||
dns_mutex.unlock();
|
||||
}
|
||||
|
||||
nsapi_error_t nsapi_dns_query_async_cancel(int id)
|
||||
{
|
||||
dns_mutex.lock();
|
||||
|
||||
|
@ -684,14 +756,26 @@ static void nsapi_dns_query_async_create(void *ptr)
|
|||
return;
|
||||
}
|
||||
|
||||
bool ongoing = false;
|
||||
|
||||
for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) {
|
||||
if (dns_query_queue[i] && dns_query_queue[i] != query) {
|
||||
if (dns_query_queue[i]->socket && dns_query_queue[i]->stack == query->stack) {
|
||||
if (!query->socket && dns_query_queue[i]->socket && dns_query_queue[i]->stack == query->stack) {
|
||||
query->socket = dns_query_queue[i]->socket;
|
||||
query->socket_cb_data = dns_query_queue[i]->socket_cb_data;
|
||||
}
|
||||
if (dns_query_queue[i]->dns_message_id != 0) {
|
||||
ongoing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ongoing) {
|
||||
// If there is already operation ongoing exits
|
||||
dns_mutex.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
UDPSocket *socket;
|
||||
|
||||
if (query->socket) {
|
||||
|
@ -700,7 +784,6 @@ static void nsapi_dns_query_async_create(void *ptr)
|
|||
socket = new (std::nothrow) UDPSocket;
|
||||
if (!socket) {
|
||||
nsapi_dns_query_async_resp(query, NSAPI_ERROR_NO_MEMORY, NULL);
|
||||
dns_mutex.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -708,12 +791,17 @@ static void nsapi_dns_query_async_create(void *ptr)
|
|||
if (err) {
|
||||
delete socket;
|
||||
nsapi_dns_query_async_resp(query, err, NULL);
|
||||
dns_mutex.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
socket->set_timeout(0);
|
||||
socket->sigio(mbed::callback(nsapi_dns_query_async_socket_callback, query->stack));
|
||||
|
||||
if (!query->socket_cb_data) {
|
||||
query->socket_cb_data = new SOCKET_CB_DATA;
|
||||
}
|
||||
query->socket_cb_data->call_in_cb = query->call_in_cb;
|
||||
query->socket_cb_data->stack = query->stack;
|
||||
socket->sigio(mbed::callback(nsapi_dns_query_async_socket_callback, query->socket_cb_data));
|
||||
|
||||
query->socket = socket;
|
||||
}
|
||||
|
@ -750,13 +838,14 @@ static nsapi_error_t nsapi_dns_query_async_delete(int unique_id)
|
|||
if (close_socket && dns_query_queue[index]->socket) {
|
||||
dns_query_queue[index]->socket->close();
|
||||
delete dns_query_queue[index]->socket;
|
||||
delete dns_query_queue[index]->socket_cb_data;
|
||||
}
|
||||
|
||||
if (dns_query_queue[index]->addrs) {
|
||||
delete[] dns_query_queue[index]->addrs;
|
||||
}
|
||||
|
||||
free(dns_query_queue[index]->host);
|
||||
delete dns_query_queue[index]->host;
|
||||
|
||||
delete dns_query_queue[index];
|
||||
dns_query_queue[index] = NULL;
|
||||
|
@ -765,8 +854,29 @@ static nsapi_error_t nsapi_dns_query_async_delete(int unique_id)
|
|||
|
||||
static void nsapi_dns_query_async_resp(DNS_QUERY *query, nsapi_error_t status, SocketAddress *address)
|
||||
{
|
||||
query->callback(status, address);
|
||||
NetworkStack::hostbyname_cb_t callback = query->callback;
|
||||
nsapi_dns_query_async_delete(query->unique_id);
|
||||
|
||||
DNS_QUERY *next_query = NULL;
|
||||
int unique_id = INT32_MAX;
|
||||
|
||||
// Find one that has been on queue longest
|
||||
for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) {
|
||||
if (dns_query_queue[i]) {
|
||||
if (dns_query_queue[i]->unique_id <= unique_id) {
|
||||
next_query = dns_query_queue[i];
|
||||
unique_id = dns_query_queue[i]->unique_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (next_query) {
|
||||
nsapi_dns_call_in(next_query->call_in_cb, 0, mbed::callback(nsapi_dns_query_async_create, reinterpret_cast<void *>(next_query->unique_id)));
|
||||
}
|
||||
|
||||
dns_mutex.unlock();
|
||||
|
||||
callback(status, address);
|
||||
}
|
||||
|
||||
static void nsapi_dns_query_async_send(void *ptr)
|
||||
|
@ -798,12 +908,14 @@ static void nsapi_dns_query_async_send(void *ptr)
|
|||
}
|
||||
|
||||
query->dns_message_id = dns_message_id++;
|
||||
if (dns_message_id == 0) {
|
||||
dns_message_id = 1;
|
||||
}
|
||||
|
||||
// create network packet
|
||||
uint8_t *packet = (uint8_t *)malloc(DNS_BUFFER_SIZE);
|
||||
if (!packet) {
|
||||
nsapi_dns_query_async_resp(query, NSAPI_ERROR_NO_MEMORY, NULL);
|
||||
dns_mutex.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -812,11 +924,10 @@ static void nsapi_dns_query_async_send(void *ptr)
|
|||
|
||||
while (true) {
|
||||
SocketAddress dns_addr;
|
||||
nsapi_size_or_error_t err = nsapi_dns_get_server_addr(query->stack, &(query->dns_server), &(query->total_retries), &dns_addr);
|
||||
nsapi_size_or_error_t err = nsapi_dns_get_server_addr(query->stack, &(query->dns_server), &(query->total_attempts), &dns_addr);
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
nsapi_dns_query_async_resp(query, NSAPI_ERROR_DNS_FAILURE, NULL);
|
||||
free(packet);
|
||||
dns_mutex.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -829,21 +940,27 @@ static void nsapi_dns_query_async_send(void *ptr)
|
|||
}
|
||||
}
|
||||
|
||||
if (query->total_retries) {
|
||||
query->total_retries--;
|
||||
if (query->total_attempts) {
|
||||
query->total_attempts--;
|
||||
}
|
||||
|
||||
free(packet);
|
||||
|
||||
if (nsapi_dns_call_in(query->call_in_cb, MBED_CONF_NSAPI_DNS_RESPONSE_WAIT_TIME,
|
||||
mbed::callback(nsapi_dns_query_async_send, reinterpret_cast<void *>(unique_id))) != NSAPI_ERROR_OK) {
|
||||
nsapi_dns_query_async_resp(query, NSAPI_ERROR_NO_MEMORY, NULL);
|
||||
}
|
||||
query->socket_timeout = MBED_CONF_NSAPI_DNS_RESPONSE_WAIT_TIME;
|
||||
|
||||
dns_mutex.unlock();
|
||||
}
|
||||
|
||||
static void nsapi_dns_query_async_socket_callback(NetworkStack *stack)
|
||||
static void nsapi_dns_query_async_socket_callback(void *ptr)
|
||||
{
|
||||
SOCKET_CB_DATA *cb_data = static_cast<SOCKET_CB_DATA *>(ptr);
|
||||
|
||||
if (cb_data) {
|
||||
nsapi_dns_call_in(cb_data->call_in_cb, 0, mbed::callback(nsapi_dns_query_async_socket_callback_handle, cb_data->stack));
|
||||
}
|
||||
}
|
||||
|
||||
static void nsapi_dns_query_async_socket_callback_handle(NetworkStack *stack)
|
||||
{
|
||||
UDPSocket *socket = NULL;
|
||||
|
||||
|
@ -903,6 +1020,8 @@ static void nsapi_dns_query_async_socket_callback(NetworkStack *stack)
|
|||
query->addrs = 0;
|
||||
} else {
|
||||
query->count = resp;
|
||||
query->status = NSAPI_ERROR_DNS_FAILURE; // Used in case failure, otherwise ok
|
||||
query->socket_timeout = 0;
|
||||
nsapi_dns_call_in(query->call_in_cb, 0, mbed::callback(nsapi_dns_query_async_response, reinterpret_cast<void *>(query->unique_id)));
|
||||
}
|
||||
}
|
||||
|
@ -929,8 +1048,11 @@ static void nsapi_dns_query_async_response(void *ptr)
|
|||
}
|
||||
|
||||
if (query) {
|
||||
SocketAddress *addresses = NULL;
|
||||
nsapi_error_t status = query->status; //NSAPI_ERROR_OK;
|
||||
|
||||
if (query->count > 0) {
|
||||
SocketAddress *addresses = new (std::nothrow) SocketAddress[query->count];
|
||||
addresses = new (std::nothrow) SocketAddress[query->count];
|
||||
|
||||
for (int i = 0; i < query->count; i++) {
|
||||
addresses[i].set_addr(query->addrs[i]);
|
||||
|
@ -939,16 +1061,19 @@ static void nsapi_dns_query_async_response(void *ptr)
|
|||
// Adds address to cache
|
||||
nsapi_dns_cache_add(query->host, &(query->addrs[0]), query->ttl);
|
||||
|
||||
nsapi_error_t status = NSAPI_ERROR_OK;
|
||||
status = NSAPI_ERROR_OK;
|
||||
if (query->addr_count > 0) {
|
||||
status = query->count;
|
||||
}
|
||||
nsapi_dns_query_async_resp(query, status, addresses);
|
||||
delete[] addresses;
|
||||
} else {
|
||||
nsapi_dns_query_async_resp(query, NSAPI_ERROR_DNS_FAILURE, NULL);
|
||||
}
|
||||
|
||||
nsapi_dns_query_async_resp(query, status, addresses);
|
||||
|
||||
if (addresses) {
|
||||
delete[] addresses;
|
||||
}
|
||||
} else {
|
||||
dns_mutex.unlock();
|
||||
}
|
||||
dns_mutex.unlock();
|
||||
}
|
||||
|
||||
|
|
|
@ -103,6 +103,13 @@ typedef unsigned int nsapi_size_t;
|
|||
*/
|
||||
typedef signed int nsapi_size_or_error_t;
|
||||
|
||||
/** Type used to represent either a value or error
|
||||
*
|
||||
* A valid nsapi_value_or_error_t is either a non-negative value or a
|
||||
* negative error code from the nsapi_error_t
|
||||
*/
|
||||
typedef signed int nsapi_value_or_error_t;
|
||||
|
||||
/** Enum of encryption types
|
||||
*
|
||||
* The security type specifies a particular security to use when
|
||||
|
|
Loading…
Reference in New Issue