8264152: javax/net/ssl/DTLS/RespondToRetransmit.java timed out

Reviewed-by: xuelei
This commit is contained in:
Fernando Guallini 2021-04-16 16:51:41 +00:00 committed by Xue-Lei Andrew Fan
parent 1c3fd46d7d
commit 79adc16fd8
3 changed files with 166 additions and 218 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -50,33 +50,33 @@ import jdk.test.lib.hexdump.HexPrinter;
*/ */
public class DTLSOverDatagram { public class DTLSOverDatagram {
private static int MAX_HANDSHAKE_LOOPS = 200; private static final int MAX_HANDSHAKE_LOOPS = 200;
private static int MAX_APP_READ_LOOPS = 60; private static final int MAX_APP_READ_LOOPS = 60;
private static int SOCKET_TIMEOUT = 10 * 1000; // in millis private static final int SOCKET_TIMEOUT = 10 * 1000; // in millis
private static int BUFFER_SIZE = 1024; private static final int BUFFER_SIZE = 1024;
private static int MAXIMUM_PACKET_SIZE = 1024; private static final int MAXIMUM_PACKET_SIZE = 1024;
/* /*
* The following is to set up the keystores. * The following is to set up the keystores.
*/ */
private static String pathToStores = "../etc"; private static final String PATH_TO_STORES = "../etc";
private static String keyStoreFile = "keystore"; private static final String KEY_STORE_FILE = "keystore";
private static String trustStoreFile = "truststore"; private static final String TRUST_STORE_FILE = "truststore";
private static String keyFilename = private static final String KEY_FILENAME =
System.getProperty("test.src", ".") + "/" + pathToStores + System.getProperty("test.src", ".") + "/" + PATH_TO_STORES +
"/" + keyStoreFile; "/" + KEY_STORE_FILE;
private static String trustFilename = private static final String TRUST_FILENAME =
System.getProperty("test.src", ".") + "/" + pathToStores + System.getProperty("test.src", ".") + "/" + PATH_TO_STORES +
"/" + trustStoreFile; "/" + TRUST_STORE_FILE;
private static Exception clientException = null;
private static Exception serverException = null;
private static ByteBuffer serverApp = private static final ByteBuffer SERVER_APP =
ByteBuffer.wrap("Hi Client, I'm Server".getBytes()); ByteBuffer.wrap("Hi Client, I'm Server".getBytes());
private static ByteBuffer clientApp = private static final ByteBuffer CLIENT_APP =
ByteBuffer.wrap("Hi Server, I'm Client".getBytes()); ByteBuffer.wrap("Hi Server, I'm Client".getBytes());
private static Exception clientException = null;
private static Exception serverException = null;
/* /*
* ============================================================= * =============================================================
* The test case * The test case
@ -91,18 +91,19 @@ public class DTLSOverDatagram {
*/ */
void doServerSide(DatagramSocket socket, InetSocketAddress clientSocketAddr) void doServerSide(DatagramSocket socket, InetSocketAddress clientSocketAddr)
throws Exception { throws Exception {
String side = "Server";
// create SSLEngine // create SSLEngine
SSLEngine engine = createSSLEngine(false); SSLEngine engine = createSSLEngine(false);
// handshaking // handshaking
handshake(engine, socket, clientSocketAddr, "Server"); handshake(engine, socket, clientSocketAddr, side);
// read client application data // read client application data
receiveAppData(engine, socket, clientApp); receiveAppData(engine, socket, CLIENT_APP);
// write server application data // write server application data
deliverAppData(engine, socket, serverApp, clientSocketAddr); deliverAppData(engine, socket, SERVER_APP, clientSocketAddr, side);
} }
/* /*
@ -110,18 +111,19 @@ public class DTLSOverDatagram {
*/ */
void doClientSide(DatagramSocket socket, InetSocketAddress serverSocketAddr) void doClientSide(DatagramSocket socket, InetSocketAddress serverSocketAddr)
throws Exception { throws Exception {
String side = "Client";
// create SSLEngine // create SSLEngine
SSLEngine engine = createSSLEngine(true); SSLEngine engine = createSSLEngine(true);
// handshaking // handshaking
handshake(engine, socket, serverSocketAddr, "Client"); handshake(engine, socket, serverSocketAddr, side);
// write client application data // write client application data
deliverAppData(engine, socket, clientApp, serverSocketAddr); deliverAppData(engine, socket, CLIENT_APP, serverSocketAddr, side);
// read server application data // read server application data
receiveAppData(engine, socket, serverApp); receiveAppData(engine, socket, SERVER_APP);
} }
/* /*
@ -153,117 +155,94 @@ public class DTLSOverDatagram {
if (--loops < 0) { if (--loops < 0) {
throw new RuntimeException( throw new RuntimeException(
"Too much loops to produce handshake packets"); "Too many loops to produce handshake packets");
} }
SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus(); SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();
log(side, "=======handshake(" + loops + ", " + hs + ")======="); log(side, "=======handshake(" + loops + ", " + hs + ")=======");
if (hs == SSLEngineResult.HandshakeStatus.NEED_UNWRAP ||
hs == SSLEngineResult.HandshakeStatus.NEED_UNWRAP_AGAIN) {
log(side, "Receive DTLS records, handshake status is " + hs); switch (hs) {
case NEED_UNWRAP, NEED_UNWRAP_AGAIN -> {
log(side, "Receive DTLS records, handshake status is " + hs);
ByteBuffer iNet; ByteBuffer iNet;
ByteBuffer iApp; ByteBuffer iApp;
if (hs == SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {
byte[] buf = new byte[BUFFER_SIZE];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
try {
socket.receive(packet);
} catch (SocketTimeoutException ste) {
log(side, "Warning: " + ste);
List<DatagramPacket> packets = new ArrayList<>(); if (hs == SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {
boolean finished = onReceiveTimeout( byte[] buf = new byte[BUFFER_SIZE];
engine, peerAddr, side, packets); DatagramPacket packet = new DatagramPacket(buf, buf.length);
try {
socket.receive(packet);
} catch (SocketTimeoutException ste) {
log(side, "Warning: " + ste);
log(side, "Reproduced " + packets.size() + " packets"); List<DatagramPacket> packets = new ArrayList<>();
for (DatagramPacket p : packets) { boolean finished = onReceiveTimeout(
printHex("Reproduced packet", engine, peerAddr, side, packets);
p.getData(), p.getOffset(), p.getLength());
socket.send(p); log(side, "Reproduced " + packets.size() + " packets");
for (DatagramPacket p : packets) {
printHex("Reproduced packet",
p.getData(), p.getOffset(), p.getLength());
socket.send(p);
}
if (finished) {
log(side, "Handshake status is FINISHED "
+ "after calling onReceiveTimeout(), "
+ "finish the loop");
endLoops = true;
}
log(side, "New handshake status is "
+ engine.getHandshakeStatus());
continue;
} }
if (finished) { iNet = ByteBuffer.wrap(buf, 0, packet.getLength());
log(side, "Handshake status is FINISHED " } else {
+ "after calling onReceiveTimeout(), " iNet = ByteBuffer.allocate(0);
+ "finish the loop");
endLoops = true;
}
log(side, "New handshake status is "
+ engine.getHandshakeStatus());
continue;
} }
iNet = ByteBuffer.wrap(buf, 0, packet.getLength());
iApp = ByteBuffer.allocate(BUFFER_SIZE);
} else {
iNet = ByteBuffer.allocate(0);
iApp = ByteBuffer.allocate(BUFFER_SIZE); iApp = ByteBuffer.allocate(BUFFER_SIZE);
SSLEngineResult r = engine.unwrap(iNet, iApp);
hs = r.getHandshakeStatus();
verifySSLEngineResultStatus(r, side);
if (hs == SSLEngineResult.HandshakeStatus.FINISHED) {
log(side, "Handshake status is FINISHED, finish the loop");
endLoops = true;
}
} }
case NEED_WRAP -> {
List<DatagramPacket> packets = new ArrayList<>();
boolean finished = produceHandshakePackets(
engine, peerAddr, side, packets);
SSLEngineResult r = engine.unwrap(iNet, iApp); log(side, "Produced " + packets.size() + " packets");
SSLEngineResult.Status rs = r.getStatus(); for (DatagramPacket p : packets) {
hs = r.getHandshakeStatus(); socket.send(p);
if (rs == SSLEngineResult.Status.OK) { }
// OK
} else if (rs == SSLEngineResult.Status.BUFFER_OVERFLOW) {
log(side, "BUFFER_OVERFLOW, handshake status is " + hs);
// the client maximum fragment size config does not work? if (finished) {
throw new Exception("Buffer overflow: " + log(side, "Handshake status is FINISHED "
"incorrect client maximum fragment size"); + "after producing handshake packets, "
} else if (rs == SSLEngineResult.Status.BUFFER_UNDERFLOW) { + "finish the loop");
log(side, "BUFFER_UNDERFLOW, handshake status is " + hs); endLoops = true;
}
// bad packet, or the client maximum fragment size
// config does not work?
if (hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
throw new Exception("Buffer underflow: " +
"incorrect client maximum fragment size");
} // otherwise, ignore this packet
} else if (rs == SSLEngineResult.Status.CLOSED) {
throw new Exception(
"SSL engine closed, handshake status is " + hs);
} else {
throw new Exception("Can't reach here, result is " + rs);
} }
case NEED_TASK -> runDelegatedTasks(engine);
if (hs == SSLEngineResult.HandshakeStatus.FINISHED) { case NOT_HANDSHAKING -> {
log(side, "Handshake status is FINISHED, finish the loop"); log(side,
"Handshake status is NOT_HANDSHAKING, finish the loop");
endLoops = true; endLoops = true;
} }
} else if (hs == SSLEngineResult.HandshakeStatus.NEED_WRAP) { case FINISHED -> throw new Exception( "Unexpected status, " +
List<DatagramPacket> packets = new ArrayList<>(); "SSLEngine.getHandshakeStatus() shouldn't return FINISHED");
boolean finished = produceHandshakePackets( default -> throw new Exception("Can't reach here, " +
engine, peerAddr, side, packets); "handshake status is " + hs);
log(side, "Produced " + packets.size() + " packets");
for (DatagramPacket p : packets) {
socket.send(p);
}
if (finished) {
log(side, "Handshake status is FINISHED "
+ "after producing handshake packets, "
+ "finish the loop");
endLoops = true;
}
} else if (hs == SSLEngineResult.HandshakeStatus.NEED_TASK) {
runDelegatedTasks(engine);
} else if (hs == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
log(side,
"Handshake status is NOT_HANDSHAKING, finish the loop");
endLoops = true;
} else if (hs == SSLEngineResult.HandshakeStatus.FINISHED) {
throw new Exception(
"Unexpected status, SSLEngine.getHandshakeStatus() "
+ "shouldn't return FINISHED");
} else {
throw new Exception(
"Can't reach here, handshake status is " + hs);
} }
} }
@ -291,13 +270,39 @@ public class DTLSOverDatagram {
} }
} }
void verifySSLEngineResultStatus(SSLEngineResult r, String side) throws Exception {
SSLEngineResult.Status rs = r.getStatus();
SSLEngineResult.HandshakeStatus hs = r.getHandshakeStatus();
switch (rs) {
case OK -> log(side, "SSLEngineResult status OK");
case BUFFER_OVERFLOW -> {
log(side, "BUFFER_OVERFLOW, handshake status is " + hs);
// the client maximum fragment size config does not work?
throw new Exception("Buffer overflow: " +
"incorrect client maximum fragment size");
}
case BUFFER_UNDERFLOW -> {
log(side, "BUFFER_UNDERFLOW, handshake status is " + hs);
// bad packet, or the client maximum fragment size
// config does not work?
if (hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
throw new Exception("Buffer underflow: " +
"incorrect client maximum fragment size");
} // otherwise, ignore this packet
}
case CLOSED -> throw new Exception(
"SSL engine closed, handshake status is " + hs);
default -> throw new Exception("Can't reach here, result is " + rs);
}
}
// deliver application data // deliver application data
void deliverAppData(SSLEngine engine, DatagramSocket socket, void deliverAppData(SSLEngine engine, DatagramSocket socket,
ByteBuffer appData, SocketAddress peerAddr) throws Exception { ByteBuffer appData, SocketAddress peerAddr, String side) throws Exception {
// Note: have not consider the packet loses // Note: have not consider the packet loses
List<DatagramPacket> packets = List<DatagramPacket> packets =
produceApplicationPackets(engine, appData, peerAddr); produceApplicationPackets(engine, appData, peerAddr, side);
appData.flip(); appData.flip();
for (DatagramPacket p : packets) { for (DatagramPacket p : packets) {
socket.send(p); socket.send(p);
@ -344,7 +349,7 @@ public class DTLSOverDatagram {
if (--loops < 0) { if (--loops < 0) {
throw new RuntimeException( throw new RuntimeException(
"Too much loops to produce handshake packets"); "Too many loops to produce handshake packets");
} }
ByteBuffer oNet = ByteBuffer.allocate(32768); ByteBuffer oNet = ByteBuffer.allocate(32768);
@ -356,30 +361,9 @@ public class DTLSOverDatagram {
SSLEngineResult.HandshakeStatus hs = r.getHandshakeStatus(); SSLEngineResult.HandshakeStatus hs = r.getHandshakeStatus();
log(side, "----produce handshake packet(" + log(side, "----produce handshake packet(" +
loops + ", " + rs + ", " + hs + ")----"); loops + ", " + rs + ", " + hs + ")----");
if (rs == SSLEngineResult.Status.BUFFER_OVERFLOW) {
// the client maximum fragment size config does not work?
throw new Exception("Buffer overflow: " +
"incorrect server maximum fragment size");
} else if (rs == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
log(side,
"Produce handshake packets: BUFFER_UNDERFLOW occured");
log(side,
"Produce handshake packets: Handshake status: " + hs);
// bad packet, or the client maximum fragment size
// config does not work?
if (hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
throw new Exception("Buffer underflow: " +
"incorrect server maximum fragment size");
} // otherwise, ignore this packet
} else if (rs == SSLEngineResult.Status.CLOSED) {
throw new Exception("SSLEngine has closed");
} else if (rs == SSLEngineResult.Status.OK) {
// OK
} else {
throw new Exception("Can't reach here, result is " + rs);
}
// SSLEngineResult.Status.OK: verifySSLEngineResultStatus(r, side);
if (oNet.hasRemaining()) { if (oNet.hasRemaining()) {
byte[] ba = new byte[oNet.remaining()]; byte[] ba = new byte[oNet.remaining()];
oNet.get(ba); oNet.get(ba);
@ -396,24 +380,20 @@ public class DTLSOverDatagram {
boolean endInnerLoop = false; boolean endInnerLoop = false;
SSLEngineResult.HandshakeStatus nhs = hs; SSLEngineResult.HandshakeStatus nhs = hs;
while (!endInnerLoop) { while (!endInnerLoop) {
if (nhs == SSLEngineResult.HandshakeStatus.NEED_TASK) { switch (nhs) {
runDelegatedTasks(engine); case NEED_TASK -> runDelegatedTasks(engine);
} else if (nhs == SSLEngineResult.HandshakeStatus.NEED_UNWRAP || case NEED_UNWRAP, NEED_UNWRAP_AGAIN, NOT_HANDSHAKING -> {
nhs == SSLEngineResult.HandshakeStatus.NEED_UNWRAP_AGAIN || endInnerLoop = true;
nhs == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) { endLoops = true;
}
endInnerLoop = true; case NEED_WRAP -> endInnerLoop = true;
endLoops = true; case FINISHED -> throw new Exception(
} else if (nhs == SSLEngineResult.HandshakeStatus.NEED_WRAP) {
endInnerLoop = true;
} else if (nhs == SSLEngineResult.HandshakeStatus.FINISHED) {
throw new Exception(
"Unexpected status, SSLEngine.getHandshakeStatus() " "Unexpected status, SSLEngine.getHandshakeStatus() "
+ "shouldn't return FINISHED"); + "should not return FINISHED");
} else { default -> throw new Exception("Can't reach here, handshake status is "
throw new Exception("Can't reach here, handshake status is "
+ nhs); + nhs);
} }
nhs = engine.getHandshakeStatus(); nhs = engine.getHandshakeStatus();
} }
} }
@ -428,30 +408,15 @@ public class DTLSOverDatagram {
// produce application packets // produce application packets
List<DatagramPacket> produceApplicationPackets( List<DatagramPacket> produceApplicationPackets(
SSLEngine engine, ByteBuffer source, SSLEngine engine, ByteBuffer source,
SocketAddress socketAddr) throws Exception { SocketAddress socketAddr, String side) throws Exception {
List<DatagramPacket> packets = new ArrayList<>(); List<DatagramPacket> packets = new ArrayList<>();
ByteBuffer appNet = ByteBuffer.allocate(32768); ByteBuffer appNet = ByteBuffer.allocate(32768);
SSLEngineResult r = engine.wrap(source, appNet); SSLEngineResult r = engine.wrap(source, appNet);
appNet.flip(); appNet.flip();
SSLEngineResult.Status rs = r.getStatus(); verifySSLEngineResultStatus(r, side);
if (rs == SSLEngineResult.Status.BUFFER_OVERFLOW) {
// the client maximum fragment size config does not work?
throw new Exception("Buffer overflow: " +
"incorrect server maximum fragment size");
} else if (rs == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
// unlikely
throw new Exception("Buffer underflow during wraping");
} else if (rs == SSLEngineResult.Status.CLOSED) {
throw new Exception("SSLEngine has closed");
} else if (rs == SSLEngineResult.Status.OK) {
// OK
} else {
throw new Exception("Can't reach here, result is " + rs);
}
// SSLEngineResult.Status.OK:
if (appNet.hasRemaining()) { if (appNet.hasRemaining()) {
byte[] ba = new byte[appNet.remaining()]; byte[] ba = new byte[appNet.remaining()];
appNet.get(ba); appNet.get(ba);
@ -472,7 +437,7 @@ public class DTLSOverDatagram {
int offset = packet.getOffset(); int offset = packet.getOffset();
int length = packet.getLength(); int length = packet.getLength();
// Normally, this pakcet should be a handshake message // Normally, this packet should be a handshake message
// record. However, even if the underlying platform // record. However, even if the underlying platform
// splits the record more, we don't really worry about // splits the record more, we don't really worry about
// the improper packet loss because DTLS implementation // the improper packet loss because DTLS implementation
@ -490,12 +455,12 @@ public class DTLSOverDatagram {
if (data[offset + 4] == 0x00) { // plaintext if (data[offset + 4] == 0x00) { // plaintext
matched = matched =
(data[offset + 13] == handshakeType); (data[offset + 13] == handshakeType);
} else { // cipherext } else { // ciphertext
// The 1st ciphertext is a Finished message. // The 1st ciphertext is a Finished message.
// //
// If it is not proposed to loss the Finished // If it is not proposed to loss the Finished
// message, it is not necessary to check the // message, it is not necessary to check the
// following packets any mroe as a Finished // following packets any more as a Finished
// message is the last handshake message. // message is the last handshake message.
matched = (handshakeType == 20); matched = (handshakeType == 20);
} }
@ -540,8 +505,8 @@ public class DTLSOverDatagram {
SSLContext getDTLSContext() throws Exception { SSLContext getDTLSContext() throws Exception {
String passphrase = "passphrase"; String passphrase = "passphrase";
return SSLContextBuilder.builder() return SSLContextBuilder.builder()
.trustStore(KeyStoreUtils.loadKeyStore(trustFilename, passphrase)) .trustStore(KeyStoreUtils.loadKeyStore(TRUST_FILENAME, passphrase))
.keyStore(KeyStoreUtils.loadKeyStore(keyFilename, passphrase)) .keyStore(KeyStoreUtils.loadKeyStore(KEY_FILENAME, passphrase))
.kmfPassphrase(passphrase) .kmfPassphrase(passphrase)
.protocol("DTLS") .protocol("DTLS")
.build(); .build();
@ -559,17 +524,22 @@ public class DTLSOverDatagram {
} }
public final void runTest(DTLSOverDatagram testCase) throws Exception { public final void runTest(DTLSOverDatagram testCase) throws Exception {
try (DatagramSocket serverSocket = new DatagramSocket(); InetSocketAddress serverSocketAddress = new InetSocketAddress
DatagramSocket clientSocket = new DatagramSocket()) { (InetAddress.getLoopbackAddress(), 0);
InetSocketAddress clientSocketAddress = new InetSocketAddress
(InetAddress.getLoopbackAddress(), 0);
try (DatagramSocket serverSocket = new DatagramSocket(serverSocketAddress);
DatagramSocket clientSocket = new DatagramSocket(clientSocketAddress)) {
serverSocket.setSoTimeout(SOCKET_TIMEOUT); serverSocket.setSoTimeout(SOCKET_TIMEOUT);
clientSocket.setSoTimeout(SOCKET_TIMEOUT); clientSocket.setSoTimeout(SOCKET_TIMEOUT);
InetSocketAddress serverSocketAddr = new InetSocketAddress( InetSocketAddress serverSocketAddr = new InetSocketAddress(
InetAddress.getLocalHost(), serverSocket.getLocalPort()); InetAddress.getLoopbackAddress(), serverSocket.getLocalPort());
InetSocketAddress clientSocketAddr = new InetSocketAddress( InetSocketAddress clientSocketAddr = new InetSocketAddress(
InetAddress.getLocalHost(), clientSocket.getLocalPort()); InetAddress.getLoopbackAddress(), clientSocket.getLocalPort());
ExecutorService pool = Executors.newFixedThreadPool(2); ExecutorService pool = Executors.newFixedThreadPool(2);
Future<String> server, client; Future<String> server, client;
@ -611,19 +581,8 @@ public class DTLSOverDatagram {
} }
} }
final static class ServerCallable implements Callable<String> { record ServerCallable(DTLSOverDatagram testCase, DatagramSocket socket,
InetSocketAddress clientSocketAddr) implements Callable<String> {
private final DTLSOverDatagram testCase;
private final DatagramSocket socket;
private final InetSocketAddress clientSocketAddr;
ServerCallable(DTLSOverDatagram testCase, DatagramSocket socket,
InetSocketAddress clientSocketAddr) {
this.testCase = testCase;
this.socket = socket;
this.clientSocketAddr = clientSocketAddr;
}
@Override @Override
public String call() throws Exception { public String call() throws Exception {
@ -649,19 +608,8 @@ public class DTLSOverDatagram {
} }
} }
final static class ClientCallable implements Callable<String> { record ClientCallable(DTLSOverDatagram testCase, DatagramSocket socket,
InetSocketAddress serverSocketAddr) implements Callable<String> {
private final DTLSOverDatagram testCase;
private final DatagramSocket socket;
private final InetSocketAddress serverSocketAddr;
ClientCallable(DTLSOverDatagram testCase, DatagramSocket socket,
InetSocketAddress serverSocketAddr) {
this.testCase = testCase;
this.socket = socket;
this.serverSocketAddr = serverSocketAddr;
}
@Override @Override
public String call() throws Exception { public String call() throws Exception {
@ -687,7 +635,7 @@ public class DTLSOverDatagram {
} }
} }
final static void printHex(String prefix, ByteBuffer bb) { static void printHex(String prefix, ByteBuffer bb) {
synchronized (System.out) { synchronized (System.out) {
System.out.println(prefix); System.out.println(prefix);
@ -700,7 +648,7 @@ public class DTLSOverDatagram {
} }
} }
final static void printHex(String prefix, static void printHex(String prefix,
byte[] bytes, int offset, int length) { byte[] bytes, int offset, int length) {
synchronized (System.out) { synchronized (System.out) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -84,7 +84,7 @@ public class PacketLossRetransmission extends DTLSOverDatagram {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
isClient = args[0].equals("client"); isClient = args[0].equals("client");
handshakeType = Byte.valueOf(args[1]); handshakeType = Byte.parseByte(args[1]);
PacketLossRetransmission testCase = new PacketLossRetransmission(); PacketLossRetransmission testCase = new PacketLossRetransmission();
testCase.runTest(testCase); testCase.runTest(testCase);
@ -97,7 +97,7 @@ public class PacketLossRetransmission extends DTLSOverDatagram {
boolean finished = super.produceHandshakePackets( boolean finished = super.produceHandshakePackets(
engine, socketAddr, side, packets); engine, socketAddr, side, packets);
if (needPacketLoss && (!(isClient ^ engine.getUseClientMode()))) { if (needPacketLoss && (isClient == engine.getUseClientMode())) {
DatagramPacket packet = getPacket(packets, handshakeType); DatagramPacket packet = getPacket(packets, handshakeType);
if (packet != null) { if (packet != null) {
needPacketLoss = false; needPacketLoss = false;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -85,7 +85,7 @@ public class RespondToRetransmit extends DTLSOverDatagram {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
isClient = args[0].equals("client"); isClient = args[0].equals("client");
handshakeType = Byte.valueOf(args[1]); handshakeType = Byte.parseByte(args[1]);
RespondToRetransmit testCase = new RespondToRetransmit(); RespondToRetransmit testCase = new RespondToRetransmit();
testCase.runTest(testCase); testCase.runTest(testCase);
@ -98,7 +98,7 @@ public class RespondToRetransmit extends DTLSOverDatagram {
boolean finished = super.produceHandshakePackets( boolean finished = super.produceHandshakePackets(
engine, socketAddr, side, packets); engine, socketAddr, side, packets);
if (needPacketDuplicate && (!(isClient ^ engine.getUseClientMode()))) { if (needPacketDuplicate && (isClient == engine.getUseClientMode())) {
DatagramPacket packet = getPacket(packets, handshakeType); DatagramPacket packet = getPacket(packets, handshakeType);
if (packet != null) { if (packet != null) {
needPacketDuplicate = false; needPacketDuplicate = false;