Loading Android.bp +56 −14 Original line number Diff line number Diff line Loading @@ -53,12 +53,12 @@ cc_library_headers { ], } dnsresolver_aidl_interface_lateststable_version = "V8" dnsresolver_aidl_interface_lateststable_version = "V10" cc_library_static { name: "dnsresolver_aidl_interface-lateststable-ndk_platform", name: "dnsresolver_aidl_interface-lateststable-ndk", whole_static_libs: [ "dnsresolver_aidl_interface-" + dnsresolver_aidl_interface_lateststable_version + "-ndk_platform", "dnsresolver_aidl_interface-" + dnsresolver_aidl_interface_lateststable_version + "-ndk", ], apex_available: [ "com.android.resolv", Loading @@ -78,7 +78,7 @@ aidl_interface { "binder/android/net/resolv/aidl/**/*.aidl", ], imports: [ "netd_event_listener_interface", "netd_event_listener_interface-V1", ], backend: { java: { Loading Loading @@ -106,6 +106,8 @@ aidl_interface { "6", "7", "8", "9", "10", ], dumpapi: { no_license: true, Loading @@ -114,6 +116,10 @@ aidl_interface { 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 Loading @@ -187,15 +193,17 @@ cc_library { // Link most things statically to minimize our dependence on system ABIs. stl: "libc++_static", static_libs: [ "dnsresolver_aidl_interface-lateststable-ndk_platform", "dnsresolver_aidl_interface-lateststable-ndk", "libbase", "libcutils", "libnetdutils", "libdoh_ffi", "libmodules-utils-build", "libprotobuf-cpp-lite", "libstatslog_resolv", "libstatspush_compat", "libsysutils", "netd_event_listener_interface-lateststable-ndk_platform", "netd_event_listener_interface-lateststable-ndk", "server_configurable_flags", "stats_proto", ], Loading Loading @@ -259,7 +267,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 @@ -268,7 +277,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 Loading @@ -319,13 +329,14 @@ filegroup { rust_ffi_static { name: "libdoh_ffi", crate_name: "doh", srcs: ["doh.rs"], srcs: ["doh/doh.rs"], edition: "2018", rlibs: [ "libandroid_logger", "libanyhow", "liblazy_static", "libbase64_rust", "libfutures", "liblibc", "liblog_rust", "libquiche", Loading @@ -342,7 +353,7 @@ rust_ffi_static { apex_available: [ "//apex_available:platform", // Needed by doh_ffi_test "com.android.resolv" "com.android.resolv", ], min_sdk_version: "29", } Loading @@ -350,7 +361,7 @@ rust_ffi_static { rust_test { name: "doh_unit_test", crate_name: "doh", srcs: ["doh.rs"], srcs: ["doh/doh.rs"], edition: "2018", test_suites: ["general-tests"], auto_gen_config: true, Loading @@ -360,7 +371,30 @@ rust_test { rustlibs: [ "libandroid_logger", "libanyhow", "liblazy_static", "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/doh.rs"], edition: "2018", rlibs: [ "libandroid_logger", "libanyhow", "libbase64_rust", "libfutures", "liblibc", "liblog_rust", "libquiche_static", Loading @@ -368,5 +402,13 @@ rust_test { "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", } Dns64Configuration.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ namespace android { using android::base::StringPrintf; using android::net::NetworkDnsEventReported; using netdutils::DumpWriter; using netdutils::IPAddress; Loading Loading @@ -65,7 +64,7 @@ void Dns64Configuration::startPrefixDiscovery(unsigned netId) { // Note that capturing |cfg| in this lambda creates a copy. std::thread discovery_thread([this, cfg, netId] { setThreadName(StringPrintf("Nat64Pfx_%u", netId).c_str()); setThreadName(fmt::format("Nat64Pfx_{}", netId)); // Make a mutable copy rather than mark the whole lambda mutable. // No particular reason. Loading DnsProxyListener.cpp +32 −28 Original line number Diff line number Diff line Loading @@ -34,13 +34,11 @@ #include <algorithm> #include <vector> #include <android-base/stringprintf.h> #include <android/multinetwork.h> // ResNsendFlags #include <cutils/misc.h> // FIRST_APPLICATION_UID #include <cutils/multiuser.h> #include <netdutils/InternetAddresses.h> #include <netdutils/ResponseCode.h> #include <netdutils/Slice.h> #include <netdutils/Stopwatch.h> #include <netdutils/ThreadUtil.h> #include <private/android_filesystem_config.h> // AID_SYSTEM Loading @@ -48,6 +46,7 @@ #include <sysutils/SocketClient.h> #include "DnsResolver.h" #include "Experiments.h" #include "NetdPermissions.h" #include "OperationLimiter.h" #include "PrivateDnsConfiguration.h" Loading @@ -65,6 +64,7 @@ using aidl::android::net::metrics::INetdEventListener; using aidl::android::net::resolv::aidl::DnsHealthEventParcel; using aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener; using android::net::NetworkDnsEventReported; using std::span; namespace android { Loading Loading @@ -147,11 +147,11 @@ void maybeFixupNetContext(android_net_context* ctx, pid_t pid) { void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr, socklen_t addrlen); int extractResNsendAnswers(const uint8_t* answer, size_t anslen, int ipType, int extractResNsendAnswers(std::span<const uint8_t> answer, int ipType, std::vector<std::string>* ip_addrs) { int total_ip_addr_count = 0; ns_msg handle; if (ns_initparse((const uint8_t*)answer, anslen, &handle) < 0) { if (ns_initparse(answer.data(), answer.size(), &handle) < 0) { return 0; } int ancount = ns_msg_count(handle, ns_s_an); Loading Loading @@ -250,21 +250,20 @@ bool simpleStrtoul(const char* input, IntegralType* output, int base = 10) { return true; } bool setQueryId(uint8_t* msg, size_t msgLen, uint16_t query_id) { if (msgLen < sizeof(HEADER)) { bool setQueryId(span<uint8_t> msg, uint16_t query_id) { if ((size_t)msg.size() < sizeof(HEADER)) { errno = EINVAL; return false; } auto hp = reinterpret_cast<HEADER*>(msg); auto hp = reinterpret_cast<HEADER*>(msg.data()); hp->id = htons(query_id); return true; } bool parseQuery(const uint8_t* msg, size_t msgLen, uint16_t* query_id, int* rr_type, std::string* rr_name) { bool parseQuery(span<const uint8_t> msg, uint16_t* query_id, int* rr_type, std::string* rr_name) { ns_msg handle; ns_rr rr; if (ns_initparse((const uint8_t*)msg, msgLen, &handle) < 0 || if (ns_initparse(msg.data(), msg.size(), &handle) < 0 || ns_parserr(&handle, ns_s_qd, 0, &rr) < 0) { return false; } Loading Loading @@ -306,8 +305,8 @@ void initDnsEvent(NetworkDnsEventReported* event, const android_net_context& net // Return 0 if the event should not be logged. // Otherwise, return subsampling_denom uint32_t getDnsEventSubsamplingRate(int netid, int returnCode) { uint32_t subsampling_denom = resolv_cache_get_subsampling_denom(netid, returnCode); uint32_t getDnsEventSubsamplingRate(int netid, int returnCode, bool isMdns) { uint32_t subsampling_denom = resolv_cache_get_subsampling_denom(netid, returnCode, isMdns); if (subsampling_denom == 0) return 0; // Sample the event with a chance of 1 / denom. return (arc4random_uniform(subsampling_denom) == 0) ? subsampling_denom : 0; Loading @@ -334,7 +333,12 @@ void maybeLogQuery(int eventType, const android_net_context& netContext, void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs, int returnCode, NetworkDnsEventReported& event, const std::string& query_name, const std::vector<std::string>& ip_addrs = {}, int total_ip_addr_count = 0) { if (uint32_t rate = getDnsEventSubsamplingRate(netContext.dns_netid, returnCode)) { uint32_t rate = (query_name.ends_with(".local") && android::net::Experiments::getInstance()->getFlag("mdns_resolution", 1)) ? getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, true) : getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, false); if (rate) { const std::string& dnsQueryStats = event.dns_query_events().SerializeAsString(); stats::BytesField dnsQueryBytesField{dnsQueryStats.c_str(), dnsQueryStats.size()}; event.set_return_code(static_cast<ReturnCode>(returnCode)); Loading Loading @@ -560,7 +564,7 @@ bool getDns64Prefix(unsigned netId, netdutils::IPPrefix* prefix) { std::string makeThreadName(unsigned netId, uint32_t uid) { // The maximum of netId and app_id are 5-digit numbers. return android::base::StringPrintf("Dns_%u_%u", netId, multiuser_get_app_id(uid)); return fmt::format("Dns_{}_{}", netId, multiuser_get_app_id(uid)); } } // namespace Loading Loading @@ -922,8 +926,8 @@ void DnsProxyListener::ResNSendHandler::run() { uint16_t original_query_id = 0; // TODO: Handle the case which is msg contains more than one query if (!parseQuery(msg.data(), msgLen, &original_query_id, &rr_type, &rr_name) || !setQueryId(msg.data(), msgLen, arc4random_uniform(65536))) { if (!parseQuery({msg.data(), msgLen}, &original_query_id, &rr_type, &rr_name) || !setQueryId({msg.data(), msgLen}, arc4random_uniform(65536))) { // If the query couldn't be parsed, block the request. LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid << ", invalid query"; sendBE32(mClient, -EINVAL); Loading @@ -933,21 +937,21 @@ void DnsProxyListener::ResNSendHandler::run() { // Send DNS query std::vector<uint8_t> ansBuf(MAXPACKET, 0); int rcode = ns_r_noerror; int nsendAns = -1; int ansLen = -1; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); if (queryLimiter.start(uid)) { if (evaluate_domain_name(mNetContext, rr_name.c_str())) { nsendAns = resolv_res_nsend(&mNetContext, msg.data(), msgLen, ansBuf.data(), MAXPACKET, &rcode, static_cast<ResNsendFlags>(mFlags), &event); ansLen = resolv_res_nsend(&mNetContext, {msg.data(), msgLen}, ansBuf, &rcode, static_cast<ResNsendFlags>(mFlags), &event); } else { nsendAns = -EAI_SYSTEM; ansLen = -EAI_SYSTEM; } queryLimiter.finish(uid); } else { LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid << ", max concurrent queries reached"; nsendAns = -EBUSY; ansLen = -EBUSY; } const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs()); Loading @@ -956,14 +960,14 @@ void DnsProxyListener::ResNSendHandler::run() { event.set_res_nsend_flags(static_cast<ResNsendFlags>(mFlags)); // Fail, send -errno if (nsendAns < 0) { if (!sendBE32(mClient, nsendAns)) { if (ansLen < 0) { if (!sendBE32(mClient, ansLen)) { PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send errno to uid " << uid << " pid " << mClient->getPid(); } if (rr_type == ns_t_a || rr_type == ns_t_aaaa) { reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, resNSendToAiError(nsendAns, rcode), event, rr_name); resNSendToAiError(ansLen, rcode), event, rr_name); } return; } Loading @@ -976,8 +980,8 @@ void DnsProxyListener::ResNSendHandler::run() { } // Restore query id and send answer if (!setQueryId(ansBuf.data(), nsendAns, original_query_id) || !sendLenAndData(mClient, nsendAns, ansBuf.data())) { if (!setQueryId({ansBuf.data(), ansLen}, original_query_id) || !sendLenAndData(mClient, ansLen, ansBuf.data())) { PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send answer to uid " << uid << " pid " << mClient->getPid(); return; Loading @@ -986,9 +990,9 @@ void DnsProxyListener::ResNSendHandler::run() { if (rr_type == ns_t_a || rr_type == ns_t_aaaa) { std::vector<std::string> ip_addrs; const int total_ip_addr_count = extractResNsendAnswers((uint8_t*)ansBuf.data(), nsendAns, rr_type, &ip_addrs); extractResNsendAnswers({ansBuf.data(), ansLen}, rr_type, &ip_addrs); reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, resNSendToAiError(nsendAns, rcode), event, rr_name, ip_addrs, resNSendToAiError(ansLen, rcode), event, rr_name, ip_addrs, total_ip_addr_count); } } Loading 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 DnsResolverService.cpp +12 −5 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ #include <vector> #include <BinderUtil.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <android/binder_manager.h> #include <android/binder_process.h> Loading @@ -36,9 +35,9 @@ #include "ResolverEventReporter.h" #include "resolv_cache.h" using aidl::android::net::ResolverOptionsParcel; using aidl::android::net::ResolverParamsParcel; using android::base::Join; using android::base::StringPrintf; using android::netdutils::DumpWriter; using android::netdutils::IPPrefix; Loading Loading @@ -181,8 +180,8 @@ binder_status_t DnsResolverService::dump(int fd, const char** args, uint32_t num } } auto err = StringPrintf("UID %d / PID %d does not have any of the following permissions: %s", uid, pid, Join(permissions, ',').c_str()); auto err = fmt::format("UID {} / PID {} does not have any of the following permissions: {}", uid, pid, Join(permissions, ',')); return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(EX_SECURITY, err.c_str())); } Loading @@ -196,7 +195,7 @@ binder_status_t DnsResolverService::dump(int fd, const char** args, uint32_t num uid_t uid = AIBinder_getCallingUid(); // CAUTION: caCertificate should NOT be used except for internal testing. if (resolverParams.caCertificate.size() != 0 && uid != AID_ROOT) { auto err = StringPrintf("UID %d is not authorized to set a non-empty CA certificate", uid); auto err = fmt::format("UID {} is not authorized to set a non-empty CA certificate", uid); return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(EX_SECURITY, err.c_str())); } Loading Loading @@ -307,5 +306,13 @@ binder_status_t DnsResolverService::dump(int fd, const char** args, uint32_t num return statusFromErrcode(res); } ::ndk::ScopedAStatus DnsResolverService::setResolverOptions(int32_t netId, const ResolverOptionsParcel& options) { // Locking happens in res_cache.cpp functions. ENFORCE_NETWORK_STACK_PERMISSIONS(); return statusFromErrcode(resolv_set_options(netId, options)); } } // namespace net } // namespace android Loading
Android.bp +56 −14 Original line number Diff line number Diff line Loading @@ -53,12 +53,12 @@ cc_library_headers { ], } dnsresolver_aidl_interface_lateststable_version = "V8" dnsresolver_aidl_interface_lateststable_version = "V10" cc_library_static { name: "dnsresolver_aidl_interface-lateststable-ndk_platform", name: "dnsresolver_aidl_interface-lateststable-ndk", whole_static_libs: [ "dnsresolver_aidl_interface-" + dnsresolver_aidl_interface_lateststable_version + "-ndk_platform", "dnsresolver_aidl_interface-" + dnsresolver_aidl_interface_lateststable_version + "-ndk", ], apex_available: [ "com.android.resolv", Loading @@ -78,7 +78,7 @@ aidl_interface { "binder/android/net/resolv/aidl/**/*.aidl", ], imports: [ "netd_event_listener_interface", "netd_event_listener_interface-V1", ], backend: { java: { Loading Loading @@ -106,6 +106,8 @@ aidl_interface { "6", "7", "8", "9", "10", ], dumpapi: { no_license: true, Loading @@ -114,6 +116,10 @@ aidl_interface { 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 Loading @@ -187,15 +193,17 @@ cc_library { // Link most things statically to minimize our dependence on system ABIs. stl: "libc++_static", static_libs: [ "dnsresolver_aidl_interface-lateststable-ndk_platform", "dnsresolver_aidl_interface-lateststable-ndk", "libbase", "libcutils", "libnetdutils", "libdoh_ffi", "libmodules-utils-build", "libprotobuf-cpp-lite", "libstatslog_resolv", "libstatspush_compat", "libsysutils", "netd_event_listener_interface-lateststable-ndk_platform", "netd_event_listener_interface-lateststable-ndk", "server_configurable_flags", "stats_proto", ], Loading Loading @@ -259,7 +267,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 @@ -268,7 +277,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 Loading @@ -319,13 +329,14 @@ filegroup { rust_ffi_static { name: "libdoh_ffi", crate_name: "doh", srcs: ["doh.rs"], srcs: ["doh/doh.rs"], edition: "2018", rlibs: [ "libandroid_logger", "libanyhow", "liblazy_static", "libbase64_rust", "libfutures", "liblibc", "liblog_rust", "libquiche", Loading @@ -342,7 +353,7 @@ rust_ffi_static { apex_available: [ "//apex_available:platform", // Needed by doh_ffi_test "com.android.resolv" "com.android.resolv", ], min_sdk_version: "29", } Loading @@ -350,7 +361,7 @@ rust_ffi_static { rust_test { name: "doh_unit_test", crate_name: "doh", srcs: ["doh.rs"], srcs: ["doh/doh.rs"], edition: "2018", test_suites: ["general-tests"], auto_gen_config: true, Loading @@ -360,7 +371,30 @@ rust_test { rustlibs: [ "libandroid_logger", "libanyhow", "liblazy_static", "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/doh.rs"], edition: "2018", rlibs: [ "libandroid_logger", "libanyhow", "libbase64_rust", "libfutures", "liblibc", "liblog_rust", "libquiche_static", Loading @@ -368,5 +402,13 @@ rust_test { "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", }
Dns64Configuration.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ namespace android { using android::base::StringPrintf; using android::net::NetworkDnsEventReported; using netdutils::DumpWriter; using netdutils::IPAddress; Loading Loading @@ -65,7 +64,7 @@ void Dns64Configuration::startPrefixDiscovery(unsigned netId) { // Note that capturing |cfg| in this lambda creates a copy. std::thread discovery_thread([this, cfg, netId] { setThreadName(StringPrintf("Nat64Pfx_%u", netId).c_str()); setThreadName(fmt::format("Nat64Pfx_{}", netId)); // Make a mutable copy rather than mark the whole lambda mutable. // No particular reason. Loading
DnsProxyListener.cpp +32 −28 Original line number Diff line number Diff line Loading @@ -34,13 +34,11 @@ #include <algorithm> #include <vector> #include <android-base/stringprintf.h> #include <android/multinetwork.h> // ResNsendFlags #include <cutils/misc.h> // FIRST_APPLICATION_UID #include <cutils/multiuser.h> #include <netdutils/InternetAddresses.h> #include <netdutils/ResponseCode.h> #include <netdutils/Slice.h> #include <netdutils/Stopwatch.h> #include <netdutils/ThreadUtil.h> #include <private/android_filesystem_config.h> // AID_SYSTEM Loading @@ -48,6 +46,7 @@ #include <sysutils/SocketClient.h> #include "DnsResolver.h" #include "Experiments.h" #include "NetdPermissions.h" #include "OperationLimiter.h" #include "PrivateDnsConfiguration.h" Loading @@ -65,6 +64,7 @@ using aidl::android::net::metrics::INetdEventListener; using aidl::android::net::resolv::aidl::DnsHealthEventParcel; using aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener; using android::net::NetworkDnsEventReported; using std::span; namespace android { Loading Loading @@ -147,11 +147,11 @@ void maybeFixupNetContext(android_net_context* ctx, pid_t pid) { void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr, socklen_t addrlen); int extractResNsendAnswers(const uint8_t* answer, size_t anslen, int ipType, int extractResNsendAnswers(std::span<const uint8_t> answer, int ipType, std::vector<std::string>* ip_addrs) { int total_ip_addr_count = 0; ns_msg handle; if (ns_initparse((const uint8_t*)answer, anslen, &handle) < 0) { if (ns_initparse(answer.data(), answer.size(), &handle) < 0) { return 0; } int ancount = ns_msg_count(handle, ns_s_an); Loading Loading @@ -250,21 +250,20 @@ bool simpleStrtoul(const char* input, IntegralType* output, int base = 10) { return true; } bool setQueryId(uint8_t* msg, size_t msgLen, uint16_t query_id) { if (msgLen < sizeof(HEADER)) { bool setQueryId(span<uint8_t> msg, uint16_t query_id) { if ((size_t)msg.size() < sizeof(HEADER)) { errno = EINVAL; return false; } auto hp = reinterpret_cast<HEADER*>(msg); auto hp = reinterpret_cast<HEADER*>(msg.data()); hp->id = htons(query_id); return true; } bool parseQuery(const uint8_t* msg, size_t msgLen, uint16_t* query_id, int* rr_type, std::string* rr_name) { bool parseQuery(span<const uint8_t> msg, uint16_t* query_id, int* rr_type, std::string* rr_name) { ns_msg handle; ns_rr rr; if (ns_initparse((const uint8_t*)msg, msgLen, &handle) < 0 || if (ns_initparse(msg.data(), msg.size(), &handle) < 0 || ns_parserr(&handle, ns_s_qd, 0, &rr) < 0) { return false; } Loading Loading @@ -306,8 +305,8 @@ void initDnsEvent(NetworkDnsEventReported* event, const android_net_context& net // Return 0 if the event should not be logged. // Otherwise, return subsampling_denom uint32_t getDnsEventSubsamplingRate(int netid, int returnCode) { uint32_t subsampling_denom = resolv_cache_get_subsampling_denom(netid, returnCode); uint32_t getDnsEventSubsamplingRate(int netid, int returnCode, bool isMdns) { uint32_t subsampling_denom = resolv_cache_get_subsampling_denom(netid, returnCode, isMdns); if (subsampling_denom == 0) return 0; // Sample the event with a chance of 1 / denom. return (arc4random_uniform(subsampling_denom) == 0) ? subsampling_denom : 0; Loading @@ -334,7 +333,12 @@ void maybeLogQuery(int eventType, const android_net_context& netContext, void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs, int returnCode, NetworkDnsEventReported& event, const std::string& query_name, const std::vector<std::string>& ip_addrs = {}, int total_ip_addr_count = 0) { if (uint32_t rate = getDnsEventSubsamplingRate(netContext.dns_netid, returnCode)) { uint32_t rate = (query_name.ends_with(".local") && android::net::Experiments::getInstance()->getFlag("mdns_resolution", 1)) ? getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, true) : getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, false); if (rate) { const std::string& dnsQueryStats = event.dns_query_events().SerializeAsString(); stats::BytesField dnsQueryBytesField{dnsQueryStats.c_str(), dnsQueryStats.size()}; event.set_return_code(static_cast<ReturnCode>(returnCode)); Loading Loading @@ -560,7 +564,7 @@ bool getDns64Prefix(unsigned netId, netdutils::IPPrefix* prefix) { std::string makeThreadName(unsigned netId, uint32_t uid) { // The maximum of netId and app_id are 5-digit numbers. return android::base::StringPrintf("Dns_%u_%u", netId, multiuser_get_app_id(uid)); return fmt::format("Dns_{}_{}", netId, multiuser_get_app_id(uid)); } } // namespace Loading Loading @@ -922,8 +926,8 @@ void DnsProxyListener::ResNSendHandler::run() { uint16_t original_query_id = 0; // TODO: Handle the case which is msg contains more than one query if (!parseQuery(msg.data(), msgLen, &original_query_id, &rr_type, &rr_name) || !setQueryId(msg.data(), msgLen, arc4random_uniform(65536))) { if (!parseQuery({msg.data(), msgLen}, &original_query_id, &rr_type, &rr_name) || !setQueryId({msg.data(), msgLen}, arc4random_uniform(65536))) { // If the query couldn't be parsed, block the request. LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid << ", invalid query"; sendBE32(mClient, -EINVAL); Loading @@ -933,21 +937,21 @@ void DnsProxyListener::ResNSendHandler::run() { // Send DNS query std::vector<uint8_t> ansBuf(MAXPACKET, 0); int rcode = ns_r_noerror; int nsendAns = -1; int ansLen = -1; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); if (queryLimiter.start(uid)) { if (evaluate_domain_name(mNetContext, rr_name.c_str())) { nsendAns = resolv_res_nsend(&mNetContext, msg.data(), msgLen, ansBuf.data(), MAXPACKET, &rcode, static_cast<ResNsendFlags>(mFlags), &event); ansLen = resolv_res_nsend(&mNetContext, {msg.data(), msgLen}, ansBuf, &rcode, static_cast<ResNsendFlags>(mFlags), &event); } else { nsendAns = -EAI_SYSTEM; ansLen = -EAI_SYSTEM; } queryLimiter.finish(uid); } else { LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid << ", max concurrent queries reached"; nsendAns = -EBUSY; ansLen = -EBUSY; } const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs()); Loading @@ -956,14 +960,14 @@ void DnsProxyListener::ResNSendHandler::run() { event.set_res_nsend_flags(static_cast<ResNsendFlags>(mFlags)); // Fail, send -errno if (nsendAns < 0) { if (!sendBE32(mClient, nsendAns)) { if (ansLen < 0) { if (!sendBE32(mClient, ansLen)) { PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send errno to uid " << uid << " pid " << mClient->getPid(); } if (rr_type == ns_t_a || rr_type == ns_t_aaaa) { reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, resNSendToAiError(nsendAns, rcode), event, rr_name); resNSendToAiError(ansLen, rcode), event, rr_name); } return; } Loading @@ -976,8 +980,8 @@ void DnsProxyListener::ResNSendHandler::run() { } // Restore query id and send answer if (!setQueryId(ansBuf.data(), nsendAns, original_query_id) || !sendLenAndData(mClient, nsendAns, ansBuf.data())) { if (!setQueryId({ansBuf.data(), ansLen}, original_query_id) || !sendLenAndData(mClient, ansLen, ansBuf.data())) { PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send answer to uid " << uid << " pid " << mClient->getPid(); return; Loading @@ -986,9 +990,9 @@ void DnsProxyListener::ResNSendHandler::run() { if (rr_type == ns_t_a || rr_type == ns_t_aaaa) { std::vector<std::string> ip_addrs; const int total_ip_addr_count = extractResNsendAnswers((uint8_t*)ansBuf.data(), nsendAns, rr_type, &ip_addrs); extractResNsendAnswers({ansBuf.data(), ansLen}, rr_type, &ip_addrs); reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, resNSendToAiError(nsendAns, rcode), event, rr_name, ip_addrs, resNSendToAiError(ansLen, rcode), event, rr_name, ip_addrs, total_ip_addr_count); } } Loading
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
DnsResolverService.cpp +12 −5 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ #include <vector> #include <BinderUtil.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <android/binder_manager.h> #include <android/binder_process.h> Loading @@ -36,9 +35,9 @@ #include "ResolverEventReporter.h" #include "resolv_cache.h" using aidl::android::net::ResolverOptionsParcel; using aidl::android::net::ResolverParamsParcel; using android::base::Join; using android::base::StringPrintf; using android::netdutils::DumpWriter; using android::netdutils::IPPrefix; Loading Loading @@ -181,8 +180,8 @@ binder_status_t DnsResolverService::dump(int fd, const char** args, uint32_t num } } auto err = StringPrintf("UID %d / PID %d does not have any of the following permissions: %s", uid, pid, Join(permissions, ',').c_str()); auto err = fmt::format("UID {} / PID {} does not have any of the following permissions: {}", uid, pid, Join(permissions, ',')); return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(EX_SECURITY, err.c_str())); } Loading @@ -196,7 +195,7 @@ binder_status_t DnsResolverService::dump(int fd, const char** args, uint32_t num uid_t uid = AIBinder_getCallingUid(); // CAUTION: caCertificate should NOT be used except for internal testing. if (resolverParams.caCertificate.size() != 0 && uid != AID_ROOT) { auto err = StringPrintf("UID %d is not authorized to set a non-empty CA certificate", uid); auto err = fmt::format("UID {} is not authorized to set a non-empty CA certificate", uid); return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(EX_SECURITY, err.c_str())); } Loading Loading @@ -307,5 +306,13 @@ binder_status_t DnsResolverService::dump(int fd, const char** args, uint32_t num return statusFromErrcode(res); } ::ndk::ScopedAStatus DnsResolverService::setResolverOptions(int32_t netId, const ResolverOptionsParcel& options) { // Locking happens in res_cache.cpp functions. ENFORCE_NETWORK_STACK_PERMISSIONS(); return statusFromErrcode(resolv_set_options(netId, options)); } } // namespace net } // namespace android