mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jean Tourrilhes <jt@bougret.hpl.hp.com>
To: Linux kernel mailing list <linux-kernel@vger.kernel.org>
Subject: Re: Kernel Multicast
Date: Tue, 28 Aug 2001 14:28:29 -0700	[thread overview]
Message-ID: <20010828142829.F8147@bougret.hpl.hp.com> (raw)
In-Reply-To: <87009604743AD411B1F600508BA0F95994CA6A@XOVER.dedham.mindspeed.com>
In-Reply-To: <87009604743AD411B1F600508BA0F95994CA6A@XOVER.dedham.mindspeed.com>; from mark.clayton@netplane.com on Tue, Aug 28, 2001 at 04:12:23PM -0400

On Tue, Aug 28, 2001 at 04:12:23PM -0400, Clayton, Mark wrote:
> 
> I think this is what I recall doing: 	
> 
> socket(AF_INET, SOCK_DGRAM, 0);
> 
> setsockopt(SO_REUSEADDR)
> 
> if ((remote_addr & 0xF0000000) == 0xE0000000) then saddr.sin_addr.s_addr 
> is INADDR_ANY otherwise use local_addr.  Port is local_port
> bind(saddr);
> 
> ipMreq.imr_multiaddr.s_addr = htonl(multicast_addr);
> ipMreq.imr_address.s_addr   = htonl(local_addr);
> ipMreq.imr_ifindex          = if_index (from /sbin/ipmaddr)
> setsockopt(IP_ADD_MEMBERSHIP, ipMreq
> 
> /* mcast sends */
> ifAddr.s_addr = htonl(local_addr) 
> setsockopt(IP_MULTICAST_IF, ifAddr);
> 
> setsockopt(SIOCGIFNAME, if_index);
> 
> setsockopt(SO_BINDTODEVICE)
> 
> Also, I think that for SOCK_RAW there needs to be a second
> socket just for reading.  But I don't recall the details.
> 
> If this helps, feel free to post the details to the list
> in a summary.  Please remove references to me though.
> 
> Thanks,
> Mark


	I did my little investigation and looked int he kernel for
answers.

	I was already looking at SO_BINDTODEVICE. This is very
powerful, unfortunately, it's reserved for ROOT. Maybe running my
program as root is not the brightest idea.
	Also, one might wonder why IP_MULTICAST_IF doesn't set
sk->bound_dev_if itself, which would be logical (it only checks that
the interface is the same as sk->bound_dev_if but seem to forget to
set it in .../net/ipv4/sockglue.c).

	Anyway, doing this definitely fix the problem :
------------------------------------------
socket(AF_INET, SOCK_DGRAM, 0);
setsockopt(SO_BINDTODEVICE, ONE_INTERFACE);
bind(sock, INADDR_ANY, MY_PORT);
setsockopt(IP_ADD_MEMBERSHIP, INADDR_ALLHOSTS_GROUP, ONE_INTERFACE);
setsockopt(IP_MULTICAST_IF, ONE_INTERFACE);
------------------------------------------
	Works as advertised : you can have one and only one socket per
interface.

	Now, let's have a bit of fun... If you do :
------------------------------------------
socket(AF_INET, SOCK_DGRAM, 0);
bind(sock, INADDR_ANY, MY_PORT);
setsockopt(SO_BINDTODEVICE, ONE_INTERFACE);
setsockopt(IP_ADD_MEMBERSHIP, INADDR_ALLHOSTS_GROUP, ONE_INTERFACE);
setsockopt(IP_MULTICAST_IF, ONE_INTERFACE);
------------------------------------------
	In that case, the kernel let you open more than one socket per
interface (two, there...). I don't know if its intended, but it works
fine ;-)

	And you can also do this :
------------------------------------------
socket(AF_INET, SOCK_DGRAM, 0);
bind(sock, INADDR_ANY, MY_PORT);
setsockopt(IP_ADD_MEMBERSHIP, INADDR_ALLHOSTS_GROUP, ONE_INTERFACE);
setsockopt(IP_MULTICAST_IF, ONE_INTERFACE);
setsockopt(SO_BINDTODEVICE, ANOTHER_INTERFACE);
------------------------------------------
	This will send packet on ANOTHER_INTERFACE, but the source
address of those packet will be the one of ONE_INTERFACE.

	And if you look in .../net/core/sock.c, you will realise that
these two calls are handled very differently :
------------------------------------------
setsockopt(SO_BINDTODEVICE, "", 0);
setsockopt(SO_BINDTODEVICE, "", IFNAMSIZ);
------------------------------------------
	Which mean the man page need to be fixed ;-)

	Anyway, I don't really want to rely on SO_BINDTODEVICE,
because it needs ROOT capability.


	Now, you suggestions to use SO_REUSEADDR is spot on. It works
as any user. I get a little bit more than I bargained for (I want only
one socket per interface), but that's ok...
	In other words, this works :
------------------------------------------
socket(AF_INET, SOCK_DGRAM, 0);
setsockopt(SO_REUSEADDR, 1);
bind(sock, INADDR_ANY, MY_PORT);
setsockopt(IP_ADD_MEMBERSHIP, INADDR_ALLHOSTS_GROUP, ONE_INTERFACE);
setsockopt(IP_MULTICAST_IF, ONE_INTERFACE);
------------------------------------------
	With one little caveat : such socket seems to receive
multicast comming from all interfaces. In other words, it seem that
IP_MULTICAST_IF only act on the outgoing path.
	In other words, IP_MULTICAST_IF doesn't do much... At least,
much less that what you would believe it to do...

	Also, using both SO_BINDTODEVICE and SO_REUSEADDR may be
overkill...

	That's it...

	Jean

       reply	other threads:[~2001-08-28 21:28 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <87009604743AD411B1F600508BA0F95994CA6A@XOVER.dedham.mindspeed.com>
2001-08-28 21:28 ` Jean Tourrilhes [this message]
     [not found] <87009604743AD411B1F600508BA0F95994CA68@XOVER.dedham.mindspeed.com>
2001-08-28 18:13 ` Jean Tourrilhes
2001-08-28 18:30   ` Ion Badulescu
2001-08-28 18:34     ` Jean Tourrilhes
2001-08-28 17:19 Jean Tourrilhes

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20010828142829.F8147@bougret.hpl.hp.com \
    --to=jt@bougret.hpl.hp.com \
    --cc=jt@hpl.hp.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®