Skip to content

Commit acd581e

Browse files
fitzsimgnu-andrew
authored andcommitted
8374557: Enhance TLS connection handling
Reviewed-by: andrew, abakhtin Backport-of: 97070420c703271ceb3f0ed567a7cce1b07921b2
1 parent 0fb5192 commit acd581e

2 files changed

Lines changed: 23 additions & 25 deletions

File tree

src/java.net.http/share/classes/jdk/internal/net/http/common/SSLFlowDelegate.java

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2026, 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
@@ -268,7 +268,7 @@ final class Reader extends SubscriberWrapper implements FlowTube.TubeSubscriber
268268

269269
final SequentialScheduler scheduler;
270270
volatile ByteBuffer readBuf;
271-
volatile boolean completing;
271+
boolean completing;
272272
final Object readBufferLock = new Object();
273273
final Logger debugr = Utils.getDebugLogger(this::dbgString, Utils.DEBUG);
274274

@@ -296,6 +296,11 @@ protected SchedulingAction enterScheduling() {
296296
return enterReadScheduling();
297297
}
298298

299+
@Override
300+
public boolean closing() {
301+
return closeNotifyReceived();
302+
}
303+
299304
public final String dbgString() {
300305
return "SSL Reader(" + tubeName + ")";
301306
}
@@ -485,7 +490,7 @@ else if (this.completing) {
485490
if (result.handshaking()) {
486491
handshaking = true;
487492
if (debugr.on()) debugr.log("handshaking");
488-
if (doHandshake(result, READER)) continue; // need unwrap
493+
if (doHandshake(result.handshakeStatus(), READER)) continue; // need unwrap
489494
else break; // doHandshake will have triggered the write scheduler if necessary
490495
} else {
491496
if (trySetALPN()) {
@@ -525,6 +530,7 @@ else if (this.completing) {
525530

526531
private volatile Status lastUnwrapStatus;
527532
EngineResult unwrapBuffer(ByteBuffer src) throws IOException {
533+
assert Thread.holdsLock(readBufferLock);
528534
ByteBuffer dst = getAppBuffer();
529535
int len = src.remaining();
530536
while (true) {
@@ -548,6 +554,8 @@ EngineResult unwrapBuffer(ByteBuffer src) throws IOException {
548554
break;
549555
case CLOSED:
550556
assert dst.position() == 0;
557+
src.position(src.limit());
558+
completing = true;
551559
return doClosure(new EngineResult(sslResult));
552560
case BUFFER_UNDERFLOW:
553561
// handled implicitly by compaction/reallocation of readBuf
@@ -808,7 +816,7 @@ private void processData() {
808816
boolean handshaking = false;
809817
if (result.handshaking()) {
810818
if (debugw.on()) debugw.log("handshaking");
811-
doHandshake(result, WRITER); // ok to ignore return
819+
doHandshake(result.handshakeStatus(), WRITER); // ok to ignore return
812820
handshaking = true;
813821
} else {
814822
if (trySetALPN()) {
@@ -1065,14 +1073,14 @@ private void resumeActivity() {
10651073
return (current & HANDSHAKING);
10661074
};
10671075

1068-
private boolean doHandshake(EngineResult r, int caller) {
1076+
private boolean doHandshake(HandshakeStatus handshakeStatus, int caller) {
10691077
// unconditionally sets the HANDSHAKING bit, while preserving task bits
10701078
handshakeState.getAndAccumulate(0, (current, unused) -> HANDSHAKING | (current & TASK_BITS));
10711079
if (stateList != null && debug.on()) {
1072-
stateList.add(r.handshakeStatus().toString());
1080+
stateList.add(handshakeStatus.toString());
10731081
stateList.add(Integer.toString(caller));
10741082
}
1075-
switch (r.handshakeStatus()) {
1083+
switch (handshakeStatus) {
10761084
case NEED_TASK:
10771085
int s = handshakeState.accumulateAndGet(0, REQUEST_OR_DO_TASKS);
10781086
if ((s & REQUESTING_TASKS) > 0) { // someone else is or will do tasks
@@ -1100,7 +1108,7 @@ private boolean doHandshake(EngineResult r, int caller) {
11001108
break;
11011109
default:
11021110
throw new InternalError("Unexpected handshake status:"
1103-
+ r.handshakeStatus());
1111+
+ handshakeStatus);
11041112
}
11051113
return true;
11061114
}
@@ -1157,30 +1165,20 @@ boolean trySetALPN() {
11571165
return false;
11581166
}
11591167

1160-
// FIXME: acknowledge a received CLOSE request from peer
11611168
EngineResult doClosure(EngineResult r) throws IOException {
11621169
if (debug.on())
11631170
debug.log("doClosure(%s): %s [isOutboundDone: %s, isInboundDone: %s]",
11641171
r.result, engine.getHandshakeStatus(),
11651172
engine.isOutboundDone(), engine.isInboundDone());
1173+
if (debug.on()) debug.log("doClosure: close_notify received");
1174+
close_notify_received = true;
1175+
engine.closeOutbound();
11661176
if (engine.getHandshakeStatus() == HandshakeStatus.NEED_WRAP) {
11671177
// we have received TLS close_notify and need to send
11681178
// an acknowledgement back. We're calling doHandshake
11691179
// to finish the close handshake.
1170-
if (engine.isInboundDone() && !engine.isOutboundDone()) {
1171-
if (debug.on()) debug.log("doClosure: close_notify received");
1172-
close_notify_received = true;
1173-
if (!writer.scheduler.isStopped()) {
1174-
doHandshake(r, READER);
1175-
} else {
1176-
// We have received closed notify, but we
1177-
// won't be able to send the acknowledgement.
1178-
// Nothing more will come from the socket either,
1179-
// so mark the reader as completed.
1180-
synchronized (reader.readBufferLock) {
1181-
reader.completing = true;
1182-
}
1183-
}
1180+
if (!writer.scheduler.isStopped()) {
1181+
doHandshake(HandshakeStatus.NEED_WRAP, READER);
11841182
}
11851183
}
11861184
return r;

src/java.net.http/share/classes/jdk/internal/net/http/common/SubscriberWrapper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2026, 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
@@ -457,7 +457,7 @@ public void addData(ByteBuffer l) {
457457
}
458458

459459
void checkCompletion() {
460-
if (downstreamCompleted || !upstreamCompleted) {
460+
if (downstreamCompleted || (!upstreamCompleted && !completionAcknowledged)) {
461461
return;
462462
}
463463
if (!outputQ.isEmpty()) {

0 commit comments

Comments
 (0)