1 // 2 // Copyright (C) 2012 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "shill/resolver.h" 18 19 #include <algorithm> 20 #include <string> 21 #include <vector> 22 23 #include <base/files/file_util.h> 24 #include <base/strings/string_util.h> 25 #include <base/strings/stringprintf.h> 26 27 #include "shill/ipconfig.h" 28 #include "shill/logging.h" 29 30 using base::StringPrintf; 31 using std::string; 32 using std::vector; 33 34 namespace shill { 35 36 namespace Logging { 37 static auto kModuleLogScope = ScopeLogger::kResolver; 38 static string ObjectID(Resolver* r) { return "(resolver)"; } 39 } 40 41 namespace { 42 base::LazyInstance<Resolver> g_resolver = LAZY_INSTANCE_INITIALIZER; 43 } // namespace 44 45 const char Resolver::kDefaultIgnoredSearchList[] = "gateway.2wire.net"; 46 47 Resolver::Resolver() {} 48 49 Resolver::~Resolver() {} 50 51 Resolver* Resolver::GetInstance() { 52 return g_resolver.Pointer(); 53 } 54 55 bool Resolver::SetDNSFromLists(const std::vector<std::string>& dns_servers, 56 const std::vector<std::string>& domain_search) { 57 SLOG(this, 2) << __func__; 58 59 if (dns_servers.empty() && domain_search.empty()) { 60 SLOG(this, 2) << "DNS list is empty"; 61 return ClearDNS(); 62 } 63 64 vector<string> lines; 65 vector<string>::const_iterator iter; 66 for (iter = dns_servers.begin(); 67 iter != dns_servers.end(); ++iter) { 68 lines.push_back("nameserver " + *iter); 69 } 70 71 vector<string> filtered_domain_search; 72 for (iter = domain_search.begin(); 73 iter != domain_search.end(); ++iter) { 74 if (std::find(ignored_search_list_.begin(), 75 ignored_search_list_.end(), 76 *iter) == ignored_search_list_.end()) { 77 filtered_domain_search.push_back(*iter); 78 } 79 } 80 81 if (!filtered_domain_search.empty()) { 82 lines.push_back("search " + base::JoinString(filtered_domain_search, " ")); 83 } 84 85 // - Send queries one-at-a-time, rather than parallelizing IPv4 86 // and IPv6 queries for a single host. 87 // - Override the default 5-second request timeout and use a 88 // 1-second timeout instead. (NOTE: Chrome's ADNS will use 89 // one second, regardless of what we put here.) 90 // - Allow 5 attempts, rather than the default of 2. 91 // - For glibc, the worst case number of queries will be 92 // attempts * count(servers) * (count(search domains)+1) 93 // - For Chrome, the worst case number of queries will be 94 // attempts * count(servers) + 3 * glibc 95 // See crbug.com/224756 for supporting data. 96 lines.push_back("options single-request timeout:1 attempts:5"); 97 98 // Newline at end of file 99 lines.push_back(""); 100 101 string contents = base::JoinString(lines, "\n"); 102 103 SLOG(this, 2) << "Writing DNS out to " << path_.value(); 104 int count = base::WriteFile(path_, contents.c_str(), contents.size()); 105 106 return count == static_cast<int>(contents.size()); 107 } 108 109 bool Resolver::ClearDNS() { 110 SLOG(this, 2) << __func__; 111 112 CHECK(!path_.empty()); 113 114 return base::DeleteFile(path_, false); 115 } 116 117 } // namespace shill 118