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 #pragma once 18 19 #include <list> 20 #include <map> 21 #include <mutex> 22 #include <vector> 23 24 #include <android-base/thread_annotations.h> 25 26 #include "DnsTlsServer.h" 27 28 namespace android { 29 namespace net { 30 31 // The DNS over TLS mode on a specific netId. 32 enum class PrivateDnsMode : uint8_t { OFF, OPPORTUNISTIC, STRICT }; 33 34 // Validation status of a DNS over TLS server (on a specific netId). 35 enum class Validation : uint8_t { in_process, success, fail, unknown_server, unknown_netid }; 36 37 struct PrivateDnsStatus { 38 PrivateDnsMode mode; 39 std::map<DnsTlsServer, Validation, AddressComparator> serversMap; 40 validatedServersPrivateDnsStatus41 std::list<DnsTlsServer> validatedServers() const { 42 std::list<DnsTlsServer> servers; 43 44 for (const auto& pair : serversMap) { 45 if (pair.second == Validation::success) { 46 servers.push_back(pair.first); 47 } 48 } 49 return servers; 50 } 51 }; 52 53 class PrivateDnsConfiguration { 54 public: 55 int set(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, 56 const std::string& name, const std::string& caCert) EXCLUDES(mPrivateDnsLock); 57 58 PrivateDnsStatus getStatus(unsigned netId) EXCLUDES(mPrivateDnsLock); 59 60 void clear(unsigned netId) EXCLUDES(mPrivateDnsLock); 61 62 private: 63 typedef std::map<DnsTlsServer, Validation, AddressComparator> PrivateDnsTracker; 64 typedef std::set<DnsTlsServer, AddressComparator> ThreadTracker; 65 66 void validatePrivateDnsProvider(const DnsTlsServer& server, PrivateDnsTracker& tracker, 67 unsigned netId, uint32_t mark) REQUIRES(mPrivateDnsLock); 68 69 bool recordPrivateDnsValidation(const DnsTlsServer& server, unsigned netId, bool success); 70 71 bool needValidateThread(const DnsTlsServer& server, unsigned netId) REQUIRES(mPrivateDnsLock); 72 void cleanValidateThreadTracker(const DnsTlsServer& server, unsigned netId); 73 74 // Start validation for newly added servers as well as any servers that have 75 // landed in Validation::fail state. Note that servers that have failed 76 // multiple validation attempts but for which there is still a validating 77 // thread running are marked as being Validation::in_process. 78 bool needsValidation(const PrivateDnsTracker& tracker, const DnsTlsServer& server); 79 80 std::mutex mPrivateDnsLock; 81 std::map<unsigned, PrivateDnsMode> mPrivateDnsModes GUARDED_BY(mPrivateDnsLock); 82 // Structure for tracking the validation status of servers on a specific netId. 83 // Using the AddressComparator ensures at most one entry per IP address. 84 std::map<unsigned, PrivateDnsTracker> mPrivateDnsTransports GUARDED_BY(mPrivateDnsLock); 85 std::map<unsigned, ThreadTracker> mPrivateDnsValidateThreads GUARDED_BY(mPrivateDnsLock); 86 }; 87 88 extern PrivateDnsConfiguration gPrivateDnsConfiguration; 89 90 } // namespace net 91 } // namespace android 92