1 /* 2 * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* @test 25 * @bug 4927640 26 * @summary Tests the SCTP protocol implementation 27 * @author chegar 28 */ 29 30 import java.io.IOException; 31 import java.util.Set; 32 import java.net.InetSocketAddress; 33 import java.net.SocketAddress; 34 import java.util.List; 35 import java.util.Arrays; 36 import java.util.Iterator; 37 import java.nio.channels.ClosedChannelException; 38 import com.sun.nio.sctp.SctpChannel; 39 import com.sun.nio.sctp.SctpServerChannel; 40 import com.sun.nio.sctp.SctpSocketOption; 41 import java.security.AccessController; 42 import java.security.PrivilegedAction; 43 import static com.sun.nio.sctp.SctpStandardSocketOptions.*; 44 import static java.lang.System.out; 45 46 public class SocketOptionTests { 47 final String osName = AccessController.doPrivileged( 48 (PrivilegedAction<String>)() -> System.getProperty("os.name")); 49 50 <T> void checkOption(SctpChannel sc, SctpSocketOption<T> name, 51 T expectedValue) throws IOException { 52 T value = sc.getOption(name); 53 check(value.equals(expectedValue), name + ": value (" + value + 54 ") not as expected (" + expectedValue + ")"); 55 } 56 57 <T> void optionalSupport(SctpChannel sc, SctpSocketOption<T> name, 58 T value) { 59 try { 60 sc.setOption(name, value); 61 checkOption(sc, name, value); 62 } catch (IOException e) { 63 /* Informational only, not all options have native support */ 64 out.println(name + " not supported. " + e); 65 } 66 } 67 68 void test(String[] args) { 69 if (!Util.isSCTPSupported()) { 70 out.println("SCTP protocol is not supported"); 71 out.println("Test cannot be run"); 72 return; 73 } 74 75 try (SctpChannel sc = SctpChannel.open()) { 76 77 /* check supported options */ 78 Set<SctpSocketOption<?>> options = sc.supportedOptions(); 79 List<? extends SctpSocketOption<?>> expected = Arrays.<SctpSocketOption<?>>asList( 80 SCTP_DISABLE_FRAGMENTS, SCTP_EXPLICIT_COMPLETE, 81 SCTP_FRAGMENT_INTERLEAVE, SCTP_INIT_MAXSTREAMS, 82 SCTP_NODELAY, SCTP_PRIMARY_ADDR, SCTP_SET_PEER_PRIMARY_ADDR, 83 SO_SNDBUF, SO_RCVBUF, SO_LINGER); 84 85 for (SctpSocketOption opt: expected) { 86 if (!options.contains(opt)) 87 fail(opt.name() + " should be supported"); 88 } 89 90 InitMaxStreams streams = InitMaxStreams.create(1024, 1024); 91 sc.setOption(SCTP_INIT_MAXSTREAMS, streams); 92 checkOption(sc, SCTP_INIT_MAXSTREAMS, streams); 93 streams = sc.getOption(SCTP_INIT_MAXSTREAMS); 94 check(streams.maxInStreams() == 1024, "Max in streams: value: " 95 + streams.maxInStreams() + ", expected 1024 "); 96 check(streams.maxOutStreams() == 1024, "Max out streams: value: " 97 + streams.maxOutStreams() + ", expected 1024 "); 98 99 optionalSupport(sc, SCTP_DISABLE_FRAGMENTS, true); 100 optionalSupport(sc, SCTP_EXPLICIT_COMPLETE, true); 101 optionalSupport(sc, SCTP_FRAGMENT_INTERLEAVE, 1); 102 103 sc.setOption(SCTP_NODELAY, true); 104 checkOption(sc, SCTP_NODELAY, true); 105 sc.setOption(SO_SNDBUF, 16*1024); 106 checkOption(sc, SO_SNDBUF, 16*1024); 107 sc.setOption(SO_RCVBUF, 16*1024); 108 checkOption(sc, SO_RCVBUF, 16*1024); 109 checkOption(sc, SO_LINGER, -1); /* default should be negative */ 110 sc.setOption(SO_LINGER, 2000); 111 checkOption(sc, SO_LINGER, 2000); 112 113 /* SCTP_PRIMARY_ADDR */ 114 sctpPrimaryAddr(); 115 116 /* NullPointerException */ 117 try { 118 sc.setOption(null, "value"); 119 fail("NullPointerException not thrown for setOption"); 120 } catch (NullPointerException unused) { 121 pass(); 122 } 123 try { 124 sc.getOption(null); 125 fail("NullPointerException not thrown for getOption"); 126 } catch (NullPointerException unused) { 127 pass(); 128 } 129 130 /* ClosedChannelException */ 131 sc.close(); 132 try { 133 sc.setOption(SCTP_INIT_MAXSTREAMS, streams); 134 fail("ClosedChannelException not thrown"); 135 } catch (ClosedChannelException unused) { 136 pass(); 137 } 138 } catch (IOException ioe) { 139 unexpected(ioe); 140 } 141 } 142 143 /* SCTP_PRIMARY_ADDR */ 144 void sctpPrimaryAddr() throws IOException { 145 System.out.println("TESTING SCTP_PRIMARY_ADDR"); 146 SctpChannel sc = SctpChannel.open(); 147 SctpServerChannel ssc = SctpServerChannel.open().bind(null); 148 Set<SocketAddress> addrs = ssc.getAllLocalAddresses(); 149 if (addrs.isEmpty()) 150 debug("addrs should not be empty"); 151 debug("Listening on " + addrs); 152 153 InetSocketAddress serverAddr = (InetSocketAddress) addrs.iterator().next(); 154 debug("connecting to " + serverAddr); 155 sc.connect(serverAddr); 156 SctpChannel peerChannel = ssc.accept(); 157 ssc.close(); 158 Set<SocketAddress> remoteAddresses = sc.getRemoteAddresses(); 159 debug("Remote Addresses: "); 160 for (Iterator<SocketAddress> it = remoteAddresses.iterator(); it.hasNext(); ) { 161 InetSocketAddress addr = (InetSocketAddress)it.next(); 162 debug("\t" + addr); 163 } 164 165 SocketAddress primaryAddr = sc.getOption(SCTP_PRIMARY_ADDR); 166 System.out.println("SCTP_PRIMARY_ADDR returned: " + primaryAddr); 167 /* Verify that this is one of the remote addresses */ 168 check(remoteAddresses.contains(primaryAddr), "SCTP_PRIMARY_ADDR returned bogus address!"); 169 170 for (Iterator<SocketAddress> it = remoteAddresses.iterator(); it.hasNext(); ) { 171 InetSocketAddress addrToSet = (InetSocketAddress) it.next(); 172 System.out.println("SCTP_PRIMARY_ADDR try set to: " + addrToSet); 173 sc.setOption(SCTP_PRIMARY_ADDR, addrToSet); 174 System.out.println("SCTP_PRIMARY_ADDR set to : " + addrToSet); 175 primaryAddr = sc.getOption(SCTP_PRIMARY_ADDR); 176 System.out.println("SCTP_PRIMARY_ADDR returned : " + primaryAddr); 177 check(addrToSet.equals(primaryAddr), "SCTP_PRIMARY_ADDR not set correctly"); 178 } 179 sc.close(); 180 peerChannel.close(); 181 } 182 //--------------------- Infrastructure --------------------------- 183 boolean debug = true; 184 volatile int passed = 0, failed = 0; 185 void pass() {passed++;} 186 void fail() {failed++; Thread.dumpStack();} 187 void fail(String msg) {System.err.println(msg); fail();} 188 void unexpected(Throwable t) {failed++; t.printStackTrace();} 189 void check(boolean cond) {if (cond) pass(); else fail();} 190 void check(boolean cond, String failMessage) {if (cond) pass(); else fail(failMessage);} 191 void debug(String message) {if(debug) { System.out.println(message); } } 192 public static void main(String[] args) throws Throwable { 193 Class<?> k = new Object(){}.getClass().getEnclosingClass(); 194 try {k.getMethod("instanceMain",String[].class) 195 .invoke( k.newInstance(), (Object) args);} 196 catch (Throwable e) {throw e.getCause();}} 197 public void instanceMain(String[] args) throws Throwable { 198 try {test(args);} catch (Throwable t) {unexpected(t);} 199 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); 200 if (failed > 0) throw new AssertionError("Some tests failed");} 201 }