blob: f45c337048f1595898d32a58781c16cde286cd87 [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#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 " + 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 = 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