| /* | |
| * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. | |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| * | |
| * This code is free software; you can redistribute it and/or modify it | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| /* | |
| * @test | |
| * @bug 4868820 | |
| * @key intermittent | |
| * @summary IPv6 support for Windows XP and 2003 server. | |
| * This test requires binding to the wildcard address and as such | |
| * may fail intermittently on some platforms. | |
| * @library /test/lib | |
| * @build jdk.test.lib.NetworkConfiguration | |
| * jdk.test.lib.Platform | |
| * @run main UdpTest -d | |
| */ | |
| import java.net.DatagramPacket; | |
| import java.net.DatagramSocket; | |
| import java.net.Inet4Address; | |
| import java.net.Inet6Address; | |
| import java.net.InetAddress; | |
| import java.net.PortUnreachableException; | |
| import java.net.SocketTimeoutException; | |
| import java.util.concurrent.TimeUnit; | |
| public class UdpTest extends Tests { | |
| static DatagramSocket c3, s1, s2, s3; | |
| static InetAddress s1peer, s2peer; | |
| static InetAddress ia4any; | |
| static InetAddress ia6any; | |
| static Inet6Address ia6addr; | |
| static InetAddress ia6bad; /* a global 6to4 IPv6 address, which cant be connected to */ | |
| static InetAddress ia6rem1; | |
| static Inet4Address ia4addr; | |
| static { | |
| try { | |
| ia4any = InetAddress.getByName ("0.0.0.0"); | |
| ia6any = InetAddress.getByName ("::0"); | |
| try { | |
| ia6bad = InetAddress.getByName ("2002:819c:dc29:1:1322:33ff:fe44:5566%net0"); | |
| } catch (Exception e) { | |
| ia6bad = InetAddress.getByName ("2002:819c:dc29:1:1322:33ff:fe44:5566"); | |
| } | |
| //ia6rem1 = InetAddress.getByName ("fe80::a00:20ff:feed:b08d%eth0"); | |
| //ia6rem1 = InetAddress.getByName ("129.156.220.63"); | |
| } catch (Exception e) { | |
| e.printStackTrace(); | |
| } | |
| ia6addr = getFirstLocalIPv6Address (); | |
| ia4addr = getFirstLocalIPv4Address (); | |
| } | |
| public static void main (String[] args) throws Exception { | |
| checkDebug(args); | |
| if (ia4addr == null) { | |
| System.out.println ("No local IPv4 addresses: exiting now"); | |
| return; | |
| } | |
| if (ia6addr == null) { | |
| System.out.println ("No local IPv6 addresses: exiting now"); | |
| return; | |
| } | |
| dprintln ("Local Addresses"); | |
| dprintln (ia4addr.toString()); | |
| dprintln (ia6addr.toString()); | |
| test1 (); | |
| test2 (); | |
| if (!isLinux()) { | |
| test3 (); | |
| } | |
| test4 (); | |
| } | |
| /* basic UDP connectivity test using IPv6 only and IPv4/IPv6 together */ | |
| static void test1 () throws Exception { | |
| System.out.println("Test1 starting"); | |
| s1 = new DatagramSocket (); | |
| s2 = new DatagramSocket (); | |
| simpleDataExchange (s1, ia4addr, s2, ia4addr); | |
| s1.close (); s2.close (); | |
| /* IPv6 */ | |
| s1 = new DatagramSocket (); | |
| s2 = new DatagramSocket (); | |
| simpleDataExchange (s1, ia6addr, s2, ia6addr); | |
| s1.close (); s2.close (); | |
| /* IPv6 only */ | |
| s1 = new DatagramSocket (0, ia6addr); | |
| s2 = new DatagramSocket (0, ia6addr); | |
| simpleDataExchange (s1, ia6addr, s2, ia6addr); | |
| s1.close (); s2.close (); | |
| /* IPv6 and IPv4 */ | |
| s1 = new DatagramSocket (); | |
| s2 = new DatagramSocket (); | |
| simpleDataExchange (s1, ia6addr, s2, ia4addr); | |
| s1.close (); s2.close (); | |
| /* listen on anyaddr and check receive from IPv4 and IPv6 */ | |
| s1 = new DatagramSocket (); | |
| s2 = new DatagramSocket (0, ia6addr); | |
| s3 = new DatagramSocket (0, ia4addr); | |
| datagramEcho (s2, s1, ia6addr); | |
| datagramEcho (s3, s1, ia4addr); | |
| s1.close (); s2.close (); s3.close(); | |
| System.out.println ("Test1: OK"); | |
| } | |
| /* check timeouts on receive */ | |
| static void test2 () throws Exception { | |
| System.out.println("Test2 starting"); | |
| s1 = new DatagramSocket (); | |
| s2 = new DatagramSocket (); | |
| s1.setSoTimeout (4000); | |
| long t1 = System.nanoTime(); | |
| try { | |
| s1.receive (new DatagramPacket (new byte [128], 128)); | |
| throw new Exception ("expected receive timeout "); | |
| } catch (SocketTimeoutException e) { | |
| } | |
| final long expectedTime = TimeUnit.SECONDS.toMillis(4); | |
| checkIfTimeOut(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t1), expectedTime); | |
| /* check data can be exchanged now */ | |
| simpleDataExchange (s1, ia6addr, s2, ia4addr); | |
| /* double check timeout still works */ | |
| t1 = System.nanoTime(); | |
| try { | |
| s1.receive (new DatagramPacket (new byte [128], 128)); | |
| throw new Exception ("expected receive timeout "); | |
| } catch (SocketTimeoutException e) { | |
| } | |
| checkIfTimeOut(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t1), expectedTime); | |
| /* check receive works after a delay < timeout */ | |
| final DatagramSocket s = s2; | |
| final InetAddress ia6 = ia6addr; | |
| final int port = s1.getLocalPort(); | |
| s1.setSoTimeout(10000); | |
| runAfter (2000, new Runnable () { | |
| public void run () { | |
| try { | |
| DatagramPacket p = new DatagramPacket ("Hello 123".getBytes(), 0, 8, ia6, port); | |
| s.send (p); | |
| } catch (Exception e) {} | |
| } | |
| }); | |
| t1 = System.nanoTime(); | |
| s1.receive (new DatagramPacket (new byte [128], 128)); | |
| final long startTime = TimeUnit.SECONDS.toMillis(2); | |
| checkIfTimeOut(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - t1), startTime); | |
| s1.close (); | |
| s2.close (); | |
| System.out.println ("Test2: OK"); | |
| } | |
| /* check connected sockets */ | |
| static void test3 () throws Exception { | |
| System.out.println("Test3 starting"); | |
| s1 = new DatagramSocket (); | |
| s2 = new DatagramSocket (); | |
| s1.connect (ia6addr, s2.getLocalPort()); | |
| datagramEcho (s1, s2, null); | |
| s1.close (); s2.close(); | |
| System.out.println ("Test3: OK"); | |
| } | |
| /* check PortUnreachable */ | |
| static void test4 () throws Exception { | |
| System.out.println("Test4 starting"); | |
| s1 = new DatagramSocket (); | |
| s1.connect (ia6addr, 5000); | |
| s1.setSoTimeout (3000); | |
| try { | |
| DatagramPacket p = new DatagramPacket ("HelloWorld".getBytes(), "HelloWorld".length()); | |
| s1.send (p); | |
| p = new DatagramPacket (new byte[128], 128); | |
| s1.receive (p); | |
| } catch (PortUnreachableException e) { | |
| System.out.println ("Test4: OK"); | |
| return; | |
| } catch (SocketTimeoutException e) { | |
| System.out.println ("Test4: failed. Never mind, it's an OS bug"); | |
| } | |
| } | |
| } |