View Javadoc
1   /*
2    * Copyright 2026 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.handler.ssl;
17  
18  import io.netty.internal.tcnative.SSLCredential;
19  import io.netty.util.AbstractReferenceCounted;
20  import io.netty.util.IllegalReferenceCountException;
21  import io.netty.util.ResourceLeakDetector;
22  import io.netty.util.ResourceLeakDetectorFactory;
23  import io.netty.util.ResourceLeakTracker;
24  
25  /**
26   * Default implementation of {@link OpenSslCredential}.
27   *
28   * <p>This class manages the lifecycle of a native BoringSSL {@code SSL_CREDENTIAL} object.
29   */
30  final class DefaultOpenSslCredential extends AbstractReferenceCounted implements OpenSslCredentialPointer {
31  
32      private static final ResourceLeakDetector<DefaultOpenSslCredential> leakDetector =
33              ResourceLeakDetectorFactory.instance().newResourceLeakDetector(DefaultOpenSslCredential.class);
34  
35      private final ResourceLeakTracker<DefaultOpenSslCredential> leak;
36      private final CredentialType type;
37      private long credential;
38  
39      /**
40       * Creates a new credential instance.
41       *
42       * @param credential the native SSL_CREDENTIAL pointer
43       * @param type the credential type
44       */
45      DefaultOpenSslCredential(long credential, CredentialType type) {
46          this.credential = credential;
47          this.type = type;
48          this.leak = leakDetector.track(this);
49      }
50  
51      @Override
52      public long credentialAddress() {
53          if (refCnt() <= 0) {
54              throw new IllegalReferenceCountException();
55          }
56          return credential;
57      }
58  
59      @Override
60      public CredentialType type() {
61          return type;
62      }
63  
64      @Override
65      protected void deallocate() {
66          try {
67              SSLCredential.free(credential);
68          } catch (Exception e) {
69              throw new IllegalStateException("Failed to free SSL_CREDENTIAL", e);
70          } finally {
71              credential = 0;
72              if (leak != null) {
73                  boolean closed = leak.close(this);
74                  assert closed;
75              }
76          }
77      }
78  
79      @Override
80      public DefaultOpenSslCredential retain() {
81          if (leak != null) {
82              leak.record();
83          }
84          super.retain();
85          return this;
86      }
87  
88      @Override
89      public DefaultOpenSslCredential retain(int increment) {
90          if (leak != null) {
91              leak.record();
92          }
93          super.retain(increment);
94          return this;
95      }
96  
97      @Override
98      public DefaultOpenSslCredential touch() {
99          if (leak != null) {
100             leak.record();
101         }
102         super.touch();
103         return this;
104     }
105 
106     @Override
107     public DefaultOpenSslCredential touch(Object hint) {
108         if (leak != null) {
109             leak.record(hint);
110         }
111         return this;
112     }
113 
114     @Override
115     public boolean release() {
116         if (leak != null) {
117             leak.record();
118         }
119         return super.release();
120     }
121 
122     @Override
123     public boolean release(int decrement) {
124         if (leak != null) {
125             leak.record();
126         }
127         return super.release(decrement);
128     }
129 }