Skip to content

Commit 4b313b5

Browse files
mpdonovaRajan Halade
authored and
Rajan Halade
committed
8297798: Timeout with DTLSOverDatagram test template
Reviewed-by: jnimeh, rhalade
1 parent ae8988e commit 4b313b5

File tree

3 files changed

+79
-135
lines changed

3 files changed

+79
-135
lines changed

test/jdk/ProblemList.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,8 +586,6 @@ sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java 8161536 generic-
586586

587587
sun/security/tools/keytool/ListKeychainStore.sh 8156889 macosx-all
588588

589-
javax/net/ssl/DTLS/CipherSuite.java 8202059 macosx-x64
590-
591589
sun/security/provider/KeyStore/DKSTest.sh 8180266 windows-all
592590

593591
sun/security/smartcardio/TestChannel.java 8039280 generic-all

test/jdk/javax/net/ssl/DTLS/DTLSOverDatagram.java

Lines changed: 65 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
3333
* @run main/othervm DTLSOverDatagram
3434
*/
3535

36+
import java.io.IOException;
3637
import java.nio.*;
3738
import java.net.*;
3839
import java.util.*;
@@ -42,6 +43,7 @@
4243
import jdk.test.lib.security.SSLContextBuilder;
4344

4445
import java.util.concurrent.*;
46+
import java.util.concurrent.atomic.AtomicBoolean;
4547

4648
import jdk.test.lib.hexdump.HexPrinter;
4749

@@ -50,8 +52,6 @@
5052
*/
5153
public class DTLSOverDatagram {
5254

53-
private static final int MAX_HANDSHAKE_LOOPS = 200;
54-
private static final int MAX_APP_READ_LOOPS = 60;
5555
private static final int SOCKET_TIMEOUT = 10 * 1000; // in millis
5656
private static final int BUFFER_SIZE = 1024;
5757
private static final int MAXIMUM_PACKET_SIZE = 1024;
@@ -75,8 +75,9 @@ public class DTLSOverDatagram {
7575
private static final ByteBuffer CLIENT_APP =
7676
ByteBuffer.wrap("Hi Server, I'm Client".getBytes());
7777

78-
private static Exception clientException = null;
79-
private static Exception serverException = null;
78+
private final AtomicBoolean exceptionOccurred = new AtomicBoolean(false);
79+
80+
private final CountDownLatch serverStarted = new CountDownLatch(1);
8081
/*
8182
* =============================================================
8283
* The test case
@@ -148,18 +149,12 @@ void handshake(SSLEngine engine, DatagramSocket socket,
148149
SocketAddress peerAddr, String side) throws Exception {
149150

150151
boolean endLoops = false;
151-
int loops = MAX_HANDSHAKE_LOOPS;
152+
int loops = 0;
152153
engine.beginHandshake();
153-
while (!endLoops &&
154-
(serverException == null) && (clientException == null)) {
155-
156-
if (--loops < 0) {
157-
throw new RuntimeException(
158-
"Too many loops to produce handshake packets");
159-
}
154+
while (!endLoops && !exceptionOccurred.get()) {
160155

161156
SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();
162-
log(side, "=======handshake(" + loops + ", " + hs + ")=======");
157+
log(side, "=======handshake(" + ++loops + ", " + hs + ")=======");
163158

164159
switch (hs) {
165160
case NEED_UNWRAP, NEED_UNWRAP_AGAIN -> {
@@ -313,16 +308,10 @@ void deliverAppData(SSLEngine engine, DatagramSocket socket,
313308
void receiveAppData(SSLEngine engine,
314309
DatagramSocket socket, ByteBuffer expectedApp) throws Exception {
315310

316-
int loops = MAX_APP_READ_LOOPS;
317-
while ((serverException == null) && (clientException == null)) {
318-
if (--loops < 0) {
319-
throw new RuntimeException(
320-
"Too much loops to receive application data");
321-
}
322-
311+
while (!exceptionOccurred.get()) {
323312
byte[] buf = new byte[BUFFER_SIZE];
324-
DatagramPacket packet = new DatagramPacket(buf, buf.length);
325-
socket.receive(packet);
313+
DatagramPacket packet = readFromSocket(socket, buf);
314+
326315
ByteBuffer netBuffer = ByteBuffer.wrap(buf, 0, packet.getLength());
327316
ByteBuffer recBuffer = ByteBuffer.allocate(BUFFER_SIZE);
328317
SSLEngineResult rs = engine.unwrap(netBuffer, recBuffer);
@@ -338,19 +327,31 @@ void receiveAppData(SSLEngine engine,
338327
}
339328
}
340329

330+
/*
331+
Some tests failed with receive time-out errors when the client tried to read
332+
from the server. The server thread had exited normally so the read _should_
333+
succeed. So let's try to read a couple of times before giving up.
334+
*/
335+
DatagramPacket readFromSocket(DatagramSocket socket, byte[] buffer) throws IOException {
336+
for (int i = 1 ; i <= 2 ; ++i) {
337+
try {
338+
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
339+
socket.receive(packet);
340+
return packet;
341+
} catch (SocketTimeoutException exc) {
342+
System.out.println("Attempt " + i + ": Timeout occurred reading from socket.");
343+
}
344+
}
345+
throw new IOException("Did not receive data after 2 attempts.");
346+
}
347+
341348
// produce handshake packets
342349
boolean produceHandshakePackets(SSLEngine engine, SocketAddress socketAddr,
343350
String side, List<DatagramPacket> packets) throws Exception {
344351

345352
boolean endLoops = false;
346-
int loops = MAX_HANDSHAKE_LOOPS / 2;
347-
while (!endLoops &&
348-
(serverException == null) && (clientException == null)) {
349-
350-
if (--loops < 0) {
351-
throw new RuntimeException(
352-
"Too many loops to produce handshake packets");
353-
}
353+
int loops = 0;
354+
while (!endLoops && !exceptionOccurred.get()) {
354355

355356
ByteBuffer oNet = ByteBuffer.allocate(32768);
356357
ByteBuffer oApp = ByteBuffer.allocate(0);
@@ -360,7 +361,7 @@ boolean produceHandshakePackets(SSLEngine engine, SocketAddress socketAddr,
360361
SSLEngineResult.Status rs = r.getStatus();
361362
SSLEngineResult.HandshakeStatus hs = r.getHandshakeStatus();
362363
log(side, "----produce handshake packet(" +
363-
loops + ", " + rs + ", " + hs + ")----");
364+
++loops + ", " + rs + ", " + hs + ")----");
364365

365366
verifySSLEngineResultStatus(r, side);
366367

@@ -518,10 +519,6 @@ SSLContext getDTLSContext() throws Exception {
518519
* The remainder is support stuff to kickstart the testing.
519520
*/
520521

521-
// Will the handshaking and application data exchange succeed?
522-
public boolean isGoodJob() {
523-
return true;
524-
}
525522

526523
public final void runTest(DTLSOverDatagram testCase) throws Exception {
527524
InetSocketAddress serverSocketAddress = new InetSocketAddress
@@ -541,97 +538,51 @@ public final void runTest(DTLSOverDatagram testCase) throws Exception {
541538
InetSocketAddress clientSocketAddr = new InetSocketAddress(
542539
InetAddress.getLoopbackAddress(), clientSocket.getLocalPort());
543540

544-
ExecutorService pool = Executors.newFixedThreadPool(2);
545-
Future<String> server, client;
541+
ExecutorService pool = Executors.newFixedThreadPool(1);
542+
Future<Void> server;
546543

547-
try {
548-
server = pool.submit(new ServerCallable(
544+
server = pool.submit(() -> runServer(
549545
testCase, serverSocket, clientSocketAddr));
550-
client = pool.submit(new ClientCallable(
551-
testCase, clientSocket, serverSocketAddr));
552-
} finally {
553-
pool.shutdown();
554-
}
555-
556-
boolean failed = false;
546+
pool.shutdown();
557547

558-
// wait for client to finish
559-
try {
560-
System.out.println("Client finished: " + client.get());
561-
} catch (CancellationException | InterruptedException
562-
| ExecutionException e) {
563-
System.out.println("Exception on client side: ");
564-
e.printStackTrace(System.out);
565-
failed = true;
566-
}
567-
568-
// wait for server to finish
569-
try {
570-
System.out.println("Client finished: " + server.get());
571-
} catch (CancellationException | InterruptedException
572-
| ExecutionException e) {
573-
System.out.println("Exception on server side: ");
574-
e.printStackTrace(System.out);
575-
failed = true;
576-
}
577-
578-
if (failed) {
579-
throw new RuntimeException("Test failed");
580-
}
548+
runClient(testCase, clientSocket, serverSocketAddr);
549+
server.get();
581550
}
582551
}
583552

584-
record ServerCallable(DTLSOverDatagram testCase, DatagramSocket socket,
585-
InetSocketAddress clientSocketAddr) implements Callable<String> {
553+
Void runServer(DTLSOverDatagram testCase, DatagramSocket socket,
554+
InetSocketAddress clientSocketAddr) throws Exception {
555+
try {
556+
serverStarted.countDown();
557+
testCase.doServerSide(socket, clientSocketAddr);
586558

587-
@Override
588-
public String call() throws Exception {
589-
try {
590-
testCase.doServerSide(socket, clientSocketAddr);
591-
} catch (Exception e) {
592-
System.out.println("Exception in ServerCallable.call():");
593-
e.printStackTrace(System.out);
594-
serverException = e;
595-
596-
if (testCase.isGoodJob()) {
597-
throw e;
598-
} else {
599-
return "Well done, server!";
600-
}
601-
}
559+
} catch (Exception exc) {
560+
exceptionOccurred.set(true);
602561

603-
if (testCase.isGoodJob()) {
604-
return "Well done, server!";
605-
} else {
606-
throw new Exception("No expected exception");
607-
}
562+
// log for debugging clarity
563+
System.out.println("Unexpected exception in server");
564+
exc.printStackTrace(System.err);
565+
throw exc;
608566
}
567+
568+
return null;
609569
}
610570

611-
record ClientCallable(DTLSOverDatagram testCase, DatagramSocket socket,
612-
InetSocketAddress serverSocketAddr) implements Callable<String> {
571+
private void runClient(DTLSOverDatagram testCase, DatagramSocket socket,
572+
InetSocketAddress serverSocketAddr) throws Exception {
573+
if(!serverStarted.await(5, TimeUnit.SECONDS)) {
574+
throw new Exception("Server did not start within 5 seconds.");
575+
}
613576

614-
@Override
615-
public String call() throws Exception {
616-
try {
617-
testCase.doClientSide(socket, serverSocketAddr);
618-
} catch (Exception e) {
619-
System.out.println("Exception in ClientCallable.call():");
620-
e.printStackTrace(System.out);
621-
clientException = e;
622-
623-
if (testCase.isGoodJob()) {
624-
throw e;
625-
} else {
626-
return "Well done, client!";
627-
}
628-
}
577+
try {
578+
testCase.doClientSide(socket, serverSocketAddr);
579+
} catch (Exception exc) {
580+
exceptionOccurred.set(true);
629581

630-
if (testCase.isGoodJob()) {
631-
return "Well done, client!";
632-
} else {
633-
throw new Exception("No expected exception");
634-
}
582+
// log for debugging clarity
583+
System.out.println("Unexpected exception in client.");
584+
exc.printStackTrace(System.err);
585+
throw exc;
635586
}
636587
}
637588

test/jdk/javax/net/ssl/DTLS/InvalidRecords.java

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -36,27 +36,32 @@
3636

3737
import java.net.DatagramPacket;
3838
import java.net.SocketAddress;
39+
import java.util.concurrent.atomic.AtomicBoolean;
3940

4041
/**
41-
* Test that if handshake messages are crasged, the handshake would fail
42+
* Test that if handshake messages are changed, the handshake would fail
4243
* because of handshaking hash verification.
4344
*/
4445
public class InvalidRecords extends DTLSOverDatagram {
45-
boolean needInvalidRecords = true;
46+
private static final AtomicBoolean needInvalidRecords = new AtomicBoolean(true);
4647

4748
public static void main(String[] args) throws Exception {
4849
InvalidRecords testCase = new InvalidRecords();
4950
testCase.runTest(testCase);
50-
}
5151

52-
@Override
53-
public boolean isGoodJob() {
54-
return false;
52+
if (needInvalidRecords.get()) {
53+
// if this is true, the createHandshakePacket() method
54+
// was NOT called twice to create ClientHello messages
55+
throw new RuntimeException(
56+
"The invalid handshake packet was not"
57+
+ " rejected as it should have been.");
58+
}
5559
}
5660

61+
5762
@Override
5863
DatagramPacket createHandshakePacket(byte[] ba, SocketAddress socketAddr) {
59-
if ((ba.length >= 60) &&
64+
if (needInvalidRecords.get() && (ba.length >= 60) &&
6065
(ba[0x00] == (byte)0x16) && (ba[0x0D] == (byte)0x01) &&
6166
(ba[0x3B] == (byte)0x00) && (ba[0x3C] > 0)) {
6267

@@ -65,18 +70,8 @@ DatagramPacket createHandshakePacket(byte[] ba, SocketAddress socketAddr) {
6570
// ba[0x3B]: length of session ID
6671
// ba[0x3C]: length of cookie
6772

68-
if (!needInvalidRecords) {
69-
// The 2nd ClientHello with cookie. The 1st one should be
70-
// rejected as expected.
71-
//
72-
// This may happen if the last few bytes of the packet are
73-
// for supported_version extension.
74-
throw new RuntimeException(
75-
"the crashed handshake message was rejected as expected");
76-
}
77-
7873
// ClientHello with cookie
79-
needInvalidRecords = false;
74+
needInvalidRecords.set(false);
8075
System.out.println("invalidate ClientHello message");
8176
if (ba[ba.length - 1] == (byte)0xFF) {
8277
ba[ba.length - 1] = (byte)0xFE;

0 commit comments

Comments
 (0)