src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java
Print this page
8167680 DTLS implementation bugs
*** 1,7 ****
/*
! * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 992,1011 ****
fatal(Alerts.alert_unexpected_message, ioe);
}
// plainText should never be null for TLS protocols
HandshakeStatus hsStatus = null;
! if (!isDTLS || plainText != null) {
hsStatus = processInputRecord(plainText, appData, offset, length);
}
if (hsStatus == null) {
hsStatus = getHSStatus(null);
}
if (plainText == null) {
! plainText = new Plaintext();
}
plainText.handshakeStatus = hsStatus;
return plainText;
}
--- 992,1026 ----
fatal(Alerts.alert_unexpected_message, ioe);
}
// plainText should never be null for TLS protocols
HandshakeStatus hsStatus = null;
! if (plainText == Plaintext.PLAINTEXT_NULL) {
! // Only happens for DTLS protocols.
! //
! // Received a retransmitted flight, and need to retransmit the
! // previous delivered handshake flight messages.
! if (enableRetransmissions) {
! if (debug != null && Debug.isOn("verbose")) {
! Debug.log(
! "Retransmit the previous handshake flight messages.");
! }
!
! synchronized (this) {
! outputRecord.launchRetransmission();
! }
! } // Otherwise, discard the retransmitted flight.
! } else if (!isDTLS || plainText != null) {
hsStatus = processInputRecord(plainText, appData, offset, length);
}
if (hsStatus == null) {
hsStatus = getHSStatus(null);
}
if (plainText == null) {
! plainText = Plaintext.PLAINTEXT_NULL;
}
plainText.handshakeStatus = hsStatus;
return plainText;
}
*** 1376,1386 ****
Ciphertext ciphertext = null;
try {
// Acquire the buffered to-be-delivered records or retransmissions.
//
// May have buffered records, or need retransmission if handshaking.
! if (!outputRecord.isEmpty() || (handshaker != null)) {
ciphertext = outputRecord.acquireCiphertext(netData);
}
if ((ciphertext == null) && (appData != null)) {
ciphertext = outputRecord.encode(
--- 1391,1402 ----
Ciphertext ciphertext = null;
try {
// Acquire the buffered to-be-delivered records or retransmissions.
//
// May have buffered records, or need retransmission if handshaking.
! if (!outputRecord.isEmpty() ||
! (enableRetransmissions && handshaker != null)) {
ciphertext = outputRecord.acquireCiphertext(netData);
}
if ((ciphertext == null) && (appData != null)) {
ciphertext = outputRecord.encode(
*** 1401,1417 ****
return Ciphertext.CIPHERTEXT_NULL;
}
HandshakeStatus hsStatus = null;
Ciphertext.RecordType recordType = ciphertext.recordType;
! if ((handshaker != null) &&
! (recordType.contentType == Record.ct_handshake) &&
(recordType.handshakeType == HandshakeMessage.ht_finished) &&
! handshaker.isDone() && outputRecord.isEmpty()) {
hsStatus = finishHandshake();
connectionState = cs_DATA;
} // Otherwise, the followed call to getHSStatus() will help.
/*
* We only need to check the sequence number state for
* non-handshaking record.
--- 1417,1456 ----
return Ciphertext.CIPHERTEXT_NULL;
}
HandshakeStatus hsStatus = null;
Ciphertext.RecordType recordType = ciphertext.recordType;
! if ((recordType.contentType == Record.ct_handshake) &&
(recordType.handshakeType == HandshakeMessage.ht_finished) &&
! outputRecord.isEmpty()) {
+ if (handshaker == null) {
+ hsStatus = HandshakeStatus.FINISHED;
+ } else if (handshaker.isDone()) {
hsStatus = finishHandshake();
connectionState = cs_DATA;
+
+ // Retransmit the last flight twice.
+ //
+ // The application data transactions may begin immediately
+ // after the last flight. If the last flight get lost, the
+ // application data may be discarded accordingly. As could
+ // be an issue for some applications. This impact can be
+ // mitigated by sending the last fligth twice.
+ if (isDTLS && enableRetransmissions) {
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log(
+ "Retransmit the last flight messages.");
+ }
+
+ synchronized (this) {
+ outputRecord.launchRetransmission();
+ }
+
+ hsStatus = HandshakeStatus.NEED_WRAP;
+ }
+ }
} // Otherwise, the followed call to getHSStatus() will help.
/*
* We only need to check the sequence number state for
* non-handshaking record.