| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/dns/dns_config_service_posix.h" | 5 #include "net/dns/dns_config_service_posix.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 FILE_PATH_LITERAL("/system/etc/hosts"); | 44 FILE_PATH_LITERAL("/system/etc/hosts"); |
| 45 #endif | 45 #endif |
| 46 | 46 |
| 47 #if defined(OS_IOS) | 47 #if defined(OS_IOS) |
| 48 | 48 |
| 49 // There is no public API to watch the DNS configuration on iOS. | 49 // There is no public API to watch the DNS configuration on iOS. |
| 50 class DnsConfigWatcher { | 50 class DnsConfigWatcher { |
| 51 public: | 51 public: |
| 52 typedef base::Callback<void(bool succeeded)> CallbackType; | 52 typedef base::Callback<void(bool succeeded)> CallbackType; |
| 53 | 53 |
| 54 bool Watch(const CallbackType& callback) { | 54 bool Watch(const CallbackType& callback) { return false; } |
| 55 return false; | |
| 56 } | |
| 57 }; | 55 }; |
| 58 | 56 |
| 59 #elif defined(OS_ANDROID) | 57 #elif defined(OS_ANDROID) |
| 60 // On Android, assume DNS config may have changed on every network change. | 58 // On Android, assume DNS config may have changed on every network change. |
| 61 class DnsConfigWatcher : public NetworkChangeNotifier::NetworkChangeObserver { | 59 class DnsConfigWatcher : public NetworkChangeNotifier::NetworkChangeObserver { |
| 62 public: | 60 public: |
| 63 DnsConfigWatcher() { | 61 DnsConfigWatcher() { NetworkChangeNotifier::AddNetworkChangeObserver(this); } |
| 64 NetworkChangeNotifier::AddNetworkChangeObserver(this); | |
| 65 } | |
| 66 | 62 |
| 67 virtual ~DnsConfigWatcher() { | 63 virtual ~DnsConfigWatcher() { |
| 68 NetworkChangeNotifier::RemoveNetworkChangeObserver(this); | 64 NetworkChangeNotifier::RemoveNetworkChangeObserver(this); |
| 69 } | 65 } |
| 70 | 66 |
| 71 bool Watch(const base::Callback<void(bool succeeded)>& callback) { | 67 bool Watch(const base::Callback<void(bool succeeded)>& callback) { |
| 72 callback_ = callback; | 68 callback_ = callback; |
| 73 return true; | 69 return true; |
| 74 } | 70 } |
| 75 | 71 |
| 76 virtual void OnNetworkChanged(NetworkChangeNotifier::ConnectionType type) | 72 virtual void OnNetworkChanged( |
| 77 OVERRIDE { | 73 NetworkChangeNotifier::ConnectionType type) OVERRIDE { |
| 78 if (!callback_.is_null() && type != NetworkChangeNotifier::CONNECTION_NONE) | 74 if (!callback_.is_null() && type != NetworkChangeNotifier::CONNECTION_NONE) |
| 79 callback_.Run(true); | 75 callback_.Run(true); |
| 80 } | 76 } |
| 81 | 77 |
| 82 private: | 78 private: |
| 83 base::Callback<void(bool succeeded)> callback_; | 79 base::Callback<void(bool succeeded)> callback_; |
| 84 }; | 80 }; |
| 85 #elif !defined(OS_MACOSX) | 81 #elif !defined(OS_MACOSX) |
| 86 // DnsConfigWatcher for OS_MACOSX is in dns_config_watcher_mac.{hh,cc}. | 82 // DnsConfigWatcher for OS_MACOSX is in dns_config_watcher_mac.{hh,cc}. |
| 87 | 83 |
| 88 #ifndef _PATH_RESCONF // Normally defined in <resolv.h> | 84 #ifndef _PATH_RESCONF // Normally defined in <resolv.h> |
| 89 #define _PATH_RESCONF "/etc/resolv.conf" | 85 #define _PATH_RESCONF "/etc/resolv.conf" |
| 90 #endif | 86 #endif |
| 91 | 87 |
| 92 static const base::FilePath::CharType* kFilePathConfig = | 88 static const base::FilePath::CharType* kFilePathConfig = |
| 93 FILE_PATH_LITERAL(_PATH_RESCONF); | 89 FILE_PATH_LITERAL(_PATH_RESCONF); |
| 94 | 90 |
| 95 class DnsConfigWatcher { | 91 class DnsConfigWatcher { |
| 96 public: | 92 public: |
| 97 typedef base::Callback<void(bool succeeded)> CallbackType; | 93 typedef base::Callback<void(bool succeeded)> CallbackType; |
| 98 | 94 |
| 99 bool Watch(const CallbackType& callback) { | 95 bool Watch(const CallbackType& callback) { |
| 100 callback_ = callback; | 96 callback_ = callback; |
| 101 return watcher_.Watch(base::FilePath(kFilePathConfig), false, | 97 return watcher_.Watch( |
| 102 base::Bind(&DnsConfigWatcher::OnCallback, | 98 base::FilePath(kFilePathConfig), |
| 103 base::Unretained(this))); | 99 false, |
| 100 base::Bind(&DnsConfigWatcher::OnCallback, base::Unretained(this))); |
| 104 } | 101 } |
| 105 | 102 |
| 106 private: | 103 private: |
| 107 void OnCallback(const base::FilePath& path, bool error) { | 104 void OnCallback(const base::FilePath& path, bool error) { |
| 108 callback_.Run(!error); | 105 callback_.Run(!error); |
| 109 } | 106 } |
| 110 | 107 |
| 111 base::FilePathWatcher watcher_; | 108 base::FilePathWatcher watcher_; |
| 112 CallbackType callback_; | 109 CallbackType callback_; |
| 113 }; | 110 }; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 127 result = CONFIG_PARSE_POSIX_RES_INIT_FAILED; | 124 result = CONFIG_PARSE_POSIX_RES_INIT_FAILED; |
| 128 } | 125 } |
| 129 #else // all other OS_POSIX | 126 #else // all other OS_POSIX |
| 130 struct __res_state res; | 127 struct __res_state res; |
| 131 memset(&res, 0, sizeof(res)); | 128 memset(&res, 0, sizeof(res)); |
| 132 if (res_ninit(&res) == 0) { | 129 if (res_ninit(&res) == 0) { |
| 133 result = ConvertResStateToDnsConfig(res, config); | 130 result = ConvertResStateToDnsConfig(res, config); |
| 134 } else { | 131 } else { |
| 135 result = CONFIG_PARSE_POSIX_RES_INIT_FAILED; | 132 result = CONFIG_PARSE_POSIX_RES_INIT_FAILED; |
| 136 } | 133 } |
| 137 // Prefer res_ndestroy where available. | 134 // Prefer res_ndestroy where available. |
| 138 #if defined(OS_MACOSX) || defined(OS_FREEBSD) | 135 #if defined(OS_MACOSX) || defined(OS_FREEBSD) |
| 139 res_ndestroy(&res); | 136 res_ndestroy(&res); |
| 140 #else | 137 #else |
| 141 res_nclose(&res); | 138 res_nclose(&res); |
| 142 #endif | 139 #endif |
| 143 #endif | 140 #endif |
| 144 | 141 |
| 145 #if defined(OS_MACOSX) && !defined(OS_IOS) | 142 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 146 ConfigParsePosixResult error = DnsConfigWatcher::CheckDnsConfig(); | 143 ConfigParsePosixResult error = DnsConfigWatcher::CheckDnsConfig(); |
| 147 switch (error) { | 144 switch (error) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 162 // Theoretically, this is bad. __system_property_get is not a supported API | 159 // Theoretically, this is bad. __system_property_get is not a supported API |
| 163 // (but it's currently visible to anyone using Bionic), and the properties | 160 // (but it's currently visible to anyone using Bionic), and the properties |
| 164 // are implementation details that may disappear in future Android releases. | 161 // are implementation details that may disappear in future Android releases. |
| 165 // Practically, libcutils provides property_get, which is a public API, and the | 162 // Practically, libcutils provides property_get, which is a public API, and the |
| 166 // DNS code (and its clients) are already robust against failing to get the DNS | 163 // DNS code (and its clients) are already robust against failing to get the DNS |
| 167 // config for whatever reason, so the properties can disappear and the world | 164 // config for whatever reason, so the properties can disappear and the world |
| 168 // won't end. | 165 // won't end. |
| 169 // TODO(ttuttle): Depend on libcutils, then switch this (and other uses of | 166 // TODO(ttuttle): Depend on libcutils, then switch this (and other uses of |
| 170 // __system_property_get) to property_get. | 167 // __system_property_get) to property_get. |
| 171 ConfigParsePosixResult ReadDnsConfig(DnsConfig* dns_config) { | 168 ConfigParsePosixResult ReadDnsConfig(DnsConfig* dns_config) { |
| 172 std::string dns1_string, dns2_string; | 169 std::string dns1_string, dns2_string; |
| 173 char property_value[PROP_VALUE_MAX]; | 170 char property_value[PROP_VALUE_MAX]; |
| 174 __system_property_get("net.dns1", property_value); | 171 __system_property_get("net.dns1", property_value); |
| 175 dns1_string = property_value; | 172 dns1_string = property_value; |
| 176 __system_property_get("net.dns2", property_value); | 173 __system_property_get("net.dns2", property_value); |
| 177 dns2_string = property_value; | 174 dns2_string = property_value; |
| 178 if (dns1_string.length() == 0 && dns2_string.length() == 0) | 175 if (dns1_string.length() == 0 && dns2_string.length() == 0) |
| 179 return CONFIG_PARSE_POSIX_NO_NAMESERVERS; | 176 return CONFIG_PARSE_POSIX_NO_NAMESERVERS; |
| 180 | 177 |
| 181 IPAddressNumber dns1_number, dns2_number; | 178 IPAddressNumber dns1_number, dns2_number; |
| 182 bool parsed1 = ParseIPLiteralToNumber(dns1_string, &dns1_number); | 179 bool parsed1 = ParseIPLiteralToNumber(dns1_string, &dns1_number); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 195 | 192 |
| 196 return CONFIG_PARSE_POSIX_OK; | 193 return CONFIG_PARSE_POSIX_OK; |
| 197 } | 194 } |
| 198 #endif | 195 #endif |
| 199 | 196 |
| 200 } // namespace | 197 } // namespace |
| 201 | 198 |
| 202 class DnsConfigServicePosix::Watcher { | 199 class DnsConfigServicePosix::Watcher { |
| 203 public: | 200 public: |
| 204 explicit Watcher(DnsConfigServicePosix* service) | 201 explicit Watcher(DnsConfigServicePosix* service) |
| 205 : weak_factory_(this), | 202 : weak_factory_(this), service_(service) {} |
| 206 service_(service) {} | |
| 207 ~Watcher() {} | 203 ~Watcher() {} |
| 208 | 204 |
| 209 bool Watch() { | 205 bool Watch() { |
| 210 bool success = true; | 206 bool success = true; |
| 211 if (!config_watcher_.Watch(base::Bind(&Watcher::OnConfigChanged, | 207 if (!config_watcher_.Watch( |
| 212 base::Unretained(this)))) { | 208 base::Bind(&Watcher::OnConfigChanged, base::Unretained(this)))) { |
| 213 LOG(ERROR) << "DNS config watch failed to start."; | 209 LOG(ERROR) << "DNS config watch failed to start."; |
| 214 success = false; | 210 success = false; |
| 215 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus", | 211 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus", |
| 216 DNS_CONFIG_WATCH_FAILED_TO_START_CONFIG, | 212 DNS_CONFIG_WATCH_FAILED_TO_START_CONFIG, |
| 217 DNS_CONFIG_WATCH_MAX); | 213 DNS_CONFIG_WATCH_MAX); |
| 218 } | 214 } |
| 219 if (!hosts_watcher_.Watch(base::FilePath(kFilePathHosts), false, | 215 if (!hosts_watcher_.Watch( |
| 220 base::Bind(&Watcher::OnHostsChanged, | 216 base::FilePath(kFilePathHosts), |
| 221 base::Unretained(this)))) { | 217 false, |
| 218 base::Bind(&Watcher::OnHostsChanged, base::Unretained(this)))) { |
| 222 LOG(ERROR) << "DNS hosts watch failed to start."; | 219 LOG(ERROR) << "DNS hosts watch failed to start."; |
| 223 success = false; | 220 success = false; |
| 224 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus", | 221 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus", |
| 225 DNS_CONFIG_WATCH_FAILED_TO_START_HOSTS, | 222 DNS_CONFIG_WATCH_FAILED_TO_START_HOSTS, |
| 226 DNS_CONFIG_WATCH_MAX); | 223 DNS_CONFIG_WATCH_MAX); |
| 227 } | 224 } |
| 228 return success; | 225 return success; |
| 229 } | 226 } |
| 230 | 227 |
| 231 private: | 228 private: |
| (...skipping 30 matching lines...) Expand all Loading... |
| 262 explicit ConfigReader(DnsConfigServicePosix* service) | 259 explicit ConfigReader(DnsConfigServicePosix* service) |
| 263 : service_(service), success_(false) {} | 260 : service_(service), success_(false) {} |
| 264 | 261 |
| 265 virtual void DoWork() OVERRIDE { | 262 virtual void DoWork() OVERRIDE { |
| 266 base::TimeTicks start_time = base::TimeTicks::Now(); | 263 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 267 ConfigParsePosixResult result = ReadDnsConfig(&dns_config_); | 264 ConfigParsePosixResult result = ReadDnsConfig(&dns_config_); |
| 268 switch (result) { | 265 switch (result) { |
| 269 case CONFIG_PARSE_POSIX_MISSING_OPTIONS: | 266 case CONFIG_PARSE_POSIX_MISSING_OPTIONS: |
| 270 case CONFIG_PARSE_POSIX_UNHANDLED_OPTIONS: | 267 case CONFIG_PARSE_POSIX_UNHANDLED_OPTIONS: |
| 271 DCHECK(dns_config_.unhandled_options); | 268 DCHECK(dns_config_.unhandled_options); |
| 272 // Fall through. | 269 // Fall through. |
| 273 case CONFIG_PARSE_POSIX_OK: | 270 case CONFIG_PARSE_POSIX_OK: |
| 274 success_ = true; | 271 success_ = true; |
| 275 break; | 272 break; |
| 276 default: | 273 default: |
| 277 success_ = false; | 274 success_ = false; |
| 278 break; | 275 break; |
| 279 } | 276 } |
| 280 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ConfigParsePosix", | 277 UMA_HISTOGRAM_ENUMERATION( |
| 281 result, CONFIG_PARSE_POSIX_MAX); | 278 "AsyncDNS.ConfigParsePosix", result, CONFIG_PARSE_POSIX_MAX); |
| 282 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.ConfigParseResult", success_); | 279 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.ConfigParseResult", success_); |
| 283 UMA_HISTOGRAM_TIMES("AsyncDNS.ConfigParseDuration", | 280 UMA_HISTOGRAM_TIMES("AsyncDNS.ConfigParseDuration", |
| 284 base::TimeTicks::Now() - start_time); | 281 base::TimeTicks::Now() - start_time); |
| 285 } | 282 } |
| 286 | 283 |
| 287 virtual void OnWorkFinished() OVERRIDE { | 284 virtual void OnWorkFinished() OVERRIDE { |
| 288 DCHECK(!IsCancelled()); | 285 DCHECK(!IsCancelled()); |
| 289 if (success_) { | 286 if (success_) { |
| 290 service_->OnConfigRead(dns_config_); | 287 service_->OnConfigRead(dns_config_); |
| 291 } else { | 288 } else { |
| 292 LOG(WARNING) << "Failed to read DnsConfig."; | 289 LOG(WARNING) << "Failed to read DnsConfig."; |
| 293 } | 290 } |
| 294 } | 291 } |
| 295 | 292 |
| 296 private: | 293 private: |
| 297 virtual ~ConfigReader() {} | 294 virtual ~ConfigReader() {} |
| 298 | 295 |
| 299 DnsConfigServicePosix* service_; | 296 DnsConfigServicePosix* service_; |
| 300 // Written in DoWork, read in OnWorkFinished, no locking necessary. | 297 // Written in DoWork, read in OnWorkFinished, no locking necessary. |
| 301 DnsConfig dns_config_; | 298 DnsConfig dns_config_; |
| 302 bool success_; | 299 bool success_; |
| 303 | 300 |
| 304 DISALLOW_COPY_AND_ASSIGN(ConfigReader); | 301 DISALLOW_COPY_AND_ASSIGN(ConfigReader); |
| 305 }; | 302 }; |
| 306 | 303 |
| 307 // A SerialWorker that reads the HOSTS file and runs Callback. | 304 // A SerialWorker that reads the HOSTS file and runs Callback. |
| 308 class DnsConfigServicePosix::HostsReader : public SerialWorker { | 305 class DnsConfigServicePosix::HostsReader : public SerialWorker { |
| 309 public: | 306 public: |
| 310 explicit HostsReader(DnsConfigServicePosix* service) | 307 explicit HostsReader(DnsConfigServicePosix* service) |
| 311 : service_(service), path_(kFilePathHosts), success_(false) {} | 308 : service_(service), path_(kFilePathHosts), success_(false) {} |
| 312 | 309 |
| 313 private: | 310 private: |
| 314 virtual ~HostsReader() {} | 311 virtual ~HostsReader() {} |
| 315 | 312 |
| 316 virtual void DoWork() OVERRIDE { | 313 virtual void DoWork() OVERRIDE { |
| 317 base::TimeTicks start_time = base::TimeTicks::Now(); | 314 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 318 success_ = ParseHostsFile(path_, &hosts_); | 315 success_ = ParseHostsFile(path_, &hosts_); |
| 319 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HostParseResult", success_); | 316 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HostParseResult", success_); |
| 320 UMA_HISTOGRAM_TIMES("AsyncDNS.HostsParseDuration", | 317 UMA_HISTOGRAM_TIMES("AsyncDNS.HostsParseDuration", |
| 321 base::TimeTicks::Now() - start_time); | 318 base::TimeTicks::Now() - start_time); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 333 const base::FilePath path_; | 330 const base::FilePath path_; |
| 334 // Written in DoWork, read in OnWorkFinished, no locking necessary. | 331 // Written in DoWork, read in OnWorkFinished, no locking necessary. |
| 335 DnsHosts hosts_; | 332 DnsHosts hosts_; |
| 336 bool success_; | 333 bool success_; |
| 337 | 334 |
| 338 DISALLOW_COPY_AND_ASSIGN(HostsReader); | 335 DISALLOW_COPY_AND_ASSIGN(HostsReader); |
| 339 }; | 336 }; |
| 340 | 337 |
| 341 DnsConfigServicePosix::DnsConfigServicePosix() | 338 DnsConfigServicePosix::DnsConfigServicePosix() |
| 342 : config_reader_(new ConfigReader(this)), | 339 : config_reader_(new ConfigReader(this)), |
| 343 hosts_reader_(new HostsReader(this)) {} | 340 hosts_reader_(new HostsReader(this)) { |
| 341 } |
| 344 | 342 |
| 345 DnsConfigServicePosix::~DnsConfigServicePosix() { | 343 DnsConfigServicePosix::~DnsConfigServicePosix() { |
| 346 config_reader_->Cancel(); | 344 config_reader_->Cancel(); |
| 347 hosts_reader_->Cancel(); | 345 hosts_reader_->Cancel(); |
| 348 } | 346 } |
| 349 | 347 |
| 350 void DnsConfigServicePosix::ReadNow() { | 348 void DnsConfigServicePosix::ReadNow() { |
| 351 config_reader_->WorkNow(); | 349 config_reader_->WorkNow(); |
| 352 hosts_reader_->WorkNow(); | 350 hosts_reader_->WorkNow(); |
| 353 } | 351 } |
| 354 | 352 |
| 355 bool DnsConfigServicePosix::StartWatching() { | 353 bool DnsConfigServicePosix::StartWatching() { |
| 356 // TODO(szym): re-start watcher if that makes sense. http://crbug.com/116139 | 354 // TODO(szym): re-start watcher if that makes sense. http://crbug.com/116139 |
| 357 watcher_.reset(new Watcher(this)); | 355 watcher_.reset(new Watcher(this)); |
| 358 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus", DNS_CONFIG_WATCH_STARTED, | 356 UMA_HISTOGRAM_ENUMERATION( |
| 359 DNS_CONFIG_WATCH_MAX); | 357 "AsyncDNS.WatchStatus", DNS_CONFIG_WATCH_STARTED, DNS_CONFIG_WATCH_MAX); |
| 360 return watcher_->Watch(); | 358 return watcher_->Watch(); |
| 361 } | 359 } |
| 362 | 360 |
| 363 void DnsConfigServicePosix::OnConfigChanged(bool succeeded) { | 361 void DnsConfigServicePosix::OnConfigChanged(bool succeeded) { |
| 364 InvalidateConfig(); | 362 InvalidateConfig(); |
| 365 if (succeeded) { | 363 if (succeeded) { |
| 366 config_reader_->WorkNow(); | 364 config_reader_->WorkNow(); |
| 367 } else { | 365 } else { |
| 368 LOG(ERROR) << "DNS config watch failed."; | 366 LOG(ERROR) << "DNS config watch failed."; |
| 369 set_watch_failed(true); | 367 set_watch_failed(true); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 IPEndPoint ipe; | 402 IPEndPoint ipe; |
| 405 if (!ipe.FromSockAddr( | 403 if (!ipe.FromSockAddr( |
| 406 reinterpret_cast<const struct sockaddr*>(&addresses[i]), | 404 reinterpret_cast<const struct sockaddr*>(&addresses[i]), |
| 407 sizeof addresses[i])) { | 405 sizeof addresses[i])) { |
| 408 return CONFIG_PARSE_POSIX_BAD_ADDRESS; | 406 return CONFIG_PARSE_POSIX_BAD_ADDRESS; |
| 409 } | 407 } |
| 410 dns_config->nameservers.push_back(ipe); | 408 dns_config->nameservers.push_back(ipe); |
| 411 } | 409 } |
| 412 #elif defined(OS_LINUX) | 410 #elif defined(OS_LINUX) |
| 413 COMPILE_ASSERT(arraysize(res.nsaddr_list) >= MAXNS && | 411 COMPILE_ASSERT(arraysize(res.nsaddr_list) >= MAXNS && |
| 414 arraysize(res._u._ext.nsaddrs) >= MAXNS, | 412 arraysize(res._u._ext.nsaddrs) >= MAXNS, |
| 415 incompatible_libresolv_res_state); | 413 incompatible_libresolv_res_state); |
| 416 DCHECK_LE(res.nscount, MAXNS); | 414 DCHECK_LE(res.nscount, MAXNS); |
| 417 // Initially, glibc stores IPv6 in |_ext.nsaddrs| and IPv4 in |nsaddr_list|. | 415 // Initially, glibc stores IPv6 in |_ext.nsaddrs| and IPv4 in |nsaddr_list|. |
| 418 // In res_send.c:res_nsend, it merges |nsaddr_list| into |nsaddrs|, | 416 // In res_send.c:res_nsend, it merges |nsaddr_list| into |nsaddrs|, |
| 419 // but we have to combine the two arrays ourselves. | 417 // but we have to combine the two arrays ourselves. |
| 420 for (int i = 0; i < res.nscount; ++i) { | 418 for (int i = 0; i < res.nscount; ++i) { |
| 421 IPEndPoint ipe; | 419 IPEndPoint ipe; |
| 422 const struct sockaddr* addr = NULL; | 420 const struct sockaddr* addr = NULL; |
| 423 size_t addr_len = 0; | 421 size_t addr_len = 0; |
| 424 if (res.nsaddr_list[i].sin_family) { // The indicator used by res_nsend. | 422 if (res.nsaddr_list[i].sin_family) { // The indicator used by res_nsend. |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 #endif // !defined(OS_ANDROID) | 487 #endif // !defined(OS_ANDROID) |
| 490 | 488 |
| 491 } // namespace internal | 489 } // namespace internal |
| 492 | 490 |
| 493 // static | 491 // static |
| 494 scoped_ptr<DnsConfigService> DnsConfigService::CreateSystemService() { | 492 scoped_ptr<DnsConfigService> DnsConfigService::CreateSystemService() { |
| 495 return scoped_ptr<DnsConfigService>(new internal::DnsConfigServicePosix()); | 493 return scoped_ptr<DnsConfigService>(new internal::DnsConfigServicePosix()); |
| 496 } | 494 } |
| 497 | 495 |
| 498 } // namespace net | 496 } // namespace net |
| OLD | NEW |