Path: blob/master/test/jdk/com/sun/nio/sctp/SctpChannel/Bind.java
41155 views
/*1* Copyright (c) 2009, 2019, 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 492764025* @summary Tests the SCTP protocol implementation26* @author chegar27*/2829import java.net.*;30import java.io.*;31import java.util.List;32import java.util.Set;33import java.util.Iterator;34import java.nio.ByteBuffer;35import java.nio.channels.AlreadyBoundException;36import java.nio.channels.AlreadyConnectedException;37import java.nio.channels.ClosedChannelException;38import java.nio.channels.UnsupportedAddressTypeException;39import com.sun.nio.sctp.AssociationChangeNotification;40import com.sun.nio.sctp.AbstractNotificationHandler;41import com.sun.nio.sctp.HandlerResult;42import com.sun.nio.sctp.IllegalUnbindException;43import com.sun.nio.sctp.MessageInfo;44import com.sun.nio.sctp.PeerAddressChangeNotification;45import com.sun.nio.sctp.SctpChannel;46import com.sun.nio.sctp.SctpServerChannel;47import com.sun.nio.sctp.ShutdownNotification;48import static java.lang.System.out;4950/**51* Tests bind, bindAddress, unbindAddress, getLocalAddress, and52* getAllLocalAddresses.53*/54public class Bind {55void test(String[] args) {56if (!Util.isSCTPSupported()) {57out.println("SCTP protocol is not supported");58out.println("Test cannot be run");59return;60}6162/* Simply bind tests */63testBind();6465/* Test unconnected */66testBindUnbind(false);6768/* Test connected */69/* Adding/Removing addresses from a connected association is optional.70* This test can be run on systems that support dynamic address71* reconfiguration */72//testBindUnbind(true);73}7475void testBind() {76SctpChannel channel = null;77try {78channel = SctpChannel.open();7980/* TEST 1: empty set if channel is not bound */81check(channel.getAllLocalAddresses().isEmpty(),82"getAllLocalAddresses returned non empty set for unbound channel");8384/* TEST 2: null to bind the channel to an automatically assigned85* socket address */86channel.bind(null);8788/* TEST 3: non empty set if the channel is bound */89check(!channel.getAllLocalAddresses().isEmpty(),90"getAllLocalAddresses returned empty set for bound channel");91debug("getAllLocalAddresses on channel bound to the wildcard:\n"92+ channel.getAllLocalAddresses());9394/* TEST 4: AlreadyBoundException if this channel is already bound */95try { channel.bind(null); }96catch (AlreadyBoundException unused) { pass(); }97catch (IOException ioe) { unexpected(ioe); }9899/* TEST 5: UnsupportedAddressTypeException */100try {101channel.close(); /* open a new unbound channel for test */102channel = SctpChannel.open();103channel.bind(new UnsupportedSocketAddress());104fail("UnsupportedSocketAddress expected");105} catch (UnsupportedAddressTypeException unused) { pass();106} catch (IOException ioe) { unexpected(ioe); }107108/* TEST 6: AlreadyConnectedException */109try {110channel.close(); /* open a new unbound channel for test */111channel = SctpChannel.open();112try (var peer = connectChannel(channel)) {113channel.bind(null);114fail("AlreadyConnectedException expected");115}116} catch (AlreadyConnectedException unused) { pass();117} catch (IOException ioe) { unexpected(ioe); }118119/* TEST 7: ClosedChannelException - If this channel is closed */120try {121channel.close(); /* open a new unbound channel for test */122channel = SctpChannel.open();123channel.close();124channel.bind(null);125fail("ClosedChannelException expected");126} catch (ClosedChannelException unused) { pass();127} catch (IOException ioe) { unexpected(ioe); }128129/* TEST 8: ClosedChannelException if channel is closed */130try {131channel.getAllLocalAddresses();132fail("should have thrown ClosedChannelException");133} catch (ClosedChannelException cce) {134pass();135} catch (Exception ioe) {136unexpected(ioe);137}138} catch (IOException ioe) {139unexpected(ioe);140} finally {141try { channel.close(); }142catch (IOException ioe) { unexpected(ioe); }143}144}145146void testBindUnbind(boolean connected) {147SctpChannel channel = null;148SctpChannel peerChannel = null;149150debug("testBindUnbind, connected: " + connected);151try {152channel = SctpChannel.open();153154List<InetAddress> addresses = Util.getAddresses(true, false);155Iterator iterator = addresses.iterator();156InetSocketAddress a = new InetSocketAddress((InetAddress)iterator.next(), 0);157debug("channel.bind( " + a + ")");158channel.bind(a);159while (iterator.hasNext()) {160InetAddress ia = (InetAddress)iterator.next();161debug("channel.bindAddress(" + ia + ")");162channel.bindAddress(ia);163}164if (debug) {Util.dumpAddresses(channel, out);}165166if (connected) {167/* Test with connected channel */168peerChannel = connectChannel(channel);169}170171/* TEST 1: bind/unbindAddresses on the system addresses */172debug("bind/unbindAddresses on the system addresses");173List<InetAddress> addrs = Util.getAddresses(true, false);174for (InetAddress addr : addrs) {175try {176debug("unbindAddress: " + addr);177check(boundAddress(channel, addr), "trying to remove address that is not bound");178channel.unbindAddress(addr);179if (debug) {Util.dumpAddresses(channel, out);}180check(!boundAddress(channel, addr), "address was not removed");181182debug("bindAddress: " + addr);183channel.bindAddress(addr);184if (debug) {Util.dumpAddresses(channel, out);}185check(boundAddress(channel, addr), "address is not bound");186} catch (IOException ioe) {187unexpected(ioe);188}189}190191/* TEST 2: bindAddress - already bound address. */192InetAddress againAddress = addrs.get(0);193try {194debug("bind already bound address " + againAddress);195channel.bindAddress(againAddress);196} catch (AlreadyBoundException unused) {197debug("Caught AlreadyBoundException - OK");198pass();199} catch (IOException ioe) {200unexpected(ioe);201}202203/* TEST 3: bind non local address */204try {205InetAddress nla = InetAddress.getByName("123.123.123.123");206debug("bind non local address " + nla);207channel.bindAddress(nla);208} catch (IOException ioe) {209debug("Informative only " + ioe);210}211212/* TEST 4: unbind address that is not bound */213try {214debug("unbind address that is not bound " + againAddress);215/* remove address first then again */216channel.unbindAddress(againAddress);217channel.unbindAddress(againAddress);218} catch (IllegalUnbindException unused) {219debug("Caught IllegalUnbindException - OK");220pass();221} catch (IOException ioe) {222unexpected(ioe);223}224225/* TEST 5: unbind address that is not bound */226try {227InetAddress nla = InetAddress.getByName("123.123.123.123");228debug("unbind address that is not bound " + nla);229channel.unbindAddress(nla);230231} catch (IllegalUnbindException unused) {232debug("Caught IllegalUnbindException - OK");233pass();234} catch (IOException ioe) {235unexpected(ioe);236}237238if (connected) {239channel.shutdown();240241BindNotificationHandler handler = new BindNotificationHandler();242ByteBuffer buffer = ByteBuffer.allocate(10);243MessageInfo info;244while((info = peerChannel.receive(buffer, null, handler)) != null) {245if (info != null) {246if (info.bytes() == -1) {247debug("peerChannel Reached EOF");248break;249}250}251}252253while((info = channel.receive(buffer, null, handler)) != null) {254if (info != null) {255if (info.bytes() == -1) {256debug("channel Reached EOF");257break;258}259}260}261}262} catch (IOException ioe) {263ioe.printStackTrace();264} finally {265try { if (channel != null) channel.close(); }266catch (IOException ioe) { unexpected(ioe); }267try { if (peerChannel != null) peerChannel.close(); }268catch (IOException ioe) { unexpected(ioe); }269}270}271272boolean boundAddress(SctpChannel channel, InetAddress addr)273throws IOException {274for (SocketAddress boundAddr : channel.getAllLocalAddresses()) {275if (((InetSocketAddress) boundAddr).getAddress().equals(addr))276return true;277}278return false;279}280281SctpChannel connectChannel(SctpChannel channel)282throws IOException {283debug("connecting channel...");284try {285SctpServerChannel ssc = SctpServerChannel.open();286ssc.bind(null);287Set<SocketAddress> addrs = ssc.getAllLocalAddresses();288Iterator<SocketAddress> iterator = addrs.iterator();289SocketAddress addr = iterator.next();290debug("using " + addr + "...");291channel.connect(addr);292SctpChannel peerChannel = ssc.accept();293ssc.close();294debug("connected");295return peerChannel;296} catch (IOException ioe) {297debug("Cannot connect channel");298unexpected(ioe);299throw ioe;300}301}302303class BindNotificationHandler extends AbstractNotificationHandler<Object>304{305@Override306public HandlerResult handleNotification(307AssociationChangeNotification acn, Object unused)308{309debug("AssociationChangeNotification: " + acn);310return HandlerResult.CONTINUE;311}312313@Override314public HandlerResult handleNotification(315PeerAddressChangeNotification pacn, Object unused)316{317debug("PeerAddressChangeNotification: " + pacn);318return HandlerResult.CONTINUE;319}320321@Override322public HandlerResult handleNotification(323ShutdownNotification sn, Object unused)324{325debug("ShutdownNotification: " + sn);326return HandlerResult.CONTINUE;327}328}329330class UnsupportedSocketAddress extends SocketAddress { }331332//--------------------- Infrastructure ---------------------------333boolean debug = true;334volatile int passed = 0, failed = 0;335void pass() {passed++;}336void fail() {failed++; Thread.dumpStack();}337void fail(String msg) {System.err.println(msg); fail();}338void unexpected(Throwable t) {failed++; t.printStackTrace();}339void check(boolean cond) {if (cond) pass(); else fail();}340void check(boolean cond, String failMessage) {if (cond) pass(); else fail(failMessage);}341void debug(String message) {if(debug) { System.out.println(message); } }342public static void main(String[] args) throws Throwable {343Class<?> k = new Object(){}.getClass().getEnclosingClass();344try {k.getMethod("instanceMain",String[].class)345.invoke( k.newInstance(), (Object) args);}346catch (Throwable e) {throw e.getCause();}}347public void instanceMain(String[] args) throws Throwable {348try {test(args);} catch (Throwable t) {unexpected(t);}349System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);350if (failed > 0) throw new AssertionError("Some tests failed");}351352}353354355