1 /* 2 * Copyright (c) 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 /* 25 * @test 26 * @bug 8032808 27 * @run main/othervm -Xcheck:jni Test 28 * @run main/othervm/policy=policy.fail -Xcheck:jni Test fail 29 * @run main/othervm/policy=policy.success -Xcheck:jni Test success 30 */ 31 32 import java.net.*; 33 import java.io.IOException; 34 import java.nio.channels.*; 35 import java.util.concurrent.*; 36 import java.util.Set; 37 import jdk.net.*; 38 39 public class Test { 40 41 static boolean security; 42 static boolean success; 43 static int testCount = 0; 44 45 interface Runner { 46 public void run() throws Exception; 47 } 48 49 static void test(String msg) { 50 testCount++; 51 System.out.println("***************************************"); 52 System.out.println("Test " + testCount + ": " + msg); 53 } 54 55 static void passed() { 56 System.out.println("Test passed."); 57 } 58 59 static void failed() { 60 System.out.println("Test failed."); 61 } 62 63 static void check(boolean pass) { 64 if (pass) { 65 passed(); 66 } else { 67 failed(); 68 } 69 } 70 71 public static void main(String[] args) throws Exception { 72 73 // quick check to see if supportedOptions() working before 74 // creating any sockets and libnet loaded 75 76 Sockets.supportedOptions(Socket.class); 77 78 security = System.getSecurityManager() != null; 79 success = security && args[0].equals("success"); 80 81 // Main thing is to check for JNI problems 82 // Doesn't matter if current system does not support the option 83 // and currently setting the option with the loopback interface 84 // doesn't work either 85 86 System.out.println ("Security Manager enabled: " + security); 87 if (security) { 88 System.out.println ("Success expected: " + success); 89 } 90 91 final SocketFlow flowIn = SocketFlow.create() 92 .bandwidth(1000) 93 .priority(SocketFlow.HIGH_PRIORITY); 94 95 boolean flowsupported = true; 96 boolean reuseportsupported = true; 97 98 // If option not available, end test 99 DatagramSocket dg = new DatagramSocket(0); 100 Set<SocketOption<?>> options = dg.supportedOptions(); 101 if (!options.contains(ExtendedSocketOptions.SO_FLOW_SLA)) { 102 System.out.println("SO_FLOW_SLA not supported"); 103 flowsupported = false; 104 } 105 if (!options.contains(ExtendedSocketOptions.SO_REUSEPORT)) { 106 System.out.println("SO_REUSEPORT not supported"); 107 reuseportsupported = false; 108 } 109 110 if (flowsupported) { 111 ServerSocket ss = new ServerSocket(0); 112 int tcp_port = ss.getLocalPort(); 113 final InetAddress loop = InetAddress.getByName("127.0.0.1"); 114 final InetSocketAddress loopad = new InetSocketAddress(loop, tcp_port); 115 116 final int udp_port = dg.getLocalPort(); 117 118 final Socket s = new Socket("127.0.0.1", tcp_port); 119 final SocketChannel sc = SocketChannel.open(); 120 sc.connect (new InetSocketAddress("127.0.0.1", tcp_port)); 121 122 doTest(()->{ 123 Sockets.setOption(s, ExtendedSocketOptions.SO_FLOW_SLA, flowIn); 124 }); 125 doTest(()->{ 126 Sockets.getOption(s, ExtendedSocketOptions.SO_FLOW_SLA); 127 }); 128 doTest(()->{ 129 sc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn); 130 }); 131 doTest(()->{ 132 sc.getOption(ExtendedSocketOptions.SO_FLOW_SLA); 133 }); 134 doTest(()->{ 135 DatagramSocket dg1 = new DatagramSocket(0); 136 dg1.connect(loop, udp_port); 137 Sockets.setOption(dg1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn); 138 }); 139 doTest(()->{ 140 DatagramChannel dg2 = DatagramChannel.open(); 141 dg2.bind(new InetSocketAddress(loop, 0)); 142 dg2.connect(new InetSocketAddress(loop, udp_port)); 143 dg2.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn); 144 }); 145 doTest(()->{ 146 MulticastSocket mc1 = new MulticastSocket(0); 147 mc1.connect(loop, udp_port); 148 Sockets.setOption(mc1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn); 149 }); 150 doTest(()->{ 151 AsynchronousSocketChannel asc = AsynchronousSocketChannel.open(); 152 Future<Void> f = asc.connect(loopad); 153 f.get(); 154 asc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn); 155 }); 156 } 157 if (reuseportsupported) { 158 Socket s1 = new Socket(); 159 Socket s2 = new Socket(); 160 test("Socket should be created with SO_REUSEPORT disabled"); 161 check(!Sockets.getOption(s1, ExtendedSocketOptions.SO_REUSEPORT)); 162 163 test("Socket.set ReusePort(true)"); 164 Sockets.setOption(s1, ExtendedSocketOptions.SO_REUSEPORT, true); 165 check(Sockets.getOption(s1, ExtendedSocketOptions.SO_REUSEPORT)); 166 167 test("Socket.set ReusePort(false)"); 168 Sockets.setOption(s1, ExtendedSocketOptions.SO_REUSEPORT, false); 169 check(!Sockets.getOption(s1, ExtendedSocketOptions.SO_REUSEPORT)); 170 171 test("Without setting SO_REUSEPORT, binding Socket to port already in use should throw a SocketException"); 172 s1.bind(new InetSocketAddress(0)); 173 try { 174 s2.bind( new InetSocketAddress(s1.getLocalPort())); 175 failed(); 176 } catch (SocketException e) { 177 passed(); 178 } 179 s1.close(); 180 s2.close(); 181 182 test("By setting SO_REUSEPORT, binding Socket to port already in use should not throw a SocketException"); 183 s1 = new Socket(); 184 s2 = new Socket(); 185 Sockets.setOption(s1, ExtendedSocketOptions.SO_REUSEPORT, true); 186 Sockets.setOption(s2, ExtendedSocketOptions.SO_REUSEPORT, true); 187 s1.bind(new InetSocketAddress(0)); 188 try { 189 s2.bind( new InetSocketAddress(s1.getLocalPort()) ); 190 passed(); 191 } catch (SocketException e) { 192 failed(); 193 } 194 s1.close(); 195 s2.close(); 196 197 ServerSocket ss1 = new ServerSocket(); 198 ServerSocket ss2 = new ServerSocket(); 199 200 test("Server Socket should be created with SO_REUSEPORT disabled"); 201 check(!Sockets.getOption(ss1, ExtendedSocketOptions.SO_REUSEPORT)); 202 203 test("ServerSocket set ReusePort(true)"); 204 Sockets.setOption(ss1, ExtendedSocketOptions.SO_REUSEPORT, true); 205 check(Sockets.getOption(ss1, ExtendedSocketOptions.SO_REUSEPORT)); 206 207 test("ServerSocket set ReusePort(false)"); 208 Sockets.setOption(ss1, ExtendedSocketOptions.SO_REUSEPORT, false); 209 check(!Sockets.getOption(ss1, ExtendedSocketOptions.SO_REUSEPORT)); 210 211 test("Without setting SO_REUSEPORT, binding Server Socket to port already in use should throw a SocketException"); 212 ss1.bind(new InetSocketAddress(0)); 213 try { 214 ss2.bind( new InetSocketAddress(ss1.getLocalPort())); 215 failed(); 216 } catch (SocketException e) { 217 passed(); 218 } 219 ss1.close(); 220 ss2.close(); 221 222 test("By setting SO_REUSEPORT, binding Server Socket to port already in use should not throw a SocketException"); 223 ss1 = new ServerSocket(); 224 ss2 = new ServerSocket(); 225 Sockets.setOption(ss1, ExtendedSocketOptions.SO_REUSEPORT, true); 226 Sockets.setOption(ss2, ExtendedSocketOptions.SO_REUSEPORT, true); 227 ss1.bind(new InetSocketAddress(0)); 228 try { 229 ss2.bind( new InetSocketAddress(ss1.getLocalPort()) ); 230 passed(); 231 } catch (SocketException e) { 232 failed(); 233 } 234 ss1.close(); 235 ss2.close(); 236 237 DatagramSocket dg1 = new DatagramSocket(null); 238 DatagramSocket dg2 = new DatagramSocket(null); 239 240 test("DatagramSocket should be created with SO_REUSEPORT disabled"); 241 check(!Sockets.getOption(dg1, ExtendedSocketOptions.SO_REUSEPORT)); 242 243 test("DatagramSocket.setReusePort(true)"); 244 Sockets.setOption(dg1, ExtendedSocketOptions.SO_REUSEPORT, true); 245 check(Sockets.getOption(dg1, ExtendedSocketOptions.SO_REUSEPORT)); 246 247 test("DatagramSocket.setReusePort(false)"); 248 Sockets.setOption(dg1, ExtendedSocketOptions.SO_REUSEPORT, false); 249 check(!Sockets.getOption(dg1, ExtendedSocketOptions.SO_REUSEPORT)); 250 251 test("Without setting SO_REUSEPORT, binding Server Socket to port already in use should throw a SocketException"); 252 dg1.bind(new InetSocketAddress(0)); 253 try { 254 dg2.bind( new InetSocketAddress(dg1.getLocalPort())); 255 failed(); 256 } catch (SocketException e) { 257 passed(); 258 } 259 dg1.close(); 260 dg2.close(); 261 262 test("By setting SO_REUSEPORT, binding Server Socket to port already in use should not throw a SocketException"); 263 dg1 = new DatagramSocket(null); 264 dg2 = new DatagramSocket(null); 265 Sockets.setOption(dg1, ExtendedSocketOptions.SO_REUSEPORT, true); 266 Sockets.setOption(dg2, ExtendedSocketOptions.SO_REUSEPORT, true); 267 dg1.bind(new InetSocketAddress(0)); 268 try { 269 dg2.bind( new InetSocketAddress(dg1.getLocalPort()) ); 270 passed(); 271 } catch (SocketException e) { 272 failed(); 273 } 274 dg1.close(); 275 dg2.close(); 276 277 MulticastSocket mc1 = new MulticastSocket(); 278 279 test("Check SO_REUSEPORT is enabled in MulticastSocket"); 280 check(Sockets.getOption(mc1, ExtendedSocketOptions.SO_REUSEPORT)); 281 mc1.close(); 282 283 test("Check SO_REUSEPORT is not disabled by MulticastSocket.bind()"); 284 mc1 = new MulticastSocket(null); 285 286 InetSocketAddress isa = new InetSocketAddress( 287 InetAddress.getLocalHost(), 0); 288 mc1.bind(isa); 289 check(Sockets.getOption(mc1, ExtendedSocketOptions.SO_REUSEPORT)); 290 mc1.close(); 291 } 292 } 293 294 static void doTest(Runner func) throws Exception { 295 try { 296 func.run(); 297 if (security && !success) { 298 throw new RuntimeException("Test failed"); 299 } 300 } catch (SecurityException e) { 301 if (success) { 302 throw new RuntimeException("Test failed"); 303 } 304 } catch (UnsupportedOperationException e) { 305 System.out.println (e); 306 } catch (IOException e) { 307 // Probably a permission error, but we're not 308 // going to check unless a specific permission exception 309 // is defined. 310 System.out.println (e); 311 } 312 } 313 }