getaddrinfo: support AF_LOCAL

the hostname is as sun_path.

Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
Jiuzhu Dong 2021-09-05 15:58:03 +08:00 committed by Xiang Xiao
parent 2cfda2bffd
commit 352f636b38
1 changed files with 37 additions and 12 deletions

View File

@ -29,6 +29,7 @@
#include <arpa/inet.h>
#include <nuttx/net/loopback.h>
#include <netdb.h>
#include <sys/un.h>
#include "libc.h"
#include "lib_netdb.h"
@ -42,6 +43,7 @@ struct ai_s
struct addrinfo ai;
union
{
struct sockaddr_un sun;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
} sa;
@ -52,13 +54,9 @@ struct ai_s
****************************************************************************/
FAR static struct ai_s *alloc_ai(int family, int socktype, int protocol,
int port, FAR void *addr)
int port, FAR const void *addr)
{
FAR struct ai_s *ai;
socklen_t addrlen;
addrlen = (family == AF_INET) ? sizeof(struct sockaddr_in)
: sizeof(struct sockaddr_in6);
ai = lib_zalloc(sizeof(struct ai_s));
if (ai == NULL)
@ -67,22 +65,30 @@ FAR static struct ai_s *alloc_ai(int family, int socktype, int protocol,
}
ai->ai.ai_addr = (FAR struct sockaddr *)&ai->sa;
ai->ai.ai_addrlen = addrlen;
ai->ai.ai_family = family;
ai->ai.ai_socktype = socktype;
ai->ai.ai_protocol = protocol;
switch (family)
{
#ifdef CONFIG_NET_LOCAL
case AF_LOCAL:
ai->ai.ai_addrlen = sizeof(struct sockaddr_un);
ai->sa.sun.sun_family = AF_LOCAL;
strncpy(ai->sa.sun.sun_path, addr, sizeof(ai->sa.sun.sun_path));
break;
#endif
#ifdef CONFIG_NET_IPv4
case AF_INET:
ai->sa.sin.sin_family = AF_INET;
ai->sa.sin.sin_port = port; /* Already network order */
ai->ai.ai_addrlen = sizeof(struct sockaddr_in);
ai->sa.sin.sin_family = AF_INET;
ai->sa.sin.sin_port = port; /* Already network order */
memcpy(&ai->sa.sin.sin_addr, addr, sizeof(ai->sa.sin.sin_addr));
break;
#endif
#ifdef CONFIG_NET_IPv6
case AF_INET6:
ai->ai.ai_addrlen = sizeof(struct sockaddr_in6);
ai->sa.sin6.sin6_family = AF_INET6;
ai->sa.sin6.sin6_port = port; /* Already network order */
memcpy(&ai->sa.sin6.sin6_addr, addr, sizeof(ai->sa.sin6.sin6_addr));
@ -138,6 +144,7 @@ int getaddrinfo(FAR const char *hostname, FAR const char *servname,
if (family != AF_INET &&
family != AF_INET6 &&
family != AF_LOCAL &&
family != AF_UNSPEC)
{
return EAI_FAMILY;
@ -188,7 +195,7 @@ int getaddrinfo(FAR const char *hostname, FAR const char *servname,
#ifdef CONFIG_NET_IPv4
if (family == AF_INET || family == AF_UNSPEC)
{
ai = alloc_ai(AF_INET, socktype, proto, port, (FAR void *)&addr);
ai = alloc_ai(AF_INET, socktype, proto, port, &addr);
if (ai != NULL)
{
*res = (FAR struct addrinfo *)ai;
@ -199,7 +206,7 @@ int getaddrinfo(FAR const char *hostname, FAR const char *servname,
#ifdef CONFIG_NET_IPv6
if (family == AF_INET6 || family == AF_UNSPEC)
{
ai = alloc_ai(AF_INET6, socktype, proto, port, (FAR void *)&addr);
ai = alloc_ai(AF_INET6, socktype, proto, port, &addr);
if (ai != NULL)
{
/* Can return both IPv4 and IPv6 loopback. */
@ -228,7 +235,7 @@ int getaddrinfo(FAR const char *hostname, FAR const char *servname,
if (family == AF_INET || family == AF_UNSPEC)
{
ai = alloc_ai(AF_INET, socktype, proto, port,
(FAR void *)&g_lo_ipv4addr);
&g_lo_ipv4addr);
if (ai != NULL)
{
*res = (FAR struct addrinfo *)ai;
@ -240,7 +247,7 @@ int getaddrinfo(FAR const char *hostname, FAR const char *servname,
if (family == AF_INET6 || family == AF_UNSPEC)
{
ai = alloc_ai(AF_INET6, socktype, proto, port,
(FAR void *)&g_lo_ipv6addr);
&g_lo_ipv6addr);
if (ai != NULL)
{
/* Can return both IPv4 and IPv6 loopback. */
@ -265,6 +272,24 @@ int getaddrinfo(FAR const char *hostname, FAR const char *servname,
#endif /* CONFIG_NET_LOOPBACK */
}
#ifdef CONFIG_NET_LOCAL
if (family == AF_LOCAL)
{
ai = alloc_ai(AF_LOCAL, socktype, proto, port, hostname);
if (ai != NULL)
{
*res = (FAR struct addrinfo *)ai;
}
if (flags & AI_CANONNAME)
{
ai->ai.ai_canonname = (FAR char *)hostname;
}
return (*res != NULL) ? OK : EAI_MEMORY;
}
#endif
hostbuffer = lib_malloc(CONFIG_NETDB_BUFSIZE);
if (hostbuffer == NULL)
{