Loading Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -199,6 +199,8 @@ cc_test { "libnetd_resolv", "libnetd_test_dnsresponder", "libnetdutils", "libprotobuf-cpp-lite", "server_configurable_flags", "stats_proto", ], } Dns64Configuration.cpp +5 −1 Original line number Diff line number Diff line Loading @@ -33,9 +33,11 @@ #include "DnsResolver.h" #include "getaddrinfo.h" #include "netd_resolv/resolv.h" #include "stats.pb.h" namespace android { using android::net::NetworkDnsEventReported; using netdutils::DumpWriter; using netdutils::IPAddress; using netdutils::IPPrefix; Loading Loading @@ -154,7 +156,9 @@ bool Dns64Configuration::doRfc7050PrefixDiscovery(const android_net_context& net // ourselves, which means we also bypass all the special netcontext flag // handling and the resolver event logging. struct addrinfo* res = nullptr; const int status = resolv_getaddrinfo(kIPv4OnlyHost, nullptr, &hints, &netcontext, &res); NetworkDnsEventReported event; const int status = resolv_getaddrinfo(kIPv4OnlyHost, nullptr, &hints, &netcontext, &res, &event); ScopedAddrinfo result(res); if (status != 0) { LOG(WARNING) << "(" << cfg->netId << ", " << cfg->discoveryId << ") plat_prefix/dns(" Loading DnsProxyListener.cpp +64 −38 Original line number Diff line number Diff line Loading @@ -299,17 +299,23 @@ bool parseQuery(const uint8_t* msg, size_t msgLen, uint16_t* query_id, int* rr_t return true; } void initDnsEvent(NetworkDnsEventReported* event) { // The value 0 has the special meaning of unset/unknown in Westworld atoms. event->set_hints_ai_flags(-1); event->set_res_nsend_flags(-1); } void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs, int returnCode, const NetworkDnsEventReported& dnsEvent, const std::string& query_name, const std::vector<std::string>& ip_addrs = {}, int total_ip_addr_count = 0) { std::string dnsQueryStats = dnsEvent.dns_query_events().SerializeAsString(); char const* dnsQueryStatsBytes = dnsQueryStats.c_str(); stats::BytesField dnsQueryBytesField{dnsQueryStatsBytes, dnsQueryStats.size()}; android::net::stats::stats_write(android::net::stats::NETWORK_DNS_EVENT_REPORTED, eventType, returnCode, latencyUs, dnsEvent.hints_ai_flags(), dnsEvent.res_nsend_flags(), dnsEvent.network_type(), dnsEvent.private_dns_modes(), dnsQueryBytesField); int returnCode, NetworkDnsEventReported& event, const std::string& query_name, const std::vector<std::string>& ip_addrs = {}, int total_ip_addr_count = 0) { 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)); android::net::stats::stats_write(android::net::stats::NETWORK_DNS_EVENT_REPORTED, event.event_type(), event.return_code(), event.latency_micros(), event.hints_ai_flags(), event.res_nsend_flags(), event.network_type(), event.private_dns_modes(), dnsQueryBytesField); const auto& listeners = ResolverEventReporter::getInstance().getListeners(); if (listeners.size() == 0) { Loading Loading @@ -590,7 +596,8 @@ static bool sendaddrinfo(SocketClient* c, addrinfo* ai) { return true; } void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinfo** res) { void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinfo** res, NetworkDnsEventReported* event) { if (mHost == nullptr) return; const bool ipv6WantedButNoData = (mHints && mHints->ai_family == AF_INET6 && *rv == EAI_NODATA); Loading @@ -613,7 +620,8 @@ void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinf 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 = android_getaddrinfofornetcontext(mHost, mService, mHints, &mNetContext, res); *rv = android_getaddrinfofornetcontext(mHost, mService, mHints, &mNetContext, res, event); queryLimiter.finish(uid); if (*rv) { *rv = EAI_NODATA; // return original error code Loading Loading @@ -648,9 +656,10 @@ void DnsProxyListener::GetAddrInfoHandler::run() { maybeFixupNetContext(&mNetContext); const uid_t uid = mClient->getUid(); int32_t rv = 0; NetworkDnsEventReported dnsEvent; NetworkDnsEventReported event; initDnsEvent(&event); if (queryLimiter.start(uid)) { rv = resolv_getaddrinfo(mHost, mService, mHints, &mNetContext, &result); rv = resolv_getaddrinfo(mHost, mService, mHints, &mNetContext, &result, &event); queryLimiter.finish(uid); } else { // Note that this error code is currently not passed down to the client. Loading @@ -660,8 +669,11 @@ void DnsProxyListener::GetAddrInfoHandler::run() { << ", max concurrent queries reached"; } doDns64Synthesis(&rv, &result); const int latencyUs = int(s.timeTakenUs()); 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); event.set_hints_ai_flags((mHints ? mHints->ai_flags : 0)); if (rv) { // getaddrinfo failed Loading @@ -680,8 +692,8 @@ void DnsProxyListener::GetAddrInfoHandler::run() { } std::vector<std::string> ip_addrs; const int total_ip_addr_count = extractGetAddrInfoAnswers(result, &ip_addrs); reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, dnsEvent, mHost, ip_addrs, total_ip_addr_count); reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, event, mHost, ip_addrs, total_ip_addr_count); freeaddrinfo(result); mClient->decRef(); } Loading Loading @@ -854,10 +866,11 @@ void DnsProxyListener::ResNSendHandler::run() { // Send DNS query std::vector<uint8_t> ansBuf(MAXPACKET, 0); int arcode, nsendAns = -1; NetworkDnsEventReported dnsEvent; NetworkDnsEventReported event; initDnsEvent(&event); if (queryLimiter.start(uid)) { nsendAns = resolv_res_nsend(&mNetContext, msg.data(), msgLen, ansBuf.data(), MAXPACKET, &arcode, static_cast<ResNsendFlags>(mFlags)); &arcode, static_cast<ResNsendFlags>(mFlags), &event); queryLimiter.finish(uid); } else { LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid Loading @@ -865,14 +878,17 @@ void DnsProxyListener::ResNSendHandler::run() { nsendAns = -EBUSY; } const int latencyUs = int(s.timeTakenUs()); const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs()); event.set_latency_micros(latencyUs); event.set_event_type(EVENT_RES_NSEND); event.set_res_nsend_flags(static_cast<ResNsendFlags>(mFlags)); // Fail, send -errno if (nsendAns < 0) { sendBE32(mClient, nsendAns); if (rr_type == ns_t_a || rr_type == ns_t_aaaa) { reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, resNSendToAiError(nsendAns, arcode), dnsEvent, rr_name); resNSendToAiError(nsendAns, arcode), event, rr_name); } return; } Loading @@ -895,7 +911,7 @@ void DnsProxyListener::ResNSendHandler::run() { const int total_ip_addr_count = extractResNsendAnswers((uint8_t*) ansBuf.data(), nsendAns, rr_type, &ip_addrs); reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, resNSendToAiError(nsendAns, arcode), dnsEvent, rr_name, ip_addrs, resNSendToAiError(nsendAns, arcode), event, rr_name, ip_addrs, total_ip_addr_count); } } Loading Loading @@ -994,7 +1010,8 @@ DnsProxyListener::GetHostByNameHandler::~GetHostByNameHandler() { free(mName); } void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, struct hostent** hpp) { void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, struct hostent** hpp, NetworkDnsEventReported* event) { // Don't have to consider family AF_UNSPEC case because gethostbyname{, 2} only supports // family AF_INET or AF_INET6. const bool ipv6WantedButNoData = (mAf == AF_INET6 && *rv == EAI_NODATA); Loading @@ -1011,7 +1028,7 @@ void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, struc // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis const uid_t uid = mClient->getUid(); if (queryLimiter.start(uid)) { *rv = android_gethostbynamefornetcontext(mName, AF_INET, &mNetContext, hpp); *rv = android_gethostbynamefornetcontext(mName, AF_INET, &mNetContext, hpp, event); queryLimiter.finish(uid); if (*rv) { *rv = EAI_NODATA; // return original error code Loading @@ -1035,9 +1052,10 @@ void DnsProxyListener::GetHostByNameHandler::run() { const uid_t uid = mClient->getUid(); hostent* hp = nullptr; int32_t rv = 0; NetworkDnsEventReported dnsEvent; NetworkDnsEventReported event; initDnsEvent(&event); if (queryLimiter.start(uid)) { rv = android_gethostbynamefornetcontext(mName, mAf, &mNetContext, &hp); rv = android_gethostbynamefornetcontext(mName, mAf, &mNetContext, &hp, &event); queryLimiter.finish(uid); } else { rv = EAI_MEMORY; Loading @@ -1045,8 +1063,11 @@ void DnsProxyListener::GetHostByNameHandler::run() { << ", max concurrent queries reached"; } doDns64Synthesis(&rv, &hp); const int latencyUs = lround(s.timeTakenUs()); doDns64Synthesis(&rv, &hp, &event); const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs()); event.set_latency_micros(latencyUs); event.set_event_type(EVENT_GETHOSTBYNAME); LOG(DEBUG) << "GetHostByNameHandler::run: errno: " << (hp ? "success" : strerror(errno)); bool success = true; Loading @@ -1064,7 +1085,7 @@ void DnsProxyListener::GetHostByNameHandler::run() { std::vector<std::string> ip_addrs; const int total_ip_addr_count = extractGetHostByNameAnswers(hp, &ip_addrs); reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, dnsEvent, reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, event, mName, ip_addrs, total_ip_addr_count); mClient->decRef(); } Loading Loading @@ -1134,7 +1155,8 @@ DnsProxyListener::GetHostByAddrHandler::~GetHostByAddrHandler() { free(mAddress); } void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(struct hostent** hpp) { void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(struct hostent** hpp, NetworkDnsEventReported* event) { if (*hpp != nullptr || mAddressFamily != AF_INET6 || !mAddress) { return; } Loading Loading @@ -1162,7 +1184,8 @@ void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(struct hostent if (queryLimiter.start(uid)) { // Remove NAT64 prefix and do reverse DNS query struct in_addr v4addr = {.s_addr = v6addr.s6_addr32[3]}; android_gethostbyaddrfornetcontext(&v4addr, sizeof(v4addr), AF_INET, &mNetContext, hpp); android_gethostbyaddrfornetcontext(&v4addr, sizeof(v4addr), AF_INET, &mNetContext, hpp, event); queryLimiter.finish(uid); if (*hpp) { // Replace IPv4 address with original queried IPv6 address in place. The space has Loading @@ -1184,10 +1207,11 @@ void DnsProxyListener::GetHostByAddrHandler::run() { const uid_t uid = mClient->getUid(); hostent* hp = nullptr; int32_t rv = 0; NetworkDnsEventReported dnsEvent; NetworkDnsEventReported event; initDnsEvent(&event); if (queryLimiter.start(uid)) { rv = android_gethostbyaddrfornetcontext(mAddress, mAddressLen, mAddressFamily, &mNetContext, &hp); rv = android_gethostbyaddrfornetcontext(mAddress, mAddressLen, mAddressFamily, &mNetContext, &hp, &event); queryLimiter.finish(uid); } else { rv = EAI_MEMORY; Loading @@ -1195,8 +1219,10 @@ void DnsProxyListener::GetHostByAddrHandler::run() { << ", max concurrent queries reached"; } doDns64ReverseLookup(&hp); const int latencyUs = int(s.timeTakenUs()); doDns64ReverseLookup(&hp, &event); const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs()); event.set_latency_micros(latencyUs); event.set_event_type(EVENT_GETHOSTBYADDR); LOG(DEBUG) << "GetHostByAddrHandler::run: result: " << (hp ? "success" : gai_strerror(rv)); Loading @@ -1212,7 +1238,7 @@ void DnsProxyListener::GetHostByAddrHandler::run() { LOG(WARNING) << "GetHostByAddrHandler::run: Error writing DNS result to client"; } reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, dnsEvent, reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, event, (hp && hp->h_name) ? hp->h_name : "null", {}, 0); mClient->decRef(); } Loading DnsProxyListener.h +5 −3 Original line number Diff line number Diff line Loading @@ -28,6 +28,8 @@ struct hostent; namespace android { namespace net { class NetworkDnsEventReported; class DnsProxyListener : public FrameworkListener { public: DnsProxyListener(); Loading @@ -54,7 +56,7 @@ class DnsProxyListener : public FrameworkListener { void run(); private: void doDns64Synthesis(int32_t* rv, addrinfo** res); void doDns64Synthesis(int32_t* rv, addrinfo** res, NetworkDnsEventReported* event); SocketClient* mClient; // ref counted char* mHost; // owned. TODO: convert to std::string. Loading @@ -80,7 +82,7 @@ class DnsProxyListener : public FrameworkListener { void run(); private: void doDns64Synthesis(int32_t* rv, hostent** hpp); void doDns64Synthesis(int32_t* rv, hostent** hpp, NetworkDnsEventReported* event); SocketClient* mClient; // ref counted char* mName; // owned. TODO: convert to std::string. Loading @@ -105,7 +107,7 @@ class DnsProxyListener : public FrameworkListener { void run(); private: void doDns64ReverseLookup(hostent** hpp); void doDns64ReverseLookup(hostent** hpp, NetworkDnsEventReported* event); SocketClient* mClient; // ref counted void* mAddress; // address to lookup; owned Loading DnsTlsDispatcher.cpp +27 −7 Original line number Diff line number Diff line Loading @@ -17,13 +17,17 @@ #define LOG_TAG "resolv" #include "DnsTlsDispatcher.h" #include <netdutils/Stopwatch.h> #include "DnsTlsSocketFactory.h" #include "resolv_private.h" #include "stats.pb.h" #include <android-base/logging.h> namespace android { namespace net { using android::netdutils::Stopwatch; using netdutils::Slice; // static Loading Loading @@ -81,29 +85,45 @@ std::list<DnsTlsServer> DnsTlsDispatcher::getOrderedServerList( return out; } DnsTlsTransport::Response DnsTlsDispatcher::query( const std::list<DnsTlsServer> &tlsServers, unsigned mark, const Slice query, const Slice ans, int *resplen) { const std::list<DnsTlsServer> orderedServers(getOrderedServerList(tlsServers, mark)); DnsTlsTransport::Response DnsTlsDispatcher::query(const std::list<DnsTlsServer>& tlsServers, res_state statp, const Slice query, const Slice ans, int* resplen) { const std::list<DnsTlsServer> orderedServers(getOrderedServerList(tlsServers, statp->_mark)); if (orderedServers.empty()) LOG(WARNING) << "Empty DnsTlsServer list"; DnsTlsTransport::Response code = DnsTlsTransport::Response::internal_error; int serverCount = 0; for (const auto& server : orderedServers) { code = this->query(server, mark, query, ans, resplen); DnsQueryEvent* dnsQueryEvent = statp->event->mutable_dns_query_events()->add_dns_query_event(); dnsQueryEvent->set_rcode(NS_R_INTERNAL_ERROR); Stopwatch query_stopwatch; code = this->query(server, statp->_mark, query, ans, resplen); dnsQueryEvent->set_latency_micros(saturate_cast<int32_t>(query_stopwatch.timeTakenUs())); dnsQueryEvent->set_dns_server_index(serverCount++); dnsQueryEvent->set_ip_version(ipFamilyToIPVersion(server.ss.ss_family)); dnsQueryEvent->set_protocol(PROTO_DOT); dnsQueryEvent->set_type(getQueryType(query.base(), query.size())); switch (code) { // These response codes are valid responses and not expected to // change if another server is queried. case DnsTlsTransport::Response::success: dnsQueryEvent->set_rcode( static_cast<NsRcode>(reinterpret_cast<HEADER*>(ans.base())->rcode)); [[fallthrough]]; case DnsTlsTransport::Response::limit_error: return code; break; // These response codes might differ when trying other servers, so // keep iterating to see if we can get a different (better) result. case DnsTlsTransport::Response::network_error: // Sync from res_tls_send in res_send.cpp dnsQueryEvent->set_rcode(NS_R_TIMEOUT); [[fallthrough]]; case DnsTlsTransport::Response::internal_error: continue; break; // No "default" statement. } } Loading Loading
Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -199,6 +199,8 @@ cc_test { "libnetd_resolv", "libnetd_test_dnsresponder", "libnetdutils", "libprotobuf-cpp-lite", "server_configurable_flags", "stats_proto", ], }
Dns64Configuration.cpp +5 −1 Original line number Diff line number Diff line Loading @@ -33,9 +33,11 @@ #include "DnsResolver.h" #include "getaddrinfo.h" #include "netd_resolv/resolv.h" #include "stats.pb.h" namespace android { using android::net::NetworkDnsEventReported; using netdutils::DumpWriter; using netdutils::IPAddress; using netdutils::IPPrefix; Loading Loading @@ -154,7 +156,9 @@ bool Dns64Configuration::doRfc7050PrefixDiscovery(const android_net_context& net // ourselves, which means we also bypass all the special netcontext flag // handling and the resolver event logging. struct addrinfo* res = nullptr; const int status = resolv_getaddrinfo(kIPv4OnlyHost, nullptr, &hints, &netcontext, &res); NetworkDnsEventReported event; const int status = resolv_getaddrinfo(kIPv4OnlyHost, nullptr, &hints, &netcontext, &res, &event); ScopedAddrinfo result(res); if (status != 0) { LOG(WARNING) << "(" << cfg->netId << ", " << cfg->discoveryId << ") plat_prefix/dns(" Loading
DnsProxyListener.cpp +64 −38 Original line number Diff line number Diff line Loading @@ -299,17 +299,23 @@ bool parseQuery(const uint8_t* msg, size_t msgLen, uint16_t* query_id, int* rr_t return true; } void initDnsEvent(NetworkDnsEventReported* event) { // The value 0 has the special meaning of unset/unknown in Westworld atoms. event->set_hints_ai_flags(-1); event->set_res_nsend_flags(-1); } void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs, int returnCode, const NetworkDnsEventReported& dnsEvent, const std::string& query_name, const std::vector<std::string>& ip_addrs = {}, int total_ip_addr_count = 0) { std::string dnsQueryStats = dnsEvent.dns_query_events().SerializeAsString(); char const* dnsQueryStatsBytes = dnsQueryStats.c_str(); stats::BytesField dnsQueryBytesField{dnsQueryStatsBytes, dnsQueryStats.size()}; android::net::stats::stats_write(android::net::stats::NETWORK_DNS_EVENT_REPORTED, eventType, returnCode, latencyUs, dnsEvent.hints_ai_flags(), dnsEvent.res_nsend_flags(), dnsEvent.network_type(), dnsEvent.private_dns_modes(), dnsQueryBytesField); int returnCode, NetworkDnsEventReported& event, const std::string& query_name, const std::vector<std::string>& ip_addrs = {}, int total_ip_addr_count = 0) { 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)); android::net::stats::stats_write(android::net::stats::NETWORK_DNS_EVENT_REPORTED, event.event_type(), event.return_code(), event.latency_micros(), event.hints_ai_flags(), event.res_nsend_flags(), event.network_type(), event.private_dns_modes(), dnsQueryBytesField); const auto& listeners = ResolverEventReporter::getInstance().getListeners(); if (listeners.size() == 0) { Loading Loading @@ -590,7 +596,8 @@ static bool sendaddrinfo(SocketClient* c, addrinfo* ai) { return true; } void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinfo** res) { void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinfo** res, NetworkDnsEventReported* event) { if (mHost == nullptr) return; const bool ipv6WantedButNoData = (mHints && mHints->ai_family == AF_INET6 && *rv == EAI_NODATA); Loading @@ -613,7 +620,8 @@ void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinf 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 = android_getaddrinfofornetcontext(mHost, mService, mHints, &mNetContext, res); *rv = android_getaddrinfofornetcontext(mHost, mService, mHints, &mNetContext, res, event); queryLimiter.finish(uid); if (*rv) { *rv = EAI_NODATA; // return original error code Loading Loading @@ -648,9 +656,10 @@ void DnsProxyListener::GetAddrInfoHandler::run() { maybeFixupNetContext(&mNetContext); const uid_t uid = mClient->getUid(); int32_t rv = 0; NetworkDnsEventReported dnsEvent; NetworkDnsEventReported event; initDnsEvent(&event); if (queryLimiter.start(uid)) { rv = resolv_getaddrinfo(mHost, mService, mHints, &mNetContext, &result); rv = resolv_getaddrinfo(mHost, mService, mHints, &mNetContext, &result, &event); queryLimiter.finish(uid); } else { // Note that this error code is currently not passed down to the client. Loading @@ -660,8 +669,11 @@ void DnsProxyListener::GetAddrInfoHandler::run() { << ", max concurrent queries reached"; } doDns64Synthesis(&rv, &result); const int latencyUs = int(s.timeTakenUs()); 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); event.set_hints_ai_flags((mHints ? mHints->ai_flags : 0)); if (rv) { // getaddrinfo failed Loading @@ -680,8 +692,8 @@ void DnsProxyListener::GetAddrInfoHandler::run() { } std::vector<std::string> ip_addrs; const int total_ip_addr_count = extractGetAddrInfoAnswers(result, &ip_addrs); reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, dnsEvent, mHost, ip_addrs, total_ip_addr_count); reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, event, mHost, ip_addrs, total_ip_addr_count); freeaddrinfo(result); mClient->decRef(); } Loading Loading @@ -854,10 +866,11 @@ void DnsProxyListener::ResNSendHandler::run() { // Send DNS query std::vector<uint8_t> ansBuf(MAXPACKET, 0); int arcode, nsendAns = -1; NetworkDnsEventReported dnsEvent; NetworkDnsEventReported event; initDnsEvent(&event); if (queryLimiter.start(uid)) { nsendAns = resolv_res_nsend(&mNetContext, msg.data(), msgLen, ansBuf.data(), MAXPACKET, &arcode, static_cast<ResNsendFlags>(mFlags)); &arcode, static_cast<ResNsendFlags>(mFlags), &event); queryLimiter.finish(uid); } else { LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid Loading @@ -865,14 +878,17 @@ void DnsProxyListener::ResNSendHandler::run() { nsendAns = -EBUSY; } const int latencyUs = int(s.timeTakenUs()); const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs()); event.set_latency_micros(latencyUs); event.set_event_type(EVENT_RES_NSEND); event.set_res_nsend_flags(static_cast<ResNsendFlags>(mFlags)); // Fail, send -errno if (nsendAns < 0) { sendBE32(mClient, nsendAns); if (rr_type == ns_t_a || rr_type == ns_t_aaaa) { reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, resNSendToAiError(nsendAns, arcode), dnsEvent, rr_name); resNSendToAiError(nsendAns, arcode), event, rr_name); } return; } Loading @@ -895,7 +911,7 @@ void DnsProxyListener::ResNSendHandler::run() { const int total_ip_addr_count = extractResNsendAnswers((uint8_t*) ansBuf.data(), nsendAns, rr_type, &ip_addrs); reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs, resNSendToAiError(nsendAns, arcode), dnsEvent, rr_name, ip_addrs, resNSendToAiError(nsendAns, arcode), event, rr_name, ip_addrs, total_ip_addr_count); } } Loading Loading @@ -994,7 +1010,8 @@ DnsProxyListener::GetHostByNameHandler::~GetHostByNameHandler() { free(mName); } void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, struct hostent** hpp) { void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, struct hostent** hpp, NetworkDnsEventReported* event) { // Don't have to consider family AF_UNSPEC case because gethostbyname{, 2} only supports // family AF_INET or AF_INET6. const bool ipv6WantedButNoData = (mAf == AF_INET6 && *rv == EAI_NODATA); Loading @@ -1011,7 +1028,7 @@ void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, struc // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis const uid_t uid = mClient->getUid(); if (queryLimiter.start(uid)) { *rv = android_gethostbynamefornetcontext(mName, AF_INET, &mNetContext, hpp); *rv = android_gethostbynamefornetcontext(mName, AF_INET, &mNetContext, hpp, event); queryLimiter.finish(uid); if (*rv) { *rv = EAI_NODATA; // return original error code Loading @@ -1035,9 +1052,10 @@ void DnsProxyListener::GetHostByNameHandler::run() { const uid_t uid = mClient->getUid(); hostent* hp = nullptr; int32_t rv = 0; NetworkDnsEventReported dnsEvent; NetworkDnsEventReported event; initDnsEvent(&event); if (queryLimiter.start(uid)) { rv = android_gethostbynamefornetcontext(mName, mAf, &mNetContext, &hp); rv = android_gethostbynamefornetcontext(mName, mAf, &mNetContext, &hp, &event); queryLimiter.finish(uid); } else { rv = EAI_MEMORY; Loading @@ -1045,8 +1063,11 @@ void DnsProxyListener::GetHostByNameHandler::run() { << ", max concurrent queries reached"; } doDns64Synthesis(&rv, &hp); const int latencyUs = lround(s.timeTakenUs()); doDns64Synthesis(&rv, &hp, &event); const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs()); event.set_latency_micros(latencyUs); event.set_event_type(EVENT_GETHOSTBYNAME); LOG(DEBUG) << "GetHostByNameHandler::run: errno: " << (hp ? "success" : strerror(errno)); bool success = true; Loading @@ -1064,7 +1085,7 @@ void DnsProxyListener::GetHostByNameHandler::run() { std::vector<std::string> ip_addrs; const int total_ip_addr_count = extractGetHostByNameAnswers(hp, &ip_addrs); reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, dnsEvent, reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, event, mName, ip_addrs, total_ip_addr_count); mClient->decRef(); } Loading Loading @@ -1134,7 +1155,8 @@ DnsProxyListener::GetHostByAddrHandler::~GetHostByAddrHandler() { free(mAddress); } void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(struct hostent** hpp) { void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(struct hostent** hpp, NetworkDnsEventReported* event) { if (*hpp != nullptr || mAddressFamily != AF_INET6 || !mAddress) { return; } Loading Loading @@ -1162,7 +1184,8 @@ void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(struct hostent if (queryLimiter.start(uid)) { // Remove NAT64 prefix and do reverse DNS query struct in_addr v4addr = {.s_addr = v6addr.s6_addr32[3]}; android_gethostbyaddrfornetcontext(&v4addr, sizeof(v4addr), AF_INET, &mNetContext, hpp); android_gethostbyaddrfornetcontext(&v4addr, sizeof(v4addr), AF_INET, &mNetContext, hpp, event); queryLimiter.finish(uid); if (*hpp) { // Replace IPv4 address with original queried IPv6 address in place. The space has Loading @@ -1184,10 +1207,11 @@ void DnsProxyListener::GetHostByAddrHandler::run() { const uid_t uid = mClient->getUid(); hostent* hp = nullptr; int32_t rv = 0; NetworkDnsEventReported dnsEvent; NetworkDnsEventReported event; initDnsEvent(&event); if (queryLimiter.start(uid)) { rv = android_gethostbyaddrfornetcontext(mAddress, mAddressLen, mAddressFamily, &mNetContext, &hp); rv = android_gethostbyaddrfornetcontext(mAddress, mAddressLen, mAddressFamily, &mNetContext, &hp, &event); queryLimiter.finish(uid); } else { rv = EAI_MEMORY; Loading @@ -1195,8 +1219,10 @@ void DnsProxyListener::GetHostByAddrHandler::run() { << ", max concurrent queries reached"; } doDns64ReverseLookup(&hp); const int latencyUs = int(s.timeTakenUs()); doDns64ReverseLookup(&hp, &event); const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs()); event.set_latency_micros(latencyUs); event.set_event_type(EVENT_GETHOSTBYADDR); LOG(DEBUG) << "GetHostByAddrHandler::run: result: " << (hp ? "success" : gai_strerror(rv)); Loading @@ -1212,7 +1238,7 @@ void DnsProxyListener::GetHostByAddrHandler::run() { LOG(WARNING) << "GetHostByAddrHandler::run: Error writing DNS result to client"; } reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, dnsEvent, reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, event, (hp && hp->h_name) ? hp->h_name : "null", {}, 0); mClient->decRef(); } Loading
DnsProxyListener.h +5 −3 Original line number Diff line number Diff line Loading @@ -28,6 +28,8 @@ struct hostent; namespace android { namespace net { class NetworkDnsEventReported; class DnsProxyListener : public FrameworkListener { public: DnsProxyListener(); Loading @@ -54,7 +56,7 @@ class DnsProxyListener : public FrameworkListener { void run(); private: void doDns64Synthesis(int32_t* rv, addrinfo** res); void doDns64Synthesis(int32_t* rv, addrinfo** res, NetworkDnsEventReported* event); SocketClient* mClient; // ref counted char* mHost; // owned. TODO: convert to std::string. Loading @@ -80,7 +82,7 @@ class DnsProxyListener : public FrameworkListener { void run(); private: void doDns64Synthesis(int32_t* rv, hostent** hpp); void doDns64Synthesis(int32_t* rv, hostent** hpp, NetworkDnsEventReported* event); SocketClient* mClient; // ref counted char* mName; // owned. TODO: convert to std::string. Loading @@ -105,7 +107,7 @@ class DnsProxyListener : public FrameworkListener { void run(); private: void doDns64ReverseLookup(hostent** hpp); void doDns64ReverseLookup(hostent** hpp, NetworkDnsEventReported* event); SocketClient* mClient; // ref counted void* mAddress; // address to lookup; owned Loading
DnsTlsDispatcher.cpp +27 −7 Original line number Diff line number Diff line Loading @@ -17,13 +17,17 @@ #define LOG_TAG "resolv" #include "DnsTlsDispatcher.h" #include <netdutils/Stopwatch.h> #include "DnsTlsSocketFactory.h" #include "resolv_private.h" #include "stats.pb.h" #include <android-base/logging.h> namespace android { namespace net { using android::netdutils::Stopwatch; using netdutils::Slice; // static Loading Loading @@ -81,29 +85,45 @@ std::list<DnsTlsServer> DnsTlsDispatcher::getOrderedServerList( return out; } DnsTlsTransport::Response DnsTlsDispatcher::query( const std::list<DnsTlsServer> &tlsServers, unsigned mark, const Slice query, const Slice ans, int *resplen) { const std::list<DnsTlsServer> orderedServers(getOrderedServerList(tlsServers, mark)); DnsTlsTransport::Response DnsTlsDispatcher::query(const std::list<DnsTlsServer>& tlsServers, res_state statp, const Slice query, const Slice ans, int* resplen) { const std::list<DnsTlsServer> orderedServers(getOrderedServerList(tlsServers, statp->_mark)); if (orderedServers.empty()) LOG(WARNING) << "Empty DnsTlsServer list"; DnsTlsTransport::Response code = DnsTlsTransport::Response::internal_error; int serverCount = 0; for (const auto& server : orderedServers) { code = this->query(server, mark, query, ans, resplen); DnsQueryEvent* dnsQueryEvent = statp->event->mutable_dns_query_events()->add_dns_query_event(); dnsQueryEvent->set_rcode(NS_R_INTERNAL_ERROR); Stopwatch query_stopwatch; code = this->query(server, statp->_mark, query, ans, resplen); dnsQueryEvent->set_latency_micros(saturate_cast<int32_t>(query_stopwatch.timeTakenUs())); dnsQueryEvent->set_dns_server_index(serverCount++); dnsQueryEvent->set_ip_version(ipFamilyToIPVersion(server.ss.ss_family)); dnsQueryEvent->set_protocol(PROTO_DOT); dnsQueryEvent->set_type(getQueryType(query.base(), query.size())); switch (code) { // These response codes are valid responses and not expected to // change if another server is queried. case DnsTlsTransport::Response::success: dnsQueryEvent->set_rcode( static_cast<NsRcode>(reinterpret_cast<HEADER*>(ans.base())->rcode)); [[fallthrough]]; case DnsTlsTransport::Response::limit_error: return code; break; // These response codes might differ when trying other servers, so // keep iterating to see if we can get a different (better) result. case DnsTlsTransport::Response::network_error: // Sync from res_tls_send in res_send.cpp dnsQueryEvent->set_rcode(NS_R_TIMEOUT); [[fallthrough]]; case DnsTlsTransport::Response::internal_error: continue; break; // No "default" statement. } } Loading