Loading DnsResolverService.cpp +6 −2 Original line number Diff line number Diff line Loading @@ -208,9 +208,13 @@ binder_status_t DnsResolverService::dump(int fd, const char** args, uint32_t num // Locking happens in PrivateDnsConfiguration and res_* functions. ENFORCE_NETWORK_STACK_PERMISSIONS(); // The interface names aren't part of the IPC signature, so cannot be passed back to the caller. // TODO: consider defining a new IP method that returns a parcel instead. std::vector<std::string> interfaceNames; int timeout_count = 0; int res = gDnsResolv->resolverCtrl.getResolverInfo(netId, servers, domains, tlsServers, params, stats, &timeout_count); int res = gDnsResolv->resolverCtrl.getResolverInfo( netId, servers, domains, tlsServers, &interfaceNames, params, stats, &timeout_count); // Due to historical reason, wait_for_pending_req_timeout_count couldn't be // an int but a vector. See aosp/858377 for more details. wait_for_pending_req_timeout_count->clear(); Loading ResolverController.cpp +14 −6 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ using aidl::android::net::IDnsResolver; using aidl::android::net::ResolverParamsParcel; using aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener; using aidl::android::net::resolv::aidl::Nat64PrefixEventParcel; using android::base::Join; using android::net::ResolverStats; namespace android { Loading Loading @@ -80,7 +81,7 @@ void sendNat64PrefixEvent(const Dns64Configuration::Nat64PrefixInfo& args) { int getDnsInfo(unsigned netId, std::vector<std::string>* servers, std::vector<std::string>* domains, res_params* params, std::vector<android::net::ResolverStats>* stats, int* wait_for_pending_req_timeout_count) { std::vector<std::string>* interfaceNames, int* wait_for_pending_req_timeout_count) { static_assert(ResolverStats::STATS_SUCCESSES == IDnsResolver::RESOLVER_STATS_SUCCESSES && ResolverStats::STATS_ERRORS == IDnsResolver::RESOLVER_STATS_ERRORS && ResolverStats::STATS_TIMEOUTS == IDnsResolver::RESOLVER_STATS_TIMEOUTS && Loading @@ -99,6 +100,7 @@ int getDnsInfo(unsigned netId, std::vector<std::string>* servers, std::vector<st res_stats res_stats[MAXNS]; servers->clear(); domains->clear(); interfaceNames->clear(); *params = res_params{}; stats->clear(); int revision_id = android_net_res_stats_get_info_for_net(netId, &nscount, res_servers, &dcount, Loading Loading @@ -149,6 +151,8 @@ int getDnsInfo(unsigned netId, std::vector<std::string>* servers, std::vector<st domains->push_back(res_domains[i]); } *interfaceNames = resolv_get_interface_names(netId); return 0; } Loading Loading @@ -233,11 +237,12 @@ int ResolverController::setResolverConfiguration(const ResolverParamsParcel& res int ResolverController::getResolverInfo(int32_t netId, std::vector<std::string>* servers, std::vector<std::string>* domains, std::vector<std::string>* tlsServers, std::vector<std::string>* interfaceNames, std::vector<int32_t>* params, std::vector<int32_t>* stats, int* wait_for_pending_req_timeout_count) { res_params res_params; std::vector<ResolverStats> res_stats; int ret = getDnsInfo(netId, servers, domains, &res_params, &res_stats, int ret = getDnsInfo(netId, servers, domains, &res_params, &res_stats, interfaceNames, wait_for_pending_req_timeout_count); if (ret != 0) { return ret; Loading Loading @@ -283,11 +288,12 @@ void ResolverController::dump(DumpWriter& dw, unsigned netId) { // No lock needed since Bionic's resolver locks all accessed data structures internally. std::vector<std::string> servers; std::vector<std::string> domains; std::vector<std::string> interfaceNames; res_params params = {}; std::vector<ResolverStats> stats; int wait_for_pending_req_timeout_count = 0; time_t now = time(nullptr); int rv = getDnsInfo(netId, &servers, &domains, ¶ms, &stats, int rv = getDnsInfo(netId, &servers, &domains, ¶ms, &stats, &interfaceNames, &wait_for_pending_req_timeout_count); dw.incIndent(); if (rv != 0) { Loading @@ -297,9 +303,9 @@ void ResolverController::dump(DumpWriter& dw, unsigned netId) { dw.println("No DNS servers defined"); } else { dw.println("DnsEvent subsampling map: " + android::base::Join(resolv_cache_dump_subsampling_map(netId, false), ' ')); Join(resolv_cache_dump_subsampling_map(netId, false), ' ')); dw.println("DnsEvent subsampling map for MDNS: " + android::base::Join(resolv_cache_dump_subsampling_map(netId, true), ' ')); Join(resolv_cache_dump_subsampling_map(netId, true), ' ')); dw.println( "DNS servers: # IP (total, successes, errors, timeouts, internal errors, " "RTT avg, last sample)"); Loading @@ -322,10 +328,12 @@ void ResolverController::dump(DumpWriter& dw, unsigned netId) { } dw.decIndent(); } std::string ifacenames_str = Join(interfaceNames, ", "); dw.println("Interface names: [%s]", ifacenames_str.c_str()); if (domains.empty()) { dw.println("No search domains defined"); } else { std::string domains_str = android::base::Join(domains, ", "); std::string domains_str = Join(domains, ", "); dw.println("search domains: %s", domains_str.c_str()); } if (params.sample_validity != 0) { Loading ResolverController.h +2 −2 Original line number Diff line number Diff line Loading @@ -46,8 +46,8 @@ class ResolverController { int getResolverInfo(int32_t netId, std::vector<std::string>* servers, std::vector<std::string>* domains, std::vector<std::string>* tlsServers, std::vector<int32_t>* params, std::vector<int32_t>* stats, int* wait_for_pending_req_timeout_count); std::vector<std::string>* interfaceNames, std::vector<int32_t>* params, std::vector<int32_t>* stats, int* wait_for_pending_req_timeout_count); // Start or stop NAT64 prefix discovery. void startPrefix64Discovery(int32_t netId); Loading tests/dnsresolver_binder_test.cpp +49 −0 Original line number Diff line number Diff line Loading @@ -622,3 +622,52 @@ TEST_F(DnsResolverBinderTest, SetResolverOptions) { "network\")", "setResolverOptions.*-1.*64"}); } static std::string getNetworkInterfaceNames(int netId, const std::vector<std::string>& lines) { bool foundNetId = false; for (const auto& line : lines) { // Find the beginning of the section for this netId. const std::string netIdMarker = "NetId: " + std::to_string(netId); if (!foundNetId && !line.compare(0, netIdMarker.size(), netIdMarker)) { foundNetId = true; continue; } // A blank line terminates the section for this netId. if (foundNetId && line.size() == 0) { foundNetId = false; break; } const std::string interfacesNamesPrefix = " Interface names: "; if (foundNetId && !line.compare(0, interfacesNamesPrefix.size(), interfacesNamesPrefix)) { return line.substr(interfacesNamesPrefix.size()); } } return ""; } TEST_F(DnsResolverBinderTest, InterfaceNamesInDumpsys) { SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsResolver.get(), 15); std::vector<std::string> lines; ndk::SpAIBinder netdBinder = ndk::SpAIBinder(AServiceManager_getService("dnsresolver")); auto resolverParams = DnsResponderClient::GetDefaultResolverParamsParcel(); resolverParams.interfaceNames = {"myinterface0"}; ::ndk::ScopedAStatus status = mDnsResolver->setResolverConfiguration(resolverParams); ASSERT_TRUE(status.isOk()) << status.getMessage(); android::status_t ret = dumpService(netdBinder, /*args=*/nullptr, /*num_args=*/0, lines); ASSERT_EQ(android::OK, ret) << "Error dumping service: " << android::statusToString(ret); EXPECT_EQ("[myinterface0]", getNetworkInterfaceNames(TEST_NETID, lines)); lines = {}; resolverParams.interfaceNames = {"myinterface0", "myinterface1"}; status = mDnsResolver->setResolverConfiguration(resolverParams); ASSERT_TRUE(status.isOk()) << status.getMessage(); ret = dumpService(netdBinder, /*args=*/nullptr, /*num_args=*/0, lines); ASSERT_EQ(android::OK, ret) << "Error dumping service: " << android::statusToString(ret); EXPECT_EQ("[myinterface0, myinterface1]", getNetworkInterfaceNames(TEST_NETID, lines)); } Loading
DnsResolverService.cpp +6 −2 Original line number Diff line number Diff line Loading @@ -208,9 +208,13 @@ binder_status_t DnsResolverService::dump(int fd, const char** args, uint32_t num // Locking happens in PrivateDnsConfiguration and res_* functions. ENFORCE_NETWORK_STACK_PERMISSIONS(); // The interface names aren't part of the IPC signature, so cannot be passed back to the caller. // TODO: consider defining a new IP method that returns a parcel instead. std::vector<std::string> interfaceNames; int timeout_count = 0; int res = gDnsResolv->resolverCtrl.getResolverInfo(netId, servers, domains, tlsServers, params, stats, &timeout_count); int res = gDnsResolv->resolverCtrl.getResolverInfo( netId, servers, domains, tlsServers, &interfaceNames, params, stats, &timeout_count); // Due to historical reason, wait_for_pending_req_timeout_count couldn't be // an int but a vector. See aosp/858377 for more details. wait_for_pending_req_timeout_count->clear(); Loading
ResolverController.cpp +14 −6 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ using aidl::android::net::IDnsResolver; using aidl::android::net::ResolverParamsParcel; using aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener; using aidl::android::net::resolv::aidl::Nat64PrefixEventParcel; using android::base::Join; using android::net::ResolverStats; namespace android { Loading Loading @@ -80,7 +81,7 @@ void sendNat64PrefixEvent(const Dns64Configuration::Nat64PrefixInfo& args) { int getDnsInfo(unsigned netId, std::vector<std::string>* servers, std::vector<std::string>* domains, res_params* params, std::vector<android::net::ResolverStats>* stats, int* wait_for_pending_req_timeout_count) { std::vector<std::string>* interfaceNames, int* wait_for_pending_req_timeout_count) { static_assert(ResolverStats::STATS_SUCCESSES == IDnsResolver::RESOLVER_STATS_SUCCESSES && ResolverStats::STATS_ERRORS == IDnsResolver::RESOLVER_STATS_ERRORS && ResolverStats::STATS_TIMEOUTS == IDnsResolver::RESOLVER_STATS_TIMEOUTS && Loading @@ -99,6 +100,7 @@ int getDnsInfo(unsigned netId, std::vector<std::string>* servers, std::vector<st res_stats res_stats[MAXNS]; servers->clear(); domains->clear(); interfaceNames->clear(); *params = res_params{}; stats->clear(); int revision_id = android_net_res_stats_get_info_for_net(netId, &nscount, res_servers, &dcount, Loading Loading @@ -149,6 +151,8 @@ int getDnsInfo(unsigned netId, std::vector<std::string>* servers, std::vector<st domains->push_back(res_domains[i]); } *interfaceNames = resolv_get_interface_names(netId); return 0; } Loading Loading @@ -233,11 +237,12 @@ int ResolverController::setResolverConfiguration(const ResolverParamsParcel& res int ResolverController::getResolverInfo(int32_t netId, std::vector<std::string>* servers, std::vector<std::string>* domains, std::vector<std::string>* tlsServers, std::vector<std::string>* interfaceNames, std::vector<int32_t>* params, std::vector<int32_t>* stats, int* wait_for_pending_req_timeout_count) { res_params res_params; std::vector<ResolverStats> res_stats; int ret = getDnsInfo(netId, servers, domains, &res_params, &res_stats, int ret = getDnsInfo(netId, servers, domains, &res_params, &res_stats, interfaceNames, wait_for_pending_req_timeout_count); if (ret != 0) { return ret; Loading Loading @@ -283,11 +288,12 @@ void ResolverController::dump(DumpWriter& dw, unsigned netId) { // No lock needed since Bionic's resolver locks all accessed data structures internally. std::vector<std::string> servers; std::vector<std::string> domains; std::vector<std::string> interfaceNames; res_params params = {}; std::vector<ResolverStats> stats; int wait_for_pending_req_timeout_count = 0; time_t now = time(nullptr); int rv = getDnsInfo(netId, &servers, &domains, ¶ms, &stats, int rv = getDnsInfo(netId, &servers, &domains, ¶ms, &stats, &interfaceNames, &wait_for_pending_req_timeout_count); dw.incIndent(); if (rv != 0) { Loading @@ -297,9 +303,9 @@ void ResolverController::dump(DumpWriter& dw, unsigned netId) { dw.println("No DNS servers defined"); } else { dw.println("DnsEvent subsampling map: " + android::base::Join(resolv_cache_dump_subsampling_map(netId, false), ' ')); Join(resolv_cache_dump_subsampling_map(netId, false), ' ')); dw.println("DnsEvent subsampling map for MDNS: " + android::base::Join(resolv_cache_dump_subsampling_map(netId, true), ' ')); Join(resolv_cache_dump_subsampling_map(netId, true), ' ')); dw.println( "DNS servers: # IP (total, successes, errors, timeouts, internal errors, " "RTT avg, last sample)"); Loading @@ -322,10 +328,12 @@ void ResolverController::dump(DumpWriter& dw, unsigned netId) { } dw.decIndent(); } std::string ifacenames_str = Join(interfaceNames, ", "); dw.println("Interface names: [%s]", ifacenames_str.c_str()); if (domains.empty()) { dw.println("No search domains defined"); } else { std::string domains_str = android::base::Join(domains, ", "); std::string domains_str = Join(domains, ", "); dw.println("search domains: %s", domains_str.c_str()); } if (params.sample_validity != 0) { Loading
ResolverController.h +2 −2 Original line number Diff line number Diff line Loading @@ -46,8 +46,8 @@ class ResolverController { int getResolverInfo(int32_t netId, std::vector<std::string>* servers, std::vector<std::string>* domains, std::vector<std::string>* tlsServers, std::vector<int32_t>* params, std::vector<int32_t>* stats, int* wait_for_pending_req_timeout_count); std::vector<std::string>* interfaceNames, std::vector<int32_t>* params, std::vector<int32_t>* stats, int* wait_for_pending_req_timeout_count); // Start or stop NAT64 prefix discovery. void startPrefix64Discovery(int32_t netId); Loading
tests/dnsresolver_binder_test.cpp +49 −0 Original line number Diff line number Diff line Loading @@ -622,3 +622,52 @@ TEST_F(DnsResolverBinderTest, SetResolverOptions) { "network\")", "setResolverOptions.*-1.*64"}); } static std::string getNetworkInterfaceNames(int netId, const std::vector<std::string>& lines) { bool foundNetId = false; for (const auto& line : lines) { // Find the beginning of the section for this netId. const std::string netIdMarker = "NetId: " + std::to_string(netId); if (!foundNetId && !line.compare(0, netIdMarker.size(), netIdMarker)) { foundNetId = true; continue; } // A blank line terminates the section for this netId. if (foundNetId && line.size() == 0) { foundNetId = false; break; } const std::string interfacesNamesPrefix = " Interface names: "; if (foundNetId && !line.compare(0, interfacesNamesPrefix.size(), interfacesNamesPrefix)) { return line.substr(interfacesNamesPrefix.size()); } } return ""; } TEST_F(DnsResolverBinderTest, InterfaceNamesInDumpsys) { SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsResolver.get(), 15); std::vector<std::string> lines; ndk::SpAIBinder netdBinder = ndk::SpAIBinder(AServiceManager_getService("dnsresolver")); auto resolverParams = DnsResponderClient::GetDefaultResolverParamsParcel(); resolverParams.interfaceNames = {"myinterface0"}; ::ndk::ScopedAStatus status = mDnsResolver->setResolverConfiguration(resolverParams); ASSERT_TRUE(status.isOk()) << status.getMessage(); android::status_t ret = dumpService(netdBinder, /*args=*/nullptr, /*num_args=*/0, lines); ASSERT_EQ(android::OK, ret) << "Error dumping service: " << android::statusToString(ret); EXPECT_EQ("[myinterface0]", getNetworkInterfaceNames(TEST_NETID, lines)); lines = {}; resolverParams.interfaceNames = {"myinterface0", "myinterface1"}; status = mDnsResolver->setResolverConfiguration(resolverParams); ASSERT_TRUE(status.isOk()) << status.getMessage(); ret = dumpService(netdBinder, /*args=*/nullptr, /*num_args=*/0, lines); ASSERT_EQ(android::OK, ret) << "Error dumping service: " << android::statusToString(ret); EXPECT_EQ("[myinterface0, myinterface1]", getNetworkInterfaceNames(TEST_NETID, lines)); }