Loading Android.bp +95 −81 Original line number Original line Diff line number Diff line Loading @@ -30,10 +30,6 @@ license { ], ], } } // Whether to enable the targets in this file that require rust toolchain. // Set to false in branches like mainline-prod where rust toolchain isn't supported. support_rust_toolchain = false cc_library_headers { cc_library_headers { name: "libnetd_resolv_headers", name: "libnetd_resolv_headers", export_include_dirs: ["include"], export_include_dirs: ["include"], Loading @@ -48,6 +44,8 @@ cc_library_headers { cc_library_headers { cc_library_headers { name: "dnsproxyd_protocol_headers", name: "dnsproxyd_protocol_headers", sdk_version: "29", min_sdk_version: "29", export_include_dirs: ["include/dnsproxyd_protocol"], export_include_dirs: ["include/dnsproxyd_protocol"], apex_available: [ apex_available: [ "//apex_available:platform", "//apex_available:platform", Loading @@ -60,7 +58,7 @@ dnsresolver_aidl_interface_lateststable_version = "V8" cc_library_static { cc_library_static { name: "dnsresolver_aidl_interface-lateststable-ndk_platform", name: "dnsresolver_aidl_interface-lateststable-ndk_platform", whole_static_libs: [ whole_static_libs: [ "dnsresolver_aidl_interface-ndk_platform", "dnsresolver_aidl_interface-" + dnsresolver_aidl_interface_lateststable_version + "-ndk_platform", ], ], apex_available: [ apex_available: [ "com.android.resolv", "com.android.resolv", Loading @@ -85,10 +83,11 @@ aidl_interface { backend: { backend: { java: { java: { apex_available: [ apex_available: [ "//apex_available:platform", "com.android.bluetooth.updatable", "com.android.bluetooth.updatable", "com.android.tethering", "com.android.wifi", "com.android.wifi", ], ], min_sdk_version: "30", }, }, ndk: { ndk: { gen_log: true, gen_log: true, Loading @@ -115,6 +114,10 @@ aidl_interface { cc_defaults { cc_defaults { name: "resolv_test_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 // 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 // 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 // to its log revelant functions changing. And most of resolv related tests must be able to run Loading @@ -123,6 +126,8 @@ cc_defaults { "libbase", "libbase", "liblog", "liblog", ], ], // This field is required to make test compatible with Q devices. min_sdk_version: "29", } } cc_defaults { cc_defaults { Loading Loading @@ -190,6 +195,7 @@ cc_library { "libbase", "libbase", "libcutils", "libcutils", "libnetdutils", "libnetdutils", "libdoh_ffi", "libprotobuf-cpp-lite", "libprotobuf-cpp-lite", "libstatslog_resolv", "libstatslog_resolv", "libstatspush_compat", "libstatspush_compat", Loading Loading @@ -258,7 +264,8 @@ cc_library_static { genrule { genrule { name: "statslog_resolv.h", name: "statslog_resolv.h", tools: ["stats-log-api-gen"], 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: [ out: [ "statslog_resolv.h", "statslog_resolv.h", ], ], Loading @@ -267,7 +274,8 @@ genrule { genrule { genrule { name: "statslog_resolv.cpp", name: "statslog_resolv.cpp", tools: ["stats-log-api-gen"], 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: [ out: [ "statslog_resolv.cpp", "statslog_resolv.cpp", ], ], Loading Loading @@ -315,81 +323,87 @@ filegroup { ], ], } } // rust_ffi_static { rust_ffi_static { // name: "libdoh_ffi", name: "libdoh_ffi", // enabled: support_rust_toolchain, crate_name: "doh", // crate_name: "doh", srcs: ["doh.rs"], // srcs: ["doh.rs"], edition: "2018", // edition: "2018", // rlibs: [ rlibs: [ // "libandroid_logger", "libandroid_logger", // "libanyhow", "libanyhow", // "liblazy_static", "libbase64_rust", // "liblibc", "libfutures", // "liblog_rust", "liblibc", // "libquiche", "liblog_rust", // "libring", "libquiche", // "libtokio", "libring", // "liburl", "libtokio", // ], "liburl", // prefer_rlib: true, ], prefer_rlib: true, // shared_libs: [ shared_libs: [ // "libcrypto", "libcrypto", // "libssl", "libssl", // ], ], // apex_available: [ apex_available: [ // "//apex_available:platform", // Needed by doh_ffi_test "//apex_available:platform", // Needed by doh_ffi_test // "com.android.resolv" "com.android.resolv" // ], ], // min_sdk_version: "29", 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", } // cc_test { // It's required by unit tests. // name: "doh_ffi_test", rust_ffi_static { // enabled: support_rust_toolchain, name: "libdoh_ffi_for_test", // test_suites: [ crate_name: "doh", // "general-tests", srcs: ["doh.rs"], // ], edition: "2018", // defaults: ["netd_defaults"], // srcs: ["doh_ffi_test.cpp"], // static_libs: [ // "libdoh_ffi", // "libgmock", // "liblog", // "libring-core", // ], // // These are not carried over from libdoh_ffi. // shared_libs: [ // "libcrypto", // "libssl", // ], // min_sdk_version: "29", // } // rust_test { rlibs: [ // name: "doh_unit_test", "libandroid_logger", // enabled: support_rust_toolchain, "libanyhow", // crate_name: "doh", "libbase64_rust", // srcs: ["doh.rs"], "libfutures", // edition: "2018", "liblibc", // test_suites: ["general-tests"], "liblog_rust", // auto_gen_config: true, "libquiche_static", // // Used to enable root permission for the test. "libring", // // TODO: remove after 'require_root' is supported in rust_test. "libtokio", // test_config_template: ":resolv_rust_test_config_template", "liburl", // rustlibs: [ ], // "libandroid_logger", prefer_rlib: true, // "libanyhow", // "liblazy_static", apex_available: [ // "liblibc", "//apex_available:platform", // Needed by doh_ffi_test // "liblog_rust", "com.android.resolv" // "libquiche", ], // "libring", min_sdk_version: "29", // "libtokio", } // "liburl", // ], // min_sdk_version: "29", // } DnsResolver.cpp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -81,6 +81,7 @@ DnsResolver::DnsResolver() { auto& dnsTlsDispatcher = DnsTlsDispatcher::getInstance(); auto& dnsTlsDispatcher = DnsTlsDispatcher::getInstance(); auto& privateDnsConfiguration = PrivateDnsConfiguration::getInstance(); auto& privateDnsConfiguration = PrivateDnsConfiguration::getInstance(); privateDnsConfiguration.setObserver(&dnsTlsDispatcher); privateDnsConfiguration.setObserver(&dnsTlsDispatcher); if (isDoHEnabled()) privateDnsConfiguration.initDoh(); } } bool DnsResolver::start() { bool DnsResolver::start() { Loading DnsStats.cpp +39 −22 Original line number Original line Diff line number Diff line Loading @@ -59,10 +59,10 @@ std::string rcodeToName(int rcode) { // clang-format on // clang-format on } } bool ensureNoInvalidIp(const std::vector<IPSockAddr>& servers) { bool ensureNoInvalidIp(const std::vector<IPSockAddr>& addrs) { for (const auto& server : servers) { for (const auto& addr : addrs) { if (server.ip() == INVALID_IPADDRESS || server.port() == 0) { if (addr.ip() == INVALID_IPADDRESS || addr.port() == 0) { LOG(WARNING) << "Invalid server: " << server; LOG(WARNING) << "Invalid addr: " << addr; return false; return false; } } } } Loading @@ -73,8 +73,8 @@ bool ensureNoInvalidIp(const std::vector<IPSockAddr>& servers) { // The comparison ignores the last update time. // The comparison ignores the last update time. bool StatsData::operator==(const StatsData& o) const { bool StatsData::operator==(const StatsData& o) const { return std::tie(serverSockAddr, total, rcodeCounts, latencyUs) == return std::tie(sockAddr, total, rcodeCounts, latencyUs) == std::tie(o.serverSockAddr, o.total, o.rcodeCounts, o.latencyUs); std::tie(o.sockAddr, o.total, o.rcodeCounts, o.latencyUs); } } int StatsData::averageLatencyMs() const { int StatsData::averageLatencyMs() const { Loading @@ -82,7 +82,7 @@ int StatsData::averageLatencyMs() const { } } std::string StatsData::toString() 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 auto now = std::chrono::steady_clock::now(); const int lastUpdateSec = duration_cast<seconds>(now - lastUpdate).count(); 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); 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); averageLatencyMs(), buf.c_str(), lastUpdateSec); } } Loading Loading @@ -171,20 +171,20 @@ void StatsRecords::incrementSkippedCount() { mSkippedCount = std::min(mSkippedCount + 1, kMaxQuality); mSkippedCount = std::min(mSkippedCount + 1, kMaxQuality); } } bool DnsStats::setServers(const std::vector<netdutils::IPSockAddr>& servers, Protocol protocol) { bool DnsStats::setAddrs(const std::vector<netdutils::IPSockAddr>& addrs, Protocol protocol) { if (!ensureNoInvalidIp(servers)) return false; if (!ensureNoInvalidIp(addrs)) return false; ServerStatsMap& statsMap = mStats[protocol]; StatsMap& statsMap = mStats[protocol]; for (const auto& server : servers) { for (const auto& addr : addrs) { statsMap.try_emplace(server, StatsRecords(server, kLogSize)); statsMap.try_emplace(addr, StatsRecords(addr, kLogSize)); } } // Clean up the map to eliminate the nodes not belonging to the given list of servers. // Clean up the map to eliminate the nodes not belonging to the given list of servers. const auto cleanup = [&](ServerStatsMap* statsMap) { const auto cleanup = [&](StatsMap* statsMap) { ServerStatsMap tmp; StatsMap tmp; for (const auto& server : servers) { for (const auto& addr : addrs) { if (statsMap->find(server) != statsMap->end()) { if (statsMap->find(addr) != statsMap->end()) { tmp.insert(statsMap->extract(server)); tmp.insert(statsMap->extract(addr)); } } } } statsMap->swap(tmp); statsMap->swap(tmp); Loading @@ -199,8 +199,8 @@ bool DnsStats::addStats(const IPSockAddr& ipSockAddr, const DnsQueryEvent& recor if (ipSockAddr.ip() == INVALID_IPADDRESS) return false; if (ipSockAddr.ip() == INVALID_IPADDRESS) return false; bool added = false; bool added = false; for (auto& [serverSockAddr, statsRecords] : mStats[record.protocol()]) { for (auto& [sockAddr, statsRecords] : mStats[record.protocol()]) { if (serverSockAddr == ipSockAddr) { if (sockAddr == ipSockAddr) { const StatsRecords::Record rec = { const StatsRecords::Record rec = { .rcode = record.rcode(), .rcode = record.rcode(), .linux_errno = record.linux_errno(), .linux_errno = record.linux_errno(), Loading Loading @@ -239,6 +239,20 @@ std::vector<IPSockAddr> DnsStats::getSortedServers(Protocol protocol) const { return ret; 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> DnsStats::getStats(Protocol protocol) const { std::vector<StatsData> ret; std::vector<StatsData> ret; Loading @@ -251,10 +265,10 @@ std::vector<StatsData> DnsStats::getStats(Protocol protocol) const { } } void DnsStats::dump(DumpWriter& dw) { void DnsStats::dump(DumpWriter& dw) { const auto dumpStatsMap = [&](ServerStatsMap& statsMap) { const auto dumpStatsMap = [&](StatsMap& statsMap) { ScopedIndent indentLog(dw); ScopedIndent indentLog(dw); if (statsMap.size() == 0) { if (statsMap.size() == 0) { dw.println("<no server>"); dw.println("<no data>"); return; return; } } for (const auto& [_, statsRecords] : statsMap) { for (const auto& [_, statsRecords] : statsMap) { Loading @@ -276,6 +290,9 @@ void DnsStats::dump(DumpWriter& dw) { dw.println("over TCP"); dw.println("over TCP"); dumpStatsMap(mStats[PROTO_TCP]); dumpStatsMap(mStats[PROTO_TCP]); dw.println("over MDNS"); dumpStatsMap(mStats[PROTO_MDNS]); } } } // namespace android::net } // namespace android::net DnsStats.h +11 −9 Original line number Original line Diff line number Diff line Loading @@ -33,12 +33,12 @@ namespace android::net { // The overall information of a StatsRecords. // The overall information of a StatsRecords. struct StatsData { struct StatsData { StatsData(const netdutils::IPSockAddr& ipSockAddr) : serverSockAddr(ipSockAddr) { StatsData(const netdutils::IPSockAddr& ipSockAddr) : sockAddr(ipSockAddr) { lastUpdate = std::chrono::steady_clock::now(); lastUpdate = std::chrono::steady_clock::now(); }; }; // Server socket address. // Socket address. netdutils::IPSockAddr serverSockAddr; netdutils::IPSockAddr sockAddr; // The most recent number of records being accumulated. // The most recent number of records being accumulated. int total = 0; int total = 0; Loading Loading @@ -106,24 +106,26 @@ class StatsRecords { static constexpr int kMaxQuality = 10000; 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. // The class itself is not thread-safe. class DnsStats { class DnsStats { public: 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. // 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. // Return true if |record| is successfully added into |server|'s stats; otherwise, return false. bool addStats(const netdutils::IPSockAddr& server, const DnsQueryEvent& record); bool addStats(const netdutils::IPSockAddr& server, const DnsQueryEvent& record); std::vector<netdutils::IPSockAddr> getSortedServers(Protocol protocol) const; 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); void dump(netdutils::DumpWriter& dw); // For testing. std::vector<StatsData> getStats(Protocol protocol) const; std::vector<StatsData> getStats(Protocol protocol) const; // TODO: Compatible support for getResolverInfo(). // TODO: Compatible support for getResolverInfo(). Loading @@ -131,7 +133,7 @@ class DnsStats { static constexpr size_t kLogSize = 128; static constexpr size_t kLogSize = 128; private: private: std::map<Protocol, ServerStatsMap> mStats; std::map<Protocol, StatsMap> mStats; }; }; } // namespace android::net } // namespace android::net Loading
Android.bp +95 −81 Original line number Original line Diff line number Diff line Loading @@ -30,10 +30,6 @@ license { ], ], } } // Whether to enable the targets in this file that require rust toolchain. // Set to false in branches like mainline-prod where rust toolchain isn't supported. support_rust_toolchain = false cc_library_headers { cc_library_headers { name: "libnetd_resolv_headers", name: "libnetd_resolv_headers", export_include_dirs: ["include"], export_include_dirs: ["include"], Loading @@ -48,6 +44,8 @@ cc_library_headers { cc_library_headers { cc_library_headers { name: "dnsproxyd_protocol_headers", name: "dnsproxyd_protocol_headers", sdk_version: "29", min_sdk_version: "29", export_include_dirs: ["include/dnsproxyd_protocol"], export_include_dirs: ["include/dnsproxyd_protocol"], apex_available: [ apex_available: [ "//apex_available:platform", "//apex_available:platform", Loading @@ -60,7 +58,7 @@ dnsresolver_aidl_interface_lateststable_version = "V8" cc_library_static { cc_library_static { name: "dnsresolver_aidl_interface-lateststable-ndk_platform", name: "dnsresolver_aidl_interface-lateststable-ndk_platform", whole_static_libs: [ whole_static_libs: [ "dnsresolver_aidl_interface-ndk_platform", "dnsresolver_aidl_interface-" + dnsresolver_aidl_interface_lateststable_version + "-ndk_platform", ], ], apex_available: [ apex_available: [ "com.android.resolv", "com.android.resolv", Loading @@ -85,10 +83,11 @@ aidl_interface { backend: { backend: { java: { java: { apex_available: [ apex_available: [ "//apex_available:platform", "com.android.bluetooth.updatable", "com.android.bluetooth.updatable", "com.android.tethering", "com.android.wifi", "com.android.wifi", ], ], min_sdk_version: "30", }, }, ndk: { ndk: { gen_log: true, gen_log: true, Loading @@ -115,6 +114,10 @@ aidl_interface { cc_defaults { cc_defaults { name: "resolv_test_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 // 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 // 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 // to its log revelant functions changing. And most of resolv related tests must be able to run Loading @@ -123,6 +126,8 @@ cc_defaults { "libbase", "libbase", "liblog", "liblog", ], ], // This field is required to make test compatible with Q devices. min_sdk_version: "29", } } cc_defaults { cc_defaults { Loading Loading @@ -190,6 +195,7 @@ cc_library { "libbase", "libbase", "libcutils", "libcutils", "libnetdutils", "libnetdutils", "libdoh_ffi", "libprotobuf-cpp-lite", "libprotobuf-cpp-lite", "libstatslog_resolv", "libstatslog_resolv", "libstatspush_compat", "libstatspush_compat", Loading Loading @@ -258,7 +264,8 @@ cc_library_static { genrule { genrule { name: "statslog_resolv.h", name: "statslog_resolv.h", tools: ["stats-log-api-gen"], 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: [ out: [ "statslog_resolv.h", "statslog_resolv.h", ], ], Loading @@ -267,7 +274,8 @@ genrule { genrule { genrule { name: "statslog_resolv.cpp", name: "statslog_resolv.cpp", tools: ["stats-log-api-gen"], 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: [ out: [ "statslog_resolv.cpp", "statslog_resolv.cpp", ], ], Loading Loading @@ -315,81 +323,87 @@ filegroup { ], ], } } // rust_ffi_static { rust_ffi_static { // name: "libdoh_ffi", name: "libdoh_ffi", // enabled: support_rust_toolchain, crate_name: "doh", // crate_name: "doh", srcs: ["doh.rs"], // srcs: ["doh.rs"], edition: "2018", // edition: "2018", // rlibs: [ rlibs: [ // "libandroid_logger", "libandroid_logger", // "libanyhow", "libanyhow", // "liblazy_static", "libbase64_rust", // "liblibc", "libfutures", // "liblog_rust", "liblibc", // "libquiche", "liblog_rust", // "libring", "libquiche", // "libtokio", "libring", // "liburl", "libtokio", // ], "liburl", // prefer_rlib: true, ], prefer_rlib: true, // shared_libs: [ shared_libs: [ // "libcrypto", "libcrypto", // "libssl", "libssl", // ], ], // apex_available: [ apex_available: [ // "//apex_available:platform", // Needed by doh_ffi_test "//apex_available:platform", // Needed by doh_ffi_test // "com.android.resolv" "com.android.resolv" // ], ], // min_sdk_version: "29", 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", } // cc_test { // It's required by unit tests. // name: "doh_ffi_test", rust_ffi_static { // enabled: support_rust_toolchain, name: "libdoh_ffi_for_test", // test_suites: [ crate_name: "doh", // "general-tests", srcs: ["doh.rs"], // ], edition: "2018", // defaults: ["netd_defaults"], // srcs: ["doh_ffi_test.cpp"], // static_libs: [ // "libdoh_ffi", // "libgmock", // "liblog", // "libring-core", // ], // // These are not carried over from libdoh_ffi. // shared_libs: [ // "libcrypto", // "libssl", // ], // min_sdk_version: "29", // } // rust_test { rlibs: [ // name: "doh_unit_test", "libandroid_logger", // enabled: support_rust_toolchain, "libanyhow", // crate_name: "doh", "libbase64_rust", // srcs: ["doh.rs"], "libfutures", // edition: "2018", "liblibc", // test_suites: ["general-tests"], "liblog_rust", // auto_gen_config: true, "libquiche_static", // // Used to enable root permission for the test. "libring", // // TODO: remove after 'require_root' is supported in rust_test. "libtokio", // test_config_template: ":resolv_rust_test_config_template", "liburl", // rustlibs: [ ], // "libandroid_logger", prefer_rlib: true, // "libanyhow", // "liblazy_static", apex_available: [ // "liblibc", "//apex_available:platform", // Needed by doh_ffi_test // "liblog_rust", "com.android.resolv" // "libquiche", ], // "libring", min_sdk_version: "29", // "libtokio", } // "liburl", // ], // min_sdk_version: "29", // }
DnsResolver.cpp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -81,6 +81,7 @@ DnsResolver::DnsResolver() { auto& dnsTlsDispatcher = DnsTlsDispatcher::getInstance(); auto& dnsTlsDispatcher = DnsTlsDispatcher::getInstance(); auto& privateDnsConfiguration = PrivateDnsConfiguration::getInstance(); auto& privateDnsConfiguration = PrivateDnsConfiguration::getInstance(); privateDnsConfiguration.setObserver(&dnsTlsDispatcher); privateDnsConfiguration.setObserver(&dnsTlsDispatcher); if (isDoHEnabled()) privateDnsConfiguration.initDoh(); } } bool DnsResolver::start() { bool DnsResolver::start() { Loading
DnsStats.cpp +39 −22 Original line number Original line Diff line number Diff line Loading @@ -59,10 +59,10 @@ std::string rcodeToName(int rcode) { // clang-format on // clang-format on } } bool ensureNoInvalidIp(const std::vector<IPSockAddr>& servers) { bool ensureNoInvalidIp(const std::vector<IPSockAddr>& addrs) { for (const auto& server : servers) { for (const auto& addr : addrs) { if (server.ip() == INVALID_IPADDRESS || server.port() == 0) { if (addr.ip() == INVALID_IPADDRESS || addr.port() == 0) { LOG(WARNING) << "Invalid server: " << server; LOG(WARNING) << "Invalid addr: " << addr; return false; return false; } } } } Loading @@ -73,8 +73,8 @@ bool ensureNoInvalidIp(const std::vector<IPSockAddr>& servers) { // The comparison ignores the last update time. // The comparison ignores the last update time. bool StatsData::operator==(const StatsData& o) const { bool StatsData::operator==(const StatsData& o) const { return std::tie(serverSockAddr, total, rcodeCounts, latencyUs) == return std::tie(sockAddr, total, rcodeCounts, latencyUs) == std::tie(o.serverSockAddr, o.total, o.rcodeCounts, o.latencyUs); std::tie(o.sockAddr, o.total, o.rcodeCounts, o.latencyUs); } } int StatsData::averageLatencyMs() const { int StatsData::averageLatencyMs() const { Loading @@ -82,7 +82,7 @@ int StatsData::averageLatencyMs() const { } } std::string StatsData::toString() 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 auto now = std::chrono::steady_clock::now(); const int lastUpdateSec = duration_cast<seconds>(now - lastUpdate).count(); 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); 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); averageLatencyMs(), buf.c_str(), lastUpdateSec); } } Loading Loading @@ -171,20 +171,20 @@ void StatsRecords::incrementSkippedCount() { mSkippedCount = std::min(mSkippedCount + 1, kMaxQuality); mSkippedCount = std::min(mSkippedCount + 1, kMaxQuality); } } bool DnsStats::setServers(const std::vector<netdutils::IPSockAddr>& servers, Protocol protocol) { bool DnsStats::setAddrs(const std::vector<netdutils::IPSockAddr>& addrs, Protocol protocol) { if (!ensureNoInvalidIp(servers)) return false; if (!ensureNoInvalidIp(addrs)) return false; ServerStatsMap& statsMap = mStats[protocol]; StatsMap& statsMap = mStats[protocol]; for (const auto& server : servers) { for (const auto& addr : addrs) { statsMap.try_emplace(server, StatsRecords(server, kLogSize)); statsMap.try_emplace(addr, StatsRecords(addr, kLogSize)); } } // Clean up the map to eliminate the nodes not belonging to the given list of servers. // Clean up the map to eliminate the nodes not belonging to the given list of servers. const auto cleanup = [&](ServerStatsMap* statsMap) { const auto cleanup = [&](StatsMap* statsMap) { ServerStatsMap tmp; StatsMap tmp; for (const auto& server : servers) { for (const auto& addr : addrs) { if (statsMap->find(server) != statsMap->end()) { if (statsMap->find(addr) != statsMap->end()) { tmp.insert(statsMap->extract(server)); tmp.insert(statsMap->extract(addr)); } } } } statsMap->swap(tmp); statsMap->swap(tmp); Loading @@ -199,8 +199,8 @@ bool DnsStats::addStats(const IPSockAddr& ipSockAddr, const DnsQueryEvent& recor if (ipSockAddr.ip() == INVALID_IPADDRESS) return false; if (ipSockAddr.ip() == INVALID_IPADDRESS) return false; bool added = false; bool added = false; for (auto& [serverSockAddr, statsRecords] : mStats[record.protocol()]) { for (auto& [sockAddr, statsRecords] : mStats[record.protocol()]) { if (serverSockAddr == ipSockAddr) { if (sockAddr == ipSockAddr) { const StatsRecords::Record rec = { const StatsRecords::Record rec = { .rcode = record.rcode(), .rcode = record.rcode(), .linux_errno = record.linux_errno(), .linux_errno = record.linux_errno(), Loading Loading @@ -239,6 +239,20 @@ std::vector<IPSockAddr> DnsStats::getSortedServers(Protocol protocol) const { return ret; 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> DnsStats::getStats(Protocol protocol) const { std::vector<StatsData> ret; std::vector<StatsData> ret; Loading @@ -251,10 +265,10 @@ std::vector<StatsData> DnsStats::getStats(Protocol protocol) const { } } void DnsStats::dump(DumpWriter& dw) { void DnsStats::dump(DumpWriter& dw) { const auto dumpStatsMap = [&](ServerStatsMap& statsMap) { const auto dumpStatsMap = [&](StatsMap& statsMap) { ScopedIndent indentLog(dw); ScopedIndent indentLog(dw); if (statsMap.size() == 0) { if (statsMap.size() == 0) { dw.println("<no server>"); dw.println("<no data>"); return; return; } } for (const auto& [_, statsRecords] : statsMap) { for (const auto& [_, statsRecords] : statsMap) { Loading @@ -276,6 +290,9 @@ void DnsStats::dump(DumpWriter& dw) { dw.println("over TCP"); dw.println("over TCP"); dumpStatsMap(mStats[PROTO_TCP]); dumpStatsMap(mStats[PROTO_TCP]); dw.println("over MDNS"); dumpStatsMap(mStats[PROTO_MDNS]); } } } // namespace android::net } // namespace android::net
DnsStats.h +11 −9 Original line number Original line Diff line number Diff line Loading @@ -33,12 +33,12 @@ namespace android::net { // The overall information of a StatsRecords. // The overall information of a StatsRecords. struct StatsData { struct StatsData { StatsData(const netdutils::IPSockAddr& ipSockAddr) : serverSockAddr(ipSockAddr) { StatsData(const netdutils::IPSockAddr& ipSockAddr) : sockAddr(ipSockAddr) { lastUpdate = std::chrono::steady_clock::now(); lastUpdate = std::chrono::steady_clock::now(); }; }; // Server socket address. // Socket address. netdutils::IPSockAddr serverSockAddr; netdutils::IPSockAddr sockAddr; // The most recent number of records being accumulated. // The most recent number of records being accumulated. int total = 0; int total = 0; Loading Loading @@ -106,24 +106,26 @@ class StatsRecords { static constexpr int kMaxQuality = 10000; 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. // The class itself is not thread-safe. class DnsStats { class DnsStats { public: 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. // 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. // Return true if |record| is successfully added into |server|'s stats; otherwise, return false. bool addStats(const netdutils::IPSockAddr& server, const DnsQueryEvent& record); bool addStats(const netdutils::IPSockAddr& server, const DnsQueryEvent& record); std::vector<netdutils::IPSockAddr> getSortedServers(Protocol protocol) const; 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); void dump(netdutils::DumpWriter& dw); // For testing. std::vector<StatsData> getStats(Protocol protocol) const; std::vector<StatsData> getStats(Protocol protocol) const; // TODO: Compatible support for getResolverInfo(). // TODO: Compatible support for getResolverInfo(). Loading @@ -131,7 +133,7 @@ class DnsStats { static constexpr size_t kLogSize = 128; static constexpr size_t kLogSize = 128; private: private: std::map<Protocol, ServerStatsMap> mStats; std::map<Protocol, StatsMap> mStats; }; }; } // namespace android::net } // namespace android::net