You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by jo...@apache.org on 2021/08/06 18:09:53 UTC
[mina] branch bugfix/DIRMINA1132 updated: SSL improvements
This is an automated email from the ASF dual-hosted git repository.
johnnyv pushed a commit to branch bugfix/DIRMINA1132
in repository https://gitbox.apache.org/repos/asf/mina.git
The following commit(s) were added to refs/heads/bugfix/DIRMINA1132 by this push:
new 4c11155 SSL improvements
4c11155 is described below
commit 4c1115590e183267d5536ded8d3eec316efb128f
Author: Jonathan Valliere <jo...@apache.org>
AuthorDate: Fri Aug 6 14:09:41 2021 -0400
SSL improvements
- Adds linger support to ssl closure; you can now choose to close the
ssl after pending writes are completed.
- Adds WriteRejectedException to dispatch exceptions for unwritten
messages once SSL is closed.
- Changes SSL_SECURED to the SSLSession object; once SSL_SECURED it set
the user has access to the session information.
---
.../mina/core/write/WriteRejectedException.java | 44 +++++++++++++++++
.../org/apache/mina/filter/ssl2/SSL2Filter.java | 38 ++++++++++-----
.../org/apache/mina/filter/ssl2/SSL2Handler.java | 8 +--
.../org/apache/mina/filter/ssl2/SSL2HandlerG0.java | 57 +++++++++++++++++++---
4 files changed, 124 insertions(+), 23 deletions(-)
diff --git a/mina-core/src/main/java/org/apache/mina/core/write/WriteRejectedException.java b/mina-core/src/main/java/org/apache/mina/core/write/WriteRejectedException.java
new file mode 100644
index 0000000..a0d4a01
--- /dev/null
+++ b/mina-core/src/main/java/org/apache/mina/core/write/WriteRejectedException.java
@@ -0,0 +1,44 @@
+package org.apache.mina.core.write;
+
+import java.util.Collection;
+
+public class WriteRejectedException extends WriteException {
+ private static final long serialVersionUID = 6272160412793858438L;
+
+ /**
+ * Create a new WriteRejectedException instance
+ *
+ * @param requests The {@link WriteRequest} which has been rejected
+ * @param message The error message
+ */
+ public WriteRejectedException(WriteRequest requests, String message) {
+ super(requests, message);
+ }
+
+ /**
+ * Create a new WriteRejectedException instance
+ *
+ * @param requests The {@link WriteRequest} which has been rejected
+ */
+ public WriteRejectedException(WriteRequest requests) {
+ super(requests);
+ }
+
+ /**
+ * Create a new WriteRejectedException instance
+ *
+ * @param requests The {@link WriteRequest} which has been rejected
+ */
+ public WriteRejectedException(Collection<WriteRequest> requests) {
+ super(requests);
+ }
+
+ /**
+ * Create a new WriteRejectedException instance
+ *
+ * @param requests The {@link WriteRequest} which has been rejected
+ */
+ public WriteRejectedException(Collection<WriteRequest> requests, String message) {
+ super(requests, message);
+ }
+}
diff --git a/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2Filter.java b/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2Filter.java
index 0b36259..00554db 100644
--- a/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2Filter.java
+++ b/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2Filter.java
@@ -49,12 +49,6 @@ import org.slf4j.LoggerFactory;
* @author <a href="http://mina.apache.org">Apache MINA Project</a>
*/
public class SSL2Filter extends IoFilterAdapter {
-
- /**
- * Returns the SSL2Handler object
- */
- static public final AttributeKey SSL_HANDLER = new AttributeKey(SSL2Filter.class, "handler");
-
/**
* The presence of this attribute in a session indicates that the session is
* secured.
@@ -62,6 +56,11 @@ public class SSL2Filter extends IoFilterAdapter {
static public final AttributeKey SSL_SECURED = new AttributeKey(SSL2Filter.class, "status");
/**
+ * Returns the SSL2Handler object
+ */
+ static protected final AttributeKey SSL_HANDLER = new AttributeKey(SSL2Filter.class, "handler");
+
+ /**
* The logger
*/
static protected final Logger LOGGER = LoggerFactory.getLogger(SSL2Filter.class);
@@ -194,11 +193,7 @@ public class SSL2Filter extends IoFilterAdapter {
@Override
public void onPreRemove(IoFilterChain parent, String name, NextFilter next) throws Exception {
IoSession session = parent.getSession();
- session.removeAttribute(SSL_SECURED);
- SSL2Handler x = SSL2Handler.class.cast(session.removeAttribute(SSL_HANDLER));
- if (x != null) {
- x.close(next);
- }
+ onClose(next, session, false);
}
/**
@@ -209,7 +204,7 @@ public class SSL2Filter extends IoFilterAdapter {
* @param session
* @throws Exception
*/
- protected void onConnected(NextFilter next, IoSession session) throws Exception {
+ synchronized protected void onConnected(NextFilter next, IoSession session) throws Exception {
SSL2Handler x = SSL2Handler.class.cast(session.getAttribute(SSL_HANDLER));
if (x == null) {
@@ -222,6 +217,14 @@ public class SSL2Filter extends IoFilterAdapter {
x.open(next);
}
+ synchronized protected void onClose(NextFilter next, IoSession session, boolean linger) throws Exception {
+ session.removeAttribute(SSL_SECURED);
+ SSL2Handler x = SSL2Handler.class.cast(session.removeAttribute(SSL_HANDLER));
+ if (x != null) {
+ x.close(next, linger);
+ }
+ }
+
/**
* Customization handler for creating the engine
*
@@ -260,6 +263,17 @@ public class SSL2Filter extends IoFilterAdapter {
* {@inheritDoc}
*/
@Override
+ public void sessionClosed(NextFilter next, IoSession session) throws Exception {
+ if (LOGGER.isDebugEnabled())
+ LOGGER.debug("session {} closed", session);
+ this.onClose(next, session, false);
+ super.sessionClosed(next, session);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public void messageReceived(NextFilter next, IoSession session, Object message) throws Exception {
if (LOGGER.isDebugEnabled())
LOGGER.debug("session {} received {}", session, message);
diff --git a/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2Handler.java b/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2Handler.java
index 4206ba6..b5e522b 100644
--- a/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2Handler.java
+++ b/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2Handler.java
@@ -11,6 +11,7 @@ import javax.net.ssl.SSLSession;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.filterchain.IoFilter.NextFilter;
import org.apache.mina.core.session.IoSession;
+import org.apache.mina.core.write.WriteRejectedException;
import org.apache.mina.core.write.WriteRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -140,18 +141,19 @@ public abstract class SSL2Handler {
* @param next
*
* @throws SSLException
+ * @throws WriteRejectedException when the session is closing
*/
- abstract public void write(NextFilter next, final WriteRequest request) throws SSLException;
+ abstract public void write(NextFilter next, final WriteRequest request) throws SSLException, WriteRejectedException;
/**
* Closes the encryption session and writes any required messages
*
- * @param session
* @param next
+ * @param linger if true, write any queued messages before closing
*
* @throws SSLException
*/
- abstract public void close(NextFilter next) throws SSLException;
+ abstract public void close(NextFilter next, final boolean linger) throws SSLException;
/**
* {@inheritDoc}
diff --git a/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2HandlerG0.java b/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2HandlerG0.java
index 1b308aa..fd2ecd1 100644
--- a/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2HandlerG0.java
+++ b/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2HandlerG0.java
@@ -1,6 +1,7 @@
package org.apache.mina.filter.ssl2;
import java.nio.BufferOverflowException;
+import java.util.ArrayList;
import java.util.concurrent.Executor;
import javax.net.ssl.SSLEngine;
@@ -10,6 +11,7 @@ import javax.net.ssl.SSLException;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.filterchain.IoFilter.NextFilter;
import org.apache.mina.core.session.IoSession;
+import org.apache.mina.core.write.WriteRejectedException;
import org.apache.mina.core.write.WriteRequest;
import org.apache.mina.filter.ssl.SslEvent;
@@ -46,7 +48,17 @@ public class SSL2HandlerG0 extends SSL2Handler {
protected boolean mHandshakeStarted = false;
/**
- * Holds the decoder thread reference
+ * Indicates that the outbound is closing
+ */
+ protected boolean mOutboundClosing = false;
+
+ /**
+ * Indicates that previously queued messages should be written before closing
+ */
+ protected boolean mOutboundLinger = false;
+
+ /**
+ * Holds the decoder thread reference; used for recursion detection
*/
protected Thread mDecodeThread = null;
@@ -207,11 +219,16 @@ public class SSL2HandlerG0 extends SSL2Handler {
/**
* {@inheritDoc}
*/
- synchronized public void write(final NextFilter next, final WriteRequest request) throws SSLException {
+ synchronized public void write(final NextFilter next, final WriteRequest request)
+ throws SSLException, WriteRejectedException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("{} write() - source {}", toString(), request);
}
+ if (this.mOutboundClosing) {
+ throw new WriteRejectedException(request, "closing");
+ }
+
if (this.mEncodeQueue.isEmpty()) {
if (qwrite(next, request) == false) {
if (LOGGER.isDebugEnabled()) {
@@ -357,6 +374,10 @@ public class SSL2HandlerG0 extends SSL2Handler {
*/
@SuppressWarnings("incomplete-switch")
protected boolean lwrite(NextFilter next, IoBuffer source, IoBuffer dest) throws SSLException {
+ if (this.mOutboundClosing && this.mEngine.isOutboundDone()) {
+ return false;
+ }
+
final SSLEngineResult result = this.mEngine.wrap(source.buf(), dest.buf());
if (LOGGER.isDebugEnabled()) {
@@ -441,7 +462,7 @@ public class SSL2HandlerG0 extends SSL2Handler {
synchronized protected void lfinish(final NextFilter next) throws SSLException {
if (this.mHandshakeComplete == false) {
this.mHandshakeComplete = true;
- this.mSession.setAttribute(SSL2Filter.SSL_SECURED, this);
+ this.mSession.setAttribute(SSL2Filter.SSL_SECURED, this.mEngine.getSession());
next.event(this.mSession, SslEvent.SECURED);
}
/**
@@ -459,7 +480,11 @@ public class SSL2HandlerG0 extends SSL2Handler {
* @throws SSLException
*/
synchronized public void flush(final NextFilter next) throws SSLException {
- if (this.mEncodeQueue.isEmpty()) {
+ if (this.mOutboundClosing && this.mOutboundLinger == false) {
+ return;
+ }
+
+ if (this.mEncodeQueue.size() != 0) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("{} flush() - no saved messages", toString());
}
@@ -476,21 +501,37 @@ public class SSL2HandlerG0 extends SSL2Handler {
break;
}
}
+
+ if (this.mOutboundClosing && this.mEncodeQueue.size() == 0) {
+ this.mEngine.closeOutbound();
+ this.write(next);
+ }
}
/**
* {@inheritDoc}
*/
- synchronized public void close(final NextFilter next) throws SSLException {
- if (this.mEngine.isOutboundDone())
+ synchronized public void close(final NextFilter next, final boolean linger) throws SSLException {
+ if (this.mOutboundClosing)
return;
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("{} close() - closing session", toString());
}
- this.mEngine.closeOutbound();
- this.write(next);
+ this.mOutboundLinger = linger;
+ this.mOutboundClosing = true;
+ if (linger == false) {
+ if (this.mEncodeQueue.size() != 0) {
+ next.exceptionCaught(this.mSession,
+ new WriteRejectedException(new ArrayList<>(this.mEncodeQueue), "closing"));
+ this.mEncodeQueue.clear();
+ }
+ this.mEngine.closeOutbound();
+ this.write(next);
+ } else {
+ this.flush(next);
+ }
}
protected void schedule_task(final NextFilter next) {