| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/host_resolver.h" | 5 #include "net/base/host_resolver.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <ws2tcpip.h> | 8 #include <ws2tcpip.h> |
| 9 #include <wspiapi.h> // Needed for Win2k compat. | 9 #include <wspiapi.h> // Needed for Win2k compat. |
| 10 #elif defined(OS_POSIX) | 10 #elif defined(OS_POSIX) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #if defined(OS_WIN) | 21 #if defined(OS_WIN) |
| 22 #include "net/base/winsock_init.h" | 22 #include "net/base/winsock_init.h" |
| 23 #endif | 23 #endif |
| 24 | 24 |
| 25 namespace net { | 25 namespace net { |
| 26 | 26 |
| 27 //----------------------------------------------------------------------------- | 27 //----------------------------------------------------------------------------- |
| 28 | 28 |
| 29 static HostMapper* host_mapper; | 29 static HostMapper* host_mapper; |
| 30 | 30 |
| 31 std::string HostMapper::MapUsingPrevious(const std::string& host) { |
| 32 return previous_mapper_.get() ? previous_mapper_->Map(host) : host; |
| 33 } |
| 34 |
| 31 HostMapper* SetHostMapper(HostMapper* value) { | 35 HostMapper* SetHostMapper(HostMapper* value) { |
| 32 std::swap(host_mapper, value); | 36 std::swap(host_mapper, value); |
| 33 return value; | 37 return value; |
| 34 } | 38 } |
| 35 | 39 |
| 36 static int HostResolverProc( | 40 static int HostResolverProc( |
| 37 const std::string& host, const std::string& port, struct addrinfo** out) { | 41 const std::string& host, const std::string& port, struct addrinfo** out) { |
| 38 struct addrinfo hints = {0}; | 42 struct addrinfo hints = {0}; |
| 39 hints.ai_family = PF_UNSPEC; | 43 hints.ai_family = PF_UNSPEC; |
| 40 hints.ai_flags = AI_ADDRCONFIG; | 44 hints.ai_flags = AI_ADDRCONFIG; |
| 41 | 45 |
| 42 // Restrict result set to only this socket type to avoid duplicates. | 46 // Restrict result set to only this socket type to avoid duplicates. |
| 43 hints.ai_socktype = SOCK_STREAM; | 47 hints.ai_socktype = SOCK_STREAM; |
| 44 | 48 |
| 45 int err = getaddrinfo(host.c_str(), port.c_str(), &hints, out); | 49 int err = getaddrinfo(host.c_str(), port.c_str(), &hints, out); |
| 46 return err ? ERR_NAME_NOT_RESOLVED : OK; | 50 return err ? ERR_NAME_NOT_RESOLVED : OK; |
| 47 } | 51 } |
| 48 | 52 |
| 49 static int ResolveAddrInfo( | 53 static int ResolveAddrInfo(HostMapper* mapper, const std::string& host, |
| 50 const std::string& host, const std::string& port, struct addrinfo** out) { | 54 const std::string& port, struct addrinfo** out) { |
| 51 int rv; | 55 int rv; |
| 52 if (host_mapper) { | 56 if (mapper) { |
| 53 rv = HostResolverProc(host_mapper->Map(host), port, out); | 57 rv = HostResolverProc(mapper->Map(host), port, out); |
| 54 } else { | 58 } else { |
| 55 rv = HostResolverProc(host, port, out); | 59 rv = HostResolverProc(host, port, out); |
| 56 } | 60 } |
| 57 return rv; | 61 return rv; |
| 58 } | 62 } |
| 59 | 63 |
| 60 //----------------------------------------------------------------------------- | 64 //----------------------------------------------------------------------------- |
| 61 | 65 |
| 62 class HostResolver::Request : | 66 class HostResolver::Request : |
| 63 public base::RefCountedThreadSafe<HostResolver::Request> { | 67 public base::RefCountedThreadSafe<HostResolver::Request> { |
| 64 public: | 68 public: |
| 65 Request(HostResolver* resolver, | 69 Request(HostResolver* resolver, |
| 66 const std::string& host, | 70 const std::string& host, |
| 67 const std::string& port, | 71 const std::string& port, |
| 68 AddressList* addresses, | 72 AddressList* addresses, |
| 69 CompletionCallback* callback) | 73 CompletionCallback* callback) |
| 70 : host_(host), | 74 : host_(host), |
| 71 port_(port), | 75 port_(port), |
| 72 resolver_(resolver), | 76 resolver_(resolver), |
| 73 addresses_(addresses), | 77 addresses_(addresses), |
| 74 callback_(callback), | 78 callback_(callback), |
| 75 origin_loop_(MessageLoop::current()), | 79 origin_loop_(MessageLoop::current()), |
| 80 host_mapper_(host_mapper), |
| 76 error_(OK), | 81 error_(OK), |
| 77 results_(NULL) { | 82 results_(NULL) { |
| 78 } | 83 } |
| 79 | 84 |
| 80 ~Request() { | 85 ~Request() { |
| 81 if (results_) | 86 if (results_) |
| 82 freeaddrinfo(results_); | 87 freeaddrinfo(results_); |
| 83 } | 88 } |
| 84 | 89 |
| 85 void DoLookup() { | 90 void DoLookup() { |
| 86 // Running on the worker thread | 91 // Running on the worker thread |
| 87 error_ = ResolveAddrInfo(host_, port_, &results_); | 92 error_ = ResolveAddrInfo(host_mapper_, host_, port_, &results_); |
| 88 | 93 |
| 89 Task* reply = NewRunnableMethod(this, &Request::DoCallback); | 94 Task* reply = NewRunnableMethod(this, &Request::DoCallback); |
| 90 | 95 |
| 91 // The origin loop could go away while we are trying to post to it, so we | 96 // The origin loop could go away while we are trying to post to it, so we |
| 92 // need to call its PostTask method inside a lock. See ~HostResolver. | 97 // need to call its PostTask method inside a lock. See ~HostResolver. |
| 93 { | 98 { |
| 94 AutoLock locked(origin_loop_lock_); | 99 AutoLock locked(origin_loop_lock_); |
| 95 if (origin_loop_) { | 100 if (origin_loop_) { |
| 96 origin_loop_->PostTask(FROM_HERE, reply); | 101 origin_loop_->PostTask(FROM_HERE, reply); |
| 97 reply = NULL; | 102 reply = NULL; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 | 142 |
| 138 // Only used on the origin thread (where Resolve was called). | 143 // Only used on the origin thread (where Resolve was called). |
| 139 HostResolver* resolver_; | 144 HostResolver* resolver_; |
| 140 AddressList* addresses_; | 145 AddressList* addresses_; |
| 141 CompletionCallback* callback_; | 146 CompletionCallback* callback_; |
| 142 | 147 |
| 143 // Used to post ourselves onto the origin thread. | 148 // Used to post ourselves onto the origin thread. |
| 144 Lock origin_loop_lock_; | 149 Lock origin_loop_lock_; |
| 145 MessageLoop* origin_loop_; | 150 MessageLoop* origin_loop_; |
| 146 | 151 |
| 152 // Hold an owning reference to the host mapper that we are going to use. |
| 153 // This may not be the current host mapper by the time we call |
| 154 // ResolveAddrInfo, but that's OK... we'll use it anyways, and the owning |
| 155 // reference ensures that it remains valid until we are done. |
| 156 scoped_refptr<HostMapper> host_mapper_; |
| 157 |
| 147 // Assigned on the worker thread, read on the origin thread. | 158 // Assigned on the worker thread, read on the origin thread. |
| 148 int error_; | 159 int error_; |
| 149 struct addrinfo* results_; | 160 struct addrinfo* results_; |
| 150 }; | 161 }; |
| 151 | 162 |
| 152 //----------------------------------------------------------------------------- | 163 //----------------------------------------------------------------------------- |
| 153 | 164 |
| 154 HostResolver::HostResolver() { | 165 HostResolver::HostResolver() { |
| 155 #if defined(OS_WIN) | 166 #if defined(OS_WIN) |
| 156 EnsureWinsockInit(); | 167 EnsureWinsockInit(); |
| 157 #endif | 168 #endif |
| 158 } | 169 } |
| 159 | 170 |
| 160 HostResolver::~HostResolver() { | 171 HostResolver::~HostResolver() { |
| 161 if (request_) | 172 if (request_) |
| 162 request_->Cancel(); | 173 request_->Cancel(); |
| 163 } | 174 } |
| 164 | 175 |
| 165 int HostResolver::Resolve(const std::string& hostname, int port, | 176 int HostResolver::Resolve(const std::string& hostname, int port, |
| 166 AddressList* addresses, | 177 AddressList* addresses, |
| 167 CompletionCallback* callback) { | 178 CompletionCallback* callback) { |
| 168 DCHECK(!request_) << "resolver already in use"; | 179 DCHECK(!request_) << "resolver already in use"; |
| 169 | 180 |
| 170 const std::string& port_str = IntToString(port); | 181 const std::string& port_str = IntToString(port); |
| 171 | 182 |
| 172 // Do a synchronous resolution. | 183 // Do a synchronous resolution. |
| 173 if (!callback) { | 184 if (!callback) { |
| 174 struct addrinfo* results; | 185 struct addrinfo* results; |
| 175 int rv = ResolveAddrInfo(hostname, port_str, &results); | 186 int rv = ResolveAddrInfo(host_mapper, hostname, port_str, &results); |
| 176 if (rv == OK) | 187 if (rv == OK) |
| 177 addresses->Adopt(results); | 188 addresses->Adopt(results); |
| 178 return rv; | 189 return rv; |
| 179 } | 190 } |
| 180 | 191 |
| 181 request_ = new Request(this, hostname, port_str, addresses, callback); | 192 request_ = new Request(this, hostname, port_str, addresses, callback); |
| 182 | 193 |
| 183 // Dispatch to worker thread... | 194 // Dispatch to worker thread... |
| 184 if (!WorkerPool::PostTask(FROM_HERE, | 195 if (!WorkerPool::PostTask(FROM_HERE, |
| 185 NewRunnableMethod(request_.get(), &Request::DoLookup), true)) { | 196 NewRunnableMethod(request_.get(), &Request::DoLookup), true)) { |
| 186 NOTREACHED(); | 197 NOTREACHED(); |
| 187 request_ = NULL; | 198 request_ = NULL; |
| 188 return ERR_FAILED; | 199 return ERR_FAILED; |
| 189 } | 200 } |
| 190 | 201 |
| 191 return ERR_IO_PENDING; | 202 return ERR_IO_PENDING; |
| 192 } | 203 } |
| 193 | 204 |
| 194 } // namespace net | 205 } // namespace net |
| OLD | NEW |