1 /* 2 * Copyright (c) 2014, 2016, 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 8036979 8072384 27 * @run main/othervm -Xcheck:jni OptionsTest 28 * @run main/othervm -Xcheck:jni -Djava.net.preferIPv4Stack=true OptionsTest 29 */ 30 31 import java.net.*; 32 import java.util.*; 33 34 public class OptionsTest { 35 36 static class Test { 37 Test(SocketOption<?> option, Object testValue) { 38 this.option = option; 39 this.testValue = testValue; 40 } 41 static Test create (SocketOption<?> option, Object testValue) { 42 return new Test(option, testValue); 43 } 44 Object option; 45 Object testValue; 46 }; 47 48 // The tests set the option using the new API, read back the set value 49 // which could be diferent, and then use the legacy get API to check 50 // these values are the same 51 52 static Test[] socketTests = new Test[] { 53 Test.create(StandardSocketOptions.SO_KEEPALIVE, Boolean.TRUE), 54 Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)), 55 Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)), 56 Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE), 57 Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE), 58 Test.create(StandardSocketOptions.SO_LINGER, Integer.valueOf(80)), 59 Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100)) 60 }; 61 62 static Test[] serverSocketTests = new Test[] { 63 Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)), 64 Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE), 65 Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE), 66 Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100)) 67 }; 68 69 static Test[] dgSocketTests = new Test[] { 70 Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)), 71 Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)), 72 Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE), 73 Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE), 74 Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100)) 75 }; 76 77 static Test[] mcSocketTests = new Test[] { 78 Test.create(StandardSocketOptions.IP_MULTICAST_IF, getNetworkInterface()), 79 Test.create(StandardSocketOptions.IP_MULTICAST_TTL, Integer.valueOf(10)), 80 Test.create(StandardSocketOptions.IP_MULTICAST_LOOP, Boolean.TRUE) 81 }; 82 83 static NetworkInterface getNetworkInterface() { 84 try { 85 Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces(); 86 while (nifs.hasMoreElements()) { 87 NetworkInterface ni = (NetworkInterface)nifs.nextElement(); 88 if (ni.supportsMulticast()) { 89 return ni; 90 } 91 } 92 } catch (Exception e) { 93 } 94 return null; 95 } 96 97 static void doSocketTests() throws Exception { 98 try ( 99 ServerSocket srv = new ServerSocket(0); 100 Socket c = new Socket("127.0.0.1", srv.getLocalPort()); 101 Socket s = srv.accept(); 102 ) { 103 Set<SocketOption<?>> options = c.supportedOptions(); 104 boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT); 105 for (int i=0; i<socketTests.length; i++) { 106 Test test = socketTests[i]; 107 if (!(test.option == StandardSocketOptions.SO_REUSEPORT && !reuseport)) { 108 c.setOption((SocketOption)test.option, test.testValue); 109 Object getval = c.getOption((SocketOption)test.option); 110 Object legacyget = legacyGetOption(Socket.class, c,test.option); 111 if (!getval.equals(legacyget)) { 112 Formatter f = new Formatter(); 113 f.format("S Err %d: %s/%s", i, getval, legacyget); 114 throw new RuntimeException(f.toString()); 115 } 116 } 117 } 118 } 119 } 120 121 static void doDgSocketTests() throws Exception { 122 try ( 123 DatagramSocket c = new DatagramSocket(0); 124 ) { 125 Set<SocketOption<?>> options = c.supportedOptions(); 126 boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT); 127 for (int i=0; i<dgSocketTests.length; i++) { 128 Test test = dgSocketTests[i]; 129 if (!(test.option == StandardSocketOptions.SO_REUSEPORT && !reuseport)) { 130 c.setOption((SocketOption)test.option, test.testValue); 131 Object getval = c.getOption((SocketOption)test.option); 132 Object legacyget = legacyGetOption(DatagramSocket.class, c,test.option); 133 if (!getval.equals(legacyget)) { 134 Formatter f = new Formatter(); 135 f.format("DG Err %d: %s/%s", i, getval, legacyget); 136 throw new RuntimeException(f.toString()); 137 } 138 } 139 } 140 } 141 } 142 143 static void doMcSocketTests() throws Exception { 144 try ( 145 MulticastSocket c = new MulticastSocket(0); 146 ) { 147 for (int i=0; i<mcSocketTests.length; i++) { 148 Test test = mcSocketTests[i]; 149 c.setOption((SocketOption)test.option, test.testValue); 150 Object getval = c.getOption((SocketOption)test.option); 151 Object legacyget = legacyGetOption(MulticastSocket.class, c,test.option); 152 if (!getval.equals(legacyget)) { 153 Formatter f = new Formatter(); 154 f.format("MC Err %d: %s/%s", i, getval, legacyget); 155 throw new RuntimeException(f.toString()); 156 } 157 } 158 } 159 } 160 161 static void doServerSocketTests() throws Exception { 162 try ( 163 ServerSocket c = new ServerSocket(0); 164 ) { 165 Set<SocketOption<?>> options = c.supportedOptions(); 166 boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT); 167 for (int i=0; i<serverSocketTests.length; i++) { 168 Test test = serverSocketTests[i]; 169 if (!(test.option == StandardSocketOptions.SO_REUSEPORT && !reuseport)) { 170 c.setOption((SocketOption)test.option, test.testValue); 171 Object getval = c.getOption((SocketOption)test.option); 172 Object legacyget = legacyGetOption( 173 ServerSocket.class, c, test.option 174 ); 175 if (!getval.equals(legacyget)) { 176 Formatter f = new Formatter(); 177 f.format("SS Err %d: %s/%s", i, getval, legacyget); 178 throw new RuntimeException(f.toString()); 179 } 180 } 181 } 182 } 183 } 184 185 static Object legacyGetOption( 186 Class<?> type, Object s, Object option) 187 188 throws Exception 189 { 190 if (type.equals(Socket.class)) { 191 Socket socket = (Socket)s; 192 Set<SocketOption<?>> options = socket.supportedOptions(); 193 boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT); 194 195 if (option.equals(StandardSocketOptions.SO_KEEPALIVE)) { 196 return Boolean.valueOf(socket.getKeepAlive()); 197 } else if (option.equals(StandardSocketOptions.SO_SNDBUF)) { 198 return Integer.valueOf(socket.getSendBufferSize()); 199 } else if (option.equals(StandardSocketOptions.SO_RCVBUF)) { 200 return Integer.valueOf(socket.getReceiveBufferSize()); 201 } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) { 202 return Boolean.valueOf(socket.getReuseAddress()); 203 } else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) { 204 return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT)); 205 } else if (option.equals(StandardSocketOptions.SO_LINGER)) { 206 return Integer.valueOf(socket.getSoLinger()); 207 } else if (option.equals(StandardSocketOptions.IP_TOS)) { 208 return Integer.valueOf(socket.getTrafficClass()); 209 } else if (option.equals(StandardSocketOptions.TCP_NODELAY)) { 210 return Boolean.valueOf(socket.getTcpNoDelay()); 211 } else { 212 throw new RuntimeException("unexecpted socket option"); 213 } 214 } else if (type.equals(ServerSocket.class)) { 215 ServerSocket socket = (ServerSocket)s; 216 Set<SocketOption<?>> options = socket.supportedOptions(); 217 boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT); 218 219 if (option.equals(StandardSocketOptions.SO_RCVBUF)) { 220 return Integer.valueOf(socket.getReceiveBufferSize()); 221 } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) { 222 return Boolean.valueOf(socket.getReuseAddress()); 223 } else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) { 224 return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT)); 225 } else if (option.equals(StandardSocketOptions.IP_TOS)) { 226 return Integer.valueOf(jdk.net.Sockets.getOption( 227 socket, StandardSocketOptions.IP_TOS)); 228 } else { 229 throw new RuntimeException("unexecpted socket option"); 230 } 231 } else if (type.equals(DatagramSocket.class)) { 232 DatagramSocket socket = (DatagramSocket)s; 233 Set<SocketOption<?>> options = socket.supportedOptions(); 234 boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT); 235 236 if (option.equals(StandardSocketOptions.SO_SNDBUF)) { 237 return Integer.valueOf(socket.getSendBufferSize()); 238 } else if (option.equals(StandardSocketOptions.SO_RCVBUF)) { 239 return Integer.valueOf(socket.getReceiveBufferSize()); 240 } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) { 241 return Boolean.valueOf(socket.getReuseAddress()); 242 } else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) { 243 return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT)); 244 } else if (option.equals(StandardSocketOptions.IP_TOS)) { 245 return Integer.valueOf(socket.getTrafficClass()); 246 } else { 247 throw new RuntimeException("unexecpted socket option"); 248 } 249 250 } else if (type.equals(MulticastSocket.class)) { 251 MulticastSocket socket = (MulticastSocket)s; 252 Set<SocketOption<?>> options = socket.supportedOptions(); 253 boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT); 254 255 if (option.equals(StandardSocketOptions.SO_SNDBUF)) { 256 return Integer.valueOf(socket.getSendBufferSize()); 257 } else if (option.equals(StandardSocketOptions.SO_RCVBUF)) { 258 return Integer.valueOf(socket.getReceiveBufferSize()); 259 } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) { 260 return Boolean.valueOf(socket.getReuseAddress()); 261 } else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) { 262 return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT)); 263 } else if (option.equals(StandardSocketOptions.IP_TOS)) { 264 return Integer.valueOf(socket.getTrafficClass()); 265 } else if (option.equals(StandardSocketOptions.IP_MULTICAST_IF)) { 266 return socket.getNetworkInterface(); 267 } else if (option.equals(StandardSocketOptions.IP_MULTICAST_TTL)) { 268 return Integer.valueOf(socket.getTimeToLive()); 269 } else if (option.equals(StandardSocketOptions.IP_MULTICAST_LOOP)) { 270 return Boolean.valueOf(socket.getLoopbackMode()); 271 } else { 272 throw new RuntimeException("unexecpted socket option"); 273 } 274 } 275 throw new RuntimeException("unexecpted socket type"); 276 } 277 278 public static void main(String args[]) throws Exception { 279 doSocketTests(); 280 doServerSocketTests(); 281 doDgSocketTests(); 282 doMcSocketTests(); 283 } 284 }