Datagram socket leak

Salter, Thomas A Thomas.Salter at unisys.com
Mon Aug 29 12:01:22 PDT 2011


Here's what I changed.  I'm working with the fcs source bundle for b147,  27_jun_2011, so I may not have the latest source base.

Left base folder: new
Right base folder: b147

File: src\share\classes\java\net\DatagramSocket.java
186,189d185
<         finally {
<             if( !isBound() )
<                 close();
<         }
234d229
<           try {
236,239d230
<           } finally {
<               if( !isBound() )
<                   close();
<           }

File: src\share\classes\java\net\MulticastSocket.java
165d164
<           try {
167,170d165
<           } finally {
<               if( !isBound() )
<                   close();
<           }




-----Original Message-----
From: Chris Hegarty [mailto:chris.hegarty at oracle.com] 
Sent: Monday, August 29, 2011 2:33 PM
To: Salter, Thomas A
Cc: net-dev at openjdk.java.net
Subject: Re: Datagram socket leak

Ah ok. I finally get it.

In which case I think you original changes should be fine. Do you want 
to make similar changes to MulticastSocket and post the diffs?

Also, I think a testcase would be useful here. I know it's not strictly 
specified that the socket should be closed if the constructor throws, 
but it does seem desirable.

-Chris.

On 08/29/11 07:14 PM, Salter, Thomas A wrote:
> I believe you're referring to the close() in the catch clause following the call to getImpl().bind.  The problem I encountered was when the Datagram.bind threw an exception before it got that far.  In my case, the checkListen was throwing a SecurityException, but any of the earlier throws would cause the same problem.  The SecurityException wouldn't have been caught by the catch addressed by the CR in any case.  We encountered this while running the TCK.  One of its tests tries to create lots of sockets, all of them getting security violations until we hit a limit on the number of open sockets.
>
>      public synchronized void bind(SocketAddress addr) throws SocketException {
>          if (isClosed())
>              throw new SocketException("Socket is closed");
>          if (isBound())
>              throw new SocketException("already bound");
>          if (addr == null)
>              addr = new InetSocketAddress(0);
>          if (!(addr instanceof InetSocketAddress))
>              throw new IllegalArgumentException("Unsupported address type!");
>          InetSocketAddress epoint = (InetSocketAddress) addr;
>          if (epoint.isUnresolved())
>              throw new SocketException("Unresolved address");
>          InetAddress iaddr = epoint.getAddress();
>          int port = epoint.getPort();
>          checkAddress(iaddr, "bind");
>          SecurityManager sec = System.getSecurityManager();
>          if (sec != null) {
>              sec.checkListen(port);<<<<<<<<<<<<<<<<<<<<<<<<<<  This throws a SecurityException
>          }
>          try {
>              getImpl().bind(port, iaddr);
>          } catch (SocketException e) {
>              getImpl().close();
>              throw e;
>          }
>          bound = true;
>      }
>
> Tom.
>
>
> -----Original Message-----
> From: Chris Hegarty [mailto:chris.hegarty at oracle.com]
> Sent: Monday, August 29, 2011 1:56 PM
> To: Salter, Thomas A
> Cc: net-dev at openjdk.java.net
> Subject: Re: Datagram socket leak
>
> [take two!]
>
> Tom,
>
> This specific area of code was changed recently due to CR 7035556 [1],
> changeset [2], and this issue was discussed during the code review [3].
>
> Essentially, bind() already closes the impl internally before throwing
> the exception. Does this resolve the issue for you? Or do you still see
> potential to leak?
>
> -Chris
>
> [1] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7035556
> [2] http://hg.openjdk.java.net/jdk8/tl/jdk/rev/07a12583d4ea
> [3] http://mail.openjdk.java.net/pipermail/net-dev/2011-July/003318.html
>
> On 08/29/11 03:27 PM, Salter, Thomas A wrote:
>> There appears to be a socket leak in both DatagramSocket and
>> MulticastSocket constructors. Both classes have constructors that create
>> a socket and then attempt to bind. The bind can fail with a variety of
>> exceptions none of which are caught by the constructor. Thus, the actual
>> system socket that was allocated by impl.create() is never closed.
>>
>> My fix was to wrap a try-finally around the bind call and call close()
>> if isBound is false.
>>
>> public DatagramSocket(SocketAddress bindaddr) throws SocketException {
>>
>> // create a datagram socket.
>>
>> createImpl();
>>
>> if (bindaddr != null) {
>>
>> try {
>>
>> bind(bindaddr);
>>
>> } finally {
>>
>> if( !isBound() )
>>
>> close();
>>
>> }
>>
>> }
>>
>> }
>>
>> Tom Salter
>>
>> Unisys Corporation
>>



More information about the net-dev mailing list