J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright 2003 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
| 21 | * have any questions. |
| 22 | */ |
| 23 | |
| 24 | /* |
| 25 | * @test |
| 26 | * @bug 4868820 |
| 27 | * @summary IPv6 support for Windows XP and 2003 server |
| 28 | */ |
| 29 | |
| 30 | import java.net.*; |
| 31 | import java.io.*; |
| 32 | |
| 33 | public class TcpTest extends Tests { |
| 34 | static ServerSocket server, server1, server2; |
| 35 | static Socket c1, c2, c3, s1, s2, s3; |
| 36 | static InetAddress s1peer, s2peer; |
| 37 | |
| 38 | static InetAddress ia4any; |
| 39 | static InetAddress ia6any; |
| 40 | static Inet6Address ia6addr; |
| 41 | static InetAddress ia6bad; /* a global 6to4 IPv6 address, which cant be connected to */ |
| 42 | static Inet4Address ia4addr; |
| 43 | |
| 44 | static { |
| 45 | ia6addr = getFirstLocalIPv6Address (); |
| 46 | ia4addr = getFirstLocalIPv4Address (); |
| 47 | try { |
| 48 | ia4any = InetAddress.getByName ("0.0.0.0"); |
| 49 | ia6any = InetAddress.getByName ("::0"); |
| 50 | int scope = ia6addr.getScopeId(); |
| 51 | if (scope != 0) { |
| 52 | ia6bad = InetAddress.getByName ("fe80::1:2:3:4:5:6%"+scope); |
| 53 | } else { |
| 54 | ia6bad = InetAddress.getByName ("fe80::1:2:3:4:5:6"); |
| 55 | } |
| 56 | } catch (Exception e) { |
| 57 | e.printStackTrace(); |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | public static void main (String[] args) throws Exception { |
| 62 | checkDebug(args); |
| 63 | if (ia6addr == null) { |
| 64 | System.out.println ("No IPV6 addresses: exiting test"); |
| 65 | return; |
| 66 | } |
| 67 | dprintln ("Local Addresses"); |
| 68 | dprintln (ia4addr.toString()); |
| 69 | dprintln (ia6addr.toString()); |
| 70 | dprintln ("Bad address: " + ia6bad); |
| 71 | test1 (0); |
| 72 | test1 (5100); |
| 73 | test2(); |
| 74 | test3(); |
| 75 | test4(); |
| 76 | } |
| 77 | |
| 78 | /* basic TCP connectivity test using IPv6 only and IPv4/IPv6 together */ |
| 79 | |
| 80 | static void test1 (int port) throws Exception { |
| 81 | server = new ServerSocket (port); |
| 82 | if (port == 0) { |
| 83 | port = server.getLocalPort(); |
| 84 | } |
| 85 | // try Ipv6 only |
| 86 | c1 = new Socket ("::1", port); |
| 87 | s1 = server.accept (); |
| 88 | simpleDataExchange (c1, s1); |
| 89 | s1.close (); |
| 90 | c1.close(); |
| 91 | // try with both IPv4 and Ipv6 |
| 92 | c1 = new Socket ("127.0.0.1", port); |
| 93 | c2 = new Socket ("::1", port); |
| 94 | s1 = server.accept(); |
| 95 | s2 = server.accept(); |
| 96 | s1peer = s1.getInetAddress(); |
| 97 | s2peer = s2.getInetAddress(); |
| 98 | if (s1peer instanceof Inet6Address) { |
| 99 | t_assert ((s2peer instanceof Inet4Address)); |
| 100 | simpleDataExchange (c2, s1); |
| 101 | simpleDataExchange (c1, s2); |
| 102 | } else { |
| 103 | t_assert ((s2peer instanceof Inet6Address)); |
| 104 | simpleDataExchange (c1, s1); |
| 105 | simpleDataExchange (c2, s2); |
| 106 | } |
| 107 | c1.close(); |
| 108 | c2.close(); |
| 109 | s1.close(); |
| 110 | s2.close(); |
| 111 | server.close (); |
| 112 | System.out.println ("Test1: OK"); |
| 113 | } |
| 114 | |
| 115 | /** bind tests: |
| 116 | * 1. bind to specific address IPv4 only (any port) |
| 117 | * 2. bind to specific address IPv6 only (any port) |
| 118 | * 3. bind to specific address IPv4 only (specific port) |
| 119 | * 4. bind to specific address IPv4 only (specific port) |
| 120 | * 5. bind to any address IPv4 (test collision) |
| 121 | */ |
| 122 | |
| 123 | static void test2 () throws Exception { |
| 124 | |
| 125 | server = new ServerSocket (); |
| 126 | InetSocketAddress sadr = new InetSocketAddress (ia4addr, 0); |
| 127 | server.bind (sadr); |
| 128 | dprintln ("server bound to " + sadr); |
| 129 | int port = server.getLocalPort(); |
| 130 | InetSocketAddress sadr6 = new InetSocketAddress (ia6addr, port); |
| 131 | |
| 132 | c1 = new Socket (ia4addr, port); |
| 133 | try { |
| 134 | dprintln ("connecting to " + ia6addr); |
| 135 | c2 = new Socket (); |
| 136 | c2.connect (sadr6, 1000); |
| 137 | throw new RuntimeException ("connect to IPv6 address should be refused"); |
| 138 | } catch (IOException e) { } |
| 139 | server.close (); |
| 140 | c1.close (); |
| 141 | |
| 142 | /* now try IPv6 only */ |
| 143 | |
| 144 | server = new ServerSocket (); |
| 145 | sadr = new InetSocketAddress (ia6addr, 0); |
| 146 | dprintln ("binding to " + sadr); |
| 147 | server.bind (sadr); |
| 148 | port = server.getLocalPort(); |
| 149 | |
| 150 | c1 = new Socket (ia6addr, port); |
| 151 | try { |
| 152 | c2 = new Socket (ia4addr, port); |
| 153 | throw new RuntimeException ("connect to IPv4 address should be refused"); |
| 154 | } catch (IOException e) { } |
| 155 | server.close (); |
| 156 | c1.close (); |
| 157 | |
| 158 | /* now try IPv6 specific port only */ |
| 159 | |
| 160 | server = new ServerSocket (); |
| 161 | sadr = new InetSocketAddress (ia6addr, 5200); |
| 162 | server.bind (sadr); |
| 163 | port = server.getLocalPort(); |
| 164 | t_assert (port == 5200); |
| 165 | |
| 166 | c1 = new Socket (ia6addr, port); |
| 167 | try { |
| 168 | c2 = new Socket (ia4addr, port); |
| 169 | throw new RuntimeException ("connect to IPv4 address should be refused"); |
| 170 | } catch (IOException e) { } |
| 171 | server.close (); |
| 172 | c1.close (); |
| 173 | |
| 174 | /* now try IPv4 specific port only */ |
| 175 | |
| 176 | server = new ServerSocket (); |
| 177 | sadr = new InetSocketAddress (ia4addr, 5200); |
| 178 | server.bind (sadr); |
| 179 | port = server.getLocalPort(); |
| 180 | t_assert (port == 5200); |
| 181 | |
| 182 | c1 = new Socket (ia4addr, port); |
| 183 | |
| 184 | try { |
| 185 | c2 = new Socket (ia6addr, port); |
| 186 | throw new RuntimeException ("connect to IPv6 address should be refused"); |
| 187 | } catch (IOException e) { } |
| 188 | server.accept().close(); |
| 189 | c1.close (); |
| 190 | server.close(); |
| 191 | System.out.println ("Test2: OK"); |
| 192 | } |
| 193 | |
| 194 | /* Test timeouts on accept(), connect() */ |
| 195 | |
| 196 | static void test3 () throws Exception { |
| 197 | server = new ServerSocket (0); |
| 198 | server.setSoTimeout (5000); |
| 199 | int port = server.getLocalPort(); |
| 200 | long t1 = System.currentTimeMillis(); |
| 201 | try { |
| 202 | server.accept (); |
| 203 | throw new RuntimeException ("accept should not have returned"); |
| 204 | } catch (SocketTimeoutException e) {} |
| 205 | t1 = System.currentTimeMillis() - t1; |
| 206 | checkTime (t1, 5000); |
| 207 | |
| 208 | c1 = new Socket (); |
| 209 | c1.connect (new InetSocketAddress (ia4addr, port), 1000); |
| 210 | s1 = server.accept (); |
| 211 | simpleDataExchange (c1,s1); |
| 212 | c2 = new Socket (); |
| 213 | c2.connect (new InetSocketAddress (ia6addr, port), 1000); |
| 214 | s2 = server.accept (); |
| 215 | simpleDataExchange (c2,s2); |
| 216 | c3 = new Socket (); |
| 217 | c3.connect (new InetSocketAddress (ia6addr, port), 1000); |
| 218 | s3 = server.accept (); |
| 219 | c2.close (); s2.close(); |
| 220 | server.close(); |
| 221 | simpleDataExchange (c3,s3); |
| 222 | c1.close (); c2.close(); |
| 223 | s1.close (); s2.close(); |
| 224 | |
| 225 | /* check if connect() timesout when connecting to unknown dest. */ |
| 226 | |
| 227 | c1 = new Socket(); |
| 228 | t1 = System.currentTimeMillis(); |
| 229 | InetSocketAddress ad1 = new InetSocketAddress (ia6bad, 2500); |
| 230 | try { |
| 231 | c1.connect (ad1, 5000); |
| 232 | throw new RuntimeException ("timeout exception was expected"); |
| 233 | } catch (SocketTimeoutException e) { |
| 234 | t1 = System.currentTimeMillis() - t1; |
| 235 | checkTime (t1, 5000); |
| 236 | } catch (NoRouteToHostException e1) { |
| 237 | } |
| 238 | System.out.println ("Test3: OK"); |
| 239 | } |
| 240 | |
| 241 | /* Test: connect to IPv4 mapped address */ |
| 242 | |
| 243 | static void test4 () throws Exception { |
| 244 | server = new ServerSocket (0); |
| 245 | int port = server.getLocalPort(); |
| 246 | |
| 247 | /* create an IPv4 mapped address corresponding to local host */ |
| 248 | |
| 249 | byte[] b = {0,0,0,0,0,0,0,0,0,0,(byte)0xff,(byte)0xff,0,0,0,0}; |
| 250 | byte[] ia4 = ia4addr.getAddress(); |
| 251 | b[12] = ia4[0]; |
| 252 | b[13] = ia4[1]; |
| 253 | b[14] = ia4[2]; |
| 254 | b[15] = ia4[3]; |
| 255 | |
| 256 | InetAddress dest = InetAddress.getByAddress (b); |
| 257 | c1 = new Socket (dest, port); |
| 258 | s1 = server.accept (); |
| 259 | simpleDataExchange (c1,s1); |
| 260 | c1.close (); |
| 261 | s1.close (); |
| 262 | server.close (); |
| 263 | System.out.println ("Test4: OK"); |
| 264 | } |
| 265 | } |