// // Copyright (C) 2012 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #include "shill/resolver.h" #include <algorithm> #include <string> #include <vector> #include <base/files/file_util.h> #include <base/strings/string_util.h> #include <base/strings/stringprintf.h> #include "shill/ipconfig.h" #include "shill/logging.h" using base::StringPrintf; using std::string; using std::vector; namespace shill { namespace Logging { static auto kModuleLogScope = ScopeLogger::kResolver; static string ObjectID(Resolver* r) { return "(resolver)"; } } namespace { base::LazyInstance<Resolver> g_resolver = LAZY_INSTANCE_INITIALIZER; } // namespace const char Resolver::kDefaultIgnoredSearchList[] = "gateway.2wire.net"; Resolver::Resolver() {} Resolver::~Resolver() {} Resolver* Resolver::GetInstance() { return g_resolver.Pointer(); } bool Resolver::SetDNSFromLists(const std::vector<std::string>& dns_servers, const std::vector<std::string>& domain_search) { SLOG(this, 2) << __func__; if (dns_servers.empty() && domain_search.empty()) { SLOG(this, 2) << "DNS list is empty"; return ClearDNS(); } vector<string> lines; vector<string>::const_iterator iter; for (iter = dns_servers.begin(); iter != dns_servers.end(); ++iter) { lines.push_back("nameserver " + *iter); } vector<string> filtered_domain_search; for (iter = domain_search.begin(); iter != domain_search.end(); ++iter) { if (std::find(ignored_search_list_.begin(), ignored_search_list_.end(), *iter) == ignored_search_list_.end()) { filtered_domain_search.push_back(*iter); } } if (!filtered_domain_search.empty()) { lines.push_back("search " + base::JoinString(filtered_domain_search, " ")); } // - Send queries one-at-a-time, rather than parallelizing IPv4 // and IPv6 queries for a single host. // - Override the default 5-second request timeout and use a // 1-second timeout instead. (NOTE: Chrome's ADNS will use // one second, regardless of what we put here.) // - Allow 5 attempts, rather than the default of 2. // - For glibc, the worst case number of queries will be // attempts * count(servers) * (count(search domains)+1) // - For Chrome, the worst case number of queries will be // attempts * count(servers) + 3 * glibc // See crbug.com/224756 for supporting data. lines.push_back("options single-request timeout:1 attempts:5"); // Newline at end of file lines.push_back(""); string contents = base::JoinString(lines, "\n"); SLOG(this, 2) << "Writing DNS out to " << path_.value(); int count = base::WriteFile(path_, contents.c_str(), contents.size()); return count == static_cast<int>(contents.size()); } bool Resolver::ClearDNS() { SLOG(this, 2) << __func__; CHECK(!path_.empty()); return base::DeleteFile(path_, false); } } // namespace shill