From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id A565549DE3 for ; Thu, 11 Apr 2024 07:50:10 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B68AD68D1C0; Thu, 11 Apr 2024 10:50:08 +0300 (EEST) Received: from w4.tutanota.de (w4.tutanota.de [81.3.6.165]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5889868D198 for ; Thu, 11 Apr 2024 10:50:02 +0300 (EEST) Received: from tutadb.w10.tutanota.de (unknown [192.168.1.10]) by w4.tutanota.de (Postfix) with ESMTP id 055EE106015E for ; Thu, 11 Apr 2024 07:50:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1712821801; s=s1; d=lynne.ee; h=From:From:To:To:Subject:Subject:Content-Description:Content-ID:Content-Type:Content-Type:Content-Transfer-Encoding:Content-Transfer-Encoding:Cc:Date:Date:In-Reply-To:In-Reply-To:MIME-Version:MIME-Version:Message-ID:Message-ID:Reply-To:References:References:Sender; bh=ilxOVM0kKvVBI0QfLnbOO+cIJOnm89oD4eB4ypdLiX4=; b=ghT2bu15ul+v1Lt1NFXl1opSfijA92t11HQbx///c0KLuHkiiHr0baROB7FTdWwy BNdJLD7Wp+rlpbcBcrxE0WloRXiLf2FPiXW9xRBMmGdb3vCTE9Ta+NAMVrGWd05lvXB rZztpMfhv3TDxKdlL6n9aTImk1AKC3/28rWCxdyuoD+VsicTRRuXMSLXyvLN0w4cTAw 8hPzuhikk2LpjtfItXKfK6F4GpeZi+FbB18faOvGrFkrbAnXAXCBI8uaPsJW9fkU13v BFo0g3RSZptfCuodeAZ2P3RplMMicb5YHFtRn37NEYwflQ1pb/E0dBcKCH+OXHi14mT vV3+TJm28w== Date: Thu, 11 Apr 2024 09:50:01 +0200 (CEST) From: Lynne To: FFmpeg development discussions and patches Message-ID: In-Reply-To: References: <8072287.ikfbygDpP0@basile.remlab.net> <4877343.GXAFRqVoOG@basile.remlab.net> <3458953.8qv5vOS332@basile.remlab.net> MIME-Version: 1.0 Subject: Re: [FFmpeg-devel] [PATCH v2] avformat: enable UDP IPv6 multicast interface selection using zone index X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: Apr 11, 2024, 09:45 by Lazar.Ignjatovic@cubic.com: > avformat: enable UDP IPv6 multicast interface selection using zone index > > Enabled IPv6 interface selection using zone index. Properly resolved > interface index in places where default 0 interface index is used > (marked with TODO: within udp.c). Adjusted binding for multicast sockets > that are used for reading from the network. > > For mcast addresses, bind to mcast address is attempted as before. > In case that this fails, which will happen on Windows, socket is bound > to INADDR_ANY/IN6ADDR_ANY_INIT depending on address family. Actual > interface selection is performed using udp_set_multicast_interface to > point to the desired interface for sending. > > Closes: #368 > > Signed-off-by: Lazar Ignjatovic > --- > V1 -> V2 reverted iface resolution for IPv4 MCAST_JOIN_SOURCE_GROUP > NOTE: Due to comments, this patch is proposed as one of two alternatives > The other alternative uses `localaddr` for defining interfaces. > > > configure | 3 ++ > doc/protocols.texi | 2 +- > libavformat/network.h | 6 +++ > libavformat/udp.c | 85 +++++++++++++++++++++++++++++++++++++++---- > 4 files changed, 88 insertions(+), 8 deletions(-) > > diff --git a/configure b/configure > index 2a1d22310b..35d6a0b78c 100755 > --- a/configure > +++ b/configure > @@ -2307,6 +2307,7 @@ HEADERS_LIST=" > valgrind_valgrind_h > windows_h > winsock2_h > + iphlpapi_h > " > > INTRINSICS_LIST=" > @@ -6475,6 +6476,8 @@ if ! disabled network; then > check_struct winsock2.h "struct sockaddr" sa_len > check_type ws2tcpip.h "struct sockaddr_in6" > check_type ws2tcpip.h "struct sockaddr_storage" > + check_headers iphlpapi.h -liphlpapi && network_extralibs="$network_extralibs -liphlpapi" || disable iphlpapi_h > + check_func_headers iphlpapi.h GetBestInterfaceEx $network_extralibs > else > disable network > fi > diff --git a/doc/protocols.texi b/doc/protocols.texi > index f54600b846..a8892845d3 100644 > --- a/doc/protocols.texi > +++ b/doc/protocols.texi > @@ -2027,7 +2027,7 @@ packet bursts. > Override the local UDP port to bind with. > > @item localaddr=@var{addr} > -Local IP address of a network interface used for sending packets or joining > +Local IPv4 address of a network interface used for sending packets or joining > multicast groups. > > @item pkt_size=@var{size} > diff --git a/libavformat/network.h b/libavformat/network.h > index ca214087fc..2461b651d4 100644 > --- a/libavformat/network.h > +++ b/libavformat/network.h > @@ -38,6 +38,10 @@ > #include > #include > > +#if HAVE_IPHLPAPI_H > +#include > +#endif > + > #ifndef EPROTONOSUPPORT > #define EPROTONOSUPPORT WSAEPROTONOSUPPORT > #endif > @@ -64,6 +68,8 @@ int ff_neterrno(void); > #include > #include > #include > +#include > +#include > > #define ff_neterrno() AVERROR(errno) > #endif /* HAVE_WINSOCK2_H */ > diff --git a/libavformat/udp.c b/libavformat/udp.c > index d9514f5026..00c73f9ec9 100644 > --- a/libavformat/udp.c > +++ b/libavformat/udp.c > @@ -35,6 +35,7 @@ > #include "libavutil/opt.h" > #include "libavutil/log.h" > #include "libavutil/time.h" > +#include "libavutil/avstring.h" > #include "internal.h" > #include "network.h" > #include "os_support.h" > @@ -220,8 +221,7 @@ static int udp_join_multicast_group(int sockfd, struct sockaddr *addr, > struct ipv6_mreq mreq6; > > memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); > - //TODO: Interface index should be looked up from local_addr > - mreq6.ipv6mr_interface = 0; > + mreq6.ipv6mr_interface = ((struct sockaddr_in6 *)addr)->sin6_scope_id; > if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { > ff_log_net_error(logctx, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP)"); > return ff_neterrno(); > @@ -231,6 +231,39 @@ static int udp_join_multicast_group(int sockfd, struct sockaddr *addr, > return 0; > } > > +static int udp_set_multicast_interface(int sockfd, struct sockaddr *addr, > + struct sockaddr *local_addr, void *logctx) > +{ > +#ifdef IP_MULTICAST_IF > + if (addr->sa_family == AF_INET) { > + struct ip_mreq mreq; > + > + mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; > + if (local_addr) > + mreq.imr_interface = ((struct sockaddr_in *)local_addr)->sin_addr; > + else > + mreq.imr_interface.s_addr = INADDR_ANY; > + > + if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF, (const void *)&mreq, sizeof(mreq)) < 0) { > + ff_log_net_error(logctx, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_IF)"); > + return ff_neterrno(); > + } > + } > +#endif > +#if defined(IPV6_MULTICAST_IF) && defined(IPPROTO_IPV6) > + if (addr->sa_family == AF_INET6) { > + unsigned int iface; > + iface = ((struct sockaddr_in6 *)addr)->sin6_scope_id; > + > + if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &iface, sizeof(unsigned int)) < 0) { > + ff_log_net_error(logctx, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_IF)"); > + return ff_neterrno(); > + } > + } > +#endif > + return 0; > +} > + > static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr, > struct sockaddr *local_addr, void *logctx) > { > @@ -254,8 +287,7 @@ static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr, > struct ipv6_mreq mreq6; > > memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); > - //TODO: Interface index should be looked up from local_addr > - mreq6.ipv6mr_interface = 0; > + mreq6.ipv6mr_interface = ((struct sockaddr_in6 *)addr)->sin6_scope_id; > if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { > ff_log_net_error(logctx, AV_LOG_ERROR, "setsockopt(IPV6_DROP_MEMBERSHIP)"); > return -1; > @@ -284,6 +316,9 @@ static int udp_set_multicast_sources(URLContext *h, > > //TODO: Interface index should be looked up from local_addr > mreqs.gsr_interface = 0; > + if (level == IPPROTO_IPV6) > + mreqs.gsr_interface = ((struct sockaddr_in6 *)addr)->sin6_scope_id; > + > memcpy(&mreqs.gsr_group, addr, addr_len); > memcpy(&mreqs.gsr_source, &sources[i], sizeof(*sources)); > > @@ -340,9 +375,24 @@ static int udp_set_url(URLContext *h, > { > struct addrinfo *res0; > int addr_len; > + const char *host, *sc; > + char address[1024], scope[1024]; > > - res0 = ff_ip_resolve_host(h, hostname, port, SOCK_DGRAM, AF_UNSPEC, 0); > + if (sc = strchr(hostname, '%')) { > + av_strlcpy(address, hostname, FFMIN(1024, sc - hostname + 1)); > + av_strlcpy(scope, sc + 1, FFMIN(1024, strlen(hostname) - (sc - hostname))); > + host = address; > + } else { > + host = hostname; > + } > + > + res0 = ff_ip_resolve_host(h, host, port, SOCK_DGRAM, AF_UNSPEC, 0); > if (!res0) return AVERROR(EIO); > +#if HAVE_IPHLPAPI_H || !HAVE_WINSOCK2_H > + if (res0->ai_family== AF_INET6 && strlen(scope) > 0) { > + ((struct sockaddr_in6*)res0->ai_addr)->sin6_scope_id = if_nametoindex(scope); > + } > +#endif > memcpy(addr, res0->ai_addr, res0->ai_addrlen); > addr_len = res0->ai_addrlen; > freeaddrinfo(res0); > @@ -841,8 +891,23 @@ static int udp_open(URLContext *h, const char *uri, int flags) > if (s->is_multicast && (h->flags & AVIO_FLAG_READ)) { > bind_ret = bind(udp_fd,(struct sockaddr *)&s->dest_addr, len); > } > - /* bind to the local address if not multicast or if the multicast > - * bind failed */ > + > + /* bind to ADDR_ANY if the multicast bind failed */ > + if (s->is_multicast && bind_ret < 0) { > + struct addrinfo *res; > + > + if (s->dest_addr.ss_family == AF_INET) > + res = ff_ip_resolve_host(h, "0.0.0.0", 0, SOCK_DGRAM, AF_UNSPEC, 0); > + else if (s->dest_addr.ss_family == AF_INET6) > + res = ff_ip_resolve_host(h, "::", 0, SOCK_DGRAM, AF_UNSPEC, 0); > + > + if (res && res->ai_addr) { > + bind_ret = bind(udp_fd, res->ai_addr, res->ai_addrlen); > + } > + > + freeaddrinfo(res); > + } > + > /* the bind is needed to give a port to the socket now */ > if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0) { > ff_log_net_error(h, AV_LOG_ERROR, "bind failed"); > @@ -855,6 +920,12 @@ static int udp_open(URLContext *h, const char *uri, int flags) > s->local_port = udp_port(&my_addr, len); > > if (s->is_multicast) { > + if ((ret = udp_set_multicast_interface(udp_fd, > + (struct sockaddr *)&s->dest_addr, > + (struct sockaddr *)&s->local_addr_storage, > + h)) < 0) > + goto fail; > + > if (h->flags & AVIO_FLAG_WRITE) { > /* output */ > if ((ret = udp_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr, h)) < 0) > -- > 2.41.0.windows.2 > Is there a reason why we can't switch to IPv4 addresses mapped in IPv6 and just use the IPv6 API everywhere? _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".