<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">I believe what is possibly missing in the Erlang code:<div class=""><br class=""></div><div class=""><div class="" style="font-family: Avenir-Book;">Port = 3100,</div><div class="" style="font-family: Avenir-Book;"><font face="Andale Mono" class="">Bin = << <<239,0,0,1>>/binary, <<0,0,0,0>>/binary, <<10,0,1,1>>/binary >>,</font></div><div class="" style="font-family: Avenir-Book;"><font face="Andale Mono" class="">{ok, _Socket} = gen_udp:open(Port,<br class=""> [binary,<br class=""> {active, true},<br class=""> {reuseaddr, true},<br class=""> {multicast_ttl, 30},<br class=""> {raw, 0, 39, Bin}]), %% 0 - IPPROTO_IP, 39 - IP_ADD_SOURCE_MEMBERSHIP</font></div><div><br class=""></div><div>Is the socket bind() of the multicast IP and Port that is done in the Python.</div><div><br class=""></div><div>Mark.</div><div><br class=""><blockquote type="cite" class=""><div class="">On Jan 21, 2021, at 11:11 AM, Mark Geib <<a href="mailto:mark.geib.44@gmail.com" class="">mark.geib.44@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="content-isolator__container"><meta http-equiv="Content-Type" content="text/html; charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">John,<div class=""><br class=""></div><div class="">To confirm that the OS may be the source of this problem I wrote a small python script, based on some examples, and then did the SSM joint to the same two multicasts as I am doing in Erlang. I am running on the same host in both cases.</div><div class=""><br class=""></div><div class="">The python script works as expected, each instance receives only the datagrams from the specified host. Of course I ran two different instances of the script. So it appears that the OS, Linux in this case, does support SSM properly. For completeness here is a snippet of the python.</div><div class=""><br class=""></div><div class=""><pre class="top tightenable bottom"> opts, args = getopt.getopt(sys.argv[2:], 'g:i:s:p:')
opts = dict(opts)
opts.setdefault('-i', '0.0.0.0')
imr = (socket.inet_pton(socket.AF_INET, opts['-g']) +
socket.inet_pton(socket.AF_INET, opts['-i']) +
socket.inet_pton(socket.AF_INET, opts['-s']))
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.setsockopt(socket.SOL_IP, socket.IP_ADD_SOURCE_MEMBERSHIP, imr)
s.bind((opts['-g'], int(opts['-p'])))
print 'READY.'
while True:
print repr(s.recvfrom(4096))</pre><div class=""><br class=""></div></div><div class="">Mark.</div><div class=""><br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Jan 21, 2021, at 8:39 AM, Mark Geib <<a href="mailto:mark.geib.44@gmail.com" class="">mark.geib.44@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="content-isolator__container"><meta http-equiv="Content-Type" content="text/html; charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Thank you John for information and references. This application runs on Linux, so I can see if maybe something is mis-configured. I also considered trying to create virtual interfaces and use a different interface for each multicast join, just have not had the time to test.<div class=""><br class=""></div><div class="">Mark.<br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Jan 21, 2021, at 4:06 AM, John Högberg <<a href="mailto:john.hogberg@ericsson.com" class="">john.hogberg@ericsson.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta charset="UTF-8" class=""><div class="WordSection1" style="page: WordSection1; caret-color: rgb(0, 0, 0); font-family: Avenir-Book; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;"><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">> After digging into the details of multicast by reading in "UNIX Network Programming” the problem may be that joining multicast groups is done at the IP level in the network stack and apparently all sockets on a network interface will receive the datagrams for all multicasts when there is more than one, so a bind() needs to be done to create a “filter” for each socket so that only datagrams from the configured multicast are sent to each socket.<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">Yes, this is how IGMPv2 and earlier works. RFC 3367 (IGMPv3) has a paragraph that summarizes it nicely:<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""> Filtering of packets based upon a socket's multicast reception<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""> state is a new feature of this service interface. The previous<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""> service interface [RFC1112] described no filtering based upon<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""> multicast join state; rather, a join on a socket simply caused the<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""> host to join a group on the given interface, and packets destined<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""> for that group could be delivered to all sockets whether they had<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""> joined or not.<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">> Maybe the {add_membership…} option includes this bind(), but of course the {raw…} does not.<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">The problem isn’t the lack of bind(2) – gen_udp:open/1-2 does that for you – I believe it’s that your OS doesn’t implement RFC 3367 which states that a socket should only receive datagrams from the SSM groups it has joined. RFC 4607 further clarifies this in section 2:<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""> The source-specific multicast service is defined as follows:<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""> A datagram sent with source IP address S and destination IP<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""> address G in the SSM range is delivered to each host socket that<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""> has specifically requested delivery of datagrams sent by S to G,<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""> and only to those sockets.<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">Since your OS apparently doesn’t do this, I’m afraid you might have to filter the unwanted datagrams out after the fact. :-(<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">/John<o:p class=""></o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div><div class=""><div style="border-style: solid none none; border-top-width: 1pt; border-top-color: rgb(225, 225, 225); padding: 3pt 0cm 0cm;" class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><b class="">From:</b><span class="Apple-converted-space"> </span>erlang-questions <<a href="mailto:erlang-questions-bounces@erlang.org" class="">erlang-questions-bounces@erlang.org</a>><span class="Apple-converted-space"> </span><b class="">On Behalf Of<span class="Apple-converted-space"> </span></b>Mark Geib<br class=""><b class="">Sent:</b><span class="Apple-converted-space"> </span>Wednesday, January 20, 2021 17:33<br class=""><b class="">To:</b><span class="Apple-converted-space"> </span>Sergej Jurečko <<a href="mailto:sergej.jurecko@gmail.com" class="">sergej.jurecko@gmail.com</a>><br class=""><b class="">Cc:</b><span class="Apple-converted-space"> </span>Erlang Questions <<a href="mailto:erlang-questions@erlang.org" class="">erlang-questions@erlang.org</a>><br class=""><b class="">Subject:</b><span class="Apple-converted-space"> </span>Re: multicast join problems (source specific)<o:p class=""></o:p></div></div></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">Yes, this suggestion is the method to join a any-source, or legacy, multicast. And this does work correctly.<o:p class=""></o:p></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">The problem I am having is trying to join a IGMPv3 source-specific multicast where the IP of the source producing the multicast must be included, which is the purpose of the {raw..} option. The normal {add_membership…} does not work with source-specific multicast.<o:p class=""></o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">After digging into the details of multicast by reading in "UNIX Network Programming” the problem may be that joining multicast groups is done at the IP level in the network stack and apparently all sockets on a network interface will receive the datagrams for all multicasts when there is more than one, so a bind() needs to be done to create a “filter” for each socket so that only datagrams from the configured multicast are sent to each socket. Maybe the {add_membership…} option includes this bind(), but of course the {raw…} does not.<o:p class=""></o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">I am thinking the way to address this problem will be using the new socket module, which provides a bind() function.<o:p class=""></o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">Thanks.<o:p class=""></o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 12pt; font-size: 11pt; font-family: Calibri, sans-serif;"><o:p class=""> </o:p></p><blockquote style="margin-top: 5pt; margin-bottom: 5pt;" class=""><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">On Jan 20, 2021, at 1:54 AM, Sergej Jurečko <<a href="mailto:sergej.jurecko@gmail.com" style="color: blue; text-decoration: underline;" class="">sergej.jurecko@gmail.com</a>> wrote:<o:p class=""></o:p></div></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div><div class=""><div class=""><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">Try connecting to multicast like so (Mc is multicast IP, Src is local IP):<o:p class=""></o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">{ok, SockSrc} = gen_udp:open(Port, [{reuseaddr,true},<span class="Apple-converted-space"> </span><br class="">{ip, {0,0,0,0}}, {add_membership, {Mc, Src}},{active,true}, binary,{recbuf, 1024*1024}]);<o:p class=""></o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">Or maybe<o:p class=""></o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">{ok, SockSrc} = gen_udp:open(Port, [{reuseaddr,true},<span class="Apple-converted-space"> </span><br class="">{ip, Src}, {multicast_ttl, 1}, {multicast_loop, false}, binary]),<br class="">inet:setopts(SockSrc, [{add_membership, {Mc, Src}}]);<o:p class=""></o:p></div></div></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div><div class=""><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">On Mon, Jan 18, 2021 at 10:20 PM Mark Geib <<a href="mailto:mark.geib.44@gmail.com" style="color: blue; text-decoration: underline;" class="">mark.geib.44@gmail.com</a>> wrote:<o:p class=""></o:p></div></div><blockquote style="border-style: none none none solid; border-left-width: 1pt; border-left-color: rgb(204, 204, 204); padding: 0cm 0cm 0cm 6pt; margin: 5pt 0cm 5pt 4.8pt;" class=""><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">I have a problem when joining more than one source specific multicast group. The first gen_udp:open() works as expected, I start receiving datagrams sent to the specified multicast address, and coming from the specified source. However, in another gen_server if I try to do the same, but on a different multicast and source address, I start receiving the datagrams on both the new socket as well as the first socket and from both multicast groups. The open looks like:<o:p class=""></o:p></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">Port = 3100,<o:p class=""></o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-family: "Andale Mono", serif;" class="">Bin = << <<239,0,0,1>>/binary, <<0,0,0,0>>/binary, <<10,0,1,1>>/binary >>,</span><o:p class=""></o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-family: "Andale Mono", serif;" class="">{ok, _Socket} = gen_udp:open(Port,<br class=""> [binary,<br class=""> {active, true},<br class=""> {reuseaddr, true},<br class=""> {multicast_ttl, 30},<br class=""> {raw, 0, 39, Bin}]), %% 0 - IPPROTO_IP, 39 - IP_ADD_SOURCE_MEMBERSHIP</span><o:p class=""></o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-family: Avenir-Book, serif;" class="">I am able to join multiple multicasts, non source specific, and receive only datagrams from the correct group by using an open like:</span><o:p class=""></o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div></div><div class=""><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">Port = 3100,<o:p class=""></o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-family: "Andale Mono", serif;" class="">{ok, _Socket} = gen_udp:open(Port,</span><o:p class=""></o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-family: "Andale Mono", serif;" class=""> [binary,<br class=""> {active, true},<br class=""> {reuseaddr, true},<br class=""> {multicast_ttl, 30},</span><o:p class=""></o:p></div></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-family: "Andale Mono", serif;" class=""> {add_membership, {239,0,0,1}, {0,0,0,0}}]),</span><o:p class=""></o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-family: Avenir-Book, serif;" class="">Any suggestions or help would be appreciated.</span><o:p class=""></o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div></div><div class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-family: Avenir-Book, serif;" class="">Mark.</span></div></div></div></blockquote></div></div></blockquote></div></div></div></div></blockquote></div><br class=""></div></div></div></div></blockquote></div><br class=""></div></div></div></div></blockquote></div><br class=""></div></body></html>