Path: blob/master/test/jdk/com/sun/nio/sctp/SctpChannel/ReceiveIntoDirect.java
41155 views
/*1* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @bug 803418125* @summary SIGBUS in SctpChannelImpl receive26* @author chegar27*/2829import java.net.InetSocketAddress;30import java.net.SocketAddress;31import java.io.IOException;32import java.nio.ByteBuffer;33import com.sun.nio.sctp.AbstractNotificationHandler;34import com.sun.nio.sctp.AssociationChangeNotification;35import com.sun.nio.sctp.AssociationChangeNotification.AssocChangeEvent;36import com.sun.nio.sctp.HandlerResult;37import com.sun.nio.sctp.MessageInfo;38import com.sun.nio.sctp.Notification;39import com.sun.nio.sctp.PeerAddressChangeNotification;40import com.sun.nio.sctp.SctpChannel;41import com.sun.nio.sctp.SctpServerChannel;42import com.sun.nio.sctp.ShutdownNotification;43import static java.lang.System.out;44import static java.lang.System.err;45import static java.nio.charset.StandardCharsets.US_ASCII;4647public class ReceiveIntoDirect {48/* suitably small message to NOT overrun small buffers */49final byte[] msgBytes = "Hello".getBytes(US_ASCII);5051/* number of client connections/combinations (accepted by the server) */52final int NUM_CONNECTIONS = 75;5354void test(String[] args) throws IOException {55SocketAddress address = null;56Server server;5758if (!Util.isSCTPSupported()) {59out.println("SCTP protocol is not supported");60out.println("Test cannot be run");61return;62}6364if (args.length == 2) {65/* requested to connecct to a specific address */66try {67int port = Integer.valueOf(args[1]);68address = new InetSocketAddress(args[0], port);69} catch (NumberFormatException nfe) {70err.println(nfe);71}72} else {73/* start server on local machine, default */74server = new Server();75server.start();76address = server.address();77debug("Server started and listening on " + address);78}7980/* many combinations with varing buffer sizes, and offsets */81runWithManyOffsets(address, 20);82runWithManyOffsets(address, 49);83runWithManyOffsets(address, 50);84runWithManyOffsets(address, 51);85runWithManyOffsets(address, 1024);86}8788void runWithManyOffsets(SocketAddress addr, int bufferSize)89throws IOException90{91doTest(addr, bufferSize, 1);92doTest(addr, bufferSize, 2);93doTest(addr, bufferSize, 3);94doTest(addr, bufferSize, 4);95doTest(addr, bufferSize, 5);96doTest(addr, bufferSize, 6);97doTest(addr, bufferSize, 7);98doTest(addr, bufferSize, 8);99doTest(addr, bufferSize, 9);100doTest(addr, bufferSize, 10);101doTest(addr, bufferSize, 11);102doTest(addr, bufferSize, 12);103doTest(addr, bufferSize, 13);104doTest(addr, bufferSize, 14);105doTest(addr, bufferSize, 15);106}107108void doTest(SocketAddress peerAddress, int bufferSize, int bufferOffset)109throws IOException110{111debug("\n\nTesting with bufferSize " + bufferSize + " and offset " + bufferOffset);112assert bufferOffset + msgBytes.length <= bufferSize :113"buffer offset + message length greater than buffer size ";114115ByteBuffer buffer = ByteBuffer.allocateDirect(bufferSize);116MessageInfo info;117118try (SctpChannel channel = SctpChannel.open()) {119channel.connect(peerAddress);120121ReceiveNotificationHandler handler =122new ReceiveNotificationHandler();123124/* TEST 1: Assoc/peer change notif into direct buffer with offest */125do {126debug("Test 1: Assoc/peer change with offset " + bufferOffset);127buffer.position(bufferOffset);128info = channel.receive(buffer, null, handler);129if (info == null) {130fail("unexpected null from receive");131return;132}133} while (!info.isComplete());134135buffer.flip().position(bufferOffset);136check(handler.receivedCommUp(), "SCTP_COMM_UP not received");137check(info != null, "info is null");138check(info.address() != null, "address is null");139check(info.association() != null, "association is null");140check(info.isComplete(), "message is not complete");141check(info.isUnordered() != true,142"message should not be unordered");143check(info.streamNumber() >= 0, "invalid stream number");144check(info.bytes() == msgBytes.length,145"bytes received not equal to message length");146check(info.bytes() == buffer.remaining(), "bytes != remaining");147check(Util.compare(buffer, msgBytes),148"received message not the same as sent message");149150/* TEST 2: shutdown notification with offset */151debug("Test 2: shutdown notif with offset " + bufferOffset);152buffer.clear().position(bufferOffset);153while ((info = channel.receive(buffer, null, handler )) != null &&154info.bytes() != -1 );155}156}157158class Server implements Runnable159{160private final InetSocketAddress serverAddr;161private final SctpServerChannel ssc;162163public Server() throws IOException {164ssc = SctpServerChannel.open().bind(null);165java.util.Set<SocketAddress> addrs = ssc.getAllLocalAddresses();166if (addrs.isEmpty())167debug("addrs should not be empty");168169serverAddr = (InetSocketAddress) addrs.iterator().next();170}171172public void start() {173(new Thread(this, "Server-" + serverAddr.getPort())).start();174}175176public InetSocketAddress address() {177return serverAddr;178}179180@Override181public void run() {182try {183for (int i=0; i<NUM_CONNECTIONS; i++) {184SctpChannel sc = ssc.accept();185186/* send a small message */187MessageInfo info = MessageInfo.createOutgoing(null, 0);188ByteBuffer buf = ByteBuffer.allocateDirect(Util.SMALL_BUFFER);189buf.put(msgBytes);190buf.flip();191192debug("sending small message: " + buf);193sc.send(buf, info);194195sc.shutdown();196sc.close();197}198} catch (IOException x) {199unexpected(x);200} finally {201try { ssc.close(); }202catch (IOException x) { unexpected(x); }203}204}205}206207class ReceiveNotificationHandler extends AbstractNotificationHandler<Object>208{209boolean receivedCommUp; // false210211public ReceiveNotificationHandler() { }212213public boolean receivedCommUp() {214return receivedCommUp;215}216217@Override218public HandlerResult handleNotification(219Notification notification, Object attachment) {220fail("Unknown notification type");221return HandlerResult.CONTINUE;222}223224@Override225public HandlerResult handleNotification(226AssociationChangeNotification notification, Object attachment) {227AssocChangeEvent event = notification.event();228debug("AssociationChangeNotification");229debug(" Association: " + notification.association());230debug(" Event: " + event);231232if (event.equals(AssocChangeEvent.COMM_UP))233receivedCommUp = true;234235return HandlerResult.CONTINUE;236}237238@Override239public HandlerResult handleNotification(240PeerAddressChangeNotification pacn, Object unused)241{242debug("PeerAddressChangeNotification: " + pacn);243return HandlerResult.CONTINUE;244}245246@Override247public HandlerResult handleNotification(248ShutdownNotification notification, Object attachment) {249debug("ShutdownNotification");250debug(" Association: " + notification.association());251return HandlerResult.CONTINUE;252}253}254//--------------------- Infrastructure ---------------------------255boolean debug = true;256volatile int passed = 0, failed = 0;257void pass() {passed++;}258void fail() {failed++; Thread.dumpStack();}259void fail(String msg) {System.err.println(msg); fail();}260void unexpected(Throwable t) {failed++; t.printStackTrace();}261void check(boolean cond) {if (cond) pass(); else fail();}262void check(boolean cond, String failMessage) {if (cond) pass(); else fail(failMessage);}263void debug(String message) {if(debug) {264System.out.println(Thread.currentThread() + " " + message); } }265public static void main(String[] args) throws Throwable {266Class<?> k = new Object(){}.getClass().getEnclosingClass();267try {k.getMethod("instanceMain",String[].class)268.invoke( k.newInstance(), (Object) args);}269catch (Throwable e) {throw e.getCause();}}270public void instanceMain(String[] args) throws Throwable {271try {test(args);} catch (Throwable t) {unexpected(t);}272System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);273if (failed > 0) throw new AssertionError("Some tests failed");}274275}276277278