View Javadoc
1   /*
2    * Copyright 2014 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.netty5.handler.ssl;
17  
18  import io.netty.internal.tcnative.SSLContext;
19  
20  import java.util.concurrent.locks.Lock;
21  
22  /**
23   * Stats exposed by an OpenSSL session context.
24   *
25   * @see <a href="https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_number.html">SSL_CTX_sess_number</a>
26   */
27  public final class OpenSslSessionStats {
28  
29      private final ReferenceCountedOpenSslContext context;
30  
31      // IMPORTANT: We take the OpenSslContext and not just the long (which points the native instance) to prevent
32      //            the GC to collect OpenSslContext as this would also free the pointer and so could result in a
33      //            segfault when the user calls any of the methods here that try to pass the pointer down to the native
34      //            level.
35      OpenSslSessionStats(ReferenceCountedOpenSslContext context) {
36          this.context = context;
37      }
38  
39      /**
40       * Returns the current number of sessions in the internal session cache.
41       */
42      public long number() {
43          Lock readerLock = context.ctxLock.readLock();
44          readerLock.lock();
45          try {
46              return SSLContext.sessionNumber(context.ctx);
47          } finally {
48              readerLock.unlock();
49          }
50      }
51  
52      /**
53       * Returns the number of started SSL/TLS handshakes in client mode.
54       */
55      public long connect() {
56          Lock readerLock = context.ctxLock.readLock();
57          readerLock.lock();
58          try {
59              return SSLContext.sessionConnect(context.ctx);
60          } finally {
61              readerLock.unlock();
62          }
63      }
64  
65      /**
66       * Returns the number of successfully established SSL/TLS sessions in client mode.
67       */
68      public long connectGood() {
69          Lock readerLock = context.ctxLock.readLock();
70          readerLock.lock();
71          try {
72              return SSLContext.sessionConnectGood(context.ctx);
73          } finally {
74              readerLock.unlock();
75          }
76      }
77  
78      /**
79       * Returns the number of start renegotiations in client mode.
80       */
81      public long connectRenegotiate() {
82          Lock readerLock = context.ctxLock.readLock();
83          readerLock.lock();
84          try {
85              return SSLContext.sessionConnectRenegotiate(context.ctx);
86          } finally {
87              readerLock.unlock();
88          }
89      }
90  
91      /**
92       * Returns the number of started SSL/TLS handshakes in server mode.
93       */
94      public long accept() {
95          Lock readerLock = context.ctxLock.readLock();
96          readerLock.lock();
97          try {
98              return SSLContext.sessionAccept(context.ctx);
99          } finally {
100             readerLock.unlock();
101         }
102     }
103 
104     /**
105      * Returns the number of successfully established SSL/TLS sessions in server mode.
106      */
107     public long acceptGood() {
108         Lock readerLock = context.ctxLock.readLock();
109         readerLock.lock();
110         try {
111             return SSLContext.sessionAcceptGood(context.ctx);
112         } finally {
113             readerLock.unlock();
114         }
115     }
116 
117     /**
118      * Returns the number of start renegotiations in server mode.
119      */
120     public long acceptRenegotiate() {
121         Lock readerLock = context.ctxLock.readLock();
122         readerLock.lock();
123         try {
124             return SSLContext.sessionAcceptRenegotiate(context.ctx);
125         } finally {
126             readerLock.unlock();
127         }
128     }
129 
130     /**
131      * Returns the number of successfully reused sessions. In client mode, a session set with {@code SSL_set_session}
132      * successfully reused is counted as a hit. In server mode, a session successfully retrieved from internal or
133      * external cache is counted as a hit.
134      */
135     public long hits() {
136         Lock readerLock = context.ctxLock.readLock();
137         readerLock.lock();
138         try {
139             return SSLContext.sessionHits(context.ctx);
140         } finally {
141             readerLock.unlock();
142         }
143     }
144 
145     /**
146      * Returns the number of successfully retrieved sessions from the external session cache in server mode.
147      */
148     public long cbHits() {
149         Lock readerLock = context.ctxLock.readLock();
150         readerLock.lock();
151         try {
152             return SSLContext.sessionCbHits(context.ctx);
153         } finally {
154             readerLock.unlock();
155         }
156     }
157 
158     /**
159      * Returns the number of sessions proposed by clients that were not found in the internal session cache
160      * in server mode.
161      */
162     public long misses() {
163         Lock readerLock = context.ctxLock.readLock();
164         readerLock.lock();
165         try {
166             return SSLContext.sessionMisses(context.ctx);
167         } finally {
168             readerLock.unlock();
169         }
170     }
171 
172     /**
173      * Returns the number of sessions proposed by clients and either found in the internal or external session cache
174      * in server mode, but that were invalid due to timeout. These sessions are not included in the {@link #hits()}
175      * count.
176      */
177     public long timeouts() {
178         Lock readerLock = context.ctxLock.readLock();
179         readerLock.lock();
180         try {
181             return SSLContext.sessionTimeouts(context.ctx);
182         } finally {
183             readerLock.unlock();
184         }
185     }
186 
187     /**
188      * Returns the number of sessions that were removed because the maximum session cache size was exceeded.
189      */
190     public long cacheFull() {
191         Lock readerLock = context.ctxLock.readLock();
192         readerLock.lock();
193         try {
194             return SSLContext.sessionCacheFull(context.ctx);
195         } finally {
196             readerLock.unlock();
197         }
198     }
199 
200     /**
201      * Returns the number of times a client presented a ticket that did not match any key in the list.
202      */
203     public long ticketKeyFail() {
204         Lock readerLock = context.ctxLock.readLock();
205         readerLock.lock();
206         try {
207             return SSLContext.sessionTicketKeyFail(context.ctx);
208         } finally {
209             readerLock.unlock();
210         }
211     }
212 
213     /**
214      * Returns the number of times a client did not present a ticket and we issued a new one
215      */
216     public long ticketKeyNew() {
217         Lock readerLock = context.ctxLock.readLock();
218         readerLock.lock();
219         try {
220             return SSLContext.sessionTicketKeyNew(context.ctx);
221         } finally {
222             readerLock.unlock();
223         }
224     }
225 
226     /**
227      * Returns the number of times a client presented a ticket derived from an older key,
228      * and we upgraded to the primary key.
229      */
230     public long ticketKeyRenew() {
231         Lock readerLock = context.ctxLock.readLock();
232         readerLock.lock();
233         try {
234             return SSLContext.sessionTicketKeyRenew(context.ctx);
235         } finally {
236             readerLock.unlock();
237         }
238     }
239 
240     /**
241      * Returns the number of times a client presented a ticket derived from the primary key.
242      */
243     public long ticketKeyResume() {
244         Lock readerLock = context.ctxLock.readLock();
245         readerLock.lock();
246         try {
247             return SSLContext.sessionTicketKeyResume(context.ctx);
248         } finally {
249             readerLock.unlock();
250         }
251     }
252 }