Hi Lucy,

in general I support the addition of SO_REUSEPORT to the set of
standard socket options. However for me the problem is not that this
new option is not supported on all platforms, but instead that it has
such different semantics on different platforms. If you look at the
code, you'll see that we already implicitly set SO_REUSEPORT on Mac
and AIX for datagram sockets for which we set SO_REUSEADDR. So maybe
we have to rethink this, once  SO_REUSEPORT becomes available as a
standard socket option.

I like the new wording you've posted for JavaDoc of SO_REUSEPORT, but
I think the sentence:

* Although SO_REUSEADDR option already enables similar
* functionality, SO_REUSEPORT prevents port hijacking and
* distributes the involving datagrams evenly across all of the
* receiving threads.

refers to a Linux-specific implementation detail which shouldn't be
mentioned in the general documentation. You already have the sentence
"The exact semantics of this socket option are socket type and system
dependent" which should let everybody think twice before using this
option. I'm also not sure about the link to the Linux article but I
again think it is inappropriate in a general API documentation
(otherwise we would have to add links for every platform which
supports SO_REUSEPORT).

As far as I can see (and please correct me if I'm wrong) you actually
only add the new option for Linux platforms. But this socket option is
also supported on Solaris (>= 11), MacOS X, AIX. So could you please
enable it on the other platforms as well.

Finally I want to mention the good stackoverflow article at
http://stackoverflow.com/questions/14388706/socket-options-so-reuseaddr-and-so-reuseport-how-do-they-differ-do-they-mean-t
which covers the topic SO_REUSEADDR vs. SO_REUSEPORT quite well. And
I've collected the man-page entries for SO_REUSEADDR and SO_REUSEPORT
for the systems I have  (unfortunately, I couldn't find an updated
Linux man-page which mentions SO_REUSEPORT):

Linux
=====

       SO_REUSEADDR
              Indicates that the rules used in validating addresses
              supplied in a bind(2) call should allow reuse of local
              addresses.  For AF_INET sockets this means that a socket
              may bind, except when there is an active listening
              socket bound to the address.  When the listening socket
              is bound to INADDR_ANY with a specific port then it is
              not possi- ble to bind to this port for any local
              address.  Argument is an integer boolean flag.

       Linux will only allow port reuse with the SO_REUSEADDR option
       when this option was set both in the previous program that
       performed a bind(2) to the port and in the program that wants
       to reuse the port.  This differs from some implementations
       (e.g., FreeBSD) where only the later program needs to set the
       SO_REUSEADDR option.  Typically this difference is invisi- ble,
       since, for example, a server program is designed to always set
       this option.

MacOS X
=======
           SO_REUSEADDR    enables local address reuse
           SO_REUSEPORT    enables duplicate address and port bindings

     SO_REUSEADDR indicates that the rules used in validating
     addresses supplied in a bind(2) call should allow reuse of local
     addresses.

     SO_REUSEPORT allows completely duplicate bindings by multiple
     processes if they all set SO_REUSEPORT before bind- ing the port.
     This option permits multiple instances of a program to each
     receive UDP/IP multicast or broadcast datagrams destined for the
     bound port.

Solaris
=======

     SO_REUSEADDR          enable/disable local address reuse


     SO_REUSEPORT          enable/disable local  port  reuse  for
                           PF_INET/PF_INET6 socket

     The SO_REUSEADDR/SO_REUSEPORT options indi- cate that the rules
     used in validating addresses and ports supplied in a
     bind(3SOCKET) call should allow reuse of local addresses or
     ports.

AIX
===

             SO_REUSEADDR
                   Specifies that the rules used in validating
                   addresses supplied by a bind subroutine should
                   allow reuse of a local port. A particular IP
                   address can only be bound once to the same
                   port. This option enables or disables reuse of
                   local ports.

                   SO_REUSEADDR allows an application to explicitly
                   deny subsequent bind subroutine to the port/address
                   of the socket with SO_REUSEADDR set. This allows an
                   application to block other applications from
                   binding with the bind subroutine.

              SO_REUSEPORT
                   Specifies that the rules used in validating
                   addresses supplied by a bind subroutine should
                   allow reuse of a local port/address
                   combination. Each binding of the port/address
                   combination must specify the SO_REUSEPORT socket
                   option. This option enables or disables the reuse
                   of local port/address combinations.

HPUX
====

           SO_REUSEADDR
              (int; boolean; AF_INET sockets only) If enabled, allows
              a local address to be reused in subsequent calls to
              bind().  Default: disallowed.

           SO_REUSEPORT
              (int; boolean; AF_INET sockets only) If enabled, allows
              a local address and port to be reused in subsequent
              calls to bind().  Default: disallowed.

      Setting the SO_REUSEADDR option allows the local socket address
      to be reused in subsequent calls to bind().  This permits
      multiple SOCK_STREAM sockets to be bound to the same local
      address, as long as all existing sockets with the desired local
      address are in a connected state before bind() is called for a
      new socket.  For SOCK_DGRAM sockets, SO_REUSEADDR allows
      multiple sockets to receive UDP multicast datagrams addressed to
      the bound port number.  For all SOCK_DGRAM sockets bound to the
      same local address, SO_REUSEADDR must be set before calling
      bind().

      Setting the SO_REUSEPORT option allows multiple SOCK_DGRAM
      sockets to share the same address and port.  Each one of those
      sockets, including the first one to use that port, must specify
      this option before calling bind().

Regards,
Volker


On Mon, Nov 23, 2015 at 9:00 AM, Alan Bateman <alan.bate...@oracle.com> wrote:
>
>
> On 23/11/2015 04:12, Lu, Yingqi wrote:
>
> Hi Alan,
>
>
>
> One more question please J I want to make sure I understand correctly on
> your following suggestion. In order to use supportedOptions method to test
> SO_REUSEPORT, I will need to first write a native function to check if
> SO_REUSEPORT is supported. Then, in the defaultOptions method, I do a
> conditional add for StandardSocketOptions.SO_REUSEPORT if it is supported on
> the platform? Is this a preferred way to implement? Please let me know!
>
>
> Yes as supportedOptions() shouldn't return SO_REUSEPORT in the set when it's
> not supported. It might be simplest to put that code in sun.nio.ch.Net,
> maybe isReusePortSupported or some such method. In the implementation
> (Net.c) then you can return true or false depending on the platform and
> maybe kernel version.
>
> -Alan

Reply via email to