SO_REUSEADDR should not also mean SO_REUSEPORT

Kurt Miller kurt at intricatesoftware.com
Wed Feb 22 04:50:43 PST 2006


On Tuesday 21 February 2006 7:12 pm, Sean McNeil wrote:
> On Tue, 2006-02-21 at 10:11 -0500, Kurt Miller wrote:
> > On Saturday 18 February 2006 3:45 pm, Arne H. Juul wrote:
> > > On Sat, 18 Feb 2006, Nate Williams wrote:
> > > >> Ok, thanks. I got that impression from reading some posts I found
> > > >> while googling. There was one in particular for NetBSD that
> > > >> discussed it in detail. Check out the Apr 2 portion of this
> > > >> http://www.tinyurl.com/b46gq by Jan Schaumann. Also this
> > > >> one http://tinyurl.com/9sa6a. From these posts it appears
> > > >> that SO_REUSEPORT is needed in some cases to be compatible
> > > >> with linux.
> > > >
> > > >> From the early days....
> > > >
> > > >  - In the Multicast constructor, the low level routine sets the
> > > >    SO_REUSEADDR option by using JSO_REUSEADDR which corresponds to a call
> > > >    to setsockopt(..SO_REUSEADDR).  To make multicast sockets work in *all*
> > > >    cases on FreeBSD, we should also set SO_REUSEPORT, else in many cases
> > > >    the multicast bind will fail.
> > > 
> > > I won't claim to know what's the best behaviour with multicast, but the 
> > > problem is that SO_REUSEPORT is always used when SO_REUSEADDR was 
> > > requested, meaning that:
> > > 
> > > > SO_REUSEPORT allows completely duplicate bindings by multiple
> > > > processes if they all set SO_REUSEPORT before binding the port.
> > > 
> > > so you can have two very different java servers listening on the same 
> > > port, for example.  Or the same java server started twice won't notice any 
> > > problem because the second instance will bind its server port fine, while 
> > > on all other OSes this would give a sensible error message.  And so on. 
> > > This is bad.
> > > 
> > > The reason I found this problem in the first place was from a Java program 
> > > that worked well on Linux, not at all on FreeBSD, and after much tracing 
> > > we deduced that something was enabling SO_REUSEPORT on FreeBSD, after 
> > > which finding the bad code was a simple matter of "grep", only leaving the 
> > > question of why it was there in the first place.
> > > 
> > > If anybody figures out what's best practice for supporting multicast 
> > > applications, ask the BSD kernel people to change the kernel behaviour to 
> > > match best practice, make it possible to control SO_REUSEPORT from the 
> > > MulticastSocket class, or find some other solution that doesn't make 
> > > *other* types of java application suffer.
> > 
> > Thanks for the explanation and also to Nate for the Multicast
> > history. I've looked into this a bit more over the weekend and
> > found that the network stack promotes SO_REUSEADDR to include
> > SO_REUSEPORT for multicast addresses, so I believe that case is
> > covered already. I ran the network jck's on the 1.5 jvm with your
> > patch and found that SO_REUSEPORT is still needed to pass the jck's
> > but for datagram sockets only.
> > 
> > Could you try this patch and test it with the program you referred
> > to above?
> > 
> > --- ../../j2se/src/solaris/native/java/net/net_util_md.c.orig	Tue Feb 21 09:56:11 2006
> > +++ ../../j2se/src/solaris/native/java/net/net_util_md.c	Tue Feb 21 10:06:31 2006
> > @@ -1022,11 +1022,20 @@
> >      }
> >  
> >      /*
> > -     * If SO_REUSEADDR option requested, unconditionally set SO_REUSEPORT.
> > +     * If SO_REUSEADDR option requested for SOCK_DGRAM, set SO_REUSEPORT also.
> 
> All UDP sockets?

It is only for datagram sockets that request SO_REUSEADDR, not all.

> Why not just test the address to see if it is a  
> multicast address?

Because the DatagramSocket ReuseAddress test fails without it
(not the multicast tests).

> Shouldn't SO_REUSEPORT be set for TCP in that case 
> as well?

Humm, isn't TCP/SOCK_STREAM inherently unicast?

-Kurt


More information about the freebsd-java mailing list