2018-06-08 15:07:21 +02:00
|
|
|
/****************************************************************************
|
|
|
|
* libs/libc/netdb/lib_getaddrinfo.c
|
|
|
|
*
|
2021-05-26 10:05:59 +02:00
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
|
|
* this work for additional information regarding copyright ownership. The
|
|
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
|
|
* "License"); you may not use this file except in compliance with the
|
|
|
|
* License. You may obtain a copy of the License at
|
2018-06-08 15:07:21 +02:00
|
|
|
*
|
2021-05-26 10:05:59 +02:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2018-06-08 15:07:21 +02:00
|
|
|
*
|
2021-05-26 10:05:59 +02:00
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
* License for the specific language governing permissions and limitations
|
|
|
|
* under the License.
|
2018-06-08 15:07:21 +02:00
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Included Files
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <nuttx/net/loopback.h>
|
2021-09-07 08:59:13 +02:00
|
|
|
#include <netpacket/rpmsg.h>
|
2018-06-08 15:07:21 +02:00
|
|
|
#include <netdb.h>
|
2021-09-05 09:58:03 +02:00
|
|
|
#include <sys/un.h>
|
2018-06-08 15:07:21 +02:00
|
|
|
|
|
|
|
#include "libc.h"
|
2020-03-31 20:21:04 +02:00
|
|
|
#include "lib_netdb.h"
|
2018-06-08 15:07:21 +02:00
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Private Data Types
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
struct ai_s
|
|
|
|
{
|
|
|
|
struct addrinfo ai;
|
|
|
|
union
|
|
|
|
{
|
2021-09-05 09:58:03 +02:00
|
|
|
struct sockaddr_un sun;
|
2018-06-08 15:07:21 +02:00
|
|
|
struct sockaddr_in sin;
|
|
|
|
struct sockaddr_in6 sin6;
|
2021-09-07 08:59:13 +02:00
|
|
|
struct sockaddr_rpmsg srp;
|
2018-06-08 15:07:21 +02:00
|
|
|
} sa;
|
|
|
|
};
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Private Functions
|
|
|
|
****************************************************************************/
|
|
|
|
|
2018-09-25 19:00:57 +02:00
|
|
|
FAR static struct ai_s *alloc_ai(int family, int socktype, int protocol,
|
2021-09-05 09:58:03 +02:00
|
|
|
int port, FAR const void *addr)
|
2018-06-08 15:07:21 +02:00
|
|
|
{
|
2020-03-29 19:22:29 +02:00
|
|
|
FAR struct ai_s *ai;
|
2018-06-08 15:07:21 +02:00
|
|
|
|
|
|
|
ai = lib_zalloc(sizeof(struct ai_s));
|
|
|
|
if (ai == NULL)
|
|
|
|
{
|
|
|
|
return ai;
|
|
|
|
}
|
|
|
|
|
2020-03-29 19:22:29 +02:00
|
|
|
ai->ai.ai_addr = (FAR struct sockaddr *)&ai->sa;
|
|
|
|
ai->ai.ai_family = family;
|
|
|
|
ai->ai.ai_socktype = socktype;
|
|
|
|
ai->ai.ai_protocol = protocol;
|
2018-06-08 15:07:21 +02:00
|
|
|
|
|
|
|
switch (family)
|
|
|
|
{
|
2021-09-05 09:58:03 +02:00
|
|
|
#ifdef CONFIG_NET_LOCAL
|
|
|
|
case AF_LOCAL:
|
|
|
|
ai->ai.ai_addrlen = sizeof(struct sockaddr_un);
|
|
|
|
ai->sa.sun.sun_family = AF_LOCAL;
|
2022-03-18 15:37:12 +01:00
|
|
|
strlcpy(ai->sa.sun.sun_path, addr, sizeof(ai->sa.sun.sun_path));
|
2021-09-05 09:58:03 +02:00
|
|
|
break;
|
|
|
|
#endif
|
2018-06-08 15:07:21 +02:00
|
|
|
#ifdef CONFIG_NET_IPv4
|
|
|
|
case AF_INET:
|
2021-09-05 09:58:03 +02:00
|
|
|
ai->ai.ai_addrlen = sizeof(struct sockaddr_in);
|
|
|
|
ai->sa.sin.sin_family = AF_INET;
|
|
|
|
ai->sa.sin.sin_port = port; /* Already network order */
|
2018-06-08 15:07:21 +02:00
|
|
|
memcpy(&ai->sa.sin.sin_addr, addr, sizeof(ai->sa.sin.sin_addr));
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_NET_IPv6
|
|
|
|
case AF_INET6:
|
2021-09-05 09:58:03 +02:00
|
|
|
ai->ai.ai_addrlen = sizeof(struct sockaddr_in6);
|
2018-06-08 15:07:21 +02:00
|
|
|
ai->sa.sin6.sin6_family = AF_INET6;
|
2018-06-19 21:37:00 +02:00
|
|
|
ai->sa.sin6.sin6_port = port; /* Already network order */
|
2018-06-08 15:07:21 +02:00
|
|
|
memcpy(&ai->sa.sin6.sin6_addr, addr, sizeof(ai->sa.sin6.sin6_addr));
|
|
|
|
break;
|
2021-09-07 08:59:13 +02:00
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_NET_RPMSG
|
|
|
|
case AF_RPMSG:
|
|
|
|
ai->ai.ai_addrlen = sizeof(struct sockaddr_rpmsg);
|
|
|
|
ai->sa.srp.rp_family = AF_RPMSG;
|
2022-03-18 15:37:12 +01:00
|
|
|
strlcpy(ai->sa.srp.rp_cpu, addr, sizeof(ai->sa.srp.rp_cpu));
|
2021-09-07 08:59:13 +02:00
|
|
|
snprintf(ai->sa.srp.rp_name, sizeof(ai->sa.srp.rp_name), "%d", port);
|
|
|
|
break;
|
2018-06-08 15:07:21 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
return ai;
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Public Functions
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Name: getaddrinfo
|
|
|
|
****************************************************************************/
|
|
|
|
|
2018-06-13 05:42:59 +02:00
|
|
|
int getaddrinfo(FAR const char *hostname, FAR const char *servname,
|
|
|
|
FAR const struct addrinfo *hint, FAR struct addrinfo **res)
|
2018-06-08 15:07:21 +02:00
|
|
|
{
|
|
|
|
int family = AF_UNSPEC;
|
|
|
|
int port = 0;
|
|
|
|
int flags = 0;
|
|
|
|
int proto = 0;
|
|
|
|
int socktype = 0;
|
2020-12-22 10:04:53 +01:00
|
|
|
FAR char *hostbuffer;
|
2020-03-31 20:21:04 +02:00
|
|
|
FAR struct hostent_s host;
|
2020-03-29 19:22:29 +02:00
|
|
|
FAR struct ai_s *ai;
|
|
|
|
FAR struct ai_s *prev_ai = NULL;
|
2018-06-08 15:07:21 +02:00
|
|
|
const int valid_flags = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST |
|
|
|
|
AI_NUMERICSERV | AI_V4MAPPED | AI_ALL |
|
|
|
|
AI_ADDRCONFIG;
|
2020-03-31 20:21:04 +02:00
|
|
|
int ret = OK;
|
2018-06-08 15:07:21 +02:00
|
|
|
int i;
|
|
|
|
|
|
|
|
if (hostname == NULL && servname == NULL)
|
|
|
|
{
|
|
|
|
return EAI_NONAME;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hint)
|
|
|
|
{
|
2018-06-13 05:42:59 +02:00
|
|
|
family = hint->ai_family;
|
|
|
|
flags = hint->ai_flags;
|
|
|
|
proto = hint->ai_protocol;
|
2018-06-08 15:07:21 +02:00
|
|
|
socktype = hint->ai_socktype;
|
|
|
|
|
|
|
|
if ((flags & valid_flags) != flags)
|
|
|
|
{
|
|
|
|
return EAI_BADFLAGS;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (family != AF_INET &&
|
|
|
|
family != AF_INET6 &&
|
2021-09-05 09:58:03 +02:00
|
|
|
family != AF_LOCAL &&
|
2021-09-07 08:59:13 +02:00
|
|
|
family != AF_RPMSG &&
|
2018-06-08 15:07:21 +02:00
|
|
|
family != AF_UNSPEC)
|
|
|
|
{
|
2019-11-18 18:36:48 +01:00
|
|
|
return EAI_FAMILY;
|
2018-06-08 15:07:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-18 18:08:15 +02:00
|
|
|
if (servname != NULL)
|
2018-06-08 15:07:21 +02:00
|
|
|
{
|
2020-04-24 11:11:03 +02:00
|
|
|
struct servent ent;
|
2020-03-29 19:22:29 +02:00
|
|
|
FAR struct servent *sp;
|
2020-04-24 11:11:03 +02:00
|
|
|
FAR char *endp;
|
2018-06-08 15:07:21 +02:00
|
|
|
|
|
|
|
port = strtol(servname, &endp, 10);
|
netdb:netdb code support ffmpeg rtsp(getaddrinfo & getnameinfo)
Related Codes:
1.ffmpeg/libavformat/ip.c
struct addrinfo *ff_ip_resolve_host(void *log_ctx,
const char *hostname, int port,
int type, int family, int flags)
{
struct addrinfo hints = { 0 }, *res = 0;
int error;
char sport[16];
const char *node = 0, *service = "0";
if (port > 0) {
snprintf(sport, sizeof(sport), "%d", port);
service = sport;
}
if ((hostname) && (hostname[0] != '\0') && (hostname[0] != '?')) {
node = hostname;
}
hints.ai_socktype = type;
hints.ai_family = family;
hints.ai_flags = flags;
if ((error = getaddrinfo(node, service, &hints, &res))) {
res = NULL;
av_log(log_ctx, AV_LOG_ERROR, "getaddrinfo(%s, %s): %s\n",
node ? node : "unknown",
service,
gai_strerror(error));
}
return res;
}
2.ffmpeg/libavformat/rtsp.c
static int sdp_read_header(AVFormatContext *s)
{
RTSPState *rt = s->priv_data;
RTSPStream *rtsp_st;
int i, err;
char url[MAX_URL_SIZE];
AVBPrint bp;
if (!ff_network_init())
return AVERROR(EIO);
if (s->max_delay < 0) /* Not set by the caller */
s->max_delay = DEFAULT_REORDERING_DELAY;
if (rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)
rt->lower_transport = RTSP_LOWER_TRANSPORT_CUSTOM;
/* read the whole sdp file */
av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
err = avio_read_to_bprint(s->pb, &bp, INT_MAX);
if (err < 0 ) {
ff_network_close();
av_bprint_finalize(&bp, NULL);
return err;
}
err = ff_sdp_parse(s, bp.str);
av_bprint_finalize(&bp, NULL);
if (err) goto fail;
/* open each RTP stream */
for (i = 0; i < rt->nb_rtsp_streams; i++) {
char namebuf[50];
rtsp_st = rt->rtsp_streams[i];
if (!(rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)) {
AVDictionary *opts = map_to_opts(rt);
char buf[MAX_URL_SIZE];
const char *p;
err = getnameinfo((struct sockaddr*) &rtsp_st->sdp_ip,
sizeof(rtsp_st->sdp_ip),
namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
if (err) {
av_log(s, AV_LOG_ERROR, "getnameinfo: %s\n", gai_strerror(err));
err = AVERROR(EIO);
av_dict_free(&opts);
goto fail;
}
ff_url_join(url, sizeof(url), "rtp", NULL,
namebuf, rtsp_st->sdp_port,
"?localport=%d&ttl=%d&connect=%d&write_to_source=%d",
rtsp_st->sdp_port, rtsp_st->sdp_ttl,
rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0,
rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0);
p = strchr(s->url, '?');
if (p && av_find_info_tag(buf, sizeof(buf), "localaddr", p))
av_strlcatf(url, sizeof(url), "&localaddr=%s", buf);
else if (rt->localaddr && rt->localaddr[0])
av_strlcatf(url, sizeof(url), "&localaddr=%s", rt->localaddr);
append_source_addrs(url, sizeof(url), "sources",
rtsp_st->nb_include_source_addrs,
rtsp_st->include_source_addrs);
append_source_addrs(url, sizeof(url), "block",
rtsp_st->nb_exclude_source_addrs,
rtsp_st->exclude_source_addrs);
err = ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ,
&s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL);
av_dict_free(&opts);
if (err < 0) {
err = AVERROR_INVALIDDATA;
goto fail;
}
}
if ((err = ff_rtsp_open_transport_ctx(s, rtsp_st)))
goto fail;
}
return 0;
fail:
ff_rtsp_close_streams(s);
ff_network_close();
return err;
}
Signed-off-by: wangchen <wangchen41@xiaomi.com>
2023-09-07 08:24:50 +02:00
|
|
|
if (port >= 0 && port <= 65535 && *endp == '\0')
|
2018-06-08 15:07:21 +02:00
|
|
|
{
|
2018-06-18 18:08:15 +02:00
|
|
|
/* Force network byte order */
|
|
|
|
|
2022-01-18 08:38:00 +01:00
|
|
|
port = HTONS(port);
|
2018-06-08 15:07:21 +02:00
|
|
|
}
|
2018-06-18 18:08:15 +02:00
|
|
|
else if ((flags & AI_NUMERICSERV) != 0)
|
2018-06-08 15:07:21 +02:00
|
|
|
{
|
|
|
|
return EAI_NONAME;
|
|
|
|
}
|
2020-04-24 11:11:03 +02:00
|
|
|
else if (getservbyname_r(servname, NULL, &ent, NULL, 0, &sp) == OK)
|
2018-06-08 15:07:21 +02:00
|
|
|
{
|
2020-03-29 19:22:29 +02:00
|
|
|
/* The s_port field of struct servent is required to
|
2018-06-18 18:08:15 +02:00
|
|
|
* be in network byte order (per OpenGroup.org)
|
|
|
|
*/
|
|
|
|
|
2018-06-08 15:07:21 +02:00
|
|
|
port = sp->s_port;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return EAI_SERVICE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-25 19:00:57 +02:00
|
|
|
*res = NULL;
|
2018-06-08 15:07:21 +02:00
|
|
|
|
2018-09-25 19:00:57 +02:00
|
|
|
/* If hostname is not NULL, then the AI_PASSIVE flag is ignored. */
|
2018-06-08 15:07:21 +02:00
|
|
|
|
2018-09-25 19:00:57 +02:00
|
|
|
if ((flags & AI_PASSIVE) != 0 && hostname == NULL)
|
|
|
|
{
|
|
|
|
struct in6_addr addr;
|
2018-06-08 15:07:21 +02:00
|
|
|
|
2018-09-25 19:00:57 +02:00
|
|
|
memset(&addr, 0, sizeof(struct in6_addr));
|
|
|
|
|
|
|
|
#ifdef CONFIG_NET_IPv4
|
|
|
|
if (family == AF_INET || family == AF_UNSPEC)
|
2018-06-08 15:07:21 +02:00
|
|
|
{
|
2021-09-05 09:58:03 +02:00
|
|
|
ai = alloc_ai(AF_INET, socktype, proto, port, &addr);
|
2020-03-29 19:22:29 +02:00
|
|
|
if (ai != NULL)
|
2018-09-25 19:00:57 +02:00
|
|
|
{
|
2020-03-29 19:22:29 +02:00
|
|
|
*res = (FAR struct addrinfo *)ai;
|
2018-09-25 19:00:57 +02:00
|
|
|
}
|
2018-06-08 15:07:21 +02:00
|
|
|
}
|
2018-09-25 19:00:57 +02:00
|
|
|
#endif
|
2019-11-18 18:36:48 +01:00
|
|
|
|
2018-09-25 19:00:57 +02:00
|
|
|
#ifdef CONFIG_NET_IPv6
|
|
|
|
if (family == AF_INET6 || family == AF_UNSPEC)
|
|
|
|
{
|
2021-09-05 09:58:03 +02:00
|
|
|
ai = alloc_ai(AF_INET6, socktype, proto, port, &addr);
|
2020-03-29 19:22:29 +02:00
|
|
|
if (ai != NULL)
|
2018-09-25 19:00:57 +02:00
|
|
|
{
|
2020-03-29 19:22:29 +02:00
|
|
|
/* Can return both IPv4 and IPv6 loopback. */
|
2018-09-25 19:00:57 +02:00
|
|
|
|
2020-03-29 19:22:29 +02:00
|
|
|
if (*res != NULL)
|
|
|
|
{
|
|
|
|
(*res)->ai_next = (FAR struct addrinfo *)ai;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*res = (FAR struct addrinfo *)ai;
|
|
|
|
}
|
2018-09-25 19:00:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2019-11-18 18:36:48 +01:00
|
|
|
|
2020-03-29 19:22:29 +02:00
|
|
|
return (*res != NULL) ? OK : EAI_MEMORY;
|
2019-11-18 18:36:48 +01:00
|
|
|
}
|
2018-06-08 15:07:21 +02:00
|
|
|
|
2018-06-18 18:08:15 +02:00
|
|
|
if (hostname == NULL)
|
2018-06-08 15:07:21 +02:00
|
|
|
{
|
|
|
|
#ifdef CONFIG_NET_LOOPBACK
|
|
|
|
/* Local service. */
|
|
|
|
|
|
|
|
#ifdef CONFIG_NET_IPv4
|
|
|
|
if (family == AF_INET || family == AF_UNSPEC)
|
|
|
|
{
|
2019-11-18 18:36:48 +01:00
|
|
|
ai = alloc_ai(AF_INET, socktype, proto, port,
|
2021-09-05 09:58:03 +02:00
|
|
|
&g_lo_ipv4addr);
|
2020-03-29 19:22:29 +02:00
|
|
|
if (ai != NULL)
|
2018-06-08 15:07:21 +02:00
|
|
|
{
|
2020-03-29 19:22:29 +02:00
|
|
|
*res = (FAR struct addrinfo *)ai;
|
2018-06-08 15:07:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2019-11-18 18:36:48 +01:00
|
|
|
|
2018-06-08 15:07:21 +02:00
|
|
|
#ifdef CONFIG_NET_IPv6
|
|
|
|
if (family == AF_INET6 || family == AF_UNSPEC)
|
|
|
|
{
|
2019-11-18 18:36:48 +01:00
|
|
|
ai = alloc_ai(AF_INET6, socktype, proto, port,
|
2021-09-05 09:58:03 +02:00
|
|
|
&g_lo_ipv6addr);
|
2020-03-29 19:22:29 +02:00
|
|
|
if (ai != NULL)
|
2018-06-08 15:07:21 +02:00
|
|
|
{
|
2020-03-29 19:22:29 +02:00
|
|
|
/* Can return both IPv4 and IPv6 loopback. */
|
2018-06-08 15:07:21 +02:00
|
|
|
|
2020-03-29 19:22:29 +02:00
|
|
|
if (*res != NULL)
|
|
|
|
{
|
|
|
|
(*res)->ai_next = (FAR struct addrinfo *)ai;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*res = (FAR struct addrinfo *)ai;
|
|
|
|
}
|
2018-06-08 15:07:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2019-11-18 18:36:48 +01:00
|
|
|
|
2020-03-29 19:22:29 +02:00
|
|
|
return (*res != NULL) ? OK : EAI_MEMORY;
|
2018-06-08 15:07:21 +02:00
|
|
|
#else
|
|
|
|
/* Local service, but no loopback so cannot succeed. */
|
|
|
|
|
|
|
|
return EAI_FAIL;
|
|
|
|
#endif /* CONFIG_NET_LOOPBACK */
|
|
|
|
}
|
|
|
|
|
2021-09-07 08:59:13 +02:00
|
|
|
#if defined(CONFIG_NET_LOCAL) || defined(CONFIG_NET_RPMSG)
|
|
|
|
if (family == AF_LOCAL || family == AF_RPMSG)
|
2021-09-05 09:58:03 +02:00
|
|
|
{
|
2021-09-07 08:59:13 +02:00
|
|
|
ai = alloc_ai(family, socktype, proto, port, hostname);
|
2021-09-05 09:58:03 +02:00
|
|
|
if (ai != NULL)
|
|
|
|
{
|
|
|
|
*res = (FAR struct addrinfo *)ai;
|
2022-03-18 17:57:37 +01:00
|
|
|
if (flags & AI_CANONNAME)
|
|
|
|
{
|
|
|
|
ai->ai.ai_canonname = (FAR char *)hostname;
|
|
|
|
}
|
2021-09-05 09:58:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return (*res != NULL) ? OK : EAI_MEMORY;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-12-22 10:04:53 +01:00
|
|
|
hostbuffer = lib_malloc(CONFIG_NETDB_BUFSIZE);
|
|
|
|
if (hostbuffer == NULL)
|
|
|
|
{
|
|
|
|
return EAI_MEMORY;
|
|
|
|
}
|
|
|
|
|
2020-03-31 20:21:04 +02:00
|
|
|
gethostentbyname_r(hostname, &host,
|
2023-01-11 10:24:47 +01:00
|
|
|
hostbuffer, CONFIG_NETDB_BUFSIZE, &ret, flags);
|
2020-03-31 20:21:04 +02:00
|
|
|
if (ret != OK)
|
|
|
|
{
|
2020-12-22 10:04:53 +01:00
|
|
|
lib_free(hostbuffer);
|
2020-03-31 20:21:04 +02:00
|
|
|
return ret;
|
|
|
|
}
|
2018-06-08 15:07:21 +02:00
|
|
|
|
2020-03-31 20:21:04 +02:00
|
|
|
for (i = 0; host.h_addr_list[i]; i++)
|
2018-06-08 15:07:21 +02:00
|
|
|
{
|
2020-03-31 20:21:04 +02:00
|
|
|
if (family != AF_UNSPEC && host.h_addrtypes[i] != family)
|
2018-06-08 15:07:21 +02:00
|
|
|
{
|
2020-03-31 20:21:04 +02:00
|
|
|
/* Filter by protocol family. */
|
2018-06-08 15:07:21 +02:00
|
|
|
|
2020-03-31 20:21:04 +02:00
|
|
|
continue;
|
|
|
|
}
|
2018-06-08 15:07:21 +02:00
|
|
|
|
2020-03-31 20:21:04 +02:00
|
|
|
/* REVISIT: filter by socktype and protocol not implemented. */
|
2018-06-08 15:07:21 +02:00
|
|
|
|
2020-03-31 20:21:04 +02:00
|
|
|
ai = alloc_ai(host.h_addrtypes[i], socktype, proto, port,
|
|
|
|
host.h_addr_list[i]);
|
|
|
|
if (ai == NULL)
|
|
|
|
{
|
|
|
|
if (*res)
|
2018-06-08 15:07:21 +02:00
|
|
|
{
|
2020-03-31 20:21:04 +02:00
|
|
|
freeaddrinfo(*res);
|
2018-06-08 15:07:21 +02:00
|
|
|
}
|
|
|
|
|
2020-12-22 10:04:53 +01:00
|
|
|
lib_free(hostbuffer);
|
2020-03-31 20:21:04 +02:00
|
|
|
return EAI_MEMORY;
|
|
|
|
}
|
2018-06-08 15:07:21 +02:00
|
|
|
|
2020-03-31 20:21:04 +02:00
|
|
|
/* REVISIT: grok canonical name.
|
|
|
|
*
|
|
|
|
* OpenGroup: "if the canonical name is not available, then
|
|
|
|
* ai_canonname shall refer to the hostname argument or a string
|
|
|
|
* with the same contents."
|
|
|
|
*/
|
2018-06-08 15:07:21 +02:00
|
|
|
|
2020-03-31 20:21:04 +02:00
|
|
|
ai->ai.ai_canonname = (FAR char *)hostname;
|
2018-06-08 15:07:21 +02:00
|
|
|
|
2020-03-31 20:21:04 +02:00
|
|
|
/* Add result to linked list.
|
|
|
|
* TODO: RFC 3484/6724 destination address sort not implemented.
|
|
|
|
*/
|
2018-06-08 15:07:21 +02:00
|
|
|
|
2020-03-31 20:21:04 +02:00
|
|
|
if (prev_ai != NULL)
|
|
|
|
{
|
|
|
|
prev_ai->ai.ai_next = (FAR struct addrinfo *)ai;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*res = (FAR struct addrinfo *)ai;
|
2018-06-08 15:07:21 +02:00
|
|
|
}
|
|
|
|
|
2020-03-31 20:21:04 +02:00
|
|
|
prev_ai = ai;
|
2018-06-08 15:07:21 +02:00
|
|
|
}
|
|
|
|
|
2020-12-22 10:04:53 +01:00
|
|
|
lib_free(hostbuffer);
|
2020-03-31 20:21:04 +02:00
|
|
|
return (*res != NULL) ? OK : EAI_FAMILY;
|
2018-06-08 15:07:21 +02:00
|
|
|
}
|