Opened 3 years ago

Closed 2 years ago

#9449 closed defect (fixed)

FFmpeg UDP multicast support broken on OpenBSD

Reported by: Brad Smith Owned by:
Priority: important Component: avformat
Version: git-master Keywords: udp multicast
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

The FFmpeg UDP multicast support is broken on OpenBSD.

$ ffmpeg -i https://ftp.openbsd.org/pub/OpenBSD/songs/song69.ogg \

"udp://239.255.0.1:9000?ttl=10"

(...)
setsockopt(IP_MULTICAST_TTL): Invalid argument
udp://239.255.0.1:9000?ttl=10: Invalid argument

The mcastTTL parameter should be of the type unsigned char not int when passed to IP_MULTICAST_TTL via setsockopt(). This appears to be the case with all of the UNIX OS's I can find (Linux, all of the BSD's, Solaris, AIX, IRIX, etc.)

static int udp_set_multicast_ttl(int sockfd, int mcastTTL,
                                 struct sockaddr *addr)
{
#ifdef IP_MULTICAST_TTL
    if (addr->sa_family == AF_INET) {
        if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) {
            ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_TTL)");
            return ff_neterrno();
        }
    }
#endif
#if defined(IPPROTO_IPV6) && defined(IPV6_MULTICAST_HOPS)
    if (addr->sa_family == AF_INET6) {
        if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL, sizeof(mcastTTL)) < 0) {
            ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_HOPS)");
            return ff_neterrno();
        }
    }
#endif
    return 0;
}

Change History (2)

comment:1 by Brad Smith, 2 years ago

There was a diff that was suggested but I am not sure this is the way you want to go.

@@ -161,9 +161,10 @@ static const AVClass udplite_context_class = {
 static int udp_set_multicast_ttl(int sockfd, int mcastTTL,
                                  struct sockaddr *addr)
 {
+  unsigned char mcastTTLc = mcastTTL;
 #ifdef IP_MULTICAST_TTL
     if (addr->sa_family == AF_INET) {
-        if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) {
+        if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTLc, sizeof(mcastTTLc)) < 0) {
             ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_TTL)");
             return ff_neterrno();
         }
@@ -171,7 +172,7 @@ static int udp_set_multicast_ttl(int sockfd, int mcast
 #endif
 #if defined(IPPROTO_IPV6) && defined(IPV6_MULTICAST_HOPS)
     if (addr->sa_family == AF_INET6) {
-        if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL, sizeof(mcastTTL)) < 0) {
+        if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTLc, sizeof(mcastTTLc)) < 0) {
             ff_log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_HOPS)");
             return ff_neterrno();
         }

comment:2 by Marton Balint, 2 years ago

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.