2614N/A/*
2614N/A * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2614N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2614N/A *
2614N/A * This code is free software; you can redistribute it and/or modify it
2614N/A * under the terms of the GNU General Public License version 2 only, as
2614N/A * published by the Free Software Foundation.
2614N/A *
2614N/A * This code is distributed in the hope that it will be useful, but WITHOUT
2614N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2614N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2614N/A * version 2 for more details (a copy is included in the LICENSE file that
2614N/A * accompanied this code).
2614N/A *
2614N/A * You should have received a copy of the GNU General Public License version
2614N/A * 2 along with this work; if not, write to the Free Software Foundation,
2614N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2614N/A *
2614N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2614N/A * or visit www.oracle.com if you need additional information or have any
2614N/A * questions.
2614N/A */
2614N/A
2614N/A/* @test
2614N/A * @summary Test socket adapter sendUrgentData method
2614N/A * @bug 6963907
2614N/A */
2614N/A
2614N/Aimport java.net.*;
2614N/Aimport java.nio.ByteBuffer;
2614N/Aimport java.nio.channels.*;
2614N/Aimport java.io.IOException;
2614N/Aimport java.util.Random;
2614N/A
2614N/Apublic class OutOfBand {
2614N/A
2614N/A private static final Random rand = new Random();
2614N/A
2614N/A public static void main(String[] args) throws Exception {
2614N/A ServerSocketChannel ssc = null;
2614N/A SocketChannel sc1 = null;
2614N/A SocketChannel sc2 = null;
2614N/A
2614N/A try {
2614N/A
2614N/A // establish loopback connection
2614N/A ssc = ServerSocketChannel.open().bind(new InetSocketAddress(0));
2614N/A InetAddress lh = InetAddress.getLocalHost();
2614N/A SocketAddress remote =
2614N/A new InetSocketAddress(lh, ssc.socket().getLocalPort());
2614N/A sc1 = SocketChannel.open(remote);
2614N/A sc2 = ssc.accept();
2614N/A
2614N/A // enable SO_OOBLINE on server side
2614N/A sc2.socket().setOOBInline(true);
2614N/A
2614N/A // run tests
2614N/A test1(sc1, sc2);
2614N/A test2(sc1, sc2);
2614N/A test3(sc1, sc2);
2614N/A test4(sc1);
2614N/A
2614N/A } finally {
2614N/A if (sc1 != null) sc1.close();
2614N/A if (sc2 != null) sc2.close();
2614N/A if (ssc != null) ssc.close();
2614N/A }
2614N/A }
2614N/A
2614N/A /**
2614N/A * Basic test to check that OOB/TCP urgent byte is received.
2614N/A */
2614N/A static void test1(SocketChannel client, SocketChannel server)
2614N/A throws Exception
2614N/A {
2614N/A assert server.socket().getOOBInline();
2614N/A ByteBuffer bb = ByteBuffer.allocate(100);
2614N/A for (int i=0; i<1000; i++) {
2614N/A int b1 = -127 + rand.nextInt(384);
2614N/A client.socket().sendUrgentData(b1);
2614N/A
2614N/A bb.clear();
2614N/A if (server.read(bb) != 1)
2614N/A throw new RuntimeException("One byte expected");
2614N/A bb.flip();
2614N/A byte b2 = bb.get();
2614N/A if ((byte)b1 != b2)
2614N/A throw new RuntimeException("Unexpected byte");
2614N/A }
2614N/A }
2614N/A
2614N/A /**
2614N/A * Basic test to check that OOB/TCP urgent byte is received, maybe with
2614N/A * OOB mark changing.
2614N/A */
2614N/A static void test2(final SocketChannel client, SocketChannel server)
2614N/A throws Exception
2614N/A {
2614N/A assert server.socket().getOOBInline();
2614N/A Runnable sender = new Runnable() {
2614N/A public void run() {
2614N/A try {
2614N/A for (int i=0; i<256; i++)
2614N/A client.socket().sendUrgentData(i);
2614N/A } catch (IOException ioe) {
2614N/A ioe.printStackTrace();
2614N/A }
2614N/A }
2614N/A };
2614N/A Thread thr = new Thread(sender);
2614N/A thr.start();
2614N/A
2614N/A ByteBuffer bb = ByteBuffer.allocate(256);
2614N/A while (bb.hasRemaining()) {
2614N/A if (server.read(bb) < 0)
2614N/A throw new RuntimeException("Unexpected EOF");
2614N/A }
2614N/A bb.flip();
2614N/A byte expect = 0;
2614N/A while (bb.hasRemaining()) {
2614N/A if (bb.get() != expect)
2614N/A throw new RuntimeException("Unexpected byte");
2614N/A expect++;
2614N/A }
2614N/A
2614N/A thr.join();
2614N/A }
2614N/A
2614N/A /**
2614N/A * Test that is close to some real world examples where an urgent byte is
2614N/A * used to "cancel" a long running query or transaction on the server.
2614N/A */
2614N/A static void test3(SocketChannel client, final SocketChannel server)
2614N/A throws Exception
2614N/A {
2614N/A final int STOP = rand.nextInt(256);
2614N/A
2614N/A assert server.socket().getOOBInline();
2614N/A Runnable reader = new Runnable() {
2614N/A public void run() {
2614N/A ByteBuffer bb = ByteBuffer.allocate(100);
2614N/A try {
2614N/A int n = server.read(bb);
2614N/A if (n != 1) {
2614N/A String msg = (n < 0) ? "Unexpected EOF" :
2614N/A "One byte expected";
2614N/A throw new RuntimeException(msg);
2614N/A }
2614N/A bb.flip();
2614N/A if (bb.get() != (byte)STOP)
2614N/A throw new RuntimeException("Unexpected byte");
2614N/A bb.flip();
2614N/A server.write(bb);
2614N/A } catch (IOException ioe) {
2614N/A ioe.printStackTrace();
2614N/A }
2614N/A
2614N/A }
2614N/A };
2614N/A
2614N/A Thread thr = new Thread(reader);
2614N/A thr.start();
2614N/A
2614N/A // "stop" server
2614N/A client.socket().sendUrgentData(STOP);
2614N/A
2614N/A // wait for server reply
2614N/A ByteBuffer bb = ByteBuffer.allocate(100);
2614N/A int n = client.read(bb);
2614N/A if (n != 1)
2614N/A throw new RuntimeException("Unexpected number of bytes");
2614N/A bb.flip();
2614N/A if (bb.get() != (byte)STOP)
2614N/A throw new RuntimeException("Unexpected reply");
2614N/A
2614N/A thr.join();
2614N/A }
2614N/A
2614N/A static void test4(SocketChannel sc) throws IOException {
2614N/A boolean blocking = sc.isBlocking();
2614N/A sc.configureBlocking(false);
2614N/A try {
2614N/A sc.socket().sendUrgentData(0);
2614N/A throw new RuntimeException("IllegalBlockingModeException expected");
2614N/A } catch (IllegalBlockingModeException x) {
2614N/A // expected
2614N/A } finally {
2614N/A sc.configureBlocking(blocking);
2614N/A }
2614N/A }
2614N/A}