SendDatagramToBadAddress.java revision 6073:cea72c2bf071
1/*
2 * Copyright (c) 2000, 2012, 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 *
27 * @bug 4204320
28 *
29 * @summary DatagramSocket.send should throw exception when connected
30 *  to an invalid destination (on platforms that support it).
31 */
32
33import java.net.*;
34import java.util.*;
35import java.io.InterruptedIOException;
36
37public class SendDatagramToBadAddress {
38
39    static boolean debug = false;
40
41    public static boolean OSsupportsFeature () {
42        Properties p = System.getProperties ();
43        String v;
44        if (p.getProperty ("os.name").equals ("Windows 2000"))
45            return (true);
46        if (p.getProperty ("os.name").equals ("Linux"))
47            return (true);
48        if (p.getProperty ("os.name").startsWith ("Mac OS"))
49            return (true);
50        // Check for specific Solaris version from here
51        v = p.getProperty ("os.arch");
52        if (!v.equalsIgnoreCase ("sparc"))
53            return (false);
54        v = p.getProperty ("os.name");
55        if (!v.equalsIgnoreCase ("Solaris") && !v.equalsIgnoreCase ("SunOS"))
56            return (false);
57        v = p.getProperty ("os.version");
58        if (v.equals ("5.8") || v.equals ("8"))
59            return (false);
60        return (true);
61    }
62
63    static void print (String s) {
64        if (debug)
65            System.out.println (s);
66    }
67
68    class Server {
69
70        DatagramSocket server;
71        byte[] buf = new byte [128];
72        DatagramPacket pack = new DatagramPacket (buf, buf.length);
73
74        public Server (DatagramSocket s) {
75            server = s;
76        }
77
78        public void receive (int loop, boolean expectError) throws Exception {
79            for (int i=0; i<loop; i++) {
80                try {
81                    server.receive (pack);
82                } catch (Exception e) {
83                    if (expectError) {
84                        print ("Got expected error: " + e);
85                        continue;
86                    } else {
87                        print ("Got: " + new String (pack.getData()));
88                        print ("Expected: " + new String (buf));
89                        throw new Exception ("Error reading data: Iter " +i);
90                    }
91                }
92                String s1 = "Hello, server"+i;
93                byte[] buf      = s1.getBytes();
94                if (!s1.equals (new String (pack.getData(),
95                                            pack.getOffset(),pack.getLength()))) {
96                    print ("Got: " + new String (pack.getData()));
97                    print ("Expected: " + new String (buf));
98                    throw new Exception ("Error comparing data: Iter " +i);
99                }
100            }
101        }
102    };
103
104    public static void main (String args[]) throws Exception {
105        if (args.length >=1 && args[0].equals ("-d")) {
106            debug = true;
107        }
108        SendDatagramToBadAddress ud = new SendDatagramToBadAddress ();
109        ud.run ();
110    }
111
112    public void run() throws Exception {
113
114        if (OSsupportsFeature()) {
115            print ("running on OS that supports ICMP port unreachable");
116        }
117        String host = "127.0.0.1";
118        InetAddress addr = InetAddress.getByName(host);
119        DatagramSocket sock = new DatagramSocket();
120        DatagramSocket serversock = new DatagramSocket(0);
121        DatagramPacket p;
122        byte[] buf;
123        int port = serversock.getLocalPort ();
124        final int loop = 5;
125        Server s = new Server (serversock);
126        int i;
127
128        print ("Checking send to connected address ...");
129        sock.connect(addr, port);
130
131        for (i = 0; i < loop; i++) {
132            try {
133                buf = ("Hello, server"+i).getBytes();
134                if (i % 2 == 1)
135                    p = new DatagramPacket(buf, buf.length, addr, port);
136                else
137                    p = new DatagramPacket(buf, buf.length);
138                sock.send(p);
139            } catch (Exception ex) {
140                print ("Got unexpected exception: " + ex);
141                throw new Exception ("Error sending data: ");
142            }
143        }
144
145        s.receive (loop, false);
146
147        // check disconnect() works
148
149        print ("Checking send to non-connected address ...");
150        sock.disconnect ();
151        buf = ("Hello, server"+0).getBytes();
152        p = new DatagramPacket(buf, buf.length, addr, port);
153        sock.send (p);
154        s.receive (1, false);
155
156        // check send() to invalid destination followed by a blocking receive
157        // returns an error
158
159        print ("Checking send to invalid address ...");
160        sock.connect(addr, port);
161        serversock.close ();
162        try {
163            sock.setSoTimeout (4000);
164        } catch (Exception e) {
165            print ("could not set timeout");
166            throw e;
167        }
168
169        boolean goterror = false;
170
171        for (i = 0; i < loop; i++) {
172            try {
173                buf = ("Hello, server"+i).getBytes();
174                p = new DatagramPacket(buf, buf.length, addr, port);
175                sock.send(p);
176                p = new DatagramPacket(buf, buf.length, addr, port);
177                sock.receive (p);
178            } catch (InterruptedIOException ex) {
179                print ("socket timeout");
180            } catch (Exception ex) {
181                print ("Got expected exception: " + ex);
182                goterror = true;
183            }
184        }
185
186        if (!goterror && OSsupportsFeature ()) {
187            print ("Didnt get expected exception: ");
188            throw new Exception ("send did not return expected error");
189        }
190    }
191}
192