1 /* 2 * Copyright (C) 2018 The Android Open Source Project 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 17 #include "DnsTlsSessionCache.h" 18 19 #define LOG_TAG "resolv" 20 21 #include <android-base/logging.h> 22 23 namespace android { 24 namespace net { 25 26 bool DnsTlsSessionCache::prepareSsl(SSL* ssl) { 27 // Add this cache as the 0-index extra data for the socket. 28 // This is used by newSessionCallback. 29 int ret = SSL_set_ex_data(ssl, 0, this); 30 return ret == 1; 31 } 32 33 void DnsTlsSessionCache::prepareSslContext(SSL_CTX* ssl_ctx) { 34 SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_CLIENT); 35 SSL_CTX_sess_set_new_cb(ssl_ctx, &DnsTlsSessionCache::newSessionCallback); 36 } 37 38 // static 39 int DnsTlsSessionCache::newSessionCallback(SSL* ssl, SSL_SESSION* session) { 40 if (!ssl || !session) { 41 LOG(ERROR) << "Null SSL object in new session callback"; 42 return 0; 43 } 44 DnsTlsSessionCache* cache = reinterpret_cast<DnsTlsSessionCache*>( 45 SSL_get_ex_data(ssl, 0)); 46 if (!cache) { 47 LOG(ERROR) << "null transport in new session callback"; 48 return 0; 49 } 50 LOG(DEBUG) << "Recording session"; 51 cache->recordSession(session); 52 return 1; // Increment the refcount of session. 53 } 54 55 void DnsTlsSessionCache::recordSession(SSL_SESSION* session) { 56 std::lock_guard guard(mLock); 57 mSessions.emplace_front(session); 58 if (mSessions.size() > kMaxSize) { 59 LOG(DEBUG) << "Too many sessions; trimming"; 60 mSessions.pop_back(); 61 } 62 } 63 64 bssl::UniquePtr<SSL_SESSION> DnsTlsSessionCache::getSession() { 65 std::lock_guard guard(mLock); 66 if (mSessions.size() == 0) { 67 LOG(DEBUG) << "No known sessions"; 68 return nullptr; 69 } 70 bssl::UniquePtr<SSL_SESSION> ret = std::move(mSessions.front()); 71 mSessions.pop_front(); 72 return ret; 73 } 74 75 } // end of namespace net 76 } // end of namespace android 77