nuttx/libs/libc/netdb/lib_getnameinfo.c
wangchen 146767a8a2 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>
2024-08-20 10:33:18 -03:00

201 lines
5.2 KiB
C

/****************************************************************************
* libs/libc/netdb/lib_getnameinfo.c
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <arpa/inet.h>
#include <assert.h>
#include "netdb/lib_netdb.h"
#ifdef CONFIG_LIBC_NETDB
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: getnameinfo
****************************************************************************/
int getnameinfo(FAR const struct sockaddr *addr, socklen_t addrlen,
FAR char *host, socklen_t hostlen,
FAR char *serv, socklen_t servlen, int flags)
{
FAR const void *saddr;
socklen_t saddr_len;
int port;
int ret;
if (addr && addr->sa_family == AF_INET &&
addrlen >= sizeof(struct sockaddr_in))
{
FAR const struct sockaddr_in *sa_in;
sa_in = (FAR const struct sockaddr_in *)addr;
port = NTOHS(sa_in->sin_port);
saddr = &sa_in->sin_addr;
saddr_len = sizeof(sa_in->sin_addr);
}
#ifdef CONFIG_NET_IPv6
else if (addr && addr->sa_family == AF_INET6 &&
addrlen == sizeof(struct sockaddr_in6))
{
FAR const struct sockaddr_in6 *sa_in6;
sa_in6 = (FAR const struct sockaddr_in6 *)addr;
port = NTOHS(sa_in6->sin6_port);
saddr = &sa_in6->sin6_addr;
saddr_len = sizeof(sa_in6->sin6_addr);
}
#endif
else
{
return EAI_FAMILY;
}
if (host && !(flags & NI_NUMERICHOST))
{
struct hostent hostent;
FAR struct hostent *res;
int error;
ret = gethostbyaddr_r(saddr, saddr_len, addr->sa_family, &hostent,
host, hostlen, &res, &error);
if (ret == OK)
{
size_t sz = strlen(res->h_name) + 1;
if (sz <= hostlen)
{
memmove(host, res->h_name, sz);
}
else
{
memmove(host, res->h_name, hostlen);
host[hostlen - 1] = '\0';
}
}
else
{
switch (error)
{
case HOST_NOT_FOUND:
{
if (flags & NI_NAMEREQD)
{
return EAI_NONAME;
}
}
break;
case NO_RECOVERY:
{
if (flags & NI_NAMEREQD)
{
return EAI_FAIL;
}
}
break;
case NO_DATA:
case TRY_AGAIN:
{
if (flags & NI_NAMEREQD)
{
return EAI_AGAIN;
}
}
break;
default:
DEBUGPANIC();
}
/* Fall-back to numeric for the host name. */
flags |= NI_NUMERICHOST;
}
}
if (host && (flags & NI_NUMERICHOST))
{
if (!inet_ntop(addr->sa_family, saddr, host, hostlen))
{
switch (get_errno())
{
case ENOSPC:
return EAI_OVERFLOW;
default:
DEBUGPANIC();
}
}
}
if (serv && !(flags & NI_NUMERICSERV))
{
struct servent servent;
FAR struct servent *result;
ret = getservbyport_r(port, flags & NI_DGRAM ? "udp" : "tcp",
&servent, serv, servlen, &result);
if (ret == OK)
{
size_t sz = strlen(servent.s_name) + 1;
if (sz <= servlen)
{
memmove(serv, servent.s_name, sz);
}
else
{
memmove(serv, servent.s_name, servlen);
serv[servlen - 1] = '\0';
}
}
else
{
/* Fall-back to numeric for the host name. */
flags |= NI_NUMERICSERV;
}
}
if (serv && (flags & NI_NUMERICSERV))
{
snprintf(serv, servlen, "%d", port);
}
return OK;
}
#endif /* CONFIG_LIBC_NETDB */