Author: markt Date: Fri Sep 15 20:11:46 2017 New Revision: 1808481 URL: http://svn.apache.org/viewvc?rev=1808481&view=rev Log: Refactor the OpenSSLContext implementation so that a reference is retained to the instance while a request that is using it is in progress. This allows destruction to be safely triggered by finalize()
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLSessionContext.java Modified: tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java?rev=1808481&r1=1808480&r2=1808481&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java Fri Sep 15 20:11:46 2017 @@ -414,7 +414,7 @@ public class OpenSSLContext implements o sslHostConfig.setEnabledCiphers(SSLContext.getCiphers(ctx)); } - sessionContext = new OpenSSLSessionContext(ctx); + sessionContext = new OpenSSLSessionContext(this); // If client authentication is being used, OpenSSL requires that // this is set so always set it in case an app is configured to // require it @@ -480,6 +480,12 @@ public class OpenSSLContext implements o return peerCerts; } + + long getSSLContextID() { + return ctx; + } + + @Override public SSLSessionContext getServerSessionContext() { return sessionContext; @@ -501,4 +507,23 @@ public class OpenSSLContext implements o throw new UnsupportedOperationException(); } + @Override + protected void finalize() throws Throwable { + /* + * When an SSLHostConfig is replaced at runtime, it is not possible to + * call destroy() on the associated OpenSSLContext since it is likely + * that there will be in-progress connections using the OpenSSLContext. + * A reference chain has been deliberately established (see + * OpenSSLSessionContext) to ensure that the OpenSSLContext remains + * ineligible for GC while those connections are alive. Once those + * connections complete, the OpenSSLContext will become eligible for GC + * and this method will ensure that the associated native resources are + * cleaned up. + */ + try { + destroy(); + } finally { + super.finalize(); + } + } } Modified: tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLSessionContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLSessionContext.java?rev=1808481&r1=1808480&r2=1808481&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLSessionContext.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLSessionContext.java Fri Sep 15 20:11:46 2017 @@ -34,11 +34,18 @@ public class OpenSSLSessionContext imple private static final Enumeration<byte[]> EMPTY = new EmptyEnumeration(); private final OpenSSLSessionStats stats; - private final long context; + // This is deliberately unused. The reference is retained so that a + // reference chain is established and maintained to the OpenSSLContext while + // there is a connection that is using the OpenSSLContext. Therefore, the + // OpenSSLContext can not be eligible for GC while it is in use. + @SuppressWarnings("unused") + private final OpenSSLContext context; + private final long contextID; - OpenSSLSessionContext(long context) { + OpenSSLSessionContext(OpenSSLContext context) { this.context = context; - stats = new OpenSSLSessionStats(context); + this.contextID = context.getSSLContextID(); + stats = new OpenSSLSessionStats(contextID); } @Override @@ -60,7 +67,7 @@ public class OpenSSLSessionContext imple if (keys == null) { throw new IllegalArgumentException(sm.getString("sessionContext.nullTicketKeys")); } - SSLContext.setSessionTicketKeys(context, keys); + SSLContext.setSessionTicketKeys(contextID, keys); } /** @@ -70,7 +77,7 @@ public class OpenSSLSessionContext imple */ public void setSessionCacheEnabled(boolean enabled) { long mode = enabled ? SSL.SSL_SESS_CACHE_SERVER : SSL.SSL_SESS_CACHE_OFF; - SSLContext.setSessionCacheMode(context, mode); + SSLContext.setSessionCacheMode(contextID, mode); } /** @@ -78,7 +85,7 @@ public class OpenSSLSessionContext imple * otherwise. */ public boolean isSessionCacheEnabled() { - return SSLContext.getSessionCacheMode(context) == SSL.SSL_SESS_CACHE_SERVER; + return SSLContext.getSessionCacheMode(contextID) == SSL.SSL_SESS_CACHE_SERVER; } /** @@ -93,12 +100,12 @@ public class OpenSSLSessionContext imple if (seconds < 0) { throw new IllegalArgumentException(); } - SSLContext.setSessionCacheTimeout(context, seconds); + SSLContext.setSessionCacheTimeout(contextID, seconds); } @Override public int getSessionTimeout() { - return (int) SSLContext.getSessionCacheTimeout(context); + return (int) SSLContext.getSessionCacheTimeout(contextID); } @Override @@ -106,12 +113,12 @@ public class OpenSSLSessionContext imple if (size < 0) { throw new IllegalArgumentException(); } - SSLContext.setSessionCacheSize(context, size); + SSLContext.setSessionCacheSize(contextID, size); } @Override public int getSessionCacheSize() { - return (int) SSLContext.getSessionCacheSize(context); + return (int) SSLContext.getSessionCacheSize(contextID); } /** @@ -124,7 +131,7 @@ public class OpenSSLSessionContext imple * @return {@code true} if success, {@code false} otherwise. */ public boolean setSessionIdContext(byte[] sidCtx) { - return SSLContext.setSessionIdContext(context, sidCtx); + return SSLContext.setSessionIdContext(contextID, sidCtx); } private static final class EmptyEnumeration implements Enumeration<byte[]> { --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org