Loading Android.bp +19 −16 Original line number Diff line number Diff line Loading @@ -44,8 +44,8 @@ cc_library_headers { cc_library_headers { name: "dnsproxyd_protocol_headers", sdk_version: "29", min_sdk_version: "29", sdk_version: "30", min_sdk_version: "30", export_include_dirs: ["include/dnsproxyd_protocol"], apex_available: [ "//apex_available:platform", Loading @@ -63,7 +63,7 @@ cc_library_static { apex_available: [ "com.android.resolv", ], min_sdk_version: "29", min_sdk_version: "30", } aidl_interface { Loading Loading @@ -93,7 +93,7 @@ aidl_interface { apex_available: [ "com.android.resolv", ], min_sdk_version: "29", min_sdk_version: "30", }, }, versions: [ Loading Loading @@ -129,7 +129,7 @@ cc_defaults { "liblog", ], // This field is required to make test compatible with Q devices. min_sdk_version: "29", min_sdk_version: "30", } cc_defaults { Loading Loading @@ -249,15 +249,11 @@ cc_library { "libcrypto", "liblog", //Used by libstatslog_resolv "libssl", "libstatssocket", ], header_libs: [ "libnetdbinder_utils_headers", ], runtime_libs: [ // Causes the linkerconfig to create a namespace link from resolv to the // libstatssocket library within the statsd apex "libstatssocket", ], export_include_dirs: ["include"], product_variables: { Loading @@ -275,7 +271,7 @@ cc_library { cfi: true, }, apex_available: ["com.android.resolv"], min_sdk_version: "29", min_sdk_version: "30", } cc_library_static { Loading @@ -289,7 +285,7 @@ cc_library_static { "stats.proto", ], apex_available: ["com.android.resolv"], min_sdk_version: "29", min_sdk_version: "30", } genrule { Loading Loading @@ -326,7 +322,7 @@ cc_library_static { "libgtest_prod_headers", // Used by libstatspush_compat ], apex_available: ["com.android.resolv"], min_sdk_version: "29", min_sdk_version: "30", } filegroup { Loading Loading @@ -362,6 +358,7 @@ doh_rust_deps = [ "liblibc", "liblog_rust", "libring", "libstatslog_rust", "libthiserror", "libtokio", "liburl", Loading @@ -385,7 +382,7 @@ rust_ffi_static { "//apex_available:platform", // Needed by doh_ffi_test "com.android.resolv", ], min_sdk_version: "29", min_sdk_version: "30", } rust_test { Loading @@ -396,7 +393,7 @@ rust_test { test_suites: ["general-tests"], auto_gen_config: true, rustlibs: doh_rust_deps + ["libquiche_static"], min_sdk_version: "29", min_sdk_version: "30", } // It's required by unit tests. Loading @@ -408,6 +405,11 @@ rust_ffi_static { rlibs: doh_rust_deps + ["libquiche_static"], prefer_rlib: true, shared_libs: [ "libstatssocket", ], // TODO(b/194022174), for unit tests to run on the Android 10 platform, // libunwind must be statically linked. whole_static_libs: ["libunwind"], Loading @@ -415,7 +417,7 @@ rust_ffi_static { "//apex_available:platform", // Needed by doh_ffi_test "com.android.resolv", ], min_sdk_version: "29", min_sdk_version: "30", } rust_ffi_static { Loading @@ -438,6 +440,7 @@ rust_ffi_static { "liblog_rust", "libquiche_static", "libring", "libstatslog_rust", "libthiserror", "libtokio", "liburl", Loading DnsProxyListener.cpp +24 −8 Original line number Diff line number Diff line Loading @@ -455,8 +455,11 @@ void logDnsQueryResult(const addrinfo* res) { LOG(DEBUG) << __func__ << ": DNS records:"; for (ai = res, i = 0; ai; ai = ai->ai_next, i++) { if ((ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6)) continue; // Reassign it to a local variable to avoid -Wnullable-to-nonnull-conversion on calling // getnameinfo. const sockaddr* ai_addr = ai->ai_addr; char ip_addr[INET6_ADDRSTRLEN]; int ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, ip_addr, sizeof(ip_addr), nullptr, 0, const int ret = getnameinfo(ai_addr, ai->ai_addrlen, ip_addr, sizeof(ip_addr), nullptr, 0, NI_NUMERICHOST); if (!ret) { LOG(DEBUG) << __func__ << ": [" << i << "] " << ai->ai_flags << " " << ai->ai_family Loading Loading @@ -573,7 +576,10 @@ bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, addrinf sa->ai_next = nullptr; if (cur4->ai_canonname != nullptr) { sa->ai_canonname = strdup(cur4->ai_canonname); // Reassign it to a local variable to avoid -Wnullable-to-nonnull-conversion on calling // strdup. const char* ai_canonname = cur4->ai_canonname; sa->ai_canonname = strdup(ai_canonname); if (sa->ai_canonname == nullptr) { LOG(ERROR) << "allocate memory failed for canonname"; freeaddrinfo(sa); Loading Loading @@ -733,13 +739,15 @@ static bool sendhostent(SocketClient* c, hostent* hp) { bool success = true; int i; if (hp->h_name != nullptr) { success &= sendLenAndData(c, strlen(hp->h_name) + 1, hp->h_name); const char* h_name = hp->h_name; success &= sendLenAndData(c, strlen(h_name) + 1, hp->h_name); } else { success &= sendLenAndData(c, 0, "") == 0; } for (i = 0; hp->h_aliases[i] != nullptr; i++) { success &= sendLenAndData(c, strlen(hp->h_aliases[i]) + 1, hp->h_aliases[i]); const char* h_aliases = hp->h_aliases[i]; success &= sendLenAndData(c, strlen(h_aliases) + 1, hp->h_aliases[i]); } success &= sendLenAndData(c, 0, ""); // null to indicate we're done Loading Loading @@ -782,7 +790,12 @@ static bool sendaddrinfo(SocketClient* c, addrinfo* ai) { } // strlen(ai_canonname) and ai_canonname. if (!sendLenAndData(c, ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, ai->ai_canonname)) { int len = 0; if (ai->ai_canonname != nullptr) { const char* ai_canonname = ai->ai_canonname; len = strlen(ai_canonname) + 1; } if (!sendLenAndData(c, len, ai->ai_canonname)) { return false; } Loading Loading @@ -1401,14 +1414,17 @@ void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(hostent* hbuf, resolv_gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET, hbuf, buf, buflen, &mNetContext, hpp, event); endQueryLimiter(uid); if (*hpp) { if (*hpp && (*hpp)->h_addr_list[0]) { // Replace IPv4 address with original queried IPv6 address in place. The space has // reserved by dns_gethtbyaddr() and netbsd_gethostent_r() in // system/netd/resolv/gethnamaddr.cpp. // Note that resolv_gethostbyaddr() returns only one entry in result. memcpy((*hpp)->h_addr_list[0], &v6addr, sizeof(v6addr)); char* addr = (*hpp)->h_addr_list[0]; memcpy(addr, &v6addr, sizeof(v6addr)); (*hpp)->h_addrtype = AF_INET6; (*hpp)->h_length = sizeof(struct in6_addr); } else { LOG(ERROR) << __func__ << ": hpp or (*hpp)->h_addr_list[0] is null"; } } else { LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached"; Loading DnsQueryLog.cpp +7 −4 Original line number Diff line number Diff line Loading @@ -51,14 +51,17 @@ void DnsQueryLog::push(Record&& record) { mQueue.push(std::move(record)); } uint64_t DnsQueryLog::getLogSizeFromSysProp() { const uint64_t logSize = android::base::GetUintProperty<uint64_t>( "persist.net.dns_query_log_size", kDefaultLogSize); return logSize <= kMaxLogSize ? logSize : kDefaultLogSize; } void DnsQueryLog::dump(netdutils::DumpWriter& dw) const { dw.println("DNS query log (last %lld minutes):", (mValidityTimeMs / 60000).count()); dw.println("DNS query log:"); netdutils::ScopedIndent indentStats(dw); const auto now = std::chrono::system_clock::now(); for (const auto& record : mQueue.copy()) { if (now - record.timestamp > mValidityTimeMs) continue; const std::string maskedHostname = maskHostname(record.hostname); const std::string maskedIpsStr = maskIps(record.addrs); const std::string time = timestampToString(record.timestamp); Loading DnsQueryLog.h +7 −7 Original line number Diff line number Diff line Loading @@ -49,23 +49,23 @@ class DnsQueryLog { const int timeTaken; }; // Allow the tests to set the capacity and the validaty time in milliseconds. DnsQueryLog(size_t size = kDefaultLogSize, std::chrono::milliseconds time = kDefaultValidityMinutes) : mQueue(size), mValidityTimeMs(time) {} DnsQueryLog() : DnsQueryLog(getLogSizeFromSysProp()) {} // Allow the tests to set the capacity. DnsQueryLog(size_t size) : mQueue(size) {} void push(Record&& record); void dump(netdutils::DumpWriter& dw) const; private: LockedRingBuffer<Record> mQueue; const std::chrono::milliseconds mValidityTimeMs; // The capacity of the circular buffer. static constexpr size_t kDefaultLogSize = 200; // The upper bound of the circular buffer. static constexpr size_t kMaxLogSize = 10000; // Limit to dump the queries within last |kDefaultValidityMinutes| minutes. static constexpr std::chrono::minutes kDefaultValidityMinutes{60}; uint64_t getLogSizeFromSysProp(); }; } // namespace android::net DnsQueryLogTest.cpp +29 −17 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <netdutils/NetNativeTestBase.h> #include "DnsQueryLog.h" #include "tests/resolv_test_utils.h" using namespace std::chrono_literals; Loading Loading @@ -140,26 +141,37 @@ TEST_F(DnsQueryLogTest, CapacityFull) { verifyDumpOutput(output, expectedNetIds); } TEST_F(DnsQueryLogTest, ValidityTime) { DnsQueryLog::Record r1(30, 1000, 1000, "www.example.com", serversV4, 10); DnsQueryLog queryLog(3, 100ms); queryLog.push(std::move(r1)); TEST_F(DnsQueryLogTest, SizeCustomization) { const size_t logSize = 3; const ScopedSystemProperties sp(kQueryLogSize, std::to_string(logSize)); DnsQueryLog queryLog; // Dump the output and verify the correctness by checking netId. std::string output = captureDumpOutput(queryLog); verifyDumpOutput(output, {30}); for (int i = 0; i < 200; i++) { DnsQueryLog::Record record(30, 1000, 1000, "www.example.com", serversV4, 10); queryLog.push(std::move(record)); } std::this_thread::sleep_for(150ms); // Verify that there are exact customized number of records in queryLog. const std::string output = captureDumpOutput(queryLog); verifyDumpOutput(output, std::vector(logSize, 30)); } // The record is expired thus not shown in the output. output = captureDumpOutput(queryLog); verifyDumpOutput(output, {}); TEST_F(DnsQueryLogTest, InvalidSizeCustomization) { // The max log size defined in DnsQueryLog.h is 10000. for (const auto& logSize : {"-1", "10001", "non-digit"}) { const ScopedSystemProperties sp(kQueryLogSize, logSize); DnsQueryLog queryLog; // Push another record to ensure it still works. DnsQueryLog::Record r2(31, 1000, 1000, "example.com", serversV4V6, 10); queryLog.push(std::move(r2)); output = captureDumpOutput(queryLog); verifyDumpOutput(output, {31}); for (int i = 0; i < 300; i++) { DnsQueryLog::Record record(30, 1000, 1000, "www.example.com", serversV4, 10); queryLog.push(std::move(record)); } // Verify that queryLog has the default number of records. The default size defined in // DnsQueryLog.h is 200. const std::string output = captureDumpOutput(queryLog); verifyDumpOutput(output, std::vector(200, 30)); } } } // namespace android::net Loading
Android.bp +19 −16 Original line number Diff line number Diff line Loading @@ -44,8 +44,8 @@ cc_library_headers { cc_library_headers { name: "dnsproxyd_protocol_headers", sdk_version: "29", min_sdk_version: "29", sdk_version: "30", min_sdk_version: "30", export_include_dirs: ["include/dnsproxyd_protocol"], apex_available: [ "//apex_available:platform", Loading @@ -63,7 +63,7 @@ cc_library_static { apex_available: [ "com.android.resolv", ], min_sdk_version: "29", min_sdk_version: "30", } aidl_interface { Loading Loading @@ -93,7 +93,7 @@ aidl_interface { apex_available: [ "com.android.resolv", ], min_sdk_version: "29", min_sdk_version: "30", }, }, versions: [ Loading Loading @@ -129,7 +129,7 @@ cc_defaults { "liblog", ], // This field is required to make test compatible with Q devices. min_sdk_version: "29", min_sdk_version: "30", } cc_defaults { Loading Loading @@ -249,15 +249,11 @@ cc_library { "libcrypto", "liblog", //Used by libstatslog_resolv "libssl", "libstatssocket", ], header_libs: [ "libnetdbinder_utils_headers", ], runtime_libs: [ // Causes the linkerconfig to create a namespace link from resolv to the // libstatssocket library within the statsd apex "libstatssocket", ], export_include_dirs: ["include"], product_variables: { Loading @@ -275,7 +271,7 @@ cc_library { cfi: true, }, apex_available: ["com.android.resolv"], min_sdk_version: "29", min_sdk_version: "30", } cc_library_static { Loading @@ -289,7 +285,7 @@ cc_library_static { "stats.proto", ], apex_available: ["com.android.resolv"], min_sdk_version: "29", min_sdk_version: "30", } genrule { Loading Loading @@ -326,7 +322,7 @@ cc_library_static { "libgtest_prod_headers", // Used by libstatspush_compat ], apex_available: ["com.android.resolv"], min_sdk_version: "29", min_sdk_version: "30", } filegroup { Loading Loading @@ -362,6 +358,7 @@ doh_rust_deps = [ "liblibc", "liblog_rust", "libring", "libstatslog_rust", "libthiserror", "libtokio", "liburl", Loading @@ -385,7 +382,7 @@ rust_ffi_static { "//apex_available:platform", // Needed by doh_ffi_test "com.android.resolv", ], min_sdk_version: "29", min_sdk_version: "30", } rust_test { Loading @@ -396,7 +393,7 @@ rust_test { test_suites: ["general-tests"], auto_gen_config: true, rustlibs: doh_rust_deps + ["libquiche_static"], min_sdk_version: "29", min_sdk_version: "30", } // It's required by unit tests. Loading @@ -408,6 +405,11 @@ rust_ffi_static { rlibs: doh_rust_deps + ["libquiche_static"], prefer_rlib: true, shared_libs: [ "libstatssocket", ], // TODO(b/194022174), for unit tests to run on the Android 10 platform, // libunwind must be statically linked. whole_static_libs: ["libunwind"], Loading @@ -415,7 +417,7 @@ rust_ffi_static { "//apex_available:platform", // Needed by doh_ffi_test "com.android.resolv", ], min_sdk_version: "29", min_sdk_version: "30", } rust_ffi_static { Loading @@ -438,6 +440,7 @@ rust_ffi_static { "liblog_rust", "libquiche_static", "libring", "libstatslog_rust", "libthiserror", "libtokio", "liburl", Loading
DnsProxyListener.cpp +24 −8 Original line number Diff line number Diff line Loading @@ -455,8 +455,11 @@ void logDnsQueryResult(const addrinfo* res) { LOG(DEBUG) << __func__ << ": DNS records:"; for (ai = res, i = 0; ai; ai = ai->ai_next, i++) { if ((ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6)) continue; // Reassign it to a local variable to avoid -Wnullable-to-nonnull-conversion on calling // getnameinfo. const sockaddr* ai_addr = ai->ai_addr; char ip_addr[INET6_ADDRSTRLEN]; int ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, ip_addr, sizeof(ip_addr), nullptr, 0, const int ret = getnameinfo(ai_addr, ai->ai_addrlen, ip_addr, sizeof(ip_addr), nullptr, 0, NI_NUMERICHOST); if (!ret) { LOG(DEBUG) << __func__ << ": [" << i << "] " << ai->ai_flags << " " << ai->ai_family Loading Loading @@ -573,7 +576,10 @@ bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, addrinf sa->ai_next = nullptr; if (cur4->ai_canonname != nullptr) { sa->ai_canonname = strdup(cur4->ai_canonname); // Reassign it to a local variable to avoid -Wnullable-to-nonnull-conversion on calling // strdup. const char* ai_canonname = cur4->ai_canonname; sa->ai_canonname = strdup(ai_canonname); if (sa->ai_canonname == nullptr) { LOG(ERROR) << "allocate memory failed for canonname"; freeaddrinfo(sa); Loading Loading @@ -733,13 +739,15 @@ static bool sendhostent(SocketClient* c, hostent* hp) { bool success = true; int i; if (hp->h_name != nullptr) { success &= sendLenAndData(c, strlen(hp->h_name) + 1, hp->h_name); const char* h_name = hp->h_name; success &= sendLenAndData(c, strlen(h_name) + 1, hp->h_name); } else { success &= sendLenAndData(c, 0, "") == 0; } for (i = 0; hp->h_aliases[i] != nullptr; i++) { success &= sendLenAndData(c, strlen(hp->h_aliases[i]) + 1, hp->h_aliases[i]); const char* h_aliases = hp->h_aliases[i]; success &= sendLenAndData(c, strlen(h_aliases) + 1, hp->h_aliases[i]); } success &= sendLenAndData(c, 0, ""); // null to indicate we're done Loading Loading @@ -782,7 +790,12 @@ static bool sendaddrinfo(SocketClient* c, addrinfo* ai) { } // strlen(ai_canonname) and ai_canonname. if (!sendLenAndData(c, ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, ai->ai_canonname)) { int len = 0; if (ai->ai_canonname != nullptr) { const char* ai_canonname = ai->ai_canonname; len = strlen(ai_canonname) + 1; } if (!sendLenAndData(c, len, ai->ai_canonname)) { return false; } Loading Loading @@ -1401,14 +1414,17 @@ void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(hostent* hbuf, resolv_gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET, hbuf, buf, buflen, &mNetContext, hpp, event); endQueryLimiter(uid); if (*hpp) { if (*hpp && (*hpp)->h_addr_list[0]) { // Replace IPv4 address with original queried IPv6 address in place. The space has // reserved by dns_gethtbyaddr() and netbsd_gethostent_r() in // system/netd/resolv/gethnamaddr.cpp. // Note that resolv_gethostbyaddr() returns only one entry in result. memcpy((*hpp)->h_addr_list[0], &v6addr, sizeof(v6addr)); char* addr = (*hpp)->h_addr_list[0]; memcpy(addr, &v6addr, sizeof(v6addr)); (*hpp)->h_addrtype = AF_INET6; (*hpp)->h_length = sizeof(struct in6_addr); } else { LOG(ERROR) << __func__ << ": hpp or (*hpp)->h_addr_list[0] is null"; } } else { LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached"; Loading
DnsQueryLog.cpp +7 −4 Original line number Diff line number Diff line Loading @@ -51,14 +51,17 @@ void DnsQueryLog::push(Record&& record) { mQueue.push(std::move(record)); } uint64_t DnsQueryLog::getLogSizeFromSysProp() { const uint64_t logSize = android::base::GetUintProperty<uint64_t>( "persist.net.dns_query_log_size", kDefaultLogSize); return logSize <= kMaxLogSize ? logSize : kDefaultLogSize; } void DnsQueryLog::dump(netdutils::DumpWriter& dw) const { dw.println("DNS query log (last %lld minutes):", (mValidityTimeMs / 60000).count()); dw.println("DNS query log:"); netdutils::ScopedIndent indentStats(dw); const auto now = std::chrono::system_clock::now(); for (const auto& record : mQueue.copy()) { if (now - record.timestamp > mValidityTimeMs) continue; const std::string maskedHostname = maskHostname(record.hostname); const std::string maskedIpsStr = maskIps(record.addrs); const std::string time = timestampToString(record.timestamp); Loading
DnsQueryLog.h +7 −7 Original line number Diff line number Diff line Loading @@ -49,23 +49,23 @@ class DnsQueryLog { const int timeTaken; }; // Allow the tests to set the capacity and the validaty time in milliseconds. DnsQueryLog(size_t size = kDefaultLogSize, std::chrono::milliseconds time = kDefaultValidityMinutes) : mQueue(size), mValidityTimeMs(time) {} DnsQueryLog() : DnsQueryLog(getLogSizeFromSysProp()) {} // Allow the tests to set the capacity. DnsQueryLog(size_t size) : mQueue(size) {} void push(Record&& record); void dump(netdutils::DumpWriter& dw) const; private: LockedRingBuffer<Record> mQueue; const std::chrono::milliseconds mValidityTimeMs; // The capacity of the circular buffer. static constexpr size_t kDefaultLogSize = 200; // The upper bound of the circular buffer. static constexpr size_t kMaxLogSize = 10000; // Limit to dump the queries within last |kDefaultValidityMinutes| minutes. static constexpr std::chrono::minutes kDefaultValidityMinutes{60}; uint64_t getLogSizeFromSysProp(); }; } // namespace android::net
DnsQueryLogTest.cpp +29 −17 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <netdutils/NetNativeTestBase.h> #include "DnsQueryLog.h" #include "tests/resolv_test_utils.h" using namespace std::chrono_literals; Loading Loading @@ -140,26 +141,37 @@ TEST_F(DnsQueryLogTest, CapacityFull) { verifyDumpOutput(output, expectedNetIds); } TEST_F(DnsQueryLogTest, ValidityTime) { DnsQueryLog::Record r1(30, 1000, 1000, "www.example.com", serversV4, 10); DnsQueryLog queryLog(3, 100ms); queryLog.push(std::move(r1)); TEST_F(DnsQueryLogTest, SizeCustomization) { const size_t logSize = 3; const ScopedSystemProperties sp(kQueryLogSize, std::to_string(logSize)); DnsQueryLog queryLog; // Dump the output and verify the correctness by checking netId. std::string output = captureDumpOutput(queryLog); verifyDumpOutput(output, {30}); for (int i = 0; i < 200; i++) { DnsQueryLog::Record record(30, 1000, 1000, "www.example.com", serversV4, 10); queryLog.push(std::move(record)); } std::this_thread::sleep_for(150ms); // Verify that there are exact customized number of records in queryLog. const std::string output = captureDumpOutput(queryLog); verifyDumpOutput(output, std::vector(logSize, 30)); } // The record is expired thus not shown in the output. output = captureDumpOutput(queryLog); verifyDumpOutput(output, {}); TEST_F(DnsQueryLogTest, InvalidSizeCustomization) { // The max log size defined in DnsQueryLog.h is 10000. for (const auto& logSize : {"-1", "10001", "non-digit"}) { const ScopedSystemProperties sp(kQueryLogSize, logSize); DnsQueryLog queryLog; // Push another record to ensure it still works. DnsQueryLog::Record r2(31, 1000, 1000, "example.com", serversV4V6, 10); queryLog.push(std::move(r2)); output = captureDumpOutput(queryLog); verifyDumpOutput(output, {31}); for (int i = 0; i < 300; i++) { DnsQueryLog::Record record(30, 1000, 1000, "www.example.com", serversV4, 10); queryLog.push(std::move(record)); } // Verify that queryLog has the default number of records. The default size defined in // DnsQueryLog.h is 200. const std::string output = captureDumpOutput(queryLog); verifyDumpOutput(output, std::vector(200, 30)); } } } // namespace android::net