mirror of
https://github.com/apache/nuttx.git
synced 2026-05-27 11:26:12 +08:00
libs/libc/netdb: Support multiple IP addresses per hostname
This commit is contained in:
committed by
Gregory Nutt
parent
d2a11cdea5
commit
3e7281e699
@@ -90,10 +90,12 @@
|
|||||||
#define DNS_RECTYPE_NSEC 47 /* RFC 4034 Next-Secure record */
|
#define DNS_RECTYPE_NSEC 47 /* RFC 4034 Next-Secure record */
|
||||||
#define DNS_RECTYPE_NSEC3 50 /* RFC 5155 NSEC record version 3 */
|
#define DNS_RECTYPE_NSEC3 50 /* RFC 5155 NSEC record version 3 */
|
||||||
#define DNS_RECTYPE_NSEC3PARAM 51 /* RFC 5155 NSEC3 parameters */
|
#define DNS_RECTYPE_NSEC3PARAM 51 /* RFC 5155 NSEC3 parameters */
|
||||||
|
#define DNS_RECTYPE_OPENPGPKEY 61 /* RFC 7929 OpenPGP public key record */
|
||||||
#define DNS_RECTYPE_PTR 12 /* RFC 1035 Pointer record */
|
#define DNS_RECTYPE_PTR 12 /* RFC 1035 Pointer record */
|
||||||
#define DNS_RECTYPE_RRSIG 46 /* RFC 4034 DNSSEC signature */
|
#define DNS_RECTYPE_RRSIG 46 /* RFC 4034 DNSSEC signature */
|
||||||
#define DNS_RECTYPE_RP 17 /* RFC 1183 Responsible person */
|
#define DNS_RECTYPE_RP 17 /* RFC 1183 Responsible person */
|
||||||
#define DNS_RECTYPE_SIG 24 /* RFC 2535 Signature */
|
#define DNS_RECTYPE_SIG 24 /* RFC 2535 Signature */
|
||||||
|
#define DNS_RECTYPE_SMIMEA 53 /* RFC 8162 S/MIME cert association */
|
||||||
#define DNS_RECTYPE_SOA 6 /* RFC 1035 and RFC 2308 Start of [a zone of] authority record */
|
#define DNS_RECTYPE_SOA 6 /* RFC 1035 and RFC 2308 Start of [a zone of] authority record */
|
||||||
#define DNS_RECTYPE_SRV 33 /* RFC 2782 Service locator */
|
#define DNS_RECTYPE_SRV 33 /* RFC 2782 Service locator */
|
||||||
#define DNS_RECTYPE_SSHFP 44 /* RFC 4255 SSH Public Key Fingerprint */
|
#define DNS_RECTYPE_SSHFP 44 /* RFC 4255 SSH Public Key Fingerprint */
|
||||||
@@ -101,7 +103,8 @@
|
|||||||
#define DNS_RECTYPE_TKEY 249 /* RFC 2930 Secret key record */
|
#define DNS_RECTYPE_TKEY 249 /* RFC 2930 Secret key record */
|
||||||
#define DNS_RECTYPE_TLSA 52 /* RFC 6698 TLSA certificate association */
|
#define DNS_RECTYPE_TLSA 52 /* RFC 6698 TLSA certificate association */
|
||||||
#define DNS_RECTYPE_TSIG 250 /* RFC 2845 Transaction Signature */
|
#define DNS_RECTYPE_TSIG 250 /* RFC 2845 Transaction Signature */
|
||||||
#define DNS_RECTYPE_TXT 16 /* RFC 1035[1] Text record */
|
#define DNS_RECTYPE_TXT 16 /* RFC 1035 Text record */
|
||||||
|
#define DNS_RECTYPE_URI 256 /* RFC 7553 Uniform Resource Identifier */
|
||||||
|
|
||||||
#define DNS_RECTYPE_ALL 255 /* RFC 1035 All cached records */
|
#define DNS_RECTYPE_ALL 255 /* RFC 1035 All cached records */
|
||||||
#define DNS_RECTYPE_AXFR 252 /* RFC 1035 Authoritative Zone Transfer */
|
#define DNS_RECTYPE_AXFR 252 /* RFC 1035 Authoritative Zone Transfer */
|
||||||
@@ -156,7 +159,7 @@ struct dns_question_s
|
|||||||
|
|
||||||
/* The DNS answer message structure */
|
/* The DNS answer message structure */
|
||||||
|
|
||||||
struct dns_answer_s
|
begin_packed_struct struct dns_answer_s
|
||||||
{
|
{
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
uint16_t class;
|
uint16_t class;
|
||||||
@@ -172,7 +175,7 @@ struct dns_answer_s
|
|||||||
struct in6_addr ipv6;
|
struct in6_addr ipv6;
|
||||||
#endif
|
#endif
|
||||||
} u;
|
} u;
|
||||||
};
|
} end_packed_struct;
|
||||||
|
|
||||||
/* The type of the callback from dns_foreach_nameserver() */
|
/* The type of the callback from dns_foreach_nameserver() */
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,13 @@ config NETDB_DNSCLIENT_MAXRESPONSE
|
|||||||
can be received by the DNS resolver. The default is 96 but may
|
can be received by the DNS resolver. The default is 96 but may
|
||||||
need to be larger on enterprise networks (perhaps 176).
|
need to be larger on enterprise networks (perhaps 176).
|
||||||
|
|
||||||
|
config NETDB_DNSCLIENT_MAXIP
|
||||||
|
int "Max number of IP addresses per host"
|
||||||
|
default 1
|
||||||
|
---help---
|
||||||
|
This setting determines the maximum number of IP addresses
|
||||||
|
stored to the name resolution cache for a given host.
|
||||||
|
|
||||||
config NETDB_DNSCLIENT_RECV_TIMEOUT
|
config NETDB_DNSCLIENT_RECV_TIMEOUT
|
||||||
int "DNS receive timeout"
|
int "DNS receive timeout"
|
||||||
default 30
|
default 30
|
||||||
|
|||||||
+23
-21
@@ -62,12 +62,14 @@
|
|||||||
# define CONFIG_NETDB_DNSCLIENT_ENTRIES 4
|
# define CONFIG_NETDB_DNSCLIENT_ENTRIES 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RESOLV_ENTRIES CONFIG_NETDB_DNSCLIENT_ENTRIES
|
|
||||||
|
|
||||||
#ifndef CONFIG_NETDB_DNSCLIENT_MAXRESPONSE
|
#ifndef CONFIG_NETDB_DNSCLIENT_MAXRESPONSE
|
||||||
# define CONFIG_NETDB_DNSCLIENT_MAXRESPONSE 96
|
# define CONFIG_NETDB_DNSCLIENT_MAXRESPONSE 96
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_NETDB_DNSCLIENT_MAXIP
|
||||||
|
# define CONFIG_NETDB_DNSCLIENT_MAXIP 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_NETDB_DNSCLIENT_NAMESIZE
|
#ifndef CONFIG_NETDB_DNSCLIENT_NAMESIZE
|
||||||
# define CONFIG_NETDB_DNSCLIENT_NAMESIZE 32
|
# define CONFIG_NETDB_DNSCLIENT_NAMESIZE 32
|
||||||
#endif
|
#endif
|
||||||
@@ -91,7 +93,7 @@
|
|||||||
* alternative to sockaddr_storage.
|
* alternative to sockaddr_storage.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
union dns_server_u
|
union dns_addr_u
|
||||||
{
|
{
|
||||||
struct sockaddr addr; /* Common address representation */
|
struct sockaddr addr; /* Common address representation */
|
||||||
#ifdef CONFIG_NET_IPv4
|
#ifdef CONFIG_NET_IPv4
|
||||||
@@ -118,7 +120,7 @@ extern "C"
|
|||||||
#ifndef CONFIG_NETDB_RESOLVCONF
|
#ifndef CONFIG_NETDB_RESOLVCONF
|
||||||
/* The DNS server address */
|
/* The DNS server address */
|
||||||
|
|
||||||
EXTERN union dns_server_u g_dns_server;
|
EXTERN union dns_addr_u g_dns_server;
|
||||||
EXTERN bool g_dns_address; /* true: We have the address of the DNS server */
|
EXTERN bool g_dns_address; /* true: We have the address of the DNS server */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -184,19 +186,19 @@ int dns_bind(void);
|
|||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* sd - The socket descriptor previously initialized by dsn_bind().
|
* sd - The socket descriptor previously initialized by dsn_bind().
|
||||||
* hostname - The hostname string to be resolved.
|
* hostname - The hostname string to be resolved.
|
||||||
* addr - The location to return the IP address associated with the
|
* addr - The location to return the IP addresses associated with the
|
||||||
* hostname
|
* hostname.
|
||||||
* addrlen - On entry, the size of the buffer backing up the 'addr'
|
* naddr - On entry, the count of addresses backing up the 'addr'
|
||||||
* pointer. On return, this location will hold the actual size of
|
* pointer. On return, this location will hold the actual count of
|
||||||
* the returned address.
|
* the returned addresses.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Returns zero (OK) if the query was successful.
|
* Returns zero (OK) if the query was successful.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int dns_query(int sd, FAR const char *hostname, FAR struct sockaddr *addr,
|
int dns_query(int sd, FAR const char *hostname, FAR union dns_addr_u *addr,
|
||||||
FAR socklen_t *addrlen);
|
FAR int *naddr);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: dns_save_answer
|
* Name: dns_save_answer
|
||||||
@@ -206,8 +208,8 @@ int dns_query(int sd, FAR const char *hostname, FAR struct sockaddr *addr,
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* hostname - The hostname string to be cached.
|
* hostname - The hostname string to be cached.
|
||||||
* addr - The IP address associated with the hostname
|
* addr - The IP addresses associated with the hostname.
|
||||||
* addrlen - The size of the of the IP address.
|
* naddr - The count of the IP addresses.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
@@ -216,7 +218,7 @@ int dns_query(int sd, FAR const char *hostname, FAR struct sockaddr *addr,
|
|||||||
|
|
||||||
#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0
|
#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0
|
||||||
void dns_save_answer(FAR const char *hostname,
|
void dns_save_answer(FAR const char *hostname,
|
||||||
FAR const struct sockaddr *addr, socklen_t addrlen);
|
FAR const union dns_addr_u *addr, int naddr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -227,11 +229,11 @@ void dns_save_answer(FAR const char *hostname,
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* hostname - The hostname string to be resolved.
|
* hostname - The hostname string to be resolved.
|
||||||
* addr - The location to return the IP address associated with the
|
* addr - The location to return the IP addresses associated with the
|
||||||
* hostname
|
* hostname.
|
||||||
* addrlen - On entry, the size of the buffer backing up the 'addr'
|
* naddr - On entry, the count of addresses backing up the 'addr'
|
||||||
* pointer. On return, this location will hold the actual size of
|
* pointer. On return, this location will hold the actual count of
|
||||||
* the returned address.
|
* the returned addresses.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* If the host name was successfully found in the DNS name resolution
|
* If the host name was successfully found in the DNS name resolution
|
||||||
@@ -242,8 +244,8 @@ void dns_save_answer(FAR const char *hostname,
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0
|
#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0
|
||||||
int dns_find_answer(FAR const char *hostname, FAR struct sockaddr *addr,
|
int dns_find_answer(FAR const char *hostname, FAR union dns_addr_u *addr,
|
||||||
FAR socklen_t *addrlen);
|
FAR int *naddr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
#ifndef CONFIG_NETDB_RESOLVCONF
|
#ifndef CONFIG_NETDB_RESOLVCONF
|
||||||
/* The DNS server address */
|
/* The DNS server address */
|
||||||
|
|
||||||
union dns_server_u g_dns_server;
|
union dns_addr_u g_dns_server;
|
||||||
bool g_dns_address; /* true: We have the address of the DNS server */
|
bool g_dns_address; /* true: We have the address of the DNS server */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
@@ -65,15 +66,20 @@
|
|||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* This described one entry in the cache of resolved hostnames */
|
/* This described one entry in the cache of resolved hostnames.
|
||||||
|
*
|
||||||
|
* REVISIT: this consumes extra space, especially when multiple
|
||||||
|
* addresses per name are stored.
|
||||||
|
*/
|
||||||
|
|
||||||
struct dns_cache_s
|
struct dns_cache_s
|
||||||
{
|
{
|
||||||
#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0
|
#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0
|
||||||
time_t ctime; /* Creation time */
|
time_t ctime; /* Creation time */
|
||||||
#endif
|
#endif
|
||||||
char name[CONFIG_NETDB_DNSCLIENT_NAMESIZE];
|
char name[CONFIG_NETDB_DNSCLIENT_NAMESIZE];
|
||||||
union dns_server_u addr; /* Resolved address */
|
uint8_t naddr; /* How many addresses per name */
|
||||||
|
union dns_addr_u addr[CONFIG_NETDB_DNSCLIENT_MAXIP]; /* Resolved address */
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -103,8 +109,8 @@ static struct dns_cache_s g_dns_cache[CONFIG_NETDB_DNSCLIENT_ENTRIES];
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* hostname - The hostname string to be cached.
|
* hostname - The hostname string to be cached.
|
||||||
* addr - The IP address associated with the hostname
|
* addr - The IP addresses associated with the hostname.
|
||||||
* addrlen - The size of the of the IP address.
|
* naddr - The count of the IP addresses.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
@@ -112,7 +118,7 @@ static struct dns_cache_s g_dns_cache[CONFIG_NETDB_DNSCLIENT_ENTRIES];
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void dns_save_answer(FAR const char *hostname,
|
void dns_save_answer(FAR const char *hostname,
|
||||||
FAR const struct sockaddr *addr, socklen_t addrlen)
|
FAR const union dns_addr_u *addr, int naddr)
|
||||||
{
|
{
|
||||||
FAR struct dns_cache_s *entry;
|
FAR struct dns_cache_s *entry;
|
||||||
#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0
|
#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0
|
||||||
@@ -121,6 +127,9 @@ void dns_save_answer(FAR const char *hostname,
|
|||||||
int next;
|
int next;
|
||||||
int ndx;
|
int ndx;
|
||||||
|
|
||||||
|
naddr = MIN(naddr, CONFIG_NETDB_DNSCLIENT_MAXIP);
|
||||||
|
DEBUGASSERT(naddr >= 1 && naddr <= UCHAR_MAX);
|
||||||
|
|
||||||
/* Get exclusive access to the DNS cache */
|
/* Get exclusive access to the DNS cache */
|
||||||
|
|
||||||
dns_semtake();
|
dns_semtake();
|
||||||
@@ -161,7 +170,8 @@ void dns_save_answer(FAR const char *hostname,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
strncpy(entry->name, hostname, CONFIG_NETDB_DNSCLIENT_NAMESIZE);
|
strncpy(entry->name, hostname, CONFIG_NETDB_DNSCLIENT_NAMESIZE);
|
||||||
memcpy(&entry->addr.addr, addr, addrlen);
|
memcpy(&entry->addr, addr, naddr * sizeof(*addr));
|
||||||
|
entry->naddr = naddr;
|
||||||
|
|
||||||
/* Save the updated head index */
|
/* Save the updated head index */
|
||||||
|
|
||||||
@@ -177,11 +187,11 @@ void dns_save_answer(FAR const char *hostname,
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* hostname - The hostname string to be resolved.
|
* hostname - The hostname string to be resolved.
|
||||||
* addr - The location to return the IP address associated with the
|
* addr - The location to return the IP addresses associated with the
|
||||||
* hostname
|
* hostname.
|
||||||
* addrlen - On entry, the size of the buffer backing up the 'addr'
|
* naddr - On entry, the count of addresses backing up the 'addr'
|
||||||
* pointer. On return, this location will hold the actual size of
|
* pointer. On return, this location will hold the actual count of
|
||||||
* the returned address.
|
* the returned addresses.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* If the host name was successfully found in the DNS name resolution
|
* If the host name was successfully found in the DNS name resolution
|
||||||
@@ -191,8 +201,8 @@ void dns_save_answer(FAR const char *hostname,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int dns_find_answer(FAR const char *hostname, FAR struct sockaddr *addr,
|
int dns_find_answer(FAR const char *hostname, FAR union dns_addr_u *addr,
|
||||||
FAR socklen_t *addrlen)
|
FAR int *naddr)
|
||||||
{
|
{
|
||||||
FAR struct dns_cache_s *entry;
|
FAR struct dns_cache_s *entry;
|
||||||
#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0
|
#if CONFIG_NETDB_DNSCLIENT_LIFESEC > 0
|
||||||
@@ -221,8 +231,6 @@ int dns_find_answer(FAR const char *hostname, FAR struct sockaddr *addr,
|
|||||||
ret = clock_gettime(DNS_CLOCK, &now);
|
ret = clock_gettime(DNS_CLOCK, &now);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* REVISIT: This is not thread safe */
|
|
||||||
|
|
||||||
for (ndx = g_dns_tail; ndx != g_dns_head; ndx = next)
|
for (ndx = g_dns_tail; ndx != g_dns_head; ndx = next)
|
||||||
{
|
{
|
||||||
entry = &g_dns_cache[ndx];
|
entry = &g_dns_cache[ndx];
|
||||||
@@ -263,41 +271,17 @@ int dns_find_answer(FAR const char *hostname, FAR struct sockaddr *addr,
|
|||||||
|
|
||||||
if (strncmp(hostname, entry->name, CONFIG_NETDB_DNSCLIENT_NAMESIZE) == 0)
|
if (strncmp(hostname, entry->name, CONFIG_NETDB_DNSCLIENT_NAMESIZE) == 0)
|
||||||
{
|
{
|
||||||
socklen_t inlen;
|
|
||||||
|
|
||||||
/* We have a match. Return the resolved host address */
|
/* We have a match. Return the resolved host address */
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv4
|
|
||||||
#ifdef CONFIG_NET_IPv6
|
|
||||||
if (entry->addr.addr.sa_family == AF_INET)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
inlen = sizeof(struct sockaddr_in);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv6
|
|
||||||
#ifdef CONFIG_NET_IPv4
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
inlen = sizeof(struct sockaddr_in6);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* Make sure that the address will fit in the caller-provided
|
/* Make sure that the address will fit in the caller-provided
|
||||||
* buffer.
|
* buffer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (*addrlen < inlen)
|
*naddr = MIN(*naddr, entry->naddr);
|
||||||
{
|
|
||||||
ret = -ERANGE;
|
|
||||||
goto errout_with_sem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the address information */
|
/* Return the address information */
|
||||||
|
|
||||||
memcpy(addr, &entry->addr.addr, inlen);
|
memcpy(addr, &entry->addr, *naddr * sizeof(*addr));
|
||||||
*addrlen = inlen;
|
|
||||||
|
|
||||||
dns_semgive();
|
dns_semgive();
|
||||||
return OK;
|
return OK;
|
||||||
@@ -307,7 +291,6 @@ int dns_find_answer(FAR const char *hostname, FAR struct sockaddr *addr,
|
|||||||
|
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
|
|
||||||
errout_with_sem:
|
|
||||||
dns_semgive();
|
dns_semgive();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ static FAR char *find_spaces(FAR char *ptr)
|
|||||||
|
|
||||||
int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg)
|
int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg)
|
||||||
{
|
{
|
||||||
union dns_server_u u;
|
union dns_addr_u u;
|
||||||
FAR FILE *stream;
|
FAR FILE *stream;
|
||||||
char line[DNS_MAX_LINE];
|
char line[DNS_MAX_LINE];
|
||||||
FAR char *addrstr;
|
FAR char *addrstr;
|
||||||
|
|||||||
@@ -88,8 +88,8 @@ struct dns_query_s
|
|||||||
int sd; /* DNS server socket */
|
int sd; /* DNS server socket */
|
||||||
int result; /* Explanation of the failure */
|
int result; /* Explanation of the failure */
|
||||||
FAR const char *hostname; /* Hostname to lookup */
|
FAR const char *hostname; /* Hostname to lookup */
|
||||||
FAR struct sockaddr *addr; /* Location to return host address */
|
FAR union dns_addr_u *addr; /* Location to return host address */
|
||||||
FAR socklen_t *addrlen; /* Length of the address */
|
FAR int *naddr; /* Number of returned addresses */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Query info to check response against. */
|
/* Query info to check response against. */
|
||||||
@@ -205,7 +205,7 @@ static inline uint16_t dns_alloc_id(void)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int dns_send_query(int sd, FAR const char *name,
|
static int dns_send_query(int sd, FAR const char *name,
|
||||||
FAR union dns_server_u *uaddr, uint16_t rectype,
|
FAR union dns_addr_u *uaddr, uint16_t rectype,
|
||||||
FAR struct dns_query_info_s *qinfo)
|
FAR struct dns_query_info_s *qinfo)
|
||||||
{
|
{
|
||||||
FAR struct dns_header_s *hdr;
|
FAR struct dns_header_s *hdr;
|
||||||
@@ -337,10 +337,13 @@ static int dns_send_query(int sd, FAR const char *name,
|
|||||||
* Description:
|
* Description:
|
||||||
* Called when new UDP data arrives
|
* Called when new UDP data arrives
|
||||||
*
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Returns number of valid IP address responses. Negated errno value is
|
||||||
|
* returned in all other cases.
|
||||||
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int dns_recv_response(int sd, FAR struct sockaddr *addr,
|
static int dns_recv_response(int sd, FAR union dns_addr_u *addr, int *naddr,
|
||||||
FAR socklen_t *addrlen,
|
|
||||||
FAR struct dns_query_info_s *qinfo)
|
FAR struct dns_query_info_s *qinfo)
|
||||||
{
|
{
|
||||||
FAR uint8_t *nameptr;
|
FAR uint8_t *nameptr;
|
||||||
@@ -352,8 +355,9 @@ static int dns_recv_response(int sd, FAR struct sockaddr *addr,
|
|||||||
FAR struct dns_question_s *que;
|
FAR struct dns_question_s *que;
|
||||||
uint16_t nquestions;
|
uint16_t nquestions;
|
||||||
uint16_t nanswers;
|
uint16_t nanswers;
|
||||||
union dns_server_u recvaddr;
|
union dns_addr_u recvaddr;
|
||||||
socklen_t raddrlen;
|
socklen_t raddrlen;
|
||||||
|
int naddr_read;
|
||||||
int errcode;
|
int errcode;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -535,6 +539,9 @@ static int dns_recv_response(int sd, FAR struct sockaddr *addr,
|
|||||||
|
|
||||||
nameptr += sizeof(struct dns_question_s);
|
nameptr += sizeof(struct dns_question_s);
|
||||||
|
|
||||||
|
ret = OK;
|
||||||
|
naddr_read = 0;
|
||||||
|
|
||||||
for (; nanswers > 0; nanswers--)
|
for (; nanswers > 0; nanswers--)
|
||||||
{
|
{
|
||||||
/* Each answer starts with a name */
|
/* Each answer starts with a name */
|
||||||
@@ -542,7 +549,8 @@ static int dns_recv_response(int sd, FAR struct sockaddr *addr,
|
|||||||
nameptr = dns_parse_name(nameptr, endofbuffer);
|
nameptr = dns_parse_name(nameptr, endofbuffer);
|
||||||
if (nameptr == endofbuffer)
|
if (nameptr == endofbuffer)
|
||||||
{
|
{
|
||||||
return -EILSEQ;
|
ret = -EILSEQ;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ans = (FAR struct dns_answer_s *)nameptr;
|
ans = (FAR struct dns_answer_s *)nameptr;
|
||||||
@@ -562,7 +570,7 @@ static int dns_recv_response(int sd, FAR struct sockaddr *addr,
|
|||||||
ans->len == HTONS(4) &&
|
ans->len == HTONS(4) &&
|
||||||
nameptr + 10 + 4 <= endofbuffer)
|
nameptr + 10 + 4 <= endofbuffer)
|
||||||
{
|
{
|
||||||
ans->u.ipv4.s_addr = *(FAR uint32_t *)(nameptr + 10);
|
nameptr += 10 + 4;
|
||||||
|
|
||||||
ninfo("IPv4 address: %d.%d.%d.%d\n",
|
ninfo("IPv4 address: %d.%d.%d.%d\n",
|
||||||
(ans->u.ipv4.s_addr ) & 0xff,
|
(ans->u.ipv4.s_addr ) & 0xff,
|
||||||
@@ -570,21 +578,25 @@ static int dns_recv_response(int sd, FAR struct sockaddr *addr,
|
|||||||
(ans->u.ipv4.s_addr >> 16) & 0xff,
|
(ans->u.ipv4.s_addr >> 16) & 0xff,
|
||||||
(ans->u.ipv4.s_addr >> 24) & 0xff);
|
(ans->u.ipv4.s_addr >> 24) & 0xff);
|
||||||
|
|
||||||
if (*addrlen >= sizeof(struct sockaddr_in))
|
if (naddr_read < *naddr)
|
||||||
{
|
{
|
||||||
FAR struct sockaddr_in *inaddr;
|
FAR struct sockaddr_in *inaddr;
|
||||||
|
|
||||||
inaddr = (FAR struct sockaddr_in *)addr;
|
inaddr = (FAR struct sockaddr_in *)&addr[naddr_read].addr;
|
||||||
inaddr->sin_family = AF_INET;
|
inaddr->sin_family = AF_INET;
|
||||||
inaddr->sin_port = 0;
|
inaddr->sin_port = 0;
|
||||||
inaddr->sin_addr.s_addr = ans->u.ipv4.s_addr;
|
inaddr->sin_addr.s_addr = ans->u.ipv4.s_addr;
|
||||||
|
|
||||||
*addrlen = sizeof(struct sockaddr_in);
|
naddr_read++;
|
||||||
return OK;
|
if (naddr_read >= *naddr)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return -ERANGE;
|
ret = -ERANGE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -595,7 +607,7 @@ static int dns_recv_response(int sd, FAR struct sockaddr *addr,
|
|||||||
ans->len == HTONS(16) &&
|
ans->len == HTONS(16) &&
|
||||||
nameptr + 10 + 16 <= endofbuffer)
|
nameptr + 10 + 16 <= endofbuffer)
|
||||||
{
|
{
|
||||||
memcpy(&ans->u.ipv6.s6_addr, nameptr + 10, 16);
|
nameptr += 10 + 16;
|
||||||
|
|
||||||
ninfo("IPv6 address: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
|
ninfo("IPv6 address: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
|
||||||
htons(ans->u.ipv6.s6_addr[7]), htons(ans->u.ipv6.s6_addr[6]),
|
htons(ans->u.ipv6.s6_addr[7]), htons(ans->u.ipv6.s6_addr[6]),
|
||||||
@@ -603,21 +615,25 @@ static int dns_recv_response(int sd, FAR struct sockaddr *addr,
|
|||||||
htons(ans->u.ipv6.s6_addr[3]), htons(ans->u.ipv6.s6_addr[2]),
|
htons(ans->u.ipv6.s6_addr[3]), htons(ans->u.ipv6.s6_addr[2]),
|
||||||
htons(ans->u.ipv6.s6_addr[1]), htons(ans->u.ipv6.s6_addr[0]));
|
htons(ans->u.ipv6.s6_addr[1]), htons(ans->u.ipv6.s6_addr[0]));
|
||||||
|
|
||||||
if (*addrlen >= sizeof(struct sockaddr_in6))
|
if (naddr_read < *naddr)
|
||||||
{
|
{
|
||||||
FAR struct sockaddr_in6 *inaddr;
|
FAR struct sockaddr_in6 *inaddr;
|
||||||
|
|
||||||
inaddr = (FAR struct sockaddr_in6 *)addr;
|
inaddr = (FAR struct sockaddr_in6 *)&addr[naddr_read].addr;
|
||||||
inaddr->sin6_family = AF_INET;
|
inaddr->sin6_family = AF_INET6;
|
||||||
inaddr->sin6_port = 0;
|
inaddr->sin6_port = 0;
|
||||||
memcpy(inaddr->sin6_addr.s6_addr, ans->u.ipv6.s6_addr, 16);
|
memcpy(inaddr->sin6_addr.s6_addr, ans->u.ipv6.s6_addr, 16);
|
||||||
|
|
||||||
*addrlen = sizeof(struct sockaddr_in6);
|
naddr_read++;
|
||||||
return OK;
|
if (naddr_read >= *naddr)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return -ERANGE;
|
ret = -ERANGE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -627,7 +643,17 @@ static int dns_recv_response(int sd, FAR struct sockaddr *addr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -EADDRNOTAVAIL;
|
if (naddr_read == 0 && ret == OK)
|
||||||
|
{
|
||||||
|
ret = -EADDRNOTAVAIL;
|
||||||
|
}
|
||||||
|
else if (naddr_read > 0 && ret != OK)
|
||||||
|
{
|
||||||
|
nwarn("Got an IP, but further parse returned %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
*naddr = naddr_read;
|
||||||
|
return (naddr_read > 0) ? naddr_read : ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -684,7 +710,7 @@ static int dns_query_callback(FAR void *arg, FAR struct sockaddr *addr,
|
|||||||
/* Send the IPv4 query */
|
/* Send the IPv4 query */
|
||||||
|
|
||||||
ret = dns_send_query(query->sd, query->hostname,
|
ret = dns_send_query(query->sd, query->hostname,
|
||||||
(FAR union dns_server_u *)addr,
|
(FAR union dns_addr_u *)addr,
|
||||||
DNS_RECTYPE_A, &qinfo);
|
DNS_RECTYPE_A, &qinfo);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
@@ -699,7 +725,7 @@ static int dns_query_callback(FAR void *arg, FAR struct sockaddr *addr,
|
|||||||
|
|
||||||
/* Obtain the IPv4 response */
|
/* Obtain the IPv4 response */
|
||||||
|
|
||||||
ret = dns_recv_response(query->sd, query->addr, query->addrlen,
|
ret = dns_recv_response(query->sd, query->addr, query->naddr,
|
||||||
&qinfo);
|
&qinfo);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
@@ -709,7 +735,7 @@ static int dns_query_callback(FAR void *arg, FAR struct sockaddr *addr,
|
|||||||
/* Save the answer in the DNS cache */
|
/* Save the answer in the DNS cache */
|
||||||
|
|
||||||
dns_save_answer(query->hostname, query->addr,
|
dns_save_answer(query->hostname, query->addr,
|
||||||
*query->addrlen);
|
*query->naddr);
|
||||||
#endif
|
#endif
|
||||||
/* Return 1 to indicate to (1) stop the traversal, and (2)
|
/* Return 1 to indicate to (1) stop the traversal, and (2)
|
||||||
* indicate that the address was found.
|
* indicate that the address was found.
|
||||||
@@ -749,7 +775,7 @@ static int dns_query_callback(FAR void *arg, FAR struct sockaddr *addr,
|
|||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv6
|
||||||
/* Is this an IPv6 address? */
|
/* Is this an IPv6 address? */
|
||||||
|
|
||||||
if (query->addr->sa_family == AF_INET6)
|
if (addr->sa_family == AF_INET6)
|
||||||
{
|
{
|
||||||
/* Yes.. verify the address size */
|
/* Yes.. verify the address size */
|
||||||
|
|
||||||
@@ -767,7 +793,7 @@ static int dns_query_callback(FAR void *arg, FAR struct sockaddr *addr,
|
|||||||
/* Send the IPv6 query */
|
/* Send the IPv6 query */
|
||||||
|
|
||||||
ret = dns_send_query(query->sd, query->hostname,
|
ret = dns_send_query(query->sd, query->hostname,
|
||||||
(FAR union dns_server_u *)addr,
|
(FAR union dns_addr_u *)addr,
|
||||||
DNS_RECTYPE_AAAA, &qinfo);
|
DNS_RECTYPE_AAAA, &qinfo);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
@@ -782,7 +808,7 @@ static int dns_query_callback(FAR void *arg, FAR struct sockaddr *addr,
|
|||||||
|
|
||||||
/* Obtain the IPv6 response */
|
/* Obtain the IPv6 response */
|
||||||
|
|
||||||
ret = dns_recv_response(query->sd, query->addr, query->addrlen,
|
ret = dns_recv_response(query->sd, query->addr, query->naddr,
|
||||||
&qinfo);
|
&qinfo);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
@@ -791,7 +817,7 @@ static int dns_query_callback(FAR void *arg, FAR struct sockaddr *addr,
|
|||||||
#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0
|
#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0
|
||||||
/* Save the answer in the DNS cache */
|
/* Save the answer in the DNS cache */
|
||||||
|
|
||||||
dns_save_answer(query->hostname, query->addr, *query->addrlen);
|
dns_save_answer(query->hostname, query->addr, *query->naddr);
|
||||||
#endif
|
#endif
|
||||||
/* Return 1 to indicate to (1) stop the traversal, and (2)
|
/* Return 1 to indicate to (1) stop the traversal, and (2)
|
||||||
* indicate that the address was found.
|
* indicate that the address was found.
|
||||||
@@ -859,19 +885,19 @@ static int dns_query_callback(FAR void *arg, FAR struct sockaddr *addr,
|
|||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* sd - The socket descriptor previously initialized by dsn_bind().
|
* sd - The socket descriptor previously initialized by dsn_bind().
|
||||||
* hostname - The hostname string to be resolved.
|
* hostname - The hostname string to be resolved.
|
||||||
* addr - The location to return the IP address associated with the
|
* addr - The location to return the IP addresses associated with the
|
||||||
* hostname
|
* hostname.
|
||||||
* addrlen - On entry, the size of the buffer backing up the 'addr'
|
* naddr - On entry, the count of addresses backing up the 'addr'
|
||||||
* pointer. On return, this location will hold the actual size of
|
* pointer. On return, this location will hold the actual count of
|
||||||
* the returned address.
|
* the returned addresses.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Returns zero (OK) if the query was successful.
|
* Returns zero (OK) if the query was successful.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int dns_query(int sd, FAR const char *hostname, FAR struct sockaddr *addr,
|
int dns_query(int sd, FAR const char *hostname, FAR union dns_addr_u *addr,
|
||||||
FAR socklen_t *addrlen)
|
FAR int *naddr)
|
||||||
{
|
{
|
||||||
FAR struct dns_query_s query;
|
FAR struct dns_query_s query;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -882,7 +908,7 @@ int dns_query(int sd, FAR const char *hostname, FAR struct sockaddr *addr,
|
|||||||
query.result = -EADDRNOTAVAIL;
|
query.result = -EADDRNOTAVAIL;
|
||||||
query.hostname = hostname;
|
query.hostname = hostname;
|
||||||
query.addr = addr;
|
query.addr = addr;
|
||||||
query.addrlen = addrlen;
|
query.naddr = naddr;
|
||||||
|
|
||||||
/* Perform the query. dns_foreach_nameserver() will return:
|
/* Perform the query. dns_foreach_nameserver() will return:
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -66,7 +66,7 @@
|
|||||||
|
|
||||||
struct hostent_info_s
|
struct hostent_info_s
|
||||||
{
|
{
|
||||||
FAR char *hi_addrlist[2];
|
FAR char *hi_addrlist[CONFIG_NETDB_DNSCLIENT_MAXIP + 1];
|
||||||
char hi_data[1];
|
char hi_data[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -360,9 +360,11 @@ static int lib_find_answer(FAR const char *name, FAR struct hostent *host,
|
|||||||
FAR char *ptr;
|
FAR char *ptr;
|
||||||
FAR void *addrdata;
|
FAR void *addrdata;
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
|
int naddr;
|
||||||
int addrtype;
|
int addrtype;
|
||||||
int namelen;
|
int namelen;
|
||||||
int ret;
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
/* Verify that we have a buffer big enough to get started (it still may not
|
/* Verify that we have a buffer big enough to get started (it still may not
|
||||||
* be big enough).
|
* be big enough).
|
||||||
@@ -379,13 +381,20 @@ static int lib_find_answer(FAR const char *name, FAR struct hostent *host,
|
|||||||
ptr = info->hi_data;
|
ptr = info->hi_data;
|
||||||
buflen -= (sizeof(struct hostent_info_s) - 1);
|
buflen -= (sizeof(struct hostent_info_s) - 1);
|
||||||
|
|
||||||
|
/* Verify again that there is space for at least one address. */
|
||||||
|
|
||||||
|
if (buflen < sizeof(union dns_addr_u))
|
||||||
|
{
|
||||||
|
return -ERANGE;
|
||||||
|
}
|
||||||
|
|
||||||
memset(host, 0, sizeof(struct hostent));
|
memset(host, 0, sizeof(struct hostent));
|
||||||
memset(info, 0, sizeof(struct hostent_info_s));
|
memset(info, 0, sizeof(struct hostent_info_s));
|
||||||
|
|
||||||
/* Try to get the host address using the DNS name server */
|
/* Try to get the host address using the DNS name server */
|
||||||
|
|
||||||
addrlen = buflen;
|
naddr = buflen / sizeof(union dns_addr_u);
|
||||||
ret = dns_find_answer(name, (FAR struct sockaddr *)ptr, &addrlen);
|
ret = dns_find_answer(name, (FAR union dns_addr_u *)ptr, &naddr);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
/* No, nothing found in the cache */
|
/* No, nothing found in the cache */
|
||||||
@@ -393,41 +402,45 @@ static int lib_find_answer(FAR const char *name, FAR struct hostent *host,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the address type; verify the address size. */
|
DEBUGASSERT(naddr <= CONFIG_NETDB_DNSCLIENT_MAXIP);
|
||||||
|
|
||||||
|
/* Get the address type. */
|
||||||
|
|
||||||
|
for (i = 0; i < naddr; i++)
|
||||||
|
{
|
||||||
#ifdef CONFIG_NET_IPv4
|
#ifdef CONFIG_NET_IPv4
|
||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv6
|
||||||
if (((FAR struct sockaddr_in *)ptr)->sin_family == AF_INET)
|
if (((FAR struct sockaddr_in *)ptr)->sin_family == AF_INET)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
DEBUGASSERT(addrlen == sizeof(struct sockaddr_in));
|
addrlen = sizeof(struct sockaddr_in);
|
||||||
addrlen = sizeof(struct sockaddr_in);
|
addrtype = AF_INET;
|
||||||
addrtype = AF_INET;
|
addrdata = &((FAR struct sockaddr_in *)ptr)->sin_addr;
|
||||||
addrdata = &((FAR struct sockaddr_in *)ptr)->sin_addr;
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv6
|
||||||
#ifdef CONFIG_NET_IPv4
|
#ifdef CONFIG_NET_IPv4
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
DEBUGASSERT(addrlen == sizeof(struct sockaddr_in6));
|
addrlen = sizeof(struct sockaddr_in6);
|
||||||
addrlen = sizeof(struct sockaddr_in6);
|
addrtype = AF_INET6;
|
||||||
addrtype = AF_INET6;
|
addrdata = &((FAR struct sockaddr_in6 *)ptr)->sin6_addr;
|
||||||
addrdata = &((FAR struct sockaddr_in6 *)ptr)->sin6_addr;
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* REVISIT: This assumes addresses are all either IPv4 or IPv6. */
|
||||||
|
|
||||||
|
info->hi_addrlist[i] = addrdata;
|
||||||
|
host->h_addrtype = addrtype;
|
||||||
|
host->h_length = addrlen;
|
||||||
|
|
||||||
|
ptr += sizeof(union dns_addr_u);
|
||||||
|
buflen -= sizeof(union dns_addr_u);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Yes.. Return the address that we obtained from the DNS cache. */
|
host->h_addr_list = info->hi_addrlist;
|
||||||
|
|
||||||
info->hi_addrlist[0] = addrdata;
|
|
||||||
host->h_addr_list = info->hi_addrlist;
|
|
||||||
host->h_addrtype = addrtype;
|
|
||||||
host->h_length = addrlen;
|
|
||||||
|
|
||||||
ptr += addrlen;
|
|
||||||
buflen -= addrlen;
|
|
||||||
|
|
||||||
/* And copy name */
|
/* And copy name */
|
||||||
|
|
||||||
@@ -459,7 +472,7 @@ static int lib_find_answer(FAR const char *name, FAR struct hostent *host,
|
|||||||
|
|
||||||
#ifdef CONFIG_NETDB_DNSCLIENT
|
#ifdef CONFIG_NETDB_DNSCLIENT
|
||||||
static int lib_dns_query(FAR const char *hostname,
|
static int lib_dns_query(FAR const char *hostname,
|
||||||
FAR struct sockaddr *addr, socklen_t *addrlen)
|
FAR union dns_addr_u *addr, int *naddr)
|
||||||
{
|
{
|
||||||
int sd;
|
int sd;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -474,7 +487,7 @@ static int lib_dns_query(FAR const char *hostname,
|
|||||||
|
|
||||||
/* Perform the query to get the IP address */
|
/* Perform the query to get the IP address */
|
||||||
|
|
||||||
ret = dns_query(sd, hostname, addr, addrlen);
|
ret = dns_query(sd, hostname, addr, naddr);
|
||||||
|
|
||||||
/* Release the socket */
|
/* Release the socket */
|
||||||
|
|
||||||
@@ -509,9 +522,11 @@ static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host,
|
|||||||
FAR char *ptr;
|
FAR char *ptr;
|
||||||
FAR void *addrdata;
|
FAR void *addrdata;
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
|
int naddr;
|
||||||
int addrtype;
|
int addrtype;
|
||||||
int namelen;
|
int namelen;
|
||||||
int ret;
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
/* Verify that we have a buffer big enough to get started (it still may not
|
/* Verify that we have a buffer big enough to get started (it still may not
|
||||||
* be big enough).
|
* be big enough).
|
||||||
@@ -528,26 +543,36 @@ static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host,
|
|||||||
ptr = info->hi_data;
|
ptr = info->hi_data;
|
||||||
buflen -= (sizeof(struct hostent_info_s) - 1);
|
buflen -= (sizeof(struct hostent_info_s) - 1);
|
||||||
|
|
||||||
|
/* Verify again that there is space for at least one address. */
|
||||||
|
|
||||||
|
if (buflen < sizeof(union dns_addr_u))
|
||||||
|
{
|
||||||
|
return -ERANGE;
|
||||||
|
}
|
||||||
|
|
||||||
memset(host, 0, sizeof(struct hostent));
|
memset(host, 0, sizeof(struct hostent));
|
||||||
memset(info, 0, sizeof(struct hostent_info_s));
|
memset(info, 0, sizeof(struct hostent_info_s));
|
||||||
|
|
||||||
/* Try to get the host address using the DNS name server */
|
/* Try to get the host address using the DNS name server */
|
||||||
|
|
||||||
addrlen = buflen;
|
naddr = buflen / sizeof(union dns_addr_u);
|
||||||
ret = lib_dns_query(name, (FAR struct sockaddr *)ptr, &addrlen);
|
ret = lib_dns_query(name, (FAR union dns_addr_u *)ptr, &naddr);
|
||||||
|
if (ret < 0)
|
||||||
/* Was the DNS lookup successful? */
|
|
||||||
|
|
||||||
if (ret >= 0)
|
|
||||||
{
|
{
|
||||||
/* Get the address type; verify the address size. */
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We can read more than maximum, limit here. */
|
||||||
|
|
||||||
|
naddr = MIN(naddr, CONFIG_NETDB_DNSCLIENT_MAXIP);
|
||||||
|
|
||||||
|
for (i = 0; i < naddr; i++)
|
||||||
|
{
|
||||||
#ifdef CONFIG_NET_IPv4
|
#ifdef CONFIG_NET_IPv4
|
||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv6
|
||||||
if (((FAR struct sockaddr_in *)ptr)->sin_family == AF_INET)
|
if (((FAR struct sockaddr_in *)ptr)->sin_family == AF_INET)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
DEBUGASSERT(addrlen == sizeof(struct sockaddr_in));
|
|
||||||
addrlen = sizeof(struct sockaddr_in);
|
addrlen = sizeof(struct sockaddr_in);
|
||||||
addrtype = AF_INET;
|
addrtype = AF_INET;
|
||||||
addrdata = &((FAR struct sockaddr_in *)ptr)->sin_addr;
|
addrdata = &((FAR struct sockaddr_in *)ptr)->sin_addr;
|
||||||
@@ -559,40 +584,39 @@ static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host,
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
DEBUGASSERT(addrlen == sizeof(struct sockaddr_in6));
|
|
||||||
addrlen = sizeof(struct sockaddr_in6);
|
addrlen = sizeof(struct sockaddr_in6);
|
||||||
addrtype = AF_INET6;
|
addrtype = AF_INET6;
|
||||||
addrdata = &((FAR struct sockaddr_in6 *)ptr)->sin6_addr;
|
addrdata = &((FAR struct sockaddr_in6 *)ptr)->sin6_addr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Yes.. Return the address that we obtained from the DNS name server. */
|
/* REVISIT: This assumes addresses are all either IPv4 or IPv6. */
|
||||||
|
|
||||||
info->hi_addrlist[0] = addrdata;
|
info->hi_addrlist[i] = addrdata;
|
||||||
host->h_addr_list = info->hi_addrlist;
|
|
||||||
host->h_addrtype = addrtype;
|
host->h_addrtype = addrtype;
|
||||||
host->h_length = addrlen;
|
host->h_length = addrlen;
|
||||||
|
|
||||||
ptr += addrlen;
|
ptr += sizeof(union dns_addr_u);
|
||||||
buflen -= addrlen;
|
buflen -= sizeof(union dns_addr_u);
|
||||||
|
|
||||||
/* And copy name */
|
|
||||||
|
|
||||||
namelen = strlen(name);
|
|
||||||
if ((namelen + 1) > buflen)
|
|
||||||
{
|
|
||||||
return -ERANGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(ptr, name, buflen);
|
|
||||||
|
|
||||||
/* Set the address to h_name */
|
|
||||||
|
|
||||||
host->h_name = ptr;
|
|
||||||
return OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
host->h_addr_list = info->hi_addrlist;
|
||||||
|
|
||||||
|
/* And copy name */
|
||||||
|
|
||||||
|
namelen = strlen(name);
|
||||||
|
if ((namelen + 1) > buflen)
|
||||||
|
{
|
||||||
|
return -ERANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(ptr, name, buflen);
|
||||||
|
|
||||||
|
/* Set the address to h_name */
|
||||||
|
|
||||||
|
host->h_name = ptr;
|
||||||
|
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NETDB_DNSCLIENT */
|
#endif /* CONFIG_NETDB_DNSCLIENT */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user