Loading Android.bp +59 −15 Original line number Diff line number Diff line Loading @@ -96,22 +96,63 @@ aidl_interface { min_sdk_version: "30", }, }, versions: [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", ], dumpapi: { 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 { Loading Loading @@ -154,7 +195,7 @@ cc_defaults { // after the build process. host_required: [ "net-tests-utils-host-common", ] ], } cc_defaults { Loading @@ -176,7 +217,7 @@ cc_defaults { // after the build process. host_required: [ "net-tests-utils-host-common", ] ], } cc_library { Loading Loading @@ -251,6 +292,9 @@ cc_library { "libssl", "libstatssocket", ], runtime_libs: [ "libcom.android.tethering.dns_helper", ], header_libs: [ "libnetdbinder_utils_headers", ], Loading DnsProxyListener.cpp +103 −58 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <arpa/inet.h> #include <dirent.h> #include <dlfcn.h> #include <linux/if.h> #include <math.h> #include <net/if.h> Loading Loading @@ -661,6 +662,54 @@ std::string makeThreadName(unsigned netId, uint32_t 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; // TODO: Pass metered information from CS to DNS resolver and replace the hardcode value. return (*ADnsHelper_isUidNetworkingBlocked)(uid, /*metered=*/false) == 1; } } // namespace DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) { Loading @@ -678,6 +727,8 @@ DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) { mGetDnsNetIdCommand = std::make_unique<GetDnsNetIdCommand>(); registerCmd(mGetDnsNetIdCommand.get()); ADnsHelper_isUidNetworkingBlocked = resolveIsUidNetworkingBlockedFn(); } void DnsProxyListener::Handler::spawn() { Loading Loading @@ -818,23 +869,16 @@ void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinf if (ipv6WantedButNoData) { // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis const uid_t uid = mClient->getUid(); if (startQueryLimiter(uid)) { const char* host = mHost.starts_with('^') ? nullptr : mHost.c_str(); const char* service = mService.starts_with('^') ? nullptr : mService.c_str(); mHints->ai_family = AF_INET; // Don't need to do freeaddrinfo(res) before starting new DNS lookup because previous // DNS lookup is failed with error EAI_NODATA. *rv = resolv_getaddrinfo(host, service, mHints.get(), &mNetContext, res, event); endQueryLimiter(uid); if (*rv) { *rv = EAI_NODATA; // return original error code return; } } else { LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached"; return; } } if (!synthesizeNat64PrefixWithARecord(prefix, res, unspecWantedButNoIPv6, &mNetContext)) { Loading @@ -860,11 +904,15 @@ void DnsProxyListener::GetAddrInfoHandler::run() { int32_t rv = 0; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); if (startQueryLimiter(uid)) { if (isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid)) { 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* service = mService.starts_with('^') ? nullptr : mService.c_str(); if (evaluate_domain_name(mNetContext, host)) { rv = resolv_getaddrinfo(host, service, mHints.get(), &mNetContext, &result, &event); doDns64Synthesis(&rv, &result, &event); } else { rv = EAI_SYSTEM; } Loading @@ -877,7 +925,6 @@ void DnsProxyListener::GetAddrInfoHandler::run() { << ", max concurrent queries reached"; } doDns64Synthesis(&rv, &result, &event); const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs()); event.set_latency_micros(latencyUs); event.set_event_type(EVENT_GETADDRINFO); Loading Loading @@ -1055,8 +1102,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(std::span(msg.data(), msgLen), &original_query_id, &rr_type, &rr_name) || !setQueryId(std::span(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 @@ -1069,11 +1116,15 @@ void DnsProxyListener::ResNSendHandler::run() { int ansLen = -1; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); if (startQueryLimiter(uid)) { if (isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid)) { LOG(INFO) << "ResNSendHandler::run: network access blocked"; ansLen = -ECONNREFUSED; } else if (startQueryLimiter(uid)) { if (evaluate_domain_name(mNetContext, rr_name.c_str())) { ansLen = resolv_res_nsend(&mNetContext, {msg.data(), msgLen}, ansBuf, &rcode, ansLen = resolv_res_nsend(&mNetContext, std::span(msg.data(), msgLen), ansBuf, &rcode, static_cast<ResNsendFlags>(mFlags), &event); } else { // TODO(b/307048182): It should return -errno. ansLen = -EAI_SYSTEM; } endQueryLimiter(uid); Loading Loading @@ -1109,7 +1160,7 @@ void DnsProxyListener::ResNSendHandler::run() { } // Restore query id if (!setQueryId({ansBuf.data(), ansLen}, original_query_id)) { if (!setQueryId(std::span(ansBuf.data(), ansLen), original_query_id)) { LOG(WARNING) << "ResNSendHandler::run: resnsend: failed to restore query id"; return; } Loading @@ -1124,7 +1175,7 @@ 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({ansBuf.data(), ansLen}, rr_type, &ip_addrs); extractResNsendAnswers(std::span(ansBuf.data(), ansLen), rr_type, &ip_addrs); reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, resNSendToAiError(ansLen, rcode), event, rr_name, ip_addrs, total_ip_addr_count); Loading Loading @@ -1244,19 +1295,12 @@ void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, hoste } // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis const uid_t uid = mClient->getUid(); if (startQueryLimiter(uid)) { const char* name = mName.starts_with('^') ? nullptr : mName.c_str(); *rv = resolv_gethostbyname(name, AF_INET, hbuf, buf, buflen, &mNetContext, hpp, event); endQueryLimiter(uid); if (*rv) { *rv = EAI_NODATA; // return original error code return; } } else { LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached"; return; } if (!synthesizeNat64PrefixWithARecord(prefix, *hpp)) { // If caller wants IPv6 answers but no data and failed to synthesize IPv4 answers, Loading @@ -1276,11 +1320,15 @@ void DnsProxyListener::GetHostByNameHandler::run() { int32_t rv = 0; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); if (startQueryLimiter(uid)) { if (isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid)) { LOG(INFO) << "GetHostByNameHandler::run: network access blocked"; rv = EAI_FAIL; } else if (startQueryLimiter(uid)) { const char* name = mName.starts_with('^') ? nullptr : mName.c_str(); if (evaluate_domain_name(mNetContext, name)) { rv = resolv_gethostbyname(name, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp, &event); doDns64Synthesis(&rv, &hbuf, tmpbuf, sizeof tmpbuf, &hp, &event); } else { rv = EAI_SYSTEM; } Loading @@ -1291,7 +1339,6 @@ void DnsProxyListener::GetHostByNameHandler::run() { << ", max concurrent queries reached"; } doDns64Synthesis(&rv, &hbuf, tmpbuf, sizeof tmpbuf, &hp, &event); const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs()); event.set_latency_micros(latencyUs); event.set_event_type(EVENT_GETHOSTBYNAME); Loading Loading @@ -1406,13 +1453,10 @@ void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(hostent* hbuf, return; } const uid_t uid = mClient->getUid(); if (startQueryLimiter(uid)) { // Remove NAT64 prefix and do reverse DNS query struct in_addr v4addr = {.s_addr = v6addr.s6_addr32[3]}; resolv_gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET, hbuf, buf, buflen, &mNetContext, hpp, event); endQueryLimiter(uid); 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 Loading @@ -1425,9 +1469,6 @@ void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(hostent* hbuf, } else { LOG(ERROR) << __func__ << ": hpp or (*hpp)->h_addr_list[0] is null"; } } else { LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached"; } } void DnsProxyListener::GetHostByAddrHandler::run() { Loading @@ -1441,7 +1482,11 @@ void DnsProxyListener::GetHostByAddrHandler::run() { int32_t rv = 0; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); if (startQueryLimiter(uid)) { if (isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid)) { 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 // 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 Loading @@ -1453,6 +1498,7 @@ void DnsProxyListener::GetHostByAddrHandler::run() { } else { rv = resolv_gethostbyaddr(&mAddress, mAddressLen, mAddressFamily, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp, &event); doDns64ReverseLookup(&hbuf, tmpbuf, sizeof tmpbuf, &hp, &event); } endQueryLimiter(uid); } else { Loading @@ -1461,7 +1507,6 @@ void DnsProxyListener::GetHostByAddrHandler::run() { << ", max concurrent queries reached"; } doDns64ReverseLookup(&hbuf, tmpbuf, sizeof tmpbuf, &hp, &event); const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs()); event.set_latency_micros(latencyUs); event.set_event_type(EVENT_GETHOSTBYADDR); Loading DnsTlsTransport.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -113,7 +113,7 @@ base::Result<void> sendUdpQuery(netdutils::IPAddress ip, uint32_t mark, return ErrnoErrorf("connect failed"); } if (send(fd, query.data(), query.size(), 0) != query.size()) { if (send(fd, query.data(), query.size(), 0) != static_cast<ptrdiff_t>(query.size())) { return ErrnoErrorf("send failed"); } Loading ResolverController.cpp +2 −7 Original line number Diff line number Diff line Loading @@ -37,9 +37,11 @@ #include "stats.h" #include "util.h" using aidl::android::net::IDnsResolver; using aidl::android::net::ResolverParamsParcel; using aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener; using aidl::android::net::resolv::aidl::Nat64PrefixEventParcel; using android::net::ResolverStats; namespace android { Loading Loading @@ -79,8 +81,6 @@ void sendNat64PrefixEvent(const Dns64Configuration::Nat64PrefixInfo& args) { int getDnsInfo(unsigned netId, std::vector<std::string>* servers, std::vector<std::string>* domains, res_params* params, std::vector<android::net::ResolverStats>* stats, int* wait_for_pending_req_timeout_count) { using aidl::android::net::IDnsResolver; using android::net::ResolverStats; static_assert(ResolverStats::STATS_SUCCESSES == IDnsResolver::RESOLVER_STATS_SUCCESSES && ResolverStats::STATS_ERRORS == IDnsResolver::RESOLVER_STATS_ERRORS && ResolverStats::STATS_TIMEOUTS == IDnsResolver::RESOLVER_STATS_TIMEOUTS && Loading Loading @@ -192,8 +192,6 @@ int ResolverController::flushNetworkCache(unsigned netId) { } int ResolverController::setResolverConfiguration(const ResolverParamsParcel& resolverParams) { using aidl::android::net::IDnsResolver; if (!has_named_cache(resolverParams.netId)) { return -ENOENT; } Loading Loading @@ -247,8 +245,6 @@ int ResolverController::getResolverInfo(int32_t netId, std::vector<std::string>* std::vector<std::string>* tlsServers, std::vector<int32_t>* params, std::vector<int32_t>* stats, int* wait_for_pending_req_timeout_count) { using aidl::android::net::IDnsResolver; using android::net::ResolverStats; res_params res_params; std::vector<ResolverStats> res_stats; int ret = getDnsInfo(netId, servers, domains, &res_params, &res_stats, Loading Loading @@ -295,7 +291,6 @@ int ResolverController::getPrefix64(unsigned netId, netdutils::IPPrefix* prefix) void ResolverController::dump(DumpWriter& dw, unsigned netId) { // No lock needed since Bionic's resolver locks all accessed data structures internally. using android::net::ResolverStats; std::vector<std::string> servers; std::vector<std::string> domains; res_params params = {}; Loading aidl_api/dnsresolver_aidl_interface/12/.hash 0 → 100644 +1 −0 Original line number Diff line number Diff line a65a6755e2e5f5c160e7be2be814019e2d5491b1 Loading
Android.bp +59 −15 Original line number Diff line number Diff line Loading @@ -96,22 +96,63 @@ aidl_interface { min_sdk_version: "30", }, }, versions: [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", ], dumpapi: { 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 { Loading Loading @@ -154,7 +195,7 @@ cc_defaults { // after the build process. host_required: [ "net-tests-utils-host-common", ] ], } cc_defaults { Loading @@ -176,7 +217,7 @@ cc_defaults { // after the build process. host_required: [ "net-tests-utils-host-common", ] ], } cc_library { Loading Loading @@ -251,6 +292,9 @@ cc_library { "libssl", "libstatssocket", ], runtime_libs: [ "libcom.android.tethering.dns_helper", ], header_libs: [ "libnetdbinder_utils_headers", ], Loading
DnsProxyListener.cpp +103 −58 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <arpa/inet.h> #include <dirent.h> #include <dlfcn.h> #include <linux/if.h> #include <math.h> #include <net/if.h> Loading Loading @@ -661,6 +662,54 @@ std::string makeThreadName(unsigned netId, uint32_t 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; // TODO: Pass metered information from CS to DNS resolver and replace the hardcode value. return (*ADnsHelper_isUidNetworkingBlocked)(uid, /*metered=*/false) == 1; } } // namespace DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) { Loading @@ -678,6 +727,8 @@ DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) { mGetDnsNetIdCommand = std::make_unique<GetDnsNetIdCommand>(); registerCmd(mGetDnsNetIdCommand.get()); ADnsHelper_isUidNetworkingBlocked = resolveIsUidNetworkingBlockedFn(); } void DnsProxyListener::Handler::spawn() { Loading Loading @@ -818,23 +869,16 @@ void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinf if (ipv6WantedButNoData) { // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis const uid_t uid = mClient->getUid(); if (startQueryLimiter(uid)) { const char* host = mHost.starts_with('^') ? nullptr : mHost.c_str(); const char* service = mService.starts_with('^') ? nullptr : mService.c_str(); mHints->ai_family = AF_INET; // Don't need to do freeaddrinfo(res) before starting new DNS lookup because previous // DNS lookup is failed with error EAI_NODATA. *rv = resolv_getaddrinfo(host, service, mHints.get(), &mNetContext, res, event); endQueryLimiter(uid); if (*rv) { *rv = EAI_NODATA; // return original error code return; } } else { LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached"; return; } } if (!synthesizeNat64PrefixWithARecord(prefix, res, unspecWantedButNoIPv6, &mNetContext)) { Loading @@ -860,11 +904,15 @@ void DnsProxyListener::GetAddrInfoHandler::run() { int32_t rv = 0; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); if (startQueryLimiter(uid)) { if (isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid)) { 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* service = mService.starts_with('^') ? nullptr : mService.c_str(); if (evaluate_domain_name(mNetContext, host)) { rv = resolv_getaddrinfo(host, service, mHints.get(), &mNetContext, &result, &event); doDns64Synthesis(&rv, &result, &event); } else { rv = EAI_SYSTEM; } Loading @@ -877,7 +925,6 @@ void DnsProxyListener::GetAddrInfoHandler::run() { << ", max concurrent queries reached"; } doDns64Synthesis(&rv, &result, &event); const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs()); event.set_latency_micros(latencyUs); event.set_event_type(EVENT_GETADDRINFO); Loading Loading @@ -1055,8 +1102,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(std::span(msg.data(), msgLen), &original_query_id, &rr_type, &rr_name) || !setQueryId(std::span(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 @@ -1069,11 +1116,15 @@ void DnsProxyListener::ResNSendHandler::run() { int ansLen = -1; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); if (startQueryLimiter(uid)) { if (isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid)) { LOG(INFO) << "ResNSendHandler::run: network access blocked"; ansLen = -ECONNREFUSED; } else if (startQueryLimiter(uid)) { if (evaluate_domain_name(mNetContext, rr_name.c_str())) { ansLen = resolv_res_nsend(&mNetContext, {msg.data(), msgLen}, ansBuf, &rcode, ansLen = resolv_res_nsend(&mNetContext, std::span(msg.data(), msgLen), ansBuf, &rcode, static_cast<ResNsendFlags>(mFlags), &event); } else { // TODO(b/307048182): It should return -errno. ansLen = -EAI_SYSTEM; } endQueryLimiter(uid); Loading Loading @@ -1109,7 +1160,7 @@ void DnsProxyListener::ResNSendHandler::run() { } // Restore query id if (!setQueryId({ansBuf.data(), ansLen}, original_query_id)) { if (!setQueryId(std::span(ansBuf.data(), ansLen), original_query_id)) { LOG(WARNING) << "ResNSendHandler::run: resnsend: failed to restore query id"; return; } Loading @@ -1124,7 +1175,7 @@ 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({ansBuf.data(), ansLen}, rr_type, &ip_addrs); extractResNsendAnswers(std::span(ansBuf.data(), ansLen), rr_type, &ip_addrs); reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, resNSendToAiError(ansLen, rcode), event, rr_name, ip_addrs, total_ip_addr_count); Loading Loading @@ -1244,19 +1295,12 @@ void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, hoste } // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis const uid_t uid = mClient->getUid(); if (startQueryLimiter(uid)) { const char* name = mName.starts_with('^') ? nullptr : mName.c_str(); *rv = resolv_gethostbyname(name, AF_INET, hbuf, buf, buflen, &mNetContext, hpp, event); endQueryLimiter(uid); if (*rv) { *rv = EAI_NODATA; // return original error code return; } } else { LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached"; return; } if (!synthesizeNat64PrefixWithARecord(prefix, *hpp)) { // If caller wants IPv6 answers but no data and failed to synthesize IPv4 answers, Loading @@ -1276,11 +1320,15 @@ void DnsProxyListener::GetHostByNameHandler::run() { int32_t rv = 0; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); if (startQueryLimiter(uid)) { if (isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid)) { LOG(INFO) << "GetHostByNameHandler::run: network access blocked"; rv = EAI_FAIL; } else if (startQueryLimiter(uid)) { const char* name = mName.starts_with('^') ? nullptr : mName.c_str(); if (evaluate_domain_name(mNetContext, name)) { rv = resolv_gethostbyname(name, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp, &event); doDns64Synthesis(&rv, &hbuf, tmpbuf, sizeof tmpbuf, &hp, &event); } else { rv = EAI_SYSTEM; } Loading @@ -1291,7 +1339,6 @@ void DnsProxyListener::GetHostByNameHandler::run() { << ", max concurrent queries reached"; } doDns64Synthesis(&rv, &hbuf, tmpbuf, sizeof tmpbuf, &hp, &event); const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs()); event.set_latency_micros(latencyUs); event.set_event_type(EVENT_GETHOSTBYNAME); Loading Loading @@ -1406,13 +1453,10 @@ void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(hostent* hbuf, return; } const uid_t uid = mClient->getUid(); if (startQueryLimiter(uid)) { // Remove NAT64 prefix and do reverse DNS query struct in_addr v4addr = {.s_addr = v6addr.s6_addr32[3]}; resolv_gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET, hbuf, buf, buflen, &mNetContext, hpp, event); endQueryLimiter(uid); 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 Loading @@ -1425,9 +1469,6 @@ void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(hostent* hbuf, } else { LOG(ERROR) << __func__ << ": hpp or (*hpp)->h_addr_list[0] is null"; } } else { LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached"; } } void DnsProxyListener::GetHostByAddrHandler::run() { Loading @@ -1441,7 +1482,11 @@ void DnsProxyListener::GetHostByAddrHandler::run() { int32_t rv = 0; NetworkDnsEventReported event; initDnsEvent(&event, mNetContext); if (startQueryLimiter(uid)) { if (isUidNetworkingBlocked(mNetContext.uid, mNetContext.dns_netid)) { 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 // 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 Loading @@ -1453,6 +1498,7 @@ void DnsProxyListener::GetHostByAddrHandler::run() { } else { rv = resolv_gethostbyaddr(&mAddress, mAddressLen, mAddressFamily, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp, &event); doDns64ReverseLookup(&hbuf, tmpbuf, sizeof tmpbuf, &hp, &event); } endQueryLimiter(uid); } else { Loading @@ -1461,7 +1507,6 @@ void DnsProxyListener::GetHostByAddrHandler::run() { << ", max concurrent queries reached"; } doDns64ReverseLookup(&hbuf, tmpbuf, sizeof tmpbuf, &hp, &event); const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs()); event.set_latency_micros(latencyUs); event.set_event_type(EVENT_GETHOSTBYADDR); Loading
DnsTlsTransport.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -113,7 +113,7 @@ base::Result<void> sendUdpQuery(netdutils::IPAddress ip, uint32_t mark, return ErrnoErrorf("connect failed"); } if (send(fd, query.data(), query.size(), 0) != query.size()) { if (send(fd, query.data(), query.size(), 0) != static_cast<ptrdiff_t>(query.size())) { return ErrnoErrorf("send failed"); } Loading
ResolverController.cpp +2 −7 Original line number Diff line number Diff line Loading @@ -37,9 +37,11 @@ #include "stats.h" #include "util.h" using aidl::android::net::IDnsResolver; using aidl::android::net::ResolverParamsParcel; using aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener; using aidl::android::net::resolv::aidl::Nat64PrefixEventParcel; using android::net::ResolverStats; namespace android { Loading Loading @@ -79,8 +81,6 @@ void sendNat64PrefixEvent(const Dns64Configuration::Nat64PrefixInfo& args) { int getDnsInfo(unsigned netId, std::vector<std::string>* servers, std::vector<std::string>* domains, res_params* params, std::vector<android::net::ResolverStats>* stats, int* wait_for_pending_req_timeout_count) { using aidl::android::net::IDnsResolver; using android::net::ResolverStats; static_assert(ResolverStats::STATS_SUCCESSES == IDnsResolver::RESOLVER_STATS_SUCCESSES && ResolverStats::STATS_ERRORS == IDnsResolver::RESOLVER_STATS_ERRORS && ResolverStats::STATS_TIMEOUTS == IDnsResolver::RESOLVER_STATS_TIMEOUTS && Loading Loading @@ -192,8 +192,6 @@ int ResolverController::flushNetworkCache(unsigned netId) { } int ResolverController::setResolverConfiguration(const ResolverParamsParcel& resolverParams) { using aidl::android::net::IDnsResolver; if (!has_named_cache(resolverParams.netId)) { return -ENOENT; } Loading Loading @@ -247,8 +245,6 @@ int ResolverController::getResolverInfo(int32_t netId, std::vector<std::string>* std::vector<std::string>* tlsServers, std::vector<int32_t>* params, std::vector<int32_t>* stats, int* wait_for_pending_req_timeout_count) { using aidl::android::net::IDnsResolver; using android::net::ResolverStats; res_params res_params; std::vector<ResolverStats> res_stats; int ret = getDnsInfo(netId, servers, domains, &res_params, &res_stats, Loading Loading @@ -295,7 +291,6 @@ int ResolverController::getPrefix64(unsigned netId, netdutils::IPPrefix* prefix) void ResolverController::dump(DumpWriter& dw, unsigned netId) { // No lock needed since Bionic's resolver locks all accessed data structures internally. using android::net::ResolverStats; std::vector<std::string> servers; std::vector<std::string> domains; res_params params = {}; Loading
aidl_api/dnsresolver_aidl_interface/12/.hash 0 → 100644 +1 −0 Original line number Diff line number Diff line a65a6755e2e5f5c160e7be2be814019e2d5491b1