This is an automated email from the ASF dual-hosted git repository. elecharny pushed a commit to branch 2.2.X in repository https://gitbox.apache.org/repos/asf/mina.git
The following commit(s) were added to refs/heads/2.2.X by this push: new ecc9972 o Make it so outbound message are written when the inbound is closed. This is necessary when a TLS error has occured and teh inbound is therefore closed, the Alert must still be sent to the remote peer. o Added some missing Javadoc o Code formatting to respect the MINA current code style (no useless final, this, added missing {}, added NL, etc) ecc9972 is described below commit ecc99727fbab3da47e1a382360ca9d0355af2344 Author: emmanuel lecharny <elecha...@apache.org> AuthorDate: Tue Mar 8 09:24:00 2022 +0100 o Make it so outbound message are written when the inbound is closed. This is necessary when a TLS error has occured and teh inbound is therefore closed, the Alert must still be sent to the remote peer. o Added some missing Javadoc o Code formatting to respect the MINA current code style (no useless final, this, added missing {}, added NL, etc) --- .../org/apache/mina/filter/ssl/SSLHandler.java | 98 +++--- .../org/apache/mina/filter/ssl/SSLHandlerG0.java | 375 ++++++++++++++------- 2 files changed, 297 insertions(+), 176 deletions(-) diff --git a/mina-core/src/main/java/org/apache/mina/filter/ssl/SSLHandler.java b/mina-core/src/main/java/org/apache/mina/filter/ssl/SSLHandler.java index d1a0ffe..661d878 100644 --- a/mina-core/src/main/java/org/apache/mina/filter/ssl/SSLHandler.java +++ b/mina-core/src/main/java/org/apache/mina/filter/ssl/SSLHandler.java @@ -96,23 +96,23 @@ public abstract class SSLHandler { /** * Instantiates a new handler * - * @param p engine - * @param e executor - * @param s session + * @param sslEngine The SSLEngine instance + * @param executor The executor instance to use to process tasks + * @param session The session to handle */ - public SSLHandler(SSLEngine p, Executor e, IoSession s) { - this.mEngine = p; - this.mExecutor = e; - this.mSession = s; + public SSLHandler(SSLEngine sslEngine, Executor executor, IoSession session) { + this.mEngine = sslEngine; + this.mExecutor = executor; + this.mSession = session; } /** - * {@code true} if the encryption session is open + * @return {@code true} if the encryption session is open */ abstract public boolean isOpen(); /** - * {@code true} if the encryption session is connected and secure + * @return {@code true} if the encryption session is connected and secure */ abstract public boolean isConnected(); @@ -120,23 +120,21 @@ public abstract class SSLHandler { * Opens the encryption session, this may include sending the initial handshake * message * - * @param session - * @param next + * @param next The next filter in the chain * - * @throws SSLException + * @throws SSLException If we get an SSL exception while processing the opening */ abstract public void open(NextFilter next) throws SSLException; /** * Decodes encrypted messages and passes the results to the {@code next} filter. * - * @param message - * @param session - * @param next + * @param next The next filter in the chain + * @param message The message to process * - * @throws SSLException + * @throws SSLException If we get an SSL exception while processing the message */ - abstract public void receive(NextFilter next, final IoBuffer message) throws SSLException; + abstract public void receive(NextFilter next, IoBuffer message) throws SSLException; /** * Acknowledge that a {@link WriteRequest} has been successfully written to the @@ -146,13 +144,12 @@ public abstract class SSLHandler { * specific number of pending write operations at any moment of time. When one * {@code WriteRequest} is acknowledged, another can be encoded and written. * - * @param request - * @param session - * @param next + * @param next The next filter in the chain + * @param request The written request * - * @throws SSLException + * @throws SSLException If we get an SSL exception while processing the ack */ - abstract public void ack(NextFilter next, final WriteRequest request) throws SSLException; + abstract public void ack(NextFilter next, WriteRequest request) throws SSLException; /** * Encrypts and writes the specified {@link WriteRequest} to the @@ -161,24 +158,23 @@ public abstract class SSLHandler { * The encryption session may be currently handshaking preventing application * messages from being written. * - * @param request - * @param session - * @param next + * @param next The next filter in the chain + * @param request The message to write * - * @throws SSLException + * @throws SSLException If we get an SSL exception while writing the message * @throws WriteRejectedException when the session is closing */ - abstract public void write(NextFilter next, final WriteRequest request) throws SSLException, WriteRejectedException; + abstract public void write(NextFilter next, WriteRequest request) throws SSLException, WriteRejectedException; /** * Closes the encryption session and writes any required messages * - * @param next + * @param next The next filter in the chain * @param linger if true, write any queued messages before closing * - * @throws SSLException - */ - abstract public void close(NextFilter next, final boolean linger) throws SSLException; + * @throws SSLException If we get an SSL exception while processing the opening session closure + **/ + abstract public void close(NextFilter next, boolean linger) throws SSLException; /** * {@inheritDoc} @@ -191,14 +187,14 @@ public abstract class SSLHandler { b.append(Integer.toHexString(this.hashCode())); b.append("[mode="); - if (this.mEngine.getUseClientMode()) { + if (mEngine.getUseClientMode()) { b.append("client"); } else { b.append("server"); } b.append(", connected="); - b.append(this.isConnected()); + b.append(isConnected()); b.append("]"); @@ -212,20 +208,23 @@ public abstract class SSLHandler { * @return buffer to decode */ protected IoBuffer resume_decode_buffer(IoBuffer source) { - if (mDecodeBuffer == null) + if (mDecodeBuffer == null) { if (source == null) { return ZERO; } else { mDecodeBuffer = source; + return source; } - else { + } else { if (source != null && source != ZERO) { mDecodeBuffer.expand(source.remaining()); mDecodeBuffer.put(source); source.free(); } + mDecodeBuffer.flip(); + return mDecodeBuffer; } } @@ -239,17 +238,18 @@ public abstract class SSLHandler { protected void suspend_decode_buffer(IoBuffer source) { if (source.hasRemaining()) { if (source.isDerived()) { - this.mDecodeBuffer = IoBuffer.allocate(source.remaining()); - this.mDecodeBuffer.put(source); + mDecodeBuffer = IoBuffer.allocate(source.remaining()); + mDecodeBuffer.put(source); } else { source.compact(); - this.mDecodeBuffer = source; + mDecodeBuffer = source; } } else { if (source != ZERO) { source.free(); } - this.mDecodeBuffer = null; + + mDecodeBuffer = null; } } @@ -260,11 +260,15 @@ public abstract class SSLHandler { * @return buffer */ protected IoBuffer allocate_encode_buffer(int estimate) { - SSLSession session = this.mEngine.getHandshakeSession(); - if (session == null) - session = this.mEngine.getSession(); + SSLSession session = mEngine.getHandshakeSession(); + + if (session == null) { + session = mEngine.getSession(); + } + int packets = Math.max(MIN_ENCODER_BUFFER_PACKETS, Math.min(MAX_ENCODER_BUFFER_PACKETS, 1 + (estimate / session.getApplicationBufferSize()))); + return IoBuffer.allocate(packets * session.getPacketBufferSize()); } @@ -275,10 +279,14 @@ public abstract class SSLHandler { * @return buffer */ protected IoBuffer allocate_app_buffer(int estimate) { - SSLSession session = this.mEngine.getHandshakeSession(); - if (session == null) - session = this.mEngine.getSession(); + SSLSession session = mEngine.getHandshakeSession(); + + if (session == null) { + session = mEngine.getSession(); + } + int packets = 1 + (estimate / session.getPacketBufferSize()); + return IoBuffer.allocate(packets * session.getApplicationBufferSize()); } } diff --git a/mina-core/src/main/java/org/apache/mina/filter/ssl/SSLHandlerG0.java b/mina-core/src/main/java/org/apache/mina/filter/ssl/SSLHandlerG0.java index 76f2d53..3a591c8 100644 --- a/mina-core/src/main/java/org/apache/mina/filter/ssl/SSLHandlerG0.java +++ b/mina-core/src/main/java/org/apache/mina/filter/ssl/SSLHandlerG0.java @@ -102,12 +102,12 @@ public class SSLHandlerG0 extends SSLHandler { /** * Instantiates a new handler * - * @param p engine - * @param e executor - * @param s session + * @param sslEngine The SSLEngine instance + * @param executor The executor instance to use to process tasks + * @param session The session to handle */ - public SSLHandlerG0(SSLEngine p, Executor e, IoSession s) { - super(p, e, s); + public SSLHandlerG0(SSLEngine sslEngine, Executor executor, IoSession session) { + super(sslEngine, executor, session); } /** @@ -115,7 +115,7 @@ public class SSLHandlerG0 extends SSLHandler { */ @Override public boolean isOpen() { - return this.mEngine.isOutboundDone() == false; + return mEngine.isOutboundDone() == false; } /** @@ -123,21 +123,24 @@ public class SSLHandlerG0 extends SSLHandler { */ @Override public boolean isConnected() { - return this.mHandshakeComplete && isOpen(); + return mHandshakeComplete && isOpen(); } /** * {@inheritDoc} */ - synchronized public void open(final NextFilter next) throws SSLException { - if (this.mHandshakeStarted == false) { - this.mHandshakeStarted = true; - if (this.mEngine.getUseClientMode()) { + @Override + synchronized public void open(NextFilter next) throws SSLException { + if (mHandshakeStarted == false) { + mHandshakeStarted = true; + + if (mEngine.getUseClientMode()) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} open() - begin handshaking", toString()); } - this.mEngine.beginHandshake(); - this.write_handshake(next); + + mEngine.beginHandshake(); + write_handshake(next); } } } @@ -145,51 +148,65 @@ public class SSLHandlerG0 extends SSLHandler { /** * {@inheritDoc} */ - synchronized public void receive(final NextFilter next, final IoBuffer message) throws SSLException { - if (this.mDecodeThread == null) { + @Override + synchronized public void receive(NextFilter next, IoBuffer message) throws SSLException { + if (mDecodeThread == null) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} receive() - message {}", toString(), message); } - this.mDecodeThread = Thread.currentThread(); - final IoBuffer source = resume_decode_buffer(message); + + mDecodeThread = Thread.currentThread(); + IoBuffer source = resume_decode_buffer(message); + try { - this.receive_loop(next, source); + receive_loop(next, source); } finally { suspend_decode_buffer(source); - this.mDecodeThread = null; + mDecodeThread = null; } } else { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} receive() - recursion", toString()); } - this.receive_loop(next, this.mDecodeBuffer); + + receive_loop(next, mDecodeBuffer); } - this.throw_pending_error(); + throw_pending_error(next); } /** * Process a received message * - * @param next - * @param message + * @param next The next filter + * @param message The message to process * - * @throws SSLException + * @throws SSLException If we get some error while processing the message */ @SuppressWarnings("incomplete-switch") - protected void receive_loop(final NextFilter next, final IoBuffer message) throws SSLException { + protected void receive_loop(NextFilter next, IoBuffer message) throws SSLException { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} receive_loop() - source {}", toString(), message); } if (mEngine.isInboundDone()) { + switch (mEngine.getHandshakeStatus()) { + case NEED_WRAP: + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("{} receive_loop() - handshake needs wrap, invoking write", toString()); + } + + write_handshake(next); + break; + } + throw new IllegalStateException("closed"); } - final IoBuffer source = message; - final IoBuffer dest = allocate_app_buffer(source.remaining()); + IoBuffer source = message; + IoBuffer dest = allocate_app_buffer(source.remaining()); - final SSLEngineResult result = mEngine.unwrap(source.buf(), dest.buf()); + SSLEngineResult result = mEngine.unwrap(source.buf(), dest.buf()); if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} receive_loop() - bytes-consumed {}, bytes-produced {}, status {}, handshake {}", @@ -201,10 +218,12 @@ public class SSLHandlerG0 extends SSLHandler { dest.free(); } else { dest.flip(); + if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} receive_loop() - result {}", toString(), dest); } - next.messageReceived(this.mSession, dest); + + next.messageReceived(mSession, dest); } switch (result.getHandshakeStatus()) { @@ -213,34 +232,44 @@ public class SSLHandlerG0 extends SSLHandler { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} receive_loop() - handshake needs unwrap, looping", toString()); } - this.receive_loop(next, message); + + receive_loop(next, message); } + break; case NEED_TASK: if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} receive_loop() - handshake needs task, scheduling", toString()); } - this.schedule_task(next); + + execute_task(next); + break; case NEED_WRAP: if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} receive_loop() - handshake needs wrap, invoking write", toString()); } - this.write_handshake(next); + + write_handshake(next); break; + case FINISHED: if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} receive_loop() - handshake finished, flushing queue", toString()); } - this.finish_handshake(next); + + finish_handshake(next); break; + case NOT_HANDSHAKING: if ((result.bytesProduced() != 0 || result.bytesConsumed() != 0) && message.hasRemaining()) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} receive_loop() - trying to decode more messages, looping", toString()); } - this.receive_loop(next, message); + + receive_loop(next, message); } + break; } } @@ -248,55 +277,62 @@ public class SSLHandlerG0 extends SSLHandler { /** * {@inheritDoc} */ - synchronized public void ack(final NextFilter next, final WriteRequest request) throws SSLException { - if (this.mAckQueue.remove(request)) { + @Override + synchronized public void ack(NextFilter next, WriteRequest request) throws SSLException { + if (mAckQueue.remove(request)) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} ack() - {}", toString(), request); } + if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} ack() - checking to see if any messages can be flushed", toString(), request); } - this.flush(next); + + flush(next); } - this.throw_pending_error(); + throw_pending_error(next); } /** * {@inheritDoc} */ - synchronized public void write(final NextFilter next, final WriteRequest request) - throws SSLException, WriteRejectedException { + @Override + synchronized public void write(NextFilter next, WriteRequest request) throws SSLException, WriteRejectedException { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write() - source {}", toString(), request); } - if (this.mOutboundClosing) { + if (mOutboundClosing) { throw new WriteRejectedException(request, "closing"); } - if (this.mEncodeQueue.isEmpty()) { - if (this.write_user_loop(next, request) == false) { + if (mEncodeQueue.isEmpty()) { + if (write_user_loop(next, request) == false) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write() - unable to write right now, saving request for later", toString(), request); } - if (this.mEncodeQueue.size() == MAX_QUEUED_MESSAGES) { + + if (mEncodeQueue.size() == MAX_QUEUED_MESSAGES) { throw new BufferOverflowException(); } - this.mEncodeQueue.add(request); + + mEncodeQueue.add(request); } } else { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write() - unable to write right now, saving request for later", toString(), request); } - if (this.mEncodeQueue.size() == MAX_QUEUED_MESSAGES) { + + if (mEncodeQueue.size() == MAX_QUEUED_MESSAGES) { throw new BufferOverflowException(); } - this.mEncodeQueue.add(request); + + mEncodeQueue.add(request); } - this.throw_pending_error(); + throw_pending_error(next); } /** @@ -311,16 +347,15 @@ public class SSLHandlerG0 extends SSLHandler { * @throws SSLException */ @SuppressWarnings("incomplete-switch") - synchronized protected boolean write_user_loop(final NextFilter next, final WriteRequest request) - throws SSLException { + synchronized protected boolean write_user_loop(NextFilter next, WriteRequest request) throws SSLException { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write_user_loop() - source {}", toString(), request); } - final IoBuffer source = IoBuffer.class.cast(request.getMessage()); - final IoBuffer dest = allocate_encode_buffer(source.remaining()); + IoBuffer source = IoBuffer.class.cast(request.getMessage()); + IoBuffer dest = allocate_encode_buffer(source.remaining()); - final SSLEngineResult result = this.mEngine.wrap(source.buf(), dest.buf()); + SSLEngineResult result = mEngine.wrap(source.buf(), dest.buf()); if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write_user_loop() - bytes-consumed {}, bytes-produced {}, status {}, handshake {}", @@ -334,32 +369,42 @@ public class SSLHandlerG0 extends SSLHandler { if (result.bytesConsumed() == 0) { // an handshaking message must have been produced EncryptedWriteRequest encrypted = new EncryptedWriteRequest(dest, null); + if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write_user_loop() - result {}", toString(), encrypted); } - next.filterWrite(this.mSession, encrypted); + + next.filterWrite(mSession, encrypted); // do not return because we want to enter the handshake switch } else { // then we probably consumed some data dest.flip(); + if (source.hasRemaining()) { EncryptedWriteRequest encrypted = new EncryptedWriteRequest(dest, null); - this.mAckQueue.add(encrypted); + mAckQueue.add(encrypted); + if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write_user_loop() - result {}", toString(), encrypted); } - next.filterWrite(this.mSession, encrypted); - if (this.mAckQueue.size() < MAX_UNACK_MESSAGES) { + + next.filterWrite(mSession, encrypted); + + if (mAckQueue.size() < MAX_UNACK_MESSAGES) { return write_user_loop(next, request); // write additional chunks } + return false; } else { EncryptedWriteRequest encrypted = new EncryptedWriteRequest(dest, request); - this.mAckQueue.add(encrypted); + mAckQueue.add(encrypted); + if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write_user_loop() - result {}", toString(), encrypted); } - next.filterWrite(this.mSession, encrypted); + + next.filterWrite(mSession, encrypted); + return true; } // we return because there is not reason to enter the handshake switch @@ -371,19 +416,26 @@ public class SSLHandlerG0 extends SSLHandler { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write_user_loop() - handshake needs task, scheduling", toString()); } - this.schedule_task(next); + + //schedule_task(next); + execute_task(next); break; + case NEED_WRAP: if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write_user_loop() - handshake needs wrap, looping", toString()); } - return this.write_user_loop(next, request); + + return write_user_loop(next, request); + case FINISHED: if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write_user_loop() - handshake finished, flushing queue", toString()); } - this.finish_handshake(next); - return this.write_user_loop(next, request); + + finish_handshake(next); + + return write_user_loop(next, request); } return false; @@ -403,8 +455,9 @@ public class SSLHandlerG0 extends SSLHandler { LOGGER.debug("{} write_handshake() - internal", toString()); } - final IoBuffer source = ZERO; - final IoBuffer dest = allocate_encode_buffer(source.remaining()); + IoBuffer source = ZERO; + IoBuffer dest = allocate_encode_buffer(source.remaining()); + return write_handshake_loop(next, source, dest); } @@ -424,11 +477,11 @@ public class SSLHandlerG0 extends SSLHandler { */ @SuppressWarnings("incomplete-switch") protected boolean write_handshake_loop(NextFilter next, IoBuffer source, IoBuffer dest) throws SSLException { - if (this.mOutboundClosing && this.mEngine.isOutboundDone()) { + if (mOutboundClosing && mEngine.isOutboundDone()) { return false; } - final SSLEngineResult result = this.mEngine.wrap(source.buf(), dest.buf()); + SSLEngineResult result = mEngine.wrap(source.buf(), dest.buf()); if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write_handshake_loop() - bytes-consumed {}, bytes-produced {}, status {}, handshake {}", @@ -455,23 +508,26 @@ public class SSLHandlerG0 extends SSLHandler { LOGGER.debug("{} write_handshake_loop() - handshake needs wrap, fast looping", toString()); } + return write_handshake_loop(next, source, dest); } break; } } - final boolean success = dest.position() != 0; + boolean success = dest.position() != 0; if (success == false) { dest.free(); } else { dest.flip(); + if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write_handshake_loop() - result {}", toString(), dest); } - final EncryptedWriteRequest encrypted = new EncryptedWriteRequest(dest, null); - next.filterWrite(this.mSession, encrypted); + + EncryptedWriteRequest encrypted = new EncryptedWriteRequest(dest, null); + next.filterWrite(mSession, encrypted); } switch (result.getHandshakeStatus()) { @@ -479,25 +535,33 @@ public class SSLHandlerG0 extends SSLHandler { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write_handshake_loop() - handshake needs unwrap, invoking receive", toString()); } - this.receive(next, ZERO); + + receive(next, ZERO); break; + case NEED_WRAP: if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write_handshake_loop() - handshake needs wrap, looping", toString()); } - this.write_handshake(next); + + write_handshake(next); break; + case NEED_TASK: if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write_handshake_loop() - handshake needs task, scheduling", toString()); } - this.schedule_task(next); + + //schedule_task(next); + execute_task(next); break; + case FINISHED: if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} write_handshake_loop() - handshake finished, flushing queue", toString()); } - this.finish_handshake(next); + + finish_handshake(next); break; } @@ -510,17 +574,18 @@ public class SSLHandlerG0 extends SSLHandler { * @param next * @throws SSLException */ - synchronized protected void finish_handshake(final NextFilter next) throws SSLException { - if (this.mHandshakeComplete == false) { - this.mHandshakeComplete = true; - this.mSession.setAttribute(SSLFilter.SSL_SECURED, this.mEngine.getSession()); - next.event(this.mSession, SSLEvent.SECURED); + synchronized protected void finish_handshake(NextFilter next) throws SSLException { + if (mHandshakeComplete == false) { + mHandshakeComplete = true; + mSession.setAttribute(SSLFilter.SSL_SECURED, mEngine.getSession()); + next.event(mSession, SSLEvent.SECURED); } + /** * There exists a bug in the JDK which emits FINISHED twice instead of once. */ - this.receive(next, ZERO); - this.flush(next); + receive(next, ZERO); + flush(next); } /** @@ -530,33 +595,38 @@ public class SSLHandlerG0 extends SSLHandler { * * @throws SSLException */ - synchronized public void flush(final NextFilter next) throws SSLException { - if (this.mOutboundClosing && this.mOutboundLinger == false) { + synchronized public void flush(NextFilter next) throws SSLException { + if (mOutboundClosing && mOutboundLinger == false) { return; } - if (this.mEncodeQueue.size() == 0) { + if (mEncodeQueue.size() == 0) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} flush() - no saved messages", toString()); } + return; } WriteRequest current = null; - while ((this.mAckQueue.size() < MAX_UNACK_MESSAGES) && (current = this.mEncodeQueue.poll()) != null) { + + while ((mAckQueue.size() < MAX_UNACK_MESSAGES) && (current = mEncodeQueue.poll()) != null) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} flush() - {}", toString(), current); } - if (this.write_user_loop(next, current) == false) { - this.mEncodeQueue.addFirst(current); + + if (write_user_loop(next, current) == false) { + mEncodeQueue.addFirst(current); + break; } } - if (this.mOutboundClosing && this.mEncodeQueue.size() == 0) { - this.mEngine.closeOutbound(); + if (mOutboundClosing && mEncodeQueue.size() == 0) { + mEngine.closeOutbound(); + if (ENABLE_SOFT_CLOSURE) { - this.write_handshake(next); + write_handshake(next); } } } @@ -564,77 +634,113 @@ public class SSLHandlerG0 extends SSLHandler { /** * {@inheritDoc} */ - synchronized public void close(final NextFilter next, final boolean linger) throws SSLException { - if (this.mOutboundClosing) + @Override + synchronized public void close(NextFilter next, boolean linger) throws SSLException { + if (mOutboundClosing) { return; + } if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} close() - closing session", toString()); } - if (this.mHandshakeComplete) { - next.event(this.mSession, SSLEvent.UNSECURED); + if (mHandshakeComplete) { + next.event(mSession, SSLEvent.UNSECURED); } - this.mOutboundLinger = linger; - this.mOutboundClosing = true; + mOutboundLinger = linger; + mOutboundClosing = true; if (linger == false) { - if (this.mEncodeQueue.size() != 0) { - next.exceptionCaught(this.mSession, - new WriteRejectedException(new ArrayList<>(this.mEncodeQueue), "closing")); - this.mEncodeQueue.clear(); + if (mEncodeQueue.size() != 0) { + next.exceptionCaught(mSession, new WriteRejectedException(new ArrayList<>(mEncodeQueue), "closing")); + mEncodeQueue.clear(); } - this.mEngine.closeOutbound(); + + mEngine.closeOutbound(); + if (ENABLE_SOFT_CLOSURE) { - this.write_handshake(next); + write_handshake(next); } } else { - this.flush(next); + flush(next); } } - synchronized protected void throw_pending_error() throws SSLException { - final SSLException e = this.mPendingError; - if (e != null) { - this.mPendingError = null; - throw e; + /** + * 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) { + mPendingError = null; + + // Loop to send back the alert messages + receive_loop(next, null); + + // And finally rethrow the exception + throw sslException; } } - synchronized protected void store_pending_error(SSLException e) { - SSLException x = this.mPendingError; - if (x == null) { - this.mPendingError = e; + /** + * Store any error we've got during the handshake or message handling + * + * @param sslException The exfeption to store + */ + synchronized protected void store_pending_error(SSLException sslException) { + if (mPendingError == null) { + mPendingError = sslException; } } - protected void schedule_task(final NextFilter next) { - if (ENABLE_ASYNC_TASKS) { - if (this.mExecutor == null) { - this.execute_task(next); - } else { - this.mExecutor.execute(new Runnable() { - @Override - public void run() { - SSLHandlerG0.this.execute_task(next); - } - }); - } + /** + * Schedule a SSLEngine task for execution, either using an Executor, or immediately. + * + * @param next The next filter to call + */ + protected void schedule_task(NextFilter next) { + if (ENABLE_ASYNC_TASKS && (mExecutor != null)) { + mExecutor.execute(new Runnable() { + @Override + public void run() { + SSLHandlerG0.this.execute_task(next); + } + }); } else { - this.execute_task(next); + execute_task(next); } } - synchronized protected void execute_task(final NextFilter next) { - Runnable t = null; - while ((t = mEngine.getDelegatedTask()) != null) { + /** + * Execute a SSLEngine task. We may have more than one. + * + * If we get any exception during the processing, an error is stored and thrown. + * + * @param next The next filer in the chain + */ + synchronized protected void execute_task(NextFilter next) { + Runnable task = null; + int nbTask = 0; + + while ((task = mEngine.getDelegatedTask()) != null) { try { + System.out.println( "--->>>>> Task number " + nbTask); + nbTask++; + if (LOGGER.isDebugEnabled()) { - LOGGER.debug("{} task() - executing {}", toString(), t); + LOGGER.debug("{} task() - executing {}", toString(), task); } - t.run(); + if (ENABLE_ASYNC_TASKS && (mExecutor != null)) { + mExecutor.execute(task); + } else { + task.run(); + } if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} task() - writing handshake messages", toString()); @@ -642,7 +748,14 @@ public class SSLHandlerG0 extends SSLHandler { write_handshake(next); } catch (SSLException e) { - this.store_pending_error(e); + store_pending_error(e); + + try { + throw_pending_error(next); + } catch ( SSLException ssle) { + // ... + } + if (LOGGER.isErrorEnabled()) { LOGGER.error("{} task() - storing error {}", toString(), e); }