You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2017/09/15 20:11:46 UTC

svn commit: r1808481 - in /tomcat/trunk/java/org/apache/tomcat/util/net/openssl: OpenSSLContext.java OpenSSLSessionContext.java

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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org