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