* Another workaround for 'missing algorithm' error in SSLEngine
* Made handshaking non-volatile
This commit is contained in:
parent
87cd22b5fd
commit
580f6f2284
@ -124,8 +124,8 @@ public class SslHandler extends FrameDecoder {
|
|||||||
private final boolean startTls;
|
private final boolean startTls;
|
||||||
|
|
||||||
final Object handshakeLock = new Object();
|
final Object handshakeLock = new Object();
|
||||||
private volatile boolean needsFirstHandshake = true;
|
private boolean initialHandshake;
|
||||||
private volatile boolean handshaking;
|
private boolean handshaking;
|
||||||
private volatile boolean handshaken;
|
private volatile boolean handshaken;
|
||||||
private volatile ChannelFuture handshakeFuture;
|
private volatile ChannelFuture handshakeFuture;
|
||||||
|
|
||||||
@ -275,6 +275,7 @@ public class SslHandler extends FrameDecoder {
|
|||||||
return this.handshakeFuture;
|
return this.handshakeFuture;
|
||||||
} else {
|
} else {
|
||||||
engine.beginHandshake();
|
engine.beginHandshake();
|
||||||
|
runDelegatedTasks();
|
||||||
handshakeFuture = this.handshakeFuture = newHandshakeFuture(channel);
|
handshakeFuture = this.handshakeFuture = newHandshakeFuture(channel);
|
||||||
handshaking = true;
|
handshaking = true;
|
||||||
}
|
}
|
||||||
@ -438,11 +439,7 @@ public class SslHandler extends FrameDecoder {
|
|||||||
|
|
||||||
SSLEngineResult result;
|
SSLEngineResult result;
|
||||||
try {
|
try {
|
||||||
if (handshaking || needsFirstHandshake) {
|
synchronized (handshakeLock) {
|
||||||
synchronized (handshakeLock) {
|
|
||||||
result = engine.wrap(outAppBuf, outNetBuf);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result = engine.wrap(outAppBuf, outNetBuf);
|
result = engine.wrap(outAppBuf, outNetBuf);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@ -504,9 +501,7 @@ public class SslHandler extends FrameDecoder {
|
|||||||
}
|
}
|
||||||
} catch (SSLException e) {
|
} catch (SSLException e) {
|
||||||
success = false;
|
success = false;
|
||||||
if (handshaking) {
|
setHandshakeFailure(channel, e);
|
||||||
setHandshakeFailure(channel, e);
|
|
||||||
}
|
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
bufferPool.release(outNetBuf);
|
bufferPool.release(outNetBuf);
|
||||||
@ -574,11 +569,7 @@ public class SslHandler extends FrameDecoder {
|
|||||||
SSLEngineResult result;
|
SSLEngineResult result;
|
||||||
try {
|
try {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (handshaking || needsFirstHandshake) {
|
synchronized (handshakeLock) {
|
||||||
synchronized (handshakeLock) {
|
|
||||||
result = engine.wrap(EMPTY_BUFFER, outNetBuf);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result = engine.wrap(EMPTY_BUFFER, outNetBuf);
|
result = engine.wrap(EMPTY_BUFFER, outNetBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,7 +591,12 @@ public class SslHandler extends FrameDecoder {
|
|||||||
runDelegatedTasks();
|
runDelegatedTasks();
|
||||||
break;
|
break;
|
||||||
case NEED_UNWRAP:
|
case NEED_UNWRAP:
|
||||||
unwrap(ctx, channel, ChannelBuffers.EMPTY_BUFFER, 0, 0);
|
if (!Thread.holdsLock(handshakeLock)) {
|
||||||
|
// unwrap shouldn't be called when this method was
|
||||||
|
// called by unwrap - unwrap will keep running after
|
||||||
|
// this method returns.
|
||||||
|
unwrap(ctx, channel, ChannelBuffers.EMPTY_BUFFER, 0, 0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case NOT_HANDSHAKING:
|
case NOT_HANDSHAKING:
|
||||||
case NEED_WRAP:
|
case NEED_WRAP:
|
||||||
@ -616,9 +612,7 @@ public class SslHandler extends FrameDecoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SSLException e) {
|
} catch (SSLException e) {
|
||||||
if (handshaking) {
|
setHandshakeFailure(channel, e);
|
||||||
setHandshakeFailure(channel, e);
|
|
||||||
}
|
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
bufferPool.release(outNetBuf);
|
bufferPool.release(outNetBuf);
|
||||||
@ -636,44 +630,55 @@ public class SslHandler extends FrameDecoder {
|
|||||||
ByteBuffer outAppBuf = bufferPool.acquire();
|
ByteBuffer outAppBuf = bufferPool.acquire();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
boolean needsWrap = false;
|
||||||
loop:
|
loop:
|
||||||
for (;;) {
|
for (;;) {
|
||||||
SSLEngineResult result;
|
SSLEngineResult result;
|
||||||
if (handshaking || needsFirstHandshake) {
|
synchronized (handshakeLock) {
|
||||||
synchronized (handshakeLock) {
|
if (initialHandshake && !engine.getUseClientMode() &&
|
||||||
|
!engine.isInboundDone() && !engine.isOutboundDone()) {
|
||||||
|
handshake(channel);
|
||||||
|
initialHandshake = false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
result = engine.unwrap(inNetBuf, outAppBuf);
|
result = engine.unwrap(inNetBuf, outAppBuf);
|
||||||
|
} catch (SSLException e) {
|
||||||
|
System.err.println(engine.getUseClientMode());
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
result = engine.unwrap(inNetBuf, outAppBuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (result.getHandshakeStatus()) {
|
switch (result.getHandshakeStatus()) {
|
||||||
case NEED_UNWRAP:
|
case NEED_UNWRAP:
|
||||||
if (inNetBuf.hasRemaining()) {
|
if (inNetBuf.hasRemaining()) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
|
case NEED_WRAP:
|
||||||
|
wrapNonAppData(ctx, channel);
|
||||||
break;
|
break;
|
||||||
} else {
|
case NEED_TASK:
|
||||||
|
runDelegatedTasks();
|
||||||
|
break;
|
||||||
|
case FINISHED:
|
||||||
|
setHandshakeSuccess(channel);
|
||||||
|
needsWrap = true;
|
||||||
break loop;
|
break loop;
|
||||||
|
case NOT_HANDSHAKING:
|
||||||
|
needsWrap = true;
|
||||||
|
break loop;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Unknown handshake status: " +
|
||||||
|
result.getHandshakeStatus());
|
||||||
}
|
}
|
||||||
case NEED_WRAP:
|
|
||||||
wrapNonAppData(ctx, channel);
|
|
||||||
break;
|
|
||||||
case NEED_TASK:
|
|
||||||
runDelegatedTasks();
|
|
||||||
break;
|
|
||||||
case FINISHED:
|
|
||||||
setHandshakeSuccess(channel);
|
|
||||||
wrap(ctx, channel);
|
|
||||||
break loop;
|
|
||||||
case NOT_HANDSHAKING:
|
|
||||||
wrap(ctx, channel);
|
|
||||||
break loop;
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Unknown handshake status: " +
|
|
||||||
result.getHandshakeStatus());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (needsWrap) {
|
||||||
|
wrap(ctx, channel);
|
||||||
|
}
|
||||||
|
|
||||||
outAppBuf.flip();
|
outAppBuf.flip();
|
||||||
|
|
||||||
if (outAppBuf.hasRemaining()) {
|
if (outAppBuf.hasRemaining()) {
|
||||||
@ -684,9 +689,7 @@ public class SslHandler extends FrameDecoder {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (SSLException e) {
|
} catch (SSLException e) {
|
||||||
if (handshaking) {
|
setHandshakeFailure(channel, e);
|
||||||
setHandshakeFailure(channel, e);
|
|
||||||
}
|
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
bufferPool.release(outAppBuf);
|
bufferPool.release(outAppBuf);
|
||||||
@ -694,13 +697,20 @@ public class SslHandler extends FrameDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void runDelegatedTasks() {
|
private void runDelegatedTasks() {
|
||||||
Runnable task;
|
for (;;) {
|
||||||
while ((task = engine.getDelegatedTask()) != null) {
|
final Runnable task;
|
||||||
final Runnable t = task;
|
synchronized (handshakeLock) {
|
||||||
|
task = engine.getDelegatedTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (task == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
delegatedTaskExecutor.execute(new Runnable() {
|
delegatedTaskExecutor.execute(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
synchronized (handshakeLock) {
|
synchronized (handshakeLock) {
|
||||||
t.run();
|
task.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -711,7 +721,6 @@ public class SslHandler extends FrameDecoder {
|
|||||||
synchronized (handshakeLock) {
|
synchronized (handshakeLock) {
|
||||||
handshaking = false;
|
handshaking = false;
|
||||||
handshaken = true;
|
handshaken = true;
|
||||||
needsFirstHandshake = false; // Will not set to true again
|
|
||||||
|
|
||||||
if (handshakeFuture == null) {
|
if (handshakeFuture == null) {
|
||||||
handshakeFuture = newHandshakeFuture(channel);
|
handshakeFuture = newHandshakeFuture(channel);
|
||||||
@ -723,6 +732,9 @@ public class SslHandler extends FrameDecoder {
|
|||||||
|
|
||||||
private void setHandshakeFailure(Channel channel, SSLException cause) {
|
private void setHandshakeFailure(Channel channel, SSLException cause) {
|
||||||
synchronized (handshakeLock) {
|
synchronized (handshakeLock) {
|
||||||
|
if (!handshaking) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
handshaking = false;
|
handshaking = false;
|
||||||
handshaken = false;
|
handshaken = false;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user