DatagramSocket vs DatagramChannel behavior in disconnect()

Florian Weimer fweimer at redhat.com
Fri Feb 28 07:57:11 PST 2014


On 02/28/2014 04:28 PM, Alan Bateman wrote:
> On 28/02/2014 14:59, Florian Weimer wrote:
>> Sockets preserve the local address on disconnect(), but channels
>> don't.  Bug 6431343 reflects that, but this is still surprising and
>> violates the NetworkChannel contract ("Once an association is
>> established then the socket remains bound until the channel is closed").
>>
>> I see this on Linux.  Behavior on other systems is different.  For
>> datagram sockets, the native disconnect() implementation has a
>> Linux-specific workaround for this, but DatagramChannel lacks it.
>>
>> What's the best way to address this?  Adjust the NetworkChannel
>> documentation?  Apply the DatagramSocket workaround to DatagramChannel
>> as well?
>>
> Does the ChangingAddress test fail for you? I thought it was just that
> the local address might change (after connect or disconnect) and not
> that the socket would move an unbound state.

The test only looks at the address part of the local name, not the port.

I added some instrumentation to it to print the local socket address 
after open/connect/..., and here is what I get:

DatagramSocket open: 0.0.0.0/0.0.0.0:56788
DatagramChannel open: /0:0:0:0:0:0:0:0:43233
DatagramSocket connect: /10.33.200.60:56788
DatagramChannel connect: /10.33.200.60:43233
DatagramSocket disconnect: 0.0.0.0/0.0.0.0:56788
DatagramChannel disconnect: /0:0:0:0:0:0:0:0:0
DatagramSocket reconnect: /10.33.200.60:56788
DatagramChannel reconnect: /10.33.200.60:37939
DatagramSocket redisconnect: 0.0.0.0/0.0.0.0:56788
DatagramChannel redisconnect: /0:0:0:0:0:0:0:0:0

So the socket preserves only the port, but not the address, and the 
channel preserves neither.

With an explicit bind, it looks like this:

DatagramSocket open: /10.33.200.60:45307
DatagramChannel open: /10.33.200.60:50218
DatagramSocket connect: /10.33.200.60:45307
DatagramChannel connect: /10.33.200.60:50218
DatagramSocket disconnect: /10.33.200.60:45307
DatagramChannel disconnect: /10.33.200.60:0
DatagramSocket reconnect: /10.33.200.60:45307
DatagramChannel reconnect: /10.33.200.60:46574
DatagramSocket redisconnect: /10.33.200.60:45307
DatagramChannel redisconnect: /10.33.200.60:0

So the channel still does not preserve the port.

With a strong end system model (do we support any of those?), preserving 
the address would result in unusable sockets, so not preserving the 
address is probably the right thing to do.

-- 
Florian Weimer / Red Hat Product Security Team


More information about the nio-dev mailing list