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 <arpa/nameser.h> 21 #include <netdb.h> 22 23 #include <filesystem> 24 #include <functional> 25 #include <string> 26 #include <vector> 27 28 #include <aidl/android/net/INetd.h> 29 #include <aidl/android/net/ResolverParamsParcel.h> 30 #include <android-base/properties.h> 31 #include <android-modules-utils/sdk_level.h> 32 #include <firewall.h> 33 #include <gtest/gtest.h> 34 #include <netdutils/InternetAddresses.h> 35 36 #include "dns_responder/dns_responder.h" 37 #include "params.h" 38 #include "util.h" 39 40 class ScopeBlockedUIDRule { 41 using INetd = aidl::android::net::INetd; 42 43 public: ScopeBlockedUIDRule(INetd * netSrv,uid_t testUid)44 ScopeBlockedUIDRule(INetd* netSrv, uid_t testUid) 45 : mNetSrv(netSrv), mTestUid(testUid), mSavedUid(getuid()) { 46 // Add drop rule for testUid. Also enable the standby chain because it might not be 47 // enabled. Unfortunately we cannot use FIREWALL_CHAIN_NONE, or custom iptables rules, for 48 // this purpose because netd calls fchown() on the DNS query sockets, and "iptables -m 49 // owner" matches the UID of the socket creator, not the UID set by fchown(). 50 // TODO: migrate FIREWALL_CHAIN_NONE to eBPF as well. 51 if (android::modules::sdklevel::IsAtLeastT()) { 52 mFw = Firewall::getInstance(); 53 EXPECT_RESULT_OK(mFw->toggleStandbyMatch(true)); 54 EXPECT_RESULT_OK(mFw->addRule(mTestUid, STANDBY_MATCH)); 55 } else { 56 EXPECT_TRUE( 57 mNetSrv->firewallEnableChildChain(INetd::FIREWALL_CHAIN_STANDBY, true).isOk()); 58 EXPECT_TRUE(mNetSrv->firewallSetUidRule(INetd::FIREWALL_CHAIN_STANDBY, mTestUid, 59 INetd::FIREWALL_RULE_DENY) 60 .isOk()); 61 } 62 EXPECT_TRUE(seteuid(mTestUid) == 0); 63 }; ~ScopeBlockedUIDRule()64 ~ScopeBlockedUIDRule() { 65 // Restore uid 66 EXPECT_TRUE(seteuid(mSavedUid) == 0); 67 // Remove drop rule for testUid, and disable the standby chain. 68 if (android::modules::sdklevel::IsAtLeastT()) { 69 EXPECT_RESULT_OK(mFw->removeRule(mTestUid, STANDBY_MATCH)); 70 EXPECT_RESULT_OK(mFw->toggleStandbyMatch(false)); 71 } else { 72 EXPECT_TRUE(mNetSrv->firewallSetUidRule(INetd::FIREWALL_CHAIN_STANDBY, mTestUid, 73 INetd::FIREWALL_RULE_ALLOW) 74 .isOk()); 75 EXPECT_TRUE( 76 mNetSrv->firewallEnableChildChain(INetd::FIREWALL_CHAIN_STANDBY, false).isOk()); 77 } 78 } 79 80 private: 81 INetd* mNetSrv; 82 Firewall* mFw; 83 const uid_t mTestUid; 84 const uid_t mSavedUid; 85 }; 86 87 // Supported from T+ only. 88 class ScopedSetDataSaverByBPF { 89 public: ScopedSetDataSaverByBPF(bool wanted)90 ScopedSetDataSaverByBPF(bool wanted) { 91 if (android::modules::sdklevel::IsAtLeastT()) { 92 mFw = Firewall::getInstance(); 93 // Backup current setting. 94 const Result<bool> current = mFw->getDataSaverSetting(); 95 EXPECT_RESULT_OK(current); 96 if (wanted != current.value()) { 97 mSavedDataSaverSetting = current; 98 EXPECT_RESULT_OK(mFw->setDataSaver(wanted)); 99 } 100 } 101 }; ~ScopedSetDataSaverByBPF()102 ~ScopedSetDataSaverByBPF() { 103 // Restore the setting. 104 if (mSavedDataSaverSetting.has_value()) { 105 EXPECT_RESULT_OK(mFw->setDataSaver(mSavedDataSaverSetting.value())); 106 } 107 } 108 109 private: 110 Firewall* mFw; 111 Result<bool> mSavedDataSaverSetting; 112 }; 113 114 class ScopedChangeUID { 115 public: ScopedChangeUID(uid_t testUid)116 ScopedChangeUID(uid_t testUid) : mTestUid(testUid), mSavedUid(getuid()) { 117 EXPECT_TRUE(seteuid(mTestUid) == 0); 118 }; ~ScopedChangeUID()119 ~ScopedChangeUID() { EXPECT_TRUE(seteuid(mSavedUid) == 0); } 120 121 private: 122 const uid_t mTestUid; 123 const uid_t mSavedUid; 124 }; 125 126 class ScopedSystemProperties { 127 public: ScopedSystemProperties(const std::string & key,const std::string & value)128 ScopedSystemProperties(const std::string& key, const std::string& value) : mStoredKey(key) { 129 mStoredValue = android::base::GetProperty(key, ""); 130 android::base::SetProperty(key, value); 131 } ~ScopedSystemProperties()132 ~ScopedSystemProperties() { android::base::SetProperty(mStoredKey, mStoredValue); } 133 134 private: 135 std::string mStoredKey; 136 std::string mStoredValue; 137 }; 138 139 class ScopedDefaultNetwork { 140 using INetd = aidl::android::net::INetd; 141 142 public: ScopedDefaultNetwork(INetd * netSrv,uid_t testDefaultNetwork)143 ScopedDefaultNetwork(INetd* netSrv, uid_t testDefaultNetwork) : mNetSrv(netSrv) { 144 EXPECT_TRUE(mNetSrv->networkGetDefault(&mStoredDefaultNetwork).isOk()); 145 EXPECT_TRUE(mNetSrv->networkSetDefault(testDefaultNetwork).isOk()); 146 }; ~ScopedDefaultNetwork()147 ~ScopedDefaultNetwork() { 148 EXPECT_TRUE(mNetSrv->networkSetDefault(mStoredDefaultNetwork).isOk()); 149 } 150 151 private: 152 INetd* mNetSrv; 153 int mStoredDefaultNetwork; 154 }; 155 156 struct DnsRecord { 157 std::string host_name; // host name 158 ns_type type; // record type 159 std::string addr; // ipv4/v6 address 160 }; 161 162 // TODO: make this dynamic and stop depending on implementation details. 163 constexpr int TEST_NETID = 30; 164 // Use the biggest two reserved appId for applications to avoid conflict with existing uids. 165 constexpr int TEST_UID = 99999; 166 constexpr int TEST_UID2 = 99998; 167 168 constexpr char kDnsPortString[] = "53"; 169 constexpr char kDohPortString[] = "443"; 170 constexpr char kDotPortString[] = "853"; 171 172 const std::string kFlagPrefix("persist.device_config.netd_native."); 173 174 const std::string kDohEarlyDataFlag(kFlagPrefix + "doh_early_data"); 175 const std::string kDohIdleTimeoutFlag(kFlagPrefix + "doh_idle_timeout_ms"); 176 const std::string kDohProbeTimeoutFlag(kFlagPrefix + "doh_probe_timeout_ms"); 177 const std::string kDohQueryTimeoutFlag(kFlagPrefix + "doh_query_timeout_ms"); 178 const std::string kDohSessionResumptionFlag(kFlagPrefix + "doh_session_resumption"); 179 const std::string kDotAsyncHandshakeFlag(kFlagPrefix + "dot_async_handshake"); 180 const std::string kDotConnectTimeoutMsFlag(kFlagPrefix + "dot_connect_timeout_ms"); 181 const std::string kDotMaxretriesFlag(kFlagPrefix + "dot_maxtries"); 182 const std::string kDotQueryTimeoutMsFlag(kFlagPrefix + "dot_query_timeout_ms"); 183 const std::string kDotQuickFallbackFlag(kFlagPrefix + "dot_quick_fallback"); 184 const std::string kDotRevalidationThresholdFlag(kFlagPrefix + "dot_revalidation_threshold"); 185 const std::string kDotXportUnusableThresholdFlag(kFlagPrefix + "dot_xport_unusable_threshold"); 186 const std::string kDotValidationLatencyFactorFlag(kFlagPrefix + "dot_validation_latency_factor"); 187 const std::string kDotValidationLatencyOffsetMsFlag(kFlagPrefix + 188 "dot_validation_latency_offset_ms"); 189 const std::string kFailFastOnUidNetworkBlockingFlag(kFlagPrefix + 190 "fail_fast_on_uid_network_blocking"); 191 const std::string kKeepListeningUdpFlag(kFlagPrefix + "keep_listening_udp"); 192 const std::string kNoRetryAfterCancelFlag(kFlagPrefix + "no_retry_after_cancel"); 193 const std::string kParallelLookupSleepTimeFlag(kFlagPrefix + "parallel_lookup_sleep_time"); 194 const std::string kRetransIntervalFlag(kFlagPrefix + "retransmission_time_interval"); 195 const std::string kRetryCountFlag(kFlagPrefix + "retry_count"); 196 const std::string kSortNameserversFlag(kFlagPrefix + "sort_nameservers"); 197 198 const std::string kPersistNetPrefix("persist.net."); 199 200 const std::string kQueryLogSize(kPersistNetPrefix + "dns_query_log_size"); 201 202 static constexpr char kLocalHost[] = "localhost"; 203 static constexpr char kLocalHostAddr[] = "127.0.0.1"; 204 static constexpr char kIp6LocalHost[] = "ip6-localhost"; 205 static constexpr char kIp6LocalHostAddr[] = "::1"; 206 static constexpr char kHelloExampleCom[] = "hello.example.com."; 207 static constexpr char kHelloExampleComAddrV4[] = "1.2.3.4"; 208 static constexpr char kHelloExampleComAddrV4_2[] = "8.8.8.8"; 209 static constexpr char kHelloExampleComAddrV4_3[] = "81.117.21.202"; 210 static constexpr char kHelloExampleComAddrV6[] = "::1.2.3.4"; 211 static constexpr char kHelloExampleComAddrV6_IPV4COMPAT[] = "::1.2.3.4"; 212 static constexpr char kHelloExampleComAddrV6_TEREDO[] = "2001::47c1"; 213 static constexpr char kHelloExampleComAddrV6_GUA[] = "2404:6800::5175:15ca"; 214 static constexpr char kExampleComDomain[] = ".example.com"; 215 216 static const std::string kNat64Prefix = "64:ff9b::/96"; 217 static const std::string kNat64Prefix2 = "2001:db8:6464::/96"; 218 219 constexpr size_t kMaxmiumLabelSize = 63; // see RFC 1035 section 2.3.4. 220 221 static const std::vector<uint8_t> kHelloExampleComQueryV4 = { 222 /* Header */ 223 0x00, 0x00, /* Transaction ID: 0x0000 */ 224 0x01, 0x00, /* Flags: rd */ 225 0x00, 0x01, /* Questions: 1 */ 226 0x00, 0x00, /* Answer RRs: 0 */ 227 0x00, 0x00, /* Authority RRs: 0 */ 228 0x00, 0x00, /* Additional RRs: 0 */ 229 /* Queries */ 230 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 231 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */ 232 0x00, 0x01, /* Type: A */ 233 0x00, 0x01 /* Class: IN */ 234 }; 235 236 static const std::vector<uint8_t> kHelloExampleComResponseV4 = { 237 /* Header */ 238 0x00, 0x00, /* Transaction ID: 0x0000 */ 239 0x81, 0x80, /* Flags: qr rd ra */ 240 0x00, 0x01, /* Questions: 1 */ 241 0x00, 0x01, /* Answer RRs: 1 */ 242 0x00, 0x00, /* Authority RRs: 0 */ 243 0x00, 0x00, /* Additional RRs: 0 */ 244 /* Queries */ 245 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 246 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */ 247 0x00, 0x01, /* Type: A */ 248 0x00, 0x01, /* Class: IN */ 249 /* Answers */ 250 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 251 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */ 252 0x00, 0x01, /* Type: A */ 253 0x00, 0x01, /* Class: IN */ 254 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */ 255 0x00, 0x04, /* Data length: 4 */ 256 0x01, 0x02, 0x03, 0x04 /* Address: 1.2.3.4 */ 257 }; 258 259 const std::vector<uint8_t> kHelloExampleComResponsesV4 = { 260 // scapy.DNS( 261 // id=0, 262 // qr=1, 263 // ra=1, 264 // qd=scapy.DNSQR(qname="hello.example.com",qtype="A"), 265 // an=scapy.DNSRR(rrname="hello.example.com",type="A",ttl=0,rdata='1.2.3.4') / 266 // scapy.DNSRR(rrname="hello.example.com",type="A",ttl=0,rdata='8.8.8.8') / 267 // scapy.DNSRR(rrname="hello.example.com",type="A",ttl=0,rdata='81.117.21.202')) 268 /* Header */ 269 0x00, 0x00, /* Transaction ID: 0x0000 */ 270 0x81, 0x80, /* Flags: qr rd ra */ 271 0x00, 0x01, /* Questions: 1 */ 272 0x00, 0x03, /* Answer RRs: 3 */ 273 0x00, 0x00, /* Authority RRs: 0 */ 274 0x00, 0x00, /* Additional RRs: 0 */ 275 /* Queries */ 276 0x05, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x03, 277 0x63, 0x6F, 0x6D, 0x00, /* Name: hello.example.com */ 278 0x00, 0x01, /* Type: A */ 279 0x00, 0x01, /* Class: IN */ 280 /* Answers */ 281 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 282 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */ 283 0x00, 0x01, /* Type: A */ 284 0x00, 0x01, /* Class: IN */ 285 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */ 286 0x00, 0x04, /* Data length: 4 */ 287 0x01, 0x02, 0x03, 0x04, /* Address: 1.2.3.4 */ 288 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 289 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */ 290 0x00, 0x01, /* Type: A */ 291 0x00, 0x01, /* Class: IN */ 292 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */ 293 0x00, 0x04, /* Data length: 4 */ 294 0x08, 0x08, 0x08, 0x08, /* Address: 8.8.8.8 */ 295 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 296 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */ 297 0x00, 0x01, /* Type: A */ 298 0x00, 0x01, /* Class: IN */ 299 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */ 300 0x00, 0x04, /* Data length: 4 */ 301 0x51, 0x75, 0x15, 0xca /* Address: 81.117.21.202 */ 302 }; 303 304 static const std::vector<uint8_t> kHelloExampleComQueryV6 = { 305 /* Header */ 306 0x00, 0x00, /* Transaction ID: 0x0000 */ 307 0x01, 0x00, /* Flags: rd */ 308 0x00, 0x01, /* Questions: 1 */ 309 0x00, 0x00, /* Answer RRs: 0 */ 310 0x00, 0x00, /* Authority RRs: 0 */ 311 0x00, 0x00, /* Additional RRs: 0 */ 312 /* Queries */ 313 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 314 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */ 315 0x00, 0x1c, /* Type: AAAA */ 316 0x00, 0x01 /* Class: IN */ 317 }; 318 319 const std::vector<uint8_t> kHelloExampleComResponsesV6 = { 320 // The addresses are IPv4-compatible address, teredo tunneling address and global unicast 321 // address. 322 // 323 // scapy.DNS( 324 // id=0, 325 // qr=1, 326 // ra=1, 327 // qd=scapy.DNSQR(qname="hello.example.com",qtype="AAAA"), 328 // an=scapy.DNSRR(rrname="hello.example.com",type="AAAA",rdata='::1.2.3.4') / 329 // scapy.DNSRR(rrname="hello.example.com",type="AAAA",rdata='2001::47c1') / 330 // scapy.DNSRR(rrname="hello.example.com",type="AAAA",rdata='2404:6800::5175:15ca')) 331 /* Header */ 332 0x00, 0x00, /* Transaction ID: 0x0000 */ 333 0x81, 0x80, /* Flags: qr rd ra */ 334 0x00, 0x01, /* Questions: 1 */ 335 0x00, 0x03, /* Answer RRs: 3 */ 336 0x00, 0x00, /* Authority RRs: 0 */ 337 0x00, 0x00, /* Additional RRs: 0 */ 338 /* Queries */ 339 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 340 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */ 341 0x00, 0x1c, /* Type: AAAA */ 342 0x00, 0x01, /* Class: IN */ 343 /* Answers */ 344 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 345 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */ 346 0x00, 0x1c, /* Type: AAAA */ 347 0x00, 0x01, /* Class: IN */ 348 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */ 349 0x00, 0x10, /* Data length: 4 */ 350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 351 0x04, /* Address: ::1.2.3.4 */ 352 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 353 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */ 354 0x00, 0x1c, /* Type: AAAA */ 355 0x00, 0x01, /* Class: IN */ 356 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */ 357 0x00, 0x10, /* Data length: 4 */ 358 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 359 0xc1, /* Address: 2001::47c1 */ 360 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 361 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */ 362 0x00, 0x1c, /* Type: AAAA */ 363 0x00, 0x01, /* Class: IN */ 364 0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */ 365 0x00, 0x10, /* Data length: 4 */ 366 0x24, 0x04, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x75, 0x15, 367 0xCA /* Address: 2404:6800::5175:15ca */ 368 }; 369 370 // Illegal hostnames 371 static constexpr char kBadCharAfterPeriodHost[] = "hello.example.^com."; 372 static constexpr char kBadCharBeforePeriodHost[] = "hello.example^.com."; 373 static constexpr char kBadCharAtTheEndHost[] = "hello.example.com^."; 374 static constexpr char kBadCharInTheMiddleOfLabelHost[] = "hello.ex^ample.com."; 375 376 static const test::DNSHeader kDefaultDnsHeader = { 377 // Don't need to initialize the flag "id" and "rd" because DNS responder assigns them from 378 // query to response. See RFC 1035 section 4.1.1. 379 .id = 0, // unused. should be assigned from query to response 380 .ra = false, // recursive query support is not available 381 .rcode = ns_r_noerror, // no error 382 .qr = true, // message is a response 383 .opcode = QUERY, // a standard query 384 .aa = false, // answer/authority portion was not authenticated by the server 385 .tr = false, // message is not truncated 386 .rd = false, // unused. should be assigned from query to response 387 .ad = false, // non-authenticated data is unacceptable 388 }; 389 390 // The CNAME chain records for building a response message which exceeds 512 bytes. 391 // 392 // Ignoring the other fields of the message, the response message has 8 CNAMEs in 5 answer RRs 393 // and each CNAME has 77 bytes as the follows. The response message at least has 616 bytes in 394 // answer section and has already exceeded 512 bytes totally. 395 // 396 // The CNAME is presented as: 397 // 0 1 64 65 72 73 76 77 398 // +---+--........--+---+---+---+---+---+---+---+---+---+---+---+---+---+ 399 // | 63| {x, .., x} | 7 | e | x | a | m | p | l | e | 3 | c | o | m | 0 | 400 // +---+--........--+---+---+---+---+---+---+---+---+---+---+---+---+---+ 401 // ^-- x = {a, b, c, d} 402 // 403 const std::string kCnameA = std::string(kMaxmiumLabelSize, 'a') + kExampleComDomain + "."; 404 const std::string kCnameB = std::string(kMaxmiumLabelSize, 'b') + kExampleComDomain + "."; 405 const std::string kCnameC = std::string(kMaxmiumLabelSize, 'c') + kExampleComDomain + "."; 406 const std::string kCnameD = std::string(kMaxmiumLabelSize, 'd') + kExampleComDomain + "."; 407 const std::vector<DnsRecord> kLargeCnameChainRecords = { 408 {kHelloExampleCom, ns_type::ns_t_cname, kCnameA}, 409 {kCnameA, ns_type::ns_t_cname, kCnameB}, 410 {kCnameB, ns_type::ns_t_cname, kCnameC}, 411 {kCnameC, ns_type::ns_t_cname, kCnameD}, 412 {kCnameD, ns_type::ns_t_a, kHelloExampleComAddrV4}, 413 }; 414 415 // TODO: Integrate GetNumQueries relevent functions 416 size_t GetNumQueries(const test::DNSResponder& dns, const char* name); 417 size_t GetNumQueriesForProtocol(const test::DNSResponder& dns, const int protocol, 418 const char* name); 419 size_t GetNumQueriesForType(const test::DNSResponder& dns, ns_type type, const char* name); 420 std::string ToString(const hostent* he); 421 std::string ToString(const addrinfo* ai); 422 std::string ToString(const android::netdutils::ScopedAddrinfo& ai); 423 std::string ToString(const sockaddr_storage* addr); 424 std::vector<std::string> ToStrings(const hostent* he); 425 std::vector<std::string> ToStrings(const addrinfo* ai); 426 std::vector<std::string> ToStrings(const android::netdutils::ScopedAddrinfo& ai); 427 428 // Wait for |condition| to be met until |timeout|. 429 bool PollForCondition(const std::function<bool()>& condition, 430 std::chrono::milliseconds timeout = std::chrono::milliseconds(1000)); 431 432 android::netdutils::ScopedAddrinfo safe_getaddrinfo(const char* node, const char* service, 433 const struct addrinfo* hints); 434 435 void SetMdnsRoute(); 436 void RemoveMdnsRoute(); 437 void AllowNetworkInBackground(int uid, bool allow); 438 439 // Local definition to avoid including resolv_cache.h. 440 int resolv_set_nameservers(const aidl::android::net::ResolverParamsParcel& params); 441 442 // For testing only. Production code passes the parcel down directly. 443 inline int resolv_set_nameservers( 444 unsigned netid, const std::vector<std::string>& servers, 445 const std::vector<std::string>& domains, const res_params& res_params, 446 std::optional<aidl::android::net::ResolverOptionsParcel> resolverOptions, 447 const std::vector<int32_t>& transportTypes = {}, bool metered = false) { 448 aidl::android::net::ResolverParamsParcel params; 449 params.netId = netid; 450 params.servers = servers; 451 params.domains = domains; 452 params.resolverOptions = resolverOptions; 453 params.transportTypes = transportTypes; 454 params.meteredNetwork = metered; 455 456 params.sampleValiditySeconds = res_params.sample_validity; 457 params.successThreshold = res_params.success_threshold; 458 params.minSamples = res_params.min_samples; 459 params.maxSamples = res_params.max_samples; 460 params.baseTimeoutMsec = res_params.base_timeout_msec; 461 params.retryCount = res_params.retry_count; 462 // This is currently not configurable. Tests relying on DnsResponderClient, are currently 463 // creating a network with no interfaces. They then end up relying on local communication to 464 // receive and send DNS queries. Adding "lo" as an interface for |TEST_NETID| makes that 465 // dependency explicit, allowing mDNS multicast queries to be sent via 466 // IP_MULTICAST_IF/IPV6_MULTICAST_IF. 467 params.interfaceNames = {"lo"}; 468 469 return resolv_set_nameservers(params); 470 } 471 472 #define SKIP_IF_BEFORE_T \ 473 do { \ 474 if (!isAtLeastT()) { \ 475 GTEST_SKIP() << "Skipping test because SDK version is less than T."; \ 476 } \ 477 } while (0) 478 479 bool is64bitAbi(); 480 481 static const std::string DNS_HELPER = 482 is64bitAbi() ? "/apex/com.android.tethering/lib64/libcom.android.tethering.dns_helper.so" 483 : "/apex/com.android.tethering/lib/libcom.android.tethering.dns_helper.so"; 484 485 #define SKIP_IF_DEPENDENT_LIB_DOES_NOT_EXIST(libPath) \ 486 do { \ 487 if (!std::filesystem::exists(libPath)) \ 488 GTEST_SKIP() << "Required " << (libPath) << " not found."; \ 489 } while (0) 490