From 826972c9d81a66f14353a67908940b84dbce785f Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Fri, 14 Sep 2018 01:17:35 +0200 Subject: [PATCH] avformat/udp: use factorized ip functions Signed-off-by: Marton Balint --- libavformat/Makefile | 4 +- libavformat/udp.c | 123 ++++++++----------------------------------- 2 files changed, 23 insertions(+), 104 deletions(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index ccb39b54699..467ae2d87eb 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -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 diff --git a/libavformat/udp.c b/libavformat/udp.c index bbdeda05fe1..427128c431e 100644 --- a/libavformat/udp.c +++ b/libavformat/udp.c @@ -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; } -- 2.39.2