Bug 149086

Summary: [multicast] Generic multicast join failure in 8.1
Product: Base System Reporter: Hans-Werner Braun <hwb>
Component: kernAssignee: freebsd-bugs (Nobody) <bugs>
Status: Open ---    
Severity: Affects Only Me CC: l0k18
Priority: Normal    
Version: 8.1-RELEASE   
Hardware: Any   
OS: Any   

Description Hans-Werner Braun 2010-07-30 01:00:09 UTC
A perl program that I used in previous FreeBSD releases does not work any
more. Specifically from tcpdump outputs it does not send the join request
to the router. The program:

#!/usr/local/bin/perl

use Socket;

$PORT=$ARGV[0];
$PATTERN=$ARGV[1];
$SERVER=$ARGV[2];

if($PORT eq ""){
 printf"Syntax: mcaststream.pl port {pattern} {multicastaddress}\n";
 exit;
}
if($SERVER eq ""){$SERVER="233.7.117.79";}

$|=1;

$IP_ADD_MEMBERSHIP=12;

($name, $aliases, $type, $len, $SERVERIP) = gethostbyname($SERVER);

$sockaddr = 'S n a4 x8';

socket(S, PF_INET,SOCK_DGRAM,UDP_PROTO)||die("$!");
setsockopt(S, SOL_SOCKET, SO_REUSEPORT, 1)||die("$!");
$us = pack($sockaddr, 2, $PORT, pack("C4", 0,0,0,0));
bind(S, $us)||die("$!");

setsockopt(S, 0, $IP_ADD_MEMBERSHIP, $SERVERIP."\0\0\0\0")||die("$!");

while($theiraddr=recv(S,$BUF,1024,0)){
 ($junk, $junk, $sourceaddr, $junk) = unpack($sockaddr, $theiraddr);
 $theirip=join('.',unpack('C4', $sourceaddr));
 if($BUF =~ $PATTERN){
  printf"$theirip\t$BUF";
 }
}

How-To-Repeat: The above program sends no traffic out of the Ethernet interface (specifically the join request).
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2010-07-30 02:35:20 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-net

Over to maintainer(s).
Comment 2 Hans-Werner Braun 2010-08-05 21:20:56 UTC
A program that is a straight adaptation from the IO::Socket::Multicast
man page does not work either:

----
  #!/usr/local/bin/perl
  
  use strict;
  use IO::Socket::Multicast;
  
  use constant GROUP => '233.7.117.79';
  use constant PORT  => '4011';
  
  my $sock = IO::Socket::Multicast->new(Proto=>'udp',LocalPort=>PORT);
  $sock->mcast_add(GROUP) || die "Couldn't set group: $!\n";
  
  while (1) {
   my $data;
   next unless $sock->recv($data,1024);
   print $data;
  }
----

It only displays data if the multicast stream already exists on the
local Ethernet, but it does not send the group join request out to
initiate the receiving stream on the local Ethernet.
Comment 3 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 07:59:49 UTC
For bugs matching the following criteria:

Status: In Progress Changed: (is less than) 2014-06-01

Reset to default assignee and clear in-progress tags.

Mail being skipped
Comment 4 Loki Verloren 2020-02-22 19:17:36 UTC
I'm not 100% sure this is related but the code here: https://github.com/p9c/pod/blob/master/pkg/transport/transport.go#L72

which works on MacOS 10.13.6 and linux 5.something kernel is not sending out any packets at all. The listener works but the sender does not. I have already tried using SO_REUSEPORT instead of SO_REUSEADDR and this makes no difference to any other platform I am testing from working.

I dug around the current open issues to see if there was something relevant, and I think this might be exactly the same issue. This is a different language and potentially does share C library accesses in common with the Perl problems being reported here. I hope my report can add something towards solving this issue.

I am at least relieved to see that this looks like a FreeBSD kernel bug since as I said, the same code above also works on MacOS. However, the *bsd platforms on the Go standard library are the least exercised of all the major platform ports and it's possible that even though it looks like a similar bug it may not be.
Comment 5 Loki Verloren 2020-02-22 22:08:26 UTC
just clarifying a little bit on my report, in previous revisions the code referenced used a function from the golang.org/x/net repository ipv4 library to join the network. It gives an error about incorrect socket options and also can't send. On linux and macos they talk across the network perfectly. 

The freebsd machine here also receives the packets, on a virtual machine with windows boxed into a NAT it can't get the packets from anywhere but I suspect it also can receive them on a normal LAN. I think that for windows it was working with the x library but also on darwin platform an error with socket options so I thought at first it was a BSD thing. That's a bit aside from anything relevant, ahem.