Merge pull request #274 from cconlon/WolfSSLAuthStoreLock

Reduce synchronization overhead in WolfSSLAuthStore
master
JacobBarthelmeh 2025-06-10 16:33:58 -06:00 committed by GitHub
commit b85d4a18a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 126 additions and 112 deletions

View File

@ -548,9 +548,13 @@ public class WolfSSLDebug {
} }
/** /**
* Check if debug logging is enabled for the specified component * Check if debug logging is enabled for the specified component.
*
* @param component the component to check (JNI or JSSE)
*
* @return true if debug logging is enabled for the component,
*/ */
private static boolean isDebugEnabled(Component component) { public static boolean isDebugEnabled(Component component) {
if (component == Component.JSSE && DEBUG) { if (component == Component.JSSE && DEBUG) {
return true; return true;
} }

View File

@ -314,13 +314,14 @@ public class WolfSSLAuthStore {
* object if not in cache, called on server side, or host * object if not in cache, called on server side, or host
* is null * is null
*/ */
protected synchronized WolfSSLImplementSSLSession getSession( protected WolfSSLImplementSSLSession getSession(
WolfSSLSession ssl, int port, String host, boolean clientMode, WolfSSLSession ssl, int port, String host, boolean clientMode,
String[] enabledCipherSuites, String[] enabledProtocols) { String[] enabledCipherSuites, String[] enabledProtocols) {
boolean needNewSession = false; boolean needNewSession = false;
WolfSSLImplementSSLSession ses = null; WolfSSLImplementSSLSession ses = null;
String toHash = null; String toHash = null;
int hashCode = 0;
if (ssl == null) { if (ssl == null) {
return null; return null;
@ -339,22 +340,25 @@ public class WolfSSLAuthStore {
* Synchronizes on storeLock internally. */ * Synchronizes on storeLock internally. */
printSessionStoreStatus(); printSessionStoreStatus();
/* Lock on static/global storeLock, since Java session cache table /* Generate cache key hash (host:port), outside lock */
* is shared between all threads */ toHash = host.concat(Integer.toString(port));
hashCode = toHash.hashCode();
/* Lock on static/global storeLock while getting session out of
* store, since Java session cache table is shared between all
* threads */
synchronized (storeLock) { synchronized (storeLock) {
/* Generate cache key hash (host:port) */
toHash = host.concat(Integer.toString(port));
/* Try getting session out of Java store */ /* Try getting session out of Java store */
ses = store.get(toHash.hashCode()); ses = store.get(hashCode);
/* Remove old entry from table. TLS 1.3 binder changes between /* Remove old entry from table. TLS 1.3 binder changes between
* resumptions and stored session should only be used to * resumptions and stored session should only be used to
* resume once. New session structure/object will be cached * resume once. New session structure/object will be cached
* after the resumed session completes the handshake, for * after the resumed session completes the handshake, for
* subsequent resumption attempts to use. */ * subsequent resumption attempts to use. */
store.remove(toHash.hashCode()); store.remove(hashCode);
}
/* Check conditions where we need to create a new new session: /* Check conditions where we need to create a new new session:
* 1. Session not found in cache * 1. Session not found in cache
@ -437,7 +441,6 @@ public class WolfSSLAuthStore {
return ses; return ses;
} }
}
/** /**
* Check if cipher suite from original WOLFSSL_SESSION * Check if cipher suite from original WOLFSSL_SESSION
@ -531,6 +534,11 @@ public class WolfSSLAuthStore {
* prints out host:port of all sessions stored in the store. * prints out host:port of all sessions stored in the store.
* Called by getSession(). */ * Called by getSession(). */
private void printSessionStoreStatus() { private void printSessionStoreStatus() {
if (!WolfSSLDebug.isDebugEnabled(WolfSSLDebug.Component.JSSE)) {
return;
}
synchronized (storeLock) { synchronized (storeLock) {
Collection<WolfSSLImplementSSLSession> values = Collection<WolfSSLImplementSSLSession> values =
store.values(); store.values();
@ -640,8 +648,6 @@ public class WolfSSLAuthStore {
return WolfSSL.SSL_FAILURE; return WolfSSL.SSL_FAILURE;
} }
/* Lock access to store while adding new session, store is global */
synchronized (storeLock) {
if (session.getPeerHost() != null) { if (session.getPeerHost() != null) {
/* Generate key for storing into session table (host:port) */ /* Generate key for storing into session table (host:port) */
toHash = session.getPeerHost().concat(Integer.toString( toHash = session.getPeerHost().concat(Integer.toString(
@ -669,10 +675,14 @@ public class WolfSSLAuthStore {
session.getPeerHost() + ", port: " + session.getPeerHost() + ", port: " +
session.getPeerPort() + ") " + "hashCode = " + hashCode + session.getPeerPort() + ") " + "hashCode = " + hashCode +
" side = " + session.getSideString()); " side = " + session.getSideString());
store.put(hashCode, session);
session.isInTable = true; session.isInTable = true;
printSessionStoreStatus();
/* Lock access to store while adding new session, store is global */
synchronized (storeLock) {
store.put(hashCode, session);
} }
printSessionStoreStatus();
} }
return WolfSSL.SSL_SUCCESS; return WolfSSL.SSL_SUCCESS;