Loading Android.bp +160 −44 Original line number Diff line number Diff line package { default_applicable_licenses: ["packages_modules_DnsResolver_license"], } // Added automatically by a large-scale-change that took the approach of // 'apply every license found to every target'. While this makes sure we respect // every license restriction, it may not be entirely correct. // // e.g. GPL in an MIT project might only apply to the contrib/ directory. // // Please consider splitting the single license below into multiple licenses, // taking care not to lose any license_kind information, and overriding the // default license using the 'licenses: [...]' property on targets as needed. // // For unused files, consider creating a 'fileGroup' with "//visibility:private" // to attach the license to, and including a comment whether the files may be // used in the current project. // See: http://go/android-license-faq license { name: "packages_modules_DnsResolver_license", visibility: [":__subpackages__"], license_kinds: [ "SPDX-license-identifier-Apache-2.0", "SPDX-license-identifier-BSD", "SPDX-license-identifier-ISC", "SPDX-license-identifier-MIT", ], license_text: [ "NOTICE", ], } cc_library_headers { name: "libnetd_resolv_headers", export_include_dirs: ["include"], Loading @@ -12,6 +44,8 @@ cc_library_headers { cc_library_headers { name: "dnsproxyd_protocol_headers", sdk_version: "29", min_sdk_version: "29", export_include_dirs: ["include/dnsproxyd_protocol"], apex_available: [ "//apex_available:platform", Loading @@ -19,6 +53,19 @@ cc_library_headers { ], } dnsresolver_aidl_interface_lateststable_version = "V8" cc_library_static { name: "dnsresolver_aidl_interface-lateststable-ndk_platform", whole_static_libs: [ "dnsresolver_aidl_interface-" + dnsresolver_aidl_interface_lateststable_version + "-ndk_platform", ], apex_available: [ "com.android.resolv", ], min_sdk_version: "29", } aidl_interface { name: "dnsresolver_aidl_interface", local_include_dir: "binder", Loading @@ -36,10 +83,11 @@ aidl_interface { backend: { java: { apex_available: [ "//apex_available:platform", "com.android.bluetooth.updatable", "com.android.tethering", "com.android.wifi", ], min_sdk_version: "30", }, ndk: { gen_log: true, Loading @@ -57,11 +105,19 @@ aidl_interface { "5", "6", "7", "8", ], dumpapi: { no_license: true, }, } cc_defaults { name: "resolv_test_defaults", cflags: [ // networkCreatePhysical and networkCreateVpn were deprecated from netd_aidl_interface v6. "-Wno-error=deprecated-declarations", ], // Note that, static link liblog and libbase is a hard requirement for resolv related tests // because libbase is not compatible between Q and R for general platform build due // to its log revelant functions changing. And most of resolv related tests must be able to run Loading @@ -70,6 +126,8 @@ cc_defaults { "libbase", "liblog", ], // This field is required to make test compatible with Q devices. min_sdk_version: "29", } cc_defaults { Loading Loading @@ -133,15 +191,16 @@ cc_library { // Link most things statically to minimize our dependence on system ABIs. stl: "libc++_static", static_libs: [ "dnsresolver_aidl_interface-ndk_platform", "dnsresolver_aidl_interface-lateststable-ndk_platform", "libbase", "libcutils", "libnetdutils", "libdoh_ffi", "libprotobuf-cpp-lite", "libstatslog_resolv", "libstatspush_compat", "libsysutils", "netd_event_listener_interface-ndk_platform", "netd_event_listener_interface-lateststable-ndk_platform", "server_configurable_flags", "stats_proto", ], Loading Loading @@ -205,7 +264,8 @@ cc_library_static { genrule { name: "statslog_resolv.h", tools: ["stats-log-api-gen"], cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_resolv.h --module resolv --namespace android,net,stats", cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_resolv.h --module resolv" + " --namespace android,net,stats --minApiLevel 29", out: [ "statslog_resolv.h", ], Loading @@ -214,7 +274,8 @@ genrule { genrule { name: "statslog_resolv.cpp", tools: ["stats-log-api-gen"], cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_resolv.cpp --module resolv --namespace android,net,stats --importHeader statslog_resolv.h --supportQ", cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_resolv.cpp --module resolv" + " --namespace android,net,stats --importHeader statslog_resolv.h --minApiLevel 29", out: [ "statslog_resolv.cpp", ], Loading @@ -228,13 +289,22 @@ cc_library_static { export_generated_headers: ["statslog_resolv.h"], static_libs: [ "libcutils", "libgtest_prod", // Used by libstatspush_compat "libstatspush_compat", ], header_libs: [ "libgtest_prod_headers", // Used by libstatspush_compat ], apex_available: ["com.android.resolv"], min_sdk_version: "29", } filegroup { name: "resolv_rust_test_config_template", srcs: [ "resolv_rust_test_config_template.xml", ], } filegroup { name: "resolv_test_config_template", srcs: [ Loading @@ -242,54 +312,100 @@ filegroup { ], } // TODO: Move this test to tests/ cc_test { name: "resolv_unit_test", test_suites: [ "general-tests", "mts", ], require_root: true, // TODO: Drop root privileges and make it be an real unit test. // TODO: Remove resolv_test_mts_coverage_defaults after mts coverage switched to 64-bit device. defaults: [ "netd_defaults", "resolv_test_defaults", "resolv_test_mts_coverage_defaults", ], filegroup { name: "resolv_unit_test_files", srcs: [ "resolv_cache_unit_test.cpp", "resolv_callback_unit_test.cpp", "resolv_tls_unit_test.cpp", "resolv_unit_test.cpp", "DnsQueryLogTest.cpp", "DnsStatsTest.cpp", "ExperimentsTest.cpp", "OperationLimiterTest.cpp", "PrivateDnsConfigurationTest.cpp", ], } rust_ffi_static { name: "libdoh_ffi", crate_name: "doh", srcs: ["doh.rs"], edition: "2018", rlibs: [ "libandroid_logger", "libanyhow", "libbase64_rust", "libfutures", "liblibc", "liblog_rust", "libquiche", "libring", "libtokio", "liburl", ], prefer_rlib: true, shared_libs: [ "libcrypto", "libbinder_ndk", "libssl", ], static_libs: [ "dnsresolver_aidl_interface-unstable-ndk_platform", "netd_aidl_interface-ndk_platform", "netd_event_listener_interface-unstable-ndk_platform", "libcutils", "libgmock", "libnetd_resolv", "libnetd_test_dnsresponder_ndk", "libnetd_test_resolv_utils", "libnetdutils", "libprotobuf-cpp-lite", "libstatslog_resolv", "libstatspush_compat", "libsysutils", "libutils", "resolv_stats_test_utils", "server_configurable_flags", "stats_proto", apex_available: [ "//apex_available:platform", // Needed by doh_ffi_test "com.android.resolv" ], min_sdk_version: "29", } rust_test { name: "doh_unit_test", crate_name: "doh", srcs: ["doh.rs"], edition: "2018", test_suites: ["general-tests"], auto_gen_config: true, // Used to enable root permission for the test. // TODO: remove after 'require_root' is supported in rust_test. test_config_template: ":resolv_rust_test_config_template", rustlibs: [ "libandroid_logger", "libanyhow", "libbase64_rust", "libfutures", "liblibc", "liblog_rust", "libquiche_static", "libring", "libtokio", "liburl", ], min_sdk_version: "29", } // It's required by unit tests. rust_ffi_static { name: "libdoh_ffi_for_test", crate_name: "doh", srcs: ["doh.rs"], edition: "2018", rlibs: [ "libandroid_logger", "libanyhow", "libbase64_rust", "libfutures", "liblibc", "liblog_rust", "libquiche_static", "libring", "libtokio", "liburl", ], prefer_rlib: true, // TODO(b/194022174), for unit tests to run on the Android 10 platform, // libunwind must be statically linked. whole_static_libs: ["libunwind"], apex_available: [ "//apex_available:platform", // Needed by doh_ffi_test "com.android.resolv" ], min_sdk_version: "29", } DnsResolver.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,9 @@ bool resolv_init(const ResolverNetdCallbacks* callbacks) { android::base::SetDefaultTag("libnetd_resolv"); LOG(INFO) << __func__ << ": Initializing resolver"; // TODO(b/170539625): restore log level to WARNING after clarifying flaky tests. resolv_set_log_severity(isUserDebugBuild() ? android::base::DEBUG : android::base::WARNING); const bool isDebug = isUserDebugBuild(); resolv_set_log_severity(isDebug ? android::base::DEBUG : android::base::WARNING); doh_init_logger(isDebug ? LOG_LEVEL_DEBUG : LOG_LEVEL_WARN); using android::net::gApiLevel; gApiLevel = getApiLevel(); using android::net::gResNetdCallbacks; Loading Loading @@ -81,6 +83,7 @@ DnsResolver::DnsResolver() { auto& dnsTlsDispatcher = DnsTlsDispatcher::getInstance(); auto& privateDnsConfiguration = PrivateDnsConfiguration::getInstance(); privateDnsConfiguration.setObserver(&dnsTlsDispatcher); if (isDoHEnabled()) privateDnsConfiguration.initDoh(); } bool DnsResolver::start() { Loading DnsStats.cpp +39 −22 Original line number Diff line number Diff line Loading @@ -59,10 +59,10 @@ std::string rcodeToName(int rcode) { // clang-format on } bool ensureNoInvalidIp(const std::vector<IPSockAddr>& servers) { for (const auto& server : servers) { if (server.ip() == INVALID_IPADDRESS || server.port() == 0) { LOG(WARNING) << "Invalid server: " << server; bool ensureNoInvalidIp(const std::vector<IPSockAddr>& addrs) { for (const auto& addr : addrs) { if (addr.ip() == INVALID_IPADDRESS || addr.port() == 0) { LOG(WARNING) << "Invalid addr: " << addr; return false; } } Loading @@ -73,8 +73,8 @@ bool ensureNoInvalidIp(const std::vector<IPSockAddr>& servers) { // The comparison ignores the last update time. bool StatsData::operator==(const StatsData& o) const { return std::tie(serverSockAddr, total, rcodeCounts, latencyUs) == std::tie(o.serverSockAddr, o.total, o.rcodeCounts, o.latencyUs); return std::tie(sockAddr, total, rcodeCounts, latencyUs) == std::tie(o.sockAddr, o.total, o.rcodeCounts, o.latencyUs); } int StatsData::averageLatencyMs() const { Loading @@ -82,7 +82,7 @@ int StatsData::averageLatencyMs() const { } std::string StatsData::toString() const { if (total == 0) return StringPrintf("%s <no data>", serverSockAddr.ip().toString().c_str()); if (total == 0) return StringPrintf("%s <no data>", sockAddr.ip().toString().c_str()); const auto now = std::chrono::steady_clock::now(); const int lastUpdateSec = duration_cast<seconds>(now - lastUpdate).count(); Loading @@ -92,7 +92,7 @@ std::string StatsData::toString() const { buf += StringPrintf("%s:%d ", rcodeToName(rcode).c_str(), counts); } } return StringPrintf("%s (%d, %dms, [%s], %ds)", serverSockAddr.ip().toString().c_str(), total, return StringPrintf("%s (%d, %dms, [%s], %ds)", sockAddr.ip().toString().c_str(), total, averageLatencyMs(), buf.c_str(), lastUpdateSec); } Loading Loading @@ -171,20 +171,20 @@ void StatsRecords::incrementSkippedCount() { mSkippedCount = std::min(mSkippedCount + 1, kMaxQuality); } bool DnsStats::setServers(const std::vector<netdutils::IPSockAddr>& servers, Protocol protocol) { if (!ensureNoInvalidIp(servers)) return false; bool DnsStats::setAddrs(const std::vector<netdutils::IPSockAddr>& addrs, Protocol protocol) { if (!ensureNoInvalidIp(addrs)) return false; ServerStatsMap& statsMap = mStats[protocol]; for (const auto& server : servers) { statsMap.try_emplace(server, StatsRecords(server, kLogSize)); StatsMap& statsMap = mStats[protocol]; for (const auto& addr : addrs) { statsMap.try_emplace(addr, StatsRecords(addr, kLogSize)); } // Clean up the map to eliminate the nodes not belonging to the given list of servers. const auto cleanup = [&](ServerStatsMap* statsMap) { ServerStatsMap tmp; for (const auto& server : servers) { if (statsMap->find(server) != statsMap->end()) { tmp.insert(statsMap->extract(server)); const auto cleanup = [&](StatsMap* statsMap) { StatsMap tmp; for (const auto& addr : addrs) { if (statsMap->find(addr) != statsMap->end()) { tmp.insert(statsMap->extract(addr)); } } statsMap->swap(tmp); Loading @@ -199,8 +199,8 @@ bool DnsStats::addStats(const IPSockAddr& ipSockAddr, const DnsQueryEvent& recor if (ipSockAddr.ip() == INVALID_IPADDRESS) return false; bool added = false; for (auto& [serverSockAddr, statsRecords] : mStats[record.protocol()]) { if (serverSockAddr == ipSockAddr) { for (auto& [sockAddr, statsRecords] : mStats[record.protocol()]) { if (sockAddr == ipSockAddr) { const StatsRecords::Record rec = { .rcode = record.rcode(), .linux_errno = record.linux_errno(), Loading Loading @@ -239,6 +239,20 @@ std::vector<IPSockAddr> DnsStats::getSortedServers(Protocol protocol) const { return ret; } std::optional<microseconds> DnsStats::getAverageLatencyUs(Protocol protocol) const { const auto stats = getStats(protocol); int count = 0; microseconds sum; for (const auto& v : stats) { count += v.total; sum += v.latencyUs; } if (count == 0) return std::nullopt; return sum / count; } std::vector<StatsData> DnsStats::getStats(Protocol protocol) const { std::vector<StatsData> ret; Loading @@ -251,10 +265,10 @@ std::vector<StatsData> DnsStats::getStats(Protocol protocol) const { } void DnsStats::dump(DumpWriter& dw) { const auto dumpStatsMap = [&](ServerStatsMap& statsMap) { const auto dumpStatsMap = [&](StatsMap& statsMap) { ScopedIndent indentLog(dw); if (statsMap.size() == 0) { dw.println("<no server>"); dw.println("<no data>"); return; } for (const auto& [_, statsRecords] : statsMap) { Loading @@ -276,6 +290,9 @@ void DnsStats::dump(DumpWriter& dw) { dw.println("over TCP"); dumpStatsMap(mStats[PROTO_TCP]); dw.println("over MDNS"); dumpStatsMap(mStats[PROTO_MDNS]); } } // namespace android::net DnsStats.h +11 −9 Original line number Diff line number Diff line Loading @@ -33,12 +33,12 @@ namespace android::net { // The overall information of a StatsRecords. struct StatsData { StatsData(const netdutils::IPSockAddr& ipSockAddr) : serverSockAddr(ipSockAddr) { StatsData(const netdutils::IPSockAddr& ipSockAddr) : sockAddr(ipSockAddr) { lastUpdate = std::chrono::steady_clock::now(); }; // Server socket address. netdutils::IPSockAddr serverSockAddr; // Socket address. netdutils::IPSockAddr sockAddr; // The most recent number of records being accumulated. int total = 0; Loading Loading @@ -106,24 +106,26 @@ class StatsRecords { static constexpr int kMaxQuality = 10000; }; // DnsStats class manages the statistics of DNS servers per netId. // DnsStats class manages the statistics of DNS servers or MDNS multicast addresses per netId. // The class itself is not thread-safe. class DnsStats { public: using ServerStatsMap = std::map<netdutils::IPSockAddr, StatsRecords>; using StatsMap = std::map<netdutils::IPSockAddr, StatsRecords>; // Add |servers| to the map, and remove no-longer-used servers. // Add |addrs| to the map, and remove no-longer-used addresses. // Return true if they are successfully added; otherwise, return false. bool setServers(const std::vector<netdutils::IPSockAddr>& servers, Protocol protocol); bool setAddrs(const std::vector<netdutils::IPSockAddr>& addrs, Protocol protocol); // Return true if |record| is successfully added into |server|'s stats; otherwise, return false. bool addStats(const netdutils::IPSockAddr& server, const DnsQueryEvent& record); std::vector<netdutils::IPSockAddr> getSortedServers(Protocol protocol) const; // Returns the average query latency in microseconds. std::optional<std::chrono::microseconds> getAverageLatencyUs(Protocol protocol) const; void dump(netdutils::DumpWriter& dw); // For testing. std::vector<StatsData> getStats(Protocol protocol) const; // TODO: Compatible support for getResolverInfo(). Loading @@ -131,7 +133,7 @@ class DnsStats { static constexpr size_t kLogSize = 128; private: std::map<Protocol, ServerStatsMap> mStats; std::map<Protocol, StatsMap> mStats; }; } // namespace android::net Loading
Android.bp +160 −44 Original line number Diff line number Diff line package { default_applicable_licenses: ["packages_modules_DnsResolver_license"], } // Added automatically by a large-scale-change that took the approach of // 'apply every license found to every target'. While this makes sure we respect // every license restriction, it may not be entirely correct. // // e.g. GPL in an MIT project might only apply to the contrib/ directory. // // Please consider splitting the single license below into multiple licenses, // taking care not to lose any license_kind information, and overriding the // default license using the 'licenses: [...]' property on targets as needed. // // For unused files, consider creating a 'fileGroup' with "//visibility:private" // to attach the license to, and including a comment whether the files may be // used in the current project. // See: http://go/android-license-faq license { name: "packages_modules_DnsResolver_license", visibility: [":__subpackages__"], license_kinds: [ "SPDX-license-identifier-Apache-2.0", "SPDX-license-identifier-BSD", "SPDX-license-identifier-ISC", "SPDX-license-identifier-MIT", ], license_text: [ "NOTICE", ], } cc_library_headers { name: "libnetd_resolv_headers", export_include_dirs: ["include"], Loading @@ -12,6 +44,8 @@ cc_library_headers { cc_library_headers { name: "dnsproxyd_protocol_headers", sdk_version: "29", min_sdk_version: "29", export_include_dirs: ["include/dnsproxyd_protocol"], apex_available: [ "//apex_available:platform", Loading @@ -19,6 +53,19 @@ cc_library_headers { ], } dnsresolver_aidl_interface_lateststable_version = "V8" cc_library_static { name: "dnsresolver_aidl_interface-lateststable-ndk_platform", whole_static_libs: [ "dnsresolver_aidl_interface-" + dnsresolver_aidl_interface_lateststable_version + "-ndk_platform", ], apex_available: [ "com.android.resolv", ], min_sdk_version: "29", } aidl_interface { name: "dnsresolver_aidl_interface", local_include_dir: "binder", Loading @@ -36,10 +83,11 @@ aidl_interface { backend: { java: { apex_available: [ "//apex_available:platform", "com.android.bluetooth.updatable", "com.android.tethering", "com.android.wifi", ], min_sdk_version: "30", }, ndk: { gen_log: true, Loading @@ -57,11 +105,19 @@ aidl_interface { "5", "6", "7", "8", ], dumpapi: { no_license: true, }, } cc_defaults { name: "resolv_test_defaults", cflags: [ // networkCreatePhysical and networkCreateVpn were deprecated from netd_aidl_interface v6. "-Wno-error=deprecated-declarations", ], // Note that, static link liblog and libbase is a hard requirement for resolv related tests // because libbase is not compatible between Q and R for general platform build due // to its log revelant functions changing. And most of resolv related tests must be able to run Loading @@ -70,6 +126,8 @@ cc_defaults { "libbase", "liblog", ], // This field is required to make test compatible with Q devices. min_sdk_version: "29", } cc_defaults { Loading Loading @@ -133,15 +191,16 @@ cc_library { // Link most things statically to minimize our dependence on system ABIs. stl: "libc++_static", static_libs: [ "dnsresolver_aidl_interface-ndk_platform", "dnsresolver_aidl_interface-lateststable-ndk_platform", "libbase", "libcutils", "libnetdutils", "libdoh_ffi", "libprotobuf-cpp-lite", "libstatslog_resolv", "libstatspush_compat", "libsysutils", "netd_event_listener_interface-ndk_platform", "netd_event_listener_interface-lateststable-ndk_platform", "server_configurable_flags", "stats_proto", ], Loading Loading @@ -205,7 +264,8 @@ cc_library_static { genrule { name: "statslog_resolv.h", tools: ["stats-log-api-gen"], cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_resolv.h --module resolv --namespace android,net,stats", cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_resolv.h --module resolv" + " --namespace android,net,stats --minApiLevel 29", out: [ "statslog_resolv.h", ], Loading @@ -214,7 +274,8 @@ genrule { genrule { name: "statslog_resolv.cpp", tools: ["stats-log-api-gen"], cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_resolv.cpp --module resolv --namespace android,net,stats --importHeader statslog_resolv.h --supportQ", cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_resolv.cpp --module resolv" + " --namespace android,net,stats --importHeader statslog_resolv.h --minApiLevel 29", out: [ "statslog_resolv.cpp", ], Loading @@ -228,13 +289,22 @@ cc_library_static { export_generated_headers: ["statslog_resolv.h"], static_libs: [ "libcutils", "libgtest_prod", // Used by libstatspush_compat "libstatspush_compat", ], header_libs: [ "libgtest_prod_headers", // Used by libstatspush_compat ], apex_available: ["com.android.resolv"], min_sdk_version: "29", } filegroup { name: "resolv_rust_test_config_template", srcs: [ "resolv_rust_test_config_template.xml", ], } filegroup { name: "resolv_test_config_template", srcs: [ Loading @@ -242,54 +312,100 @@ filegroup { ], } // TODO: Move this test to tests/ cc_test { name: "resolv_unit_test", test_suites: [ "general-tests", "mts", ], require_root: true, // TODO: Drop root privileges and make it be an real unit test. // TODO: Remove resolv_test_mts_coverage_defaults after mts coverage switched to 64-bit device. defaults: [ "netd_defaults", "resolv_test_defaults", "resolv_test_mts_coverage_defaults", ], filegroup { name: "resolv_unit_test_files", srcs: [ "resolv_cache_unit_test.cpp", "resolv_callback_unit_test.cpp", "resolv_tls_unit_test.cpp", "resolv_unit_test.cpp", "DnsQueryLogTest.cpp", "DnsStatsTest.cpp", "ExperimentsTest.cpp", "OperationLimiterTest.cpp", "PrivateDnsConfigurationTest.cpp", ], } rust_ffi_static { name: "libdoh_ffi", crate_name: "doh", srcs: ["doh.rs"], edition: "2018", rlibs: [ "libandroid_logger", "libanyhow", "libbase64_rust", "libfutures", "liblibc", "liblog_rust", "libquiche", "libring", "libtokio", "liburl", ], prefer_rlib: true, shared_libs: [ "libcrypto", "libbinder_ndk", "libssl", ], static_libs: [ "dnsresolver_aidl_interface-unstable-ndk_platform", "netd_aidl_interface-ndk_platform", "netd_event_listener_interface-unstable-ndk_platform", "libcutils", "libgmock", "libnetd_resolv", "libnetd_test_dnsresponder_ndk", "libnetd_test_resolv_utils", "libnetdutils", "libprotobuf-cpp-lite", "libstatslog_resolv", "libstatspush_compat", "libsysutils", "libutils", "resolv_stats_test_utils", "server_configurable_flags", "stats_proto", apex_available: [ "//apex_available:platform", // Needed by doh_ffi_test "com.android.resolv" ], min_sdk_version: "29", } rust_test { name: "doh_unit_test", crate_name: "doh", srcs: ["doh.rs"], edition: "2018", test_suites: ["general-tests"], auto_gen_config: true, // Used to enable root permission for the test. // TODO: remove after 'require_root' is supported in rust_test. test_config_template: ":resolv_rust_test_config_template", rustlibs: [ "libandroid_logger", "libanyhow", "libbase64_rust", "libfutures", "liblibc", "liblog_rust", "libquiche_static", "libring", "libtokio", "liburl", ], min_sdk_version: "29", } // It's required by unit tests. rust_ffi_static { name: "libdoh_ffi_for_test", crate_name: "doh", srcs: ["doh.rs"], edition: "2018", rlibs: [ "libandroid_logger", "libanyhow", "libbase64_rust", "libfutures", "liblibc", "liblog_rust", "libquiche_static", "libring", "libtokio", "liburl", ], prefer_rlib: true, // TODO(b/194022174), for unit tests to run on the Android 10 platform, // libunwind must be statically linked. whole_static_libs: ["libunwind"], apex_available: [ "//apex_available:platform", // Needed by doh_ffi_test "com.android.resolv" ], min_sdk_version: "29", }
DnsResolver.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,9 @@ bool resolv_init(const ResolverNetdCallbacks* callbacks) { android::base::SetDefaultTag("libnetd_resolv"); LOG(INFO) << __func__ << ": Initializing resolver"; // TODO(b/170539625): restore log level to WARNING after clarifying flaky tests. resolv_set_log_severity(isUserDebugBuild() ? android::base::DEBUG : android::base::WARNING); const bool isDebug = isUserDebugBuild(); resolv_set_log_severity(isDebug ? android::base::DEBUG : android::base::WARNING); doh_init_logger(isDebug ? LOG_LEVEL_DEBUG : LOG_LEVEL_WARN); using android::net::gApiLevel; gApiLevel = getApiLevel(); using android::net::gResNetdCallbacks; Loading Loading @@ -81,6 +83,7 @@ DnsResolver::DnsResolver() { auto& dnsTlsDispatcher = DnsTlsDispatcher::getInstance(); auto& privateDnsConfiguration = PrivateDnsConfiguration::getInstance(); privateDnsConfiguration.setObserver(&dnsTlsDispatcher); if (isDoHEnabled()) privateDnsConfiguration.initDoh(); } bool DnsResolver::start() { Loading
DnsStats.cpp +39 −22 Original line number Diff line number Diff line Loading @@ -59,10 +59,10 @@ std::string rcodeToName(int rcode) { // clang-format on } bool ensureNoInvalidIp(const std::vector<IPSockAddr>& servers) { for (const auto& server : servers) { if (server.ip() == INVALID_IPADDRESS || server.port() == 0) { LOG(WARNING) << "Invalid server: " << server; bool ensureNoInvalidIp(const std::vector<IPSockAddr>& addrs) { for (const auto& addr : addrs) { if (addr.ip() == INVALID_IPADDRESS || addr.port() == 0) { LOG(WARNING) << "Invalid addr: " << addr; return false; } } Loading @@ -73,8 +73,8 @@ bool ensureNoInvalidIp(const std::vector<IPSockAddr>& servers) { // The comparison ignores the last update time. bool StatsData::operator==(const StatsData& o) const { return std::tie(serverSockAddr, total, rcodeCounts, latencyUs) == std::tie(o.serverSockAddr, o.total, o.rcodeCounts, o.latencyUs); return std::tie(sockAddr, total, rcodeCounts, latencyUs) == std::tie(o.sockAddr, o.total, o.rcodeCounts, o.latencyUs); } int StatsData::averageLatencyMs() const { Loading @@ -82,7 +82,7 @@ int StatsData::averageLatencyMs() const { } std::string StatsData::toString() const { if (total == 0) return StringPrintf("%s <no data>", serverSockAddr.ip().toString().c_str()); if (total == 0) return StringPrintf("%s <no data>", sockAddr.ip().toString().c_str()); const auto now = std::chrono::steady_clock::now(); const int lastUpdateSec = duration_cast<seconds>(now - lastUpdate).count(); Loading @@ -92,7 +92,7 @@ std::string StatsData::toString() const { buf += StringPrintf("%s:%d ", rcodeToName(rcode).c_str(), counts); } } return StringPrintf("%s (%d, %dms, [%s], %ds)", serverSockAddr.ip().toString().c_str(), total, return StringPrintf("%s (%d, %dms, [%s], %ds)", sockAddr.ip().toString().c_str(), total, averageLatencyMs(), buf.c_str(), lastUpdateSec); } Loading Loading @@ -171,20 +171,20 @@ void StatsRecords::incrementSkippedCount() { mSkippedCount = std::min(mSkippedCount + 1, kMaxQuality); } bool DnsStats::setServers(const std::vector<netdutils::IPSockAddr>& servers, Protocol protocol) { if (!ensureNoInvalidIp(servers)) return false; bool DnsStats::setAddrs(const std::vector<netdutils::IPSockAddr>& addrs, Protocol protocol) { if (!ensureNoInvalidIp(addrs)) return false; ServerStatsMap& statsMap = mStats[protocol]; for (const auto& server : servers) { statsMap.try_emplace(server, StatsRecords(server, kLogSize)); StatsMap& statsMap = mStats[protocol]; for (const auto& addr : addrs) { statsMap.try_emplace(addr, StatsRecords(addr, kLogSize)); } // Clean up the map to eliminate the nodes not belonging to the given list of servers. const auto cleanup = [&](ServerStatsMap* statsMap) { ServerStatsMap tmp; for (const auto& server : servers) { if (statsMap->find(server) != statsMap->end()) { tmp.insert(statsMap->extract(server)); const auto cleanup = [&](StatsMap* statsMap) { StatsMap tmp; for (const auto& addr : addrs) { if (statsMap->find(addr) != statsMap->end()) { tmp.insert(statsMap->extract(addr)); } } statsMap->swap(tmp); Loading @@ -199,8 +199,8 @@ bool DnsStats::addStats(const IPSockAddr& ipSockAddr, const DnsQueryEvent& recor if (ipSockAddr.ip() == INVALID_IPADDRESS) return false; bool added = false; for (auto& [serverSockAddr, statsRecords] : mStats[record.protocol()]) { if (serverSockAddr == ipSockAddr) { for (auto& [sockAddr, statsRecords] : mStats[record.protocol()]) { if (sockAddr == ipSockAddr) { const StatsRecords::Record rec = { .rcode = record.rcode(), .linux_errno = record.linux_errno(), Loading Loading @@ -239,6 +239,20 @@ std::vector<IPSockAddr> DnsStats::getSortedServers(Protocol protocol) const { return ret; } std::optional<microseconds> DnsStats::getAverageLatencyUs(Protocol protocol) const { const auto stats = getStats(protocol); int count = 0; microseconds sum; for (const auto& v : stats) { count += v.total; sum += v.latencyUs; } if (count == 0) return std::nullopt; return sum / count; } std::vector<StatsData> DnsStats::getStats(Protocol protocol) const { std::vector<StatsData> ret; Loading @@ -251,10 +265,10 @@ std::vector<StatsData> DnsStats::getStats(Protocol protocol) const { } void DnsStats::dump(DumpWriter& dw) { const auto dumpStatsMap = [&](ServerStatsMap& statsMap) { const auto dumpStatsMap = [&](StatsMap& statsMap) { ScopedIndent indentLog(dw); if (statsMap.size() == 0) { dw.println("<no server>"); dw.println("<no data>"); return; } for (const auto& [_, statsRecords] : statsMap) { Loading @@ -276,6 +290,9 @@ void DnsStats::dump(DumpWriter& dw) { dw.println("over TCP"); dumpStatsMap(mStats[PROTO_TCP]); dw.println("over MDNS"); dumpStatsMap(mStats[PROTO_MDNS]); } } // namespace android::net
DnsStats.h +11 −9 Original line number Diff line number Diff line Loading @@ -33,12 +33,12 @@ namespace android::net { // The overall information of a StatsRecords. struct StatsData { StatsData(const netdutils::IPSockAddr& ipSockAddr) : serverSockAddr(ipSockAddr) { StatsData(const netdutils::IPSockAddr& ipSockAddr) : sockAddr(ipSockAddr) { lastUpdate = std::chrono::steady_clock::now(); }; // Server socket address. netdutils::IPSockAddr serverSockAddr; // Socket address. netdutils::IPSockAddr sockAddr; // The most recent number of records being accumulated. int total = 0; Loading Loading @@ -106,24 +106,26 @@ class StatsRecords { static constexpr int kMaxQuality = 10000; }; // DnsStats class manages the statistics of DNS servers per netId. // DnsStats class manages the statistics of DNS servers or MDNS multicast addresses per netId. // The class itself is not thread-safe. class DnsStats { public: using ServerStatsMap = std::map<netdutils::IPSockAddr, StatsRecords>; using StatsMap = std::map<netdutils::IPSockAddr, StatsRecords>; // Add |servers| to the map, and remove no-longer-used servers. // Add |addrs| to the map, and remove no-longer-used addresses. // Return true if they are successfully added; otherwise, return false. bool setServers(const std::vector<netdutils::IPSockAddr>& servers, Protocol protocol); bool setAddrs(const std::vector<netdutils::IPSockAddr>& addrs, Protocol protocol); // Return true if |record| is successfully added into |server|'s stats; otherwise, return false. bool addStats(const netdutils::IPSockAddr& server, const DnsQueryEvent& record); std::vector<netdutils::IPSockAddr> getSortedServers(Protocol protocol) const; // Returns the average query latency in microseconds. std::optional<std::chrono::microseconds> getAverageLatencyUs(Protocol protocol) const; void dump(netdutils::DumpWriter& dw); // For testing. std::vector<StatsData> getStats(Protocol protocol) const; // TODO: Compatible support for getResolverInfo(). Loading @@ -131,7 +133,7 @@ class DnsStats { static constexpr size_t kLogSize = 128; private: std::map<Protocol, ServerStatsMap> mStats; std::map<Protocol, StatsMap> mStats; }; } // namespace android::net