1 | /* |
---|---|
2 | * Copyright 2017-present Facebook, Inc. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * 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, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | #include <folly/ssl/Init.h> |
17 | |
18 | #include <mutex> |
19 | |
20 | #include <folly/portability/OpenSSL.h> |
21 | #include <folly/ssl/detail/OpenSSLThreading.h> |
22 | #include <glog/logging.h> |
23 | |
24 | namespace folly { |
25 | namespace ssl { |
26 | |
27 | namespace { |
28 | bool initialized_ = false; |
29 | |
30 | std::mutex& initMutex() { |
31 | static std::mutex m; |
32 | return m; |
33 | } |
34 | |
35 | void initializeOpenSSLLocked() { |
36 | if (initialized_) { |
37 | return; |
38 | } |
39 | OPENSSL_init_ssl(0, nullptr); |
40 | randomize(); |
41 | initialized_ = true; |
42 | } |
43 | |
44 | void cleanupOpenSSLLocked() { |
45 | if (!initialized_) { |
46 | return; |
47 | } |
48 | |
49 | OPENSSL_cleanup(); |
50 | initialized_ = false; |
51 | } |
52 | } // namespace |
53 | |
54 | void init() { |
55 | std::lock_guard<std::mutex> g(initMutex()); |
56 | initializeOpenSSLLocked(); |
57 | } |
58 | |
59 | void cleanup() { |
60 | std::lock_guard<std::mutex> g(initMutex()); |
61 | cleanupOpenSSLLocked(); |
62 | } |
63 | |
64 | void markInitialized() { |
65 | std::lock_guard<std::mutex> g(initMutex()); |
66 | initialized_ = true; |
67 | } |
68 | |
69 | void setLockTypesAndInit(LockTypeMapping inLockTypes) { |
70 | std::lock_guard<std::mutex> g(initMutex()); |
71 | CHECK(!initialized_) << "OpenSSL is already initialized"; |
72 | detail::setLockTypes(std::move(inLockTypes)); |
73 | initializeOpenSSLLocked(); |
74 | } |
75 | |
76 | void setLockTypes(LockTypeMapping inLockTypes) { |
77 | std::lock_guard<std::mutex> g(initMutex()); |
78 | if (initialized_) { |
79 | // We set the locks on initialization, so if we are already initialized |
80 | // this would have no affect. |
81 | LOG(INFO) << "Ignoring setSSLLockTypes after initialization"; |
82 | return; |
83 | } |
84 | detail::setLockTypes(std::move(inLockTypes)); |
85 | } |
86 | |
87 | void randomize() { |
88 | RAND_poll(); |
89 | } |
90 | |
91 | bool isLockDisabled(int lockId) { |
92 | return detail::isSSLLockDisabled(lockId); |
93 | } |
94 | |
95 | } // namespace ssl |
96 | } // namespace folly |
97 |