@@ -1077,20 +1077,17 @@ private SSLException shutdownWithError(String operations, int sslError) {
10771077 }
10781078
10791079 private SSLException shutdownWithError (String operation , int sslError , int error ) {
1080- String errorString = SSL .getErrorString (error );
10811080 if (logger .isDebugEnabled ()) {
1081+ String errorString = SSL .getErrorString (error );
10821082 logger .debug ("{} failed with {}: OpenSSL error: {} {}" ,
10831083 operation , sslError , error , errorString );
10841084 }
10851085
10861086 // There was an internal error -- shutdown
10871087 shutdown ();
1088- if (handshakeState == HandshakeState .FINISHED ) {
1089- return new SSLException (errorString );
1090- }
10911088
1092- SSLHandshakeException exception = new SSLHandshakeException ( errorString );
1093- // If we have a handshakeException stored already we should include it as well to help the user debug things.
1089+ SSLException exception = newSSLExceptionForError ( error );
1090+ // If we have a pendingException stored already we should include it as well to help the user debug things.
10941091 if (pendingException != null ) {
10951092 exception .initCause (pendingException );
10961093 pendingException = null ;
@@ -1360,15 +1357,12 @@ private boolean needWrapAgain(int stackError) {
13601357 // This is needed so we ensure close_notify etc is correctly send to the remote peer.
13611358 // See https://github.com/netty/netty/issues/3900
13621359 if (SSL .bioLengthNonApplication (networkBIO ) > 0 ) {
1363- // we seems to have data left that needs to be transferred and so the user needs
1360+ // we seem to have data left that needs to be transferred and so the user needs
13641361 // call wrap(...). Store the error so we can pick it up later.
1365- String message = SSL .getErrorString (stackError );
1366- SSLException exception = handshakeState == HandshakeState .FINISHED ?
1367- new SSLException (message ) : new SSLHandshakeException (message );
13681362 if (pendingException == null ) {
1369- pendingException = exception ;
1370- } else {
1371- ThrowableUtil .addSuppressed (pendingException , exception );
1363+ pendingException = newSSLExceptionForError ( stackError ) ;
1364+ } else if ( shouldAddSuppressed ( pendingException , stackError )) {
1365+ ThrowableUtil .addSuppressed (pendingException , newSSLExceptionForError ( stackError ) );
13721366 }
13731367 // We need to clear all errors so we not pick up anything that was left on the stack on the next
13741368 // operation. Note that shutdownWithError(...) will cleanup the stack as well so its only needed here.
@@ -1378,6 +1372,23 @@ private boolean needWrapAgain(int stackError) {
13781372 return false ;
13791373 }
13801374
1375+ private SSLException newSSLExceptionForError (int stackError ) {
1376+ String message = SSL .getErrorString (stackError );
1377+ return handshakeState == HandshakeState .FINISHED ?
1378+ new OpenSslException (message , stackError ) : new OpenSslHandshakeException (message , stackError );
1379+ }
1380+
1381+ private static boolean shouldAddSuppressed (Throwable target , int errorCode ) {
1382+ for (Throwable suppressed : ThrowableUtil .getSuppressed (target )) {
1383+ if (suppressed instanceof NativeSslException &&
1384+ ((NativeSslException ) suppressed ).errorCode () == errorCode ) {
1385+ /// An exception with this errorCode was already added before.
1386+ return false ;
1387+ }
1388+ }
1389+ return true ;
1390+ }
1391+
13811392 private SSLEngineResult sslReadErrorResult (int error , int stackError , int bytesConsumed , int bytesProduced )
13821393 throws SSLException {
13831394 if (needWrapAgain (stackError )) {
@@ -2661,4 +2672,36 @@ public String toString() {
26612672 '}' ;
26622673 }
26632674 }
2675+
2676+ private interface NativeSslException {
2677+ int errorCode ();
2678+ }
2679+
2680+ private static final class OpenSslException extends SSLException implements NativeSslException {
2681+ private final int errorCode ;
2682+
2683+ OpenSslException (String reason , int errorCode ) {
2684+ super (reason );
2685+ this .errorCode = errorCode ;
2686+ }
2687+
2688+ @ Override
2689+ public int errorCode () {
2690+ return errorCode ;
2691+ }
2692+ }
2693+
2694+ private static final class OpenSslHandshakeException extends SSLHandshakeException implements NativeSslException {
2695+ private final int errorCode ;
2696+
2697+ OpenSslHandshakeException (String reason , int errorCode ) {
2698+ super (reason );
2699+ this .errorCode = errorCode ;
2700+ }
2701+
2702+ @ Override
2703+ public int errorCode () {
2704+ return errorCode ;
2705+ }
2706+ }
26642707}
0 commit comments