summaryrefslogtreecommitdiffstats
path: root/jingle
diff options
context:
space:
mode:
authorakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-15 00:09:53 +0000
committerakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-15 00:09:53 +0000
commit1d1e68efc0a14fe775c001319569f0ec8dd1bc8f (patch)
treecc49f7dd51b3c5dc032be07f2aa6dc90bb10636d /jingle
parent46e6df6041b1ad00d31a4c97eb55162e6d008038 (diff)
downloadchromium_src-1d1e68efc0a14fe775c001319569f0ec8dd1bc8f.zip
chromium_src-1d1e68efc0a14fe775c001319569f0ec8dd1bc8f.tar.gz
chromium_src-1d1e68efc0a14fe775c001319569f0ec8dd1bc8f.tar.bz2
[Sync] Clean up XMPP connection code
Remove dead DNS-resolution-related code. Remove complicated XmppConnectionGenerator class now that we don't have to do DNS resolution ourselves. Move the simplified logic into MakeConnectionSettingsList(). Add unit tests for it. Remove unused ConnectionOptions struct. Simplify SingleLoginAttempt a bit and add tests for it. Also document redirection protocol. Simplify LoginSettings and add tests for it. Move redirection timeout logic from Login to LoginSettings. Replace some bools with enums. Document sketchy (but necessary) include of libjingle's p2p/port.h. Some minor cleanup here and there. BUG=38091 TEST= Review URL: https://chromiumcodereview.appspot.com/10391084 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@137027 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'jingle')
-rw-r--r--jingle/jingle.gyp8
-rw-r--r--jingle/notifier/base/notifier_options_util.cc11
-rw-r--r--jingle/notifier/base/server_information.cc22
-rw-r--r--jingle/notifier/base/server_information.h11
-rw-r--r--jingle/notifier/base/xmpp_connection.cc7
-rw-r--r--jingle/notifier/base/xmpp_connection.h17
-rw-r--r--jingle/notifier/communicator/DEPS4
-rw-r--r--jingle/notifier/communicator/connection_options.cc16
-rw-r--r--jingle/notifier/communicator/connection_options.h53
-rw-r--r--jingle/notifier/communicator/connection_settings.cc165
-rw-r--r--jingle/notifier/communicator/connection_settings.h75
-rw-r--r--jingle/notifier/communicator/connection_settings_unittest.cc99
-rw-r--r--jingle/notifier/communicator/login.cc44
-rw-r--r--jingle/notifier/communicator/login.h20
-rw-r--r--jingle/notifier/communicator/login_settings.cc65
-rw-r--r--jingle/notifier/communicator/login_settings.h66
-rw-r--r--jingle/notifier/communicator/login_settings_unittest.cc77
-rw-r--r--jingle/notifier/communicator/single_login_attempt.cc178
-rw-r--r--jingle/notifier/communicator/single_login_attempt.h48
-rw-r--r--jingle/notifier/communicator/single_login_attempt_unittest.cc226
-rw-r--r--jingle/notifier/communicator/xmpp_connection_generator.cc190
-rw-r--r--jingle/notifier/communicator/xmpp_connection_generator.h84
-rw-r--r--jingle/notifier/communicator/xmpp_connection_generator_unittest.cc112
-rw-r--r--jingle/notifier/listener/mediator_thread_impl.cc6
24 files changed, 785 insertions, 819 deletions
diff --git a/jingle/jingle.gyp b/jingle/jingle.gyp
index b940bd6..02a5a05 100644
--- a/jingle/jingle.gyp
+++ b/jingle/jingle.gyp
@@ -67,8 +67,6 @@
'notifier/base/xmpp_client_socket_factory.h',
'notifier/base/xmpp_connection.cc',
'notifier/base/xmpp_connection.h',
- 'notifier/communicator/connection_options.cc',
- 'notifier/communicator/connection_options.h',
'notifier/communicator/connection_settings.cc',
'notifier/communicator/connection_settings.h',
'notifier/communicator/login.cc',
@@ -77,8 +75,6 @@
'notifier/communicator/login_settings.h',
'notifier/communicator/single_login_attempt.cc',
'notifier/communicator/single_login_attempt.h',
- 'notifier/communicator/xmpp_connection_generator.cc',
- 'notifier/communicator/xmpp_connection_generator.h',
'notifier/listener/mediator_thread.h',
'notifier/listener/mediator_thread_impl.cc',
'notifier/listener/mediator_thread_impl.h',
@@ -165,7 +161,9 @@
'notifier/base/task_pump_unittest.cc',
'notifier/base/xmpp_connection_unittest.cc',
'notifier/base/weak_xmpp_client_unittest.cc',
- 'notifier/communicator/xmpp_connection_generator_unittest.cc',
+ 'notifier/communicator/connection_settings_unittest.cc',
+ 'notifier/communicator/login_settings_unittest.cc',
+ 'notifier/communicator/single_login_attempt_unittest.cc',
'notifier/listener/mediator_thread_mock.cc',
'notifier/listener/mediator_thread_mock.h',
'notifier/listener/mediator_thread_unittest.cc',
diff --git a/jingle/notifier/base/notifier_options_util.cc b/jingle/notifier/base/notifier_options_util.cc
index e4b1752..9e107bc 100644
--- a/jingle/notifier/base/notifier_options_util.cc
+++ b/jingle/notifier/base/notifier_options_util.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -42,19 +42,20 @@ ServerList GetServerList(
// provided.
if (!notifier_options.xmpp_host_port.host().empty()) {
servers.push_back(
- ServerInformation(notifier_options.xmpp_host_port, false));
+ ServerInformation(notifier_options.xmpp_host_port,
+ DOES_NOT_SUPPORT_SSLTCP));
} else {
- // The default servers know how to serve over port 443 (that's the magic).
+ // The default servers support SSLTCP.
servers.push_back(
ServerInformation(
net::HostPortPair("talk.google.com",
notifier::kDefaultXmppPort),
- true));
+ SUPPORTS_SSLTCP));
servers.push_back(
ServerInformation(
net::HostPortPair("talkx.l.google.com",
notifier::kDefaultXmppPort),
- true));
+ SUPPORTS_SSLTCP));
}
return servers;
}
diff --git a/jingle/notifier/base/server_information.cc b/jingle/notifier/base/server_information.cc
index ba66507..003daca 100644
--- a/jingle/notifier/base/server_information.cc
+++ b/jingle/notifier/base/server_information.cc
@@ -1,15 +1,29 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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 "jingle/notifier/base/server_information.h"
+#include "base/logging.h"
+
namespace notifier {
ServerInformation::ServerInformation(
- const net::HostPortPair& server, bool special_port_magic)
- : server(server), special_port_magic(special_port_magic) {}
+ const net::HostPortPair& server, SslTcpSupport ssltcp_support)
+ : server(server), ssltcp_support(ssltcp_support) {
+ DCHECK(!server.host().empty());
+ DCHECK_GT(server.port(), 0);
+}
+
+ServerInformation::ServerInformation()
+ : ssltcp_support(DOES_NOT_SUPPORT_SSLTCP) {}
+
+ServerInformation::~ServerInformation() {}
-ServerInformation::ServerInformation() : special_port_magic(false) {}
+bool ServerInformation::Equals(const ServerInformation& other) const {
+ return
+ server.Equals(other.server) &&
+ (ssltcp_support == other.ssltcp_support);
+}
} // namespace notifier
diff --git a/jingle/notifier/base/server_information.h b/jingle/notifier/base/server_information.h
index c42b69e..c6e3ffd 100644
--- a/jingle/notifier/base/server_information.h
+++ b/jingle/notifier/base/server_information.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
//
@@ -13,13 +13,18 @@
namespace notifier {
+enum SslTcpSupport { DOES_NOT_SUPPORT_SSLTCP, SUPPORTS_SSLTCP };
+
struct ServerInformation {
ServerInformation(const net::HostPortPair& server,
- bool special_port_magic);
+ SslTcpSupport ssltcp_support);
ServerInformation();
+ ~ServerInformation();
+
+ bool Equals(const ServerInformation& other) const;
net::HostPortPair server;
- bool special_port_magic;
+ SslTcpSupport ssltcp_support;
};
typedef std::vector<ServerInformation> ServerList;
diff --git a/jingle/notifier/base/xmpp_connection.cc b/jingle/notifier/base/xmpp_connection.cc
index da1b5a1..6df0de8 100644
--- a/jingle/notifier/base/xmpp_connection.cc
+++ b/jingle/notifier/base/xmpp_connection.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -19,6 +19,8 @@
namespace notifier {
+XmppConnection::Delegate::~Delegate() {}
+
namespace {
buzz::AsyncSocket* CreateSocket(
@@ -47,7 +49,8 @@ buzz::AsyncSocket* CreateSocket(
XmppConnection::XmppConnection(
const buzz::XmppClientSettings& xmpp_client_settings,
const scoped_refptr<net::URLRequestContextGetter>& request_context_getter,
- Delegate* delegate, buzz::PreXmppAuth* pre_xmpp_auth)
+ Delegate* delegate,
+ buzz::PreXmppAuth* pre_xmpp_auth)
: task_pump_(new TaskPump()),
on_connect_called_(false),
delegate_(delegate) {
diff --git a/jingle/notifier/base/xmpp_connection.h b/jingle/notifier/base/xmpp_connection.h
index 886f58f..9baea68 100644
--- a/jingle/notifier/base/xmpp_connection.h
+++ b/jingle/notifier/base/xmpp_connection.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
//
@@ -34,8 +34,6 @@ class XmppConnection : public sigslot::has_slots<> {
public:
class Delegate {
public:
- virtual ~Delegate() {}
-
// Called (at most once) when a connection has been established.
// |base_task| can be used by the client as the parent of any Task
// it creates as long as it is valid (i.e., non-NULL).
@@ -52,22 +50,25 @@ class XmppConnection : public sigslot::has_slots<> {
// is non-NULL iff |error| == ERROR_STREAM. |stream_error| is
// valid only for the lifetime of this function.
//
- // Ideally, |error| would be set to something that is not
+ // Ideally, |error| would always be set to something that is not
// ERROR_NONE, but due to inconsistent error-handling this doesn't
// always happen.
virtual void OnError(buzz::XmppEngine::Error error, int subcode,
const buzz::XmlElement* stream_error) = 0;
+
+ protected:
+ virtual ~Delegate();
};
- // Does not take ownership of |cert_verifier|, which may not be NULL.
- // Does not take ownership of |delegate|, which may not be NULL.
- // Takes ownership of |pre_xmpp_auth|, which may be NULL.
+ // Does not take ownership of |delegate|, which must not be
+ // NULL. Takes ownership of |pre_xmpp_auth|, which may be NULL.
//
// TODO(akalin): Avoid the need for |pre_xmpp_auth|.
XmppConnection(const buzz::XmppClientSettings& xmpp_client_settings,
const scoped_refptr<net::URLRequestContextGetter>&
request_context_getter,
- Delegate* delegate, buzz::PreXmppAuth* pre_xmpp_auth);
+ Delegate* delegate,
+ buzz::PreXmppAuth* pre_xmpp_auth);
// Invalidates any weak pointers passed to the delegate by
// OnConnect(), but does not trigger a call to the delegate's
diff --git a/jingle/notifier/communicator/DEPS b/jingle/notifier/communicator/DEPS
new file mode 100644
index 0000000..fe7e23f
--- /dev/null
+++ b/jingle/notifier/communicator/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ # Need for cricket::ProtocolType.
+ "+talk/p2p/base/port.h",
+]
diff --git a/jingle/notifier/communicator/connection_options.cc b/jingle/notifier/communicator/connection_options.cc
deleted file mode 100644
index c103127..0000000
--- a/jingle/notifier/communicator/connection_options.cc
+++ /dev/null
@@ -1,16 +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 "jingle/notifier/communicator/connection_options.h"
-
-namespace notifier {
-
-ConnectionOptions::ConnectionOptions()
- : autodetect_proxy_(true),
- proxy_port_(0),
- use_proxy_auth_(0),
- allow_unverified_certs_(false) {
-}
-
-} // namespace notifier
diff --git a/jingle/notifier/communicator/connection_options.h b/jingle/notifier/communicator/connection_options.h
deleted file mode 100644
index 4f24b44..0000000
--- a/jingle/notifier/communicator/connection_options.h
+++ /dev/null
@@ -1,53 +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 JINGLE_NOTIFIER_COMMUNICATOR_CONNECTION_OPTIONS_H_
-#define JINGLE_NOTIFIER_COMMUNICATOR_CONNECTION_OPTIONS_H_
-
-#include <string>
-
-#include "talk/base/cryptstring.h"
-#include "talk/base/helpers.h"
-
-namespace notifier {
-
-class ConnectionOptions {
- public:
- ConnectionOptions();
-
- bool autodetect_proxy() const { return autodetect_proxy_; }
- const std::string& proxy_host() const { return proxy_host_; }
- int proxy_port() const { return proxy_port_; }
- bool use_proxy_auth() const { return use_proxy_auth_; }
- const std::string& auth_user() const { return auth_user_; }
- const talk_base::CryptString& auth_pass() const { return auth_pass_; }
- bool allow_unverified_certs() const { return allow_unverified_certs_; }
-
- void set_autodetect_proxy(bool f) { autodetect_proxy_ = f; }
- void set_proxy_host(const std::string& val) { proxy_host_ = val; }
- void set_proxy_port(int val) { proxy_port_ = val; }
- void set_use_proxy_auth(bool f) { use_proxy_auth_ = f; }
- void set_auth_user(const std::string& val) { auth_user_ = val; }
- void set_auth_pass(const talk_base::CryptString& val) { auth_pass_ = val; }
-
- // Setting this to true opens a security hole, so it is *highly* recommended
- // that you don't do this.
- void set_allow_unverified_certs(bool allow_unverified_certs) {
- allow_unverified_certs_ = allow_unverified_certs;
- }
-
- private:
- bool autodetect_proxy_;
- std::string proxy_host_;
- int proxy_port_;
- bool use_proxy_auth_;
- std::string auth_user_;
- talk_base::CryptString auth_pass_;
- bool allow_unverified_certs_;
- // Allow the copy constructor and operator=.
-};
-
-} // namespace notifier
-
-#endif // JINGLE_NOTIFIER_COMMUNICATOR_CONNECTION_OPTIONS_H_
diff --git a/jingle/notifier/communicator/connection_settings.cc b/jingle/notifier/communicator/connection_settings.cc
index d4b764c..862f905 100644
--- a/jingle/notifier/communicator/connection_settings.cc
+++ b/jingle/notifier/communicator/connection_settings.cc
@@ -1,111 +1,102 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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 <algorithm>
-#include <deque>
-#include <string>
-#include <vector>
+#include "jingle/notifier/communicator/connection_settings.h"
#include "base/logging.h"
-#include "jingle/notifier/communicator/connection_settings.h"
-#include "talk/base/helpers.h"
+
+// Ideally we shouldn't include anything from talk/p2p, but we need
+// the definition of ProtocolType. Don't use any functions from
+// port.h, since it won't link.
+#include "talk/p2p/base/port.h"
+
#include "talk/xmpp/xmppclientsettings.h"
namespace notifier {
-class RandomGenerator {
- public:
- int operator()(int ceiling) {
- return static_cast<int>(talk_base::CreateRandomId() % ceiling);
- }
-};
+const uint16 kSslTcpPort = 443;
+
+ConnectionSettings::ConnectionSettings(
+ const talk_base::SocketAddress& server,
+ SslTcpMode ssltcp_mode,
+ SslTcpSupport ssltcp_support)
+ : server(server),
+ ssltcp_mode(ssltcp_mode),
+ ssltcp_support(ssltcp_support) {}
-ConnectionSettings::ConnectionSettings() : protocol_(cricket::PROTO_TCP) {}
+ConnectionSettings::ConnectionSettings()
+ : ssltcp_mode(DO_NOT_USE_SSLTCP),
+ ssltcp_support(DOES_NOT_SUPPORT_SSLTCP) {}
ConnectionSettings::~ConnectionSettings() {}
-void ConnectionSettings::FillXmppClientSettings(
- buzz::XmppClientSettings* xcs) const {
- DCHECK(xcs);
- xcs->set_protocol(protocol_);
- xcs->set_server(server_);
- xcs->set_proxy(talk_base::PROXY_NONE);
- xcs->set_use_proxy_auth(false);
+bool ConnectionSettings::Equals(const ConnectionSettings& settings) const {
+ return
+ server == settings.server &&
+ ssltcp_mode == settings.ssltcp_mode &&
+ ssltcp_support == settings.ssltcp_support;
}
-ConnectionSettingsList::ConnectionSettingsList() {}
-
-ConnectionSettingsList::~ConnectionSettingsList() {}
-
-void ConnectionSettingsList::AddPermutations(const std::string& hostname,
- const std::vector<uint32>& iplist,
- uint16 port,
- bool special_port_magic,
- bool try_ssltcp_first) {
- // randomize the list. This ensures the iplist isn't always
- // evaluated in the order returned by DNS
- std::vector<uint32> iplist_random = iplist;
- RandomGenerator rg;
- std::random_shuffle(iplist_random.begin(), iplist_random.end(), rg);
-
- // Put generated addresses in a new deque, then append on the list_, since
- // there are order dependencies and AddPermutations() may be called more
- // than once.
- std::deque<ConnectionSettings> list_temp;
-
- // Permute addresses for this server. In some cases we haven't resolved the
- // to ip addresses.
- talk_base::SocketAddress server(hostname, port);
- if (iplist_random.empty()) {
- // We couldn't pre-resolve the hostname, so let's hope it will resolve
- // further down the pipeline (by a proxy, for example).
- PermuteForAddress(server, special_port_magic, try_ssltcp_first,
- &list_temp);
- } else {
- // Generate a set of possibilities for each server address.
- // Don't do permute duplicates.
- for (size_t index = 0; index < iplist_random.size(); ++index) {
- if (std::find(iplist_seen_.begin(), iplist_seen_.end(),
- iplist_random[index]) != iplist_seen_.end()) {
- continue;
- }
- iplist_seen_.push_back(iplist_random[index]);
- server.SetResolvedIP(iplist_random[index]);
- PermuteForAddress(server, special_port_magic, try_ssltcp_first,
- &list_temp);
- }
- }
+namespace {
- // Add this list to the instance list
- while (!list_temp.empty()) {
- list_.push_back(list_temp[0]);
- list_temp.pop_front();
- }
+const char* SslTcpModeToString(SslTcpMode ssltcp_mode) {
+ return (ssltcp_mode == USE_SSLTCP) ? "USE_SSLTCP" : "DO_NOT_USE_SSLTCP";
}
+const char* SslTcpSupportToString(SslTcpSupport ssltcp_support) {
+ return
+ (ssltcp_support == SUPPORTS_SSLTCP) ?
+ "SUPPORTS_SSLTCP" :
+ "DOES_NOT_SUPPORT_SSLTCP";
+}
-void ConnectionSettingsList::PermuteForAddress(
- const talk_base::SocketAddress& server,
- bool special_port_magic,
- bool try_ssltcp_first,
- std::deque<ConnectionSettings>* list_temp) {
- DCHECK(list_temp);
- *(template_.mutable_server()) = server;
-
- // Use all of the original settings
- list_temp->push_back(template_);
-
- // Try alternate port
- if (special_port_magic) {
- ConnectionSettings settings(template_);
- settings.set_protocol(cricket::PROTO_SSLTCP);
- settings.mutable_server()->SetPort(443);
- if (try_ssltcp_first) {
- list_temp->push_front(settings);
+} // namespace
+
+std::string ConnectionSettings::ToString() const {
+ return
+ server.ToString() + ":" + SslTcpModeToString(ssltcp_mode) + ":" +
+ SslTcpSupportToString(ssltcp_support);
+}
+
+void ConnectionSettings::FillXmppClientSettings(
+ buzz::XmppClientSettings* client_settings) const {
+ client_settings->set_protocol(
+ (ssltcp_mode == USE_SSLTCP) ?
+ cricket::PROTO_SSLTCP :
+ cricket::PROTO_TCP);
+ client_settings->set_server(server);
+}
+
+ConnectionSettingsList MakeConnectionSettingsList(
+ const ServerList& servers,
+ bool try_ssltcp_first) {
+ ConnectionSettingsList settings_list;
+
+ for (ServerList::const_iterator it = servers.begin();
+ it != servers.end(); ++it) {
+ const ConnectionSettings settings(
+ talk_base::SocketAddress(it->server.host(), it->server.port()),
+ DO_NOT_USE_SSLTCP, it->ssltcp_support);
+
+ if (it->ssltcp_support == SUPPORTS_SSLTCP) {
+ const ConnectionSettings settings_with_ssltcp(
+ talk_base::SocketAddress(it->server.host(), kSslTcpPort),
+ USE_SSLTCP, it->ssltcp_support);
+
+ if (try_ssltcp_first) {
+ settings_list.push_back(settings_with_ssltcp);
+ settings_list.push_back(settings);
+ } else {
+ settings_list.push_back(settings);
+ settings_list.push_back(settings_with_ssltcp);
+ }
} else {
- list_temp->push_back(settings);
+ settings_list.push_back(settings);
}
}
+
+ return settings_list;
}
+
} // namespace notifier
diff --git a/jingle/notifier/communicator/connection_settings.h b/jingle/notifier/communicator/connection_settings.h
index 91c95af..fe0f6b0 100644
--- a/jingle/notifier/communicator/connection_settings.h
+++ b/jingle/notifier/communicator/connection_settings.h
@@ -1,67 +1,58 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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 JINGLE_NOTIFIER_COMMUNICATOR_CONNECTION_SETTINGS_H_
#define JINGLE_NOTIFIER_COMMUNICATOR_CONNECTION_SETTINGS_H_
-#include <deque>
#include <string>
#include <vector>
#include "base/basictypes.h"
-#include "talk/xmpp/xmppclientsettings.h"
+#include "jingle/notifier/base/server_information.h"
+#include "talk/base/socketaddress.h"
+
+namespace buzz {
+class XmppClientSettings;
+} // namespace
namespace notifier {
-class ConnectionSettings {
+// The port for SSLTCP (just the regular port for SSL).
+extern const uint16 kSslTcpPort;
+
+enum SslTcpMode { DO_NOT_USE_SSLTCP, USE_SSLTCP };
+
+struct ConnectionSettings {
public:
+ ConnectionSettings(const talk_base::SocketAddress& server,
+ SslTcpMode ssltcp_mode,
+ SslTcpSupport ssltcp_support);
ConnectionSettings();
~ConnectionSettings();
- cricket::ProtocolType protocol() { return protocol_; }
- const talk_base::SocketAddress& server() const { return server_; }
+ bool Equals(const ConnectionSettings& settings) const;
- void set_protocol(cricket::ProtocolType protocol) { protocol_ = protocol; }
- talk_base::SocketAddress* mutable_server() { return &server_; }
+ std::string ToString() const;
- void FillXmppClientSettings(buzz::XmppClientSettings* xcs) const;
+ // Fill in the connection-related fields of |client_settings|.
+ void FillXmppClientSettings(buzz::XmppClientSettings* client_settings) const;
- private:
- cricket::ProtocolType protocol_; // PROTO_TCP, PROTO_SSLTCP, etc.
- talk_base::SocketAddress server_; // Server.
- // Need copy constructor due to use in stl deque.
+ talk_base::SocketAddress server;
+ SslTcpMode ssltcp_mode;
+ SslTcpSupport ssltcp_support;
};
-class ConnectionSettingsList {
- public:
- ConnectionSettingsList();
- ~ConnectionSettingsList();
-
- int GetCount() { return list_.size(); }
- ConnectionSettings* GetSettings(size_t index) { return &list_[index]; }
-
- void ClearPermutations() {
- list_.clear();
- iplist_seen_.clear();
- }
-
- void AddPermutations(const std::string& hostname,
- const std::vector<uint32>& iplist,
- uint16 port,
- bool special_port_magic,
- bool try_ssltcp_first);
- private:
- void PermuteForAddress(const talk_base::SocketAddress& server,
- bool special_port_magic,
- bool try_ssltcp_first,
- std::deque<ConnectionSettings>* list_temp);
-
- ConnectionSettings template_;
- std::deque<ConnectionSettings> list_;
- std::vector<uint32> iplist_seen_;
- DISALLOW_COPY_AND_ASSIGN(ConnectionSettingsList);
-};
+typedef std::vector<ConnectionSettings> ConnectionSettingsList;
+
+// Given a list of servers in priority order, generate a list of
+// ConnectionSettings to try in priority order. If |try_ssltcp_first|
+// is set, for each server that supports SSLTCP, the
+// ConnectionSettings using SSLTCP will come first. If it is not set,
+// the ConnectionSettings using SSLTCP will come last.
+ConnectionSettingsList MakeConnectionSettingsList(
+ const ServerList& servers,
+ bool try_ssltcp_first);
} // namespace notifier
diff --git a/jingle/notifier/communicator/connection_settings_unittest.cc b/jingle/notifier/communicator/connection_settings_unittest.cc
new file mode 100644
index 0000000..c7e0c4c
--- /dev/null
+++ b/jingle/notifier/communicator/connection_settings_unittest.cc
@@ -0,0 +1,99 @@
+// Copyright (c) 2012 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 "jingle/notifier/communicator/connection_settings.h"
+
+#include "jingle/notifier/base/server_information.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace notifier {
+
+namespace {
+
+class ConnectionSettingsTest : public ::testing::Test {
+ protected:
+ ConnectionSettingsTest() {
+ servers_.push_back(
+ ServerInformation(
+ net::HostPortPair("supports_ssltcp.com", 100),
+ SUPPORTS_SSLTCP));
+ servers_.push_back(
+ ServerInformation(
+ net::HostPortPair("does_not_support_ssltcp.com", 200),
+ DOES_NOT_SUPPORT_SSLTCP));
+ }
+
+ ServerList servers_;
+};
+
+// An empty server list should always map to an empty connection
+// settings list.
+TEST_F(ConnectionSettingsTest, Empty) {
+ EXPECT_TRUE(MakeConnectionSettingsList(ServerList(), false).empty());
+ EXPECT_TRUE(MakeConnectionSettingsList(ServerList(), true).empty());
+}
+
+// Make sure that servers that support SSLTCP get mapped to two
+// settings entries (with the SSLTCP one coming last) whereas those
+// that don't map to only one.
+TEST_F(ConnectionSettingsTest, Basic) {
+ const ConnectionSettingsList settings_list =
+ MakeConnectionSettingsList(servers_, false /* try_ssltcp_first */);
+
+ ConnectionSettingsList expected_settings_list;
+ expected_settings_list.push_back(
+ ConnectionSettings(
+ talk_base::SocketAddress("supports_ssltcp.com", 100),
+ DO_NOT_USE_SSLTCP,
+ SUPPORTS_SSLTCP));
+ expected_settings_list.push_back(
+ ConnectionSettings(
+ talk_base::SocketAddress("supports_ssltcp.com", 443),
+ USE_SSLTCP,
+ SUPPORTS_SSLTCP));
+ expected_settings_list.push_back(
+ ConnectionSettings(
+ talk_base::SocketAddress("does_not_support_ssltcp.com", 200),
+ DO_NOT_USE_SSLTCP,
+ DOES_NOT_SUPPORT_SSLTCP));
+
+ ASSERT_EQ(expected_settings_list.size(), settings_list.size());
+ for (size_t i = 0; i < settings_list.size(); ++i) {
+ EXPECT_TRUE(settings_list[i].Equals(expected_settings_list[i]));
+ }
+}
+
+// Make sure that servers that support SSLTCP get mapped to two
+// settings entries (with the SSLTCP one coming first) when
+// try_ssltcp_first is set.
+TEST_F(ConnectionSettingsTest, TrySslTcpFirst) {
+ const ConnectionSettingsList settings_list =
+ MakeConnectionSettingsList(servers_, true /* try_ssltcp_first */);
+
+ ConnectionSettingsList expected_settings_list;
+ expected_settings_list.push_back(
+ ConnectionSettings(
+ talk_base::SocketAddress("supports_ssltcp.com", 443),
+ USE_SSLTCP,
+ SUPPORTS_SSLTCP));
+ expected_settings_list.push_back(
+ ConnectionSettings(
+ talk_base::SocketAddress("supports_ssltcp.com", 100),
+ DO_NOT_USE_SSLTCP,
+ SUPPORTS_SSLTCP));
+ expected_settings_list.push_back(
+ ConnectionSettings(
+ talk_base::SocketAddress("does_not_support_ssltcp.com", 200),
+ DO_NOT_USE_SSLTCP,
+ DOES_NOT_SUPPORT_SSLTCP));
+
+ ASSERT_EQ(expected_settings_list.size(), settings_list.size());
+ for (size_t i = 0; i < settings_list.size(); ++i) {
+ EXPECT_TRUE(settings_list[i].Equals(expected_settings_list[i]));
+ }
+}
+
+} // namespace
+
+} // namespace notifier
diff --git a/jingle/notifier/communicator/login.cc b/jingle/notifier/communicator/login.cc
index bc960b5..886ea84 100644
--- a/jingle/notifier/communicator/login.cc
+++ b/jingle/notifier/communicator/login.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -9,9 +9,6 @@
#include "base/logging.h"
#include "base/rand_util.h"
#include "base/time.h"
-#include "jingle/notifier/communicator/connection_options.h"
-#include "jingle/notifier/communicator/login_settings.h"
-#include "jingle/notifier/communicator/single_login_attempt.h"
#include "net/base/host_port_pair.h"
#include "talk/base/common.h"
#include "talk/base/firewallsocketserver.h"
@@ -32,20 +29,17 @@ static const int kRedirectTimeoutMinutes = 5;
Login::Login(Delegate* delegate,
const buzz::XmppClientSettings& user_settings,
- const ConnectionOptions& options,
const scoped_refptr<net::URLRequestContextGetter>&
request_context_getter,
const ServerList& servers,
bool try_ssltcp_first,
const std::string& auth_mechanism)
: delegate_(delegate),
- login_settings_(new LoginSettings(user_settings,
- options,
- request_context_getter,
- servers,
- try_ssltcp_first,
- auth_mechanism)),
- redirect_port_(0) {
+ login_settings_(user_settings,
+ request_context_getter,
+ servers,
+ try_ssltcp_first,
+ auth_mechanism) {
net::NetworkChangeNotifier::AddIPAddressObserver(this);
ResetReconnectState();
}
@@ -55,25 +49,12 @@ Login::~Login() {
}
void Login::StartConnection() {
- // If there is a server redirect, use it.
- if (base::Time::Now() <
- (redirect_time_ +
- base::TimeDelta::FromMinutes(kRedirectTimeoutMinutes))) {
- // Override server/port with redirect values.
- DCHECK_NE(redirect_port_, 0);
- net::HostPortPair server_override(redirect_server_, redirect_port_);
- login_settings_->set_server_override(server_override);
- } else {
- login_settings_->clear_server_override();
- }
-
VLOG(1) << "Starting connection...";
-
- single_attempt_.reset(new SingleLoginAttempt(login_settings_.get(), this));
+ single_attempt_.reset(new SingleLoginAttempt(login_settings_, this));
}
void Login::UpdateXmppSettings(const buzz::XmppClientSettings& user_settings) {
- *(login_settings_->modifiable_user_settings()) = user_settings;
+ login_settings_.set_user_settings(user_settings);
}
void Login::OnConnect(base::WeakPtr<buzz::XmppTaskParentInterface> base_task) {
@@ -85,13 +66,8 @@ void Login::OnNeedReconnect() {
TryReconnect();
}
-void Login::OnRedirect(const std::string& redirect_server, int redirect_port) {
- DCHECK_NE(redirect_port_, 0);
-
- redirect_time_ = base::Time::Now();
- redirect_server_ = redirect_server;
- redirect_port_ = redirect_port;
-
+void Login::OnRedirect(const ServerInformation& redirect_server) {
+ login_settings_.SetRedirectServer(redirect_server);
// Drop the current connection, and start the login process again.
StartConnection();
}
diff --git a/jingle/notifier/communicator/login.h b/jingle/notifier/communicator/login.h
index d3bbfd4..d0667b1 100644
--- a/jingle/notifier/communicator/login.h
+++ b/jingle/notifier/communicator/login.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -14,6 +14,7 @@
#include "base/time.h"
#include "base/timer.h"
#include "jingle/notifier/base/server_information.h"
+#include "jingle/notifier/communicator/login_settings.h"
#include "jingle/notifier/communicator/single_login_attempt.h"
#include "net/base/network_change_notifier.h"
#include "talk/xmpp/xmppengine.h"
@@ -30,7 +31,6 @@ class URLRequestContextGetter;
namespace notifier {
-class ConnectionOptions;
class LoginSettings;
// Workaround for MSVS 2005 bug that fails to handle inheritance from a nested
@@ -52,11 +52,9 @@ class Login : public net::NetworkChangeNotifier::IPAddressObserver,
virtual void OnDisconnect() = 0;
};
- // Does not take ownership of |delegate|, |host_resolver|, |cert_verifier|,
- // or |server_list|, none of which may be NULL.
+ // Does not take ownership of |delegate|, which must not be NULL.
Login(Delegate* delegate,
const buzz::XmppClientSettings& user_settings,
- const ConnectionOptions& options,
const scoped_refptr<net::URLRequestContextGetter>&
request_context_getter,
const ServerList& servers,
@@ -76,8 +74,7 @@ class Login : public net::NetworkChangeNotifier::IPAddressObserver,
virtual void OnConnect(
base::WeakPtr<buzz::XmppTaskParentInterface> base_task) OVERRIDE;
virtual void OnNeedReconnect() OVERRIDE;
- virtual void OnRedirect(const std::string& redirect_server,
- int redirect_port) OVERRIDE;
+ virtual void OnRedirect(const ServerInformation& redirect_server) OVERRIDE;
private:
void OnLogoff();
@@ -94,19 +91,14 @@ class Login : public net::NetworkChangeNotifier::IPAddressObserver,
// reconnection.
void DoReconnect();
- Delegate* delegate_;
- scoped_ptr<LoginSettings> login_settings_;
+ Delegate* const delegate_;
+ LoginSettings login_settings_;
scoped_ptr<SingleLoginAttempt> single_attempt_;
// reconnection state.
base::TimeDelta reconnect_interval_;
base::OneShotTimer<Login> reconnect_timer_;
- // server redirect information
- base::Time redirect_time_;
- std::string redirect_server_;
- int redirect_port_;
-
DISALLOW_COPY_AND_ASSIGN(Login);
};
diff --git a/jingle/notifier/communicator/login_settings.cc b/jingle/notifier/communicator/login_settings.cc
index f36e739..762d96c 100644
--- a/jingle/notifier/communicator/login_settings.cc
+++ b/jingle/notifier/communicator/login_settings.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -8,44 +8,65 @@
#include "base/logging.h"
#include "jingle/notifier/base/server_information.h"
-#include "jingle/notifier/communicator/connection_options.h"
-#include "jingle/notifier/communicator/xmpp_connection_generator.h"
#include "net/base/cert_verifier.h"
#include "talk/base/common.h"
#include "talk/base/socketaddress.h"
-#include "talk/xmpp/xmppclientsettings.h"
namespace notifier {
LoginSettings::LoginSettings(const buzz::XmppClientSettings& user_settings,
- const ConnectionOptions& options,
const scoped_refptr<net::URLRequestContextGetter>&
request_context_getter,
- const ServerList& servers,
+ const ServerList& default_servers,
bool try_ssltcp_first,
const std::string& auth_mechanism)
- : try_ssltcp_first_(try_ssltcp_first),
- request_context_getter_(request_context_getter),
- servers_(servers),
- user_settings_(new buzz::XmppClientSettings(user_settings)),
- connection_options_(new ConnectionOptions(options)),
- auth_mechanism_(auth_mechanism) {
- DCHECK_GT(servers_.size(), 0u);
+ : user_settings_(user_settings),
+ request_context_getter_(request_context_getter),
+ default_servers_(default_servers),
+ try_ssltcp_first_(try_ssltcp_first),
+ auth_mechanism_(auth_mechanism) {
+ DCHECK_GT(default_servers_.size(), 0u);
}
-// Defined so that the destructors are executed here (and the corresponding
-// classes don't need to be included in the header file).
-LoginSettings::~LoginSettings() {
+LoginSettings::~LoginSettings() {}
+
+void LoginSettings::set_user_settings(
+ const buzz::XmppClientSettings& user_settings) {
+ user_settings_ = user_settings;
+}
+
+ServerList LoginSettings::GetServers() const {
+ return GetServersForTime(base::Time::Now());
+}
+
+namespace {
+
+// How long a redirect is valid for.
+const int kRedirectExpirationTimeMinutes = 5;
+
+} // namespace
+
+void LoginSettings::SetRedirectServer(
+ const ServerInformation& redirect_server) {
+ redirect_server_ = redirect_server;
+ redirect_expiration_ =
+ base::Time::Now() +
+ base::TimeDelta::FromMinutes(kRedirectExpirationTimeMinutes);
+}
+
+ServerList LoginSettings::GetServersForTimeForTest(base::Time now) const {
+ return GetServersForTime(now);
}
-void LoginSettings::set_server_override(
- const net::HostPortPair& server) {
- server_override_.reset(
- new ServerInformation(server, servers_[0].special_port_magic));
+base::Time LoginSettings::GetRedirectExpirationForTest() const {
+ return redirect_expiration_;
}
-void LoginSettings::clear_server_override() {
- server_override_.reset();
+ServerList LoginSettings::GetServersForTime(base::Time now) const {
+ return
+ (now < redirect_expiration_) ?
+ ServerList(1, redirect_server_) :
+ default_servers_;
}
} // namespace notifier
diff --git a/jingle/notifier/communicator/login_settings.h b/jingle/notifier/communicator/login_settings.h
index 7899cef..7ccc109 100644
--- a/jingle/notifier/communicator/login_settings.h
+++ b/jingle/notifier/communicator/login_settings.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -7,74 +7,68 @@
#include <string>
#include "base/memory/ref_counted.h"
+#include "base/time.h"
#include "jingle/notifier/base/server_information.h"
-#include "jingle/notifier/communicator/xmpp_connection_generator.h"
#include "net/url_request/url_request_context_getter.h"
-
-namespace buzz {
-class XmppClientSettings;
-}
+#include "talk/xmpp/xmppclientsettings.h"
namespace notifier {
-class ConnectionOptions;
class LoginSettings {
public:
LoginSettings(const buzz::XmppClientSettings& user_settings,
- const ConnectionOptions& options,
const scoped_refptr<net::URLRequestContextGetter>&
request_context_getter,
- const ServerList& servers,
+ const ServerList& default_servers,
bool try_ssltcp_first,
const std::string& auth_mechanism);
~LoginSettings();
- bool try_ssltcp_first() const {
- return try_ssltcp_first_;
+ // Copy constructor and assignment operator welcome.
+
+ const buzz::XmppClientSettings& user_settings() const {
+ return user_settings_;
}
- scoped_refptr<net::URLRequestContextGetter> request_context_getter() {
+ void set_user_settings(const buzz::XmppClientSettings& user_settings);
+
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter() const {
return request_context_getter_;
}
- ServerList servers() const {
- return
- server_override_.get() ? ServerList(1, *server_override_) : servers_;
+ bool try_ssltcp_first() const {
+ return try_ssltcp_first_;
}
- const buzz::XmppClientSettings& user_settings() const {
- return *user_settings_.get();
+ const std::string& auth_mechanism() const {
+ return auth_mechanism_;
}
- buzz::XmppClientSettings* modifiable_user_settings() {
- return user_settings_.get();
- }
+ ServerList GetServers() const;
- const ConnectionOptions& connection_options() const {
- return *connection_options_.get();
- }
+ // The redirect server will eventually expire.
+ void SetRedirectServer(const ServerInformation& redirect_server);
- void set_server_override(const net::HostPortPair& server);
- void clear_server_override();
+ ServerList GetServersForTimeForTest(base::Time now) const;
- std::string auth_mechanism() const {
- return auth_mechanism_;
- }
+ base::Time GetRedirectExpirationForTest() const;
private:
- bool try_ssltcp_first_;
+ ServerList GetServersForTime(base::Time now) const;
+ buzz::XmppClientSettings user_settings_;
scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
- const ServerList servers_;
- // Used to handle redirects
- scoped_ptr<ServerInformation> server_override_;
-
- scoped_ptr<buzz::XmppClientSettings> user_settings_;
- scoped_ptr<ConnectionOptions> connection_options_;
+ ServerList default_servers_;
+ bool try_ssltcp_first_;
std::string auth_mechanism_;
- DISALLOW_COPY_AND_ASSIGN(LoginSettings);
+ // Used to handle redirects
+ ServerInformation redirect_server_;
+ base::Time redirect_expiration_;
+
};
+
} // namespace notifier
+
#endif // JINGLE_NOTIFIER_COMMUNICATOR_LOGIN_SETTINGS_H_
diff --git a/jingle/notifier/communicator/login_settings_unittest.cc b/jingle/notifier/communicator/login_settings_unittest.cc
new file mode 100644
index 0000000..5919d1d
--- /dev/null
+++ b/jingle/notifier/communicator/login_settings_unittest.cc
@@ -0,0 +1,77 @@
+// Copyright (c) 2012 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 "jingle/notifier/communicator/login_settings.h"
+
+#include <cstddef>
+
+#include "talk/xmpp/xmppclientsettings.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace notifier {
+
+namespace {
+
+const char kAuthMechanism[] = "auth_mechanism";
+
+class LoginSettingsTest : public ::testing::Test {
+ protected:
+ LoginSettingsTest() {
+ servers_.push_back(
+ ServerInformation(
+ net::HostPortPair("default.com", 100),
+ DOES_NOT_SUPPORT_SSLTCP));
+ }
+
+ ServerList servers_;
+};
+
+TEST_F(LoginSettingsTest, Basic) {
+ const LoginSettings login_settings(buzz::XmppClientSettings(),
+ NULL,
+ servers_,
+ false /* try_ssltcp_first */,
+ kAuthMechanism);
+ EXPECT_EQ(base::Time(), login_settings.GetRedirectExpirationForTest());
+ const ServerList& servers = login_settings.GetServers();
+ ASSERT_EQ(servers_.size(), servers.size());
+ for (size_t i = 0; i < servers.size(); ++i) {
+ EXPECT_TRUE(servers[i].Equals(servers_[i]));
+ }
+}
+
+TEST_F(LoginSettingsTest, Redirect) {
+ LoginSettings login_settings(buzz::XmppClientSettings(),
+ NULL,
+ servers_,
+ false /* try_ssltcp_first */,
+ kAuthMechanism);
+ const ServerInformation redirect_server(
+ net::HostPortPair("redirect.com", 200),
+ SUPPORTS_SSLTCP);
+ login_settings.SetRedirectServer(redirect_server);
+
+ {
+ const ServerList& servers =
+ login_settings.GetServersForTimeForTest(
+ login_settings.GetRedirectExpirationForTest() -
+ base::TimeDelta::FromMilliseconds(1));
+ ASSERT_EQ(servers_.size(), 1u);
+ EXPECT_TRUE(servers[0].Equals(redirect_server));
+ }
+
+ {
+ const ServerList& servers =
+ login_settings.GetServersForTimeForTest(
+ login_settings.GetRedirectExpirationForTest());
+ ASSERT_EQ(servers_.size(), servers.size());
+ for (size_t i = 0; i < servers.size(); ++i) {
+ EXPECT_TRUE(servers[i].Equals(servers_[i]));
+ }
+ }
+}
+
+} // namespace
+
+} // namespace notifier
diff --git a/jingle/notifier/communicator/single_login_attempt.cc b/jingle/notifier/communicator/single_login_attempt.cc
index 3088f6e..dfaa03a 100644
--- a/jingle/notifier/communicator/single_login_attempt.cc
+++ b/jingle/notifier/communicator/single_login_attempt.cc
@@ -1,50 +1,40 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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 <algorithm>
-#include <cstddef>
#include <string>
-#include <vector>
#include "jingle/notifier/communicator/single_login_attempt.h"
-#include "base/compiler_specific.h"
+#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/string_number_conversions.h"
+#include "base/string_split.h"
#include "jingle/notifier/base/const_communicator.h"
#include "jingle/notifier/base/gaia_token_pre_xmpp_auth.h"
-#include "jingle/notifier/communicator/connection_options.h"
-#include "jingle/notifier/communicator/connection_settings.h"
-#include "jingle/notifier/communicator/login_settings.h"
#include "jingle/notifier/listener/xml_element_util.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_context_getter.h"
+#include "net/base/host_port_pair.h"
#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/xmppclient.h"
-#include "talk/xmpp/xmppclientsettings.h"
#include "talk/xmpp/constants.h"
-
-namespace net {
-class NetLog;
-} // namespace net
+#include "talk/xmpp/xmppclientsettings.h"
namespace notifier {
-SingleLoginAttempt::SingleLoginAttempt(LoginSettings* login_settings,
+SingleLoginAttempt::Delegate::~Delegate() {}
+
+SingleLoginAttempt::SingleLoginAttempt(const LoginSettings& login_settings,
Delegate* delegate)
: login_settings_(login_settings),
delegate_(delegate),
- connection_generator_(
- ALLOW_THIS_IN_INITIALIZER_LIST(this),
- login_settings_->request_context_getter()->GetURLRequestContext()->
- host_resolver(),
- &login_settings_->connection_options(),
- login_settings_->try_ssltcp_first(),
- login_settings_->servers()) {
- // DNS resolution will happen at a lower layer (we are using the socket
- // pools).
- connection_generator_.SetShouldResolveDNS(false);
- connection_generator_.StartGenerating();
+ settings_list_(
+ MakeConnectionSettingsList(login_settings_.GetServers(),
+ login_settings_.try_ssltcp_first())),
+ current_settings_(settings_list_.begin()) {
+ if (settings_list_.empty()) {
+ NOTREACHED();
+ return;
+ }
+ TryConnect(*current_settings_);
}
SingleLoginAttempt::~SingleLoginAttempt() {}
@@ -54,15 +44,64 @@ void SingleLoginAttempt::OnConnect(
delegate_->OnConnect(base_task);
}
+namespace {
+
+// This function is more permissive than
+// net::HostPortPair::FromString(). If the port is missing or
+// unparseable, it assumes the default XMPP port. The hostname may be
+// empty.
+net::HostPortPair ParseRedirectText(const std::string& redirect_text) {
+ std::vector<std::string> parts;
+ base::SplitString(redirect_text, ':', &parts);
+ net::HostPortPair redirect_server;
+ redirect_server.set_port(kDefaultXmppPort);
+ if (parts.empty()) {
+ return redirect_server;
+ }
+ redirect_server.set_host(parts[0]);
+ if (parts.size() <= 1) {
+ return redirect_server;
+ }
+ // Try to parse the port, falling back to kDefaultXmppPort.
+ int port = kDefaultXmppPort;
+ if (!base::StringToInt(parts[1], &port)) {
+ port = kDefaultXmppPort;
+ }
+ if (port <= 0 || port > kuint16max) {
+ port = kDefaultXmppPort;
+ }
+ redirect_server.set_port(port);
+ return redirect_server;
+}
+
+} // namespace
+
void SingleLoginAttempt::OnError(buzz::XmppEngine::Error error, int subcode,
const buzz::XmlElement* stream_error) {
- VLOG(1) << "Error: " << error << ", subcode: " << subcode;
- if (stream_error) {
- DCHECK_EQ(error, buzz::XmppEngine::ERROR_STREAM);
- VLOG(1) << "Stream error: " << XmlElementToString(*stream_error);
- }
+ DVLOG(1) << "Error: " << error << ", subcode: " << subcode
+ << (stream_error ?
+ (", stream error: " + XmlElementToString(*stream_error)) :
+ "");
- // Check for redirection.
+ DCHECK_EQ(error == buzz::XmppEngine::ERROR_STREAM, stream_error != NULL);
+
+ // Check for redirection. We expect something like:
+ //
+ // <stream:error><see-other-host xmlns="urn:ietf:params:xml:ns:xmpp-streams"/><str:text xmlns:str="urn:ietf:params:xml:ns:xmpp-streams">talk.google.com</str:text></stream:error> [2]
+ //
+ // There are some differences from the spec [1]:
+ //
+ // - we expect a separate text element with the redirection info
+ // (which is the format Google Talk's servers use), whereas the
+ // spec puts the redirection info directly in the see-other-host
+ // element;
+ // - we check for redirection only during login, whereas the
+ // server can send down a redirection at any time according to
+ // the spec. (TODO(akalin): Figure out whether we need to handle
+ // redirection at any other point.)
+ //
+ // [1]: http://xmpp.org/internet-drafts/draft-saintandre-rfc3920bis-08.html#streams-error-conditions-see-other-host
+ // [2]: http://forums.miranda-im.org/showthread.php?24376-GoogleTalk-drops
if (stream_error) {
const buzz::XmlElement* other =
stream_error->FirstNamed(buzz::QN_XSTREAM_SEE_OTHER_HOST);
@@ -73,38 +112,45 @@ void SingleLoginAttempt::OnError(buzz::XmppEngine::Error error, int subcode,
// Yep, its a "stream:error" with "see-other-host" text,
// let's parse out the server:port, and then reconnect
// with that.
- const std::string& redirect = text->BodyText();
- size_t colon = redirect.find(":");
- int redirect_port = kDefaultXmppPort;
- std::string redirect_server;
- if (colon == std::string::npos) {
- redirect_server = redirect;
- } else {
- redirect_server = redirect.substr(0, colon);
- const std::string& port_text = redirect.substr(colon + 1);
- std::istringstream ist(port_text);
- ist >> redirect_port;
- }
- // We never allow a redirect to port 0.
- if (redirect_port == 0) {
- redirect_port = kDefaultXmppPort;
+ const net::HostPortPair& redirect_server =
+ ParseRedirectText(text->BodyText());
+ // ParseRedirectText shouldn't return a zero port.
+ DCHECK_NE(redirect_server.port(), 0u);
+ // If we don't have a host, ignore the redirection and treat
+ // it like a regular error.
+ if (!redirect_server.host().empty()) {
+ delegate_->OnRedirect(
+ ServerInformation(
+ redirect_server,
+ current_settings_->ssltcp_support));
+ // May be deleted at this point.
+ return;
}
- delegate_->OnRedirect(redirect_server, redirect_port);
- // May be deleted at this point.
- return;
}
}
}
- // Iterate to the next possible connection (still trying to connect).
- connection_generator_.UseNextConnection();
+ if (current_settings_ == settings_list_.end()) {
+ NOTREACHED();
+ return;
+ }
+
+ ++current_settings_;
+ if (current_settings_ == settings_list_.end()) {
+ VLOG(1) << "Could not connect to any XMPP server";
+ delegate_->OnNeedReconnect();
+ return;
+ }
+
+ TryConnect(*current_settings_);
}
-void SingleLoginAttempt::OnNewSettings(
+void SingleLoginAttempt::TryConnect(
const ConnectionSettings& connection_settings) {
- buzz::XmppClientSettings client_settings =
- login_settings_->user_settings();
- // Fill in the rest of the client settings.
+ DVLOG(1) << "Trying to connect to " << connection_settings.ToString();
+ // Copy the user settings and fill in the connection parameters from
+ // |connection_settings|.
+ buzz::XmppClientSettings client_settings = login_settings_.user_settings();
connection_settings.FillXmppClientSettings(&client_settings);
buzz::Jid jid(client_settings.user(), client_settings.host(),
@@ -113,20 +159,12 @@ void SingleLoginAttempt::OnNewSettings(
new GaiaTokenPreXmppAuth(
jid.Str(), client_settings.auth_cookie(),
client_settings.token_service(),
- login_settings_->auth_mechanism());
+ login_settings_.auth_mechanism());
xmpp_connection_.reset(
new XmppConnection(client_settings,
- login_settings_->request_context_getter(),
- this, pre_xmpp_auth));
-}
-
-void SingleLoginAttempt::OnExhaustedSettings(
- bool successfully_resolved_dns,
- int first_dns_error) {
- if (!successfully_resolved_dns)
- VLOG(1) << "Could not resolve DNS: " << first_dns_error;
- VLOG(1) << "Could not connect to any XMPP server";
- delegate_->OnNeedReconnect();
+ login_settings_.request_context_getter(),
+ this,
+ pre_xmpp_auth));
}
} // namespace notifier
diff --git a/jingle/notifier/communicator/single_login_attempt.h b/jingle/notifier/communicator/single_login_attempt.h
index 2bdab1f..1e0332d 100644
--- a/jingle/notifier/communicator/single_login_attempt.h
+++ b/jingle/notifier/communicator/single_login_attempt.h
@@ -1,16 +1,15 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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 JINGLE_NOTIFIER_COMMUNICATOR_SINGLE_LOGIN_ATTEMPT_H_
#define JINGLE_NOTIFIER_COMMUNICATOR_SINGLE_LOGIN_ATTEMPT_H_
-#include <string>
-
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "jingle/notifier/base/xmpp_connection.h"
-#include "jingle/notifier/communicator/xmpp_connection_generator.h"
+#include "jingle/notifier/communicator/connection_settings.h"
+#include "jingle/notifier/communicator/login_settings.h"
#include "talk/xmpp/xmppengine.h"
namespace buzz {
@@ -19,30 +18,27 @@ class XmppTaskParentInterface;
namespace notifier {
-class ConnectionSettings;
-class LoginSettings;
+struct ServerInformation;
-// Handles all of the aspects of a single login attempt (across multiple ip
-// addresses) and maintainence. By containing this within one class, when
-// another login attempt is made, this class will be disposed and all of the
-// signalling for the previous login attempt will be cleaned up immediately.
-class SingleLoginAttempt : public XmppConnection::Delegate,
- public XmppConnectionGenerator::Delegate {
+// Handles all of the aspects of a single login attempt. By
+// containing this within one class, when another login attempt is
+// made, this class can be destroyed to immediately stop the previous
+// login attempt.
+class SingleLoginAttempt : public XmppConnection::Delegate {
public:
class Delegate {
public:
- virtual ~Delegate() {}
-
virtual void OnConnect(
base::WeakPtr<buzz::XmppTaskParentInterface> base_task) = 0;
virtual void OnNeedReconnect() = 0;
- virtual void OnRedirect(const std::string& redirect_server,
- int redirect_port) = 0;
+ virtual void OnRedirect(const ServerInformation& redirect_server) = 0;
+
+ protected:
+ virtual ~Delegate();
};
- // Does not take ownership of |login_settings| or |delegate|.
- // Neither may be NULL.
- SingleLoginAttempt(LoginSettings* login_settings, Delegate* delegate);
+ // Does not take ownership of |delegate|, which must not be NULL.
+ SingleLoginAttempt(const LoginSettings& login_settings, Delegate* delegate);
virtual ~SingleLoginAttempt();
@@ -53,15 +49,13 @@ class SingleLoginAttempt : public XmppConnection::Delegate,
int error_subcode,
const buzz::XmlElement* stream_error) OVERRIDE;
- // XmppConnectionGenerator::Delegate implementation.
- virtual void OnNewSettings(const ConnectionSettings& new_settings) OVERRIDE;
- virtual void OnExhaustedSettings(bool successfully_resolved_dns,
- int first_dns_error) OVERRIDE;
-
private:
- LoginSettings* login_settings_;
- Delegate* delegate_;
- XmppConnectionGenerator connection_generator_;
+ void TryConnect(const ConnectionSettings& new_settings);
+
+ const LoginSettings login_settings_;
+ Delegate* const delegate_;
+ const ConnectionSettingsList settings_list_;
+ ConnectionSettingsList::const_iterator current_settings_;
scoped_ptr<XmppConnection> xmpp_connection_;
DISALLOW_COPY_AND_ASSIGN(SingleLoginAttempt);
diff --git a/jingle/notifier/communicator/single_login_attempt_unittest.cc b/jingle/notifier/communicator/single_login_attempt_unittest.cc
new file mode 100644
index 0000000..83f81ff
--- /dev/null
+++ b/jingle/notifier/communicator/single_login_attempt_unittest.cc
@@ -0,0 +1,226 @@
+// Copyright (c) 2012 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 "jingle/notifier/communicator/single_login_attempt.h"
+
+#include <cstddef>
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop.h"
+#include "jingle/notifier/base/const_communicator.h"
+#include "jingle/notifier/base/fake_base_task.h"
+#include "jingle/notifier/communicator/login_settings.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "talk/xmllite/xmlelement.h"
+#include "talk/xmpp/constants.h"
+#include "talk/xmpp/xmppengine.h"
+
+namespace buzz {
+class XmppTaskParentInterface;
+} // namespace buzz
+
+namespace notifier {
+
+namespace {
+
+enum DelegateState { IDLE, CONNECTED, NEED_RECONNECT, REDIRECTED };
+
+class FakeDelegate : public SingleLoginAttempt::Delegate {
+ public:
+ FakeDelegate() : state_(IDLE) {}
+
+ void OnConnect(base::WeakPtr<buzz::XmppTaskParentInterface> base_task) {
+ state_ = CONNECTED;
+ base_task_ = base_task;
+ }
+
+ virtual void OnNeedReconnect() {
+ state_ = NEED_RECONNECT;
+ }
+
+ virtual void OnRedirect(const ServerInformation& redirect_server) OVERRIDE {
+ state_ = REDIRECTED;
+ redirect_server_ = redirect_server;
+ }
+
+ DelegateState state() const { return state_; }
+
+ base::WeakPtr<buzz::XmppTaskParentInterface> base_task() const {
+ return base_task_;
+ }
+
+ const ServerInformation& redirect_server() const {
+ return redirect_server_;
+ }
+
+ private:
+ DelegateState state_;
+ base::WeakPtr<buzz::XmppTaskParentInterface> base_task_;
+ ServerInformation redirect_server_;
+};
+
+class SingleLoginAttemptTest : public ::testing::Test {
+ protected:
+ SingleLoginAttemptTest()
+ : login_settings_(
+ buzz::XmppClientSettings(),
+ new TestURLRequestContextGetter(base::MessageLoopProxy::current()),
+ ServerList(
+ 1,
+ ServerInformation(
+ net::HostPortPair("example.com", 100), SUPPORTS_SSLTCP)),
+ false /* try_ssltcp_first */,
+ "auth_mechanism"),
+ attempt_(login_settings_, &fake_delegate_) {}
+
+ virtual void TearDown() OVERRIDE {
+ message_loop_.RunAllPending();
+ }
+
+ void FireRedirect(buzz::XmlElement* redirect_error) {
+ attempt_.OnError(buzz::XmppEngine::ERROR_STREAM, 0, redirect_error);
+ }
+
+ private:
+ MessageLoop message_loop_;
+ const LoginSettings login_settings_;
+
+ protected:
+ SingleLoginAttempt attempt_;
+ FakeDelegate fake_delegate_;
+ FakeBaseTask fake_base_task_;
+};
+
+// Fire OnConnect and make sure the base task gets passed to the
+// delegate properly.
+TEST_F(SingleLoginAttemptTest, Basic) {
+ attempt_.OnConnect(fake_base_task_.AsWeakPtr());
+ EXPECT_EQ(CONNECTED, fake_delegate_.state());
+ EXPECT_EQ(fake_base_task_.AsWeakPtr().get(),
+ fake_delegate_.base_task().get());
+}
+
+// Fire OnErrors and make sure the delegate gets the OnNeedReconnect()
+// event.
+TEST_F(SingleLoginAttemptTest, Error) {
+ for (int i = 0; i < 2; ++i) {
+ EXPECT_EQ(IDLE, fake_delegate_.state());
+ attempt_.OnError(buzz::XmppEngine::ERROR_NONE, 0, NULL);
+ }
+ EXPECT_EQ(NEED_RECONNECT, fake_delegate_.state());
+}
+
+// Fire OnErrors but replace the last one with OnConnect, and make
+// sure the delegate still gets the OnConnect message.
+TEST_F(SingleLoginAttemptTest, ErrorThenSuccess) {
+ attempt_.OnError(buzz::XmppEngine::ERROR_NONE, 0, NULL);
+ attempt_.OnConnect(fake_base_task_.AsWeakPtr());
+ EXPECT_EQ(CONNECTED, fake_delegate_.state());
+ EXPECT_EQ(fake_base_task_.AsWeakPtr().get(),
+ fake_delegate_.base_task().get());
+}
+
+buzz::XmlElement* MakeRedirectError(const std::string& redirect_server) {
+ buzz::XmlElement* stream_error =
+ new buzz::XmlElement(buzz::QN_STREAM_ERROR, true);
+ stream_error->AddElement(
+ new buzz::XmlElement(buzz::QN_XSTREAM_SEE_OTHER_HOST, true));
+ buzz::XmlElement* text =
+ new buzz::XmlElement(buzz::QN_XSTREAM_TEXT, true);
+ stream_error->AddElement(text);
+ text->SetBodyText(redirect_server);
+ return stream_error;
+}
+
+// Fire a redirect and make sure the delegate gets the proper redirect
+// server info.
+TEST_F(SingleLoginAttemptTest, Redirect) {
+ const ServerInformation redirect_server(
+ net::HostPortPair("example.com", 1000),
+ SUPPORTS_SSLTCP);
+
+ scoped_ptr<buzz::XmlElement> redirect_error(
+ MakeRedirectError(redirect_server.server.ToString()));
+ FireRedirect(redirect_error.get());
+
+ EXPECT_EQ(REDIRECTED, fake_delegate_.state());
+ EXPECT_TRUE(fake_delegate_.redirect_server().Equals(redirect_server));
+}
+
+// Fire a redirect with the host only and make sure the delegate gets
+// the proper redirect server info with the default XMPP port.
+TEST_F(SingleLoginAttemptTest, RedirectHostOnly) {
+ const ServerInformation redirect_server(
+ net::HostPortPair("example.com", kDefaultXmppPort),
+ SUPPORTS_SSLTCP);
+
+ scoped_ptr<buzz::XmlElement> redirect_error(
+ MakeRedirectError(redirect_server.server.host()));
+ FireRedirect(redirect_error.get());
+
+ EXPECT_EQ(REDIRECTED, fake_delegate_.state());
+ EXPECT_TRUE(fake_delegate_.redirect_server().Equals(redirect_server));
+}
+
+// Fire a redirect with a zero port and make sure the delegate gets
+// the proper redirect server info with the default XMPP port.
+TEST_F(SingleLoginAttemptTest, RedirectZeroPort) {
+ const ServerInformation redirect_server(
+ net::HostPortPair("example.com", kDefaultXmppPort),
+ SUPPORTS_SSLTCP);
+
+ scoped_ptr<buzz::XmlElement> redirect_error(
+ MakeRedirectError(redirect_server.server.host() + ":0"));
+ FireRedirect(redirect_error.get());
+
+ EXPECT_EQ(REDIRECTED, fake_delegate_.state());
+ EXPECT_TRUE(fake_delegate_.redirect_server().Equals(redirect_server));
+}
+
+// Fire a redirect with an invalid port and make sure the delegate
+// gets the proper redirect server info with the default XMPP port.
+TEST_F(SingleLoginAttemptTest, RedirectInvalidPort) {
+ const ServerInformation redirect_server(
+ net::HostPortPair("example.com", kDefaultXmppPort),
+ SUPPORTS_SSLTCP);
+
+ scoped_ptr<buzz::XmlElement> redirect_error(
+ MakeRedirectError(redirect_server.server.host() + ":invalidport"));
+ FireRedirect(redirect_error.get());
+
+ EXPECT_EQ(REDIRECTED, fake_delegate_.state());
+ EXPECT_TRUE(fake_delegate_.redirect_server().Equals(redirect_server));
+}
+
+// Fire an empty redirect and make sure the delegate does not get a
+// redirect.
+TEST_F(SingleLoginAttemptTest, RedirectEmpty) {
+ scoped_ptr<buzz::XmlElement> redirect_error(MakeRedirectError(""));
+ FireRedirect(redirect_error.get());
+ EXPECT_EQ(IDLE, fake_delegate_.state());
+}
+
+// Fire a redirect with a missing text element and make sure the
+// delegate does not get a redirect.
+TEST_F(SingleLoginAttemptTest, RedirectMissingText) {
+ scoped_ptr<buzz::XmlElement> redirect_error(MakeRedirectError(""));
+ redirect_error->RemoveChildAfter(redirect_error->FirstChild());
+ FireRedirect(redirect_error.get());
+ EXPECT_EQ(IDLE, fake_delegate_.state());
+}
+
+// Fire a redirect with a missing see-other-host element and make sure
+// the delegate does not get a redirect.
+TEST_F(SingleLoginAttemptTest, RedirectMissingSeeOtherHost) {
+ scoped_ptr<buzz::XmlElement> redirect_error(MakeRedirectError(""));
+ redirect_error->RemoveChildAfter(NULL);
+ FireRedirect(redirect_error.get());
+ EXPECT_EQ(IDLE, fake_delegate_.state());
+}
+
+} // namespace
+
+} // namespace notifier
diff --git a/jingle/notifier/communicator/xmpp_connection_generator.cc b/jingle/notifier/communicator/xmpp_connection_generator.cc
deleted file mode 100644
index 3611dae0..0000000
--- a/jingle/notifier/communicator/xmpp_connection_generator.cc
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright (c) 2012 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.
-//
-// XmppConnectionGenerator does the following algorithm:
-// proxy = ResolveProxyInformation(connection_options)
-// for server in server_list
-// get dns_addresses for server
-// connection_list = (dns_addresses X connection methods X proxy).shuffle()
-// for connection in connection_list
-// yield connection
-
-#include "jingle/notifier/communicator/xmpp_connection_generator.h"
-
-#include <vector>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "base/sys_byteorder.h"
-#include "jingle/notifier/base/server_information.h"
-#include "jingle/notifier/communicator/connection_options.h"
-#include "jingle/notifier/communicator/connection_settings.h"
-#include "net/base/net_errors.h"
-#include "talk/base/httpcommon-inl.h"
-#include "talk/base/task.h"
-#include "talk/base/thread.h"
-#include "talk/xmpp/prexmppauth.h"
-#include "talk/xmpp/xmppclientsettings.h"
-#include "talk/xmpp/xmppengine.h"
-
-namespace notifier {
-
-XmppConnectionGenerator::XmppConnectionGenerator(
- Delegate* delegate,
- net::HostResolver* host_resolver,
- const ConnectionOptions* options,
- bool try_ssltcp_first,
- const ServerList& servers)
- : delegate_(delegate),
- host_resolver_(host_resolver),
- settings_list_(new ConnectionSettingsList()),
- settings_index_(0),
- servers_(servers),
- current_server_(servers_.end()),
- try_ssltcp_first_(try_ssltcp_first),
- successfully_resolved_dns_(false),
- first_dns_error_(0),
- should_resolve_dns_(true),
- options_(options) {
- DCHECK(delegate_);
- DCHECK(host_resolver);
- DCHECK(options_);
- DCHECK_GT(servers_.size(), 0u);
-}
-
-XmppConnectionGenerator::~XmppConnectionGenerator() {
- VLOG(1) << "XmppConnectionGenerator::~XmppConnectionGenerator";
-}
-
-// Starts resolving proxy information.
-void XmppConnectionGenerator::StartGenerating() {
- VLOG(1) << "XmppConnectionGenerator::StartGenerating";
-
- // TODO(akalin): Detect proxy settings once we use Chrome sockets.
-
- // Start iterating through the connections (which are generated on demand).
- UseNextConnection();
-}
-
-namespace {
-
-const char* const PROTO_NAMES[cricket::PROTO_LAST + 1] = {
- "udp", "tcp", "ssltcp"
-};
-
-} // namespace
-
-void XmppConnectionGenerator::UseNextConnection() {
- DCHECK(settings_list_.get());
- // 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.
- ConnectionSettings* settings =
- settings_list_->GetSettings(settings_index_);
- VLOG(1) << "*** Attempting " << PROTO_NAMES[settings->protocol()]
- << " connection to " << settings->server().IPAsString()
- << ":" << settings->server().port();
- delegate_->OnNewSettings(*settings);
- return;
- }
-
- // Iterate to the next possible server.
- if (current_server_ == servers_.end()) {
- current_server_ = servers_.begin();
- } else {
- ++current_server_;
- }
- if (current_server_ == servers_.end()) {
- // All out of possibilities.
- VLOG(1) << "(" << buzz::XmppEngine::ERROR_SOCKET
- << ", " << first_dns_error_ << ")";
- delegate_->OnExhaustedSettings(
- successfully_resolved_dns_, first_dns_error_);
- return;
- }
-
- if (should_resolve_dns_) {
- // Resolve the server.
- const net::HostPortPair& server = current_server_->server;
- net::HostResolver::RequestInfo request_info(server);
- int status =
- host_resolver_.Resolve(
- request_info, &address_list_,
- base::Bind(&XmppConnectionGenerator::OnServerDNSResolved,
- base::Unretained(this)),
- bound_net_log_);
- if (status == net::ERR_IO_PENDING) // OnServerDNSResolved will be called.
- return;
-
- HandleServerDNSResolved(status);
- } else {
- // We are not resolving DNS here (DNS will be resolved by a lower layer).
- // Generate settings using an empty IP list (which will just use the
- // host name for the current server).
- std::vector<uint32> ip_list;
- GenerateSettingsForIPList(ip_list);
- }
- }
-}
-
-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);
- VLOG(1) << "XmppConnectionGenerator::HandleServerDNSResolved";
- // Print logging info.
- VLOG(1) << " server: " << current_server_->server.ToString()
- << ", error: " << status;
- if (status != net::OK) {
- if (first_dns_error_ == 0)
- first_dns_error_ = status;
- return;
- }
-
- // Slurp the addresses into a vector.
- std::vector<uint32> ip_list; // TODO(szym): not IPv6-safe.
- for (size_t i = 0; i < address_list_.size(); ++i) {
- const net::IPEndPoint& addr = address_list_[i];
- DCHECK_EQ(addr.GetFamily(), AF_INET);
- uint32 ip = talk_base::NetworkToHost32(
- *reinterpret_cast<const uint32*>(&addr.address()[0]));
- ip_list.push_back(ip);
- }
- successfully_resolved_dns_ = !ip_list.empty();
-
- for (size_t i = 0; i < ip_list.size(); ++i) {
- VLOG(1) << " ip " << i
- << " : " << talk_base::SocketAddress::IPToString(ip_list[i]);
- }
-
- GenerateSettingsForIPList(ip_list);
-}
-
-void XmppConnectionGenerator::GenerateSettingsForIPList(
- const std::vector<uint32>& ip_list) {
- // Build the ip list.
- DCHECK(settings_list_.get());
- settings_index_ = -1;
- settings_list_->ClearPermutations();
- settings_list_->AddPermutations(
- current_server_->server.host(),
- ip_list,
- current_server_->server.port(),
- current_server_->special_port_magic,
- try_ssltcp_first_);
-}
-
-} // namespace notifier
diff --git a/jingle/notifier/communicator/xmpp_connection_generator.h b/jingle/notifier/communicator/xmpp_connection_generator.h
deleted file mode 100644
index 9f3ad79..0000000
--- a/jingle/notifier/communicator/xmpp_connection_generator.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2011 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 JINGLE_NOTIFIER_COMMUNICATOR_XMPP_CONNECTION_GENERATOR_H_
-#define JINGLE_NOTIFIER_COMMUNICATOR_XMPP_CONNECTION_GENERATOR_H_
-
-#include <vector>
-
-#include "base/memory/scoped_ptr.h"
-#include "net/base/address_list.h"
-#include "net/base/host_resolver.h"
-#include "net/base/net_log.h"
-#include "net/base/single_request_host_resolver.h"
-#include "jingle/notifier/base/server_information.h"
-
-namespace notifier {
-
-class ConnectionOptions;
-class ConnectionSettings;
-class ConnectionSettingsList;
-
-// Resolves dns names and iterates through the various ip address and transport
-// combinations.
-class XmppConnectionGenerator {
- public:
- class Delegate {
- public:
- virtual ~Delegate() {}
-
- virtual void OnNewSettings(const ConnectionSettings& new_settings) = 0;
- virtual void OnExhaustedSettings(bool successfully_resolved_dns,
- int first_dns_error) = 0;
- };
-
- // Does not take ownership of |delegate|.
- // |try_ssltcp_first| indicates that SSLTCP is tried before
- // XMPP. Used by tests.
- // |server_list| is the list of connections to attempt in priority order.
- // |server_count| is the number of items in the server list.
- XmppConnectionGenerator(
- Delegate* delegate,
- net::HostResolver* host_resolver,
- const ConnectionOptions* options,
- bool try_ssltcp_first,
- const ServerList& servers);
- ~XmppConnectionGenerator();
-
- // Only call this once. Create a new XmppConnectionGenerator and delete the
- // current one if the process needs to start again.
- void StartGenerating();
-
- void UseNextConnection();
-
- // TODO(sanjeevr): Rip out the DNS resolution code eventually.
- void SetShouldResolveDNS(bool should_resolve_dns) {
- should_resolve_dns_ = should_resolve_dns;
- }
-
- private:
- void OnServerDNSResolved(int status);
- void HandleServerDNSResolved(int status);
- void GenerateSettingsForIPList(const std::vector<uint32>& ip_list);
-
- Delegate* delegate_;
- net::SingleRequestHostResolver host_resolver_;
- net::AddressList address_list_;
- net::BoundNetLog bound_net_log_;
- scoped_ptr<ConnectionSettingsList> settings_list_;
- int settings_index_; // The setting that is currently being used.
- const ServerList servers_;
- ServerList::const_iterator current_server_;
- bool try_ssltcp_first_; // Used when sync tests are run on chromium builders.
- bool successfully_resolved_dns_;
- int first_dns_error_;
- bool should_resolve_dns_;
- const ConnectionOptions* options_;
-
- DISALLOW_COPY_AND_ASSIGN(XmppConnectionGenerator);
-};
-
-} // namespace notifier
-
-#endif // JINGLE_NOTIFIER_COMMUNICATOR_XMPP_CONNECTION_GENERATOR_H_
diff --git a/jingle/notifier/communicator/xmpp_connection_generator_unittest.cc b/jingle/notifier/communicator/xmpp_connection_generator_unittest.cc
deleted file mode 100644
index b57a3c3..0000000
--- a/jingle/notifier/communicator/xmpp_connection_generator_unittest.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2011 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 "jingle/notifier/communicator/xmpp_connection_generator.h"
-
-#include "base/basictypes.h"
-#include "base/message_loop.h"
-#include "jingle/notifier/communicator/connection_options.h"
-#include "jingle/notifier/communicator/connection_settings.h"
-#include "net/base/host_port_pair.h"
-#include "net/base/mock_host_resolver.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace notifier {
-
-namespace {
-
-using ::testing::_;
-using ::testing::InvokeWithoutArgs;
-
-class MockXmppConnectionGeneratorDelegate
- : public XmppConnectionGenerator::Delegate {
- public:
- MOCK_METHOD1(OnNewSettings, void(const ConnectionSettings&));
- MOCK_METHOD2(OnExhaustedSettings, void(bool, int));
-};
-
-const ServerInformation kXmppServers[] = {
- ServerInformation(net::HostPortPair("www.foo.com", 5222), true),
- ServerInformation(net::HostPortPair("www.bar.com", 8080), false),
- ServerInformation(net::HostPortPair("www.baz.com", 80), true),
-};
-
-class XmppConnectionGeneratorTest : public testing::Test {
- public:
- XmppConnectionGeneratorTest()
- : xmpp_connection_generator_(
- &delegate_,
- &mock_host_resolver_,
- &connection_options_,
- false /* try_ssltcp_first */,
- ServerList(kXmppServers,
- kXmppServers + arraysize(kXmppServers))) {}
-
- virtual ~XmppConnectionGeneratorTest() {}
-
- protected:
- MockXmppConnectionGeneratorDelegate delegate_;
- net::MockHostResolver mock_host_resolver_;
- ConnectionOptions connection_options_;
- XmppConnectionGenerator xmpp_connection_generator_;
-};
-
-TEST_F(XmppConnectionGeneratorTest, DnsFailure) {
- MessageLoop message_loop;
-
- EXPECT_CALL(delegate_, OnNewSettings(_)).Times(0);
- EXPECT_CALL(delegate_, OnExhaustedSettings(_, _)).
- WillOnce(InvokeWithoutArgs(&message_loop, &MessageLoop::Quit));
-
- mock_host_resolver_.rules()->AddSimulatedFailure("*");
- xmpp_connection_generator_.StartGenerating();
- message_loop.Run();
-}
-
-TEST_F(XmppConnectionGeneratorTest, DnsFailureSynchronous) {
- MessageLoop message_loop;
-
- EXPECT_CALL(delegate_, OnNewSettings(_)).Times(0);
- EXPECT_CALL(delegate_, OnExhaustedSettings(_, _)).Times(1);
-
- mock_host_resolver_.set_synchronous_mode(true);
- mock_host_resolver_.rules()->AddSimulatedFailure("*");
- xmpp_connection_generator_.StartGenerating();
-}
-
-TEST_F(XmppConnectionGeneratorTest, ConnectionFailure) {
- MessageLoop message_loop;
-
- EXPECT_CALL(delegate_, OnNewSettings(_)).
- Times(5).
- WillRepeatedly(
- InvokeWithoutArgs(
- &xmpp_connection_generator_,
- &XmppConnectionGenerator::UseNextConnection));
- EXPECT_CALL(delegate_, OnExhaustedSettings(_, _)).
- WillOnce(InvokeWithoutArgs(&message_loop, &MessageLoop::Quit));
-
- xmpp_connection_generator_.StartGenerating();
- message_loop.Run();
-}
-
-TEST_F(XmppConnectionGeneratorTest, ConnectionFailureSynchronous) {
- MessageLoop message_loop;
-
- EXPECT_CALL(delegate_, OnNewSettings(_)).
- Times(5).
- WillRepeatedly(
- InvokeWithoutArgs(
- &xmpp_connection_generator_,
- &XmppConnectionGenerator::UseNextConnection));
- EXPECT_CALL(delegate_, OnExhaustedSettings(_, _)).Times(1);
-
- mock_host_resolver_.set_synchronous_mode(true);
- xmpp_connection_generator_.StartGenerating();
-}
-
-} // namespace
-
-} // namespace notifier
diff --git a/jingle/notifier/listener/mediator_thread_impl.cc b/jingle/notifier/listener/mediator_thread_impl.cc
index ba85ac77..ea6d18d 100644
--- a/jingle/notifier/listener/mediator_thread_impl.cc
+++ b/jingle/notifier/listener/mediator_thread_impl.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -14,9 +14,7 @@
#include "jingle/notifier/base/const_communicator.h"
#include "jingle/notifier/base/notifier_options_util.h"
#include "jingle/notifier/base/task_pump.h"
-#include "jingle/notifier/communicator/connection_options.h"
#include "jingle/notifier/communicator/login.h"
-#include "jingle/notifier/communicator/xmpp_connection_generator.h"
#include "jingle/notifier/listener/push_notifications_listen_task.h"
#include "jingle/notifier/listener/push_notifications_send_update_task.h"
#include "jingle/notifier/listener/push_notifications_subscribe_task.h"
@@ -99,11 +97,9 @@ void MediatorThreadImpl::Core::Login(const buzz::XmppClientSettings& settings) {
BelongsToCurrentThread());
VLOG(1) << "P2P: Thread logging into talk network.";
- // TODO(sanjeevr): Pass in the URLRequestContextGetter to Login.
base_task_.reset();
login_.reset(new notifier::Login(this,
settings,
- notifier::ConnectionOptions(),
notifier_options_.request_context_getter,
GetServerList(notifier_options_),
notifier_options_.try_ssltcp_first,