blob: d5c0fb2f670e243afc1b1fceed1b0e97c167d341 [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());
Ben Schwartz33860762017-10-25 14:41:02 -040049 auto res = xport->transport.query(query);
50 ALOGV("Awaiting response");
51 const auto& result = res.get();
Ben Schwartzded1b702017-10-25 14:41:02 -040052 DnsTlsTransport::Response code = result.code;
53 if (code == DnsTlsTransport::Response::success) {
54 if (result.response.size() > ans.size()) {
55 ALOGV("Response too large: %zu > %zu", result.response.size(), ans.size());
56 code = DnsTlsTransport::Response::limit_error;
57 } else {
58 ALOGV("Got response successfully");
59 *resplen = result.response.size();
60 netdutils::copy(ans, netdutils::makeSlice(result.response));
61 }
62 } else {
63 ALOGV("Query failed: %u", (unsigned int)code);
64 }
65
Ben Schwartz66810f62017-10-16 19:27:46 -040066 auto now = std::chrono::steady_clock::now();
67 {
68 std::lock_guard<std::mutex> guard(sLock);
69 --xport->useCount;
70 xport->lastUsed = now;
71 cleanup(now);
72 }
Ben Schwartzded1b702017-10-25 14:41:02 -040073 return code;
Ben Schwartz66810f62017-10-16 19:27:46 -040074}
75
Ben Schwartzded1b702017-10-25 14:41:02 -040076// This timeout effectively controls how long to keep SSL session tickets.
Ben Schwartz66810f62017-10-16 19:27:46 -040077static constexpr std::chrono::minutes IDLE_TIMEOUT(5);
Ben Schwartz66810f62017-10-16 19:27:46 -040078void DnsTlsDispatcher::cleanup(std::chrono::time_point<std::chrono::steady_clock> now) {
Ben Schwartzded1b702017-10-25 14:41:02 -040079 // To avoid scanning mStore after every query, return early if a cleanup has been
80 // performed recently.
81 if (now - mLastCleanup < IDLE_TIMEOUT) {
Ben Schwartz66810f62017-10-16 19:27:46 -040082 return;
83 }
Ben Schwartzded1b702017-10-25 14:41:02 -040084 for (auto it = mStore.begin(); it != mStore.end();) {
Ben Schwartz66810f62017-10-16 19:27:46 -040085 auto& s = it->second;
86 if (s->useCount == 0 && now - s->lastUsed > IDLE_TIMEOUT) {
Ben Schwartzded1b702017-10-25 14:41:02 -040087 it = mStore.erase(it);
Ben Schwartz66810f62017-10-16 19:27:46 -040088 } else {
89 ++it;
90 }
91 }
Ben Schwartzded1b702017-10-25 14:41:02 -040092 mLastCleanup = now;
Ben Schwartz66810f62017-10-16 19:27:46 -040093}
94
Ben Schwartzded1b702017-10-25 14:41:02 -040095} // end of namespace net
96} // end of namespace android