1 /*
2  * Copyright (c) 2003, 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 import jdk.test.lib.NetworkConfiguration;
25 
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.OutputStream;
29 import java.net.DatagramPacket;
30 import java.net.DatagramSocket;
31 import java.net.Inet4Address;
32 import java.net.Inet6Address;
33 import java.net.InetAddress;
34 import java.net.InetSocketAddress;
35 import java.net.Socket;
36 import java.net.SocketAddress;
37 
38 public class Tests {
39 
40     static final boolean isWindows =
41             System.getProperty("os.name").startsWith("Windows");
42     static final boolean isMacOS =
43             System.getProperty("os.name").contains("OS X");
44 
45     /**
46      * performs a simple exchange of data between the two sockets
47      * and throws an exception if there is any problem.
48      */
simpleDataExchange(Socket s1, Socket s2)49     public static void simpleDataExchange (Socket s1, Socket s2)
50         throws Exception {
51 
52         InputStream i1 = s1.getInputStream();
53         InputStream i2 = s2.getInputStream();
54         OutputStream o1 = s1.getOutputStream();
55         OutputStream o2 = s2.getOutputStream();
56 
57         startSimpleWriter("SimpleWriter-1", o1, 100);
58         startSimpleWriter("SimpleWriter-2", o2, 200);
59         simpleRead (i2, 100);
60         simpleRead (i1, 200);
61     }
62 
startSimpleWriter(String threadName, final OutputStream os, final int start)63     static void startSimpleWriter(String threadName, final OutputStream os, final int start) {
64         (new Thread(new Runnable() {
65             public void run() {
66                 try { simpleWrite(os, start); }
67                 catch (Exception e) {unexpected(e); }
68             }}, threadName)).start();
69     }
70 
unexpected(Exception e )71     static void unexpected(Exception e ) {
72         System.out.println("Unexcepted Exception: " + e);
73         e.printStackTrace();
74     }
75 
76     /**
77      * Send a packet from s1 to s2 (ia2/s2.localPort) and check it
78      * Send a packet from s2 to s1 (ia1/s1.localPort) and check it
79      */
simpleDataExchange(DatagramSocket s1, InetAddress ia1, DatagramSocket s2, InetAddress ia2)80     public static void simpleDataExchange (DatagramSocket s1, InetAddress ia1,
81                                            DatagramSocket s2, InetAddress ia2)
82         throws Exception {
83 
84         SocketAddress dest1 = new InetSocketAddress (ia1, s1.getLocalPort());
85         dprintln ("dest1 = " + dest1);
86         SocketAddress dest2 = new InetSocketAddress (ia2, s2.getLocalPort());
87         dprintln ("dest2 = " + dest2);
88 
89         byte[] ba = "Hello world".getBytes();
90         byte[] bb = "HELLO WORLD1".getBytes();
91         DatagramPacket p1 = new DatagramPacket (ba, ba.length, dest1);
92         DatagramPacket p2 = new DatagramPacket (ba, ba.length, dest2);
93 
94         DatagramPacket r1 = new DatagramPacket (new byte[256], 256);
95         DatagramPacket r2 = new DatagramPacket (new byte[256], 256);
96 
97         s2.send (p1);
98         s1.send (p2);
99         s1.receive (r1);
100         s2.receive (r2);
101         comparePackets (p1, r1);
102         comparePackets (p2, r2);
103     }
104 
105     /**
106      * Send a packet from s1 to s2 (ia2/s2.localPort) and send same packet
107      * back from s2 to sender. Check s1 receives original packet
108      */
109 
datagramEcho(DatagramSocket s1, DatagramSocket s2, InetAddress ia2)110     public static void datagramEcho (DatagramSocket s1, DatagramSocket s2,
111                                      InetAddress ia2)
112         throws Exception {
113 
114         byte[] ba = "Hello world".getBytes();
115         DatagramPacket p1;
116 
117         SocketAddress dest2 = null;
118         if (ia2 != null) {
119             dest2 = new InetSocketAddress (ia2, s2.getLocalPort());
120             p1 = new DatagramPacket (ba, ba.length, dest2);
121         } else {
122             p1 = new DatagramPacket (ba, ba.length);
123         }
124 
125         dprintln ("dest2 = " + dest2);
126 
127 
128         DatagramPacket r1 = new DatagramPacket (new byte[256], 256);
129         DatagramPacket r2 = new DatagramPacket (new byte[256], 256);
130 
131         s1.send (p1);
132         s2.receive (r1);
133         s2.send (r1);
134         s1.receive (r2);
135         comparePackets (p1, r1);
136         comparePackets (p1, r2);
137     }
138 
comparePackets(DatagramPacket p1, DatagramPacket p2)139     public static void comparePackets (DatagramPacket p1, DatagramPacket p2)
140         throws Exception {
141 
142         byte[] b1 = p1.getData();
143         byte[] b2 = p2.getData();
144         int len = p1.getLength () > p2.getLength() ? p2.getLength()
145                                                    : p1.getLength();
146         for (int i=0; i<len; i++) {
147             if (b1[i] != b2[i]) {
148                 throw new Exception ("packets not the same");
149             }
150         }
151     }
152 
153     /* check the time got is within 50% of the time expected */
checkTime(long got, long expected)154     public static void checkTime (long got, long expected) {
155         checkTime(got, expected, expected);
156     }
157 
158     /* check the time got is between start and end, given 50% tolerance */
checkTime(long got, long start, long end)159     public static void checkTime(long got, long start, long end) {
160         dprintln("checkTime: got = " + got + " start = " + start + " end = " + end);
161         long upper = end + (end / 2);
162         long lower = start - (start / 2);
163         if (got > upper || got < lower) {
164             throw new RuntimeException("checkTime failed: got " + got
165                     + ", expected between " + start + " and " + end);
166         }
167     }
168 
169     static boolean debug = false;
170 
checkDebug(String[] args)171     public static void checkDebug (String[] args) {
172         debug = args.length > 0 && args[0].equals("-d");
173     }
174 
dprint(String s)175     public static void dprint (String s) {
176         if (debug) {
177             System.out.print (s);
178         }
179     }
180 
dprintln(String s)181     public static void dprintln (String s) {
182         if (debug) {
183             System.out.println (s);
184         }
185     }
186 
getFirstLocalIPv4Address()187     public static Inet4Address getFirstLocalIPv4Address () {
188         return getNetworkConfig().ip4Addresses()
189                                  .filter(a -> !a.isLoopbackAddress())
190                                  .findFirst()
191                                  .orElse(null);
192     }
193 
getFirstLocalIPv6Address()194     public static Inet6Address getFirstLocalIPv6Address () {
195         return getNetworkConfig().ip6Addresses()
196                                  .filter(a -> !a.isLoopbackAddress())
197                                  .findFirst()
198                                  .orElse(null);
199     }
200 
getNetworkConfig()201     private static NetworkConfiguration getNetworkConfig() {
202         try {
203             return NetworkConfiguration.probe();
204         } catch (IOException e) {
205             System.out.println("Failed to probe NetworkConfiguration");
206             throw new RuntimeException(e);
207         }
208     }
209 
210     /**
211      * Throws a RuntimeException if the boolean condition is false
212      */
t_assert(boolean assertion)213     public static void t_assert (boolean assertion) {
214         if (assertion) {
215             return;
216         }
217         Throwable t = new Throwable();
218         StackTraceElement[] strace = t.getStackTrace();
219         String msg = "Assertion failed at: " + strace[1].toString();
220         throw new RuntimeException (msg);
221     }
222 
simpleRead(InputStream is, int start)223     private static void simpleRead (InputStream is, int start) throws Exception {
224         byte b[] = new byte [2];
225         for (int i=start; i<start+100; i++) {
226             int x = is.read (b);
227             if (x == 1) {
228                 x += is.read (b,1,1);
229             }
230             if (x!=2) {
231                 throw new Exception ("read error");
232             }
233             int r = bytes (b[0], b[1]);
234             if (r != i) {
235                 throw new Exception ("read " + r + " expected " +i);
236             }
237         }
238     }
239 
240     /* convert signed bytes to unisigned int */
bytes(byte b1, byte b2)241     private static int bytes (byte b1, byte b2) {
242         int i1 = (int)b1 & 0xFF;
243         int i2 = (int)b2 & 0xFF;
244         return i1 * 256 + i2;
245     }
246 
simpleWrite(OutputStream os, int start)247     static void simpleWrite (OutputStream os, int start) throws Exception {
248         byte b[] = new byte [2];
249         for (int i=start; i<start+100; i++) {
250             b[0] = (byte) (i / 256);
251             b[1] = (byte) (i % 256);
252             os.write (b);
253         }
254     }
255 
256     private static class Runner extends Thread {
257         Runnable runnee;
258         long delay;
259 
Runner(Runnable runnee, long delay)260         Runner (Runnable runnee, long delay) {
261             super();
262             this.runnee = runnee;
263             this.delay = delay;
264         }
265 
run()266         public void run () {
267             try {
268                 Thread.sleep (delay);
269                 runnee.run ();
270             } catch (Exception e) {
271                 e.printStackTrace();
272             }
273         }
274     }
275 
276     /*
277      * Take the given Runnable and run it in a spawned thread
278      * after the given time has elapsed. runAfter() returns immediately
279      */
runAfter(long millis, Runnable runnee)280     public static void runAfter (long millis, Runnable runnee) {
281         Runner runner = new Runner (runnee, millis);
282         runner.start ();
283     }
284 
285     static String osname;
286 
287     static {
288         osname = System.getProperty ("os.name");
289     }
290 
isLinux()291     static boolean isLinux () {
292         return osname.equals ("Linux");
293     }
294 
isWindows()295     static boolean isWindows () {
296         return osname.startsWith ("Windows");
297     }
298 }
299