libc/netdb: Support save the mix of IPv4/IPv6 address into hostent
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com> Change-Id: I704d38afde14b6d90a7726096fd1f483f96ba237
This commit is contained in:
parent
7f2810f73a
commit
8d66a316da
@ -184,14 +184,17 @@ struct hostent
|
||||
FAR char **h_aliases; /* A pointer to an array of pointers to the
|
||||
* alternative host names, terminated by a
|
||||
* null pointer. */
|
||||
int h_addrtype; /* Address type. */
|
||||
int h_length; /* The length, in bytes, of the address. */
|
||||
FAR int *h_addrtypes; /* A pointer to an array of address type. */
|
||||
FAR int *h_lengths; /* A pointer to an array of the length, in bytes,
|
||||
* of the address. */
|
||||
FAR char **h_addr_list; /* A pointer to an array of pointers to network
|
||||
* addresses (in network byte order) for the host,
|
||||
* terminated by a null pointer. */
|
||||
};
|
||||
|
||||
#define h_addr h_addr_list[0] /* For backward compatibility */
|
||||
#define h_length h_lengths[0]
|
||||
#define h_addrtype h_addrtypes[0]
|
||||
|
||||
struct netent
|
||||
{
|
||||
|
@ -287,7 +287,7 @@ int getaddrinfo(FAR const char *hostname, FAR const char *servname,
|
||||
{
|
||||
for (i = 0; hp->h_addr_list[i]; i++)
|
||||
{
|
||||
if (family != AF_UNSPEC && hp->h_addrtype != family)
|
||||
if (family != AF_UNSPEC && hp->h_addrtypes[i] != family)
|
||||
{
|
||||
/* Filter by protocol family. */
|
||||
|
||||
@ -296,7 +296,7 @@ int getaddrinfo(FAR const char *hostname, FAR const char *servname,
|
||||
|
||||
/* REVISIT: filter by socktype and protocol not implemented. */
|
||||
|
||||
ai = alloc_ai(hp->h_addrtype, socktype, proto, port,
|
||||
ai = alloc_ai(hp->h_addrtypes[i], socktype, proto, port,
|
||||
hp->h_addr_list[i]);
|
||||
if (ai == NULL)
|
||||
{
|
||||
|
@ -61,8 +61,10 @@
|
||||
|
||||
struct hostent_info_s
|
||||
{
|
||||
int hi_addrtypes[CONFIG_NETDB_MAX_IPADDR + 1];
|
||||
int hi_lengths[CONFIG_NETDB_MAX_IPADDR + 1];
|
||||
FAR char *hi_addrlist[CONFIG_NETDB_MAX_IPADDR + 1];
|
||||
char hi_data[1];
|
||||
char hi_data[1];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -164,34 +166,48 @@ static int lib_localhost(FAR const void *addr, socklen_t len, int type,
|
||||
size_t buflen)
|
||||
{
|
||||
FAR struct hostent_info_s *info;
|
||||
socklen_t addrlen;
|
||||
FAR const uint8_t *src;
|
||||
FAR char *dest;
|
||||
int namelen;
|
||||
|
||||
/* Make sure that space remains to hold the hostent structure */
|
||||
|
||||
if (buflen <= sizeof(struct hostent_info_s))
|
||||
{
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
info = (FAR struct hostent_info_s *)buf;
|
||||
dest = info->hi_data;
|
||||
buflen -= (sizeof(struct hostent_info_s) - 1);
|
||||
|
||||
memset(host, 0, sizeof(struct hostent));
|
||||
memset(info, 0, sizeof(struct hostent_info_s));
|
||||
|
||||
host->h_addrtypes = info->hi_addrtypes;
|
||||
host->h_lengths = info->hi_lengths;
|
||||
host->h_addr_list = info->hi_addrlist;
|
||||
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
if (lib_lo_ipv4match(addr, len, type))
|
||||
{
|
||||
/* Setup to transfer the IPv4 address */
|
||||
/* Save the IPv4 address */
|
||||
|
||||
addrlen = sizeof(struct in_addr);
|
||||
src = (FAR uint8_t *)&g_lo_ipv4addr;
|
||||
host->h_length = sizeof(struct in_addr);
|
||||
host->h_addr = (FAR char *)&g_lo_ipv4addr;
|
||||
host->h_addrtype = AF_INET;
|
||||
goto out_copy;
|
||||
goto out_copyname;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
if (lib_lo_ipv6match(addr, len, type))
|
||||
{
|
||||
/* Setup to transfer the IPv6 address */
|
||||
/* Save the IPv6 address */
|
||||
|
||||
addrlen = sizeof(struct in6_addr);
|
||||
src = (FAR uint8_t *)&g_lo_ipv6addr;
|
||||
host->h_length = sizeof(struct in6_addr);
|
||||
host->h_addr = (FAR char *)&g_lo_ipv6addr;
|
||||
host->h_addrtype = AF_INET6;
|
||||
goto out_copy;
|
||||
goto out_copyname;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -199,29 +215,7 @@ static int lib_localhost(FAR const void *addr, socklen_t len, int type,
|
||||
|
||||
return 1;
|
||||
|
||||
out_copy:
|
||||
/* Make sure that space remains to hold the hostent structure and
|
||||
* the IP address.
|
||||
*/
|
||||
|
||||
if (buflen <= (sizeof(struct hostent_info_s) + addrlen))
|
||||
{
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
info = (FAR struct hostent_info_s *)buf;
|
||||
dest = info->hi_data;
|
||||
buflen -= (sizeof(struct hostent_info_s) - 1);
|
||||
|
||||
memset(info, 0, sizeof(struct hostent_info_s));
|
||||
memcpy(dest, src, addrlen);
|
||||
|
||||
info->hi_addrlist[0] = dest;
|
||||
host->h_addr_list = info->hi_addrlist;
|
||||
host->h_length = addrlen;
|
||||
|
||||
dest += addrlen;
|
||||
buflen -= addrlen;
|
||||
out_copyname:
|
||||
|
||||
/* And copy localhost host name */
|
||||
|
||||
|
@ -66,8 +66,10 @@
|
||||
|
||||
struct hostent_info_s
|
||||
{
|
||||
int hi_addrtypes[CONFIG_NETDB_MAX_IPADDR + 1];
|
||||
int hi_lengths[CONFIG_NETDB_MAX_IPADDR + 1];
|
||||
FAR char *hi_addrlist[CONFIG_NETDB_MAX_IPADDR + 1];
|
||||
char hi_data[1];
|
||||
char hi_data[1];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -120,6 +122,10 @@ static int lib_numeric_address(FAR const char *name,
|
||||
memset(host, 0, sizeof(struct hostent));
|
||||
memset(info, 0, sizeof(struct hostent_info_s));
|
||||
|
||||
host->h_addrtypes = info->hi_addrtypes;
|
||||
host->h_lengths = info->hi_lengths;
|
||||
host->h_addr_list = info->hi_addrlist;
|
||||
|
||||
/* If the address contains a colon, then it might be a numeric IPv6
|
||||
* address
|
||||
*/
|
||||
@ -189,12 +195,11 @@ static int lib_numeric_address(FAR const char *name,
|
||||
return 1;
|
||||
}
|
||||
|
||||
info->hi_addrlist[0] = ptr;
|
||||
host->h_addr_list = info->hi_addrlist;
|
||||
host->h_length = addrlen;
|
||||
host->h_addr = ptr;
|
||||
host->h_length = addrlen;
|
||||
|
||||
ptr += addrlen;
|
||||
buflen -= addrlen;
|
||||
ptr += addrlen;
|
||||
buflen -= addrlen;
|
||||
|
||||
/* And copy name */
|
||||
|
||||
@ -235,53 +240,49 @@ static int lib_localhost(FAR const char *name, FAR struct hostent *host,
|
||||
FAR char *buf, size_t buflen)
|
||||
{
|
||||
FAR struct hostent_info_s *info;
|
||||
socklen_t addrlen;
|
||||
FAR const char *src;
|
||||
FAR char *dest;
|
||||
int namelen;
|
||||
int i = 0;
|
||||
|
||||
if (strcmp(name, g_lo_hostname) == 0)
|
||||
{
|
||||
/* Yes.. it is the localhost */
|
||||
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
/* Setup to transfer the IPv4 address */
|
||||
/* Make sure that space remains to hold the hostent structure */
|
||||
|
||||
addrlen = sizeof(struct in_addr);
|
||||
src = (FAR const char *)&g_lo_ipv4addr;
|
||||
host->h_addrtype = AF_INET;
|
||||
|
||||
#else /* CONFIG_NET_IPv6 */
|
||||
/* Setup to transfer the IPv6 address */
|
||||
|
||||
addrlen = sizeof(struct in6_addr);
|
||||
src = (FAR const char *)&g_lo_ipv6addr;
|
||||
host->h_addrtype = AF_INET6;
|
||||
#endif
|
||||
|
||||
/* Make sure that space remains to hold the hostent structure and
|
||||
* the IP address.
|
||||
*/
|
||||
|
||||
if (buflen <= (sizeof(struct hostent_info_s) + addrlen))
|
||||
if (buflen <= sizeof(struct hostent_info_s))
|
||||
{
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
info = (FAR struct hostent_info_s *)buf;
|
||||
dest = info->hi_data;
|
||||
buflen -= (sizeof(struct hostent_info_s) - 1);
|
||||
info = (FAR struct hostent_info_s *)buf;
|
||||
dest = info->hi_data;
|
||||
buflen -= (sizeof(struct hostent_info_s) - 1);
|
||||
|
||||
memset(host, 0, sizeof(struct hostent));
|
||||
memset(info, 0, sizeof(struct hostent_info_s));
|
||||
memcpy(dest, src, addrlen);
|
||||
|
||||
info->hi_addrlist[0] = dest;
|
||||
host->h_addr_list = info->hi_addrlist;
|
||||
host->h_length = addrlen;
|
||||
host->h_addrtypes = info->hi_addrtypes;
|
||||
host->h_lengths = info->hi_lengths;
|
||||
host->h_addr_list = info->hi_addrlist;
|
||||
|
||||
dest += addrlen;
|
||||
buflen -= addrlen;
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
/* Save the IPv4 address */
|
||||
|
||||
info->hi_addrtypes[i] = AF_INET;
|
||||
info->hi_lengths[i] = sizeof(struct in_addr);
|
||||
info->hi_addrlist[i] = (FAR char *)&g_lo_ipv4addr;
|
||||
i++;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
/* Save the IPv6 address */
|
||||
|
||||
info->hi_addrtypes[i] = AF_INET6;
|
||||
info->hi_lengths[i] = sizeof(struct in6_addr);
|
||||
info->hi_addrlist[i] = (FAR char *)&g_lo_ipv6addr;
|
||||
i++;
|
||||
#endif
|
||||
|
||||
/* And copy name */
|
||||
|
||||
@ -362,6 +363,10 @@ static int lib_find_answer(FAR const char *name, FAR struct hostent *host,
|
||||
memset(host, 0, sizeof(struct hostent));
|
||||
memset(info, 0, sizeof(struct hostent_info_s));
|
||||
|
||||
host->h_addrtypes = info->hi_addrtypes;
|
||||
host->h_lengths = info->hi_lengths;
|
||||
host->h_addr_list = info->hi_addrlist;
|
||||
|
||||
/* Try to get the host address using the DNS name server */
|
||||
|
||||
naddr = buflen / sizeof(union dns_addr_u);
|
||||
@ -401,18 +406,14 @@ static int lib_find_answer(FAR const char *name, FAR struct hostent *host,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* REVISIT: This assumes addresses are all either IPv4 or IPv6. */
|
||||
info->hi_addrtypes[i] = addrtype;
|
||||
info->hi_lengths[i] = addrlen;
|
||||
info->hi_addrlist[i] = addrdata;
|
||||
|
||||
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);
|
||||
ptr += sizeof(union dns_addr_u);
|
||||
buflen -= sizeof(union dns_addr_u);
|
||||
}
|
||||
|
||||
host->h_addr_list = info->hi_addrlist;
|
||||
|
||||
/* And copy name */
|
||||
|
||||
namelen = strlen(name);
|
||||
@ -524,6 +525,10 @@ static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host,
|
||||
memset(host, 0, sizeof(struct hostent));
|
||||
memset(info, 0, sizeof(struct hostent_info_s));
|
||||
|
||||
host->h_addrtypes = info->hi_addrtypes;
|
||||
host->h_lengths = info->hi_lengths;
|
||||
host->h_addr_list = info->hi_addrlist;
|
||||
|
||||
/* Try to get the host address using the DNS name server */
|
||||
|
||||
naddr = buflen / sizeof(union dns_addr_u);
|
||||
@ -561,18 +566,14 @@ static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* REVISIT: This assumes addresses are all either IPv4 or IPv6. */
|
||||
info->hi_addrtypes[i] = addrtype;
|
||||
info->hi_lengths[i] = addrlen;
|
||||
info->hi_addrlist[i] = addrdata;
|
||||
|
||||
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);
|
||||
ptr += sizeof(union dns_addr_u);
|
||||
buflen -= sizeof(union dns_addr_u);
|
||||
}
|
||||
|
||||
host->h_addr_list = info->hi_addrlist;
|
||||
|
||||
/* And copy name */
|
||||
|
||||
namelen = strlen(name);
|
||||
|
@ -72,8 +72,10 @@
|
||||
struct hostent_info_s
|
||||
{
|
||||
FAR char *hi_aliases[CONFIG_NETDB_MAX_ALTNAMES + 1];
|
||||
int hi_addrtypes[2];
|
||||
int hi_lengths[2];
|
||||
FAR char *hi_addrlist[2];
|
||||
char hi_data[1];
|
||||
char hi_data[1];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -292,6 +294,10 @@ ssize_t lib_parse_hostfile(FAR FILE *stream, FAR struct hostent *host,
|
||||
memset(host, 0, sizeof(struct hostent));
|
||||
memset(info, 0, sizeof(struct hostent_info_s));
|
||||
|
||||
host->h_addrtypes = info->hi_addrtypes;
|
||||
host->h_lengths = info->hi_lengths;
|
||||
host->h_addr_list = info->hi_addrlist;
|
||||
|
||||
/* Skip over any leading spaces */
|
||||
|
||||
do
|
||||
@ -379,12 +385,11 @@ ssize_t lib_parse_hostfile(FAR FILE *stream, FAR struct hostent *host,
|
||||
host->h_addrtype = AF_INET;
|
||||
}
|
||||
|
||||
info->hi_addrlist[0] = ptr;
|
||||
host->h_addr_list = info->hi_addrlist;
|
||||
host->h_length = addrlen;
|
||||
host->h_addr = ptr;
|
||||
host->h_length = addrlen;
|
||||
|
||||
ptr += addrlen;
|
||||
buflen -= addrlen;
|
||||
ptr += addrlen;
|
||||
buflen -= addrlen;
|
||||
|
||||
/* Skip over any additional whitespace */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user