Skip to content

Support underflow handling without thread sleep #701

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/main/java/com/rabbitmq/client/impl/nio/FrameBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,9 @@ private void handleProtocolVersionMismatch() throws IOException {
}
throw x;
}

//Indicates ssl underflow state - means that cipherBuffer should aggregate next chunks of bytes
public boolean isUnderflowHandlingEnabled() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;


/**
*
*/
Expand Down Expand Up @@ -176,11 +177,14 @@ void endWriteSequence() {

void prepareForReadSequence() throws IOException {
if(ssl) {
cipherIn.clear();
plainIn.clear();
if (!frameBuilder.isUnderflowHandlingEnabled()) {
cipherIn.clear();
cipherIn.flip();
}

cipherIn.flip();
plainIn.clear();
plainIn.flip();

} else {
NioHelper.read(channel, plainIn);
plainIn.flip();
Expand All @@ -189,6 +193,15 @@ void prepareForReadSequence() throws IOException {

boolean continueReading() throws IOException {
if(ssl) {
if (frameBuilder.isUnderflowHandlingEnabled()) {
int bytesRead = NioHelper.read(channel, cipherIn);
if (bytesRead == 0) {
return false;
} else {
cipherIn.flip();
return true;
}
}
if (!plainIn.hasRemaining() && !cipherIn.hasRemaining()) {
// need to try to read something
cipherIn.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;


/**
* Sub-class of {@link FrameBuilder} that unwraps crypted data from the network.
* @since 4.4.0
Expand All @@ -32,6 +33,8 @@ public class SslEngineFrameBuilder extends FrameBuilder {

private final ByteBuffer cipherBuffer;

private boolean isUnderflowHandlingEnabled = false;

public SslEngineFrameBuilder(SSLEngine sslEngine, ByteBuffer plainIn, ByteBuffer cipherIn, ReadableByteChannel channel) {
super(channel, plainIn);
this.sslEngine = sslEngine;
Expand All @@ -40,12 +43,14 @@ public SslEngineFrameBuilder(SSLEngine sslEngine, ByteBuffer plainIn, ByteBuffer

@Override
protected boolean somethingToRead() throws IOException {
if (applicationBuffer.hasRemaining()) {
if (applicationBuffer.hasRemaining() && !isUnderflowHandlingEnabled) {
return true;
} else {
applicationBuffer.clear();

while (true) {
boolean underflowHandling = false;

try {
SSLEngineResult result = sslEngine.unwrap(cipherBuffer, applicationBuffer);
switch (result.getStatus()) {
case OK:
Expand All @@ -59,19 +64,23 @@ protected boolean somethingToRead() throws IOException {
throw new SSLException("buffer overflow in read");
case BUFFER_UNDERFLOW:
cipherBuffer.compact();
int read = NioHelper.read(channel, cipherBuffer);
if (read == 0) {
return false;
}
cipherBuffer.flip();
break;
underflowHandling = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, removing some reading logic and putting it in the class that was already doing, nice.

return false;
case CLOSED:
throw new SSLException("closed in read");
default:
throw new IllegalStateException("Invalid SSL status: " + result.getStatus());
}
}
} finally {
isUnderflowHandlingEnabled = underflowHandling;
}

return false;
}
}

@Override
public boolean isUnderflowHandlingEnabled() {
return isUnderflowHandlingEnabled;
}
}