Loading Android.bp +60 −16 Original line number Original line Diff line number Diff line Loading @@ -53,7 +53,7 @@ cc_library_headers { ], ], } } dnsresolver_aidl_interface_lateststable_version = "V11" dnsresolver_aidl_interface_lateststable_version = "V12" cc_library_static { cc_library_static { name: "dnsresolver_aidl_interface-lateststable-ndk", name: "dnsresolver_aidl_interface-lateststable-ndk", Loading Loading @@ -96,22 +96,63 @@ aidl_interface { min_sdk_version: "30", min_sdk_version: "30", }, }, }, }, versions: [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", ], dumpapi: { dumpapi: { no_license: true, no_license: true, }, }, versions_with_info: [ { version: "1", imports: ["netd_event_listener_interface-V1"], }, { version: "2", imports: ["netd_event_listener_interface-V1"], }, { version: "3", imports: ["netd_event_listener_interface-V1"], }, { version: "4", imports: ["netd_event_listener_interface-V1"], }, { version: "5", imports: ["netd_event_listener_interface-V1"], }, { version: "6", imports: ["netd_event_listener_interface-V1"], }, { version: "7", imports: ["netd_event_listener_interface-V1"], }, { version: "8", imports: ["netd_event_listener_interface-V1"], }, { version: "9", imports: ["netd_event_listener_interface-V1"], }, { version: "10", imports: ["netd_event_listener_interface-V1"], }, { version: "11", imports: ["netd_event_listener_interface-V1"], }, { version: "12", imports: ["netd_event_listener_interface-V1"], }, ], frozen: true, } } cc_defaults { cc_defaults { Loading Loading @@ -154,7 +195,7 @@ cc_defaults { // after the build process. // after the build process. host_required: [ host_required: [ "net-tests-utils-host-common", "net-tests-utils-host-common", ] ], } } cc_defaults { cc_defaults { Loading @@ -176,7 +217,7 @@ cc_defaults { // after the build process. // after the build process. host_required: [ host_required: [ "net-tests-utils-host-common", "net-tests-utils-host-common", ] ], } } cc_library { cc_library { Loading Loading @@ -251,6 +292,9 @@ cc_library { "libssl", "libssl", "libstatssocket", "libstatssocket", ], ], runtime_libs: [ "libcom.android.tethering.dns_helper", ], header_libs: [ header_libs: [ "libnetdbinder_utils_headers", "libnetdbinder_utils_headers", ], ], Loading DnsProxyListener.cpp +84 −14 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <arpa/inet.h> #include <arpa/inet.h> #include <dirent.h> #include <dirent.h> #include <dlfcn.h> #include <linux/if.h> #include <linux/if.h> #include <math.h> #include <math.h> #include <net/if.h> #include <net/if.h> Loading Loading @@ -321,9 +322,11 @@ void maybeLogQuery(int eventType, const android_net_context& netContext, void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs, void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs, int returnCode, NetworkDnsEventReported& event, const std::string& query_name, int returnCode, NetworkDnsEventReported& event, const std::string& query_name, const std::vector<std::string>& ip_addrs = {}, int total_ip_addr_count = 0) { bool skipStats, const std::vector<std::string>& ip_addrs = {}, uint32_t rate = int total_ip_addr_count = 0) { (query_name.ends_with(".local") && is_mdns_supported_network(netContext.dns_netid) && int32_t rate = skipStats ? 0 : (query_name.ends_with(".local") && is_mdns_supported_network(netContext.dns_netid) && android::net::Experiments::getInstance()->getFlag("mdns_resolution", 1)) android::net::Experiments::getInstance()->getFlag("mdns_resolution", 1)) ? getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, true) ? getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, true) : getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, false); : getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, false); Loading Loading @@ -661,6 +664,53 @@ std::string makeThreadName(unsigned netId, uint32_t uid) { return fmt::format("Dns_{}_{}", netId, multiuser_get_app_id(uid)); return fmt::format("Dns_{}_{}", netId, multiuser_get_app_id(uid)); } } typedef int (*InitFn)(); typedef int (*IsUidBlockedFn)(uid_t, bool); IsUidBlockedFn ADnsHelper_isUidNetworkingBlocked; IsUidBlockedFn resolveIsUidNetworkingBlockedFn() { // Related BPF maps were mainlined from T. if (!isAtLeastT()) return nullptr; // TODO: Check whether it is safe to shared link the .so without using dlopen when the carrier // APEX module (tethering) is fully released. void* handle = dlopen("libcom.android.tethering.dns_helper.so", RTLD_NOW | RTLD_LOCAL); if (!handle) { LOG(WARNING) << __func__ << ": " << dlerror(); return nullptr; } InitFn ADnsHelper_init = reinterpret_cast<InitFn>(dlsym(handle, "ADnsHelper_init")); if (!ADnsHelper_init) { LOG(ERROR) << __func__ << ": " << dlerror(); abort(); } const int ret = (*ADnsHelper_init)(); if (ret) { LOG(ERROR) << __func__ << ": ADnsHelper_init failed " << strerror(-ret); abort(); } IsUidBlockedFn f = reinterpret_cast<IsUidBlockedFn>(dlsym(handle, "ADnsHelper_isUidNetworkingBlocked")); if (!f) { LOG(ERROR) << __func__ << ": " << dlerror(); abort(); } return f; } bool isUidNetworkingBlocked(uid_t uid, unsigned netId) { if (!ADnsHelper_isUidNetworkingBlocked) return false; // The enforceDnsUid is an OEM feature that sets DNS packet with AID_DNS instead of the // application's UID. Its DNS packets are not subject to certain network restriction features. if (resolv_is_enforceDnsUid_enabled_network(netId)) return false; return (*ADnsHelper_isUidNetworkingBlocked)(uid, resolv_is_metered_network(netId)) == 1; } } // namespace } // namespace DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) { DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) { Loading @@ -678,6 +728,8 @@ DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) { mGetDnsNetIdCommand = std::make_unique<GetDnsNetIdCommand>(); mGetDnsNetIdCommand = std::make_unique<GetDnsNetIdCommand>(); registerCmd(mGetDnsNetIdCommand.get()); registerCmd(mGetDnsNetIdCommand.get()); ADnsHelper_isUidNetworkingBlocked = resolveIsUidNetworkingBlockedFn(); } } void DnsProxyListener::Handler::spawn() { void DnsProxyListener::Handler::spawn() { Loading Loading @@ -853,7 +905,11 @@ void DnsProxyListener::GetAddrInfoHandler::run() { int32_t rv = 0; int32_t rv = 0; NetworkDnsEventReported event; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); initDnsEvent(&event, mNetContext); if (startQueryLimiter(uid)) { const bool isUidBlocked = isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid); if (isUidBlocked) { LOG(INFO) << "GetAddrInfoHandler::run: network access blocked"; rv = EAI_FAIL; } else if (startQueryLimiter(uid)) { const char* host = mHost.starts_with('^') ? nullptr : mHost.c_str(); const char* host = mHost.starts_with('^') ? nullptr : mHost.c_str(); const char* service = mService.starts_with('^') ? nullptr : mService.c_str(); const char* service = mService.starts_with('^') ? nullptr : mService.c_str(); if (evaluate_domain_name(mNetContext, host)) { if (evaluate_domain_name(mNetContext, host)) { Loading Loading @@ -898,7 +954,7 @@ void DnsProxyListener::GetAddrInfoHandler::run() { std::vector<std::string> ip_addrs; std::vector<std::string> ip_addrs; const int total_ip_addr_count = extractGetAddrInfoAnswers(result, &ip_addrs); const int total_ip_addr_count = extractGetAddrInfoAnswers(result, &ip_addrs); reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, event, mHost, reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, event, mHost, ip_addrs, total_ip_addr_count); isUidBlocked, ip_addrs, total_ip_addr_count); freeaddrinfo(result); freeaddrinfo(result); } } Loading Loading @@ -1062,11 +1118,16 @@ void DnsProxyListener::ResNSendHandler::run() { int ansLen = -1; int ansLen = -1; NetworkDnsEventReported event; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); initDnsEvent(&event, mNetContext); if (startQueryLimiter(uid)) { const bool isUidBlocked = isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid); if (isUidBlocked) { LOG(INFO) << "ResNSendHandler::run: network access blocked"; ansLen = -ECONNREFUSED; } else if (startQueryLimiter(uid)) { if (evaluate_domain_name(mNetContext, rr_name.c_str())) { if (evaluate_domain_name(mNetContext, rr_name.c_str())) { ansLen = resolv_res_nsend(&mNetContext, std::span(msg.data(), msgLen), ansBuf, &rcode, ansLen = resolv_res_nsend(&mNetContext, std::span(msg.data(), msgLen), ansBuf, &rcode, static_cast<ResNsendFlags>(mFlags), &event); static_cast<ResNsendFlags>(mFlags), &event); } else { } else { // TODO(b/307048182): It should return -errno. ansLen = -EAI_SYSTEM; ansLen = -EAI_SYSTEM; } } endQueryLimiter(uid); endQueryLimiter(uid); Loading @@ -1089,7 +1150,7 @@ void DnsProxyListener::ResNSendHandler::run() { } } if (rr_type == ns_t_a || rr_type == ns_t_aaaa) { if (rr_type == ns_t_a || rr_type == ns_t_aaaa) { reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, resNSendToAiError(ansLen, rcode), event, rr_name); resNSendToAiError(ansLen, rcode), event, rr_name, isUidBlocked); } } return; return; } } Loading Loading @@ -1119,8 +1180,8 @@ void DnsProxyListener::ResNSendHandler::run() { const int total_ip_addr_count = const int total_ip_addr_count = extractResNsendAnswers(std::span(ansBuf.data(), ansLen), rr_type, &ip_addrs); extractResNsendAnswers(std::span(ansBuf.data(), ansLen), rr_type, &ip_addrs); reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, resNSendToAiError(ansLen, rcode), event, rr_name, ip_addrs, resNSendToAiError(ansLen, rcode), event, rr_name, /*skipStats=*/false, total_ip_addr_count); ip_addrs, total_ip_addr_count); } } } } Loading Loading @@ -1262,7 +1323,11 @@ void DnsProxyListener::GetHostByNameHandler::run() { int32_t rv = 0; int32_t rv = 0; NetworkDnsEventReported event; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); initDnsEvent(&event, mNetContext); if (startQueryLimiter(uid)) { const bool isUidBlocked = isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid); if (isUidBlocked) { LOG(INFO) << "GetHostByNameHandler::run: network access blocked"; rv = EAI_FAIL; } else if (startQueryLimiter(uid)) { const char* name = mName.starts_with('^') ? nullptr : mName.c_str(); const char* name = mName.starts_with('^') ? nullptr : mName.c_str(); if (evaluate_domain_name(mNetContext, name)) { if (evaluate_domain_name(mNetContext, name)) { rv = resolv_gethostbyname(name, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp, rv = resolv_gethostbyname(name, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp, Loading Loading @@ -1303,7 +1368,7 @@ void DnsProxyListener::GetHostByNameHandler::run() { std::vector<std::string> ip_addrs; std::vector<std::string> ip_addrs; const int total_ip_addr_count = extractGetHostByNameAnswers(hp, &ip_addrs); const int total_ip_addr_count = extractGetHostByNameAnswers(hp, &ip_addrs); reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, event, reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, event, mName, ip_addrs, total_ip_addr_count); mName, isUidBlocked, ip_addrs, total_ip_addr_count); } } std::string DnsProxyListener::GetHostByNameHandler::threadName() { std::string DnsProxyListener::GetHostByNameHandler::threadName() { Loading Loading @@ -1421,7 +1486,12 @@ void DnsProxyListener::GetHostByAddrHandler::run() { int32_t rv = 0; int32_t rv = 0; NetworkDnsEventReported event; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); initDnsEvent(&event, mNetContext); if (startQueryLimiter(uid)) { const bool isUidBlocked = isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid); if (isUidBlocked) { LOG(INFO) << "GetHostByAddrHandler::run: network access blocked"; rv = EAI_FAIL; } else if (startQueryLimiter(uid)) { // From Android U, evaluate_domain_name() is not only for OEM customization, but also tells // From Android U, evaluate_domain_name() is not only for OEM customization, but also tells // DNS resolver whether the UID can send DNS on the specified network. The function needs // DNS resolver whether the UID can send DNS on the specified network. The function needs // to be called even when there is no domain name to evaluate (GetHostByAddr). This is // to be called even when there is no domain name to evaluate (GetHostByAddr). This is Loading Loading @@ -1464,7 +1534,7 @@ void DnsProxyListener::GetHostByAddrHandler::run() { } } reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, event, reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, event, (hp && hp->h_name) ? hp->h_name : "null", {}, 0); (hp && hp->h_name) ? hp->h_name : "null", isUidBlocked, {}, 0); } } std::string DnsProxyListener::GetHostByAddrHandler::threadName() { std::string DnsProxyListener::GetHostByAddrHandler::threadName() { Loading ResolverController.cpp +2 −1 Original line number Original line Diff line number Diff line Loading @@ -237,7 +237,8 @@ int ResolverController::setResolverConfiguration(const ResolverParamsParcel& res return resolv_set_nameservers(resolverParams.netId, resolverParams.servers, return resolv_set_nameservers(resolverParams.netId, resolverParams.servers, resolverParams.domains, res_params, resolverParams.domains, res_params, resolverParams.resolverOptions, resolverParams.transportTypes); resolverParams.resolverOptions, resolverParams.transportTypes, resolverParams.meteredNetwork); } } int ResolverController::getResolverInfo(int32_t netId, std::vector<std::string>* servers, int ResolverController::getResolverInfo(int32_t netId, std::vector<std::string>* servers, Loading aidl_api/dnsresolver_aidl_interface/12/.hash 0 → 100644 +1 −0 Original line number Original line Diff line number Diff line a65a6755e2e5f5c160e7be2be814019e2d5491b1 aidl_api/dnsresolver_aidl_interface/12/android/net/IDnsResolver.aidl 0 → 100644 +69 −0 Original line number Original line Diff line number Diff line /////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// // This file is a snapshot of an AIDL file. Do not edit it manually. There are // two cases: // 1). this is a frozen version file - do not edit this in any case. // 2). this is a 'current' file. If you make a backwards compatible change to // the interface (from the latest frozen version), the build system will // prompt you to update this file with `m <name>-update-api`. // // You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped // with such a backward incompatible change, it has a high risk of breaking // later when a module using the interface is updated, e.g., Mainline modules. package android.net; /* @hide */ interface IDnsResolver { boolean isAlive(); void registerEventListener(android.net.metrics.INetdEventListener listener); void setResolverConfiguration(in android.net.ResolverParamsParcel resolverParams); void getResolverInfo(int netId, out @utf8InCpp String[] servers, out @utf8InCpp String[] domains, out @utf8InCpp String[] tlsServers, out int[] params, out int[] stats, out int[] wait_for_pending_req_timeout_count); void startPrefix64Discovery(int netId); void stopPrefix64Discovery(int netId); @utf8InCpp String getPrefix64(int netId); void createNetworkCache(int netId); void destroyNetworkCache(int netId); void setLogSeverity(int logSeverity); void flushNetworkCache(int netId); void setPrefix64(int netId, @utf8InCpp String prefix); void registerUnsolicitedEventListener(android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener listener); void setResolverOptions(int netId, in android.net.ResolverOptionsParcel optionParams); const int RESOLVER_PARAMS_SAMPLE_VALIDITY = 0; const int RESOLVER_PARAMS_SUCCESS_THRESHOLD = 1; const int RESOLVER_PARAMS_MIN_SAMPLES = 2; const int RESOLVER_PARAMS_MAX_SAMPLES = 3; const int RESOLVER_PARAMS_BASE_TIMEOUT_MSEC = 4; const int RESOLVER_PARAMS_RETRY_COUNT = 5; const int RESOLVER_PARAMS_COUNT = 6; const int RESOLVER_STATS_SUCCESSES = 0; const int RESOLVER_STATS_ERRORS = 1; const int RESOLVER_STATS_TIMEOUTS = 2; const int RESOLVER_STATS_INTERNAL_ERRORS = 3; const int RESOLVER_STATS_RTT_AVG = 4; const int RESOLVER_STATS_LAST_SAMPLE_TIME = 5; const int RESOLVER_STATS_USABLE = 6; const int RESOLVER_STATS_COUNT = 7; const int DNS_RESOLVER_LOG_VERBOSE = 0; const int DNS_RESOLVER_LOG_DEBUG = 1; const int DNS_RESOLVER_LOG_INFO = 2; const int DNS_RESOLVER_LOG_WARNING = 3; const int DNS_RESOLVER_LOG_ERROR = 4; const int TC_MODE_DEFAULT = 0; const int TC_MODE_UDP_TCP = 1; const int TRANSPORT_UNKNOWN = (-1) /* -1 */; const int TRANSPORT_CELLULAR = 0; const int TRANSPORT_WIFI = 1; const int TRANSPORT_BLUETOOTH = 2; const int TRANSPORT_ETHERNET = 3; const int TRANSPORT_VPN = 4; const int TRANSPORT_WIFI_AWARE = 5; const int TRANSPORT_LOWPAN = 6; const int TRANSPORT_TEST = 7; const int TRANSPORT_USB = 8; const int TRANSPORT_THREAD = 9; } Loading
Android.bp +60 −16 Original line number Original line Diff line number Diff line Loading @@ -53,7 +53,7 @@ cc_library_headers { ], ], } } dnsresolver_aidl_interface_lateststable_version = "V11" dnsresolver_aidl_interface_lateststable_version = "V12" cc_library_static { cc_library_static { name: "dnsresolver_aidl_interface-lateststable-ndk", name: "dnsresolver_aidl_interface-lateststable-ndk", Loading Loading @@ -96,22 +96,63 @@ aidl_interface { min_sdk_version: "30", min_sdk_version: "30", }, }, }, }, versions: [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", ], dumpapi: { dumpapi: { no_license: true, no_license: true, }, }, versions_with_info: [ { version: "1", imports: ["netd_event_listener_interface-V1"], }, { version: "2", imports: ["netd_event_listener_interface-V1"], }, { version: "3", imports: ["netd_event_listener_interface-V1"], }, { version: "4", imports: ["netd_event_listener_interface-V1"], }, { version: "5", imports: ["netd_event_listener_interface-V1"], }, { version: "6", imports: ["netd_event_listener_interface-V1"], }, { version: "7", imports: ["netd_event_listener_interface-V1"], }, { version: "8", imports: ["netd_event_listener_interface-V1"], }, { version: "9", imports: ["netd_event_listener_interface-V1"], }, { version: "10", imports: ["netd_event_listener_interface-V1"], }, { version: "11", imports: ["netd_event_listener_interface-V1"], }, { version: "12", imports: ["netd_event_listener_interface-V1"], }, ], frozen: true, } } cc_defaults { cc_defaults { Loading Loading @@ -154,7 +195,7 @@ cc_defaults { // after the build process. // after the build process. host_required: [ host_required: [ "net-tests-utils-host-common", "net-tests-utils-host-common", ] ], } } cc_defaults { cc_defaults { Loading @@ -176,7 +217,7 @@ cc_defaults { // after the build process. // after the build process. host_required: [ host_required: [ "net-tests-utils-host-common", "net-tests-utils-host-common", ] ], } } cc_library { cc_library { Loading Loading @@ -251,6 +292,9 @@ cc_library { "libssl", "libssl", "libstatssocket", "libstatssocket", ], ], runtime_libs: [ "libcom.android.tethering.dns_helper", ], header_libs: [ header_libs: [ "libnetdbinder_utils_headers", "libnetdbinder_utils_headers", ], ], Loading
DnsProxyListener.cpp +84 −14 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <arpa/inet.h> #include <arpa/inet.h> #include <dirent.h> #include <dirent.h> #include <dlfcn.h> #include <linux/if.h> #include <linux/if.h> #include <math.h> #include <math.h> #include <net/if.h> #include <net/if.h> Loading Loading @@ -321,9 +322,11 @@ void maybeLogQuery(int eventType, const android_net_context& netContext, void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs, void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs, int returnCode, NetworkDnsEventReported& event, const std::string& query_name, int returnCode, NetworkDnsEventReported& event, const std::string& query_name, const std::vector<std::string>& ip_addrs = {}, int total_ip_addr_count = 0) { bool skipStats, const std::vector<std::string>& ip_addrs = {}, uint32_t rate = int total_ip_addr_count = 0) { (query_name.ends_with(".local") && is_mdns_supported_network(netContext.dns_netid) && int32_t rate = skipStats ? 0 : (query_name.ends_with(".local") && is_mdns_supported_network(netContext.dns_netid) && android::net::Experiments::getInstance()->getFlag("mdns_resolution", 1)) android::net::Experiments::getInstance()->getFlag("mdns_resolution", 1)) ? getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, true) ? getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, true) : getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, false); : getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, false); Loading Loading @@ -661,6 +664,53 @@ std::string makeThreadName(unsigned netId, uint32_t uid) { return fmt::format("Dns_{}_{}", netId, multiuser_get_app_id(uid)); return fmt::format("Dns_{}_{}", netId, multiuser_get_app_id(uid)); } } typedef int (*InitFn)(); typedef int (*IsUidBlockedFn)(uid_t, bool); IsUidBlockedFn ADnsHelper_isUidNetworkingBlocked; IsUidBlockedFn resolveIsUidNetworkingBlockedFn() { // Related BPF maps were mainlined from T. if (!isAtLeastT()) return nullptr; // TODO: Check whether it is safe to shared link the .so without using dlopen when the carrier // APEX module (tethering) is fully released. void* handle = dlopen("libcom.android.tethering.dns_helper.so", RTLD_NOW | RTLD_LOCAL); if (!handle) { LOG(WARNING) << __func__ << ": " << dlerror(); return nullptr; } InitFn ADnsHelper_init = reinterpret_cast<InitFn>(dlsym(handle, "ADnsHelper_init")); if (!ADnsHelper_init) { LOG(ERROR) << __func__ << ": " << dlerror(); abort(); } const int ret = (*ADnsHelper_init)(); if (ret) { LOG(ERROR) << __func__ << ": ADnsHelper_init failed " << strerror(-ret); abort(); } IsUidBlockedFn f = reinterpret_cast<IsUidBlockedFn>(dlsym(handle, "ADnsHelper_isUidNetworkingBlocked")); if (!f) { LOG(ERROR) << __func__ << ": " << dlerror(); abort(); } return f; } bool isUidNetworkingBlocked(uid_t uid, unsigned netId) { if (!ADnsHelper_isUidNetworkingBlocked) return false; // The enforceDnsUid is an OEM feature that sets DNS packet with AID_DNS instead of the // application's UID. Its DNS packets are not subject to certain network restriction features. if (resolv_is_enforceDnsUid_enabled_network(netId)) return false; return (*ADnsHelper_isUidNetworkingBlocked)(uid, resolv_is_metered_network(netId)) == 1; } } // namespace } // namespace DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) { DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) { Loading @@ -678,6 +728,8 @@ DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) { mGetDnsNetIdCommand = std::make_unique<GetDnsNetIdCommand>(); mGetDnsNetIdCommand = std::make_unique<GetDnsNetIdCommand>(); registerCmd(mGetDnsNetIdCommand.get()); registerCmd(mGetDnsNetIdCommand.get()); ADnsHelper_isUidNetworkingBlocked = resolveIsUidNetworkingBlockedFn(); } } void DnsProxyListener::Handler::spawn() { void DnsProxyListener::Handler::spawn() { Loading Loading @@ -853,7 +905,11 @@ void DnsProxyListener::GetAddrInfoHandler::run() { int32_t rv = 0; int32_t rv = 0; NetworkDnsEventReported event; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); initDnsEvent(&event, mNetContext); if (startQueryLimiter(uid)) { const bool isUidBlocked = isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid); if (isUidBlocked) { LOG(INFO) << "GetAddrInfoHandler::run: network access blocked"; rv = EAI_FAIL; } else if (startQueryLimiter(uid)) { const char* host = mHost.starts_with('^') ? nullptr : mHost.c_str(); const char* host = mHost.starts_with('^') ? nullptr : mHost.c_str(); const char* service = mService.starts_with('^') ? nullptr : mService.c_str(); const char* service = mService.starts_with('^') ? nullptr : mService.c_str(); if (evaluate_domain_name(mNetContext, host)) { if (evaluate_domain_name(mNetContext, host)) { Loading Loading @@ -898,7 +954,7 @@ void DnsProxyListener::GetAddrInfoHandler::run() { std::vector<std::string> ip_addrs; std::vector<std::string> ip_addrs; const int total_ip_addr_count = extractGetAddrInfoAnswers(result, &ip_addrs); const int total_ip_addr_count = extractGetAddrInfoAnswers(result, &ip_addrs); reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, event, mHost, reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, event, mHost, ip_addrs, total_ip_addr_count); isUidBlocked, ip_addrs, total_ip_addr_count); freeaddrinfo(result); freeaddrinfo(result); } } Loading Loading @@ -1062,11 +1118,16 @@ void DnsProxyListener::ResNSendHandler::run() { int ansLen = -1; int ansLen = -1; NetworkDnsEventReported event; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); initDnsEvent(&event, mNetContext); if (startQueryLimiter(uid)) { const bool isUidBlocked = isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid); if (isUidBlocked) { LOG(INFO) << "ResNSendHandler::run: network access blocked"; ansLen = -ECONNREFUSED; } else if (startQueryLimiter(uid)) { if (evaluate_domain_name(mNetContext, rr_name.c_str())) { if (evaluate_domain_name(mNetContext, rr_name.c_str())) { ansLen = resolv_res_nsend(&mNetContext, std::span(msg.data(), msgLen), ansBuf, &rcode, ansLen = resolv_res_nsend(&mNetContext, std::span(msg.data(), msgLen), ansBuf, &rcode, static_cast<ResNsendFlags>(mFlags), &event); static_cast<ResNsendFlags>(mFlags), &event); } else { } else { // TODO(b/307048182): It should return -errno. ansLen = -EAI_SYSTEM; ansLen = -EAI_SYSTEM; } } endQueryLimiter(uid); endQueryLimiter(uid); Loading @@ -1089,7 +1150,7 @@ void DnsProxyListener::ResNSendHandler::run() { } } if (rr_type == ns_t_a || rr_type == ns_t_aaaa) { if (rr_type == ns_t_a || rr_type == ns_t_aaaa) { reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, resNSendToAiError(ansLen, rcode), event, rr_name); resNSendToAiError(ansLen, rcode), event, rr_name, isUidBlocked); } } return; return; } } Loading Loading @@ -1119,8 +1180,8 @@ void DnsProxyListener::ResNSendHandler::run() { const int total_ip_addr_count = const int total_ip_addr_count = extractResNsendAnswers(std::span(ansBuf.data(), ansLen), rr_type, &ip_addrs); extractResNsendAnswers(std::span(ansBuf.data(), ansLen), rr_type, &ip_addrs); reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, resNSendToAiError(ansLen, rcode), event, rr_name, ip_addrs, resNSendToAiError(ansLen, rcode), event, rr_name, /*skipStats=*/false, total_ip_addr_count); ip_addrs, total_ip_addr_count); } } } } Loading Loading @@ -1262,7 +1323,11 @@ void DnsProxyListener::GetHostByNameHandler::run() { int32_t rv = 0; int32_t rv = 0; NetworkDnsEventReported event; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); initDnsEvent(&event, mNetContext); if (startQueryLimiter(uid)) { const bool isUidBlocked = isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid); if (isUidBlocked) { LOG(INFO) << "GetHostByNameHandler::run: network access blocked"; rv = EAI_FAIL; } else if (startQueryLimiter(uid)) { const char* name = mName.starts_with('^') ? nullptr : mName.c_str(); const char* name = mName.starts_with('^') ? nullptr : mName.c_str(); if (evaluate_domain_name(mNetContext, name)) { if (evaluate_domain_name(mNetContext, name)) { rv = resolv_gethostbyname(name, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp, rv = resolv_gethostbyname(name, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp, Loading Loading @@ -1303,7 +1368,7 @@ void DnsProxyListener::GetHostByNameHandler::run() { std::vector<std::string> ip_addrs; std::vector<std::string> ip_addrs; const int total_ip_addr_count = extractGetHostByNameAnswers(hp, &ip_addrs); const int total_ip_addr_count = extractGetHostByNameAnswers(hp, &ip_addrs); reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, event, reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, event, mName, ip_addrs, total_ip_addr_count); mName, isUidBlocked, ip_addrs, total_ip_addr_count); } } std::string DnsProxyListener::GetHostByNameHandler::threadName() { std::string DnsProxyListener::GetHostByNameHandler::threadName() { Loading Loading @@ -1421,7 +1486,12 @@ void DnsProxyListener::GetHostByAddrHandler::run() { int32_t rv = 0; int32_t rv = 0; NetworkDnsEventReported event; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); initDnsEvent(&event, mNetContext); if (startQueryLimiter(uid)) { const bool isUidBlocked = isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid); if (isUidBlocked) { LOG(INFO) << "GetHostByAddrHandler::run: network access blocked"; rv = EAI_FAIL; } else if (startQueryLimiter(uid)) { // From Android U, evaluate_domain_name() is not only for OEM customization, but also tells // From Android U, evaluate_domain_name() is not only for OEM customization, but also tells // DNS resolver whether the UID can send DNS on the specified network. The function needs // DNS resolver whether the UID can send DNS on the specified network. The function needs // to be called even when there is no domain name to evaluate (GetHostByAddr). This is // to be called even when there is no domain name to evaluate (GetHostByAddr). This is Loading Loading @@ -1464,7 +1534,7 @@ void DnsProxyListener::GetHostByAddrHandler::run() { } } reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, event, reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, event, (hp && hp->h_name) ? hp->h_name : "null", {}, 0); (hp && hp->h_name) ? hp->h_name : "null", isUidBlocked, {}, 0); } } std::string DnsProxyListener::GetHostByAddrHandler::threadName() { std::string DnsProxyListener::GetHostByAddrHandler::threadName() { Loading
ResolverController.cpp +2 −1 Original line number Original line Diff line number Diff line Loading @@ -237,7 +237,8 @@ int ResolverController::setResolverConfiguration(const ResolverParamsParcel& res return resolv_set_nameservers(resolverParams.netId, resolverParams.servers, return resolv_set_nameservers(resolverParams.netId, resolverParams.servers, resolverParams.domains, res_params, resolverParams.domains, res_params, resolverParams.resolverOptions, resolverParams.transportTypes); resolverParams.resolverOptions, resolverParams.transportTypes, resolverParams.meteredNetwork); } } int ResolverController::getResolverInfo(int32_t netId, std::vector<std::string>* servers, int ResolverController::getResolverInfo(int32_t netId, std::vector<std::string>* servers, Loading
aidl_api/dnsresolver_aidl_interface/12/.hash 0 → 100644 +1 −0 Original line number Original line Diff line number Diff line a65a6755e2e5f5c160e7be2be814019e2d5491b1
aidl_api/dnsresolver_aidl_interface/12/android/net/IDnsResolver.aidl 0 → 100644 +69 −0 Original line number Original line Diff line number Diff line /////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// // This file is a snapshot of an AIDL file. Do not edit it manually. There are // two cases: // 1). this is a frozen version file - do not edit this in any case. // 2). this is a 'current' file. If you make a backwards compatible change to // the interface (from the latest frozen version), the build system will // prompt you to update this file with `m <name>-update-api`. // // You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped // with such a backward incompatible change, it has a high risk of breaking // later when a module using the interface is updated, e.g., Mainline modules. package android.net; /* @hide */ interface IDnsResolver { boolean isAlive(); void registerEventListener(android.net.metrics.INetdEventListener listener); void setResolverConfiguration(in android.net.ResolverParamsParcel resolverParams); void getResolverInfo(int netId, out @utf8InCpp String[] servers, out @utf8InCpp String[] domains, out @utf8InCpp String[] tlsServers, out int[] params, out int[] stats, out int[] wait_for_pending_req_timeout_count); void startPrefix64Discovery(int netId); void stopPrefix64Discovery(int netId); @utf8InCpp String getPrefix64(int netId); void createNetworkCache(int netId); void destroyNetworkCache(int netId); void setLogSeverity(int logSeverity); void flushNetworkCache(int netId); void setPrefix64(int netId, @utf8InCpp String prefix); void registerUnsolicitedEventListener(android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener listener); void setResolverOptions(int netId, in android.net.ResolverOptionsParcel optionParams); const int RESOLVER_PARAMS_SAMPLE_VALIDITY = 0; const int RESOLVER_PARAMS_SUCCESS_THRESHOLD = 1; const int RESOLVER_PARAMS_MIN_SAMPLES = 2; const int RESOLVER_PARAMS_MAX_SAMPLES = 3; const int RESOLVER_PARAMS_BASE_TIMEOUT_MSEC = 4; const int RESOLVER_PARAMS_RETRY_COUNT = 5; const int RESOLVER_PARAMS_COUNT = 6; const int RESOLVER_STATS_SUCCESSES = 0; const int RESOLVER_STATS_ERRORS = 1; const int RESOLVER_STATS_TIMEOUTS = 2; const int RESOLVER_STATS_INTERNAL_ERRORS = 3; const int RESOLVER_STATS_RTT_AVG = 4; const int RESOLVER_STATS_LAST_SAMPLE_TIME = 5; const int RESOLVER_STATS_USABLE = 6; const int RESOLVER_STATS_COUNT = 7; const int DNS_RESOLVER_LOG_VERBOSE = 0; const int DNS_RESOLVER_LOG_DEBUG = 1; const int DNS_RESOLVER_LOG_INFO = 2; const int DNS_RESOLVER_LOG_WARNING = 3; const int DNS_RESOLVER_LOG_ERROR = 4; const int TC_MODE_DEFAULT = 0; const int TC_MODE_UDP_TCP = 1; const int TRANSPORT_UNKNOWN = (-1) /* -1 */; const int TRANSPORT_CELLULAR = 0; const int TRANSPORT_WIFI = 1; const int TRANSPORT_BLUETOOTH = 2; const int TRANSPORT_ETHERNET = 3; const int TRANSPORT_VPN = 4; const int TRANSPORT_WIFI_AWARE = 5; const int TRANSPORT_LOWPAN = 6; const int TRANSPORT_TEST = 7; const int TRANSPORT_USB = 8; const int TRANSPORT_THREAD = 9; }