Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(332)

Side by Side Diff: net/dns/dns_config_service_posix.cc

Issue 7518028: DnsConfigService and a posix implementation (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: fixed lint Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <resolv.h>
6
7 #include "base/compiler_specific.h"
8 #include "base/file_path.h"
9 #include "base/files/file_path_watcher.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/message_loop.h"
12 #include "base/message_loop_proxy.h"
13 #include "base/scoped_ptr.h"
14 #include "base/task.h"
15 #include "base/threading/worker_pool.h"
16 #include "net/base/ip_endpoint.h"
17 #include "net/base/net_util.h"
18 #include "net/dns/dns_config_service.h"
19
20 namespace net {
21
22 using base::files::FilePathWatcher;
23
24 class DnsConfigReaderPosix : public DnsConfigReader {
25 public:
26 bool Read(DnsConfig* dns_config) OVERRIDE {
27 // res_ninit is available on Linux (glibc 2+), Mac OS X, and Android.
28 // TODO(szym): res_ninit is not thread-safe on BSD?
29 struct __res_state res;
30 if (res_ninit(&res) != 0)
cbentzel 2011/08/01 19:52:26 Assuming that it's a newly constructed DnsConfig o
szym 2011/08/01 20:22:01 I'm not sure this is a safe general assumption. It
31 return false;
32
33 dns_config->nameservers.clear();
34 for (int i = 0; i < res.nscount; ++i) {
35 IPEndPoint ipe;
36 if (ipe.FromSockAddr(
37 reinterpret_cast<struct sockaddr*>(&res.nsaddr_list[i]),
38 sizeof res.nsaddr_list[i]))
39 dns_config->nameservers.push_back(ipe);
40 }
41
42 dns_config->search.clear();
43 for (int i = 0; (i < MAXDNSRCH) && *res.dnsrch[i]; ++i) {
44 dns_config->search.push_back(std::string(res.dnsrch[i]));
45 }
46
47 dns_config->domain = res.defdname; // use only if |search| is empty
48 dns_config->ndots = res.ndots;
49 dns_config->timeout = res.retrans;
50 dns_config->attempts = res.retry;
51 dns_config->rotate = res.options & RES_ROTATE;
52 dns_config->edns0 = res.options & RES_USE_EDNS0;
53 return true;
54 }
55 };
56
57 // NOTE: this makes it ref counted thread-safe
58 class DnsConfigServicePosix : public DnsConfigService,
cbentzel 2011/08/01 19:52:26 Is this compiling? Doesn't it need to be derived f
szym 2011/08/01 20:22:01 It is compiling. Is that an error? Is it safe to a
59 public FilePathWatcher::Delegate {
60 public:
61 DnsConfigServicePosix() {}
62 virtual ~DnsConfigServicePosix() {}
63 virtual bool Watch(DnsConfigService::Delegate* delegate) OVERRIDE;
64
65 private:
66 // TODO(szym): convert Task -> Closure?
67
68 // called on the worker thread
69 // reads DnsConfig and posts OnResultAvailable to |message_loop|
70 void ReadConfig(scoped_refptr<base::MessageLoopProxy> message_loop);
71
72 // called on the delegate's thread
73 // communicates result from DnsConfigReader to the delegate
74 void OnResultAvailable(const DnsConfig &config, bool error);
75
76 // FilePathWatcher::Delegate interface
77 virtual void OnFilePathChanged(const FilePath& path) OVERRIDE;
78
79 virtual void OnFilePathError(const FilePath& path) OVERRIDE {
80 delegate_->OnConfigError();
81 }
82
83 // message loop for the thread on which Watch is called
84 // this should be an IO loop
85 scoped_refptr<base::MessageLoopProxy> message_loop_;
86 scoped_ptr<FilePathWatcher> resolv_file_watcher_;
87 DnsConfigService::Delegate* delegate_;
88 DnsConfig last_config_;
89 };
90
91 bool DnsConfigServicePosix::Watch(DnsConfigService::Delegate* delegate) {
92 DCHECK(!resolv_file_watcher_.get());
93 DCHECK(MessageLoopForIO::current());
94
cbentzel 2011/08/01 19:52:26 Should probably DCHECK that delegate_ is NULL.
szym 2011/08/01 20:22:01 Done.
95 message_loop_ = base::MessageLoopProxy::CreateForCurrentThread();
96 delegate_ = delegate;
97
98 // start FilePathWatcher
99 resolv_file_watcher_.reset(new FilePathWatcher());
100 return resolv_file_watcher_->Watch(
101 FilePath(FILE_PATH_LITERAL("/etc/resolv.conf")),
102 this
103 );
104 }
105
106 void DnsConfigServicePosix::ReadConfig(
107 scoped_refptr<base::MessageLoopProxy> message_loop) {
108 // on the WorkerPool
109 DnsConfigReaderPosix reader;
110 DnsConfig config;
111 bool error = reader.Read(&config);
112 message_loop->PostTask(FROM_HERE, NewRunnableMethod(
113 this, &DnsConfigServicePosix::OnResultAvailable, config, error));
114 }
115
116 void DnsConfigServicePosix::OnResultAvailable(const DnsConfig &config,
117 bool error) {
118 if (error) {
119 delegate_->OnConfigError();
120 } else if (config != last_config_) {
121 delegate_->OnConfigChanged(config);
122 last_config_ = config;
123 }
124 }
125
126 // FilePathWatcher::Delegate interface
127 void DnsConfigServicePosix::OnFilePathChanged(const FilePath& path) {
128 DCHECK(MessageLoopForIO::current());
129 // we should be on the same thread that called Watch so delegate should
130 // still exist?
131 if (!base::WorkerPool::PostTask(FROM_HERE, NewRunnableMethod(
132 this, &DnsConfigServicePosix::ReadConfig, message_loop_), false)) {
133 delegate_->OnConfigError();
134 }
135 }
136
137 DnsConfigService* DnsConfigService::CreateSystemService() {
138 return new DnsConfigServicePosix();
139 }
140 }
141
OLDNEW
« net/dns/dns_config_service.h ('K') | « net/dns/dns_config_service.h ('k') | net/net.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698