mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-13 21:28:01 +02:00
avformat/udp: use factorized ip functions
Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
parent
45fa756fa4
commit
826972c9d8
@ -609,8 +609,8 @@ TLS-OBJS-$(CONFIG_OPENSSL) += tls_openssl.o
|
||||
TLS-OBJS-$(CONFIG_SECURETRANSPORT) += tls_securetransport.o
|
||||
TLS-OBJS-$(CONFIG_SCHANNEL) += tls_schannel.o
|
||||
OBJS-$(CONFIG_TLS_PROTOCOL) += tls.o $(TLS-OBJS-yes)
|
||||
OBJS-$(CONFIG_UDP_PROTOCOL) += udp.o
|
||||
OBJS-$(CONFIG_UDPLITE_PROTOCOL) += udp.o
|
||||
OBJS-$(CONFIG_UDP_PROTOCOL) += udp.o ip.o
|
||||
OBJS-$(CONFIG_UDPLITE_PROTOCOL) += udp.o ip.o
|
||||
OBJS-$(CONFIG_UNIX_PROTOCOL) += unix.o
|
||||
|
||||
# external library protocols
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "network.h"
|
||||
#include "os_support.h"
|
||||
#include "url.h"
|
||||
#include "ip.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "TargetConditionals.h"
|
||||
@ -109,6 +110,7 @@ typedef struct UDPContext {
|
||||
struct sockaddr_storage local_addr_storage;
|
||||
char *sources;
|
||||
char *block;
|
||||
IPSourceFilters filters;
|
||||
} UDPContext;
|
||||
|
||||
#define OFFSET(x) offsetof(UDPContext, x)
|
||||
@ -236,39 +238,9 @@ static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr,struct so
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct addrinfo *udp_resolve_host(URLContext *h,
|
||||
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(h, AV_LOG_ERROR, "getaddrinfo(%s, %s): %s\n",
|
||||
node ? node : "unknown",
|
||||
service,
|
||||
gai_strerror(error));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int udp_set_multicast_sources(URLContext *h,
|
||||
int sockfd, struct sockaddr *addr,
|
||||
int addr_len, char **sources,
|
||||
int addr_len, struct sockaddr_storage *sources,
|
||||
int nb_sources, int include)
|
||||
{
|
||||
#if HAVE_STRUCT_GROUP_SOURCE_REQ && defined(MCAST_BLOCK_SOURCE) && !defined(_WIN32) && (!defined(TARGET_OS_TV) || !TARGET_OS_TV)
|
||||
@ -278,16 +250,10 @@ static int udp_set_multicast_sources(URLContext *h,
|
||||
for (i = 0; i < nb_sources; i++) {
|
||||
struct group_source_req mreqs;
|
||||
int level = addr->sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
|
||||
struct addrinfo *sourceaddr = udp_resolve_host(h, sources[i], 0,
|
||||
SOCK_DGRAM, AF_UNSPEC,
|
||||
0);
|
||||
if (!sourceaddr)
|
||||
return AVERROR(ENOENT);
|
||||
|
||||
mreqs.gsr_interface = 0;
|
||||
memcpy(&mreqs.gsr_group, addr, addr_len);
|
||||
memcpy(&mreqs.gsr_source, sourceaddr->ai_addr, sourceaddr->ai_addrlen);
|
||||
freeaddrinfo(sourceaddr);
|
||||
memcpy(&mreqs.gsr_source, &sources[i], sizeof(*sources));
|
||||
|
||||
if (setsockopt(sockfd, level,
|
||||
include ? MCAST_JOIN_SOURCE_GROUP : MCAST_BLOCK_SOURCE,
|
||||
@ -308,22 +274,14 @@ static int udp_set_multicast_sources(URLContext *h,
|
||||
}
|
||||
for (i = 0; i < nb_sources; i++) {
|
||||
struct ip_mreq_source mreqs;
|
||||
struct addrinfo *sourceaddr = udp_resolve_host(h, sources[i], 0,
|
||||
SOCK_DGRAM, AF_UNSPEC,
|
||||
0);
|
||||
if (!sourceaddr)
|
||||
return AVERROR(ENOENT);
|
||||
if (sourceaddr->ai_addr->sa_family != AF_INET) {
|
||||
freeaddrinfo(sourceaddr);
|
||||
av_log(NULL, AV_LOG_ERROR, "%s is of incorrect protocol family\n",
|
||||
sources[i]);
|
||||
if (sources[i].ss_family != AF_INET) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Source/block address %d is of incorrect protocol family\n", i + 1);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
mreqs.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
|
||||
mreqs.imr_interface.s_addr = INADDR_ANY;
|
||||
mreqs.imr_sourceaddr.s_addr = ((struct sockaddr_in *)sourceaddr->ai_addr)->sin_addr.s_addr;
|
||||
freeaddrinfo(sourceaddr);
|
||||
mreqs.imr_sourceaddr.s_addr = ((struct sockaddr_in *)&sources[i])->sin_addr.s_addr;
|
||||
|
||||
if (setsockopt(sockfd, IPPROTO_IP,
|
||||
include ? IP_ADD_SOURCE_MEMBERSHIP : IP_BLOCK_SOURCE,
|
||||
@ -347,7 +305,7 @@ static int udp_set_url(URLContext *h,
|
||||
struct addrinfo *res0;
|
||||
int addr_len;
|
||||
|
||||
res0 = udp_resolve_host(h, hostname, port, SOCK_DGRAM, AF_UNSPEC, 0);
|
||||
res0 = ff_ip_resolve_host(h, hostname, port, SOCK_DGRAM, AF_UNSPEC, 0);
|
||||
if (!res0) return AVERROR(EIO);
|
||||
memcpy(addr, res0->ai_addr, res0->ai_addrlen);
|
||||
addr_len = res0->ai_addrlen;
|
||||
@ -366,7 +324,7 @@ static int udp_socket_create(URLContext *h, struct sockaddr_storage *addr,
|
||||
|
||||
if (((struct sockaddr *) &s->dest_addr)->sa_family)
|
||||
family = ((struct sockaddr *) &s->dest_addr)->sa_family;
|
||||
res0 = udp_resolve_host(h, (localaddr && localaddr[0]) ? localaddr : NULL,
|
||||
res0 = ff_ip_resolve_host(h, (localaddr && localaddr[0]) ? localaddr : NULL,
|
||||
s->local_port,
|
||||
SOCK_DGRAM, family, AI_PASSIVE);
|
||||
if (!res0)
|
||||
@ -646,27 +604,6 @@ end:
|
||||
|
||||
#endif
|
||||
|
||||
static int parse_source_list(char *buf, char **sources, int *num_sources,
|
||||
int max_sources)
|
||||
{
|
||||
char *source_start;
|
||||
|
||||
source_start = buf;
|
||||
while (1) {
|
||||
char *next = strchr(source_start, ',');
|
||||
if (next)
|
||||
*next = '\0';
|
||||
sources[*num_sources] = av_strdup(source_start);
|
||||
if (!sources[*num_sources])
|
||||
return AVERROR(ENOMEM);
|
||||
source_start = next + 1;
|
||||
(*num_sources)++;
|
||||
if (*num_sources >= max_sources || !next)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* put it in UDP context */
|
||||
/* return non zero if error */
|
||||
static int udp_open(URLContext *h, const char *uri, int flags)
|
||||
@ -679,8 +616,6 @@ static int udp_open(URLContext *h, const char *uri, int flags)
|
||||
char buf[256];
|
||||
struct sockaddr_storage my_addr;
|
||||
socklen_t len;
|
||||
int i, num_include_sources = 0, num_exclude_sources = 0;
|
||||
char *include_sources[32], *exclude_sources[32];
|
||||
|
||||
h->is_streamed = 1;
|
||||
|
||||
@ -689,15 +624,12 @@ static int udp_open(URLContext *h, const char *uri, int flags)
|
||||
s->buffer_size = is_output ? UDP_TX_BUF_SIZE : UDP_MAX_PKT_SIZE;
|
||||
|
||||
if (s->sources) {
|
||||
if (parse_source_list(s->sources, include_sources,
|
||||
&num_include_sources,
|
||||
FF_ARRAY_ELEMS(include_sources)))
|
||||
if (ff_ip_parse_sources(h, s->sources, &s->filters) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (s->block) {
|
||||
if (parse_source_list(s->block, exclude_sources, &num_exclude_sources,
|
||||
FF_ARRAY_ELEMS(exclude_sources)))
|
||||
if (ff_ip_parse_blocks(h, s->block, &s->filters) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -766,13 +698,11 @@ static int udp_open(URLContext *h, const char *uri, int flags)
|
||||
av_strlcpy(localaddr, buf, sizeof(localaddr));
|
||||
}
|
||||
if (av_find_info_tag(buf, sizeof(buf), "sources", p)) {
|
||||
if (parse_source_list(buf, include_sources, &num_include_sources,
|
||||
FF_ARRAY_ELEMS(include_sources)))
|
||||
if (ff_ip_parse_sources(h, buf, &s->filters) < 0)
|
||||
goto fail;
|
||||
}
|
||||
if (av_find_info_tag(buf, sizeof(buf), "block", p)) {
|
||||
if (parse_source_list(buf, exclude_sources, &num_exclude_sources,
|
||||
FF_ARRAY_ELEMS(exclude_sources)))
|
||||
if (ff_ip_parse_blocks(h, buf, &s->filters) < 0)
|
||||
goto fail;
|
||||
}
|
||||
if (!is_output && av_find_info_tag(buf, sizeof(buf), "timeout", p))
|
||||
@ -875,27 +805,23 @@ static int udp_open(URLContext *h, const char *uri, int flags)
|
||||
}
|
||||
if (h->flags & AVIO_FLAG_READ) {
|
||||
/* input */
|
||||
if (num_include_sources && num_exclude_sources) {
|
||||
av_log(h, AV_LOG_ERROR, "Simultaneously including and excluding multicast sources is not supported\n");
|
||||
goto fail;
|
||||
}
|
||||
if (num_include_sources) {
|
||||
if (s->filters.nb_include_addrs) {
|
||||
if (udp_set_multicast_sources(h, udp_fd,
|
||||
(struct sockaddr *)&s->dest_addr,
|
||||
s->dest_addr_len,
|
||||
include_sources,
|
||||
num_include_sources, 1) < 0)
|
||||
s->filters.include_addrs,
|
||||
s->filters.nb_include_addrs, 1) < 0)
|
||||
goto fail;
|
||||
} else {
|
||||
if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr,(struct sockaddr *)&s->local_addr_storage) < 0)
|
||||
goto fail;
|
||||
}
|
||||
if (num_exclude_sources) {
|
||||
if (s->filters.nb_exclude_addrs) {
|
||||
if (udp_set_multicast_sources(h, udp_fd,
|
||||
(struct sockaddr *)&s->dest_addr,
|
||||
s->dest_addr_len,
|
||||
exclude_sources,
|
||||
num_exclude_sources, 0) < 0)
|
||||
s->filters.exclude_addrs,
|
||||
s->filters.nb_exclude_addrs, 0) < 0)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
@ -933,11 +859,6 @@ static int udp_open(URLContext *h, const char *uri, int flags)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < num_include_sources; i++)
|
||||
av_freep(&include_sources[i]);
|
||||
for (i = 0; i < num_exclude_sources; i++)
|
||||
av_freep(&exclude_sources[i]);
|
||||
|
||||
s->udp_fd = udp_fd;
|
||||
|
||||
#if HAVE_PTHREAD_CANCEL
|
||||
@ -987,10 +908,7 @@ static int udp_open(URLContext *h, const char *uri, int flags)
|
||||
if (udp_fd >= 0)
|
||||
closesocket(udp_fd);
|
||||
av_fifo_freep(&s->fifo);
|
||||
for (i = 0; i < num_include_sources; i++)
|
||||
av_freep(&include_sources[i]);
|
||||
for (i = 0; i < num_exclude_sources; i++)
|
||||
av_freep(&exclude_sources[i]);
|
||||
ff_ip_reset_filters(&s->filters);
|
||||
return AVERROR(EIO);
|
||||
}
|
||||
|
||||
@ -1144,6 +1062,7 @@ static int udp_close(URLContext *h)
|
||||
#endif
|
||||
closesocket(s->udp_fd);
|
||||
av_fifo_freep(&s->fifo);
|
||||
ff_ip_reset_filters(&s->filters);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user