blob: be9c669710ed5ce3b93a4ce24091e3b0f365b3de [file] [log] [blame]
Ben Schwartz66810f62017-10-16 19:27:46 -04001/*
2 * Copyright (C) 2017 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
Ben Schwartzded1b702017-10-25 14:41:02 -040017#define LOG_TAG "DnsTlsDispatcher"
18//#define LOG_NDEBUG 0
19
Ben Schwartz66810f62017-10-16 19:27:46 -040020#include "dns/DnsTlsDispatcher.h"
21
Ben Schwartzded1b702017-10-25 14:41:02 -040022#include "log/log.h"
23
Ben Schwartz66810f62017-10-16 19:27:46 -040024namespace android {
25namespace net {
26
Ben Schwartzded1b702017-10-25 14:41:02 -040027using netdutils::Slice;
28
Ben Schwartz66810f62017-10-16 19:27:46 -040029// static
30std::mutex DnsTlsDispatcher::sLock;
Ben Schwartz66810f62017-10-16 19:27:46 -040031DnsTlsTransport::Response DnsTlsDispatcher::query(const DnsTlsServer& server, unsigned mark,
Ben Schwartzded1b702017-10-25 14:41:02 -040032 const Slice query,
33 const Slice ans, int *resplen) {
Ben Schwartz66810f62017-10-16 19:27:46 -040034 const Key key = std::make_pair(mark, server);
35 Transport* xport;
36 {
37 std::lock_guard<std::mutex> guard(sLock);
Ben Schwartzded1b702017-10-25 14:41:02 -040038 auto it = mStore.find(key);
39 if (it == mStore.end()) {
40 xport = new Transport(server, mark, mFactory.get());
41 mStore[key].reset(xport);
Ben Schwartz66810f62017-10-16 19:27:46 -040042 } else {
43 xport = it->second.get();
44 }
45 ++xport->useCount;
46 }
47
Ben Schwartzded1b702017-10-25 14:41:02 -040048 ALOGV("Sending query of length %zu", query.size());
49 auto result = xport->transport.query(query);
50 DnsTlsTransport::Response code = result.code;
51 if (code == DnsTlsTransport::Response::success) {
52 if (result.response.size() > ans.size()) {
53 ALOGV("Response too large: %zu > %zu", result.response.size(), ans.size());
54 code = DnsTlsTransport::Response::limit_error;
55 } else {
56 ALOGV("Got response successfully");
57 *resplen = result.response.size();
58 netdutils::copy(ans, netdutils::makeSlice(result.response));
59 }
60 } else {
61 ALOGV("Query failed: %u", (unsigned int)code);
62 }
63
Ben Schwartz66810f62017-10-16 19:27:46 -040064 auto now = std::chrono::steady_clock::now();
65 {
66 std::lock_guard<std::mutex> guard(sLock);
67 --xport->useCount;
68 xport->lastUsed = now;
69 cleanup(now);
70 }
Ben Schwartzded1b702017-10-25 14:41:02 -040071 return code;
Ben Schwartz66810f62017-10-16 19:27:46 -040072}
73
Ben Schwartzded1b702017-10-25 14:41:02 -040074// This timeout effectively controls how long to keep SSL session tickets.
Ben Schwartz66810f62017-10-16 19:27:46 -040075static constexpr std::chrono::minutes IDLE_TIMEOUT(5);
Ben Schwartz66810f62017-10-16 19:27:46 -040076void DnsTlsDispatcher::cleanup(std::chrono::time_point<std::chrono::steady_clock> now) {
Ben Schwartzded1b702017-10-25 14:41:02 -040077 // To avoid scanning mStore after every query, return early if a cleanup has been
78 // performed recently.
79 if (now - mLastCleanup < IDLE_TIMEOUT) {
Ben Schwartz66810f62017-10-16 19:27:46 -040080 return;
81 }
Ben Schwartzded1b702017-10-25 14:41:02 -040082 for (auto it = mStore.begin(); it != mStore.end();) {
Ben Schwartz66810f62017-10-16 19:27:46 -040083 auto& s = it->second;
84 if (s->useCount == 0 && now - s->lastUsed > IDLE_TIMEOUT) {
Ben Schwartzded1b702017-10-25 14:41:02 -040085 it = mStore.erase(it);
Ben Schwartz66810f62017-10-16 19:27:46 -040086 } else {
87 ++it;
88 }
89 }
Ben Schwartzded1b702017-10-25 14:41:02 -040090 mLastCleanup = now;
Ben Schwartz66810f62017-10-16 19:27:46 -040091}
92
Ben Schwartzded1b702017-10-25 14:41:02 -040093} // end of namespace net
94} // end of namespace android