mirror of https://github.com/ARMmbed/mbed-os.git
commit
9ec0ec0309
|
@ -217,7 +217,7 @@ static int lwip_err_remap(err_t err) {
|
|||
|
||||
|
||||
/* LWIP network stack implementation */
|
||||
static nsapi_addr_t lwip_get_addr(nsapi_stack_t *stack)
|
||||
static nsapi_addr_t lwip_getaddr(nsapi_stack_t *stack)
|
||||
{
|
||||
if (!lwip_get_ip_address()) {
|
||||
return (nsapi_addr_t){0};
|
||||
|
@ -229,6 +229,17 @@ static nsapi_addr_t lwip_get_addr(nsapi_stack_t *stack)
|
|||
return addr;
|
||||
}
|
||||
|
||||
static int lwip_gethostbyname(nsapi_stack_t *stack, nsapi_addr_t *addr, const char *host)
|
||||
{
|
||||
err_t err = netconn_gethostbyname(host, (ip_addr_t *)addr->bytes);
|
||||
if (err != ERR_OK) {
|
||||
return NSAPI_ERROR_DNS_FAILURE;
|
||||
}
|
||||
|
||||
addr->version = NSAPI_IPv4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lwip_socket_open(nsapi_stack_t *stack, nsapi_socket_t *handle, nsapi_protocol_t proto)
|
||||
{
|
||||
struct lwip_socket *s = lwip_arena_alloc();
|
||||
|
@ -449,7 +460,8 @@ static void lwip_socket_attach(nsapi_stack_t *stack, nsapi_socket_t handle, void
|
|||
|
||||
/* LWIP network stack */
|
||||
const nsapi_stack_api_t lwip_stack_api = {
|
||||
.get_ip_address = lwip_get_addr,
|
||||
.get_ip_address = lwip_getaddr,
|
||||
.gethostbyname = lwip_gethostbyname,
|
||||
.socket_open = lwip_socket_open,
|
||||
.socket_close = lwip_socket_close,
|
||||
.socket_bind = lwip_socket_bind,
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
|
||||
#define LWIP_DHCP 1
|
||||
#define LWIP_DNS 1
|
||||
#define LWIP_SOCKET 0
|
||||
|
||||
#define SO_REUSE 1
|
||||
|
||||
|
|
|
@ -1,216 +0,0 @@
|
|||
/* Copyright (c) 2013 Henry Leinen (henry[dot]leinen [at] online [dot] de)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
* and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "DnsQuery.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define DNS_COUNT (sizeof DNS_IPS / sizeof DNS_IPS[0])
|
||||
const char *DNS_IPS[] = {
|
||||
"8.8.8.8",
|
||||
"209.244.0.3",
|
||||
"84.200.69.80",
|
||||
"8.26.56.26",
|
||||
"208.67.222.222"
|
||||
};
|
||||
|
||||
static bool isIP(const char *host)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; host[i]; i++) {
|
||||
if (!(host[i] >= '0' && host[i] <= '9') && host[i] != '.') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Ending with '.' garuntees host
|
||||
if (i > 0 && host[i-1] == '.') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool parseRR(uint8_t *resp, int &c, char *adr)
|
||||
{
|
||||
int n = 0;
|
||||
while((n=resp[c++]) != 0) {
|
||||
if ((n & 0xc0) != 0) {
|
||||
// This is a link
|
||||
c++;
|
||||
break;
|
||||
} else {
|
||||
// skip this segment, not interested in string domain names
|
||||
c+= n;
|
||||
}
|
||||
}
|
||||
|
||||
int TYPE = (((int)resp[c])<<8) + resp[c+1];
|
||||
int CLASS = (((int)resp[c+2])<<8) + resp[c+3];
|
||||
int RDLENGTH = (((int)resp[c+8])<<8) + resp[c+9];
|
||||
|
||||
c+= 10;
|
||||
if ((CLASS == 1) && (TYPE == 1)) {
|
||||
sprintf(adr,"%d.%d.%d.%d", resp[c], resp[c+1], resp[c+2], resp[c+3]);
|
||||
c+= RDLENGTH;
|
||||
return true;
|
||||
}
|
||||
c+= RDLENGTH;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool resolve(unsigned char *resp, char *ipaddress)
|
||||
{
|
||||
|
||||
int ID = (((int)resp[0]) <<8) + resp[1];
|
||||
int QR = resp[2] >>7;
|
||||
int Opcode = (resp[2]>>3) & 0x0F;
|
||||
int RCODE = (resp[3] & 0x0F);
|
||||
int ANCOUNT = (((int)resp[6])<<8)+ resp[7];
|
||||
|
||||
if ((ID != 1) || (QR != 1) || (Opcode != 0) || (RCODE != 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int c = 12;
|
||||
int d;
|
||||
// Skip domain question
|
||||
while( (d=resp[c++]) != 0) {
|
||||
c+=d;
|
||||
}
|
||||
c+= 4; // skip QTYPE and QCLASS
|
||||
|
||||
// Here comes the resource record
|
||||
for (int ans = 0 ; ans < ANCOUNT; ans++) {
|
||||
if (parseRR(resp, c, ipaddress)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int32_t query(UDPSocket *socket, const SocketAddress &addr, const char *hostname, char *ipaddress)
|
||||
{
|
||||
int len = 0;
|
||||
if (hostname == NULL) {
|
||||
return false;
|
||||
}
|
||||
len = strlen(hostname);
|
||||
if ((len > 128) || (len == 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int packetlen = /* size of HEADER structure */ 12 + /* size of QUESTION Structure */5 + len + 1;
|
||||
uint8_t *packet = new uint8_t[packetlen]; /* this is the UDP packet to send to the DNS */
|
||||
if (packet == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fill the header
|
||||
memset(packet, 0, packetlen);
|
||||
packet[1] = 1; // ID = 1
|
||||
packet[5] = 1; // QDCOUNT = 1 (contains one question)
|
||||
packet[2] = 1; // recursion requested
|
||||
|
||||
int c = 13; // point to NAME element in question section or request
|
||||
int cnt = 12; // points to the counter of
|
||||
packet[cnt] = 0;
|
||||
for (int i = 0 ; i < len ; i++) {
|
||||
if (hostname[i] != '.') {
|
||||
// Copy the character and increment the character counter
|
||||
packet[cnt]++;
|
||||
packet[c++] = hostname[i];
|
||||
} else {
|
||||
// Finished with this part, so go to the next
|
||||
cnt = c++;
|
||||
packet[cnt] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Terminate this domain name with a zero entry
|
||||
packet[c++] = 0;
|
||||
|
||||
// Set QTYPE
|
||||
packet[c++] = 0;
|
||||
packet[c++] = 1;
|
||||
// Set QCLASS
|
||||
packet[c++] = 0;
|
||||
packet[c++] = 1;
|
||||
|
||||
|
||||
if (socket->sendto(addr, packet, packetlen) < 0) {
|
||||
delete packet;
|
||||
return false;
|
||||
}
|
||||
delete packet;
|
||||
|
||||
packet = new uint8_t [1024];
|
||||
|
||||
// Receive the answer from DNS
|
||||
int response_length = 0;
|
||||
response_length = socket->recvfrom(NULL, packet, 1024);
|
||||
|
||||
if (response_length > 0 ) {
|
||||
if (!resolve(packet, ipaddress)) {
|
||||
delete packet;
|
||||
return NSAPI_ERROR_DNS_FAILURE;
|
||||
}
|
||||
|
||||
// cleanup and return
|
||||
delete packet;
|
||||
return 0;
|
||||
}
|
||||
|
||||
delete packet;
|
||||
return NSAPI_ERROR_DNS_FAILURE;
|
||||
}
|
||||
|
||||
int32_t dnsQuery(NetworkStack *iface, const char *host, char *ip)
|
||||
{
|
||||
if (isIP(host)) {
|
||||
strcpy(ip, host);
|
||||
return 0;
|
||||
}
|
||||
|
||||
UDPSocket sock(iface);
|
||||
|
||||
for (unsigned i = 0; i < DNS_COUNT; i++) {
|
||||
return query(&sock, SocketAddress(DNS_IPS[0], 53), host, ip);
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_DNS_FAILURE;
|
||||
}
|
||||
|
||||
int32_t dnsQuery(UDPSocket *socket, const char *host, char *ip)
|
||||
{
|
||||
if (isIP(host)) {
|
||||
strcpy(ip, host);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < DNS_COUNT; i++) {
|
||||
return query(socket, SocketAddress(DNS_IPS[0], 53), host, ip);
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_DNS_FAILURE;
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
* and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef __DNSQUERY_H__
|
||||
#define __DNSQUERY_H__
|
||||
|
||||
#include "NetworkStack.h"
|
||||
#include "UDPSocket.h"
|
||||
|
||||
|
||||
/** Function dnsQuery implements the functionality to query a domain name
|
||||
* server for an IP-Address of a given hostname.
|
||||
* @param iface : Network interface to use for DNS resolution.
|
||||
* @param sock : Previously opened socket to use for DNS resolution.
|
||||
* @param hostname : The hostname of interest as a string.
|
||||
* Format must be without http:// or www. IE google.com, mbed.org, etc.
|
||||
* If a standard IP Address is passed, it will be copied into ip unmodified.
|
||||
* @param ipaddress : A reference to a IPADDRESS_t object which will receive
|
||||
* the resolved IP Address of the host in question.
|
||||
* @returns 0 on succes, NS_DNS_FAILURE if host is not found,
|
||||
* or a negative value for other errors.
|
||||
*/
|
||||
int32_t dnsQuery(NetworkStack *iface, const char *host, char *ip);
|
||||
int32_t dnsQuery(UDPSocket *sock, const char *host, char *ip);
|
||||
|
||||
|
||||
#endif // __DNSQUERY_H__
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "NetworkStack.h"
|
||||
#include "DnsQuery.h"
|
||||
#include "nsapi_dns.h"
|
||||
#include "mbed.h"
|
||||
#include "stddef.h"
|
||||
#include <new>
|
||||
|
@ -24,14 +24,7 @@
|
|||
// Default NetworkStack operations
|
||||
int NetworkStack::gethostbyname(SocketAddress *address, const char *name)
|
||||
{
|
||||
char buffer[NSAPI_IP_SIZE];
|
||||
int err = dnsQuery(this, name, buffer);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
address->set_ip_address(buffer);
|
||||
return 0;
|
||||
return nsapi_dns_query(this, address, name);
|
||||
}
|
||||
|
||||
int NetworkStack::setstackopt(int level, int optname, const void *optval, unsigned optlen)
|
||||
|
|
|
@ -0,0 +1,304 @@
|
|||
/* nsapi_dns.cpp
|
||||
* Original work Copyright (c) 2013 Henry Leinen (henry[dot]leinen [at] online [dot] de)
|
||||
* Modified work Copyright (c) 2015 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.
|
||||
*/
|
||||
#include "nsapi_dns.h"
|
||||
#include "network-socket/UDPSocket.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
// DNS options
|
||||
#define DNS_BUFFER_SIZE 256
|
||||
#define DNS_TIMEOUT 5000
|
||||
#define DNS_SERVERS_SIZE 5
|
||||
|
||||
nsapi_addr_t dns_servers[DNS_SERVERS_SIZE] = {
|
||||
{NSAPI_IPv4, {8, 8, 8, 8}},
|
||||
{NSAPI_IPv4, {209, 244, 0, 3}},
|
||||
{NSAPI_IPv4, {84, 200, 69, 80}},
|
||||
{NSAPI_IPv4, {8, 26, 56, 26}},
|
||||
{NSAPI_IPv4, {208, 67, 222, 222}},
|
||||
};
|
||||
|
||||
|
||||
// DNS server configuration
|
||||
extern "C" int nsapi_dns_add_server(nsapi_addr_t addr)
|
||||
{
|
||||
memmove(&dns_servers[1], &dns_servers[0],
|
||||
(DNS_SERVERS_SIZE-1)*sizeof(nsapi_addr_t));
|
||||
|
||||
dns_servers[0] = addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// DNS packet parsing
|
||||
static void dns_append_byte(uint8_t **p, uint8_t byte)
|
||||
{
|
||||
*(*p)++ = byte;
|
||||
}
|
||||
|
||||
static void dns_append_word(uint8_t **p, uint16_t word)
|
||||
{
|
||||
|
||||
dns_append_byte(p, 0xff & (word >> 8));
|
||||
dns_append_byte(p, 0xff & (word >> 0));
|
||||
}
|
||||
|
||||
static void dns_append_name(uint8_t **p, const char *name, uint8_t len)
|
||||
{
|
||||
dns_append_byte(p, len);
|
||||
memcpy(*p, name, len);
|
||||
*p += len;
|
||||
}
|
||||
|
||||
static uint8_t dns_scan_byte(const uint8_t **p)
|
||||
{
|
||||
return *(*p)++;
|
||||
}
|
||||
|
||||
static uint16_t dns_scan_word(const uint8_t **p)
|
||||
{
|
||||
uint16_t a = dns_scan_byte(p);
|
||||
uint16_t b = dns_scan_byte(p);
|
||||
return (a << 8) | b;
|
||||
}
|
||||
|
||||
|
||||
static void dns_append_question(uint8_t **p, const char *host, nsapi_version_t version)
|
||||
{
|
||||
// fill the header
|
||||
dns_append_word(p, 1); // id = 1
|
||||
dns_append_word(p, 0x0100); // flags = recursion required
|
||||
dns_append_word(p, 1); // qdcount = 1
|
||||
dns_append_word(p, 0); // ancount = 0
|
||||
dns_append_word(p, 0); // nscount = 0
|
||||
dns_append_word(p, 0); // arcount = 0
|
||||
|
||||
// fill out the question names
|
||||
while (host[0]) {
|
||||
size_t label_len = strcspn(host, ".");
|
||||
dns_append_name(p, host, label_len);
|
||||
host += label_len + (host[label_len] == '.');
|
||||
}
|
||||
|
||||
dns_append_byte(p, 0);
|
||||
|
||||
// fill out question footer
|
||||
if (version == NSAPI_IPv4) {
|
||||
dns_append_word(p, 1); // qtype = ipv4
|
||||
} else {
|
||||
dns_append_word(p, 28); // qtype = ipv6
|
||||
}
|
||||
dns_append_word(p, 1); // qclass = 1
|
||||
}
|
||||
|
||||
static int dns_scan_response(const uint8_t **p, nsapi_addr_t *addr, unsigned addr_count)
|
||||
{
|
||||
// scan header
|
||||
uint16_t id = dns_scan_word(p);
|
||||
uint16_t flags = dns_scan_word(p);
|
||||
bool qr = 0x1 & (flags >> 15);
|
||||
uint8_t opcode = 0xf & (flags >> 11);
|
||||
uint8_t rcode = 0xf & (flags >> 0);
|
||||
|
||||
uint16_t qdcount = dns_scan_word(p); // qdcount
|
||||
uint16_t ancount = dns_scan_word(p); // ancount
|
||||
dns_scan_word(p); // nscount
|
||||
dns_scan_word(p); // arcount
|
||||
|
||||
// verify header is response to query
|
||||
if (!(id == 1 && qr && opcode == 0 && rcode == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// skip questions
|
||||
for (int i = 0; i < qdcount; i++) {
|
||||
while (true) {
|
||||
uint8_t len = dns_scan_byte(p);
|
||||
if (len == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
*p += len;
|
||||
}
|
||||
|
||||
dns_scan_word(p); // qtype
|
||||
dns_scan_word(p); // qclass
|
||||
}
|
||||
|
||||
// scan each response
|
||||
unsigned count = 0;
|
||||
|
||||
for (int i = 0; i < ancount && count < addr_count; i++) {
|
||||
while (true) {
|
||||
uint8_t len = dns_scan_byte(p);
|
||||
if (len == 0) {
|
||||
break;
|
||||
} else if (len & 0xc0) { // this is link
|
||||
dns_scan_byte(p);
|
||||
break;
|
||||
}
|
||||
|
||||
*p += len;
|
||||
}
|
||||
|
||||
uint16_t rtype = dns_scan_word(p); // rtype
|
||||
uint16_t rclass = dns_scan_word(p); // rclass
|
||||
*p += 4; // ttl
|
||||
uint16_t rdlength = dns_scan_word(p); // rdlength
|
||||
|
||||
if (rtype == 1 && rclass == 1 && rdlength == NSAPI_IPv4_BYTES) {
|
||||
// accept A record
|
||||
addr->version = NSAPI_IPv4;
|
||||
for (int i = 0; i < NSAPI_IPv4_BYTES; i++) {
|
||||
addr->bytes[i] = dns_scan_byte(p);
|
||||
}
|
||||
|
||||
addr += 1;
|
||||
count += 1;
|
||||
} else if (rtype == 28 && rclass == 1 && rdlength == NSAPI_IPv6_BYTES) {
|
||||
// accept AAAA record
|
||||
addr->version = NSAPI_IPv6;
|
||||
for (int i = 0; i < NSAPI_IPv6_BYTES; i++) {
|
||||
addr->bytes[i] = dns_scan_byte(p);
|
||||
}
|
||||
|
||||
addr += 1;
|
||||
count += 1;
|
||||
} else {
|
||||
// skip unrecognized records
|
||||
*p += rdlength;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// core query function
|
||||
static int nsapi_dns_query_multiple(NetworkStack *stack,
|
||||
nsapi_addr_t *addr, unsigned addr_count,
|
||||
const char *host, nsapi_version_t version)
|
||||
{
|
||||
// check for valid host name
|
||||
int host_len = host ? strlen(host) : 0;
|
||||
if (host_len > 128 || host_len == 0) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
// create a udp socket
|
||||
UDPSocket socket;
|
||||
int err = socket.open(stack);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
socket.set_timeout(DNS_TIMEOUT);
|
||||
|
||||
// create network packet
|
||||
uint8_t *packet = (uint8_t *)malloc(DNS_BUFFER_SIZE);
|
||||
if (!packet) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
int result = NSAPI_ERROR_DNS_FAILURE;
|
||||
|
||||
// check against each dns server
|
||||
for (unsigned i = 0; i < DNS_SERVERS_SIZE; i++) {
|
||||
// send the question
|
||||
uint8_t *p = packet;
|
||||
dns_append_question(&p, host, version);
|
||||
|
||||
err = socket.sendto(SocketAddress(dns_servers[i], 53), packet, DNS_BUFFER_SIZE);
|
||||
if (err == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
continue;
|
||||
} else if (err < 0) {
|
||||
result = err;
|
||||
break;
|
||||
}
|
||||
|
||||
// recv the response
|
||||
err = socket.recvfrom(NULL, packet, DNS_BUFFER_SIZE);
|
||||
if (err == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
continue;
|
||||
} else if (err < 0) {
|
||||
result = err;
|
||||
break;
|
||||
}
|
||||
|
||||
p = packet;
|
||||
int found = dns_scan_response((const uint8_t **)&p, addr, addr_count);
|
||||
if (found) {
|
||||
result = found;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// clean up packet
|
||||
free(packet);
|
||||
|
||||
// clean up udp
|
||||
err = socket.close();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// return result
|
||||
return result;
|
||||
}
|
||||
|
||||
// convenience functions for other forms of queries
|
||||
extern "C" int nsapi_dns_query_multiple(nsapi_stack_t *stack,
|
||||
nsapi_addr_t *addr, unsigned addr_count,
|
||||
const char *host, nsapi_version_t version)
|
||||
{
|
||||
NetworkStack *nstack = nsapi_create_stack(stack);
|
||||
return nsapi_dns_query_multiple(nstack, addr, addr_count, host, version);
|
||||
}
|
||||
|
||||
int nsapi_dns_query_multiple(NetworkStack *stack,
|
||||
SocketAddress *addresses, unsigned addr_count,
|
||||
const char *host, nsapi_version_t version)
|
||||
{
|
||||
nsapi_addr_t *addrs = new nsapi_addr_t[addr_count];
|
||||
int result = nsapi_dns_query_multiple(stack, addrs, addr_count, host, version);
|
||||
|
||||
if (result > 0) {
|
||||
for (int i = 0; i < result; i++) {
|
||||
addresses[i].set_addr(addrs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] addrs;
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" int nsapi_dns_query(nsapi_stack_t *stack,
|
||||
nsapi_addr_t *addr, const char *host, nsapi_version_t version)
|
||||
{
|
||||
NetworkStack *nstack = nsapi_create_stack(stack);
|
||||
int result = nsapi_dns_query_multiple(nstack, addr, 1, host, version);
|
||||
return (result > 0) ? 0 : result;
|
||||
}
|
||||
|
||||
int nsapi_dns_query(NetworkStack *stack,
|
||||
SocketAddress *address, const char *host, nsapi_version_t version)
|
||||
{
|
||||
nsapi_addr_t addr;
|
||||
int result = nsapi_dns_query_multiple(stack, &addr, 1, host, version);
|
||||
address->set_addr(addr);
|
||||
return (result > 0) ? 0 : result;
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
/* nsapi_dns.h
|
||||
* Original work Copyright (c) 2013 Henry Leinen (henry[dot]leinen [at] online [dot] de)
|
||||
* Modified work Copyright (c) 2015 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 NSAPI_DNS_H
|
||||
#define NSAPI_DNS_H
|
||||
|
||||
#include "nsapi_types.h"
|
||||
#ifdef __cplusplus
|
||||
#include "network-socket/NetworkStack.h"
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
|
||||
/** Query a domain name server for an IP address of a given hostname
|
||||
*
|
||||
* @param stack Network stack as target for DNS query
|
||||
* @param addr Destination for the host address
|
||||
* @param host Hostname to resolve
|
||||
* @param version IP version to resolve
|
||||
* @return 0 on success, negative error code on failure
|
||||
* NSAPI_ERROR_DNS_FAILURE indicates the host could not be found
|
||||
*/
|
||||
int nsapi_dns_query(nsapi_stack_t *stack, nsapi_addr_t *addr,
|
||||
const char *host, nsapi_version_t version);
|
||||
|
||||
/** Query a domain name server for multiple IP address of a given hostname
|
||||
*
|
||||
* @param stack Network stack as target for DNS query
|
||||
* @param addr Array for the host addresses
|
||||
* @param addr_count Number of addresses allocated in the array
|
||||
* @param host Hostname to resolve
|
||||
* @param version IP version to resolve
|
||||
* @return Number of addresses found on success, negative error code on failure
|
||||
* NSAPI_ERROR_DNS_FAILURE indicates the host could not be found
|
||||
*/
|
||||
int nsapi_dns_query_multiple(nsapi_stack_t *stack,
|
||||
nsapi_addr_t *addr, unsigned addr_count,
|
||||
const char *host, nsapi_version_t version);
|
||||
|
||||
/** Add a domain name server to list of servers to query
|
||||
*
|
||||
* @param addr Destination for the host address
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
int nsapi_dns_add_server(nsapi_addr_t addr);
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
||||
/** Query a domain name server for an IP address of a given hostname
|
||||
*
|
||||
* @param stack Network stack as target for DNS query
|
||||
* @param addr Destination for the host address
|
||||
* @param host Hostname to resolve
|
||||
* @param version IP version to resolve (defaults to NSAPI_IPv4)
|
||||
* @return 0 on success, negative error code on failure
|
||||
* NSAPI_ERROR_DNS_FAILURE indicates the host could not be found
|
||||
*/
|
||||
int nsapi_dns_query(NetworkStack *stack, SocketAddress *addr,
|
||||
const char *host, nsapi_version_t version = NSAPI_IPv4);
|
||||
|
||||
/** Query a domain name server for an IP address of a given hostname
|
||||
*
|
||||
* @param stack Network stack as target for DNS query
|
||||
* @param addr Destination for the host address
|
||||
* @param host Hostname to resolve
|
||||
* @param version IP version to resolve (defaults to NSAPI_IPv4)
|
||||
* @return 0 on success, negative error code on failure
|
||||
* NSAPI_ERROR_DNS_FAILURE indicates the host could not be found
|
||||
*/
|
||||
extern "C" int nsapi_dns_query(nsapi_stack_t *stack, nsapi_addr_t *addr,
|
||||
const char *host, nsapi_version_t version = NSAPI_IPv4);
|
||||
|
||||
/** Query a domain name server for an IP address of a given hostname
|
||||
*
|
||||
* @param stack Network stack as target for DNS query
|
||||
* @param addr Destination for the host address
|
||||
* @param host Hostname to resolve
|
||||
* @param version IP version to resolve (defaults to NSAPI_IPv4)
|
||||
* @return 0 on success, negative error code on failure
|
||||
* NSAPI_ERROR_DNS_FAILURE indicates the host could not be found
|
||||
*/
|
||||
template <typename S>
|
||||
int nsapi_dns_query(S *stack, SocketAddress *addr,
|
||||
const char *host, nsapi_version_t version = NSAPI_IPv4)
|
||||
{
|
||||
return nsapi_dns_query(nsapi_create_stack(stack), addr, host, version);
|
||||
}
|
||||
|
||||
/** Query a domain name server for multiple IP address of a given hostname
|
||||
*
|
||||
* @param stack Network stack as target for DNS query
|
||||
* @param addr Array for the host addresses
|
||||
* @param addr_count Number of addresses allocated in the array
|
||||
* @param host Hostname to resolve
|
||||
* @param version IP version to resolve (defaults to NSAPI_IPv4)
|
||||
* @return Number of addresses found on success, negative error code on failure
|
||||
* NSAPI_ERROR_DNS_FAILURE indicates the host could not be found
|
||||
*/
|
||||
int nsapi_dns_query_multiple(NetworkStack *stack,
|
||||
SocketAddress *addr, unsigned addr_count,
|
||||
const char *host, nsapi_version_t version = NSAPI_IPv4);
|
||||
|
||||
/** Query a domain name server for multiple IP address of a given hostname
|
||||
*
|
||||
* @param stack Network stack as target for DNS query
|
||||
* @param addr Array for the host addresses
|
||||
* @param addr_count Number of addresses allocated in the array
|
||||
* @param host Hostname to resolve
|
||||
* @param version IP version to resolve (defaults to NSAPI_IPv4)
|
||||
* @return Number of addresses found on success, negative error code on failure
|
||||
* NSAPI_ERROR_DNS_FAILURE indicates the host could not be found
|
||||
*/
|
||||
extern "C" int nsapi_dns_query_multiple(nsapi_stack_t *stack,
|
||||
nsapi_addr_t *addr, unsigned addr_count,
|
||||
const char *host, nsapi_version_t version = NSAPI_IPv4);
|
||||
|
||||
/** Query a domain name server for multiple IP address of a given hostname
|
||||
*
|
||||
* @param stack Network stack as target for DNS query
|
||||
* @param addr Array for the host addresses
|
||||
* @param addr_count Number of addresses allocated in the array
|
||||
* @param host Hostname to resolve
|
||||
* @param version IP version to resolve (defaults to NSAPI_IPv4)
|
||||
* @return Number of addresses found on success, negative error code on failure
|
||||
* NSAPI_ERROR_DNS_FAILURE indicates the host could not be found
|
||||
*/
|
||||
template <typename S>
|
||||
int nsapi_dns_query_multiple(S *stack,
|
||||
SocketAddress *addr, unsigned addr_count,
|
||||
const char *host, nsapi_version_t version = NSAPI_IPv4)
|
||||
{
|
||||
return nsapi_dns_query_multiple(nsapi_create_stack(stack),
|
||||
addr, addr_count, host, version);
|
||||
}
|
||||
|
||||
/** Add a domain name server to list of servers to query
|
||||
*
|
||||
* @param addr Destination for the host address
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
extern "C" int nsapi_dns_add_server(nsapi_addr_t addr);
|
||||
|
||||
/** Add a domain name server to list of servers to query
|
||||
*
|
||||
* @param addr Destination for the host address
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
static inline int nsapi_dns_add_server(const SocketAddress &address)
|
||||
{
|
||||
return nsapi_dns_add_server(address.get_addr());
|
||||
}
|
||||
|
||||
/** Add a domain name server to list of servers to query
|
||||
*
|
||||
* @param addr Destination for the host address
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
static inline int nsapi_dns_add_server(const char *address)
|
||||
{
|
||||
return nsapi_dns_add_server(SocketAddress(address));
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue