1/*
2 * Copyright (c) 2006, 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// SunJSSE does not support dynamic system properties, no way to re-use
26// system properties in samevm/agentvm mode.
27//
28
29/*
30 * @test
31 *
32 * @bug 6388456
33 * @summary Need adjustable TLS max record size for interoperability
34 *      with non-compliant
35 * @run main/othervm LargePacket
36 *
37 * @author Xuelei Fan
38 */
39
40import javax.net.ssl.*;
41import java.nio.channels.*;
42import java.net.*;
43
44public class LargePacket extends SSLEngineService {
45
46    /*
47     * =============================================================
48     * Set the various variables needed for the tests, then
49     * specify what tests to run on each side.
50     */
51
52    /*
53     * Should we run the client or server in a separate thread?
54     * Both sides can throw exceptions, but do you have a preference
55     * as to which side should be the main thread.
56     */
57    static boolean separateServerThread = true;
58
59    // Is the server ready to serve?
60    volatile static boolean serverReady = false;
61
62    /*
63     * Turn on SSL debugging?
64     */
65    static boolean debug = false;
66
67    /*
68     * Define the server side of the test.
69     *
70     * If the server prematurely exits, serverReady will be set to true
71     * to avoid infinite hangs.
72     */
73    void doServerSide() throws Exception {
74        // create SSLEngine.
75        SSLEngine ssle = createSSLEngine(false);
76
77        // Create a server socket channel.
78        InetSocketAddress isa =
79                new InetSocketAddress(InetAddress.getLocalHost(), serverPort);
80        ServerSocketChannel ssc = ServerSocketChannel.open();
81        ssc.socket().bind(isa);
82        serverPort = ssc.socket().getLocalPort();
83
84        // Signal Client, we're ready for his connect.
85        serverReady = true;
86
87        // Accept a socket channel.
88        SocketChannel sc = ssc.accept();
89
90        // Complete connection.
91        while (!sc.finishConnect()) {
92            // waiting for the connection completed.
93        }
94
95        // handshaking
96        handshaking(ssle, sc, null);
97
98        // receive application data
99        receive(ssle, sc);
100
101        // send out application data
102        deliver(ssle, sc);
103
104        // close the socket channel.
105        sc.close();
106        ssc.close();
107    }
108
109    /*
110     * Define the client side of the test.
111     *
112     * If the server prematurely exits, serverReady will be set to true
113     * to avoid infinite hangs.
114     */
115    void doClientSide() throws Exception {
116        // create SSLEngine.
117        SSLEngine ssle = createSSLEngine(true);
118
119        /*
120         * Wait for server to get started.
121         */
122        while (!serverReady) {
123            Thread.sleep(50);
124        }
125
126        // Create a non-blocking socket channel.
127        SocketChannel sc = SocketChannel.open();
128        sc.configureBlocking(false);
129        InetSocketAddress isa =
130                new InetSocketAddress(InetAddress.getLocalHost(), serverPort);
131        sc.connect(isa);
132
133        // Complete connection.
134        while (!sc.finishConnect() ) {
135            // waiting for the connection completed.
136        }
137
138        // handshaking
139        handshaking(ssle, sc, null);
140
141        // send out application data
142        deliver(ssle, sc);
143
144        // receive application data
145        receive(ssle, sc);
146
147        // close the socket channel.
148        sc.close();
149    }
150
151    /*
152     * =============================================================
153     * The remainder is just support stuff
154     */
155    volatile Exception serverException = null;
156    volatile Exception clientException = null;
157
158    // use any free port by default
159    volatile int serverPort = 0;
160
161    public static void main(String args[]) throws Exception {
162        if (debug)
163            System.setProperty("javax.net.debug", "all");
164
165        new LargePacket();
166    }
167
168    Thread clientThread = null;
169    Thread serverThread = null;
170
171    /*
172     * Primary constructor, used to drive remainder of the test.
173     *
174     * Fork off the other side, then do your work.
175     */
176    LargePacket() throws Exception {
177        super("../etc");
178
179        if (separateServerThread) {
180            startServer(true);
181            startClient(false);
182        } else {
183            startClient(true);
184            startServer(false);
185        }
186
187        /*
188         * Wait for other side to close down.
189         */
190        if (separateServerThread) {
191            serverThread.join();
192        } else {
193            clientThread.join();
194        }
195
196        /*
197         * When we get here, the test is pretty much over.
198         *
199         * If the main thread excepted, that propagates back
200         * immediately.  If the other thread threw an exception, we
201         * should report back.
202         */
203        if (serverException != null) {
204            System.out.print("Server Exception:");
205            throw serverException;
206        }
207        if (clientException != null) {
208            System.out.print("Client Exception:");
209            throw clientException;
210        }
211    }
212
213    void startServer(boolean newThread) throws Exception {
214        if (newThread) {
215            serverThread = new Thread() {
216                public void run() {
217                    try {
218                        doServerSide();
219                    } catch (Exception e) {
220                        /*
221                         * Our server thread just died.
222                         *
223                         * Release the client, if not active already...
224                         */
225                        System.err.println("Server died...");
226                        System.err.println(e);
227                        serverReady = true;
228                        serverException = e;
229                    }
230                }
231            };
232            serverThread.start();
233        } else {
234            doServerSide();
235        }
236    }
237
238    void startClient(boolean newThread) throws Exception {
239        if (newThread) {
240            clientThread = new Thread() {
241                public void run() {
242                    try {
243                        doClientSide();
244                    } catch (Exception e) {
245                        /*
246                         * Our client thread just died.
247                         */
248                        System.err.println("Client died...");
249                        clientException = e;
250                    }
251                }
252            };
253            clientThread.start();
254        } else {
255            doClientSide();
256        }
257    }
258}
259