kern/179901: [netinet] [patch] Multicast SO_REUSEADDR handled incorrectly
Mikolaj Golub
to.my.trociny at gmail.com
Thu Jun 27 20:10:01 UTC 2013
The following reply was made to PR kern/179901; it has been noted by GNATS.
From: Mikolaj Golub <to.my.trociny at gmail.com>
To: Michael Gmelin <freebsd at grem.de>
Cc: Mikolaj Golub <trociny at FreeBSD.org>, bug-followup at FreeBSD.org
Subject: Re: kern/179901: [netinet] [patch] Multicast SO_REUSEADDR handled
incorrectly
Date: Thu, 27 Jun 2013 23:00:16 +0300
On Wed, Jun 26, 2013 at 03:03:40PM +0200, Michael Gmelin wrote:
> Hi,
>
> I adapted the test code, you can find it at
>
> http://blog.grem.de/multicast.c
>
> Test output is:
>
> IPv4 Port 5555:
> Bind using SO_REUSEADDR.......OK (expected)
> Bind using SO_REUSEADDR.......OK (expected)
> Bind using SO_REUSEPORT.......FAIL (NOT expected): Address already in
> use IPv4 Port 5556:
> Bind using SO_REUSEPORT.......OK (expected)
> Bind using SO_REUSEPORT.......OK (expected)
> Bind using SO_REUSEADDR.......OK (expected)
> Bind using SO_REUSEPORT.......FAIL (NOT expected): Address already in
> use IPv4 Port 5557:
> Bind using SO_REUSEADDR x 2...OK (expected)
> Bind using SO_REUSEADDR x 2...OK (expected)
> Bind using SO_REUSEPORT.......FAIL (NOT expected): Address already in
> use Bind using SO_REUSEADDR.......OK (expected)
> Bind using SO_REUSEPORT.......FAIL (NOT expected): Address already in
> use IPv4 Port 5558:
> Bind without socketopts.......OK (expected)
> Bind using SO_REUSEADDR.......FAIL (expected): Address already in use
> Bind using SO_REUSEPORT.......FAIL (expected): Address already in use
> IPv4 Port 5559:
> Bind using SO_REUSEADDR.......OK (expected)
> Bind without socketopts.......FAIL (expected): Address already in use
> IPv4 Port 5560:
> Bind using SO_REUSEPORT.......OK (expected)
> Bind using SO_REUSEPORT.......OK (expected)
> Bind without socketopts.......FAIL (expected): Address already in use
> IPv6 Port 5555:
> Bind using SO_REUSEADDR.......OK (expected)
> Bind using SO_REUSEADDR.......OK (expected)
> Bind using SO_REUSEPORT.......FAIL (NOT expected): Address already in
> use IPv6 Port 5556:
> Bind using SO_REUSEPORT.......OK (expected)
> Bind using SO_REUSEPORT.......OK (expected)
> Bind using SO_REUSEADDR.......OK (expected)
> Bind using SO_REUSEPORT.......FAIL (NOT expected): Address already in
> use IPv6 Port 5557:
> Bind using SO_REUSEADDR x 2...OK (expected)
> Bind using SO_REUSEADDR x 2...OK (expected)
> Bind using SO_REUSEPORT.......FAIL (NOT expected): Address already in
> use Bind using SO_REUSEADDR.......OK (expected)
> Bind using SO_REUSEPORT.......FAIL (NOT expected): Address already in
> use IPv6 Port 5558:
> Bind without socketopts.......OK (expected)
> Bind using SO_REUSEADDR.......FAIL (expected): Address already in use
> Bind using SO_REUSEPORT.......FAIL (expected): Address already in use
> IPv6 Port 5559:
> Bind using SO_REUSEADDR.......OK (expected)
> Bind without socketopts.......FAIL (expected): Address already in use
> IPv6 Port 5560:
> Bind using SO_REUSEPORT.......OK (expected)
> Bind using SO_REUSEPORT.......OK (expected)
> Bind without socketopts.......FAIL (expected): Address already in use
>
Thank you for testing!
> So you maintained the old PORT/ADDR behavior, which I think is not such
> a great idea. I would suggest to get another opinion on this, just
> because it's broken now doesn't mean we have to perpetuate it - maybe we
> should compare the behavior with other Unix(like) OSes like the other
> BSDs and Linux to see how their implementations work - usually ported
> software is not changed in that respect, so being compatible is
> valuable.
It is difficult to talk about portability in the case of SO_REUSEPORT.
AFAIK, there is no SO_REUSEPORT in Linux and it is recommended to
always use SO_REUSEADDR for multicast in portable code. It looks like
in this case we will always have expected behavior with the proposed
patch.
> Besides my rant the code works as designed and seems to resemble the
> behavior before r227207 correctly (I manually applied the patches to
> 9.1-RELEASE).
>
> Fun fact: The code in ip6_output.c could have never worked in the first
> place, since it used IN_MULTICAST instead of IN6_IS_ADDR_MULTICAST:
>
> if (IN_MULTICAST(ntohl(in6p->inp_laddr.s_addr)))
> ...
I don't insist on maintaining the old behaviour. But as actually we
have 2 issues here (regression introduced by me in FreeBSD9 and
historical behavior that looks wrong), with different priority, I
would like to fix the issues separately. This way it will be easier to
track the changes, e.g. when after a year it turns out that the second
change has broken some other case.
For now I am more concerned about having SO_REUSEADDR regression fixed
in CURRENT and STABLE9 before 9.2. The patch is under review and I
plan to commit it next week if it is ok.
The second issue might require more discussion before commiting the
change.
--
Mikolaj Golub
More information about the freebsd-net
mailing list