diff options
author | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-20 18:39:34 +0000 |
---|---|---|
committer | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-20 18:39:34 +0000 |
commit | 74d6abc9361e01dda3862c94fac48c3ec0281df7 (patch) | |
tree | 789b3b70051b59c8ec11cf2403d07cdc96d52ccd /chrome/common | |
parent | 68da8f78cd06ba70144c9e3fb2e1bae724208e6a (diff) | |
download | chromium_src-74d6abc9361e01dda3862c94fac48c3ec0281df7.zip chromium_src-74d6abc9361e01dda3862c94fac48c3ec0281df7.tar.gz chromium_src-74d6abc9361e01dda3862c94fac48c3ec0281df7.tar.bz2 |
Use net::HostResolver instead of AsyncDnsLookup.
BUG=none
TEST=manual
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=47815
Review URL: http://codereview.chromium.org/2092008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47820 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common')
13 files changed, 157 insertions, 338 deletions
diff --git a/chrome/common/net/notifier/base/async_dns_lookup.cc b/chrome/common/net/notifier/base/async_dns_lookup.cc deleted file mode 100644 index 4cc254d..0000000 --- a/chrome/common/net/notifier/base/async_dns_lookup.cc +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) 2009 The Chromium 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 "chrome/common/net/notifier/base/async_dns_lookup.h" - -#include "build/build_config.h" - -#if defined(OS_POSIX) -#include <arpa/inet.h> -#include <netdb.h> -#include <netinet/in_systm.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <sys/socket.h> -#include <sys/types.h> -#endif // defined(OS_POSIX) - -// Apparently, inet_aton() is available for Windows, but just not -// declared anywhere. We'd use inet_pton(), but it's Vista-only. -#if defined(OS_WIN) -int inet_aton(const char* cp, struct in_addr* inp); -#endif // defined(OS_WIN) - -#include <vector> - -#include "base/basictypes.h" -#include "base/logging.h" -#include "chrome/common/net/notifier/base/nethelpers.h" -#include "talk/base/byteorder.h" -#include "talk/base/common.h" -#include "talk/base/socketaddress.h" -#include "talk/base/thread.h" - -enum { MSG_TIMEOUT = talk_base::SignalThread::ST_MSG_FIRST_AVAILABLE }; - -#ifndef WIN32 -const int WSAHOST_NOT_FOUND = 11001; // Follows the format in winsock2.h. -#endif // WIN32 - -namespace notifier { - -AsyncDNSLookup::AsyncDNSLookup(const talk_base::SocketAddress& server) - : server_(new talk_base::SocketAddress(server)), - error_(0) { - // Timeout after 5 seconds. - talk_base::Thread::Current()->PostDelayed(5000, this, MSG_TIMEOUT); -} - -AsyncDNSLookup::~AsyncDNSLookup() { -} - -void AsyncDNSLookup::DoWork() { - std::string hostname(server_->IPAsString()); - - in_addr addr; - if (inet_aton(hostname.c_str(), &addr)) { - talk_base::CritScope scope(&cs_); - ip_list_.push_back(talk_base::NetworkToHost32(addr.s_addr)); - } else { - LOG(INFO) << "(" << hostname << ")"; - hostent ent; - char buffer[8192]; - int errcode = 0; - hostent* host = SafeGetHostByName(hostname.c_str(), &ent, - buffer, sizeof(buffer), - &errcode); - talk_base::Thread::Current()->Clear(this, MSG_TIMEOUT); - if (host) { - talk_base::CritScope scope(&cs_); - - // Check to see if this already timed out. - if (error_ == 0) { - for (int index = 0; true; ++index) { - uint32* addr = reinterpret_cast<uint32*>(host->h_addr_list[index]); - if (addr == 0) { // 0 = end of list. - break; - } - uint32 ip = talk_base::NetworkToHost32(*addr); - LOG(INFO) << "(" << hostname << ") resolved to: " - << talk_base::SocketAddress::IPToString(ip); - ip_list_.push_back(ip); - } - // Maintain the invariant that either the list is not empty or the - // error is non zero when we are done with processing the dnslookup. - if (ip_list_.empty() && error_ == 0) { - error_ = WSAHOST_NOT_FOUND; - } - } - FreeHostEnt(host); - } else { - { // Scoping for the critical section. - talk_base::CritScope scope(&cs_); - - // Check to see if this already timed out. - if (error_ == 0) { - error_ = errcode; - } - } - LOG(ERROR) << "(" << hostname << ") error: " << error_; - } - } -} - -void AsyncDNSLookup::OnMessage(talk_base::Message* message) { - DCHECK(message); - if (message->message_id == MSG_TIMEOUT) { - OnTimeout(); - } else { - talk_base::SignalThread::OnMessage(message); - } -} - -void AsyncDNSLookup::OnTimeout() { - // Allow the scope for the critical section to be the whole method, just to - // be sure that the worker thread can't exit while we are doing - // SignalWorkDone (because that could possibly cause the class to be - // deleted). - talk_base::CritScope scope(&cs_); - - // Check to see if the ip list was already filled (or errored out). - if (!ip_list_.empty() || error_ != 0) { - return; - } - - // Worker thread is taking too long so timeout. - error_ = WSAHOST_NOT_FOUND; - - // Rely on the caller to do the Release/Destroy. - // - // Doing this signal while holding cs_ won't cause a deadlock because the - // AsyncDNSLookup::DoWork thread doesn't have any locks at this point, and it - // is the only thread being held up by this. - SignalWorkDone(this); - - // Ensure that no more "WorkDone" signaling is done. - // Don't call Release or Destroy since that was already done by the callback. - SignalWorkDone.disconnect_all(); -} - -} // namespace notifier diff --git a/chrome/common/net/notifier/base/async_dns_lookup.h b/chrome/common/net/notifier/base/async_dns_lookup.h deleted file mode 100644 index 276eadeb5..0000000 --- a/chrome/common/net/notifier/base/async_dns_lookup.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_COMMON_NET_NOTIFIER_BASE_ASYNC_DNS_LOOKUP_H_ -#define CHROME_COMMON_NET_NOTIFIER_BASE_ASYNC_DNS_LOOKUP_H_ - -#include <vector> - -#include "base/scoped_ptr.h" -#include "talk/base/signalthread.h" - -namespace talk_base { -class SocketAddress; -class Task; -} - -namespace notifier { - -class AsyncDNSLookup : public talk_base::SignalThread { - public: - explicit AsyncDNSLookup(const talk_base::SocketAddress& server); - virtual ~AsyncDNSLookup(); - - int error() const { - return error_; - } - - const std::vector<uint32>& ip_list() const { - return ip_list_; - } - - protected: - // SignalThread Interface. - virtual void DoWork(); - virtual void OnMessage(talk_base::Message* message); - - private: - void OnTimeout(); - - scoped_ptr<talk_base::SocketAddress> server_; - talk_base::CriticalSection cs_; - int error_; - std::vector<uint32> ip_list_; - - DISALLOW_COPY_AND_ASSIGN(AsyncDNSLookup); -}; - -} // namespace notifier - -#endif // CHROME_COMMON_NET_NOTIFIER_BASE_ASYNC_DNS_LOOKUP_H_ diff --git a/chrome/common/net/notifier/base/nethelpers.cc b/chrome/common/net/notifier/base/nethelpers.cc deleted file mode 100644 index df93768..0000000 --- a/chrome/common/net/notifier/base/nethelpers.cc +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2009 The Chromium 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 "build/build_config.h" -#include "chrome/common/net/notifier/base/nethelpers.h" - -namespace notifier { - -hostent* SafeGetHostByName(const char* hostname, hostent* host, - char* buffer, size_t buffer_len, - int* herrno) { - hostent* result = NULL; -#if WIN32 - result = gethostbyname(hostname); - if (!result) { - *herrno = WSAGetLastError(); - } -#elif OS_LINUX - gethostbyname_r(hostname, host, buffer, buffer_len, &result, herrno); -#elif OS_MACOSX - result = getipnodebyname(hostname, AF_INET, AI_DEFAULT, herrno); -#else -#error "I don't know how to do gethostbyname safely on your system." -#endif - return result; -} - -// This function should mirror the above function, and free any resources -// allocated by the above. -void FreeHostEnt(hostent* host) { -#if WIN32 - // No need to free anything, struct returned is static memory. -#elif OS_LINUX - // No need to free anything, we pass in a pointer to a struct. -#elif OS_MACOSX - freehostent(host); -#else -#error "I don't know how to free a hostent on your system." -#endif -} - -} // namespace notifier diff --git a/chrome/common/net/notifier/base/nethelpers.h b/chrome/common/net/notifier/base/nethelpers.h deleted file mode 100644 index d53d01a..0000000 --- a/chrome/common/net/notifier/base/nethelpers.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_COMMON_NET_NOTIFIER_BASE_NETHELPERS_H_ -#define CHROME_COMMON_NET_NOTIFIER_BASE_NETHELPERS_H_ - -#include "base/basictypes.h" - -#if defined(OS_POSIX) -#include <cstddef> -#include <netdb.h> -#elif defined(OS_WIN) -#include <winsock2.h> -#endif - -namespace notifier { - -hostent* SafeGetHostByName(const char* hostname, hostent* host, - char* buffer, size_t buffer_len, - int* herrno); - -void FreeHostEnt(hostent* host); - -} // namespace notifier - -#endif // CHROME_COMMON_NET_NOTIFIER_BASE_NETHELPERS_H_ diff --git a/chrome/common/net/notifier/communicator/login.cc b/chrome/common/net/notifier/communicator/login.cc index 4c382ae..26bc600 100644 --- a/chrome/common/net/notifier/communicator/login.cc +++ b/chrome/common/net/notifier/communicator/login.cc @@ -14,6 +14,7 @@ #include "chrome/common/net/notifier/communicator/login_settings.h" #include "chrome/common/net/notifier/communicator/product_info.h" #include "chrome/common/net/notifier/communicator/single_login_attempt.h" +#include "net/base/host_port_pair.h" #include "net/base/network_change_notifier.h" #include "talk/base/common.h" #include "talk/base/firewallsocketserver.h" @@ -39,6 +40,7 @@ Login::Login(talk_base::Task* parent, const buzz::XmppClientSettings& user_settings, const ConnectionOptions& options, std::string lang, + net::HostResolver* host_resolver, ServerInformation* server_list, int server_count, net::NetworkChangeNotifier* network_change_notifier, @@ -49,6 +51,7 @@ Login::Login(talk_base::Task* parent, login_settings_(new LoginSettings(user_settings, options, lang, + host_resolver, server_list, server_count, firewall, @@ -98,10 +101,8 @@ void Login::StartConnection() { // If there is a server redirect, use it. if (GetCurrent100NSTime() < redirect_time_ns_ + kRedirectTimeoutNs) { // Override server/port with redirect values. - talk_base::SocketAddress server_override; - server_override.SetIP(redirect_server_, false); DCHECK_NE(redirect_port_, 0); - server_override.SetPort(redirect_port_); + net::HostPortPair server_override(redirect_server_, redirect_port_); login_settings_->set_server_override(server_override); } else { login_settings_->clear_server_override(); diff --git a/chrome/common/net/notifier/communicator/login.h b/chrome/common/net/notifier/communicator/login.h index 4d4cafa..3394529 100644 --- a/chrome/common/net/notifier/communicator/login.h +++ b/chrome/common/net/notifier/communicator/login.h @@ -21,6 +21,10 @@ class XmppEngine; class XmppClientSettings; } // namespace buzz +namespace net { +class HostResolver; +} // namespace net + namespace talk_base { class FirewallManager; struct ProxyInfo; @@ -48,6 +52,7 @@ class Login : public net::NetworkChangeNotifier::Observer, const buzz::XmppClientSettings& user_settings, const ConnectionOptions& options, std::string lang, + net::HostResolver* host_resolver, ServerInformation* server_list, int server_count, net::NetworkChangeNotifier* network_change_notifier, diff --git a/chrome/common/net/notifier/communicator/login_settings.cc b/chrome/common/net/notifier/communicator/login_settings.cc index a546d5b..23ea983 100644 --- a/chrome/common/net/notifier/communicator/login_settings.cc +++ b/chrome/common/net/notifier/communicator/login_settings.cc @@ -17,7 +17,8 @@ namespace notifier { LoginSettings::LoginSettings(const buzz::XmppClientSettings& user_settings, const ConnectionOptions& options, - std::string lang, + const std::string& lang, + net::HostResolver* host_resolver, ServerInformation* server_list, int server_count, talk_base::FirewallManager* firewall, @@ -25,12 +26,14 @@ LoginSettings::LoginSettings(const buzz::XmppClientSettings& user_settings, : proxy_only_(proxy_only), firewall_(firewall), lang_(lang), + host_resolver_(host_resolver), server_list_(new ServerInformation[server_count]), server_count_(server_count), user_settings_(new buzz::XmppClientSettings(user_settings)), connection_options_(new ConnectionOptions(options)) { // Note: firewall may be NULL. DCHECK(server_list); + DCHECK(host_resolver); DCHECK_GT(server_count, 0); for (int i = 0; i < server_count_; ++i) { server_list_[i] = server_list[i]; @@ -43,7 +46,7 @@ LoginSettings::~LoginSettings() { } void LoginSettings::set_server_override( - const talk_base::SocketAddress& server) { + const net::HostPortPair& server) { server_override_.reset(new ServerInformation()); server_override_->server = server; server_override_->special_port_magic = server_list_[0].special_port_magic; diff --git a/chrome/common/net/notifier/communicator/login_settings.h b/chrome/common/net/notifier/communicator/login_settings.h index 2f05729..90eae31 100644 --- a/chrome/common/net/notifier/communicator/login_settings.h +++ b/chrome/common/net/notifier/communicator/login_settings.h @@ -13,6 +13,11 @@ namespace buzz { class XmppClientSettings; } +namespace net { +struct HostPortPair; +class HostResolver; +} + namespace talk_base { class FirewallManager; class SocketAddress; @@ -26,7 +31,8 @@ class LoginSettings { public: LoginSettings(const buzz::XmppClientSettings& user_settings, const ConnectionOptions& options, - std::string lang, + const std::string& lang, + net::HostResolver* host_resolver, ServerInformation* server_list, int server_count, talk_base::FirewallManager* firewall, @@ -50,6 +56,10 @@ class LoginSettings { return lang_; } + net::HostResolver* host_resolver() { + return host_resolver_; + } + const ServerInformation* server_list() const { return server_override_.get() ? server_override_.get() : server_list_.get(); } @@ -70,7 +80,7 @@ class LoginSettings { return *connection_options_.get(); } - void set_server_override(const talk_base::SocketAddress& server); + void set_server_override(const net::HostPortPair& server); void clear_server_override(); private: @@ -78,6 +88,7 @@ class LoginSettings { talk_base::FirewallManager* firewall_; std::string lang_; + net::HostResolver* host_resolver_; talk_base::scoped_array<ServerInformation> server_list_; int server_count_; // Used to handle redirects diff --git a/chrome/common/net/notifier/communicator/single_login_attempt.cc b/chrome/common/net/notifier/communicator/single_login_attempt.cc index 6afb23b..217e13f 100644 --- a/chrome/common/net/notifier/communicator/single_login_attempt.cc +++ b/chrome/common/net/notifier/communicator/single_login_attempt.cc @@ -124,6 +124,7 @@ SingleLoginAttempt::SingleLoginAttempt(talk_base::Task* parent, #endif connection_generator_.reset(new XmppConnectionGenerator( this, + login_settings_->host_resolver(), &login_settings_->connection_options(), login_settings_->proxy_only(), login_settings_->server_list(), diff --git a/chrome/common/net/notifier/communicator/xmpp_connection_generator.cc b/chrome/common/net/notifier/communicator/xmpp_connection_generator.cc index 269c19e0..1c157f8 100644 --- a/chrome/common/net/notifier/communicator/xmpp_connection_generator.cc +++ b/chrome/common/net/notifier/communicator/xmpp_connection_generator.cc @@ -12,14 +12,23 @@ #include "chrome/common/net/notifier/communicator/xmpp_connection_generator.h" +#if defined(OS_WIN) +#include <winsock2.h> +#elif defined(OS_POSIX) +#include <arpa/inet.h> +#endif + #include <vector> +#include "base/callback.h" +#include "base/compiler_specific.h" #include "base/logging.h" -#include "chrome/common/net/notifier/base/async_dns_lookup.h" #include "chrome/common/net/notifier/base/signal_thread_task.h" #include "chrome/common/net/notifier/communicator/connection_options.h" #include "chrome/common/net/notifier/communicator/connection_settings.h" #include "chrome/common/net/notifier/communicator/product_info.h" +#include "net/base/net_errors.h" +#include "net/base/sys_addrinfo.h" #include "talk/base/autodetectproxy.h" #include "talk/base/httpcommon-inl.h" #include "talk/base/task.h" @@ -32,11 +41,17 @@ namespace notifier { XmppConnectionGenerator::XmppConnectionGenerator( talk_base::Task* parent, + const scoped_refptr<net::HostResolver>& host_resolver, const ConnectionOptions* options, bool proxy_only, const ServerInformation* server_list, int server_count) - : settings_list_(new ConnectionSettingsList()), + : host_resolver_(host_resolver), + resolve_callback_( + ALLOW_THIS_IN_INITIALIZER_LIST( + NewCallback(this, + &XmppConnectionGenerator::OnServerDNSResolved))), + settings_list_(new ConnectionSettingsList()), settings_index_(0), server_list_(new ServerInformation[server_count]), server_count_(server_count), @@ -46,6 +61,7 @@ XmppConnectionGenerator::XmppConnectionGenerator( first_dns_error_(0), options_(options), parent_(parent) { + DCHECK(host_resolver); DCHECK(parent); DCHECK(options); DCHECK_GT(server_count_, 0); @@ -79,8 +95,8 @@ void XmppConnectionGenerator::StartGenerating() { // Pretend the xmpp server is https, when detecting whether a proxy is // required to connect. talk_base::Url<char> host_url("/", - server_list_[0].server.IPAsString().c_str(), - server_list_[0].server.port()); + server_list_[0].server.host.c_str(), + server_list_[0].server.port); host_url.set_secure(true); proxy_detect->set_server_url(host_url.url()); } else if (options_->proxy_host().length()) { @@ -113,55 +129,79 @@ void XmppConnectionGenerator::OnProxyDetect( } void XmppConnectionGenerator::UseNextConnection() { - // Trying to connect. - - // Iterate to the next possible connection. - settings_index_++; - if (settings_index_ < settings_list_->GetCount()) { - // We have more connection settings in the settings_list_ to try, kick off - // the next one. - UseCurrentConnection(); - return; - } - - // Iterate to the next possible server. - server_index_++; - if (server_index_ < server_count_) { - AsyncDNSLookup* dns_lookup = new AsyncDNSLookup( - server_list_[server_index_].server); - SignalThreadTask<AsyncDNSLookup>* wrapper_task = - new SignalThreadTask<AsyncDNSLookup>(parent_, &dns_lookup); - wrapper_task->SignalWorkDone.connect( - this, - &XmppConnectionGenerator::OnServerDNSResolved); - wrapper_task->Start(); - return; + // Loop until we can use a connection or we run out of connections + // to try. + while (true) { + // Iterate to the next possible connection. + settings_index_++; + if (settings_index_ < settings_list_->GetCount()) { + // We have more connection settings in the settings_list_ to + // try, kick off the next one. + UseCurrentConnection(); + return; + } + + // Iterate to the next possible server. + server_index_++; + if (server_index_ >= server_count_) { + // All out of possibilities. + HandleExhaustedConnections(); + return; + } + + // Resolve the server. + const net::HostPortPair& server = + server_list_[server_index_].server; + net::HostResolver::RequestInfo request_info( + server.host, server.port); + int status = + host_resolver_.Resolve( + request_info, &address_list_, resolve_callback_.get(), + bound_net_log_); + if (status == net::ERR_IO_PENDING) { + // resolve_callback_ will call us when it's called. + return; + } + HandleServerDNSResolved(status); } - - // All out of possibilities. - HandleExhaustedConnections(); } -void XmppConnectionGenerator::OnServerDNSResolved( - AsyncDNSLookup* dns_lookup) { - LOG(INFO) << "XmppConnectionGenerator::OnServerDNSResolved"; +void XmppConnectionGenerator::OnServerDNSResolved(int status) { + DCHECK_NE(status, net::ERR_IO_PENDING); + HandleServerDNSResolved(status); + // Reenter loop. + UseNextConnection(); +} +void XmppConnectionGenerator::HandleServerDNSResolved(int status) { + DCHECK_NE(status, net::ERR_IO_PENDING); + LOG(INFO) << "XmppConnectionGenerator::HandleServerDNSResolved"; // Print logging info. - LOG(INFO) << " server: " << - server_list_[server_index_].server.ToString() << - " error: " << dns_lookup->error(); - if (first_dns_error_ == 0 && dns_lookup->error() != 0) { - first_dns_error_ = dns_lookup->error(); + LOG(INFO) << " server: " + << server_list_[server_index_].server.ToString() + << ", error: " << status; + if (status != net::OK) { + if (first_dns_error_ == 0) { + first_dns_error_ = status; + } + return; } - if (!successfully_resolved_dns_ && dns_lookup->ip_list().size() > 0) { - successfully_resolved_dns_ = true; + // Slurp the addresses into a vector. + std::vector<uint32> ip_list; + for (const addrinfo* addr = address_list_.head(); + addr != NULL; addr = addr->ai_next) { + const sockaddr_in& sockaddr = + *reinterpret_cast<const sockaddr_in*>(addr->ai_addr); + uint32 ip = ntohl(sockaddr.sin_addr.s_addr); + ip_list.push_back(ip); } + successfully_resolved_dns_ = !ip_list.empty(); - for (int i = 0; i < static_cast<int>(dns_lookup->ip_list().size()); ++i) { + for (int i = 0; i < static_cast<int>(ip_list.size()); ++i) { LOG(INFO) << " ip " << i << " : " - << talk_base::SocketAddress::IPToString(dns_lookup->ip_list()[i]); + << talk_base::SocketAddress::IPToString(ip_list[i]); } // Build the ip list. @@ -169,13 +209,11 @@ void XmppConnectionGenerator::OnServerDNSResolved( settings_index_ = -1; settings_list_->ClearPermutations(); settings_list_->AddPermutations( - server_list_[server_index_].server.IPAsString(), - dns_lookup->ip_list(), - server_list_[server_index_].server.port(), + server_list_[server_index_].server.host, + ip_list, + server_list_[server_index_].server.port, server_list_[server_index_].special_port_magic, proxy_only_); - - UseNextConnection(); } static const char* const PROTO_NAMES[cricket::PROTO_LAST + 1] = { diff --git a/chrome/common/net/notifier/communicator/xmpp_connection_generator.h b/chrome/common/net/notifier/communicator/xmpp_connection_generator.h index 47a2e40..114ac4b 100644 --- a/chrome/common/net/notifier/communicator/xmpp_connection_generator.h +++ b/chrome/common/net/notifier/communicator/xmpp_connection_generator.h @@ -7,9 +7,14 @@ #include <vector> +#include "base/ref_counted.h" +#include "net/base/address_list.h" +#include "net/base/completion_callback.h" +#include "net/base/host_port_pair.h" +#include "net/base/host_resolver.h" +#include "net/base/net_log.h" #include "talk/base/scoped_ptr.h" #include "talk/base/sigslot.h" -#include "talk/base/socketaddress.h" namespace talk_base { class AutoDetectProxy; @@ -20,13 +25,12 @@ class Task; namespace notifier { -class AsyncDNSLookup; class ConnectionOptions; class ConnectionSettings; class ConnectionSettingsList; struct ServerInformation { - talk_base::SocketAddress server; + net::HostPortPair server; bool special_port_magic; }; @@ -39,11 +43,13 @@ class XmppConnectionGenerator : public sigslot::has_slots<> { // proxy. // server_list is the list of connections to attempt in priority order. // server_count is the number of items in the server list. - XmppConnectionGenerator(talk_base::Task* parent, - const ConnectionOptions* options, - bool proxy_only, - const ServerInformation* server_list, - int server_count); + XmppConnectionGenerator( + talk_base::Task* parent, + const scoped_refptr<net::HostResolver>& host_resolver, + const ConnectionOptions* options, + bool proxy_only, + const ServerInformation* server_list, + int server_count); ~XmppConnectionGenerator(); // Only call this once. Create a new XmppConnectionGenerator and delete the @@ -63,9 +69,14 @@ class XmppConnectionGenerator : public sigslot::has_slots<> { private: void OnProxyDetect(talk_base::AutoDetectProxy* proxy_detect); - void OnServerDNSResolved(AsyncDNSLookup* dns_lookup); + void OnServerDNSResolved(int status); + void HandleServerDNSResolved(int status); void HandleExhaustedConnections(); + net::SingleRequestHostResolver host_resolver_; + scoped_ptr<net::CompletionCallback> resolve_callback_; + net::AddressList address_list_; + net::BoundNetLog bound_net_log_; talk_base::scoped_ptr<ConnectionSettingsList> settings_list_; int settings_index_; // The setting that is currently being used. talk_base::scoped_array<ServerInformation> server_list_; diff --git a/chrome/common/net/notifier/listener/mediator_thread_impl.cc b/chrome/common/net/notifier/listener/mediator_thread_impl.cc index 4ce5a97..1d8fd83 100644 --- a/chrome/common/net/notifier/listener/mediator_thread_impl.cc +++ b/chrome/common/net/notifier/listener/mediator_thread_impl.cc @@ -8,7 +8,6 @@ #include "base/message_loop.h" #include "base/platform_thread.h" #include "chrome/common/net/network_change_notifier_proxy.h" -#include "chrome/common/net/notifier/base/async_dns_lookup.h" #include "chrome/common/net/notifier/base/task_pump.h" #include "chrome/common/net/notifier/communicator/connection_options.h" #include "chrome/common/net/notifier/communicator/const_communicator.h" @@ -16,6 +15,8 @@ #include "chrome/common/net/notifier/listener/listen_task.h" #include "chrome/common/net/notifier/listener/send_update_task.h" #include "chrome/common/net/notifier/listener/subscribe_task.h" +#include "net/base/host_port_pair.h" +#include "net/base/host_resolver.h" #include "talk/base/thread.h" #include "talk/xmpp/xmppclient.h" #include "talk/xmpp/xmppclientsettings.h" @@ -136,24 +137,27 @@ void MediatorThreadImpl::DoLogin(LoginData* login_data) { LOG(INFO) << "P2P: Thread logging into talk network."; buzz::XmppClientSettings& user_settings = login_data->user_settings; - // Start a new pump for the login. - login_.reset(); network_change_notifier_.reset( new chrome_common_net::NetworkChangeNotifierProxy( network_change_notifier_thread_)); + // TODO(akalin): Use an existing HostResolver from somewhere (maybe + // the IOThread one). + host_resolver_ = + net::CreateSystemHostResolver(network_change_notifier_.get()); + + // Start a new pump for the login. + login_.reset(); pump_.reset(new notifier::TaskPump()); notifier::ServerInformation server_list[2]; int server_list_count = 2; // The default servers know how to serve over port 443 (that's the magic). - server_list[0].server = talk_base::SocketAddress("talk.google.com", - notifier::kDefaultXmppPort, - true); // Use DNS. + server_list[0].server = net::HostPortPair("talk.google.com", + notifier::kDefaultXmppPort); server_list[0].special_port_magic = true; - server_list[1].server = talk_base::SocketAddress("talkx.l.google.com", - notifier::kDefaultXmppPort, - true); // Use DNS. + server_list[1].server = net::HostPortPair("talkx.l.google.com", + notifier::kDefaultXmppPort); server_list[1].special_port_magic = true; // Autodetect proxy is on by default. @@ -165,6 +169,7 @@ void MediatorThreadImpl::DoLogin(LoginData* login_data) { user_settings, options, lang, + host_resolver_.get(), server_list, server_list_count, network_change_notifier_.get(), @@ -199,10 +204,12 @@ void MediatorThreadImpl::OnOutputDebug(const char* msg, int length) { void MediatorThreadImpl::DoDisconnect() { LOG(INFO) << "P2P: Thread logging out of talk network."; login_.reset(); - network_change_notifier_.reset(); // Delete the old pump while on the thread to ensure that everything is // cleaned-up in a predicatable manner. pump_.reset(); + + host_resolver_ = NULL; + network_change_notifier_.reset(); } void MediatorThreadImpl::DoSubscribeForUpdates( diff --git a/chrome/common/net/notifier/listener/mediator_thread_impl.h b/chrome/common/net/notifier/listener/mediator_thread_impl.h index fb660da..f0bb4c7 100644 --- a/chrome/common/net/notifier/listener/mediator_thread_impl.h +++ b/chrome/common/net/notifier/listener/mediator_thread_impl.h @@ -24,6 +24,7 @@ #include <vector> #include "base/logging.h" +#include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "chrome/common/net/notifier/communicator/login.h" #include "chrome/common/net/notifier/communicator/login_failure.h" @@ -37,6 +38,7 @@ class NetworkChangeNotifierThread; } // namespace chrome_common_net namespace net { +class HostResolver; class NetworkChangeNotifier; } // namespace net @@ -148,14 +150,16 @@ class MediatorThreadImpl buzz::XmppClient* xmpp_client(); + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread_; + scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; + scoped_refptr<net::HostResolver> host_resolver_; + // All buzz::XmppClients are owned by their parent. The root parent is the // SingleLoginTask created by the notifier::Login object. This in turn is // owned by the TaskPump. They are destroyed either when processing is // complete or the pump shuts down. scoped_ptr<notifier::TaskPump> pump_; - chrome_common_net::NetworkChangeNotifierThread* - network_change_notifier_thread_; - scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; scoped_ptr<notifier::Login> login_; DISALLOW_COPY_AND_ASSIGN(MediatorThreadImpl); }; |