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; std::vector<ResolverStats> stats; time_t now = time(nullptr); int rv = getDnsInfo(netId, &servers, &domains, ¶ms, &stats); dw.incIndent(); if (rv != 0) { dw.println("getDnsInfo() failed for netid %u", netId); } else { if (servers.empty()) { dw.println("No DNS servers defined"); } else { dw.println("DNS servers: # IP (total, successes, errors, timeouts, internal errors, " "RTT avg, last sample)"); dw.incIndent(); for (size_t i = 0 ; i < servers.size() ; ++i) { if (i < stats.size()) { const ResolverStats& s = stats[i]; int total = s.successes + s.errors + s.timeouts + s.internal_errors; if (total > 0) { int time_delta = (s.last_sample_time > 0) ? now - s.last_sample_time : -1; dw.println("%s (%d, %d, %d, %d, %d, %dms, %ds)%s", servers[i].c_str(), total, s.successes, s.errors, s.timeouts, s.internal_errors, s.rtt_avg, time_delta, s.usable ? "" : " BROKEN"); } else { dw.println("%s <no data>", servers[i].c_str()); } } else { dw.println("%s <no stats>", servers[i].c_str()); } } dw.decIndent(); } if (domains.empty()) { dw.println("No search domains defined"); } else { std::string domains_str = android::base::Join(domains, ", "); dw.println("search domains: %s", domains_str.c_str()); } if (params.sample_validity != 0) { dw.println("DNS parameters: sample validity = %us, success threshold = %u%%, " "samples (min, max) = (%u, %u)", params.sample_validity, static_cast<unsigned>(params.success_threshold), static_cast<unsigned>(params.min_samples), static_cast<unsigned>(params.max_samples)); } { std::lock_guard<std::mutex> guard(privateDnsLock); const auto& mode = privateDnsModes.find(netId); dw.println("Private DNS mode: %s", getPrivateDnsModeString( mode != privateDnsModes.end() ? mode->second : PrivateDnsMode::OFF)); const auto& netPair = privateDnsTransports.find(netId); if (netPair == privateDnsTransports.end()) { dw.println("No Private DNS servers configured"); } else { const auto& tracker = netPair->second; dw.println("Private DNS configuration (%zu entries)", tracker.size()); dw.incIndent(); for (const auto& kv : tracker) { const auto& server = kv.first; const auto status = kv.second; dw.println("%s name{%s} status{%s}", addrToString(&(server.ss)).c_str(), server.name.c_str(), validationStatusToString(status)); } dw.decIndent(); } } } dw.decIndent(); }