diff --git a/include/nuttx/net/dns.h b/include/nuttx/net/dns.h index 0886a4b7752..cac5436caef 100644 --- a/include/nuttx/net/dns.h +++ b/include/nuttx/net/dns.h @@ -54,19 +54,6 @@ * Pre-processor Definitions ****************************************************************************/ - /* If both IPv4 and IPv6 are enabled, the DNS client can support only one or - * the other. - */ - -#if !defined(CONFIG_NETDB_DNSCLIENT_IPv4) && \ - !defined(CONFIG_NETDB_DNSCLIENT_IPv6) -# ifdef CONFIG_NET_IPv6 -# define CONFIG_NETDB_DNSCLIENT_IPv6 1 -# else -# define CONFIG_NETDB_DNSCLIENT_IPv4 1 -# endif -#endif - #define DNS_FLAG1_RESPONSE 0x80 #define DNS_FLAG1_OPCODE_STATUS 0x10 #define DNS_FLAG1_OPCODE_INVERSE 0x08 @@ -108,7 +95,7 @@ struct dns_answer_s uint16_t class; uint16_t ttl[2]; uint16_t len; -#ifdef CONFIG_NETDB_DNSCLIENT_IPv6 +#if 0 /* REVISIT: Not yet support for IPv6 */ struct in6_addr ipaddr; #else struct in_addr ipaddr; diff --git a/libc/Kconfig b/libc/Kconfig index d45dd35f249..747c94a62b7 100644 --- a/libc/Kconfig +++ b/libc/Kconfig @@ -544,21 +544,6 @@ config NETDB_DNSCLIENT if NETDB_DNSCLIENT -choice - prompt "Internet Protocol" - default NETDB_DNSCLIENT_IPv4 if NET_IPv4 - default NETDB_DNSCLIENT_IPv6 if NET_IPv6 && !NET_IPv4 - -config NETDB_DNSCLIENT_IPv4 - bool "IPv4" - depends on NET_IPv4 - -config NETDB_DNSCLIENT_IPv6 - bool "IPv6" - depends on NET_IPv6 - -endchoice # Internet Protocol - config NETDB_DNSCLIENT_ENTRIES int "Number of DNS resolver entries" default 8 @@ -575,7 +560,6 @@ config NETDB_DNSCLIENT_MAXRESPONSE endif # NETDB_DNSCLIENT - comment "Non-standard Library Support" if BUILD_PROTECTED || BUILD_KERNEL diff --git a/libc/netdb/lib_dns.h b/libc/netdb/lib_dns.h index f3198a831da..35485140ba7 100644 --- a/libc/netdb/lib_dns.h +++ b/libc/netdb/lib_dns.h @@ -45,6 +45,7 @@ #include +#include #include #include @@ -65,21 +66,6 @@ # define CONFIG_NETDB_DNSCLIENT_MAXRESPONSE 96 #endif -/**************************************************************************** - * Public Types - ****************************************************************************/ - -union dns_server_u -{ - struct sockaddr addr; -#ifdef CONFIG_NET_IPv4 - struct sockaddr_in ipv4; -#endif -#ifdef CONFIG_NET_IPv6 - struct sockaddr_in6 ipv6; -#endif -}; - /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -115,7 +101,7 @@ int dns_bind(void); * Name: dns_query * * Description: - * Using the DNS resolver socket (sockfd), look up the the 'hostname', and + * Using the DNS resolver socket (sd), look up the the 'hostname', and * return its IP address in 'ipaddr' * * Returned Value: @@ -123,7 +109,8 @@ int dns_bind(void); * ****************************************************************************/ -int dns_query(int sockfd, FAR const char *hostname, FAR in_addr_t *ipaddr); +int dns_query(int sd, FAR const char *hostname, FAR struct sockaddr *addr, + FAR socklen_t *addrlen); #undef EXTERN #if defined(__cplusplus) diff --git a/libc/netdb/lib_dnsclient.c b/libc/netdb/lib_dnsclient.c index dd8f0a1e578..66b7f2d9cf7 100644 --- a/libc/netdb/lib_dnsclient.c +++ b/libc/netdb/lib_dnsclient.c @@ -75,6 +75,21 @@ #define SEND_BUFFER_SIZE 64 #define RECV_BUFFER_SIZE CONFIG_NETDB_DNSCLIENT_MAXRESPONSE +/**************************************************************************** + * Private Types + ****************************************************************************/ + +union dns_server_u +{ + struct sockaddr addr; +#ifdef CONFIG_NET_IPv4 + struct sockaddr_in ipv4; +#endif +#ifdef CONFIG_NET_IPv6 + struct sockaddr_in6 ipv6; +#endif +}; + /**************************************************************************** * Private Data ****************************************************************************/ @@ -205,11 +220,8 @@ static int dns_send_query(int sd, FAR const char *name, * ****************************************************************************/ -#ifdef CONFIG_NETDB_DNSCLIENT_IPv6 -# error "Not implemented" -#else -static int dns_recv_response(int sd, FAR struct sockaddr_in *addr) -#endif +static int dns_recv_response(int sd, FAR struct sockaddr *addr, + FAR socklen_t *addrlen) { FAR unsigned char *nameptr; char buffer[RECV_BUFFER_SIZE]; @@ -314,6 +326,11 @@ static int dns_recv_response(int sd, FAR struct sockaddr_in *addr) /* Check for IP address type and Internet class. Others are discarded. */ +#ifdef CONFIG_NET_IPv6 +# warning Missing IPv6 support! +#endif + +#ifdef CONFIG_NET_IPv4 if (ans->type == HTONS(1) && ans->class == HTONS(1) && ans->len == HTONS(4)) @@ -330,10 +347,25 @@ static int dns_recv_response(int sd, FAR struct sockaddr_in *addr) * we want. */ - addr->sin_addr.s_addr = ans->ipaddr.s_addr; - return OK; + if (*addrlen >=sizeof(struct sockaddr_in)) + { + FAR struct sockaddr_in *inaddr; + + inaddr = (FAR struct sockaddr_in *)addr; + inaddr->sin_family = AF_INET; + inaddr->sin_port = 0; + inaddr->sin_addr.s_addr = ans->ipaddr.s_addr; + + *addrlen = sizeof(struct sockaddr_in); + return OK; + } + else + { + return -ERANGE; + } } else +#endif { nameptr = nameptr + 10 + htons(ans->len); } @@ -408,13 +440,9 @@ int dns_bind(void) * ****************************************************************************/ -int dns_query(int sd, FAR const char *hostname, FAR in_addr_t *ipaddr) +int dns_query(int sd, FAR const char *hostname, FAR struct sockaddr *addr, + FAR socklen_t *addrlen) { -#ifdef CONFIG_NETDB_DNSCLIENT_IPv6 - struct sockaddr_in6 addr; -#else - struct sockaddr_in addr; -#endif int retries; int ret; @@ -433,13 +461,12 @@ int dns_query(int sd, FAR const char *hostname, FAR in_addr_t *ipaddr) /* Obtain the response */ - ret = dns_recv_response(sd, &addr); + ret = dns_recv_response(sd, addr, addrlen); if (ret >= 0) { /* Response received successfully */ /* Save the host address -- Needs fixed for IPv6 */ - *ipaddr = addr.sin_addr.s_addr; return OK; } diff --git a/libc/netdb/lib_gethostbynamer.c b/libc/netdb/lib_gethostbynamer.c index 8d5d073e1e5..4d69c482e8f 100644 --- a/libc/netdb/lib_gethostbynamer.c +++ b/libc/netdb/lib_gethostbynamer.c @@ -46,6 +46,7 @@ #include #include #include +#include #include @@ -203,11 +204,8 @@ static int lib_numeric_address(FAR const char *name, FAR struct hostent *host, * ****************************************************************************/ -#ifdef CONFIG_NETDB_DNSCLIENT_IPv6 -static int lib_dns_query(FAR const char *hostname, FAR struct in6_addr *ipaddr) -#else -static int lib_dns_query(FAR const char *hostname, FAR in_addr_t *ipaddr) -#endif +static int lib_dns_query(FAR const char *hostname, + FAR struct sockaddr *addr, socklen_t *addrlen) { int sd; int ret; @@ -222,7 +220,7 @@ static int lib_dns_query(FAR const char *hostname, FAR in_addr_t *ipaddr) /* Perform the query to get the IP address */ - ret = dns_query(sd, hostname, ipaddr); + ret = dns_query(sd, hostname, addr, addrlen); /* Release the socket */ @@ -236,7 +234,7 @@ static int lib_dns_query(FAR const char *hostname, FAR in_addr_t *ipaddr) * Description: * Try to look-up the host name from the DNS server * - * Input paramters: + * Input Parameters: * name - The name of the host to find. * host - Caller provided location to return the host data. * buf - Caller provided buffer to hold string data associated with the @@ -279,20 +277,37 @@ static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host, /* Try to get the host address using the DNS name server */ -#ifdef CONFIG_NETDB_DNSCLIENT_IPv6 - addrlen = sizeof(struct in6_addr); - addrtype = AF_INET6; - ret = lib_dns_query(name, (FAR struct in6_addr *)ptr); -#else - addrlen = sizeof(struct in6_addr); - addrtype = AF_INET; - ret = lib_dns_query(name, (FAR in_addr_t *)ptr); -#endif + addrlen = buflen; + ret = lib_dns_query(name, (FAR struct sockaddr *)ptr, &addrlen); /* Was the DNS lookup successful? */ if (ret >= 0) { + /* Get the address type; verify the address size. */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (((FAR struct sockaddr_in *)ptr)->sin_family == AF_INET) +#endif + { + DEBUGASSERT(addrlen == sizeof(struct sockaddr_in)); + addrlen = sizeof(struct sockaddr_in); + addrtype = AF_INET; + } +#endif + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + DEBUGASSERT(addrlen == sizeof(struct sockaddr_in6)); + addrlen = sizeof(struct sockaddr_in6); + addrtype = AF_INET6; + } +#endif + /* Yes.. Return the address that we obtained from the DNS name server. */ info->hi_addrlist[0] = ptr;