[erlang-questions] udp multicast: problem with OSX? [solved]

Peter Morgan peter.james.morgan@REDACTED
Tue Apr 12 21:19:41 CEST 2016


Thanks! So does Linux do SO_REUSEPORT by default?


> On 12 Apr 2016, at 20:00, steve@REDACTED wrote:
> 
> It’s setting the SO_REUSEPORT option - https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/setsockopt.2.html
> 
> 16#ffff == SOL_SOCKET
> 16#0200 == SO_REUSEPORT
> 1:32 == true 
> 
> Some -defines would probably have made it more readable :)
> -- 
> 
> Sent with Airmail
> 
>> On 12 April 2016 at 19:54:27, Peter Morgan (peter.james.morgan@REDACTED) wrote:
>> 
>> Hi Steve -
>> 
>> Whoa! What magic is that doing?
>> 
>> Thanks
>> Peter
>> 
>> On 12 Apr 2016, at 19:43, steve@REDACTED wrote:
>> 
>>> Hi Peter,
>>> 
>>> On OSX, try adding:
>>> 
>>> { raw, 16#ffff, 16#0200, <<1:32/native>> }
>>> 
>>> into the options list on the gen_udp open…
>>> 
>>> Cheers,
>>> 
>>> Steve
>>> 
>>> -- 
>>> 
>>> Sent with Airmail
>>> 
>>>> On 12 April 2016 at 19:41:00, Peter Morgan (peter.james.morgan@REDACTED) wrote:
>>>> 
>>>> Hello -
>>>> 
>>>> It appears that OSX doesn’t like to reuse a port on gen_udp:open/2 when sending, whereas Linux appears to be quite happy doing so:
>>>> 
>>>> I had for both sender and receiver:
>>>> 
>>>> gen_udp:open(5353, [{mode, binary},
>>>> {reuseaddr, true},
>>>> {ip, {224, 0, 0, 251}},
>>>> {multicast_ttl, 4},
>>>> {multicast_loop, true},
>>>> {broadcast, true},
>>>> {add_membership, {{224, 0, 0, 251}, {0, 0, 0, 0}}},
>>>> {active, once}]).
>>>> 
>>>> Where 5353 is the port for mDNS - already being used by mDNS daemons on both Linux and OSX. The above works fine for Linux (to send and receive), whereas on OSX it only appears to work for receiving.
>>>> 
>>>> To make it work on OSX, I need to call gen_udp:open/2 slightly differently depending on whether I want to call gen_udp:send/4 on the returned socket:
>>>> 
>>>> {ok, Sender} = gen_udp:open(0, [binary]).
>>>> gen_udp:send(Sender, {224, 0, 0, 251}, 5353, <<“hello world”>>).
>>>> 
>>>> Note the “0” as the Port parameter to gen_udp:open/2 above.
>>>> 
>>>> Whereas the receiver must be (as originally):
>>>> 
>>>> {ok, Sender} = gen_udp:open(5353, [{mode, binary},
>>>> {reuseaddr, true},
>>>> {ip, {224, 0, 0, 251}},
>>>> {multicast_ttl, 4},
>>>> {multicast_loop, true},
>>>> {broadcast, true},
>>>> {add_membership, {{224, 0, 0, 251}, {0, 0, 0, 0}}},
>>>> {active, once}]).
>>>> 
>>>> On Linux, it seems quite happy for the sender and receiver to use the {reuseaddr, true} form immediately above and port 5353 as the parameter to gen_udp:open/2. OSX is OK until gen_udp:send/4 is called it responds with: {error, eaddrnotavail}.
>>>> 
>>>> The updated code is https://github.com/shortishly/mdns/blob/develop/src/mdns_udp.erl and now works for both OSX and Linux.
>>>> 
>>>> 
>>>> Thanks,
>>>> Peter.
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> > On 12 Apr 2016, at 17:06, Peter Morgan <peter.james.morgan@REDACTED> wrote:
>>>> >
>>>> > Hi Torben, Max,
>>>> >
>>>> > On OSX I can receive multicast traffic using the following options (the same as Max’s pretty much):
>>>> >
>>>> > [binary,
>>>> > inet,
>>>> > {reuseaddr, true},
>>>> > {ip, MulticastAddress},
>>>> > {multicast_ttl, 4},
>>>> > {multicast_loop, true},
>>>> > {add_membership, {MulticastAddress, {0, 0, 0, 0}}},
>>>> > {active, once}].
>>>> >
>>>> > Where MulticastAddress is {224, 0, 0, 251}. I’m using that address because it is one used by OSX, Linux/everything for multicast DNS :)
>>>> >
>>>> > On OSX I can happily receive multicast traffic on a gen_udp socket that is opened with the above parameters.
>>>> >
>>>> > However, on OSX I cannot send to the same socket using:
>>>> >
>>>> > gen_udp:send(Socket, MulticastAddress, Port, SomeMessage).
>>>> >
>>>> > On Linux (Fedora 23) the above send does work. On OSX I get {error, eaddrnotavail} on send.
>>>> >
>>>> > I’m sure I have had this working on OSX and Linux together, so I’m probably doing some rather stupid…
>>>> >
>>>> > OSX is El Capitan (10.11.4 beta). Erlang is 18.3 (brew).
>>>> >
>>>> > I’ve tried replacing the {0, 0, 0, 0} in {add_membership, {MulticastAddress, {0, 0, 0, 0}}} with IP address of the interface, but it didn’t make any difference.
>>>> >
>>>> > Thanks,
>>>> > Peter.
>>>> >
>>>> >
>>>> >
>>>> >
>>>> >> On 11 Apr 2016, at 16:58, Max Lapshin <max.lapshin@REDACTED> wrote:
>>>> >>
>>>> >> This is how it is working for me:
>>>> >>
>>>> >> {ok, Addr} = inet_parse:address(Host),
>>>> >> Common = [binary,{reuseaddr,true},{recbuf,2*1024*1024},inet,{ip,Addr},{read_packets,100}],
>>>> >> Options = case is_multicast(Addr) of
>>>> >> true ->
>>>> >> Multicast = [{multicast_ttl,4},{multicast_loop,true},{add_membership,{Addr,GwIP}}],
>>>> >> Common ++ Multicast;
>>>> >> false ->
>>>> >> Common
>>>> >> end,
>>>> >>
>>>> >
>>>> 
>>>> _______________________________________________
>>>> erlang-questions mailing list
>>>> erlang-questions@REDACTED
>>>> http://erlang.org/mailman/listinfo/erlang-questions
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20160412/ae6d1d49/attachment.htm>


More information about the erlang-questions mailing list