From 7dec298ef3c439f1dd81a6c8a3e5914b0c5f66ac Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 10 Jul 2015 13:30:09 -0600 Subject: [PATCH] gethostbyname() will not attempt a DNS lookup if so enabled --- include/nuttx/net/dnsclient.h | 4 + libc/Kconfig | 6 +- libc/lib_internal.h | 1 + libc/net/Make.defs | 7 - libc/netdb/Make.defs | 13 +- libc/netdb/dns_gethostip.c | 4 + libc/netdb/lib_gethostbyname.c | 4 +- libc/netdb/lib_gethostbynamer.c | 242 +++++++++++++++++++++++++------- libc/netdb/lib_netdb.c | 4 +- libc/netdb/lib_netdb.h | 12 +- 10 files changed, 226 insertions(+), 71 deletions(-) diff --git a/include/nuttx/net/dnsclient.h b/include/nuttx/net/dnsclient.h index 91d513befd..c4a0f40014 100644 --- a/include/nuttx/net/dnsclient.h +++ b/include/nuttx/net/dnsclient.h @@ -206,7 +206,11 @@ int dns_whois(FAR const char *name, FAR struct sockaddr_in *addr); * ****************************************************************************/ +#ifdef CONFIG_NETDB_DNSCLIENT_IPv6 +int dns_gethostip(FAR const char *hostname, FAR struct in6_addr *ipaddr); +#else int dns_gethostip(FAR const char *hostname, FAR in_addr_t *ipaddr); +#endif #undef EXTERN #if defined(__cplusplus) diff --git a/libc/Kconfig b/libc/Kconfig index d1faff083f..d45dd35f24 100644 --- a/libc/Kconfig +++ b/libc/Kconfig @@ -513,6 +513,9 @@ menuconfig NETDB_HOSTFILE default n depends on FS_READABLE select LIBC_NETDB + ---help--- + Enable network host table look ups via gethostbyname() and + gethostbyaddr(). if NETDB_HOSTFILE @@ -536,7 +539,8 @@ config NETDB_DNSCLIENT depends on NET && NET_UDP select LIBC_NETDB ---help--- - Enable support for the name resolution. + Enable support for the name resolution; Enable network host + resolution via gethostbyname(). if NETDB_DNSCLIENT diff --git a/libc/lib_internal.h b/libc/lib_internal.h index 59b85a7aed..c4610dfe62 100644 --- a/libc/lib_internal.h +++ b/libc/lib_internal.h @@ -219,6 +219,7 @@ float lib_sqrtapprox(float x); /* Defined in lib_parsehostfile.c */ #ifdef CONFIG_NETDB_HOSTFILE +struct hostent; ssize_t lib_parse_hostfile(FAR FILE *stream, FAR struct hostent *host, FAR char *buf, size_t buflen); #endif diff --git a/libc/net/Make.defs b/libc/net/Make.defs index ce1b267015..6fe3cce9c2 100644 --- a/libc/net/Make.defs +++ b/libc/net/Make.defs @@ -44,13 +44,6 @@ ifeq ($(CONFIG_NET_ROUTE),y) CSRCS += lib_addroute.c lib_delroute.c endif -# netdb support - -ifeq ($(CONFIG_NETDB_HOSTFILE),y) -CSRCS += lib_netdb.c lib_gethostbyname.c lib_gethostbynamer.c -CSRCS += lib_gethostbyaddr.c lib_gethostbyaddrr.c lib_parsehostfile.c -endif - # Add the net directory to the build DEPPATH += --dep-path net diff --git a/libc/netdb/Make.defs b/libc/netdb/Make.defs index 5e52d5f644..a86c4db195 100644 --- a/libc/netdb/Make.defs +++ b/libc/netdb/Make.defs @@ -37,17 +37,22 @@ ifeq ($(CONFIG_LIBC_NETDB),y) # Add the netdb C files to the build +CSRCS += lib_netdb.c + # Add host file support ifeq ($(CONFIG_NETDB_HOSTFILE),y) -CSRCS += lib_netdb.c lib_gethostbyname.c lib_gethostbynamer.c -CSRCS += lib_gethostbyaddr.c lib_gethostbyaddrr.c lib_parsehostfile.c +CSRCS += lib_gethostbyname.c lib_gethostbynamer.c lib_gethostbyaddr.c +CSRCS += lib_gethostbyaddrr.c lib_parsehostfile.c endif -# Add DNS support +# Add DNS lookup support ifeq ($(CONFIG_NETDB_DNSCLIENT),y) -CSRCS = dns_resolver.c dns_socket.c dns_gethostip.c +ifneq ($(CONFIG_NETDB_HOSTFILE),y) +CSRCS += lib_gethostbyname.c lib_gethostbynamer.c +endif +CSRCS += dns_resolver.c dns_socket.c dns_gethostip.c endif # Add the net directory to the build diff --git a/libc/netdb/dns_gethostip.c b/libc/netdb/dns_gethostip.c index e02113d5a1..792fccc9ea 100644 --- a/libc/netdb/dns_gethostip.c +++ b/libc/netdb/dns_gethostip.c @@ -75,7 +75,11 @@ * ****************************************************************************/ +#ifdef CONFIG_NETDB_DNSCLIENT_IPv6 +int dns_gethostip(FAR const char *hostname, FAR struct in6_addr *ipaddr) +#else int dns_gethostip(FAR const char *hostname, FAR in_addr_t *ipaddr) +#endif { int sockfd = -1; int ret=ERROR; diff --git a/libc/netdb/lib_gethostbyname.c b/libc/netdb/lib_gethostbyname.c index ea613e6022..4aae74a204 100644 --- a/libc/netdb/lib_gethostbyname.c +++ b/libc/netdb/lib_gethostbyname.c @@ -45,7 +45,7 @@ #include "lib_internal.h" #include "netdb/lib_netdb.h" -#ifdef CONFIG_NETDB_HOSTFILE +#ifdef CONFIG_LIBC_NETDB /**************************************************************************** * Public Functions @@ -89,4 +89,4 @@ FAR struct hostent *gethostbyname(FAR const char *name) return ret == 0 ? &g_hostent : NULL; } -#endif /* CONFIG_NETDB_HOSTFILE */ +#endif /* CONFIG_LIBC_NETDB */ diff --git a/libc/netdb/lib_gethostbynamer.c b/libc/netdb/lib_gethostbynamer.c index 7e7c9e71f5..071444a650 100644 --- a/libc/netdb/lib_gethostbynamer.c +++ b/libc/netdb/lib_gethostbynamer.c @@ -47,9 +47,11 @@ #include +#include + #include "lib_internal.h" -#ifdef CONFIG_NETDB_HOSTFILE +#ifdef CONFIG_LIBC_NETDB /**************************************************************************** * Pre-processor Definitions @@ -189,71 +191,120 @@ static int lib_numeric_address(FAR const char *name, FAR struct hostent *host, } /**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: gethostname_r + * Name: lib_dns_lookup * * Description: - * The gethostbyname_r() function returns a structure of type hostent for - * the given host name. Here name is either a hostname, or an IPv4 address - * in standard dot notation (as for inet_addr(3)), or an IPv6 address in - * colon (and possibly dot) notation. + * Try to look-up the host name from the DNS server * - * If name is an IPv4 or IPv6 address, no lookup is performed and - * gethostbyname_r() simply copies name into the h_name field - * and its struct in_addr equivalent into the h_addr_list[0] field of the - * returned hostent structure. - * - * gethostname_r() is *not* POSIX but is similar to a Glibc extension and is - * used internally by NuttX to implement the POSIX gethostname(). - * - * Input Parameters: + * Input paramters: * 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 * host data. * buflen - The size of the caller-provided buffer - * h_errnop - There h_errno value returned in the event of a failure. * * Returned Value: - * Zero (OK) is returned on success, -1 (ERROR) is returned on a failure - * with the returned h_errno value provided the reason for the failure. + * Zero (0) is returned if the DNS lookup was successful. * ****************************************************************************/ -int gethostbyname_r(FAR const char *name, FAR struct hostent *host, - FAR char *buf, size_t buflen, int *h_errnop) +#ifdef CONFIG_NETDB_DNSCLIENT +static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host, + FAR char *buf, size_t buflen) +{ + FAR struct hostent_info_s *info; + FAR char *ptr; + size_t addrlen; + int addrtype; + int namelen; + int ret; + + /* Verify that we have a buffer big enough to get started (it still may not + * be big enough). + */ + + if (buflen <= sizeof(struct hostent_info_s)) + { + return -ERANGE; + } + + /* Initialize buffers */ + + info = (FAR struct hostent_info_s *)buf; + ptr = info->hi_data; + buflen -= (sizeof(struct hostent_info_s) - 1); + + memset(host, 0, sizeof(struct hostent)); + memset(info, 0, sizeof(struct hostent_info_s)); + + /* 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 = dns_gethostip(name, (FAR struct in6_addr *)ptr); +#else + addrlen = sizeof(struct in6_addr); + addrtype = AF_INET; + ret = dns_gethostip(name, (FAR in_addr_t *)ptr); +#endif + + /* Was the DNS lookup successful? */ + + if (ret >= 0) + { + /* Yes.. Return the address that we obtained from the DNS name server. */ + + info->hi_addrlist[0] = ptr; + host->h_addr_list = info->hi_addrlist; + host->h_addrtype = addrtype; + host->h_length = addrlen; + + ptr += addrlen; + buflen -= addrlen; + + /* And copy name */ + + namelen = strlen(name); + if (addrlen + namelen + 1 > buflen) + { + return -ERANGE; + } + + strncpy(ptr, name, buflen); + return OK; + } + + return ret; +} +#endif /* CONFIG_NETDB_DNSCLIENT */ + +/**************************************************************************** + * Name: lib_hostfile_lookup + * + * Description: + * Try to look-up the host name from the network host file + * + * Input paramters: + * 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 + * host data. + * buflen - The size of the caller-provided buffer + * + * Returned Value: + * Zero (0) is returned if the DNS lookup was successful. + * + ****************************************************************************/ + +#ifdef CONFIG_NETDB_HOSTFILE +static int lib_hostfile_lookup(FAR const char *name, FAR struct hostent *host, + FAR char *buf, size_t buflen, int *h_errnop) { FAR FILE *stream; int herrnocode; int nread; - DEBUGASSERT(name != NULL && host != NULL && buf != NULL); - - /* Make sure that the h_errno has a non-error code */ - - if (h_errnop) - { - *h_errnop = 0; - } - - /* Check for a numeric hostname */ - - if (lib_numeric_address(name, host, buf, buflen) == 0) - { - /* Yes.. we are done */ - - return OK; - } - - /* Try to find the name in the HOSTALIASES environment variable */ - /* REVISIT: Not implemented */ - - /* Try to get the host address using the DNS name server */ - /* REVISIT: Not implemented */ - /* Search the hosts file for a match */ stream = fopen(CONFIG_NETDB_HOSTCONF_PATH, "r"); @@ -352,5 +403,98 @@ errorout_with_herrnocode: return ERROR; } - #endif /* CONFIG_NETDB_HOSTFILE */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: gethostname_r + * + * Description: + * The gethostbyname_r() function returns a structure of type hostent for + * the given host name. Here name is either a hostname, or an IPv4 address + * in standard dot notation (as for inet_addr(3)), or an IPv6 address in + * colon (and possibly dot) notation. + * + * If name is an IPv4 or IPv6 address, no lookup is performed and + * gethostbyname_r() simply copies name into the h_name field + * and its struct in_addr equivalent into the h_addr_list[0] field of the + * returned hostent structure. + * + * gethostname_r() is *not* POSIX but is similar to a Glibc extension and is + * used internally by NuttX to implement the POSIX gethostname(). + * + * 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 + * host data. + * buflen - The size of the caller-provided buffer + * h_errnop - There h_errno value returned in the event of a failure. + * + * Returned Value: + * Zero (OK) is returned on success, -1 (ERROR) is returned on a failure + * with the returned h_errno value provided the reason for the failure. + * + ****************************************************************************/ + +int gethostbyname_r(FAR const char *name, FAR struct hostent *host, + FAR char *buf, size_t buflen, int *h_errnop) +{ + int ret; + + DEBUGASSERT(name != NULL && host != NULL && buf != NULL); + + /* Make sure that the h_errno has a non-error code */ + + if (h_errnop) + { + *h_errnop = 0; + } + + /* Check for a numeric hostname */ + + if (lib_numeric_address(name, host, buf, buflen) == 0) + { + /* Yes.. we are done */ + + return OK; + } + + /* Try to find the name in the HOSTALIASES environment variable */ + /* REVISIT: Not implemented */ + +#ifdef CONFIG_NETDB_DNSCLIENT + /* Try to get the host address using the DNS name server */ + + ret = lib_dns_lookup(name, host, buf, buflen); + if (ret >= 0) + { + /* Successful DNS lookup! */ + + return OK; + } +#endif /* CONFIG_NETDB_DNSCLIENT */ + +#ifdef CONFIG_NETDB_HOSTFILE + /* Search the hosts file for a match */ + + return lib_hostfile_lookup(name, host, buf, buflen, h_errnop); + +#else + /* The host file file is not supported. The host name mapping was not + * found from any lookup heuristic + */ + + if (h_errnop) + { + *h_errnop = HOST_NOT_FOUND; + } + + return ERROR; +#endif +} + +#endif /* CONFIG_LIBC_NETDB */ diff --git a/libc/netdb/lib_netdb.c b/libc/netdb/lib_netdb.c index 4aadbb91f1..c8e9e4de13 100644 --- a/libc/netdb/lib_netdb.c +++ b/libc/netdb/lib_netdb.c @@ -43,7 +43,7 @@ #include "netdb/lib_netdb.h" -#ifdef CONFIG_NETDB_HOSTFILE +#ifdef CONFIG_LIBC_NETDB /**************************************************************************** * Public Data @@ -56,4 +56,4 @@ char g_hostbuffer[CONFIG_NETDB_BUFSIZE]; * Public Functions ****************************************************************************/ -#endif /* CONFIG_NETDB_HOSTFILE */ +#endif /* CONFIG_LIBC_NETDB */ diff --git a/libc/netdb/lib_netdb.h b/libc/netdb/lib_netdb.h index 331fa98320..83f17aab79 100644 --- a/libc/netdb/lib_netdb.h +++ b/libc/netdb/lib_netdb.h @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/netdb/lib_netdb.h + * libc/net/lib_netdb.h * * Copyright (C) 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -33,8 +33,8 @@ * ****************************************************************************/ -#ifndef __LIBC_NET_LIB_NETDB_H -#define __LIBC_NET_LIB_NETDB_H +#ifndef __LIBC_NETDB_LIB_NETDB_H +#define __LIBC_NETDB_LIB_NETDB_H /**************************************************************************** * Included Files @@ -44,7 +44,7 @@ #include -#ifdef CONFIG_NETDB_HOSTFILE +#ifdef CONFIG_LIBC_NETDB /**************************************************************************** * Pre-processor Definitions @@ -94,5 +94,5 @@ EXTERN char g_hostbuffer[CONFIG_NETDB_BUFSIZE]; } #endif -#endif /* __INCLUDE_NETDB_H */ -#endif /* __LIBC_NET_LIB_NETDB_H */ +#endif /* CONFIG_LIBC_NETDB */ +#endif /* __LIBC_NETDB_LIB_NETDB_H */