diff --git a/doc/protocols.texi b/doc/protocols.texi index ac5299aad2..a62156f4d8 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -1857,6 +1857,10 @@ When true, use Timestamp-based Packet Delivery mode. The default behavior depends on the transmission type: enabled in live mode, disabled in file mode. +@item ipv6only=@var{1|0} +Accept IPv4 or not while using the IPv6 wildcard address. This should be set +when listening on a IPv6 wildcard address. + @end table For more information see: @url{https://github.com/Haivision/srt}. diff --git a/libavformat/libsrt.c b/libavformat/libsrt.c index 12a7ad6a52..c1d93b2550 100644 --- a/libavformat/libsrt.c +++ b/libavformat/libsrt.c @@ -94,6 +94,9 @@ typedef struct SRTContext { SRT_TRANSTYPE transtype; int linger; int tsbpd; +#if SRT_VERSION_VALUE >= 0x010400 + int ipv6only; +#endif } SRTContext; #define D AV_OPT_FLAG_DECODING_PARAM @@ -147,6 +150,9 @@ static const AVOption libsrt_options[] = { { "file", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRTT_FILE }, INT_MIN, INT_MAX, .flags = D|E, .unit = "transtype" }, { "linger", "Number of seconds that the socket waits for unsent data when closing", OFFSET(linger), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, { "tsbpd", "Timestamp-based packet delivery", OFFSET(tsbpd), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = D|E }, +#if SRT_VERSION_VALUE >= 0x010400 + { "ipv6only", "Accept IPv4 or not while using the IPv6 wildcard address", OFFSET(ipv6only), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = D|E }, +#endif { NULL } }; @@ -447,6 +453,23 @@ static int libsrt_setup(URLContext *h, const char *uri, int flags) av_log(h, AV_LOG_DEBUG, "libsrt_socket_nonblock failed\n"); if (s->mode == SRT_MODE_LISTENER) { +#if SRT_VERSION_VALUE >= 0x010400 + if (s->ipv6only != -1) { + if (srt_setsockopt(fd, SOL_SOCKET, SRTO_IPV6ONLY, &s->ipv6only, sizeof(s->ipv6only))) { + av_log(h, AV_LOG_WARNING, "setsockopt(SRTO_IPV6ONLY) failed\n"); + } + } +#if SRT_VERSION_VALUE >= 0x010502 + else if (cur_ai->ai_family == AF_INET6) { + struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)cur_ai->ai_addr; + if (IN6_IS_ADDR_UNSPECIFIED(&(ipv6->sin6_addr))) { + av_log(h, AV_LOG_ERROR, "You must specify \"ipv6only\" option if you use a IPv6 wildcard address\n"); + ret = AVERROR(EINVAL); + goto fail1; + } + } +#endif +#endif int read_eid = ret = libsrt_epoll_create(h, fd, 0); if (ret < 0) goto fail1;