[FFmpeg-devel] Quick Patch for Multicast UDP Receive on macOS

Submitted by ffmpeg@gallery.co.uk on Aug. 16, 2018, 2:56 p.m.

Details

Message ID F63008A6-E2F1-4AC6-A472-33F55ACD74E0@gallery.co.uk
State New
Headers show

Commit Message

ffmpeg@gallery.co.uk Aug. 16, 2018, 2:56 p.m.
Hi Folks.

New here, so apologies if this is not how its done,  but I have a tiny patch to fix a fundamental flaw in FFMPEG on macOS.

The Problem:  
-------------------
On macOS Try to run 2 copies of FFMPEG each consuming an RTP Multicast which are on *different* multicast addresses - but the *same* port.
The second copy will fail with a bind error and possibly a crash.

The Solution:
------------------
Very simple - on macOS you need to use SO_REUSEPORT as well as SO_REUSEADDR to avoid this sort of issue.

Thanks

Mark Gilbert
CTO: Gallery SIENNA.



PATCH FOLLOWS:
--------------------------

Comments

Thilo Borgmann Aug. 16, 2018, 4:43 p.m.
Hi,

> --- /Users/mark/Downloads/udpORIG.c	2018-08-16 15:39:21.000000000 +0100
> +++ /Users/mark/Downloads/udp.c	2018-08-16 15:40:55.000000000 +0100
> @@ -828,7 +828,11 @@
>         s->reuse_socket = 1;
>         if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEADDR, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0)
>             goto fail;
> -    }
> +  #ifdef __APPLE__  // MacOS/X requires an additional call 
> +        if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEPORT, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0)
> +            goto fail;
> +  #endif
> +      }
> 
>     if (s->is_broadcast) {
> #ifdef SO_BROADCAST

Not sure but that might also affect other BSD derivatives like Gentoo... can you test on Linux and some BSD also?
(I've got no other BSD kind of OS other than OSX)

-Thilo
ffmpeg@gallery.co.uk Aug. 16, 2018, 4:49 p.m.
> On 16 Aug 2018, at 17:43, Thilo Borgmann <thilo.borgmann@mail.de> wrote:
> 
> Hi,
> 
>> --- /Users/mark/Downloads/udpORIG.c	2018-08-16 15:39:21.000000000 +0100
>> +++ /Users/mark/Downloads/udp.c	2018-08-16 15:40:55.000000000 +0100
>> @@ -828,7 +828,11 @@
>>        s->reuse_socket = 1;
>>        if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEADDR, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0)
>>            goto fail;
>> -    }
>> +  #ifdef __APPLE__  // MacOS/X requires an additional call 
>> +        if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEPORT, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0)
>> +            goto fail;
>> +  #endif
>> +      }
>> 
>>    if (s->is_broadcast) {
>> #ifdef SO_BROADCAST
> 
> Not sure but that might also affect other BSD derivatives like Gentoo... can you test on Linux and some BSD also?
> (I've got no other BSD kind of OS other than OSX)

Its certainly NOT an issue on Ubuntu Linux.

I don't have any other BSD variants to test with either, sorry.
This is a fairly well documented quirk of macOS, however.

> 
> -Thilo
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
mypopy@gmail.com Aug. 17, 2018, 12:47 a.m.
On Fri, Aug 17, 2018 at 12:50 AM <ffmpeg@gallery.co.uk> wrote:
>
>
> > On 16 Aug 2018, at 17:43, Thilo Borgmann <thilo.borgmann@mail.de> wrote:
> >
> > Hi,
> >
> >> --- /Users/mark/Downloads/udpORIG.c  2018-08-16 15:39:21.000000000 +0100
> >> +++ /Users/mark/Downloads/udp.c      2018-08-16 15:40:55.000000000 +0100
> >> @@ -828,7 +828,11 @@
> >>        s->reuse_socket = 1;
> >>        if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEADDR, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0)
> >>            goto fail;
> >> -    }
> >> +  #ifdef __APPLE__  // MacOS/X requires an additional call
> >> +        if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEPORT, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0)
> >> +            goto fail;
> >> +  #endif
> >> +      }
> >>
> >>    if (s->is_broadcast) {
> >> #ifdef SO_BROADCAST
> >
> > Not sure but that might also affect other BSD derivatives like Gentoo... can you test on Linux and some BSD also?
> > (I've got no other BSD kind of OS other than OSX)
f
>
> Its certainly NOT an issue on Ubuntu Linux.
>
> I don't have any other BSD variants to test with either, sorry.
> This is a fairly well documented quirk of macOS, however.
>
>
Can you use a new option for SO_REUSEPORT, as my point:
1). An option more flexible than a hard code.
2). As I know, Linux (Kernel > 3.9) has support SO_REUSEPORT, and
maybe we will add this function in Linux
(https://lwn.net/Articles/542629/
3). Do you plan enable this function for TCP?

Thanks.

Patch hide | download patch | download mbox

--- /Users/mark/Downloads/udpORIG.c	2018-08-16 15:39:21.000000000 +0100
+++ /Users/mark/Downloads/udp.c	2018-08-16 15:40:55.000000000 +0100
@@ -828,7 +828,11 @@ 
        s->reuse_socket = 1;
        if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEADDR, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0)
            goto fail;
-    }
+  #ifdef __APPLE__  // MacOS/X requires an additional call 
+        if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEPORT, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0)
+            goto fail;
+  #endif
+      }

    if (s->is_broadcast) {
#ifdef SO_BROADCAST