[PATCH] gethostbyname(): correct returned address format when DNS is used. The hostent.h_addr_list should point to raw in_addr or in6_addr as defined in the standard. Original implementation used that

for numeric addresses but for DNS lookup returned pointer to whole sockaddr_in or sockaddr_in6.

getaddrinfo() should be preferred in a long term perspective. Return of complete addresses from the lookup would be better in such case but it requires significant changes anyway - multiple addresses support and most probably dynamic memory allocation which is bad for many RT applications. So gethostbyname() is sufficient for most applications now.

Signed-off-by: Pavel Pisa <ppisa@pikron.com>
This commit is contained in:
Pavel Pisa
2015-08-21 18:33:03 -06:00
committed by Gregory Nutt
parent 0b2fbd7a2c
commit 23035ca68d
3 changed files with 12 additions and 3 deletions
+8 -2
View File
@@ -236,6 +236,7 @@ static int lib_find_answer(FAR const char *name, FAR struct hostent *host,
{
FAR struct hostent_info_s *info;
FAR char *ptr;
FAR void *addrdata;
socklen_t addrlen;
int addrtype;
int namelen;
@@ -280,6 +281,7 @@ static int lib_find_answer(FAR const char *name, FAR struct hostent *host,
DEBUGASSERT(addrlen == sizeof(struct sockaddr_in));
addrlen = sizeof(struct sockaddr_in);
addrtype = AF_INET;
addrdata = &((FAR struct sockaddr_in *)ptr)->sin_addr;
}
#endif
@@ -291,12 +293,13 @@ static int lib_find_answer(FAR const char *name, FAR struct hostent *host,
DEBUGASSERT(addrlen == sizeof(struct sockaddr_in6));
addrlen = sizeof(struct sockaddr_in6);
addrtype = AF_INET6;
addrdata = &((FAR struct sockaddr_in6 *)ptr)->sin_addr;
}
#endif
/* Yes.. Return the address that we obtained from the DNS cache. */
info->hi_addrlist[0] = ptr;
info->hi_addrlist[0] = addrdata;
host->h_addr_list = info->hi_addrlist;
host->h_addrtype = addrtype;
host->h_length = addrlen;
@@ -377,6 +380,7 @@ static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host,
{
FAR struct hostent_info_s *info;
FAR char *ptr;
FAR void *addrdata;
socklen_t addrlen;
int addrtype;
int namelen;
@@ -419,6 +423,7 @@ static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host,
DEBUGASSERT(addrlen == sizeof(struct sockaddr_in));
addrlen = sizeof(struct sockaddr_in);
addrtype = AF_INET;
addrdata = &((FAR struct sockaddr_in *)ptr)->sin_addr;
}
#endif
@@ -430,12 +435,13 @@ static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host,
DEBUGASSERT(addrlen == sizeof(struct sockaddr_in6));
addrlen = sizeof(struct sockaddr_in6);
addrtype = AF_INET6;
addrdata = &((FAR struct sockaddr_in6 *)ptr)->sin_addr;
}
#endif
/* Yes.. Return the address that we obtained from the DNS name server. */
info->hi_addrlist[0] = ptr;
info->hi_addrlist[0] = addrdata;
host->h_addr_list = info->hi_addrlist;
host->h_addrtype = addrtype;
host->h_length = addrlen;