mirror of https://github.com/ARMmbed/mbed-os.git
Corrected defects
- Changed call_in/call methods of the stack to callback provided by the stack - Specified what are limitations for operations that are made in callback - Added pure virtual class DNS that defines DNS operations - Added cancel operation and unique ID to DNS request used in cancel - Added DNS configuration options to netsocket/mbed_lib.json for retries, response wait time and cache size - Changed host name to use dynamic memory in DNS query list and cache, set maximum length for the name to 255 bytes. - Added mutex to asynchronous DNS - Reworked retries: there is now total retry count and a server specific count - Ignores invalid incoming UDP socket messages (DNS header is not valid), and retries DNS query - Reworked DNS module asynchronous operation functions - Corrected other review issues (nothrow new, missing free, missing mutex unlock etc.)pull/6847/head
parent
b7e8400c2c
commit
1c01f5dda4
|
|
@ -207,11 +207,6 @@ void LWIP::tcpip_thread_callback(void *ptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsapi_error_t LWIP::call(mbed::Callback<void()> func)
|
|
||||||
{
|
|
||||||
return call_in(0, func);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsapi_error_t LWIP::call_in(int delay, mbed::Callback<void()> func)
|
nsapi_error_t LWIP::call_in(int delay, mbed::Callback<void()> func)
|
||||||
{
|
{
|
||||||
lwip_callback *cb = new lwip_callback;
|
lwip_callback *cb = new lwip_callback;
|
||||||
|
|
@ -229,6 +224,12 @@ nsapi_error_t LWIP::call_in(int delay, mbed::Callback<void()> func)
|
||||||
return NSAPI_ERROR_OK;
|
return NSAPI_ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LWIP::call_in_callback_cb_t LWIP::get_call_in_callback()
|
||||||
|
{
|
||||||
|
call_in_callback_cb_t cb(this, &LWIP::call_in);
|
||||||
|
return cb;
|
||||||
|
}
|
||||||
|
|
||||||
const char *LWIP::get_ip_address()
|
const char *LWIP::get_ip_address()
|
||||||
{
|
{
|
||||||
if (!default_interface) {
|
if (!default_interface) {
|
||||||
|
|
|
||||||
|
|
@ -209,27 +209,6 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual nsapi_error_t get_dns_server(int index, SocketAddress *address);
|
virtual nsapi_error_t get_dns_server(int index, SocketAddress *address);
|
||||||
|
|
||||||
/** Call a callback
|
|
||||||
*
|
|
||||||
* Call a callback from the network stack context. If returns error
|
|
||||||
* callback will not be called.
|
|
||||||
*
|
|
||||||
* @param func Callback to be called
|
|
||||||
* @return 0 on success, negative error code on failure
|
|
||||||
*/
|
|
||||||
virtual nsapi_error_t call(mbed::Callback<void()> func);
|
|
||||||
|
|
||||||
/** Call a callback after a delay
|
|
||||||
*
|
|
||||||
* Call a callback from the network stack context after a delay. If
|
|
||||||
* returns error callback will not be called.
|
|
||||||
*
|
|
||||||
* @param delay Delay in milliseconds
|
|
||||||
* @param func Callback to be called
|
|
||||||
* @return 0 on success, negative error code on failure
|
|
||||||
*/
|
|
||||||
virtual nsapi_error_t call_in(int delay, mbed::Callback<void()> func);
|
|
||||||
|
|
||||||
/** Get the local IP address
|
/** Get the local IP address
|
||||||
*
|
*
|
||||||
* @return Null-terminated representation of the local IP address
|
* @return Null-terminated representation of the local IP address
|
||||||
|
|
@ -438,6 +417,37 @@ protected:
|
||||||
int optname, void *optval, unsigned *optlen);
|
int optname, void *optval, unsigned *optlen);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/** Call in callback
|
||||||
|
*
|
||||||
|
* Callback is used to call the call in method of the network stack.
|
||||||
|
*/
|
||||||
|
typedef mbed::Callback<nsapi_error_t (int delay_ms, mbed::Callback<void()> user_cb)> call_in_callback_cb_t;
|
||||||
|
|
||||||
|
/** Get a call in callback
|
||||||
|
*
|
||||||
|
* Get a call in callback from the network stack context.
|
||||||
|
*
|
||||||
|
* Callback should not take more than 10ms to execute, otherwise it might
|
||||||
|
* prevent underlying thread processing. A portable user of the callback
|
||||||
|
* should not make calls to network operations due to stack size limitations.
|
||||||
|
* The callback should not perform expensive operations such as socket recv/send
|
||||||
|
* calls or blocking operations.
|
||||||
|
*
|
||||||
|
* @return Call in callback
|
||||||
|
*/
|
||||||
|
virtual call_in_callback_cb_t get_call_in_callback();
|
||||||
|
|
||||||
|
/** Call a callback after a delay
|
||||||
|
*
|
||||||
|
* Call a callback from the network stack context after a delay. If function
|
||||||
|
* returns error callback will not be called.
|
||||||
|
*
|
||||||
|
* @param delay Delay in milliseconds
|
||||||
|
* @param func Callback to be called
|
||||||
|
* @return 0 on success, negative error code on failure
|
||||||
|
*/
|
||||||
|
nsapi_error_t call_in(int delay, mbed::Callback<void()> func);
|
||||||
|
|
||||||
struct mbed_lwip_socket {
|
struct mbed_lwip_socket {
|
||||||
bool in_use;
|
bool in_use;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -482,20 +482,14 @@ void sys_msleep(u32_t ms) {
|
||||||
|
|
||||||
osThreadId_t lwip_tcpip_thread_id = 0;
|
osThreadId_t lwip_tcpip_thread_id = 0;
|
||||||
|
|
||||||
bool sys_tcpip_thread_set(void)
|
void sys_tcpip_thread_set(void)
|
||||||
{
|
{
|
||||||
lwip_tcpip_thread_id = osThreadGetId();
|
lwip_tcpip_thread_id = osThreadGetId();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sys_tcpip_thread_check(void)
|
bool sys_tcpip_thread_check(void)
|
||||||
{
|
{
|
||||||
osThreadId_t thread_id = osThreadGetId();
|
return osThreadGetId() == lwip_tcpip_thread_id;
|
||||||
|
|
||||||
if (thread_id == lwip_tcpip_thread_id) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep a pool of thread structures
|
// Keep a pool of thread structures
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ typedef sys_thread_data_t* sys_thread_t;
|
||||||
// === PROTECTION ===
|
// === PROTECTION ===
|
||||||
typedef int sys_prot_t;
|
typedef int sys_prot_t;
|
||||||
|
|
||||||
bool sys_tcpip_thread_set(void);
|
void sys_tcpip_thread_set(void);
|
||||||
bool sys_tcpip_thread_check(void);
|
bool sys_tcpip_thread_check(void);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
|
|
@ -910,6 +910,8 @@ netconn_join_leave_group(struct netconn *conn,
|
||||||
#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
|
#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
|
||||||
|
|
||||||
#if LWIP_DNS
|
#if LWIP_DNS
|
||||||
|
#if LWIP_FULL_DNS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup netconn_common
|
* @ingroup netconn_common
|
||||||
* Execute a DNS query, only one IP address is returned
|
* Execute a DNS query, only one IP address is returned
|
||||||
|
|
@ -989,6 +991,8 @@ netconn_gethostbyname(const char *name, ip_addr_t *addr)
|
||||||
API_VAR_FREE(MEMP_DNS_API_MSG, msg);
|
API_VAR_FREE(MEMP_DNS_API_MSG, msg);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_FULL_DNS */
|
||||||
#endif /* LWIP_DNS*/
|
#endif /* LWIP_DNS*/
|
||||||
|
|
||||||
#if LWIP_NETCONN_SEM_PER_THREAD
|
#if LWIP_NETCONN_SEM_PER_THREAD
|
||||||
|
|
|
||||||
|
|
@ -1892,6 +1892,7 @@ lwip_netconn_do_join_leave_group(void *m)
|
||||||
#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
|
#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
|
||||||
|
|
||||||
#if LWIP_DNS
|
#if LWIP_DNS
|
||||||
|
#if LWIP_FULL_DNS
|
||||||
/**
|
/**
|
||||||
* Callback function that is called when DNS name is resolved
|
* Callback function that is called when DNS name is resolved
|
||||||
* (or on timeout). A waiting application thread is waked up by
|
* (or on timeout). A waiting application thread is waked up by
|
||||||
|
|
@ -1943,5 +1944,6 @@ lwip_netconn_do_gethostbyname(void *arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* LWIP_DNS */
|
#endif /* LWIP_DNS */
|
||||||
|
#endif /* LWIP_FULL_DNS */
|
||||||
|
|
||||||
#endif /* LWIP_NETCONN */
|
#endif /* LWIP_NETCONN */
|
||||||
|
|
|
||||||
|
|
@ -461,11 +461,6 @@ void Nanostack::call_event_tasklet_main(arm_event_s *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsapi_error_t Nanostack::call(mbed::Callback<void()> func)
|
|
||||||
{
|
|
||||||
return call_in(0, func);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsapi_error_t Nanostack::call_in(int delay, mbed::Callback<void()> func)
|
nsapi_error_t Nanostack::call_in(int delay, mbed::Callback<void()> func)
|
||||||
{
|
{
|
||||||
if (call_event_tasklet < 0) {
|
if (call_event_tasklet < 0) {
|
||||||
|
|
@ -494,10 +489,12 @@ nsapi_error_t Nanostack::call_in(int delay, mbed::Callback<void()> func)
|
||||||
if (delay) {
|
if (delay) {
|
||||||
uint32_t ticks = eventOS_event_timer_ms_to_ticks(delay);
|
uint32_t ticks = eventOS_event_timer_ms_to_ticks(delay);
|
||||||
if (!eventOS_event_send_in(&event, ticks)) {
|
if (!eventOS_event_send_in(&event, ticks)) {
|
||||||
|
delete cb;
|
||||||
return NSAPI_ERROR_NO_MEMORY;
|
return NSAPI_ERROR_NO_MEMORY;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (eventOS_event_send(&event) < 0) {
|
if (eventOS_event_send(&event) < 0) {
|
||||||
|
delete cb;
|
||||||
return NSAPI_ERROR_NO_MEMORY;
|
return NSAPI_ERROR_NO_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -505,6 +502,12 @@ nsapi_error_t Nanostack::call_in(int delay, mbed::Callback<void()> func)
|
||||||
return NSAPI_ERROR_OK;
|
return NSAPI_ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Nanostack::call_in_callback_cb_t Nanostack::get_call_in_callback()
|
||||||
|
{
|
||||||
|
call_in_callback_cb_t cb(this, &Nanostack::call_in);
|
||||||
|
return cb;
|
||||||
|
}
|
||||||
|
|
||||||
const char * Nanostack::get_ip_address()
|
const char * Nanostack::get_ip_address()
|
||||||
{
|
{
|
||||||
NanostackLockGuard lock;
|
NanostackLockGuard lock;
|
||||||
|
|
|
||||||
|
|
@ -44,27 +44,6 @@ public:
|
||||||
/* Local variant with stronger typing and manual address specification */
|
/* Local variant with stronger typing and manual address specification */
|
||||||
nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, Nanostack::EthernetInterface **interface_out, const uint8_t *mac_addr = NULL);
|
nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, Nanostack::EthernetInterface **interface_out, const uint8_t *mac_addr = NULL);
|
||||||
|
|
||||||
/** Call a callback
|
|
||||||
*
|
|
||||||
* Call a callback from the network stack context. If returns error
|
|
||||||
* callback will not be called.
|
|
||||||
*
|
|
||||||
* @param func Callback to be called
|
|
||||||
* @return 0 on success, negative error code on failure
|
|
||||||
*/
|
|
||||||
virtual nsapi_error_t call(mbed::Callback<void()> func);
|
|
||||||
|
|
||||||
/** Call a callback after a delay
|
|
||||||
*
|
|
||||||
* Call a callback from the network stack context after a delay. If
|
|
||||||
* returns error callback will not be called.
|
|
||||||
*
|
|
||||||
* @param delay Delay in milliseconds
|
|
||||||
* @param func Callback to be called
|
|
||||||
* @return 0 on success, negative error code on failure
|
|
||||||
*/
|
|
||||||
virtual nsapi_error_t call_in(int delay, mbed::Callback<void()> func);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Nanostack();
|
Nanostack();
|
||||||
|
|
@ -266,6 +245,38 @@ protected:
|
||||||
virtual nsapi_error_t getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen);
|
virtual nsapi_error_t getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/** Call in callback
|
||||||
|
*
|
||||||
|
* Callback is used to call the call in method of the network stack.
|
||||||
|
*/
|
||||||
|
typedef mbed::Callback<nsapi_error_t (int delay_ms, mbed::Callback<void()> user_cb)> call_in_callback_cb_t;
|
||||||
|
|
||||||
|
/** Get a call in callback
|
||||||
|
*
|
||||||
|
* Get a call in callback from the network stack context.
|
||||||
|
*
|
||||||
|
* Callback should not take more than 10ms to execute, otherwise it might
|
||||||
|
* prevent underlying thread processing. A portable user of the callback
|
||||||
|
* should not make calls to network operations due to stack size limitations.
|
||||||
|
* The callback should not perform expensive operations such as socket recv/send
|
||||||
|
* calls or blocking operations.
|
||||||
|
*
|
||||||
|
* @return Call in callback
|
||||||
|
*/
|
||||||
|
virtual call_in_callback_cb_t get_call_in_callback();
|
||||||
|
|
||||||
|
/** Call a callback after a delay
|
||||||
|
*
|
||||||
|
* Call a callback from the network stack context after a delay. If function
|
||||||
|
* returns error callback will not be called.
|
||||||
|
*
|
||||||
|
* @param delay Delay in milliseconds
|
||||||
|
* @param func Callback to be called
|
||||||
|
* @return 0 on success, negative error code on failure
|
||||||
|
*/
|
||||||
|
nsapi_error_t call_in(int delay, mbed::Callback<void()> func);
|
||||||
|
|
||||||
struct nanostack_callback {
|
struct nanostack_callback {
|
||||||
mbed::Callback<void()> callback;
|
mbed::Callback<void()> callback;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 ARM Limited
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DNS_H
|
||||||
|
#define DNS_H
|
||||||
|
|
||||||
|
class DNS {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** Translates a hostname to an IP address with specific version
|
||||||
|
*
|
||||||
|
* 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 host Hostname to resolve
|
||||||
|
* @param address Destination for the host SocketAddress
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
virtual nsapi_error_t gethostbyname(const char *host,
|
||||||
|
SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC) = 0;
|
||||||
|
|
||||||
|
/** Hostname translation callback (asynchronous)
|
||||||
|
*
|
||||||
|
* Callback will be called after DNS resolution completes or a failure occurs.
|
||||||
|
*
|
||||||
|
* Callback should not take more than 10ms to execute, otherwise it might
|
||||||
|
* prevent underlying thread processing. A portable user of the callback
|
||||||
|
* should not make calls to network operations due to stack size limitations.
|
||||||
|
* The callback should not perform expensive operations such as socket recv/send
|
||||||
|
* calls or blocking operations.
|
||||||
|
*
|
||||||
|
* @param status 0 on success, negative error code on failure
|
||||||
|
* @param address On success, destination for the host SocketAddress
|
||||||
|
*/
|
||||||
|
typedef mbed::Callback<void (nsapi_error_t result, SocketAddress *address)> hostbyname_cb_t;
|
||||||
|
|
||||||
|
/** Translates a hostname to an IP address (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.
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
virtual nsapi_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback,
|
||||||
|
nsapi_version_t version = NSAPI_UNSPEC) = 0;
|
||||||
|
|
||||||
|
/** Cancels asynchronous hostname translation
|
||||||
|
*
|
||||||
|
* When translation is cancelled, callback will not be called.
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
|
||||||
|
/** Add a domain name server to list of servers to query
|
||||||
|
*
|
||||||
|
* @param address Destination for the host address
|
||||||
|
* @return 0 on success, negative error code on failure
|
||||||
|
*/
|
||||||
|
virtual nsapi_error_t add_dns_server(const SocketAddress &address) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -60,9 +60,14 @@ nsapi_error_t NetworkInterface::gethostbyname(const char *name, SocketAddress *a
|
||||||
return get_stack()->gethostbyname(name, address, version);
|
return get_stack()->gethostbyname(name, address, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsapi_error_t NetworkInterface::gethostbyname_async(const char *host, hostbyname_cb_t callback, void *data, nsapi_version_t version)
|
nsapi_error_t NetworkInterface::gethostbyname_async(const char *host, hostbyname_cb_t callback, nsapi_version_t version)
|
||||||
{
|
{
|
||||||
return get_stack()->gethostbyname_async(host, callback, data, version);
|
return get_stack()->gethostbyname_async(host, callback, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsapi_error_t NetworkInterface::gethostbyname_async_cancel(nsapi_error_t handle)
|
||||||
|
{
|
||||||
|
return get_stack()->gethostbyname_async_cancel(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsapi_error_t NetworkInterface::add_dns_server(const SocketAddress &address)
|
nsapi_error_t NetworkInterface::add_dns_server(const SocketAddress &address)
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
#include "netsocket/nsapi_types.h"
|
#include "netsocket/nsapi_types.h"
|
||||||
#include "netsocket/SocketAddress.h"
|
#include "netsocket/SocketAddress.h"
|
||||||
#include "Callback.h"
|
#include "Callback.h"
|
||||||
|
#include "DNS.h"
|
||||||
|
|
||||||
|
|
||||||
// Predeclared classes
|
// Predeclared classes
|
||||||
class NetworkStack;
|
class NetworkStack;
|
||||||
|
|
@ -34,7 +36,7 @@ class EMACInterface;
|
||||||
* Common interface that is shared between network devices
|
* Common interface that is shared between network devices
|
||||||
* @addtogroup netsocket
|
* @addtogroup netsocket
|
||||||
*/
|
*/
|
||||||
class NetworkInterface {
|
class NetworkInterface: public DNS {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -118,8 +120,8 @@ public:
|
||||||
* If no stack-specific DNS resolution is provided, the hostname
|
* If no stack-specific DNS resolution is provided, the hostname
|
||||||
* will be resolve using a UDP socket on the stack.
|
* will be resolve using a UDP socket on the stack.
|
||||||
*
|
*
|
||||||
* @param address Destination for the host SocketAddress
|
|
||||||
* @param host Hostname to resolve
|
* @param host Hostname to resolve
|
||||||
|
* @param address Destination for the host SocketAddress
|
||||||
* @param version IP version of address to resolve, NSAPI_UNSPEC indicates
|
* @param version IP version of address to resolve, NSAPI_UNSPEC indicates
|
||||||
* version is chosen by the stack (defaults to NSAPI_UNSPEC)
|
* version is chosen by the stack (defaults to NSAPI_UNSPEC)
|
||||||
* @return 0 on success, negative error code on failure
|
* @return 0 on success, negative error code on failure
|
||||||
|
|
@ -129,14 +131,18 @@ public:
|
||||||
|
|
||||||
/** Hostname translation callback (asynchronous)
|
/** Hostname translation callback (asynchronous)
|
||||||
*
|
*
|
||||||
* Callback will be called after DNS resolution completes or a failure
|
* Callback will be called after DNS resolution completes or a failure occurs.
|
||||||
* occurs.
|
*
|
||||||
|
* Callback should not take more than 10ms to execute, otherwise it might
|
||||||
|
* prevent underlying thread processing. A portable user of the callback
|
||||||
|
* should not make calls to network operations due to stack size limitations.
|
||||||
|
* The callback should not perform expensive operations such as socket recv/send
|
||||||
|
* calls or blocking operations.
|
||||||
*
|
*
|
||||||
* @param status 0 on success, negative error code on failure
|
* @param status 0 on success, negative error code on failure
|
||||||
* @param address On success, destination for the host SocketAddress
|
* @param address On success, destination for the host SocketAddress
|
||||||
* @param data Caller defined data
|
|
||||||
*/
|
*/
|
||||||
typedef mbed::Callback<void (nsapi_error_t result, SocketAddress *address, void *data)> hostbyname_cb_t;
|
typedef mbed::Callback<void (nsapi_error_t result, SocketAddress *address)> hostbyname_cb_t;
|
||||||
|
|
||||||
/** Translates a hostname to an IP address (asynchronous)
|
/** Translates a hostname to an IP address (asynchronous)
|
||||||
*
|
*
|
||||||
|
|
@ -147,17 +153,29 @@ public:
|
||||||
* will be resolve using a UDP socket on the stack.
|
* will be resolve using a UDP socket on the stack.
|
||||||
*
|
*
|
||||||
* Call is non-blocking. Result of the DNS operation is returned by the callback.
|
* Call is non-blocking. Result of the DNS operation is returned by the callback.
|
||||||
* If this function returns failure, callback will not be called.
|
* 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 host Hostname to resolve
|
||||||
* @param callback Callback that is called for result
|
* @param callback Callback that is called for result
|
||||||
* @param data Caller defined data returned in callback
|
|
||||||
* @param version IP version of address to resolve, NSAPI_UNSPEC indicates
|
* @param version IP version of address to resolve, NSAPI_UNSPEC indicates
|
||||||
* version is chosen by the stack (defaults to NSAPI_UNSPEC)
|
* 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
|
||||||
|
*/
|
||||||
|
virtual nsapi_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback,
|
||||||
|
nsapi_version_t version = NSAPI_UNSPEC);
|
||||||
|
|
||||||
|
/** Cancels asynchronous hostname translation
|
||||||
|
*
|
||||||
|
* When translation is cancelled, callback will not be called.
|
||||||
|
*
|
||||||
|
* @param id Unique id of the hostname translation operation
|
||||||
* @return 0 on success, negative error code on failure
|
* @return 0 on success, negative error code on failure
|
||||||
*/
|
*/
|
||||||
virtual nsapi_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback, void *data,
|
virtual nsapi_error_t gethostbyname_async_cancel(nsapi_error_t id);
|
||||||
nsapi_version_t version = NSAPI_UNSPEC);
|
|
||||||
|
|
||||||
/** Add a domain name server to list of servers to query
|
/** 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);
|
return nsapi_dns_query(this, name, address, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsapi_error_t NetworkStack::gethostbyname_async(const char *name, hostbyname_cb_t callback, void *data, nsapi_version_t version)
|
nsapi_error_t NetworkStack::gethostbyname_async(const char *name, hostbyname_cb_t callback, nsapi_version_t version)
|
||||||
{
|
{
|
||||||
SocketAddress address;
|
SocketAddress address;
|
||||||
|
|
||||||
|
|
@ -59,6 +59,7 @@ nsapi_error_t NetworkStack::gethostbyname_async(const char *name, hostbyname_cb_
|
||||||
return NSAPI_ERROR_DNS_FAILURE;
|
return NSAPI_ERROR_DNS_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callback(NSAPI_ERROR_OK, &address);
|
||||||
return NSAPI_ERROR_OK;
|
return NSAPI_ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,7 +72,14 @@ nsapi_error_t NetworkStack::gethostbyname_async(const char *name, hostbyname_cb_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nsapi_dns_query_async(this, name, callback, data, version);
|
call_in_callback_cb_t call_in_cb = get_call_in_callback();
|
||||||
|
|
||||||
|
return nsapi_dns_query_async(this, name, callback, call_in_cb, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsapi_error_t NetworkStack::gethostbyname_async_cancel(nsapi_error_t handle)
|
||||||
|
{
|
||||||
|
return nsapi_dns_query_async_cancel(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsapi_error_t NetworkStack::add_dns_server(const SocketAddress &address)
|
nsapi_error_t NetworkStack::add_dns_server(const SocketAddress &address)
|
||||||
|
|
@ -104,6 +112,39 @@ nsapi_error_t NetworkStack::getsockopt(void *handle, int level, int optname, voi
|
||||||
return NSAPI_ERROR_UNSUPPORTED;
|
return NSAPI_ERROR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delay > 0) {
|
||||||
|
if (event_queue->call_in(delay, func) == 0) {
|
||||||
|
return NSAPI_ERROR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (event_queue->call(func) == 0) {
|
||||||
|
return NSAPI_ERROR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
// NetworkStackWrapper class for encapsulating the raw nsapi_stack structure
|
||||||
class NetworkStackWrapper : public NetworkStack
|
class NetworkStackWrapper : public NetworkStack
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#include "nsapi_types.h"
|
#include "nsapi_types.h"
|
||||||
#include "netsocket/SocketAddress.h"
|
#include "netsocket/SocketAddress.h"
|
||||||
#include "netsocket/NetworkInterface.h"
|
#include "netsocket/NetworkInterface.h"
|
||||||
|
#include "DNS.h"
|
||||||
|
|
||||||
// Predeclared classes
|
// Predeclared classes
|
||||||
class OnboardNetworkStack;
|
class OnboardNetworkStack;
|
||||||
|
|
@ -33,7 +34,7 @@ class OnboardNetworkStack;
|
||||||
* for instantiating network sockets.
|
* for instantiating network sockets.
|
||||||
* @addtogroup netsocket
|
* @addtogroup netsocket
|
||||||
*/
|
*/
|
||||||
class NetworkStack
|
class NetworkStack: public DNS
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~NetworkStack() {};
|
virtual ~NetworkStack() {};
|
||||||
|
|
@ -64,14 +65,18 @@ public:
|
||||||
|
|
||||||
/** Hostname translation callback (asynchronous)
|
/** Hostname translation callback (asynchronous)
|
||||||
*
|
*
|
||||||
* Callback will be called after DNS resolution completes or a failure
|
* Callback will be called after DNS resolution completes or a failure occurs.
|
||||||
* occurs.
|
*
|
||||||
|
* Callback should not take more than 10ms to execute, otherwise it might
|
||||||
|
* prevent underlying thread processing. A portable user of the callback
|
||||||
|
* should not make calls to network operations due to stack size limitations.
|
||||||
|
* The callback should not perform expensive operations such as socket recv/send
|
||||||
|
* calls or blocking operations.
|
||||||
*
|
*
|
||||||
* @param status 0 on success, negative error code on failure
|
* @param status 0 on success, negative error code on failure
|
||||||
* @param address On success, destination for the host SocketAddress
|
* @param address On success, destination for the host SocketAddress
|
||||||
* @param data Caller defined data
|
|
||||||
*/
|
*/
|
||||||
typedef mbed::Callback<void (nsapi_error_t result, SocketAddress *address, void *data)> hostbyname_cb_t;
|
typedef mbed::Callback<void (nsapi_error_t result, SocketAddress *address)> hostbyname_cb_t;
|
||||||
|
|
||||||
/** Translates a hostname to an IP address (asynchronous)
|
/** Translates a hostname to an IP address (asynchronous)
|
||||||
*
|
*
|
||||||
|
|
@ -82,17 +87,29 @@ public:
|
||||||
* will be resolve using a UDP socket on the stack.
|
* will be resolve using a UDP socket on the stack.
|
||||||
*
|
*
|
||||||
* Call is non-blocking. Result of the DNS operation is returned by the callback.
|
* Call is non-blocking. Result of the DNS operation is returned by the callback.
|
||||||
* If this function returns failure, callback will not be called.
|
* 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 host Hostname to resolve
|
||||||
* @param callback Callback that is called for result
|
* @param callback Callback that is called for result
|
||||||
* @param data Caller defined data returned in callback
|
|
||||||
* @param version IP version of address to resolve, NSAPI_UNSPEC indicates
|
* @param version IP version of address to resolve, NSAPI_UNSPEC indicates
|
||||||
* version is chosen by the stack (defaults to NSAPI_UNSPEC)
|
* 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
|
||||||
|
*/
|
||||||
|
virtual nsapi_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback,
|
||||||
|
nsapi_version_t version = NSAPI_UNSPEC);
|
||||||
|
|
||||||
|
/** Cancels asynchronous hostname translation
|
||||||
|
*
|
||||||
|
* When translation is cancelled, callback will not be called.
|
||||||
|
*
|
||||||
|
* @param id Unique id of the hostname translation operation
|
||||||
* @return 0 on success, negative error code on failure
|
* @return 0 on success, negative error code on failure
|
||||||
*/
|
*/
|
||||||
virtual nsapi_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback, void *data,
|
virtual nsapi_error_t gethostbyname_async_cancel(nsapi_error_t id);
|
||||||
nsapi_version_t version = NSAPI_UNSPEC);
|
|
||||||
|
|
||||||
/** Add a domain name server to list of servers to query
|
/** Add a domain name server to list of servers to query
|
||||||
*
|
*
|
||||||
|
|
@ -347,8 +364,40 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual nsapi_error_t getsockopt(nsapi_socket_t handle, int level,
|
virtual nsapi_error_t getsockopt(nsapi_socket_t handle, int level,
|
||||||
int optname, void *optval, unsigned *optlen);
|
int optname, void *optval, unsigned *optlen);
|
||||||
};
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/** Call in callback
|
||||||
|
*
|
||||||
|
* Callback is used to call the call in method of the network stack.
|
||||||
|
*/
|
||||||
|
typedef mbed::Callback<nsapi_error_t (int delay_ms, mbed::Callback<void()> user_cb)> call_in_callback_cb_t;
|
||||||
|
|
||||||
|
/** Get a call in callback
|
||||||
|
*
|
||||||
|
* Get a call in callback from the network stack context.
|
||||||
|
*
|
||||||
|
* Callback should not take more than 10ms to execute, otherwise it might
|
||||||
|
* prevent underlying thread processing. A portable user of the callback
|
||||||
|
* should not make calls to network operations due to stack size limitations.
|
||||||
|
* The callback should not perform expensive operations such as socket recv/send
|
||||||
|
* calls or blocking operations.
|
||||||
|
*
|
||||||
|
* @return Call in callback
|
||||||
|
*/
|
||||||
|
virtual call_in_callback_cb_t get_call_in_callback();
|
||||||
|
|
||||||
|
/** Call a callback after a delay
|
||||||
|
*
|
||||||
|
* Call a callback from the network stack context after a delay. If function
|
||||||
|
* returns error callback will not be called.
|
||||||
|
*
|
||||||
|
* @param delay Delay in milliseconds
|
||||||
|
* @param func Callback to be called
|
||||||
|
* @return 0 on success, negative error code on failure
|
||||||
|
*/
|
||||||
|
virtual nsapi_error_t call_in(int delay, mbed::Callback<void()> func);
|
||||||
|
};
|
||||||
|
|
||||||
/** Convert a raw nsapi_stack_t object into a C++ NetworkStack object
|
/** Convert a raw nsapi_stack_t object into a C++ NetworkStack object
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,6 @@ public:
|
||||||
*/
|
*/
|
||||||
static OnboardNetworkStack &get_default_instance();
|
static OnboardNetworkStack &get_default_instance();
|
||||||
|
|
||||||
virtual OnboardNetworkStack *onboardNetworkStack() { return this; }
|
|
||||||
|
|
||||||
/** Representation of a stack's view of an interface.
|
/** Representation of a stack's view of an interface.
|
||||||
*
|
*
|
||||||
* Provides facilities required by a driver to implement the application
|
* Provides facilities required by a driver to implement the application
|
||||||
|
|
@ -123,27 +121,6 @@ public:
|
||||||
virtual char *get_gateway(char *buf, nsapi_size_t buflen) = 0;
|
virtual char *get_gateway(char *buf, nsapi_size_t buflen) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Call a callback
|
|
||||||
*
|
|
||||||
* Call a callback from the network stack context. If returns error
|
|
||||||
* callback will not be called.
|
|
||||||
*
|
|
||||||
* @param func Callback to be called
|
|
||||||
* @return 0 on success, negative error code on failure
|
|
||||||
*/
|
|
||||||
virtual nsapi_error_t call(mbed::Callback<void()> func) = 0;
|
|
||||||
|
|
||||||
/** Call a callback after a delay
|
|
||||||
*
|
|
||||||
* Call a callback from the network stack context after a delay. If
|
|
||||||
* returns error callback will not be called.
|
|
||||||
*
|
|
||||||
* @param delay Delay in milliseconds
|
|
||||||
* @param func Callback to be called
|
|
||||||
* @return 0 on success, negative error code on failure
|
|
||||||
*/
|
|
||||||
virtual nsapi_error_t call_in(int delay, mbed::Callback<void()> func) = 0;
|
|
||||||
|
|
||||||
/** Register a network interface with the IP stack
|
/** Register a network interface with the IP stack
|
||||||
*
|
*
|
||||||
* Connects EMAC layer with the IP stack and initializes all the required infrastructure.
|
* Connects EMAC layer with the IP stack and initializes all the required infrastructure.
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,22 @@
|
||||||
"name": "nsapi",
|
"name": "nsapi",
|
||||||
"config": {
|
"config": {
|
||||||
"present": 1,
|
"present": 1,
|
||||||
"default-stack": "LWIP"
|
"default-stack": "LWIP",
|
||||||
|
"dns-response-wait-time": {
|
||||||
|
"help": "How long the DNS translator waits for a reply from a server",
|
||||||
|
"value": 5000
|
||||||
|
},
|
||||||
|
"dns-total-retries": {
|
||||||
|
"help": "Number of total DNS query retries that the DNS translator makes",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
"dns-retries": {
|
||||||
|
"help": "Number of DNS query retries that the DNS translator makes per server",
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"dns-cache-size": {
|
||||||
|
"help": "Number of cached host name resolutions",
|
||||||
|
"value": 3
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,17 +31,32 @@
|
||||||
|
|
||||||
// DNS options
|
// DNS options
|
||||||
#define DNS_BUFFER_SIZE 512
|
#define DNS_BUFFER_SIZE 512
|
||||||
#define DNS_TIMEOUT 5000
|
|
||||||
#define DNS_SERVERS_SIZE 5
|
#define DNS_SERVERS_SIZE 5
|
||||||
#define DNS_RESPONSE_MIN_SIZE 12
|
#define DNS_RESPONSE_MIN_SIZE 12
|
||||||
#define DNS_MAX_TTL 604800
|
#define DNS_MAX_TTL 604800
|
||||||
#define DNS_CACHE_SIZE 3
|
|
||||||
#define DNS_STACK_SERVERS_NUM 5
|
#define DNS_STACK_SERVERS_NUM 5
|
||||||
#define DNS_QUERY_QUEUE_SIZE 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
|
||||||
|
|
||||||
struct DNS_CACHE {
|
struct DNS_CACHE {
|
||||||
SocketAddress address;
|
nsapi_addr_t address;
|
||||||
char host[128];
|
char *host;
|
||||||
uint64_t expires; /*!< time to live in milliseconds */
|
uint64_t expires; /*!< time to live in milliseconds */
|
||||||
uint64_t accessed; /*!< last accessed */
|
uint64_t accessed; /*!< last accessed */
|
||||||
};
|
};
|
||||||
|
|
@ -49,33 +64,35 @@ struct DNS_CACHE {
|
||||||
struct DNS_QUERY {
|
struct DNS_QUERY {
|
||||||
int unique_id;
|
int unique_id;
|
||||||
NetworkStack *stack;
|
NetworkStack *stack;
|
||||||
char host[128];
|
char *host;
|
||||||
NetworkStack::hostbyname_cb_t callback;
|
NetworkStack::hostbyname_cb_t callback;
|
||||||
void *cb_data;
|
call_in_callback_cb_t call_in_cb;
|
||||||
nsapi_size_t addr_count;
|
nsapi_size_t addr_count;
|
||||||
nsapi_version_t version;
|
nsapi_version_t version;
|
||||||
UDPSocket *socket;
|
UDPSocket *socket;
|
||||||
|
nsapi_addr_t *addrs;
|
||||||
int dns_server;
|
int dns_server;
|
||||||
int retries;
|
int retries;
|
||||||
|
int total_retries;
|
||||||
int dns_message_id;
|
int dns_message_id;
|
||||||
|
int count;
|
||||||
|
uint32_t ttl;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef nsapi_error_t (*nsapi_dns_call_t)(mbed::Callback<void()> func);
|
typedef nsapi_error_t (*nsapi_dns_call_t)(mbed::Callback<void()> func);
|
||||||
typedef nsapi_error_t (*nsapi_dns_call_in_t)(int delay, mbed::Callback<void()> func);
|
typedef nsapi_error_t (*nsapi_dns_call_in_t)(int delay, mbed::Callback<void()> func);
|
||||||
|
|
||||||
static void nsapi_dns_cache_add(const char *host, SocketAddress *address, uint32_t ttl);
|
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, SocketAddress *address);
|
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, SocketAddress *dns_addr);
|
static nsapi_error_t nsapi_dns_get_server_addr(NetworkStack *stack, int *index, int *total_retries, SocketAddress *dns_addr);
|
||||||
|
|
||||||
static void nsapi_dns_query_async_create(DNS_QUERY *query);
|
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_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_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(NetworkStack *stack);
|
||||||
static void nsapi_dns_query_async_socket_callback_handle(NetworkStack *stack);
|
static void nsapi_dns_query_async_response(void *ptr);
|
||||||
|
|
||||||
static nsapi_error_t nsapi_dns_call_default(mbed::Callback<void()> func);
|
|
||||||
static nsapi_error_t nsapi_dns_call_in_default(int delay, mbed::Callback<void()> func);
|
|
||||||
|
|
||||||
static nsapi_addr_t dns_servers[DNS_SERVERS_SIZE] = {
|
static nsapi_addr_t dns_servers[DNS_SERVERS_SIZE] = {
|
||||||
{NSAPI_IPv4, {8, 8, 8, 8}}, // Google
|
{NSAPI_IPv4, {8, 8, 8, 8}}, // Google
|
||||||
|
|
@ -87,13 +104,15 @@ static nsapi_addr_t dns_servers[DNS_SERVERS_SIZE] = {
|
||||||
0,0, 0,0, 0x1c,0x04, 0xb1,0x2f}},
|
0,0, 0,0, 0x1c,0x04, 0xb1,0x2f}},
|
||||||
};
|
};
|
||||||
|
|
||||||
static DNS_CACHE *dns_cache[DNS_CACHE_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 = 0;
|
||||||
static int dns_unique_id = 0;
|
static int dns_unique_id = 1;
|
||||||
static DNS_QUERY *dns_query_queue[DNS_QUERY_QUEUE_SIZE];
|
static DNS_QUERY *dns_query_queue[DNS_QUERY_QUEUE_SIZE];
|
||||||
|
// Protects cache shared between blocking and asynchronous calls
|
||||||
static rtos::Mutex dns_cache_mutex;
|
static rtos::Mutex dns_cache_mutex;
|
||||||
static nsapi_dns_call_t dns_call = nsapi_dns_call_default;
|
// Protects from several threads running asynchronous DNS
|
||||||
static nsapi_dns_call_in_t dns_call_in = nsapi_dns_call_in_default;
|
static rtos::Mutex dns_mutex;
|
||||||
|
static nsapi_dns_call_in_t dns_call_in = 0;
|
||||||
|
|
||||||
// DNS server configuration
|
// DNS server configuration
|
||||||
extern "C" nsapi_error_t nsapi_dns_add_server(nsapi_addr_t addr)
|
extern "C" nsapi_error_t nsapi_dns_add_server(nsapi_addr_t addr)
|
||||||
|
|
@ -199,7 +218,7 @@ static int dns_scan_response(const uint8_t *ptr, uint16_t exp_id, uint32_t *ttl,
|
||||||
|
|
||||||
// verify header is response to query
|
// verify header is response to query
|
||||||
if (!(id == exp_id && qr && opcode == 0 && rcode == 0)) {
|
if (!(id == exp_id && qr && opcode == 0 && rcode == 0)) {
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip questions
|
// skip questions
|
||||||
|
|
@ -273,7 +292,7 @@ static int dns_scan_response(const uint8_t *ptr, uint16_t exp_id, uint32_t *ttl,
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nsapi_dns_cache_add(const char *host, SocketAddress *address, 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
|
// RFC 1034: if TTL is zero, entry is not added to cache
|
||||||
if (!ttl) {
|
if (!ttl) {
|
||||||
|
|
@ -281,17 +300,17 @@ static void nsapi_dns_cache_add(const char *host, SocketAddress *address, uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if already cached
|
// Checks if already cached
|
||||||
if (nsapi_dns_cache_find(host, address->get_ip_version(), NULL) == NSAPI_ERROR_OK) {
|
if (nsapi_dns_cache_find(host, address->version, NULL) == NSAPI_ERROR_OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_cache_mutex.lock();
|
dns_cache_mutex.lock();
|
||||||
|
|
||||||
int index = -1;
|
int index = -1;
|
||||||
uint64_t accessed = -1;
|
uint64_t accessed = ~0;
|
||||||
|
|
||||||
// Finds free or last accessed entry
|
// Finds free or last accessed entry
|
||||||
for (int i = 0; i < DNS_CACHE_SIZE; i++) {
|
for (int i = 0; i < MBED_CONF_NSAPI_DNS_CACHE_SIZE; i++) {
|
||||||
if (!dns_cache[i]) {
|
if (!dns_cache[i]) {
|
||||||
index = i;
|
index = i;
|
||||||
break;
|
break;
|
||||||
|
|
@ -302,17 +321,21 @@ static void nsapi_dns_cache_add(const char *host, SocketAddress *address, uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
|
dns_cache_mutex.unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocates in case entry is free, otherwise reuses
|
// Allocates in case entry is free, otherwise reuses
|
||||||
if (!dns_cache[index]) {
|
if (!dns_cache[index]) {
|
||||||
dns_cache[index] = new DNS_CACHE;
|
dns_cache[index] = new (std::nothrow) DNS_CACHE;
|
||||||
|
} else {
|
||||||
|
free(dns_cache[index]->host);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dns_cache[index]) {
|
if (dns_cache[index]) {
|
||||||
dns_cache[index]->address = *address;
|
dns_cache[index]->address = *address;
|
||||||
strncpy(dns_cache[index]->host, host, 127);
|
dns_cache[index]->host = (char *) malloc(strlen(host) + 1);
|
||||||
|
strcpy(dns_cache[index]->host, host);
|
||||||
uint64_t ms_count = rtos::Kernel::get_ms_count();
|
uint64_t ms_count = rtos::Kernel::get_ms_count();
|
||||||
dns_cache[index]->expires = ms_count + ttl * 1000;
|
dns_cache[index]->expires = ms_count + ttl * 1000;
|
||||||
dns_cache[index]->accessed = ms_count;
|
dns_cache[index]->accessed = ms_count;
|
||||||
|
|
@ -321,21 +344,22 @@ static void nsapi_dns_cache_add(const char *host, SocketAddress *address, uint32
|
||||||
dns_cache_mutex.unlock();
|
dns_cache_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static nsapi_error_t nsapi_dns_cache_find(const char *host, nsapi_version_t version, SocketAddress *address)
|
static nsapi_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;
|
nsapi_error_t ret_val = NSAPI_ERROR_NO_ADDRESS;
|
||||||
|
|
||||||
dns_cache_mutex.lock();
|
dns_cache_mutex.lock();
|
||||||
|
|
||||||
for (int i = 0; i < DNS_CACHE_SIZE; i++) {
|
for (int i = 0; i < MBED_CONF_NSAPI_DNS_CACHE_SIZE; i++) {
|
||||||
if (dns_cache[i]) {
|
if (dns_cache[i]) {
|
||||||
uint64_t ms_count = rtos::Kernel::get_ms_count();
|
uint64_t ms_count = rtos::Kernel::get_ms_count();
|
||||||
// Checks all entries for expired entries
|
// Checks all entries for expired entries
|
||||||
if (ms_count > dns_cache[i]->expires) {
|
if (ms_count > dns_cache[i]->expires) {
|
||||||
|
free(dns_cache[i]->host);
|
||||||
delete dns_cache[i];
|
delete dns_cache[i];
|
||||||
dns_cache[i] = NULL;
|
dns_cache[i] = NULL;
|
||||||
} else if (((version == NSAPI_UNSPEC) || (version == dns_cache[i]->address.get_ip_version())) &&
|
} else if ((version == NSAPI_UNSPEC || version == dns_cache[i]->address.version) &&
|
||||||
(strncmp(dns_cache[i]->host, host, 127) == 0)) {
|
strcmp(dns_cache[i]->host, host) == 0) {
|
||||||
if (address) {
|
if (address) {
|
||||||
*address = dns_cache[i]->address;
|
*address = dns_cache[i]->address;
|
||||||
}
|
}
|
||||||
|
|
@ -350,14 +374,22 @@ static nsapi_error_t nsapi_dns_cache_find(const char *host, nsapi_version_t vers
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static nsapi_error_t nsapi_dns_get_server_addr(NetworkStack *stack, int *index, SocketAddress *dns_addr)
|
static nsapi_error_t nsapi_dns_get_server_addr(NetworkStack *stack, int *index, int *total_retries, SocketAddress *dns_addr)
|
||||||
{
|
{
|
||||||
bool dns_addr_set = false;
|
bool dns_addr_set = false;
|
||||||
|
|
||||||
if (*index >= DNS_SERVERS_SIZE + DNS_STACK_SERVERS_NUM) {
|
if (*total_retries == 0) {
|
||||||
return NSAPI_ERROR_NO_ADDRESS;
|
return NSAPI_ERROR_NO_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*index >= DNS_SERVERS_SIZE + DNS_STACK_SERVERS_NUM) {
|
||||||
|
if (*total_retries) {
|
||||||
|
*index = 0;
|
||||||
|
} else {
|
||||||
|
return NSAPI_ERROR_NO_ADDRESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (*index < DNS_STACK_SERVERS_NUM) {
|
if (*index < DNS_STACK_SERVERS_NUM) {
|
||||||
nsapi_error_t ret = stack->get_dns_server(*index, dns_addr);
|
nsapi_error_t ret = stack->get_dns_server(*index, dns_addr);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
|
@ -382,14 +414,12 @@ static nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const
|
||||||
{
|
{
|
||||||
// check for valid host name
|
// check for valid host name
|
||||||
int host_len = host ? strlen(host) : 0;
|
int host_len = host ? strlen(host) : 0;
|
||||||
if (host_len > 128 || host_len == 0) {
|
if (host_len > DNS_HOST_NAME_MAX_LEN || host_len == 0) {
|
||||||
return NSAPI_ERROR_PARAMETER;
|
return NSAPI_ERROR_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check cache
|
// check cache
|
||||||
SocketAddress address;
|
if (nsapi_dns_cache_find(host, version, addr) == NSAPI_ERROR_OK) {
|
||||||
if (nsapi_dns_cache_find(host, version, &address) == NSAPI_ERROR_OK) {
|
|
||||||
*addr = address.get_addr();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -400,7 +430,7 @@ static nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.set_timeout(DNS_TIMEOUT);
|
socket.set_timeout(MBED_CONF_NSAPI_DNS_RESPONSE_WAIT_TIME);
|
||||||
|
|
||||||
// create network packet
|
// create network packet
|
||||||
uint8_t * const packet = (uint8_t *)malloc(DNS_BUFFER_SIZE);
|
uint8_t * const packet = (uint8_t *)malloc(DNS_BUFFER_SIZE);
|
||||||
|
|
@ -410,14 +440,15 @@ static nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const
|
||||||
|
|
||||||
nsapi_size_or_error_t result = NSAPI_ERROR_DNS_FAILURE;
|
nsapi_size_or_error_t result = NSAPI_ERROR_DNS_FAILURE;
|
||||||
|
|
||||||
bool retry = false;
|
int retries = MBED_CONF_NSAPI_DNS_RETRIES;
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
int total_retries = MBED_CONF_NSAPI_DNS_TOTAL_RETRIES;
|
||||||
|
|
||||||
// check against each dns server
|
// check against each dns server
|
||||||
while (true) {
|
while (true) {
|
||||||
SocketAddress dns_addr;
|
SocketAddress dns_addr;
|
||||||
err = nsapi_dns_get_server_addr(stack, &index, &dns_addr);
|
err = nsapi_dns_get_server_addr(stack, &index, &total_retries, &dns_addr);
|
||||||
if (err != NSAPI_ERROR_OK) {
|
if (err != NSAPI_ERROR_OK) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -429,20 +460,24 @@ static nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const
|
||||||
// send may fail for various reasons, including wrong address type - move on
|
// send may fail for various reasons, including wrong address type - move on
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
// goes to next dns server
|
// goes to next dns server
|
||||||
retry = false;
|
retries = MBED_CONF_NSAPI_DNS_RETRIES;
|
||||||
index++;
|
index++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (total_retries) {
|
||||||
|
total_retries--;
|
||||||
|
}
|
||||||
|
|
||||||
// recv the response
|
// recv the response
|
||||||
err = socket.recvfrom(NULL, packet, DNS_BUFFER_SIZE);
|
err = socket.recvfrom(NULL, packet, DNS_BUFFER_SIZE);
|
||||||
if (err == NSAPI_ERROR_WOULD_BLOCK) {
|
if (err == NSAPI_ERROR_WOULD_BLOCK) {
|
||||||
if (!retry) {
|
if (retries) {
|
||||||
// retries once
|
// retries
|
||||||
retry = true;
|
retries--;
|
||||||
} else {
|
} else {
|
||||||
// goes to next dns server
|
// goes to next dns server
|
||||||
retry = false;
|
retries = MBED_CONF_NSAPI_DNS_RETRIES;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -453,13 +488,12 @@ static nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const
|
||||||
|
|
||||||
const uint8_t *response = packet;
|
const uint8_t *response = packet;
|
||||||
uint32_t ttl;
|
uint32_t ttl;
|
||||||
int count = dns_scan_response(response, 1, &ttl, addr, addr_count);
|
int resp = dns_scan_response(response, 1, &ttl, addr, addr_count);
|
||||||
if (count > 0) {
|
if (resp > 0) {
|
||||||
// Adds address to cache
|
nsapi_dns_cache_add(host, addr, ttl);
|
||||||
SocketAddress address(*addr);
|
result = resp;
|
||||||
nsapi_dns_cache_add(host, &address, ttl);
|
} else if (resp < 0) {
|
||||||
|
continue;
|
||||||
result = count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The DNS response is final, no need to check other servers */
|
/* The DNS response is final, no need to check other servers */
|
||||||
|
|
@ -490,7 +524,7 @@ extern "C" nsapi_size_or_error_t nsapi_dns_query_multiple(nsapi_stack_t *stack,
|
||||||
nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const char *host,
|
nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const char *host,
|
||||||
SocketAddress *addresses, nsapi_size_t addr_count, nsapi_version_t version)
|
SocketAddress *addresses, nsapi_size_t addr_count, nsapi_version_t version)
|
||||||
{
|
{
|
||||||
nsapi_addr_t *addrs = new nsapi_addr_t[addr_count];
|
nsapi_addr_t *addrs = new (std::nothrow) nsapi_addr_t[addr_count];
|
||||||
nsapi_size_or_error_t result = nsapi_dns_query_multiple(stack, host, addrs, addr_count, version);
|
nsapi_size_or_error_t result = nsapi_dns_query_multiple(stack, host, addrs, addr_count, version);
|
||||||
|
|
||||||
if (result > 0) {
|
if (result > 0) {
|
||||||
|
|
@ -521,39 +555,10 @@ nsapi_error_t nsapi_dns_query(NetworkStack *stack, const char *host,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsapi_error_t nsapi_dns_query_async(NetworkStack *stack, const char *host,
|
nsapi_error_t nsapi_dns_query_async(NetworkStack *stack, const char *host,
|
||||||
NetworkStack::hostbyname_cb_t callback, void *data, nsapi_version_t version)
|
NetworkStack::hostbyname_cb_t callback, call_in_callback_cb_t call_in_cb,
|
||||||
|
nsapi_version_t version)
|
||||||
{
|
{
|
||||||
nsapi_size_or_error_t result = nsapi_dns_query_multiple_async(stack, host, callback, data, 1, version);
|
return nsapi_dns_query_multiple_async(stack, host, callback, 0, call_in_cb, version);
|
||||||
return (nsapi_error_t)((result > 0) ? 0 : result);
|
|
||||||
}
|
|
||||||
|
|
||||||
static nsapi_error_t nsapi_dns_call_default(mbed::Callback<void()> func)
|
|
||||||
{
|
|
||||||
events::EventQueue *event_queue = mbed::mbed_event_queue();
|
|
||||||
if (!event_queue) {
|
|
||||||
return NSAPI_ERROR_NO_MEMORY;
|
|
||||||
}
|
|
||||||
if (event_queue->call(func) == 0) {
|
|
||||||
return NSAPI_ERROR_NO_MEMORY;
|
|
||||||
}
|
|
||||||
return NSAPI_ERROR_OK ;
|
|
||||||
}
|
|
||||||
|
|
||||||
static nsapi_error_t nsapi_dns_call_in_default(int delay, mbed::Callback<void()> func)
|
|
||||||
{
|
|
||||||
events::EventQueue *event_queue = mbed::mbed_event_queue();
|
|
||||||
if (!event_queue) {
|
|
||||||
return NSAPI_ERROR_NO_MEMORY;
|
|
||||||
}
|
|
||||||
if (event_queue->call_in(delay, func) == 0) {
|
|
||||||
return NSAPI_ERROR_NO_MEMORY;
|
|
||||||
}
|
|
||||||
return NSAPI_ERROR_OK ;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsapi_dns_call_set(nsapi_dns_call_t callback)
|
|
||||||
{
|
|
||||||
dns_call = callback;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsapi_dns_call_in_set(nsapi_dns_call_in_t callback)
|
void nsapi_dns_call_in_set(nsapi_dns_call_in_t callback)
|
||||||
|
|
@ -561,32 +566,19 @@ void nsapi_dns_call_in_set(nsapi_dns_call_in_t callback)
|
||||||
dns_call_in = callback;
|
dns_call_in = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
static nsapi_error_t nsapi_dns_call(NetworkStack *stack, mbed::Callback<void()> func)
|
nsapi_error_t nsapi_dns_call_in(call_in_callback_cb_t cb, int delay, mbed::Callback<void()> func)
|
||||||
{
|
{
|
||||||
if (stack->onboardNetworkStack()) {
|
if (dns_call_in) {
|
||||||
OnboardNetworkStack *onboard_stack = reinterpret_cast<OnboardNetworkStack *>(stack);
|
|
||||||
return onboard_stack->call(func);
|
|
||||||
} else {
|
|
||||||
dns_call(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NSAPI_ERROR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static nsapi_error_t nsapi_dns_call_in(NetworkStack *stack, int delay, mbed::Callback<void()> func)
|
|
||||||
{
|
|
||||||
if (stack->onboardNetworkStack()) {
|
|
||||||
OnboardNetworkStack *onboard_stack = reinterpret_cast<OnboardNetworkStack *>(stack);
|
|
||||||
return onboard_stack->call_in(delay, func);
|
|
||||||
} else {
|
|
||||||
dns_call_in(delay, func);
|
dns_call_in(delay, func);
|
||||||
|
} else {
|
||||||
|
return cb(delay, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NSAPI_ERROR_OK;
|
return NSAPI_ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsapi_error_t nsapi_dns_query_multiple_async(NetworkStack *stack, const char *host,
|
nsapi_error_t nsapi_dns_query_multiple_async(NetworkStack *stack, const char *host,
|
||||||
NetworkStack::hostbyname_cb_t callback, void *data, nsapi_size_t addr_count, nsapi_version_t version)
|
NetworkStack::hostbyname_cb_t callback, nsapi_size_t addr_count,
|
||||||
|
call_in_callback_cb_t call_in_cb, nsapi_version_t version)
|
||||||
{
|
{
|
||||||
if (!stack) {
|
if (!stack) {
|
||||||
return NSAPI_ERROR_PARAMETER;
|
return NSAPI_ERROR_PARAMETER;
|
||||||
|
|
@ -594,129 +586,87 @@ nsapi_error_t nsapi_dns_query_multiple_async(NetworkStack *stack, const char *ho
|
||||||
|
|
||||||
// check for valid host name
|
// check for valid host name
|
||||||
int host_len = host ? strlen(host) : 0;
|
int host_len = host ? strlen(host) : 0;
|
||||||
if (host_len > 128 || host_len == 0) {
|
if (host_len > DNS_HOST_NAME_MAX_LEN || host_len == 0) {
|
||||||
return NSAPI_ERROR_PARAMETER;
|
return NSAPI_ERROR_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
DNS_QUERY *query = new DNS_QUERY;
|
nsapi_addr address;
|
||||||
|
if (nsapi_dns_cache_find(host, version, &address) == NSAPI_ERROR_OK) {
|
||||||
|
SocketAddress addr(address);
|
||||||
|
callback(NSAPI_ERROR_OK, &addr);
|
||||||
|
return NSAPI_ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (!query) {
|
dns_mutex.lock();
|
||||||
|
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) {
|
||||||
|
if (!dns_query_queue[i]) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < 0) {
|
||||||
|
dns_mutex.unlock();
|
||||||
return NSAPI_ERROR_NO_MEMORY;
|
return NSAPI_ERROR_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
query->unique_id = 0;
|
DNS_QUERY *query = new (std::nothrow) DNS_QUERY;
|
||||||
|
|
||||||
|
if (!query) {
|
||||||
|
dns_mutex.unlock();
|
||||||
|
return NSAPI_ERROR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
query->host = (char *) malloc(host_len + 1);
|
||||||
strcpy(query->host, host);
|
strcpy(query->host, host);
|
||||||
query->callback = callback;
|
query->callback = callback;
|
||||||
query->cb_data = data;
|
query->call_in_cb = call_in_cb;
|
||||||
query->stack = stack;
|
query->stack = stack;
|
||||||
query->addr_count = addr_count;
|
query->addr_count = addr_count;
|
||||||
query->version = version;
|
query->version = version;
|
||||||
query->socket = NULL;
|
query->socket = NULL;
|
||||||
|
query->addrs = NULL;
|
||||||
query->dns_server = 0;
|
query->dns_server = 0;
|
||||||
query->retries = 2;
|
query->retries = MBED_CONF_NSAPI_DNS_RETRIES + 1;
|
||||||
|
query->total_retries = MBED_CONF_NSAPI_DNS_TOTAL_RETRIES;
|
||||||
query->dns_message_id = -1;
|
query->dns_message_id = -1;
|
||||||
|
|
||||||
if (nsapi_dns_call(stack, mbed::callback(nsapi_dns_query_async_create, query)) != NSAPI_ERROR_OK) {
|
|
||||||
delete query;
|
|
||||||
return NSAPI_ERROR_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NSAPI_ERROR_IN_PROGRESS ;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nsapi_dns_query_async_create(DNS_QUERY *query)
|
|
||||||
{
|
|
||||||
SocketAddress address;
|
|
||||||
if (nsapi_dns_cache_find(query->host, query->version, &address) == NSAPI_ERROR_OK) {
|
|
||||||
nsapi_dns_query_async_resp(query, NSAPI_ERROR_OK, &address);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int index = -1;
|
|
||||||
|
|
||||||
for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) {
|
|
||||||
if (dns_query_queue[i]) {
|
|
||||||
if (dns_query_queue[i]->stack == query->stack) {
|
|
||||||
query->socket = dns_query_queue[i]->socket;
|
|
||||||
}
|
|
||||||
} else if (index < 0) {
|
|
||||||
index = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index < 0) {
|
|
||||||
nsapi_dns_query_async_resp(query, NSAPI_ERROR_NO_MEMORY, NULL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UDPSocket *socket;
|
|
||||||
|
|
||||||
if (query->socket) {
|
|
||||||
socket = query->socket;
|
|
||||||
} else {
|
|
||||||
socket = new UDPSocket;
|
|
||||||
if (!socket) {
|
|
||||||
nsapi_dns_query_async_resp(query, NSAPI_ERROR_NO_MEMORY, NULL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int err = socket->open(query->stack);
|
|
||||||
if (err) {
|
|
||||||
delete socket;
|
|
||||||
nsapi_dns_query_async_resp(query, err, NULL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket->set_timeout(0);
|
|
||||||
socket->sigio(mbed::callback(nsapi_dns_query_async_socket_callback, query->stack));
|
|
||||||
|
|
||||||
query->socket = socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
query->unique_id = dns_unique_id++;
|
query->unique_id = dns_unique_id++;
|
||||||
|
if (query->unique_id > 0x7FFF) {
|
||||||
|
query->unique_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
dns_query_queue[index] = query;
|
dns_query_queue[index] = query;
|
||||||
|
|
||||||
nsapi_dns_query_async_send(reinterpret_cast<void *>(query->unique_id));
|
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;
|
||||||
static void nsapi_dns_query_async_delete(DNS_QUERY *query)
|
|
||||||
{
|
|
||||||
int index = -1;
|
|
||||||
bool close_socket = true;
|
|
||||||
|
|
||||||
for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) {
|
|
||||||
if (dns_query_queue[i]) {
|
|
||||||
if (dns_query_queue[i] == query) {
|
|
||||||
index = i;
|
|
||||||
} else if (dns_query_queue[i]->stack == query->stack) {
|
|
||||||
close_socket = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index < 0) {
|
dns_mutex.unlock();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (close_socket) {
|
return query->unique_id;
|
||||||
query->socket->close();
|
|
||||||
delete query->socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
dns_query_queue[index] = NULL;
|
|
||||||
delete query;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nsapi_dns_query_async_resp(DNS_QUERY *query, nsapi_error_t status, SocketAddress *address)
|
nsapi_error_t nsapi_dns_query_async_cancel(nsapi_error_t id)
|
||||||
{
|
{
|
||||||
query->callback(status, address, query->cb_data);
|
dns_mutex.lock();
|
||||||
nsapi_dns_query_async_delete(query);
|
|
||||||
|
nsapi_error_t ret = nsapi_dns_query_async_delete(id);
|
||||||
|
|
||||||
|
dns_mutex.unlock();
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nsapi_dns_query_async_send(void *ptr)
|
static void nsapi_dns_query_async_create(void *ptr)
|
||||||
{
|
{
|
||||||
|
dns_mutex.lock();
|
||||||
|
|
||||||
int unique_id = reinterpret_cast<int>(ptr);
|
int unique_id = reinterpret_cast<int>(ptr);
|
||||||
|
|
||||||
DNS_QUERY *query = NULL;
|
DNS_QUERY *query = NULL;
|
||||||
|
|
@ -729,7 +679,114 @@ static void nsapi_dns_query_async_send(void *ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!query) {
|
if (!query) {
|
||||||
nsapi_dns_query_async_resp(query, NSAPI_ERROR_NO_MEMORY, NULL);
|
// Cancel has been called
|
||||||
|
dns_mutex.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
query->socket = dns_query_queue[i]->socket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UDPSocket *socket;
|
||||||
|
|
||||||
|
if (query->socket) {
|
||||||
|
socket = query->socket;
|
||||||
|
} else {
|
||||||
|
socket = new (std::nothrow) UDPSocket;
|
||||||
|
if (!socket) {
|
||||||
|
nsapi_dns_query_async_resp(query, NSAPI_ERROR_NO_MEMORY, NULL);
|
||||||
|
dns_mutex.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int err = socket->open(query->stack);
|
||||||
|
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));
|
||||||
|
|
||||||
|
query->socket = socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_mutex.unlock();
|
||||||
|
|
||||||
|
nsapi_dns_query_async_send(reinterpret_cast<void *>(query->unique_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
static nsapi_error_t nsapi_dns_query_async_delete(int unique_id)
|
||||||
|
{
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) {
|
||||||
|
if (dns_query_queue[i] && dns_query_queue[i]->unique_id == unique_id) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < 0) {
|
||||||
|
return NSAPI_ERROR_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool close_socket = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) {
|
||||||
|
if (i != index && dns_query_queue[i] && dns_query_queue[i]->socket &&
|
||||||
|
dns_query_queue[i]->stack == dns_query_queue[index]->stack) {
|
||||||
|
close_socket = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (close_socket && dns_query_queue[index]->socket) {
|
||||||
|
dns_query_queue[index]->socket->close();
|
||||||
|
delete dns_query_queue[index]->socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dns_query_queue[index]->addrs) {
|
||||||
|
delete[] dns_query_queue[index]->addrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(dns_query_queue[index]->host);
|
||||||
|
|
||||||
|
delete dns_query_queue[index];
|
||||||
|
dns_query_queue[index] = NULL;
|
||||||
|
return NSAPI_ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nsapi_dns_query_async_resp(DNS_QUERY *query, nsapi_error_t status, SocketAddress *address)
|
||||||
|
{
|
||||||
|
query->callback(status, address);
|
||||||
|
nsapi_dns_query_async_delete(query->unique_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nsapi_dns_query_async_send(void *ptr)
|
||||||
|
{
|
||||||
|
dns_mutex.lock();
|
||||||
|
|
||||||
|
int unique_id = reinterpret_cast<int>(ptr);
|
||||||
|
|
||||||
|
DNS_QUERY *query = NULL;
|
||||||
|
|
||||||
|
for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) {
|
||||||
|
if (dns_query_queue[i] && dns_query_queue[i]->unique_id == unique_id) {
|
||||||
|
query = dns_query_queue[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query) {
|
||||||
|
// Cancel has been called
|
||||||
|
dns_mutex.unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -737,7 +794,7 @@ static void nsapi_dns_query_async_send(void *ptr)
|
||||||
query->retries--;
|
query->retries--;
|
||||||
} else {
|
} else {
|
||||||
query->dns_server++;
|
query->dns_server++;
|
||||||
query->retries = 1;
|
query->retries = MBED_CONF_NSAPI_DNS_RETRIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
query->dns_message_id = dns_message_id++;
|
query->dns_message_id = dns_message_id++;
|
||||||
|
|
@ -746,6 +803,7 @@ static void nsapi_dns_query_async_send(void *ptr)
|
||||||
uint8_t *packet = (uint8_t *)malloc(DNS_BUFFER_SIZE);
|
uint8_t *packet = (uint8_t *)malloc(DNS_BUFFER_SIZE);
|
||||||
if (!packet) {
|
if (!packet) {
|
||||||
nsapi_dns_query_async_resp(query, NSAPI_ERROR_NO_MEMORY, NULL);
|
nsapi_dns_query_async_resp(query, NSAPI_ERROR_NO_MEMORY, NULL);
|
||||||
|
dns_mutex.unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -754,10 +812,11 @@ static void nsapi_dns_query_async_send(void *ptr)
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
SocketAddress dns_addr;
|
SocketAddress dns_addr;
|
||||||
nsapi_size_or_error_t err = nsapi_dns_get_server_addr(query->stack, &(query->dns_server), &dns_addr);
|
nsapi_size_or_error_t err = nsapi_dns_get_server_addr(query->stack, &(query->dns_server), &(query->total_retries), &dns_addr);
|
||||||
if (err != NSAPI_ERROR_OK) {
|
if (err != NSAPI_ERROR_OK) {
|
||||||
nsapi_dns_query_async_resp(query, NSAPI_ERROR_DNS_FAILURE, NULL);
|
nsapi_dns_query_async_resp(query, NSAPI_ERROR_DNS_FAILURE, NULL);
|
||||||
free(packet);
|
free(packet);
|
||||||
|
dns_mutex.unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -770,23 +829,26 @@ static void nsapi_dns_query_async_send(void *ptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (query->total_retries) {
|
||||||
|
query->total_retries--;
|
||||||
|
}
|
||||||
|
|
||||||
free(packet);
|
free(packet);
|
||||||
|
|
||||||
if (nsapi_dns_call_in(query->stack, DNS_TIMEOUT,
|
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) {
|
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);
|
nsapi_dns_query_async_resp(query, NSAPI_ERROR_NO_MEMORY, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dns_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nsapi_dns_query_async_socket_callback(NetworkStack *stack)
|
static void nsapi_dns_query_async_socket_callback(NetworkStack *stack)
|
||||||
{
|
|
||||||
nsapi_dns_call(stack, mbed::callback(nsapi_dns_query_async_socket_callback_handle, stack));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nsapi_dns_query_async_socket_callback_handle(NetworkStack *stack)
|
|
||||||
{
|
{
|
||||||
UDPSocket *socket = NULL;
|
UDPSocket *socket = NULL;
|
||||||
|
|
||||||
|
dns_mutex.lock();
|
||||||
|
|
||||||
for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) {
|
for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) {
|
||||||
if (dns_query_queue[i] && dns_query_queue[i]->stack == stack) {
|
if (dns_query_queue[i] && dns_query_queue[i]->stack == stack) {
|
||||||
socket = dns_query_queue[i]->socket;
|
socket = dns_query_queue[i]->socket;
|
||||||
|
|
@ -798,58 +860,95 @@ static void nsapi_dns_query_async_socket_callback_handle(NetworkStack *stack)
|
||||||
// create network packet
|
// create network packet
|
||||||
uint8_t *packet = (uint8_t *)malloc(DNS_BUFFER_SIZE);
|
uint8_t *packet = (uint8_t *)malloc(DNS_BUFFER_SIZE);
|
||||||
if (!packet) {
|
if (!packet) {
|
||||||
|
dns_mutex.unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// recv the response
|
while (true) {
|
||||||
nsapi_size_or_error_t size = socket->recvfrom(NULL, packet, DNS_BUFFER_SIZE);
|
// recv the response
|
||||||
|
nsapi_size_or_error_t size = socket->recvfrom(NULL, packet, DNS_BUFFER_SIZE);
|
||||||
|
|
||||||
if (size < DNS_RESPONSE_MIN_SIZE) {
|
if (size < DNS_RESPONSE_MIN_SIZE) {
|
||||||
free(packet);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// gets id from response to associate with correct query
|
|
||||||
uint16_t id = (*packet << 8) | *(packet + 1);
|
|
||||||
|
|
||||||
DNS_QUERY *query = NULL;
|
|
||||||
|
|
||||||
for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) {
|
|
||||||
if (dns_query_queue[i] && dns_query_queue[i]->dns_message_id == id) {
|
|
||||||
query = dns_query_queue[i];
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gets id from response to associate with correct query
|
||||||
|
uint16_t id = (packet[0] << 8) | packet[1];
|
||||||
|
|
||||||
|
DNS_QUERY *query = NULL;
|
||||||
|
|
||||||
|
for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) {
|
||||||
|
if (dns_query_queue[i] && dns_query_queue[i]->dns_message_id == id) {
|
||||||
|
query = dns_query_queue[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int requested_count = 1;
|
||||||
|
if (query->addr_count > 1) {
|
||||||
|
requested_count = query->addr_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
query->addrs = new (std::nothrow) nsapi_addr_t[requested_count];
|
||||||
|
|
||||||
|
int resp = dns_scan_response(packet, id, &(query->ttl), query->addrs, requested_count);
|
||||||
|
|
||||||
|
// Ignore invalid responses
|
||||||
|
if (resp < 0) {
|
||||||
|
delete[] query->addrs;
|
||||||
|
query->addrs = 0;
|
||||||
|
} else {
|
||||||
|
query->count = resp;
|
||||||
|
nsapi_dns_call_in(query->call_in_cb, 0, mbed::callback(nsapi_dns_query_async_response, reinterpret_cast<void *>(query->unique_id)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!query) {
|
|
||||||
free(packet);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsapi_addr_t *addrs = new nsapi_addr_t[query->addr_count];
|
|
||||||
|
|
||||||
uint32_t ttl;
|
|
||||||
int count = dns_scan_response((const uint8_t *) packet, id, &ttl, addrs, query->addr_count);
|
|
||||||
|
|
||||||
free(packet);
|
free(packet);
|
||||||
|
}
|
||||||
|
|
||||||
if (count > 0) {
|
dns_mutex.unlock();
|
||||||
SocketAddress *addresses = new SocketAddress[count];
|
}
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
static void nsapi_dns_query_async_response(void *ptr)
|
||||||
addresses[i].set_addr(addrs[i]);
|
{
|
||||||
|
dns_mutex.lock();
|
||||||
|
|
||||||
|
int unique_id = reinterpret_cast<int>(ptr);
|
||||||
|
|
||||||
|
DNS_QUERY *query = NULL;
|
||||||
|
|
||||||
|
for (int i = 0; i < DNS_QUERY_QUEUE_SIZE; i++) {
|
||||||
|
if (dns_query_queue[i] && dns_query_queue[i]->unique_id == unique_id) {
|
||||||
|
query = dns_query_queue[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query) {
|
||||||
|
if (query->count > 0) {
|
||||||
|
SocketAddress *addresses = new (std::nothrow) SocketAddress[query->count];
|
||||||
|
|
||||||
|
for (int i = 0; i < query->count; i++) {
|
||||||
|
addresses[i].set_addr(query->addrs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds address to cache
|
// Adds address to cache
|
||||||
nsapi_dns_cache_add(query->host, addresses, ttl);
|
nsapi_dns_cache_add(query->host, &(query->addrs[0]), query->ttl);
|
||||||
|
|
||||||
nsapi_dns_query_async_resp(query, NSAPI_ERROR_OK, addresses);
|
|
||||||
|
|
||||||
|
nsapi_error_t status = NSAPI_ERROR_OK;
|
||||||
|
if (query->addr_count > 0) {
|
||||||
|
status = query->count;
|
||||||
|
}
|
||||||
|
nsapi_dns_query_async_resp(query, status, addresses);
|
||||||
delete[] addresses;
|
delete[] addresses;
|
||||||
} else {
|
} else {
|
||||||
nsapi_dns_query_async_resp(query, NSAPI_ERROR_DNS_FAILURE, NULL);
|
nsapi_dns_query_async_resp(query, NSAPI_ERROR_DNS_FAILURE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] addrs;
|
|
||||||
}
|
}
|
||||||
|
dns_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ nsapi_error_t nsapi_dns_add_server(nsapi_addr_t addr);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
typedef mbed::Callback<nsapi_error_t (int delay_ms, mbed::Callback<void()> user_cb)> call_in_callback_cb_t;
|
||||||
|
|
||||||
/** Query a domain name server for an IP address of a given hostname
|
/** Query a domain name server for an IP address of a given hostname
|
||||||
*
|
*
|
||||||
|
|
@ -80,14 +81,15 @@ nsapi_error_t nsapi_dns_query(NetworkStack *stack, const char *host,
|
||||||
*
|
*
|
||||||
* @param stack Network stack as target for DNS query
|
* @param stack Network stack as target for DNS query
|
||||||
* @param host Hostname to resolve
|
* @param host Hostname to resolve
|
||||||
* @param callback Callback that is called for result*
|
* @param callback Callback that is called for result
|
||||||
* @param data Caller defined data returned in callback
|
|
||||||
* @param version IP version to resolve (defaults to NSAPI_IPv4)
|
* @param version IP version to resolve (defaults to NSAPI_IPv4)
|
||||||
* @return 0 on success, negative error code on failure
|
* @return 0 on success, negative error code on failure or an unique id that
|
||||||
* NSAPI_ERROR_DNS_FAILURE indicates the host could not be found
|
* represents the hostname translation operation and can be passed to
|
||||||
|
* cancel, NSAPI_ERROR_DNS_FAILURE indicates the host could not be found
|
||||||
*/
|
*/
|
||||||
nsapi_error_t nsapi_dns_query_async(NetworkStack *stack, const char *host,
|
nsapi_error_t nsapi_dns_query_async(NetworkStack *stack, const char *host,
|
||||||
NetworkStack::hostbyname_cb_t callback, void *data, nsapi_version_t version = NSAPI_IPv4);
|
NetworkStack::hostbyname_cb_t callback, call_in_callback_cb_t call_in_cb,
|
||||||
|
nsapi_version_t version = NSAPI_IPv4);
|
||||||
|
|
||||||
/** Query a domain name server for an IP address of a given hostname (asynchronous)
|
/** Query a domain name server for an IP address of a given hostname (asynchronous)
|
||||||
*
|
*
|
||||||
|
|
@ -135,14 +137,15 @@ nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const char *
|
||||||
* @param stack Network stack as target for DNS query
|
* @param stack Network stack as target for DNS query
|
||||||
* @param host Hostname to resolve
|
* @param host Hostname to resolve
|
||||||
* @param callback Callback that is called for result
|
* @param callback Callback that is called for result
|
||||||
* @param data Caller defined data returned in callback
|
|
||||||
* @param addr_count Number of addresses allocated in the array
|
* @param addr_count Number of addresses allocated in the array
|
||||||
* @param version IP version to resolve (defaults to NSAPI_IPv4)
|
* @param version IP version to resolve (defaults to NSAPI_IPv4)
|
||||||
* @return 0 on success, negative error code on failure
|
* @return 0 on success, negative error code on failure or an unique id that
|
||||||
* NSAPI_ERROR_DNS_FAILURE indicates the host could not be found
|
represents the hostname translation operation and can be passed to
|
||||||
|
* cancel, NSAPI_ERROR_DNS_FAILURE indicates the host could not be found
|
||||||
*/
|
*/
|
||||||
nsapi_size_or_error_t nsapi_dns_query_multiple_async(NetworkStack *stack, const char *host,
|
nsapi_size_or_error_t nsapi_dns_query_multiple_async(NetworkStack *stack, const char *host,
|
||||||
NetworkStack::hostbyname_cb_t callback, void *data, nsapi_size_t addr_count, nsapi_version_t version = NSAPI_IPv4);
|
NetworkStack::hostbyname_cb_t callback, nsapi_size_t addr_count,
|
||||||
|
call_in_callback_cb_t call_in_cb, nsapi_version_t version = NSAPI_IPv4);
|
||||||
|
|
||||||
/** Query a domain name server for multiple IP address of a given hostname
|
/** Query a domain name server for multiple IP address of a given hostname
|
||||||
*
|
*
|
||||||
|
|
@ -176,6 +179,15 @@ nsapi_size_or_error_t nsapi_dns_query_multiple(S *stack, const char *host,
|
||||||
host, addr, addr_count, version);
|
host, addr, addr_count, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Cancels asynchronous hostname translation
|
||||||
|
*
|
||||||
|
* When translation is cancelled, callback will not be called.
|
||||||
|
*
|
||||||
|
* @param id Unique id of the hostname translation operation
|
||||||
|
* @return 0 on success, negative error code on failure
|
||||||
|
*/
|
||||||
|
nsapi_error_t nsapi_dns_query_async_cancel(nsapi_error_t id);
|
||||||
|
|
||||||
/** Add a domain name server to list of servers to query
|
/** Add a domain name server to list of servers to query
|
||||||
*
|
*
|
||||||
* @param addr Destination for the host address
|
* @param addr Destination for the host address
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue