blob: c9594f3f5a59f43bec06250ca2af25aa0f9ef3b3 [file] [log] [blame]
Thieu Le3bd0faa2012-02-15 15:44:46 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Paul Stewartb6063942011-08-05 10:17:29 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/resolver.h"
6
7#include <string>
8#include <vector>
9
10#include <base/file_util.h>
11#include <base/string_util.h>
12#include <base/stringprintf.h>
13
14#include "shill/ipconfig.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070015#include "shill/logging.h"
Paul Stewartb6063942011-08-05 10:17:29 -070016
Paul Stewartb6063942011-08-05 10:17:29 -070017using base::StringPrintf;
18using std::string;
19using std::vector;
20
Paul Stewart0d2ada32011-08-09 17:01:57 -070021namespace shill {
22
Ben Chanbbdef5f2012-04-23 13:58:15 -070023namespace {
24base::LazyInstance<Resolver> g_resolver = LAZY_INSTANCE_INITIALIZER;
25} // namespace
Paul Stewart0d2ada32011-08-09 17:01:57 -070026
Paul Stewartbf667612012-06-29 14:49:54 -070027const char Resolver::kDefaultShortTimeoutTechnologies[] = "ethernet,wifi";
28const char Resolver::kDefaultTimeoutOptions[] =
29 "options single-request timeout:1 attempts:3";
30const char Resolver::kShortTimeoutOptions[] =
31 "options single-request timeout-ms:300 attempts:15";
32
Paul Stewartb6063942011-08-05 10:17:29 -070033Resolver::Resolver() {}
34
35Resolver::~Resolver() {}
36
37Resolver* Resolver::GetInstance() {
Paul Stewart0d2ada32011-08-09 17:01:57 -070038 return g_resolver.Pointer();
Paul Stewartb6063942011-08-05 10:17:29 -070039}
40
Paul Stewartbf667612012-06-29 14:49:54 -070041bool Resolver::SetDNSFromIPConfig(const IPConfigRefPtr &ipconfig,
42 TimeoutParameters timeout) {
Ben Chanfad4a0b2012-04-18 15:49:59 -070043 SLOG(Resolver, 2) << __func__;
Paul Stewarte6132022011-08-16 09:11:02 -070044
Paul Stewartb6063942011-08-05 10:17:29 -070045 CHECK(!path_.empty());
46
47 const IPConfig::Properties &props = ipconfig->properties();
48
Paul Stewartbf667612012-06-29 14:49:54 -070049 return SetDNSFromLists(props.dns_servers, props.domain_search, timeout);
Paul Stewartdd60e452011-08-08 11:38:36 -070050}
51
52bool Resolver::SetDNSFromLists(const std::vector<std::string> &dns_servers,
Paul Stewartbf667612012-06-29 14:49:54 -070053 const std::vector<std::string> &domain_search,
54 TimeoutParameters timeout) {
Ben Chanfad4a0b2012-04-18 15:49:59 -070055 SLOG(Resolver, 2) << __func__;
Paul Stewarte6132022011-08-16 09:11:02 -070056
Paul Stewartdd60e452011-08-08 11:38:36 -070057 if (dns_servers.empty() && domain_search.empty()) {
Ben Chanfad4a0b2012-04-18 15:49:59 -070058 SLOG(Resolver, 2) << "DNS list is empty";
Paul Stewartb6063942011-08-05 10:17:29 -070059 return ClearDNS();
60 }
61
62 vector<string> lines;
63 vector<string>::const_iterator iter;
Paul Stewartdd60e452011-08-08 11:38:36 -070064 for (iter = dns_servers.begin();
65 iter != dns_servers.end(); ++iter) {
Paul Stewartb6063942011-08-05 10:17:29 -070066 lines.push_back("nameserver " + *iter);
67 }
68
Paul Stewartdd60e452011-08-08 11:38:36 -070069 if (!domain_search.empty()) {
70 lines.push_back("search " + JoinString(domain_search, ' '));
Paul Stewartb6063942011-08-05 10:17:29 -070071 }
72
Thieu Le3bd0faa2012-02-15 15:44:46 -080073 // Send queries one-at-a-time, rather than parallelizing IPv4
Paul Stewartabc41aa2012-04-07 13:15:37 -070074 // and IPv6 queries for a single host. Also override the default
Paul Stewartbf667612012-06-29 14:49:54 -070075 // 5-second request timeout and 2 retries.
76 if (timeout == kDefaultTimeout) {
77 lines.push_back(kDefaultTimeoutOptions);
78 } else if (timeout == kShortTimeout) {
79 lines.push_back(kShortTimeoutOptions);
80 } else {
81 NOTIMPLEMENTED() << "Unknown Resolver timeout parameters";
82 }
Thieu Le3bd0faa2012-02-15 15:44:46 -080083
Paul Stewartb6063942011-08-05 10:17:29 -070084 // Newline at end of file
85 lines.push_back("");
86
87 string contents = JoinString(lines, '\n');
Paul Stewarte6132022011-08-16 09:11:02 -070088
Ben Chanfad4a0b2012-04-18 15:49:59 -070089 SLOG(Resolver, 2) << "Writing DNS out to " << path_.value();
Paul Stewartb6063942011-08-05 10:17:29 -070090 int count = file_util::WriteFile(path_, contents.c_str(), contents.size());
91
92 return count == static_cast<int>(contents.size());
93}
94
95bool Resolver::ClearDNS() {
Ben Chanfad4a0b2012-04-18 15:49:59 -070096 SLOG(Resolver, 2) << __func__;
Paul Stewarte6132022011-08-16 09:11:02 -070097
Paul Stewartb6063942011-08-05 10:17:29 -070098 CHECK(!path_.empty());
99
100 return file_util::Delete(path_, false);
101}
102
103} // namespace shill