You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2022/09/14 14:36:48 UTC

[tomcat] branch main updated: Interim update towards Java 20 Panama API

This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
     new b22d5b8433 Interim update towards Java 20 Panama API
b22d5b8433 is described below

commit b22d5b8433892dad8a3935f6febfc3d7c8daa5ac
Author: remm <re...@apache.org>
AuthorDate: Wed Sep 14 16:36:21 2022 +0200

    Interim update towards Java 20 Panama API
    
    Java 20 removes MemoryAddress (which was a decorated long basically) and
    Addressable, and will use MemorySegment everywhere.
    As a result, MemoryAddress in the state has to be replaced with a
    MemorySegment. Since MemorySegment in the cleaner (or action) will be a
    reference preventing GC, there's a need for another strategy. After
    testing a few option, this one looks like one that looks decent and
    works.
    This is an interim update before the big one (when the PR for JDK trunk
    happens, along with a compatible jextract - too many updates to bother
    doing it manually, and still ongoing anyway), which allowed verifying
    leaking using heap dumps.
---
 .../util/net/openssl/panama/OpenSSLContext.java    | 25 +++++++++++------
 .../util/net/openssl/panama/OpenSSLEngine.java     | 32 +++++++++++++---------
 webapps/docs/changelog.xml                         |  7 +++++
 3 files changed, 42 insertions(+), 22 deletions(-)

diff --git a/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java b/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
index ebf5bc6086..37fe09a49d 100644
--- a/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
+++ b/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
@@ -735,7 +735,7 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
                 sslHostConfig.setEnabledProtocols(
                         enabled.toArray(new String[0]));
                 // Reconfigure the enabled ciphers
-                sslHostConfig.setEnabledCiphers(getCiphers(state.sslCtx));
+                sslHostConfig.setEnabledCiphers(getCiphers(state.sslCtx.address()));
             }
 
             sessionContext = new OpenSSLSessionContext(this);
@@ -743,7 +743,7 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
             // this is set so always set it in case an app is configured to
             // require it
             sessionContext.setSessionIdContext(DEFAULT_SESSION_ID_CONTEXT);
-            sslHostConfig.setOpenSslContext(state.sslCtx.toRawLongValue());
+            sslHostConfig.setOpenSslContext(state.sslCtx.address().toRawLongValue());
             initialized = true;
         } catch (Exception e) {
             log.warn(sm.getString("openssl.errorSSLCtxInit"), e);
@@ -753,7 +753,7 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
 
 
     public MemoryAddress getSSLContext() {
-        return state.sslCtx;
+        return state.sslCtx.address();
     }
 
     // DH *(*tmp_dh_callback)(SSL *ssl, int is_export, int keylength)
@@ -1373,8 +1373,9 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
     private static class ContextState implements Runnable {
 
         private final MemorySession contextMemorySession;
-        private final MemoryAddress sslCtx;
-        private final MemoryAddress confCtx;
+        private final MemorySession stateSession = MemorySession.openShared();
+        private final MemorySegment sslCtx;
+        private final MemorySegment confCtx;
         private final List<byte[]> negotiableProtocols;
 
         private X509TrustManager x509TrustManager = null;
@@ -1383,20 +1384,26 @@ public class OpenSSLContext implements org.apache.tomcat.util.net.SSLContext {
                 MemoryAddress confCtx, List<byte[]> negotiableProtocols) {
             states.put(Long.valueOf(sslCtx.toRawLongValue()), this);
             this.contextMemorySession = contextMemorySession;
-            this.sslCtx = sslCtx;
-            this.confCtx = confCtx;
+            // Allocate another session to avoid keeping a reference through segments
+            this.sslCtx = MemorySegment.ofAddress(sslCtx, ValueLayout.ADDRESS.byteSize(), stateSession);
+            if (!MemoryAddress.NULL.equals(confCtx)) {
+                this.confCtx = MemorySegment.ofAddress(confCtx, ValueLayout.ADDRESS.byteSize(), stateSession);
+            } else {
+                this.confCtx = null;
+            }
             this.negotiableProtocols = negotiableProtocols;
         }
 
         @Override
         public void run() {
             try {
-                states.remove(Long.valueOf(sslCtx.toRawLongValue()));
+                states.remove(Long.valueOf(sslCtx.address().toRawLongValue()));
                 SSL_CTX_free(sslCtx);
-                if (!MemoryAddress.NULL.equals(confCtx)) {
+                if (confCtx != null) {
                     SSL_CONF_CTX_free(confCtx);
                 }
             } finally {
+                stateSession.close();
                 contextMemorySession.close();
             }
         }
diff --git a/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java b/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
index 3f34895b1d..c0cf0d6b8e 100644
--- a/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
+++ b/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java
@@ -237,7 +237,7 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn
      * @param certificateVerificationOptionalNoCA Skip CA verification in
      *   optional mode
      */
-    OpenSSLEngine(MemoryAddress sslCtx, String fallbackApplicationProtocol,
+    OpenSSLEngine(MemorySegment sslCtx, String fallbackApplicationProtocol,
             boolean clientMode, OpenSSLSessionContext sessionContext, boolean alpn,
             boolean initialized, int certificateVerificationDepth,
             boolean certificateVerificationOptionalNoCA, boolean noOcspCheck) {
@@ -299,7 +299,7 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn
      * Calling this function with src.remaining == 0 is undefined.
      * @throws SSLException if the OpenSSL error check fails
      */
-    private int writePlaintextData(final MemoryAddress ssl, final ByteBuffer src) throws SSLException {
+    private int writePlaintextData(final MemorySegment ssl, final ByteBuffer src) throws SSLException {
         clearLastError();
         final int pos = src.position();
         final int len = Math.min(src.remaining(), MAX_PLAINTEXT_LENGTH);
@@ -321,7 +321,7 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn
      * Write encrypted data to the OpenSSL network BIO.
      * @throws SSLException if the OpenSSL error check fails
      */
-    private int writeEncryptedData(final MemoryAddress networkBIO, final ByteBuffer src) throws SSLException {
+    private int writeEncryptedData(final MemorySegment networkBIO, final ByteBuffer src) throws SSLException {
         clearLastError();
         final int pos = src.position();
         final int len = src.remaining();
@@ -343,7 +343,7 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn
      * Read plain text data from the OpenSSL internal BIO
      * @throws SSLException if the OpenSSL error check fails
      */
-    private int readPlaintextData(final MemoryAddress ssl, final ByteBuffer dst) throws SSLException {
+    private int readPlaintextData(final MemorySegment ssl, final ByteBuffer dst) throws SSLException {
         clearLastError();
         final int pos = dst.position();
         final int len = Math.min(dst.remaining(), MAX_ENCRYPTED_PACKET_LENGTH);
@@ -365,7 +365,7 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn
      * Read encrypted data from the OpenSSL network BIO
      * @throws SSLException if the OpenSSL error check fails
      */
-    private int readEncryptedData(final MemoryAddress networkBIO, final ByteBuffer dst, final int pending) throws SSLException {
+    private int readEncryptedData(final MemorySegment networkBIO, final ByteBuffer dst, final int pending) throws SSLException {
         clearLastError();
         final int pos = dst.position();
         MemorySegment dstSegment = dst.isDirect() ? MemorySegment.ofBuffer(dst) : bufSegment;
@@ -716,7 +716,7 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn
         if (destroyed) {
             return new String[0];
         }
-        String[] enabled = getCiphers(state.ssl);
+        String[] enabled = getCiphers(state.ssl.address());
         if (enabled == null) {
             return new String[0];
         } else {
@@ -1792,8 +1792,9 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn
 
     private static class EngineState implements Runnable {
 
-        private final MemoryAddress ssl;
-        private final MemoryAddress networkBIO;
+        private final MemorySession stateSession = MemorySession.openShared();
+        private final MemorySegment ssl;
+        private final MemorySegment networkBIO;
         private final int certificateVerificationDepth;
         private final boolean noOcspCheck;
 
@@ -1804,17 +1805,22 @@ public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolIn
         private EngineState(MemoryAddress ssl, MemoryAddress networkBIO,
                 int certificateVerificationDepth, boolean noOcspCheck) {
             states.put(Long.valueOf(ssl.toRawLongValue()), this);
-            this.ssl = ssl;
-            this.networkBIO = networkBIO;
+            // Allocate another session to avoid keeping a reference through segments
+            this.ssl = MemorySegment.ofAddress(ssl, ValueLayout.ADDRESS.byteSize(), stateSession);
+            this.networkBIO = MemorySegment.ofAddress(networkBIO, ValueLayout.ADDRESS.byteSize(), stateSession);
             this.certificateVerificationDepth = certificateVerificationDepth;
             this.noOcspCheck = noOcspCheck;
         }
 
         @Override
         public void run() {
-            states.remove(Long.valueOf(ssl.toRawLongValue()));
-            BIO_free(networkBIO);
-            SSL_free(ssl);
+            try {
+                states.remove(Long.valueOf(ssl.address().toRawLongValue()));
+                BIO_free(networkBIO);
+                SSL_free(ssl);
+            } finally {
+                stateSession.close();
+            }
         }
     }
 }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index b4080ba318..25b43791f2 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -105,6 +105,13 @@
   issues do not "pop up" wrt. others).
 -->
 <section name="Tomcat 10.1.0-M20 (markt)" rtext="in development">
+  <subsection name="Coyote">
+    <changelog>
+      <fix>
+        Prepare OpenSSL Panama module for Java 20 API changes. (remm)
+      </fix>
+    </changelog>
+  </subsection>
 </section>
 <section name="Tomcat 10.1.0-M19 (markt)" rtext="release in progress">
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org