8198753: (dc) DatagramChannel throws unspecified exceptions

Reviewed-by: alanb
This commit is contained in:
Brian Burkhalter 2018-03-22 12:29:52 -07:00
parent 9aff9cb645
commit 37f1b2b1e3
7 changed files with 217 additions and 75 deletions

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -279,6 +279,9 @@ public abstract class DatagramChannel
* *
* @return This datagram channel * @return This datagram channel
* *
* @throws AlreadyConnectedException
* If this channel is already connected
*
* @throws ClosedChannelException * @throws ClosedChannelException
* If this channel is closed * If this channel is closed
* *
@ -292,6 +295,12 @@ public abstract class DatagramChannel
* closing the channel and setting the current thread's * closing the channel and setting the current thread's
* interrupt status * interrupt status
* *
* @throws UnresolvedAddressException
* If the given remote address is not fully resolved
*
* @throws UnsupportedAddressTypeException
* If the type of the given remote address is not supported
*
* @throws SecurityException * @throws SecurityException
* If a security manager has been installed * If a security manager has been installed
* and it does not permit access to the given remote address * and it does not permit access to the given remote address
@ -444,6 +453,10 @@ public abstract class DatagramChannel
* zero if there was insufficient room for the datagram in the * zero if there was insufficient room for the datagram in the
* underlying output buffer * underlying output buffer
* *
* @throws AlreadyConnectedException
* If this channel is connected to a different address
* from that specified by {@code target}
*
* @throws ClosedChannelException * @throws ClosedChannelException
* If this channel is closed * If this channel is closed
* *
@ -457,6 +470,12 @@ public abstract class DatagramChannel
* closing the channel and setting the current thread's * closing the channel and setting the current thread's
* interrupt status * interrupt status
* *
* @throws UnresolvedAddressException
* If the given remote address is not fully resolved
*
* @throws UnsupportedAddressTypeException
* If the type of the given remote address is not supported
*
* @throws SecurityException * @throws SecurityException
* If a security manager has been installed * If a security manager has been installed
* and it does not permit datagrams to be sent * and it does not permit datagrams to be sent

View file

@ -508,8 +508,7 @@ class DatagramChannelImpl
if (remote != null) { if (remote != null) {
// connected // connected
if (!target.equals(remote)) { if (!target.equals(remote)) {
throw new IllegalArgumentException( throw new AlreadyConnectedException();
"Connected address not equal to target address");
} }
do { do {
n = IOUtil.write(fd, src, -1, nd); n = IOUtil.write(fd, src, -1, nd);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -102,7 +102,7 @@ public class Connect {
try { try {
dc.send(bb, bogus); dc.send(bb, bogus);
throw new RuntimeException("Allowed bogus send while connected"); throw new RuntimeException("Allowed bogus send while connected");
} catch (IllegalArgumentException iae) { } catch (AlreadyConnectedException ace) {
// Correct behavior // Correct behavior
} }

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 8198753
* @summary Test DatagramChannel connect exceptions
* @library ..
* @run testng ConnectExceptions
*/
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
public class ConnectExceptions {
static DatagramChannel sndChannel;
static DatagramChannel rcvChannel;
static InetSocketAddress sender;
static InetSocketAddress receiver;
@BeforeTest
public static void setup() throws Exception {
sndChannel = DatagramChannel.open();
sndChannel.bind(null);
InetAddress address = InetAddress.getLocalHost();
if (address.isLoopbackAddress()) {
address = InetAddress.getLoopbackAddress();
}
sender = new InetSocketAddress(address,
sndChannel.socket().getLocalPort());
rcvChannel = DatagramChannel.open();
rcvChannel.bind(null);
receiver = new InetSocketAddress(address,
rcvChannel.socket().getLocalPort());
}
@Test(expectedExceptions = UnsupportedAddressTypeException.class)
public static void unsupportedAddressTypeException() throws Exception {
rcvChannel.connect(sender);
sndChannel.connect(new SocketAddress() {});
}
@Test(expectedExceptions = UnresolvedAddressException.class)
public static void unresolvedAddressException() throws Exception {
String host = TestUtil.UNRESOLVABLE_HOST;
InetSocketAddress unresolvable = new InetSocketAddress (host, 37);
sndChannel.connect(unresolvable);
}
@Test(expectedExceptions = AlreadyConnectedException.class)
public static void alreadyConnectedException() throws Exception {
sndChannel.connect(receiver);
InetSocketAddress random = new InetSocketAddress(0);
sndChannel.connect(random);
}
@AfterTest
public static void cleanup() throws Exception {
rcvChannel.close();
sndChannel.close();
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,6 +24,8 @@
/* @test /* @test
* @bug 4849277 7183800 * @bug 4849277 7183800
* @summary Test DatagramChannel send while connected * @summary Test DatagramChannel send while connected
* @library ..
* @run testng ConnectedSend
* @author Mike McCloskey * @author Mike McCloskey
*/ */
@ -32,20 +34,16 @@ import java.net.*;
import java.nio.*; import java.nio.*;
import java.nio.channels.*; import java.nio.channels.*;
import java.nio.charset.*; import java.nio.charset.*;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
public class ConnectedSend { public class ConnectedSend {
public static void main(String[] args) throws Exception {
test1();
test2();
}
// Check if DatagramChannel.send while connected can include // Check if DatagramChannel.send while connected can include
// address without throwing // address without throwing
private static void test1() throws Exception { @Test
public static void sendToConnectedAddress() throws Exception {
DatagramChannel sndChannel = DatagramChannel.open(); DatagramChannel sndChannel = DatagramChannel.open();
sndChannel.socket().bind(null); sndChannel.bind(null);
InetAddress address = InetAddress.getLocalHost(); InetAddress address = InetAddress.getLocalHost();
if (address.isLoopbackAddress()) { if (address.isLoopbackAddress()) {
address = InetAddress.getLoopbackAddress(); address = InetAddress.getLoopbackAddress();
@ -55,7 +53,7 @@ public class ConnectedSend {
sndChannel.socket().getLocalPort()); sndChannel.socket().getLocalPort());
DatagramChannel rcvChannel = DatagramChannel.open(); DatagramChannel rcvChannel = DatagramChannel.open();
rcvChannel.socket().bind(null); rcvChannel.bind(null);
InetSocketAddress receiver = new InetSocketAddress( InetSocketAddress receiver = new InetSocketAddress(
address, address,
rcvChannel.socket().getLocalPort()); rcvChannel.socket().getLocalPort());
@ -71,8 +69,7 @@ public class ConnectedSend {
rcvChannel.receive(bb); rcvChannel.receive(bb);
bb.flip(); bb.flip();
CharBuffer cb = Charset.forName("US-ASCII").newDecoder().decode(bb); CharBuffer cb = Charset.forName("US-ASCII").newDecoder().decode(bb);
if (!cb.toString().startsWith("h")) assertTrue(cb.toString().startsWith("h"), "Unexpected message content");
throw new RuntimeException("Test failed");
rcvChannel.close(); rcvChannel.close();
sndChannel.close(); sndChannel.close();
@ -81,9 +78,10 @@ public class ConnectedSend {
// Check if the datagramsocket adaptor can send with a packet // Check if the datagramsocket adaptor can send with a packet
// that has not been initialized with an address; the legacy // that has not been initialized with an address; the legacy
// datagram socket will send in this case // datagram socket will send in this case
private static void test2() throws Exception { @Test
public static void sendAddressedPacket() throws Exception {
DatagramChannel sndChannel = DatagramChannel.open(); DatagramChannel sndChannel = DatagramChannel.open();
sndChannel.socket().bind(null); sndChannel.bind(null);
InetAddress address = InetAddress.getLocalHost(); InetAddress address = InetAddress.getLocalHost();
if (address.isLoopbackAddress()) { if (address.isLoopbackAddress()) {
address = InetAddress.getLoopbackAddress(); address = InetAddress.getLoopbackAddress();
@ -93,7 +91,7 @@ public class ConnectedSend {
sndChannel.socket().getLocalPort()); sndChannel.socket().getLocalPort());
DatagramChannel rcvChannel = DatagramChannel.open(); DatagramChannel rcvChannel = DatagramChannel.open();
rcvChannel.socket().bind(null); rcvChannel.bind(null);
InetSocketAddress receiver = new InetSocketAddress( InetSocketAddress receiver = new InetSocketAddress(
address, address,
rcvChannel.socket().getLocalPort()); rcvChannel.socket().getLocalPort());
@ -109,13 +107,12 @@ public class ConnectedSend {
rcvChannel.receive(bb); rcvChannel.receive(bb);
bb.flip(); bb.flip();
CharBuffer cb = Charset.forName("US-ASCII").newDecoder().decode(bb); CharBuffer cb = Charset.forName("US-ASCII").newDecoder().decode(bb);
if (!cb.toString().startsWith("h")) assertTrue(cb.toString().startsWith("h"), "Unexpected message content");
throw new RuntimeException("Test failed");
// Check that the pkt got set with the target address; // Check that the pkt got set with the target address;
// This is legacy behavior // This is legacy behavior
if (!pkt.getSocketAddress().equals(receiver)) assertEquals(pkt.getSocketAddress(), receiver,
throw new RuntimeException("Test failed"); "Unexpected address set on packet");
rcvChannel.close(); rcvChannel.close();
sndChannel.close(); sndChannel.close();

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 4675045 8198753
* @summary Test DatagramChannel send exceptions
* @library ..
* @run testng SendExceptions
*/
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
public class SendExceptions {
static DatagramChannel sndChannel;
static DatagramChannel rcvChannel;
static InetSocketAddress sender;
static InetSocketAddress receiver;
static ByteBuffer buf = ByteBuffer.allocate(17);
@BeforeTest
public static void setup() throws Exception {
sndChannel = DatagramChannel.open();
sndChannel.bind(null);
InetAddress address = InetAddress.getLocalHost();
if (address.isLoopbackAddress()) {
address = InetAddress.getLoopbackAddress();
}
sender = new InetSocketAddress(address,
sndChannel.socket().getLocalPort());
rcvChannel = DatagramChannel.open();
rcvChannel.bind(null);
receiver = new InetSocketAddress(address,
rcvChannel.socket().getLocalPort());
}
@Test(expectedExceptions = UnsupportedAddressTypeException.class)
public static void unsupportedAddressTypeException() throws Exception {
rcvChannel.connect(sender);
sndChannel.send(buf, new SocketAddress() {});
}
@Test(expectedExceptions = UnresolvedAddressException.class)
public static void unresolvedAddressException() throws Exception {
String host = TestUtil.UNRESOLVABLE_HOST;
InetSocketAddress unresolvable = new InetSocketAddress (host, 37);
sndChannel.send(buf, unresolvable);
}
@Test(expectedExceptions = AlreadyConnectedException.class)
public static void alreadyConnectedException() throws Exception {
sndChannel.connect(receiver);
InetSocketAddress random = new InetSocketAddress(0);
sndChannel.send(buf, random);
}
@AfterTest
public static void cleanup() throws Exception {
rcvChannel.close();
sndChannel.close();
}
}

View file

@ -1,50 +0,0 @@
/*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 4675045
* @summary Test DatagramChannel send to unresolved address
* @library ..
*/
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
public class SendToUnresolved {
public static void main(String [] argv) throws Exception {
String host = TestUtil.UNRESOLVABLE_HOST;
DatagramChannel dc = DatagramChannel.open();
ByteBuffer bb = ByteBuffer.allocate(4);
InetSocketAddress sa = new InetSocketAddress (host, 37);
InetAddress inetaddr = sa.getAddress();
try {
dc.send(bb, sa);
throw new RuntimeException("Expected exception not thrown");
} catch (IOException | UnresolvedAddressException e) {
// Correct result
}
dc.close();
}
}