1 /*
2  * Copyright (C) 2019 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 
18 #pragma once
19 
20 #include <memory>
21 #include <string>
22 #include <vector>
23 
24 #include <android-base/format.h>
25 #include <android-base/logging.h>
26 #include <android-base/result.h>
27 
28 #include <aidl/android/net/IDnsResolver.h>
29 #include <aidl/android/net/INetd.h>
30 #include "ResolverStats.h"  // TODO: stop depending on this internal header
31 #include "dns_responder.h"
32 #include "dns_tls_certificate.h"
33 #include "params.h"
34 
35 using aidl::android::net::NativeNetworkConfig;
36 using aidl::android::net::NativeNetworkType;
37 using aidl::android::net::NativeVpnType;
38 
39 inline constexpr char kDefaultServer[] = "127.0.0.3";
40 inline constexpr char kDefaultSearchDomain[] = "example.com";
41 
42 #define SKIP_IF_REMOTE_VERSION_LESS_THAN(service, version)                                         \
43     do {                                                                                           \
44         if (!DnsResponderClient::isRemoteVersionSupported(service, version)) {                     \
45             std::cerr << "    Skip test. Remote version is too old, required version: " << version \
46                       << std::endl;                                                                \
47             return;                                                                                \
48         }                                                                                          \
49     } while (0)
50 
51 // A thin wrapper to store the outputs of DnsResolver::getResolverInfo().
52 struct ResolverInfo {
53     std::vector<std::string> dnsServers;
54     std::vector<std::string> domains;
55     std::vector<std::string> dotServers;
56     res_params params;
57     std::vector<android::net::ResolverStats> stats;
58     int waitForPendingReqTimeoutCount;
59 };
60 
61 class ResolverParams {
62   public:
63     class Builder {
64       public:
65         Builder();
setDnsServers(const std::vector<std::string> & servers)66         constexpr Builder& setDnsServers(const std::vector<std::string>& servers) {
67             mParcel.servers = servers;
68             return *this;
69         }
setDotServers(const std::vector<std::string> & servers)70         constexpr Builder& setDotServers(const std::vector<std::string>& servers) {
71             mParcel.tlsServers = servers;
72             return *this;
73         }
setDomains(const std::vector<std::string> & domains)74         constexpr Builder& setDomains(const std::vector<std::string>& domains) {
75             mParcel.domains = domains;
76             return *this;
77         }
setPrivateDnsProvider(const std::string & provider)78         constexpr Builder& setPrivateDnsProvider(const std::string& provider) {
79             mParcel.tlsName = provider;
80             return *this;
81         }
setParams(const std::array<int,aidl::android::net::IDnsResolver::RESOLVER_PARAMS_COUNT> & params)82         constexpr Builder& setParams(
83                 const std::array<int, aidl::android::net::IDnsResolver::RESOLVER_PARAMS_COUNT>&
84                         params) {
85             using aidl::android::net::IDnsResolver;
86             mParcel.sampleValiditySeconds = params[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY];
87             mParcel.successThreshold = params[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD];
88             mParcel.minSamples = params[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES];
89             mParcel.maxSamples = params[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES];
90             mParcel.baseTimeoutMsec = params[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC];
91             mParcel.retryCount = params[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT];
92             return *this;
93         }
setMetered(const bool metered)94         constexpr Builder& setMetered(const bool metered) {
95             mParcel.meteredNetwork = metered;
96             return *this;
97         }
setDohParams(const aidl::android::net::resolv::aidl::DohParamsParcel & dohParams)98         constexpr Builder& setDohParams(
99                 const aidl::android::net::resolv::aidl::DohParamsParcel& dohParams) {
100             mParcel.dohParams = dohParams;
101             return *this;
102         }
build()103         aidl::android::net::ResolverParamsParcel build() { return mParcel; }
104 
105       private:
106         aidl::android::net::ResolverParamsParcel mParcel;
107     };
108 };
109 
110 // TODO: Remove dns_responder_client_ndk.{h,cpp} after replacing the binder usage of
111 // dns_responder_client.*
112 class DnsResponderClient {
113   public:
114     struct Mapping {
115         std::string host;
116         std::string entry;
117         std::string ip4;
118         std::string ip6;
119     };
120 
121     virtual ~DnsResponderClient() = default;
122 
123     static void SetupMappings(unsigned num_hosts, const std::vector<std::string>& domains,
124                               std::vector<Mapping>* mappings);
125 
126     // Sets up DnsResolver with given DNS servers. This is used to set up for private DNS off mode.
127     bool SetResolversForNetwork(const std::vector<std::string>& servers = {kDefaultServer},
128                                 const std::vector<std::string>& domains = {kDefaultSearchDomain});
129 
130     // Sets up DnsResolver from a given parcel.
131     bool SetResolversFromParcel(const aidl::android::net::ResolverParamsParcel& resolverParams);
132 
133     template <class T>
isRemoteVersionSupported(T remoteService,int requiredVersion)134     static bool isRemoteVersionSupported(T remoteService, int requiredVersion) {
135         int remoteVersion = 0;
136         if (!remoteService->getInterfaceVersion(&remoteVersion).isOk()) {
137             LOG(FATAL) << "Can't get remote version";
138         }
139         if (remoteVersion < requiredVersion) {
140             LOG(WARNING) << fmt::format("Remote version: {} < Required version: {}", remoteVersion,
141                                         requiredVersion);
142             return false;
143         }
144         return true;
145     };
146 
147     static NativeNetworkConfig makeNativeNetworkConfig(int netId, NativeNetworkType networkType,
148                                                        int permission, bool secure);
149 
150     android::base::Result<ResolverInfo> getResolverInfo();
151 
152     // Return a default resolver configuration for opportunistic mode.
153     static aidl::android::net::ResolverParamsParcel GetDefaultResolverParamsParcel();
154 
155     static void SetupDNSServers(unsigned numServers, const std::vector<Mapping>& mappings,
156                                 std::vector<std::unique_ptr<test::DNSResponder>>* dns,
157                                 std::vector<std::string>* servers);
158 
159     // Returns 0 on success and a negative value on failure.
160     int SetupOemNetwork(int oemNetId);
161     int TearDownOemNetwork(int oemNetId);
162 
163     virtual void SetUp();
164     virtual void TearDown();
165 
resolvService()166     aidl::android::net::IDnsResolver* resolvService() const { return mDnsResolvSrv.get(); }
netdService()167     aidl::android::net::INetd* netdService() const { return mNetdSrv.get(); }
168 
169   private:
170     std::shared_ptr<aidl::android::net::INetd> mNetdSrv;
171     std::shared_ptr<aidl::android::net::IDnsResolver> mDnsResolvSrv;
172 };
173