Skip to content

Commit ba69698

Browse files
author
yandryakov
committed
support underflow handling without thread sleep
1 parent 281b679 commit ba69698

File tree

2 files changed

+37
-14
lines changed

2 files changed

+37
-14
lines changed

src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerState.java

+20-4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import java.nio.ByteBuffer;
2727
import java.nio.channels.SelectionKey;
2828
import java.nio.channels.SocketChannel;
29+
import java.util.concurrent.atomic.AtomicBoolean;
30+
2931

3032
/**
3133
*
@@ -70,6 +72,8 @@ public class SocketChannelFrameHandlerState {
7072

7173
final FrameBuilder frameBuilder;
7274

75+
private final AtomicBoolean isUnderflowHandlingEnabled = new AtomicBoolean(false);
76+
7377
public SocketChannelFrameHandlerState(SocketChannel channel, NioLoopContext nioLoopsState, NioParams nioParams, SSLEngine sslEngine) {
7478
this.channel = channel;
7579
this.readSelectorState = nioLoopsState.readSelectorState;
@@ -105,7 +109,7 @@ public SocketChannelFrameHandlerState(SocketChannel channel, NioLoopContext nioL
105109
this.outputStream = new DataOutputStream(
106110
new SslEngineByteBufferOutputStream(sslEngine, plainOut, cipherOut, channel)
107111
);
108-
this.frameBuilder = new SslEngineFrameBuilder(sslEngine, plainIn, cipherIn, channel);
112+
this.frameBuilder = new SslEngineFrameBuilder(sslEngine, plainIn, cipherIn, channel, isUnderflowHandlingEnabled);
109113
}
110114

111115
}
@@ -176,11 +180,14 @@ void endWriteSequence() {
176180

177181
void prepareForReadSequence() throws IOException {
178182
if(ssl) {
179-
cipherIn.clear();
180-
plainIn.clear();
183+
if (!isUnderflowHandlingEnabled.get()) {
184+
cipherIn.clear();
185+
cipherIn.flip();
186+
}
181187

182-
cipherIn.flip();
188+
plainIn.clear();
183189
plainIn.flip();
190+
184191
} else {
185192
NioHelper.read(channel, plainIn);
186193
plainIn.flip();
@@ -189,6 +196,15 @@ void prepareForReadSequence() throws IOException {
189196

190197
boolean continueReading() throws IOException {
191198
if(ssl) {
199+
if (isUnderflowHandlingEnabled.get()) {
200+
int bytesRead = NioHelper.read(channel, cipherIn);
201+
if (bytesRead == 0) {
202+
return false;
203+
} else {
204+
cipherIn.flip();
205+
return true;
206+
}
207+
}
192208
if (!plainIn.hasRemaining() && !cipherIn.hasRemaining()) {
193209
// need to try to read something
194210
cipherIn.clear();

src/main/java/com/rabbitmq/client/impl/nio/SslEngineFrameBuilder.java

+17-10
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.io.IOException;
2222
import java.nio.ByteBuffer;
2323
import java.nio.channels.ReadableByteChannel;
24+
import java.util.concurrent.atomic.AtomicBoolean;
25+
2426

2527
/**
2628
* Sub-class of {@link FrameBuilder} that unwraps crypted data from the network.
@@ -32,20 +34,25 @@ public class SslEngineFrameBuilder extends FrameBuilder {
3234

3335
private final ByteBuffer cipherBuffer;
3436

35-
public SslEngineFrameBuilder(SSLEngine sslEngine, ByteBuffer plainIn, ByteBuffer cipherIn, ReadableByteChannel channel) {
37+
private final AtomicBoolean isUnderflowHandlingEnabled;
38+
39+
public SslEngineFrameBuilder(SSLEngine sslEngine, ByteBuffer plainIn, ByteBuffer cipherIn, ReadableByteChannel channel, final AtomicBoolean isUnderflowHandlingEnabled) {
3640
super(channel, plainIn);
3741
this.sslEngine = sslEngine;
3842
this.cipherBuffer = cipherIn;
43+
this.isUnderflowHandlingEnabled = isUnderflowHandlingEnabled;
3944
}
4045

4146
@Override
4247
protected boolean somethingToRead() throws IOException {
43-
if (applicationBuffer.hasRemaining()) {
48+
if (applicationBuffer.hasRemaining() && !isUnderflowHandlingEnabled.get()) {
4449
return true;
4550
} else {
4651
applicationBuffer.clear();
4752

48-
while (true) {
53+
boolean underflowHandling = false;
54+
55+
try {
4956
SSLEngineResult result = sslEngine.unwrap(cipherBuffer, applicationBuffer);
5057
switch (result.getStatus()) {
5158
case OK:
@@ -59,18 +66,18 @@ protected boolean somethingToRead() throws IOException {
5966
throw new SSLException("buffer overflow in read");
6067
case BUFFER_UNDERFLOW:
6168
cipherBuffer.compact();
62-
int read = NioHelper.read(channel, cipherBuffer);
63-
if (read == 0) {
64-
return false;
65-
}
66-
cipherBuffer.flip();
67-
break;
69+
underflowHandling = true;
70+
return false;
6871
case CLOSED:
6972
throw new SSLException("closed in read");
7073
default:
7174
throw new IllegalStateException("Invalid SSL status: " + result.getStatus());
72-
}
75+
}
76+
} finally {
77+
isUnderflowHandlingEnabled.set(underflowHandling);
7378
}
79+
80+
return false;
7481
}
7582
}
7683

0 commit comments

Comments
 (0)