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