Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,6 @@
*/
protected Thread mDecodeThread = null;

/**
* Captured error state
*/
protected SSLException mPendingError = null;

/**
* Instantiates a new handler
*
Expand Down Expand Up @@ -207,6 +202,15 @@ protected void receive_loop(NextFilter next, IoBuffer message) throws SSLExcepti
}
}

// The message is null when we have had an exception
if (message==null) {
if ( mPendingError != null ) {
throw mPendingError;
} else {
throw new IllegalStateException("closed");
}
}

IoBuffer source = message;

// No need to fo for another loop if the message is empty
Expand Down Expand Up @@ -450,26 +454,6 @@ synchronized protected boolean write_user_loop(NextFilter next, WriteRequest req
return false;
}

/**
* Attempts to generate a handshake message and write the data to the IoSession
*
* @param next
*
* @return {@code true} if a message was generated and written
*
* @throws SSLException
*/
synchronized protected boolean write_handshake(NextFilter next) throws SSLException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("{} write_handshake() - internal", toString());
}

IoBuffer source = ZERO;
IoBuffer dest = allocate_encode_buffer(source.remaining());

return write_handshake_loop(next, source, dest);
}

/**
* Attempts to generate a handshake message and write the data to the IoSession.
* <p>
Expand All @@ -484,6 +468,7 @@ synchronized protected boolean write_handshake(NextFilter next) throws SSLExcept
*
* @throws SSLException
*/
@Override
@SuppressWarnings("incomplete-switch")
protected boolean write_handshake_loop(NextFilter next, IoBuffer source, IoBuffer dest) throws SSLException {
if (mOutboundClosing && mEngine.isOutboundDone()) {
Expand Down Expand Up @@ -675,26 +660,6 @@ synchronized public void close(NextFilter next, boolean linger) throws SSLExcept
}
}

/**
* Process the pending error and loop to send the associated alert if we have some.
*
* @param next The next filter in the chain
* @throws SSLException The rethrown pending error
*/
synchronized protected void throw_pending_error(NextFilter next) throws SSLException {
SSLException sslException = mPendingError;

if (sslException != null) {
// Loop to send back the alert messages
receive_loop(next, null);

mPendingError = null;

// And finally rethrow the exception
throw sslException;
}
}

/**
* Store any error we've got during the handshake or message handling
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLException;

import java.nio.BufferOverflowException;
import java.util.ArrayList;
import java.util.Deque;
Expand Down Expand Up @@ -69,7 +70,7 @@
/**
* Enable asynchronous tasks. Default to false.
*/
static protected final boolean ENABLE_ASYNC_TASKS = false;
static protected final boolean ENABLE_ASYNC_TASKS = true;

/**
* Indicates whether the first handshake was completed
Expand Down Expand Up @@ -111,11 +112,6 @@
*/
protected final Deque<FilterEvent> mEventQueue = new ConcurrentLinkedDeque<>();

/**
* Captured error state
*/
protected SSLException mPendingError = null;

/**
* Instantiates a new handler
*
Expand Down Expand Up @@ -237,10 +233,19 @@ protected void receive_loop(NextFilter next, IoBuffer message) throws SSLExcepti
throw new IllegalStateException("closed");
}
}

// The message is null when we have had an exception
if (message==null) {
if ( mPendingError != null ) {
throw mPendingError;
} else {
throw new IllegalStateException("closed");
}
}

IoBuffer source = message;

// No need to fo for another loop if the message is empty
// No need to go for another loop if the message is empty
if (source.remaining() == 0) {
return;
}
Expand Down Expand Up @@ -490,26 +495,6 @@ synchronized protected boolean write_loop(NextFilter next, WriteRequest request)
return false;
}

/**
* Attempts to generate a handshake message and write the data to the IoSession
*
* @param next
*
* @return {@code true} if a message was generated and written
*
* @throws SSLException
*/
synchronized protected boolean write_handshake(NextFilter next) throws SSLException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("{} write_handshake() - internal", toString());
}

IoBuffer source = ZERO;
IoBuffer dest = allocate_encode_buffer(source.remaining());

return write_handshake_loop(next, source, dest);
}

/**
* Attempts to generate a handshake message and write the data to the IoSession.
* <p>
Expand All @@ -524,6 +509,7 @@ synchronized protected boolean write_handshake(NextFilter next) throws SSLExcept
*
* @throws SSLException
*/
@Override
@SuppressWarnings("incomplete-switch")
protected boolean write_handshake_loop(NextFilter next, IoBuffer source, IoBuffer dest) throws SSLException {
if (mOutboundClosing && mEngine.isOutboundDone()) {
Expand Down Expand Up @@ -728,26 +714,6 @@ synchronized protected void close_start(NextFilter next, boolean linger) throws
}
}

/**
* Process the pending error and loop to send the associated alert if we have some.
*
* @param next The next filter in the chain
* @throws SSLException The rethrown pending error
*/
synchronized protected void throw_pending_error(NextFilter next) throws SSLException {
SSLException sslException = mPendingError;
if (sslException != null) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("{} throw_pending_error() - throwing pending error");
}
// Loop to send back the alert messages
receive_loop(next, null);
mPendingError = null;
// And finally rethrow the exception
throw sslException;
}
}

/**
* Store any error we've got during the handshake or message handling
*
Expand Down
66 changes: 66 additions & 0 deletions mina-core/src/main/java/org/apache/mina/filter/ssl/SslHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLEngineResult.HandshakeStatus;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.filterchain.IoFilter.NextFilter;
Expand Down Expand Up @@ -93,6 +94,11 @@ public abstract class SslHandler {
*/
protected IoBuffer mDecodeBuffer;

/**
* Captured error state
*/
protected SSLException mPendingError = null;

/**
* Instantiates a new handler
*
Expand Down Expand Up @@ -176,6 +182,22 @@ public SslHandler(SSLEngine p, Executor e, IoSession s) {
*/
abstract public void close(NextFilter next, final boolean linger) throws SSLException;

/**
* Attempts to generate a handshake message and write the data to the IoSession.
* <p>
* If FAST_HANDSHAKE is enabled, this method will recursively loop in order to
* combine multiple messages into one buffer.
*
* @param next
* @param source
* @param dest
*
* @return {@code true} if a message was generated and written
*
* @throws SSLException
*/
protected abstract boolean write_handshake_loop(NextFilter next, IoBuffer source, IoBuffer dest) throws SSLException;

/**
* {@inheritDoc}
*/
Expand Down Expand Up @@ -281,4 +303,48 @@ protected IoBuffer allocate_app_buffer(int estimate) {
int packets = 1 + (estimate / session.getPacketBufferSize());
return IoBuffer.allocate(packets * session.getApplicationBufferSize());
}


/**
* Process the pending error and loop to send the associated alert if we have some.
*
* @param next The next filter in the chain
* @throws SSLException The rethrown pending error
*/
synchronized protected void throw_pending_error(NextFilter next) throws SSLException {
SSLException sslException = mPendingError;

if (sslException != null) {
// Errors are fatal: the pending error stays set and is rethrown on every subsequent call.
if (mEngine.isInboundDone() && mEngine.getHandshakeStatus() == HandshakeStatus.NEED_WRAP) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("{} throw_pending_error() - handshake needs wrap, invoking write", toString());
}

write_handshake(next);
}

throw sslException;
}
}

/**
* Attempts to generate a handshake message and write the data to the IoSession
*
* @param next
*
* @return {@code true} if a message was generated and written
*
* @throws SSLException
*/
synchronized protected boolean write_handshake(NextFilter next) throws SSLException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("{} write_handshake() - internal", toString());
}

IoBuffer source = ZERO;
IoBuffer dest = allocate_encode_buffer(source.remaining());

return write_handshake_loop(next, source, dest);
}
}
Loading
Loading