2464N/A/*
2464N/A * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2464N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2464N/A *
2464N/A * This code is free software; you can redistribute it and/or modify it
2464N/A * under the terms of the GNU General Public License version 2 only, as
2464N/A * published by the Free Software Foundation.
2464N/A *
2464N/A * This code is distributed in the hope that it will be useful, but WITHOUT
2464N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2464N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2464N/A * version 2 for more details (a copy is included in the LICENSE file that
2464N/A * accompanied this code).
2464N/A *
2464N/A * You should have received a copy of the GNU General Public License version
2464N/A * 2 along with this work; if not, write to the Free Software Foundation,
2464N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2464N/A *
2464N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2464N/A * or visit www.oracle.com if you need additional information or have any
2464N/A * questions.
2464N/A */
2464N/A
2464N/A/* @test
5748N/A * @bug 6935563 7044870
2464N/A * @summary Test that Selector does not select an unconnected DatagramChannel when
2464N/A * ICMP port unreachable received
2464N/A */
2464N/A
2464N/Aimport java.nio.ByteBuffer;
2464N/Aimport java.nio.channels.*;
2464N/Aimport java.net.*;
2464N/Aimport java.io.IOException;
2464N/A
2464N/Apublic class SelectWhenRefused {
2464N/A
2464N/A public static void main(String[] args) throws IOException {
5748N/A DatagramChannel dc1 = DatagramChannel.open().bind(new InetSocketAddress(0));
5748N/A int port = dc1.socket().getLocalPort();
2464N/A
2464N/A // datagram sent to this address should be refused
2464N/A SocketAddress refuser = new InetSocketAddress(InetAddress.getLocalHost(), port);
2464N/A
5748N/A DatagramChannel dc = DatagramChannel.open().bind(new InetSocketAddress(0));
5748N/A dc1.close();
5748N/A
2546N/A Selector sel = Selector.open();
2464N/A try {
2464N/A dc.configureBlocking(false);
2464N/A dc.register(sel, SelectionKey.OP_READ);
2464N/A
2464N/A /* Test 1: not connected so ICMP port unreachable should not be received */
2464N/A sendDatagram(dc, refuser);
2464N/A int n = sel.select(2000);
2464N/A if (n > 0) {
5748N/A sel.selectedKeys().clear();
5748N/A // BindException will be thrown if another service is using
5748N/A // our expected refuser port, cannot run just exit.
5748N/A DatagramChannel.open().bind(refuser).close();
2464N/A throw new RuntimeException("Unexpected wakeup");
2464N/A }
2464N/A
2464N/A /* Test 2: connected so ICMP port unreachable may be received */
2464N/A dc.connect(refuser);
2464N/A try {
2464N/A sendDatagram(dc, refuser);
2464N/A n = sel.select(2000);
2464N/A if (n > 0) {
2464N/A sel.selectedKeys().clear();
2464N/A try {
2464N/A n = dc.read(ByteBuffer.allocate(100));
2464N/A throw new RuntimeException("Unexpected datagram received");
2464N/A } catch (PortUnreachableException pue) {
2464N/A // expected
2464N/A }
2464N/A }
2464N/A } finally {
2464N/A dc.disconnect();
2464N/A }
2464N/A
2464N/A /* Test 3: not connected so ICMP port unreachable should not be received */
2464N/A sendDatagram(dc, refuser);
2464N/A n = sel.select(2000);
2464N/A if (n > 0) {
2464N/A throw new RuntimeException("Unexpected wakeup after disconnect");
2464N/A }
2464N/A
5748N/A } catch(BindException e) {
5748N/A // Do nothing, some other test has used this port
2464N/A } finally {
2546N/A sel.close();
2464N/A dc.close();
2464N/A }
2464N/A }
2464N/A
2464N/A static void sendDatagram(DatagramChannel dc, SocketAddress remote)
2464N/A throws IOException
2464N/A {
2464N/A ByteBuffer bb = ByteBuffer.wrap("Greetings!".getBytes());
2464N/A dc.send(bb, remote);
2464N/A }
2464N/A}