diff --git a/remoting/base/service_urls.cc b/remoting/base/service_urls.cc index 124cbfe4798305..8c786af65b3e89 100644 --- a/remoting/base/service_urls.cc +++ b/remoting/base/service_urls.cc @@ -12,9 +12,6 @@ // Configurable service data. constexpr char kDirectoryBaseUrl[] = "https://www.googleapis.com/chromoting/v1"; constexpr char kGcdBaseUrl[] = "https://www.googleapis.com/clouddevices/v1"; -constexpr char kXmppServerAddress[] = "talk.google.com:443"; -constexpr char kXmppServerAddressForMe2MeHost[] = "talk.google.com:5222"; -constexpr bool kXmppServerUseTls = true; constexpr char kGcdJid[] = "clouddevices.gserviceaccount.com"; constexpr char kFtlServerEndpoint[] = "instantmessaging-pa.googleapis.com"; constexpr char kRemotingServerEndpoint[] = "remotedesktop-pa.googleapis.com"; @@ -23,8 +20,6 @@ constexpr char kRemotingServerEndpoint[] = "remotedesktop-pa.googleapis.com"; #if !defined(NDEBUG) constexpr char kDirectoryBaseUrlSwitch[] = "directory-base-url"; constexpr char kGcdBaseUrlSwitch[] = "gcd-base-url"; -constexpr char kXmppServerAddressSwitch[] = "xmpp-server-address"; -constexpr char kXmppServerDisableTlsSwitch[] = "disable-xmpp-server-tls"; constexpr char kDirectoryBotJidSwitch[] = "directory-bot-jid"; constexpr char kGcdJidSwitch[] = "gcd-jid"; constexpr char kFtlServerEndpointSwitch[] = "ftl-server-endpoint"; @@ -40,9 +35,6 @@ namespace remoting { ServiceUrls::ServiceUrls() : directory_base_url_(kDirectoryBaseUrl), gcd_base_url_(kGcdBaseUrl), - xmpp_server_address_(kXmppServerAddress), - xmpp_server_address_for_me2me_host_(kXmppServerAddressForMe2MeHost), - xmpp_server_use_tls_(kXmppServerUseTls), directory_bot_jid_(kRemotingBotJid), gcd_jid_(kGcdJid), ftl_server_endpoint_(kFtlServerEndpoint), @@ -60,14 +52,6 @@ ServiceUrls::ServiceUrls() if (command_line->HasSwitch(kGcdBaseUrlSwitch)) { gcd_base_url_ = command_line->GetSwitchValueASCII(kGcdBaseUrlSwitch); } - if (command_line->HasSwitch(kXmppServerAddressSwitch)) { - xmpp_server_address_ = - command_line->GetSwitchValueASCII(kXmppServerAddressSwitch); - xmpp_server_address_for_me2me_host_ = xmpp_server_address_; - } - if (command_line->HasSwitch(kXmppServerDisableTlsSwitch)) { - xmpp_server_use_tls_ = false; - } if (command_line->HasSwitch(kDirectoryBotJidSwitch)) { directory_bot_jid_ = command_line->GetSwitchValueASCII(kDirectoryBotJidSwitch); diff --git a/remoting/base/service_urls.h b/remoting/base/service_urls.h index 2268ef7f9a3cec..2a690482922aab 100644 --- a/remoting/base/service_urls.h +++ b/remoting/base/service_urls.h @@ -27,15 +27,6 @@ class ServiceUrls { } const std::string& gcd_base_url() const { return gcd_base_url_; } - // XMPP Server configuration. - const std::string& xmpp_server_address() const { - return xmpp_server_address_; - } - const std::string& xmpp_server_address_for_me2me_host() const { - return xmpp_server_address_for_me2me_host_; - } - bool xmpp_server_use_tls() const { return xmpp_server_use_tls_; } - // Remoting directory bot JID (for registering hosts, logging, heartbeats). const std::string& directory_bot_jid() const { return directory_bot_jid_; } @@ -69,9 +60,6 @@ class ServiceUrls { std::string directory_base_url_; std::string directory_hosts_url_; std::string gcd_base_url_; - std::string xmpp_server_address_; - std::string xmpp_server_address_for_me2me_host_; - bool xmpp_server_use_tls_; std::string directory_bot_jid_; std::string gcd_jid_; std::string ice_config_url_; diff --git a/remoting/client/chromoting_session.cc b/remoting/client/chromoting_session.cc index ace885619b32da..747677fadb99a5 100644 --- a/remoting/client/chromoting_session.cc +++ b/remoting/client/chromoting_session.cc @@ -45,10 +45,6 @@ namespace remoting { namespace { -const char* const kXmppServer = "talk.google.com"; -const int kXmppPort = 5222; -const bool kXmppUseTls = true; - // Default DPI to assume for old clients that use notifyClientResolution. const int kDefaultDPI = 96; @@ -489,24 +485,10 @@ void ChromotingSession::Core::ConnectOnNetworkThread() { client_context_.get(), this, session_context_->video_renderer.get(), session_context_->audio_player_weak_factory->GetWeakPtr())); - XmppSignalStrategy::XmppServerConfig xmpp_config; - xmpp_config.host = kXmppServer; - xmpp_config.port = kXmppPort; - xmpp_config.use_tls = kXmppUseTls; - xmpp_config.username = session_context_->info.username; - xmpp_config.auth_token = session_context_->info.auth_token; - - if (!session_context_->info.host_ftl_id.empty()) { - signaling_ = std::make_unique( - runtime_->CreateOAuthTokenGetter(), - std::make_unique()); - logger_->SetSignalStrategyType(ChromotingEvent::SignalStrategyType::FTL); - } else { - signaling_ = std::make_unique( - net::ClientSocketFactory::GetDefaultFactory(), - runtime_->url_requester(), xmpp_config); - logger_->SetSignalStrategyType(ChromotingEvent::SignalStrategyType::XMPP); - } + signaling_ = std::make_unique( + runtime_->CreateOAuthTokenGetter(), + std::make_unique()); + logger_->SetSignalStrategyType(ChromotingEvent::SignalStrategyType::FTL); token_getter_ = runtime_->CreateOAuthTokenGetter(); diff --git a/remoting/client/chromoting_session.h b/remoting/client/chromoting_session.h index bfc6becc0d6f7e..4820eabfd24837 100644 --- a/remoting/client/chromoting_session.h +++ b/remoting/client/chromoting_session.h @@ -23,7 +23,7 @@ #include "remoting/protocol/clipboard_stub.h" #include "remoting/protocol/cursor_shape_stub.h" #include "remoting/signaling/ftl_device_id_provider.h" -#include "remoting/signaling/xmpp_signal_strategy.h" +#include "remoting/signaling/signal_strategy.h" namespace remoting { diff --git a/remoting/host/heartbeat_sender_unittest.cc b/remoting/host/heartbeat_sender_unittest.cc index 827d9be5f816b3..c04bec991b6904 100644 --- a/remoting/host/heartbeat_sender_unittest.cc +++ b/remoting/host/heartbeat_sender_unittest.cc @@ -142,7 +142,7 @@ class HeartbeatSenderTest : public testing::Test, public LogToServer { ServerLogEntry::Mode mode() const override { return ServerLogEntry::ME2ME; } - // |heartbeat_sender_| must be deleted before |muxing_signal_strategy_|. + // |heartbeat_sender_| must be deleted before |signal_strategy_|. std::unique_ptr heartbeat_sender_; FakeOAuthTokenGetter oauth_token_getter_{OAuthTokenGetter::Status::SUCCESS, diff --git a/remoting/host/it2me/it2me_host.h b/remoting/host/it2me/it2me_host.h index c1cde094867a96..713e70534a590d 100644 --- a/remoting/host/it2me/it2me_host.h +++ b/remoting/host/it2me/it2me_host.h @@ -20,7 +20,7 @@ #include "remoting/protocol/errors.h" #include "remoting/protocol/port_range.h" #include "remoting/protocol/validating_authenticator.h" -#include "remoting/signaling/xmpp_signal_strategy.h" +#include "remoting/signaling/signal_strategy.h" namespace base { class DictionaryValue; diff --git a/remoting/host/signaling_connector.cc b/remoting/host/signaling_connector.cc deleted file mode 100644 index ffe1cee3db8bae..00000000000000 --- a/remoting/host/signaling_connector.cc +++ /dev/null @@ -1,192 +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. - -#include "remoting/host/signaling_connector.h" - -#include - -#include "base/bind.h" -#include "base/callback.h" -#include "base/strings/string_util.h" -#include "google_apis/google_api_keys.h" -#include "net/url_request/url_fetcher.h" -#include "net/url_request/url_request_context_getter.h" -#include "remoting/base/logging.h" -#include "remoting/host/dns_blackhole_checker.h" -#include "remoting/signaling/signaling_address.h" - -namespace remoting { - -namespace { - -constexpr base::TimeDelta kBackoffResetDelay = base::TimeDelta::FromSeconds(30); - -// The delay between reconnect attempts will increase exponentially up -// to the maximum specified here. -const int kMaxReconnectDelaySeconds = 10 * 60; - -const char* SignalStrategyErrorToString(SignalStrategy::Error error){ - switch(error) { - case SignalStrategy::OK: - return "OK"; - case SignalStrategy::AUTHENTICATION_FAILED: - return "AUTHENTICATION_FAILED"; - case SignalStrategy::NETWORK_ERROR: - return "NETWORK_ERROR"; - case SignalStrategy::PROTOCOL_ERROR: - return "PROTOCOL_ERROR"; - } - NOTREACHED(); - return ""; -} - -} // namespace - -SignalingConnector::SignalingConnector( - XmppSignalStrategy* signal_strategy, - std::unique_ptr dns_blackhole_checker, - OAuthTokenGetter* oauth_token_getter, - const base::Closure& auth_failed_callback) - : signal_strategy_(signal_strategy), - auth_failed_callback_(auth_failed_callback), - dns_blackhole_checker_(std::move(dns_blackhole_checker)), - oauth_token_getter_(oauth_token_getter), - reconnect_attempts_(0), - weak_factory_(this) { - DCHECK(!auth_failed_callback_.is_null()); - DCHECK(dns_blackhole_checker_.get()); - net::NetworkChangeNotifier::AddNetworkChangeObserver(this); - signal_strategy_->AddListener(this); - ScheduleTryReconnect(); -} - -SignalingConnector::~SignalingConnector() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - signal_strategy_->RemoveListener(this); - net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); -} - -void SignalingConnector::OnSignalStrategyStateChange( - SignalStrategy::State state) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - if (state == SignalStrategy::CONNECTED) { - HOST_LOG << "Signaling connected. New JID: " - << signal_strategy_->GetLocalAddress().jid(); - backoff_reset_timer_.Start(FROM_HERE, kBackoffResetDelay, this, - &SignalingConnector::ResetBackoff); - } else if (state == SignalStrategy::DISCONNECTED) { - HOST_LOG << "Signaling disconnected. error=" - << SignalStrategyErrorToString(signal_strategy_->GetError()); - backoff_reset_timer_.Stop(); - reconnect_attempts_++; - - if (signal_strategy_->GetError() == SignalStrategy::AUTHENTICATION_FAILED) - oauth_token_getter_->InvalidateCache(); - - ScheduleTryReconnect(); - } -} - -bool SignalingConnector::OnSignalStrategyIncomingStanza( - const jingle_xmpp::XmlElement* stanza) { - return false; -} - -void SignalingConnector::OnNetworkChanged( - net::NetworkChangeNotifier::ConnectionType type) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (type != net::NetworkChangeNotifier::CONNECTION_NONE && - signal_strategy_->GetState() == SignalStrategy::DISCONNECTED) { - HOST_LOG << "Network state changed to online."; - ResetAndTryReconnect(); - } -} - -void SignalingConnector::OnAccessToken(OAuthTokenGetter::Status status, - const std::string& user_email, - const std::string& access_token) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - if (status == OAuthTokenGetter::AUTH_ERROR) { - auth_failed_callback_.Run(); - return; - } else if (status == OAuthTokenGetter::NETWORK_ERROR) { - OnNetworkError(); - return; - } - - DCHECK_EQ(status, OAuthTokenGetter::SUCCESS); - HOST_LOG << "Received user info."; - - signal_strategy_->SetAuthInfo(user_email, access_token); - - // Now that we've refreshed the token and verified that it's for the correct - // user account, try to connect using the new token. - DCHECK_EQ(signal_strategy_->GetState(), SignalStrategy::DISCONNECTED); - signal_strategy_->Connect(); -} - -void SignalingConnector::OnNetworkError() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - reconnect_attempts_++; - ScheduleTryReconnect(); -} - -void SignalingConnector::ScheduleTryReconnect() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (timer_.IsRunning() || net::NetworkChangeNotifier::IsOffline()) - return; - int delay_s = std::min(1 << reconnect_attempts_, - kMaxReconnectDelaySeconds); - timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(delay_s), - this, &SignalingConnector::TryReconnect); -} - -void SignalingConnector::ResetAndTryReconnect() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - signal_strategy_->Disconnect(); - ResetBackoff(); - timer_.Stop(); - ScheduleTryReconnect(); -} - -void SignalingConnector::TryReconnect() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(dns_blackhole_checker_.get()); - - // This will check if this machine is allowed to access the chromoting - // host talkgadget. - dns_blackhole_checker_->CheckForDnsBlackhole( - base::Bind(&SignalingConnector::OnDnsBlackholeCheckerDone, - base::Unretained(this))); -} - -void SignalingConnector::OnDnsBlackholeCheckerDone(bool allow) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - // Unable to access the host talkgadget. Don't allow the connection, but - // schedule a reconnect in case this is a transient problem rather than - // an outright block. - if (!allow) { - reconnect_attempts_++; - HOST_LOG << "Talkgadget check failed. Scheduling reconnect. Attempt " - << reconnect_attempts_; - ScheduleTryReconnect(); - return; - } - - if (signal_strategy_->GetState() == SignalStrategy::DISCONNECTED) { - HOST_LOG << "Attempting to connect signaling."; - oauth_token_getter_->CallWithToken(base::BindOnce( - &SignalingConnector::OnAccessToken, weak_factory_.GetWeakPtr())); - } -} - -void SignalingConnector::ResetBackoff() { - backoff_reset_timer_.Stop(); - reconnect_attempts_ = 0; -} - -} // namespace remoting diff --git a/remoting/host/signaling_connector.h b/remoting/host/signaling_connector.h deleted file mode 100644 index f0d78f30bfb92f..00000000000000 --- a/remoting/host/signaling_connector.h +++ /dev/null @@ -1,82 +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. - -#ifndef REMOTING_HOST_SIGNALING_CONNECTOR_H_ -#define REMOTING_HOST_SIGNALING_CONNECTOR_H_ - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/sequence_checker.h" -#include "base/timer/timer.h" -#include "net/base/network_change_notifier.h" -#include "remoting/base/oauth_token_getter.h" -#include "remoting/signaling/xmpp_signal_strategy.h" - -namespace remoting { - -class DnsBlackholeChecker; - -// SignalingConnector listens for SignalStrategy status notifications -// and attempts to keep it connected when possible. When signalling is -// not connected it keeps trying to reconnect it until it is -// connected. It limits connection attempt rate using exponential -// backoff. It also monitors network state and reconnects signalling -// whenever connection type changes or IP address changes. -class SignalingConnector - : public SignalStrategy::Listener, - public net::NetworkChangeNotifier::NetworkChangeObserver { - public: - // The |auth_failed_callback| is called when authentication fails. - SignalingConnector(XmppSignalStrategy* signal_strategy, - std::unique_ptr dns_blackhole_checker, - OAuthTokenGetter* oauth_token_getter, - const base::Closure& auth_failed_callback); - ~SignalingConnector() override; - - // OAuthTokenGetter callback. - void OnAccessToken(OAuthTokenGetter::Status status, - const std::string& user_email, - const std::string& access_token); - - // SignalStrategy::Listener interface. - void OnSignalStrategyStateChange(SignalStrategy::State state) override; - bool OnSignalStrategyIncomingStanza(const jingle_xmpp::XmlElement* stanza) override; - - // NetworkChangeNotifier::NetworkChangeObserver interface. - void OnNetworkChanged( - net::NetworkChangeNotifier::ConnectionType type) override; - - private: - void OnNetworkError(); - void ScheduleTryReconnect(); - void ResetAndTryReconnect(); - void TryReconnect(); - void OnDnsBlackholeCheckerDone(bool allow); - void ResetBackoff(); - - XmppSignalStrategy* signal_strategy_; - base::Closure auth_failed_callback_; - std::unique_ptr dns_blackhole_checker_; - - OAuthTokenGetter* oauth_token_getter_; - - // Number of times we tried to connect without success. - int reconnect_attempts_; - - base::OneShotTimer timer_; - - // Timer to reset |backoff_|. We delay resetting the backoff so that we can - // treat an immediate CONNECTED->DISCONNECTED transition as failure. - base::OneShotTimer backoff_reset_timer_; - - SEQUENCE_CHECKER(sequence_checker_); - - base::WeakPtrFactory weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(SignalingConnector); -}; - -} // namespace remoting - -#endif // REMOTING_HOST_SIGNALING_CONNECTOR_H_ diff --git a/remoting/signaling/BUILD.gn b/remoting/signaling/BUILD.gn index 9227f13973f68d..44df316b3e0e9d 100644 --- a/remoting/signaling/BUILD.gn +++ b/remoting/signaling/BUILD.gn @@ -29,8 +29,6 @@ static_library("signaling") { "message_tracker.cc", "message_tracker.h", "messaging_client.h", - "muxing_signal_strategy.cc", - "muxing_signal_strategy.h", "push_notification_subscriber.cc", "push_notification_subscriber.h", "registration_manager.h", @@ -44,12 +42,6 @@ static_library("signaling") { "signaling_address.h", "xmpp_log_to_server.cc", "xmpp_log_to_server.h", - "xmpp_login_handler.cc", - "xmpp_login_handler.h", - "xmpp_signal_strategy.cc", - "xmpp_signal_strategy.h", - "xmpp_stream_parser.cc", - "xmpp_stream_parser.h", ] configs += [ @@ -98,7 +90,6 @@ static_library("signaling") { "remoting_log_to_server.h", "server_log_entry.cc", "xmpp_log_to_server.cc", - "xmpp_signal_strategy.cc", ] deps -= [ "//google_apis", @@ -139,16 +130,12 @@ source_set("unit_tests") { "iq_sender_unittest.cc", "jid_util_unittest.cc", "message_tracker_unittest.cc", - "muxing_signal_strategy_unittest.cc", "push_notification_subscriber_unittest.cc", "remoting_log_to_server_unittest.cc", "server_log_entry_unittest.cc", "server_log_entry_unittest.h", "signaling_address_unittest.cc", "xmpp_log_to_server_unittest.cc", - "xmpp_login_handler_unittest.cc", - "xmpp_signal_strategy_unittest.cc", - "xmpp_stream_parser_unittest.cc", ] deps = [ diff --git a/remoting/signaling/muxing_signal_strategy.cc b/remoting/signaling/muxing_signal_strategy.cc deleted file mode 100644 index 708711edfde64d..00000000000000 --- a/remoting/signaling/muxing_signal_strategy.cc +++ /dev/null @@ -1,371 +0,0 @@ -// Copyright 2019 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 "remoting/signaling/muxing_signal_strategy.h" - -#include - -#include "base/bind.h" -#include "base/logging.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/observer_list.h" -#include "base/rand_util.h" -#include "base/sequence_checker.h" -#include "base/sequenced_task_runner.h" -#include "base/strings/string_number_conversions.h" -#include "base/threading/sequenced_task_runner_handle.h" -#include "base/timer/timer.h" -#include "remoting/signaling/signaling_address.h" -#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" - -namespace remoting { - -namespace { - -constexpr base::TimeDelta kWaitForAllStrategiesConnectedTimeout = - base::TimeDelta::FromSeconds(5); - -} // namespace - -class MuxingSignalStrategy::Core final : public SignalStrategy::Listener { - public: - Core(std::unique_ptr ftl_signal_strategy, - std::unique_ptr xmpp_signal_strategy); - ~Core() override; - - void Invalidate(); - - void Connect(); - State GetState() const; - const SignalingAddress& GetLocalAddress() const; - void AddListener(SignalStrategy::Listener* listener); - void RemoveListener(SignalStrategy::Listener* listener); - bool SendStanza(std::unique_ptr stanza); - - SignalStrategy* ftl_signal_strategy() { return ftl_signal_strategy_.get(); } - - SignalStrategy* xmpp_signal_strategy() { return xmpp_signal_strategy_.get(); } - - private: - enum class MuxingState { - ALL_DISCONNECTED, - SOME_CONNECTING, - ONLY_ONE_CONNECTED_BEFORE_TIMEOUT, - ALL_CONNECTED, - ONLY_ONE_CONNECTED_AFTER_TIMEOUT, - }; - - SignalStrategy* GetSignalStrategyForStanza( - const jingle_xmpp::XmlElement* stanza); - - // Returns true if the state is updated. - bool UpdateState(); - - void OnWaitForAllStrategiesConnectedTimeout(); - - // SignalStrategy::Listener implementations. - void OnSignalStrategyStateChange(SignalStrategy::State state) override; - bool OnSignalStrategyIncomingStanza( - const jingle_xmpp::XmlElement* stanza) override; - - bool IsAnyStrategyConnected() const; - bool IsEveryStrategyConnected() const; - bool IsEveryStrategyDisconnected() const; - - base::ObserverList listeners_; - - std::unique_ptr ftl_signal_strategy_; - std::unique_ptr xmpp_signal_strategy_; - - SignalingAddress current_local_address_; - MuxingState state_ = MuxingState::ALL_DISCONNECTED; - - base::OneShotTimer wait_for_all_strategies_connected_timeout_timer_; - - SEQUENCE_CHECKER(sequence_checker_); - - base::WeakPtrFactory weak_factory_; - DISALLOW_COPY_AND_ASSIGN(Core); -}; - -MuxingSignalStrategy::Core::Core( - std::unique_ptr ftl_signal_strategy, - std::unique_ptr xmpp_signal_strategy) - : weak_factory_(this) { - ftl_signal_strategy_ = std::move(ftl_signal_strategy); - xmpp_signal_strategy_ = std::move(xmpp_signal_strategy); - DCHECK(ftl_signal_strategy_); - DCHECK(xmpp_signal_strategy_); - DCHECK_EQ(State::DISCONNECTED, ftl_signal_strategy_->GetState()); - DCHECK_EQ(State::DISCONNECTED, xmpp_signal_strategy_->GetState()); - ftl_signal_strategy_->AddListener(this); - xmpp_signal_strategy_->AddListener(this); - - UpdateState(); -} - -MuxingSignalStrategy::Core::~Core() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(!ftl_signal_strategy_); - DCHECK(!xmpp_signal_strategy_); -} - -void MuxingSignalStrategy::Core::Invalidate() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - wait_for_all_strategies_connected_timeout_timer_.AbandonAndStop(); - ftl_signal_strategy_->RemoveListener(this); - xmpp_signal_strategy_->RemoveListener(this); - ftl_signal_strategy_.reset(); - xmpp_signal_strategy_.reset(); -} - -void MuxingSignalStrategy::Core::Connect() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - ftl_signal_strategy_->Connect(); - xmpp_signal_strategy_->Connect(); -} - -SignalStrategy::State MuxingSignalStrategy::Core::GetState() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - switch (state_) { - case MuxingState::ALL_DISCONNECTED: - return State::DISCONNECTED; - case MuxingState::SOME_CONNECTING: - case MuxingState::ONLY_ONE_CONNECTED_BEFORE_TIMEOUT: - return State::CONNECTING; - case MuxingState::ONLY_ONE_CONNECTED_AFTER_TIMEOUT: - case MuxingState::ALL_CONNECTED: - return State::CONNECTED; - default: - NOTREACHED(); - return State::DISCONNECTED; - } -} - -const SignalingAddress& MuxingSignalStrategy::Core::GetLocalAddress() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - CHECK(!current_local_address_.empty()) - << "GetLocalAddress() can only be called inside " - << "OnSignalStrategyIncomingStanza()."; - return current_local_address_; -} - -void MuxingSignalStrategy::Core::AddListener( - SignalStrategy::Listener* listener) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - listeners_.AddObserver(listener); -} - -void MuxingSignalStrategy::Core::RemoveListener( - SignalStrategy::Listener* listener) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - listeners_.RemoveObserver(listener); -} - -bool MuxingSignalStrategy::Core::SendStanza( - std::unique_ptr stanza) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - SignalStrategy* strategy = GetSignalStrategyForStanza(stanza.get()); - if (!strategy) { - return false; - } - return strategy->SendStanza(std::move(stanza)); -} - -SignalStrategy* MuxingSignalStrategy::Core::GetSignalStrategyForStanza( - const jingle_xmpp::XmlElement* stanza) { - std::string error; - SignalingAddress receiver = - SignalingAddress::Parse(stanza, SignalingAddress::TO, &error); - if (!error.empty()) { - LOG(DFATAL) << "Failed to parse receiver address: " << error; - return nullptr; - } - if (receiver.channel() == SignalingAddress::Channel::FTL) { - DCHECK(ftl_signal_strategy_->GetLocalAddress().empty() || - ftl_signal_strategy_->GetLocalAddress().channel() == - SignalingAddress::Channel::FTL) - << "|ftl_signal_strategy_|'s local address channel is not FTL. " - << "You might have flipped the signal strategies. " - << "Local address: " << ftl_signal_strategy_->GetLocalAddress().jid(); - return ftl_signal_strategy_.get(); - } else { - DCHECK(xmpp_signal_strategy_->GetLocalAddress().empty() || - xmpp_signal_strategy_->GetLocalAddress().channel() != - SignalingAddress::Channel::FTL) - << "|xmpp_signal_strategy_|'s local address channel is FTL. " - << "You might have flipped the signal strategies. " - << "Local address: " << xmpp_signal_strategy_->GetLocalAddress().jid(); - } - return xmpp_signal_strategy_.get(); -} - -bool MuxingSignalStrategy::Core::UpdateState() { - MuxingState new_state = state_; - if (IsEveryStrategyConnected()) { - wait_for_all_strategies_connected_timeout_timer_.AbandonAndStop(); - new_state = MuxingState::ALL_CONNECTED; - } else if (IsEveryStrategyDisconnected()) { - wait_for_all_strategies_connected_timeout_timer_.AbandonAndStop(); - new_state = MuxingState::ALL_DISCONNECTED; - } else if (IsAnyStrategyConnected()) { - if (state_ == MuxingState::ALL_CONNECTED // One connection is dropped - || (state_ == MuxingState::ONLY_ONE_CONNECTED_BEFORE_TIMEOUT && - !wait_for_all_strategies_connected_timeout_timer_.IsRunning())) { - new_state = MuxingState::ONLY_ONE_CONNECTED_AFTER_TIMEOUT; - } else if (state_ != MuxingState::ONLY_ONE_CONNECTED_AFTER_TIMEOUT) { - new_state = MuxingState::ONLY_ONE_CONNECTED_BEFORE_TIMEOUT; - if (!wait_for_all_strategies_connected_timeout_timer_.IsRunning()) { - wait_for_all_strategies_connected_timeout_timer_.Start( - FROM_HERE, kWaitForAllStrategiesConnectedTimeout, this, - &MuxingSignalStrategy::Core:: - OnWaitForAllStrategiesConnectedTimeout); - } - } - // Otherwise we are not changing the state unless all strategies are - // connected or all strategies are disconnected. - } else { - new_state = MuxingState::SOME_CONNECTING; - } - if (state_ == new_state) { - return false; - } - state_ = new_state; - return true; -} - -void MuxingSignalStrategy::Core::OnWaitForAllStrategiesConnectedTimeout() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - if (!IsEveryStrategyConnected()) { - LOG(WARNING) << "Timeout waiting for all strategies to be connected."; - OnSignalStrategyStateChange(/* unused */ State::CONNECTED); - } -} - -void MuxingSignalStrategy::Core::OnSignalStrategyStateChange( - SignalStrategy::State unused) { - bool is_state_changed = UpdateState(); - if (is_state_changed) { - for (auto& listener : listeners_) { - listener.OnSignalStrategyStateChange(GetState()); - } - } -} - -bool MuxingSignalStrategy::Core::OnSignalStrategyIncomingStanza( - const jingle_xmpp::XmlElement* stanza) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - SignalStrategy* strategy = GetSignalStrategyForStanza(stanza); - DCHECK(current_local_address_.empty()); - current_local_address_ = strategy->GetLocalAddress(); - bool message_handled = false; - for (auto& listener : listeners_) { - if (listener.OnSignalStrategyIncomingStanza(stanza)) { - message_handled = true; - break; - } - } - current_local_address_ = SignalingAddress(); - return message_handled; -} - -bool MuxingSignalStrategy::Core::IsAnyStrategyConnected() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return xmpp_signal_strategy_->GetState() == State::CONNECTED || - ftl_signal_strategy_->GetState() == State::CONNECTED; -} - -bool MuxingSignalStrategy::Core::IsEveryStrategyConnected() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return xmpp_signal_strategy_->GetState() == State::CONNECTED && - ftl_signal_strategy_->GetState() == State::CONNECTED; -} - -bool MuxingSignalStrategy::Core::IsEveryStrategyDisconnected() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return xmpp_signal_strategy_->GetState() == State::DISCONNECTED && - ftl_signal_strategy_->GetState() == State::DISCONNECTED; -} - -MuxingSignalStrategy::MuxingSignalStrategy( - std::unique_ptr ftl_signal_strategy, - std::unique_ptr xmpp_signal_strategy) - : ftl_signal_strategy_(std::move(ftl_signal_strategy)), - xmpp_signal_strategy_(std::move(xmpp_signal_strategy)) {} - -MuxingSignalStrategy::~MuxingSignalStrategy() { - if (!core_) { - // The core has never been created. Just do nothing. - return; - } - GetCore()->Invalidate(); - base::SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, - std::move(core_)); -} - -void MuxingSignalStrategy::Connect() { - GetCore()->Connect(); -} - -SignalStrategy::State MuxingSignalStrategy::GetState() const { - return GetCore()->GetState(); -} - -const SignalingAddress& MuxingSignalStrategy::GetLocalAddress() const { - return GetCore()->GetLocalAddress(); -} - -void MuxingSignalStrategy::AddListener(SignalStrategy::Listener* listener) { - GetCore()->AddListener(listener); -} - -void MuxingSignalStrategy::RemoveListener(SignalStrategy::Listener* listener) { - GetCore()->RemoveListener(listener); -} - -bool MuxingSignalStrategy::SendStanza( - std::unique_ptr stanza) { - return GetCore()->SendStanza(std::move(stanza)); -} - -std::string MuxingSignalStrategy::GetNextId() { - return base::NumberToString(base::RandUint64()); -} - -SignalStrategy* MuxingSignalStrategy::ftl_signal_strategy() { - return GetCore()->ftl_signal_strategy(); -} - -SignalStrategy* MuxingSignalStrategy::xmpp_signal_strategy() { - return GetCore()->xmpp_signal_strategy(); -} - -void MuxingSignalStrategy::Disconnect() { - NOTREACHED(); -} - -SignalStrategy::Error MuxingSignalStrategy::GetError() const { - NOTREACHED(); - return Error::NETWORK_ERROR; -} - -MuxingSignalStrategy::Core* MuxingSignalStrategy::GetCore() { - return GetCoreImpl(); -} - -const MuxingSignalStrategy::Core* MuxingSignalStrategy::GetCore() const { - return const_cast(this)->GetCoreImpl(); -} - -MuxingSignalStrategy::Core* MuxingSignalStrategy::GetCoreImpl() { - if (!core_) { - core_ = std::make_unique(std::move(ftl_signal_strategy_), - std::move(xmpp_signal_strategy_)); - } - return core_.get(); -} - -} // namespace remoting diff --git a/remoting/signaling/muxing_signal_strategy.h b/remoting/signaling/muxing_signal_strategy.h deleted file mode 100644 index 69593b55f66bd4..00000000000000 --- a/remoting/signaling/muxing_signal_strategy.h +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2019 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 REMOTING_SIGNALING_MUXING_SIGNAL_STRATEGY_H_ -#define REMOTING_SIGNALING_MUXING_SIGNAL_STRATEGY_H_ - -#include - -#include "base/macros.h" -#include "remoting/signaling/signal_strategy.h" - -namespace remoting { - -// WARNING: This class is designed to be used exclusively by -// JingleSessionManager on the host during the XMPP->FTL signaling migration -// process. It doesn't support anything other than sending and receiving -// stanzas. Use (Ftl|Xmpp)SignalStrategy directly if possible. -// -// MuxingSignalStrategy multiplexes FtlSignalStrategy and XmppSignalStrategy. -// It can accept stanzas with FTL or XMPP receiver and forward them to the -// proper SignalStrategy. -// -// Caller can create MuxingSignalStrategy on one thread and thereafter use it -// on another thread. -class MuxingSignalStrategy final : public SignalStrategy { - public: - MuxingSignalStrategy(std::unique_ptr ftl_signal_strategy, - std::unique_ptr xmpp_signal_strategy); - ~MuxingSignalStrategy() override; - - // SignalStrategy implementations. - - // This will connect both |ftl_signal_strategy_| and |xmpp_signal_strategy_|. - void Connect() override; - - // The state is a mapping of the MuxingState (defined in - // MuxingSignalStrategy::Core): - // - // ALL_DISCONNECTED -> DISCONNECTED - // SOME_CONNECTING, ONLY_ONE_CONNECTED_BEFORE_TIMEOUT -> CONNECTING - // ALL_CONNECTED, ONLY_ONE_CONNECTED_AFTER_TIMEOUT -> CONNECTED - // - // Note that MuxingSignalStrategy will notify listeners whenever the muxing - // state is changed, which means listeners may get notified for - // CONNECTING->CONNECTING and CONNECTED->CONNECTED transitions. This is to - // allow heartbeat sender to send new heartbeat when a strategy is connected - // or disconnected after the timeout. - State GetState() const override; - - // GetLocalAddress() can only be called inside - // OnSignalStrategyIncomingStanza(). - const SignalingAddress& GetLocalAddress() const override; - - void AddListener(SignalStrategy::Listener* listener) override; - void RemoveListener(SignalStrategy::Listener* listener) override; - - bool SendStanza(std::unique_ptr stanza) override; - std::string GetNextId() override; - - SignalStrategy* ftl_signal_strategy(); - SignalStrategy* xmpp_signal_strategy(); - - private: - class Core; - - // These methods are not supported. Caller should directly call them on the - // underlying signal strategies instead. - void Disconnect() override; - Error GetError() const override; - - // Returns pointer to the core, and creates a core if it has not been created. - // - // The Core constructor will bind the underlying signal strategies to the - // current sequence, so we delay construction of the core so that user can - // create MuxingSignalStrategy on one sequence and use it on another sequence. - Core* GetCore(); - const Core* GetCore() const; - Core* GetCoreImpl(); - - // These will be moved to |core_| once the core is created. - std::unique_ptr ftl_signal_strategy_; - std::unique_ptr xmpp_signal_strategy_; - - std::unique_ptr core_; - DISALLOW_COPY_AND_ASSIGN(MuxingSignalStrategy); -}; - -} // namespace remoting - -#endif // REMOTING_SIGNALING_MUXING_SIGNAL_STRATEGY_H_ diff --git a/remoting/signaling/muxing_signal_strategy_unittest.cc b/remoting/signaling/muxing_signal_strategy_unittest.cc deleted file mode 100644 index 2df6cab1d2ab3f..00000000000000 --- a/remoting/signaling/muxing_signal_strategy_unittest.cc +++ /dev/null @@ -1,340 +0,0 @@ -// Copyright 2019 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 "remoting/signaling/muxing_signal_strategy.h" - -#include -#include -#include - -#include "base/memory/ptr_util.h" -#include "base/test/mock_callback.h" -#include "base/test/scoped_task_environment.h" -#include "base/time/time.h" -#include "remoting/signaling/fake_signal_strategy.h" -#include "remoting/signaling/signaling_address.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" -#include "third_party/libjingle_xmpp/xmpp/constants.h" - -namespace remoting { - -namespace { - -using testing::_; -using testing::Return; - -constexpr char kLocalFtlId[] = "local_user@domain.com/chromoting_ftl_abc123"; -constexpr char kRemoteFtlId[] = "remote_user@domain.com/chromoting_ftl_def456"; -constexpr char kLocalJabberId[] = "local_user@domain.com/chromotingABC123"; -constexpr char kRemoteJabberId[] = "remote_user@domain.com/chromotingDEF456"; - -constexpr base::TimeDelta kWaitForAllStrategiesConnectedTimeout = - base::TimeDelta::FromSecondsD(5.5); - -MATCHER_P(StanzaMatchesString, expected_str, "") { - return arg->Str() == expected_str; -} - -std::unique_ptr CreateXmlStanza( - const std::string& from, - const std::string& to) { - static constexpr char kStanzaTemplate[] = - "" - "" - "chromoting" - "" - ""; - auto stanza = base::WrapUnique( - jingle_xmpp::XmlElement::ForStr(kStanzaTemplate)); - stanza->SetAttr(jingle_xmpp::QN_FROM, from); - stanza->SetAttr(jingle_xmpp::QN_TO, to); - return stanza; -} - -} // namespace - -class MuxingSignalStrategyTest : public testing::Test, - public SignalStrategy::Listener { - public: - MuxingSignalStrategyTest() { - auto ftl_signal_strategy = - std::make_unique(SignalingAddress(kLocalFtlId)); - auto xmpp_signal_strategy = - std::make_unique(SignalingAddress(kLocalJabberId)); - ftl_signal_strategy_ = ftl_signal_strategy.get(); - xmpp_signal_strategy_ = xmpp_signal_strategy.get(); - - // Start in disconnected state. - ftl_signal_strategy_->Disconnect(); - xmpp_signal_strategy_->Disconnect(); - - ftl_signal_strategy_->SetPeerCallback(mock_ftl_peer_callback_.Get()); - xmpp_signal_strategy_->SetPeerCallback(mock_xmpp_peer_callback_.Get()); - - muxing_signal_strategy_ = std::make_unique( - std::move(ftl_signal_strategy), std::move(xmpp_signal_strategy)); - muxing_signal_strategy_->AddListener(this); - } - - ~MuxingSignalStrategyTest() override { - muxing_signal_strategy_->RemoveListener(this); - muxing_signal_strategy_.reset(); - scoped_task_environment_.FastForwardUntilNoTasksRemain(); - } - - protected: - base::test::ScopedTaskEnvironment scoped_task_environment_{ - base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME}; - - std::unique_ptr muxing_signal_strategy_; - - FakeSignalStrategy* ftl_signal_strategy_; - FakeSignalStrategy* xmpp_signal_strategy_; - - base::MockCallback mock_ftl_peer_callback_; - base::MockCallback mock_xmpp_peer_callback_; - - std::vector state_history_; - std::vector> received_messages_; - std::vector received_stanza_local_addresses_; - - private: - // SignalStrategy::Listener overrides. - void OnSignalStrategyStateChange(SignalStrategy::State state) override { - state_history_.push_back(state); - } - - bool OnSignalStrategyIncomingStanza( - const jingle_xmpp::XmlElement* stanza) override { - received_messages_.push_back( - std::make_unique(*stanza)); - received_stanza_local_addresses_.push_back( - muxing_signal_strategy_->GetLocalAddress()); - return true; - } -}; - -TEST_F(MuxingSignalStrategyTest, StateTransition_NothingIsConnected) { - scoped_task_environment_.FastForwardBy(kWaitForAllStrategiesConnectedTimeout); - - ASSERT_EQ(0u, state_history_.size()); -} - -TEST_F(MuxingSignalStrategyTest, StateTransition_OnlyXmppIsConnected) { - xmpp_signal_strategy_->SetState(SignalStrategy::CONNECTING); - xmpp_signal_strategy_->Connect(); - scoped_task_environment_.FastForwardBy(kWaitForAllStrategiesConnectedTimeout); - - ASSERT_EQ(3u, state_history_.size()); - - // SOME_CONNECTING - ASSERT_EQ(SignalStrategy::CONNECTING, state_history_[0]); - - // ONLY_ONE_CONNECTED_BEFORE_TIMEOUT - ASSERT_EQ(SignalStrategy::CONNECTING, state_history_[1]); - - // ONLY_ONE_CONNECTED_AFTER_TIMEOUT - ASSERT_EQ(SignalStrategy::CONNECTED, state_history_[2]); -} - -TEST_F(MuxingSignalStrategyTest, StateTransition_OnlyFtlIsConnected) { - ftl_signal_strategy_->SetState(SignalStrategy::CONNECTING); - ftl_signal_strategy_->Connect(); - scoped_task_environment_.FastForwardBy(kWaitForAllStrategiesConnectedTimeout); - - ASSERT_EQ(3u, state_history_.size()); - - // SOME_CONNECTING - ASSERT_EQ(SignalStrategy::CONNECTING, state_history_[0]); - - // ONLY_ONE_CONNECTED_BEFORE_TIMEOUT - ASSERT_EQ(SignalStrategy::CONNECTING, state_history_[1]); - - // ONLY_ONE_CONNECTED_AFTER_TIMEOUT - ASSERT_EQ(SignalStrategy::CONNECTED, state_history_[2]); -} - -TEST_F(MuxingSignalStrategyTest, - StateTransition_BothAreConnectingThenConnected) { - xmpp_signal_strategy_->SetState(SignalStrategy::CONNECTING); - ftl_signal_strategy_->SetState(SignalStrategy::CONNECTING); - xmpp_signal_strategy_->Connect(); - ftl_signal_strategy_->Connect(); - scoped_task_environment_.FastForwardBy(kWaitForAllStrategiesConnectedTimeout); - - ASSERT_EQ(3u, state_history_.size()); - - // SOME_CONNECTING - ASSERT_EQ(SignalStrategy::CONNECTING, state_history_[0]); - - // ONLY_ONE_CONNECTED_BEFORE_TIMEOUT - ASSERT_EQ(SignalStrategy::CONNECTING, state_history_[1]); - - // ALL_CONNECTED - ASSERT_EQ(SignalStrategy::CONNECTED, state_history_[2]); -} - -TEST_F(MuxingSignalStrategyTest, - StateTransition_ConnectingThenConnectedOneAfterAnother) { - xmpp_signal_strategy_->SetState(SignalStrategy::CONNECTING); - xmpp_signal_strategy_->Connect(); - ftl_signal_strategy_->SetState(SignalStrategy::CONNECTING); - ftl_signal_strategy_->Connect(); - scoped_task_environment_.FastForwardBy(kWaitForAllStrategiesConnectedTimeout); - - ASSERT_EQ(3u, state_history_.size()); - - // SOME_CONNECTING - ASSERT_EQ(SignalStrategy::CONNECTING, state_history_[0]); - - // ONLY_ONE_CONNECTED_BEFORE_TIMEOUT - ASSERT_EQ(SignalStrategy::CONNECTING, state_history_[1]); - - // ALL_CONNECTED - ASSERT_EQ(SignalStrategy::CONNECTED, state_history_[2]); -} - -TEST_F( - MuxingSignalStrategyTest, - StateTransition_StartedConnectionBeforeTimeoutAndTheOtherStartedConnectionAfterTimeout) { - xmpp_signal_strategy_->SetState(SignalStrategy::CONNECTING); - xmpp_signal_strategy_->Connect(); - scoped_task_environment_.FastForwardBy(kWaitForAllStrategiesConnectedTimeout); - ftl_signal_strategy_->SetState(SignalStrategy::CONNECTING); - ftl_signal_strategy_->Connect(); - - ASSERT_EQ(4u, state_history_.size()); - - // SOME_CONNECTING - ASSERT_EQ(SignalStrategy::CONNECTING, state_history_[0]); - - // ONLY_ONE_CONNECTED_BEFORE_TIMEOUT - ASSERT_EQ(SignalStrategy::CONNECTING, state_history_[1]); - - // ONLY_ONE_CONNECTED_AFTER_TIMEOUT - ASSERT_EQ(SignalStrategy::CONNECTED, state_history_[2]); - - // ALL_CONNECTED - ASSERT_EQ(SignalStrategy::CONNECTED, state_history_[3]); -} - -TEST_F( - MuxingSignalStrategyTest, - StateTransition_OneConnectedBeforeTimeoutAndTheOtherConnectedAfterTimeout) { - xmpp_signal_strategy_->SetState(SignalStrategy::CONNECTING); - ftl_signal_strategy_->SetState(SignalStrategy::CONNECTING); - xmpp_signal_strategy_->Connect(); - scoped_task_environment_.FastForwardBy(kWaitForAllStrategiesConnectedTimeout); - ftl_signal_strategy_->Connect(); - - ASSERT_EQ(4u, state_history_.size()); - - // SOME_CONNECTING - ASSERT_EQ(SignalStrategy::CONNECTING, state_history_[0]); - - // ONLY_ONE_CONNECTED_BEFORE_TIMEOUT - ASSERT_EQ(SignalStrategy::CONNECTING, state_history_[1]); - - // ONLY_ONE_CONNECTED_AFTER_TIMEOUT - ASSERT_EQ(SignalStrategy::CONNECTED, state_history_[2]); - - // ALL_CONNECTED - ASSERT_EQ(SignalStrategy::CONNECTED, state_history_[3]); -} - -TEST_F(MuxingSignalStrategyTest, StateTransition_OneConnectedThenDisconnected) { - xmpp_signal_strategy_->SetState(SignalStrategy::CONNECTING); - xmpp_signal_strategy_->Connect(); - scoped_task_environment_.FastForwardBy(kWaitForAllStrategiesConnectedTimeout); - xmpp_signal_strategy_->Disconnect(); - - ASSERT_EQ(4u, state_history_.size()); - - // SOME_CONNECTING - ASSERT_EQ(SignalStrategy::CONNECTING, state_history_[0]); - - // ONLY_ONE_CONNECTED_BEFORE_TIMEOUT - ASSERT_EQ(SignalStrategy::CONNECTING, state_history_[1]); - - // ONLY_ONE_CONNECTED_AFTER_TIMEOUT - ASSERT_EQ(SignalStrategy::CONNECTED, state_history_[2]); - - // ALL_DISCONNECTED - ASSERT_EQ(SignalStrategy::DISCONNECTED, state_history_[3]); -} - -TEST_F(MuxingSignalStrategyTest, - StateTransition_BothConnectedThenDisconnectedOneByOne) { - xmpp_signal_strategy_->SetState(SignalStrategy::CONNECTING); - ftl_signal_strategy_->SetState(SignalStrategy::CONNECTING); - xmpp_signal_strategy_->Connect(); - ftl_signal_strategy_->Connect(); - scoped_task_environment_.FastForwardBy(kWaitForAllStrategiesConnectedTimeout); - xmpp_signal_strategy_->Disconnect(); - ftl_signal_strategy_->Disconnect(); - - ASSERT_EQ(5u, state_history_.size()); - - // SOME_CONNECTING - ASSERT_EQ(SignalStrategy::CONNECTING, state_history_[0]); - - // ONLY_ONE_CONNECTED_BEFORE_TIMEOUT - ASSERT_EQ(SignalStrategy::CONNECTING, state_history_[1]); - - // ALL_CONNECTED - ASSERT_EQ(SignalStrategy::CONNECTED, state_history_[2]); - - // ONLY_ONE_CONNECTED_AFTER_TIMEOUT - ASSERT_EQ(SignalStrategy::CONNECTED, state_history_[3]); - - // ALL_DISCONNECTED - ASSERT_EQ(SignalStrategy::DISCONNECTED, state_history_[4]); -} - -TEST_F(MuxingSignalStrategyTest, SendStanza_MessageRoutedToFtlSignalStrategy) { - xmpp_signal_strategy_->Connect(); - ftl_signal_strategy_->Connect(); - - auto stanza = CreateXmlStanza(kLocalFtlId, kRemoteFtlId); - std::string stanza_string = stanza->Str(); - EXPECT_CALL(mock_ftl_peer_callback_, Run(StanzaMatchesString(stanza_string))) - .WillOnce(Return()); - muxing_signal_strategy_->SendStanza(std::move(stanza)); -} - -TEST_F(MuxingSignalStrategyTest, SendStanza_MessageRoutedToXmppSignalStrategy) { - xmpp_signal_strategy_->Connect(); - ftl_signal_strategy_->Connect(); - - auto stanza = CreateXmlStanza(kLocalJabberId, kRemoteJabberId); - std::string stanza_string = stanza->Str(); - EXPECT_CALL(mock_xmpp_peer_callback_, Run(StanzaMatchesString(stanza_string))) - .WillOnce(Return()); - muxing_signal_strategy_->SendStanza(std::move(stanza)); -} - -TEST_F(MuxingSignalStrategyTest, - ReceiveStanza_MessagesFromBothStrategiesAreReceived) { - xmpp_signal_strategy_->Connect(); - ftl_signal_strategy_->Connect(); - - xmpp_signal_strategy_->OnIncomingMessage( - CreateXmlStanza(kRemoteJabberId, kLocalJabberId)); - ftl_signal_strategy_->OnIncomingMessage( - CreateXmlStanza(kRemoteFtlId, kLocalFtlId)); - - ASSERT_EQ(2u, received_messages_.size()); - ASSERT_EQ(kRemoteJabberId, received_messages_[0]->Attr(jingle_xmpp::QN_FROM)); - ASSERT_EQ(kLocalJabberId, received_messages_[0]->Attr(jingle_xmpp::QN_TO)); - ASSERT_EQ(kRemoteFtlId, received_messages_[1]->Attr(jingle_xmpp::QN_FROM)); - ASSERT_EQ(kLocalFtlId, received_messages_[1]->Attr(jingle_xmpp::QN_TO)); - - ASSERT_EQ(2u, received_stanza_local_addresses_.size()); - ASSERT_EQ(kLocalJabberId, received_stanza_local_addresses_[0].jid()); - ASSERT_EQ(kLocalFtlId, received_stanza_local_addresses_[1].jid()); -} - -} // namespace remoting diff --git a/remoting/signaling/xmpp_login_handler.cc b/remoting/signaling/xmpp_login_handler.cc deleted file mode 100644 index f331f27b815816..00000000000000 --- a/remoting/signaling/xmpp_login_handler.cc +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright 2015 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 "remoting/signaling/xmpp_login_handler.h" - -#include - -#include "base/base64.h" -#include "base/bind.h" -#include "base/logging.h" -#include "remoting/signaling/xmpp_stream_parser.h" -#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" - -// Undefine SendMessage and ERROR defined in Windows headers. -#ifdef SendMessage -#undef SendMessage -#endif - -#ifdef ERROR -#undef ERROR -#endif - -namespace remoting { - -const char kOAuthMechanism[] = "X-OAUTH2"; - -jingle_xmpp::StaticQName kXmppIqName = {"jabber:client", "iq"}; - -char kXmppBindNs[] = "urn:ietf:params:xml:ns:xmpp-bind"; -jingle_xmpp::StaticQName kXmppBindName = {kXmppBindNs, "bind"}; -jingle_xmpp::StaticQName kXmppJidName = {kXmppBindNs, "jid"}; - -jingle_xmpp::StaticQName kJabberFeaturesName = {"http://etherx.jabber.org/streams", - "features"}; - -char kXmppTlsNs[] = "urn:ietf:params:xml:ns:xmpp-tls"; -jingle_xmpp::StaticQName kStartTlsName = {kXmppTlsNs, "starttls"}; -jingle_xmpp::StaticQName kTlsProceedName = {kXmppTlsNs, "proceed"}; - -char kXmppSaslNs[] = "urn:ietf:params:xml:ns:xmpp-sasl"; -jingle_xmpp::StaticQName kSaslMechanismsName = {kXmppSaslNs, "mechanisms"}; -jingle_xmpp::StaticQName kSaslMechanismName = {kXmppSaslNs, "mechanism"}; -jingle_xmpp::StaticQName kSaslSuccessName = {kXmppSaslNs, "success"}; - -XmppLoginHandler::XmppLoginHandler(const std::string& server, - const std::string& username, - const std::string& auth_token, - TlsMode tls_mode, - Delegate* delegate) - : server_(server), - username_(username), - auth_token_(auth_token), - tls_mode_(tls_mode), - delegate_(delegate), - state_(State::INIT) { -} - -XmppLoginHandler::~XmppLoginHandler() = default; - -void XmppLoginHandler::Start() { - switch (tls_mode_) { - case TlsMode::NO_TLS: - state_ = State::WAIT_STREAM_HEADER_AFTER_TLS; - StartAuthHandshake(); - break; - case TlsMode::WITH_HANDSHAKE: - state_ = State::WAIT_STREAM_HEADER; - StartStream(""); - break; - case TlsMode::WITHOUT_HANDSHAKE: - // If handshake is not required then start TLS right away. - state_ = State::STARTING_TLS; - delegate_->StartTls(); - break; - } -} - -void XmppLoginHandler::OnDataReceived(const std::string& data) { - DCHECK(state_ != State::INIT && state_ != State::DONE && - state_ != State::ERROR); - stream_parser_->AppendData(data); -} - -void XmppLoginHandler::OnStanza(std::unique_ptr stanza) { - switch (state_) { - case State::WAIT_STREAM_HEADER: { - if (stanza->Name() == kJabberFeaturesName && - stanza->FirstNamed(kStartTlsName) != nullptr) { - state_ = State::WAIT_STARTTLS_RESPONSE; - } else { - LOG(ERROR) << "Server doesn't support TLS."; - OnError(SignalStrategy::PROTOCOL_ERROR); - } - break; - } - - case State::WAIT_STARTTLS_RESPONSE: { - if (stanza->Name() == kTlsProceedName) { - state_ = State::STARTING_TLS; - delegate_->StartTls(); - } else { - LOG(ERROR) << "Failed to start TLS: " << stanza->Str(); - OnError(SignalStrategy::PROTOCOL_ERROR); - } - break; - } - - case State::WAIT_STREAM_HEADER_AFTER_TLS: { - jingle_xmpp::XmlElement* mechanisms_element = - stanza->FirstNamed(kSaslMechanismsName); - bool oauth_supported = false; - if (mechanisms_element) { - for (jingle_xmpp::XmlElement* element = - mechanisms_element->FirstNamed(kSaslMechanismName); - element; element = element->NextNamed(kSaslMechanismName)) { - if (element->BodyText() == kOAuthMechanism) { - oauth_supported = true; - break; - } - } - } - - if (!oauth_supported) { - LOG(ERROR) << kOAuthMechanism - << " auth mechanism is not supported by the server."; - OnError(SignalStrategy::PROTOCOL_ERROR); - return; - } - - state_ = State::WAIT_AUTH_RESULT; - break; - } - - case State::WAIT_AUTH_RESULT: { - if (stanza->Name() == kSaslSuccessName) { - state_ = State::WAIT_STREAM_HEADER_AFTER_AUTH; - StartStream( - "" - "" - "chromoting" - "" - "" - "" - "" - ""); - } else { - OnError(SignalStrategy::AUTHENTICATION_FAILED); - } - break; - } - - case State::WAIT_STREAM_HEADER_AFTER_AUTH: - if (stanza->Name() == kJabberFeaturesName && - stanza->FirstNamed(kXmppBindName) != nullptr) { - state_ = State::WAIT_BIND_RESULT; - } else { - LOG(ERROR) << "Server doesn't support bind after authentication."; - OnError(SignalStrategy::PROTOCOL_ERROR); - } - break; - - case State::WAIT_BIND_RESULT: { - jingle_xmpp::XmlElement* bind = stanza->FirstNamed(kXmppBindName); - jingle_xmpp::XmlElement* jid = bind ? bind->FirstNamed(kXmppJidName) : nullptr; - if (stanza->Attr(jingle_xmpp::QName("", "id")) != "0" || - stanza->Attr(jingle_xmpp::QName("", "type")) != "result" || !jid) { - LOG(ERROR) << "Received unexpected response to bind: " << stanza->Str(); - OnError(SignalStrategy::PROTOCOL_ERROR); - return; - } - jid_ = jid->BodyText(); - state_ = State::WAIT_SESSION_IQ_RESULT; - break; - } - - case State::WAIT_SESSION_IQ_RESULT: - if (stanza->Name() != kXmppIqName || - stanza->Attr(jingle_xmpp::QName("", "id")) != "1" || - stanza->Attr(jingle_xmpp::QName("", "type")) != "result") { - LOG(ERROR) << "Failed to start session: " << stanza->Str(); - OnError(SignalStrategy::PROTOCOL_ERROR); - return; - } - state_ = State::DONE; - delegate_->OnHandshakeDone(jid_, std::move(stream_parser_)); - break; - - default: - NOTREACHED(); - break; - } -} - -void XmppLoginHandler::OnTlsStarted() { - DCHECK(state_ == State::STARTING_TLS); - state_ = State::WAIT_STREAM_HEADER_AFTER_TLS; - StartAuthHandshake(); -} - -void XmppLoginHandler::StartAuthHandshake() { - DCHECK(state_ == State::WAIT_STREAM_HEADER_AFTER_TLS); - - std::string cookie; - base::Base64Encode( - std::string("\0", 1) + username_ + std::string("\0", 1) + auth_token_, - &cookie); - StartStream( - "" + - cookie + - ""); -} - -void XmppLoginHandler::OnParserError() { - OnError(SignalStrategy::PROTOCOL_ERROR); -} - -void XmppLoginHandler::StartStream(const std::string& first_message) { - stream_parser_.reset(new XmppStreamParser()); - stream_parser_->SetCallbacks( - base::Bind(&XmppLoginHandler::OnStanza, base::Unretained(this)), - base::Bind(&XmppLoginHandler::OnParserError, base::Unretained(this))); - delegate_->SendMessage("" + - first_message); -} - -void XmppLoginHandler::OnError(SignalStrategy::Error error) { - if (state_ != State::ERROR) { - state_ = State::ERROR; - delegate_->OnLoginHandlerError(error); - } -} - -} // namespace remoting diff --git a/remoting/signaling/xmpp_login_handler.h b/remoting/signaling/xmpp_login_handler.h deleted file mode 100644 index 46c8b0d9824635..00000000000000 --- a/remoting/signaling/xmpp_login_handler.h +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright 2015 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 REMOTING_SIGNALING_XMPP_LOGIN_HANDLER_H_ -#define REMOTING_SIGNALING_XMPP_LOGIN_HANDLER_H_ - -#include -#include - -#include "base/macros.h" -#include "remoting/signaling/signal_strategy.h" - -// Undefine SendMessage and ERROR defined in Windows headers. -#ifdef SendMessage -#undef SendMessage -#endif - -#ifdef ERROR -#undef ERROR -#endif - -namespace remoting { - -class XmppStreamParser; - -// XmppLoginHandler handles authentication handshake for XmppSignalStrategy. It -// receives incoming data using onDataReceived(), calls Delegate::SendMessage() -// to send outgoing messages and calls Delegate::OnHandshakeDone() after -// authentication is finished successfully or Delegate::OnError() on error. -// -// See RFC3920 for description of XMPP and authentication handshake. -class XmppLoginHandler { - public: - class Delegate { - public: - Delegate() {} - - // All Delegate methods are allowed to destroy XmppLoginHandler. - virtual void SendMessage(const std::string& message) = 0; - virtual void StartTls() = 0; - virtual void OnHandshakeDone(const std::string& jid, - std::unique_ptr parser) = 0; - virtual void OnLoginHandlerError(SignalStrategy::Error error) = 0; - - protected: - virtual ~Delegate() {} - }; - - enum class TlsMode { - NO_TLS, - WITH_HANDSHAKE, - WITHOUT_HANDSHAKE, - }; - - XmppLoginHandler(const std::string& server, - const std::string& username, - const std::string& auth_token, - TlsMode tls_mode, - Delegate* delegate); - ~XmppLoginHandler(); - - void Start(); - void OnDataReceived(const std::string& data); - void OnTlsStarted(); - - private: - // States the handshake goes through. States are iterated from INIT to DONE - // sequentially, except for ERROR state which may be accepted at any point. - // - // Following messages are sent/received in each state: - // INIT - // client -> server: Stream header - // client -> server: - // WAIT_STREAM_HEADER - // client <- server: Stream header with list of supported features which - // should include starttls. - // WAIT_STARTTLS_RESPONSE - // client <- server: - // STARTING_TLS - // TLS handshake - // client -> server: Stream header - // client -> server: message with the OAuth2 token. - // WAIT_STREAM_HEADER_AFTER_TLS - // client <- server: Stream header with list of supported authentication - // methods which is expected to include X-OAUTH2 - // WAIT_AUTH_RESULT - // client <- server: or - // client -> server: Stream header - // client -> server: - // client -> server: to start the session - // WAIT_STREAM_HEADER_AFTER_AUTH - // client <- server: Stream header with list of features that should - // include . - // WAIT_BIND_RESULT - // client <- server: result with JID. - // WAIT_SESSION_IQ_RESULT - // client <- server: result for - // DONE - enum class State { - INIT, - WAIT_STREAM_HEADER, - WAIT_STARTTLS_RESPONSE, - STARTING_TLS, - WAIT_STREAM_HEADER_AFTER_TLS, - WAIT_AUTH_RESULT, - WAIT_STREAM_HEADER_AFTER_AUTH, - WAIT_BIND_RESULT, - WAIT_SESSION_IQ_RESULT, - DONE, - ERROR, - }; - - // Callbacks for XmppStreamParser. - void OnStanza(std::unique_ptr stanza); - void OnParserError(); - - // Starts authentication handshake in WAIT_STREAM_HEADER_AFTER_TLS state. - void StartAuthHandshake(); - - // Helper used to send stream header. - void StartStream(const std::string& first_message); - - // Report the |error| to the delegate and changes |state_| to ERROR, - void OnError(SignalStrategy::Error error); - - std::string server_; - std::string username_; - std::string auth_token_; - TlsMode tls_mode_; - Delegate* delegate_; - - State state_; - - std::string jid_; - - std::unique_ptr stream_parser_; - - DISALLOW_COPY_AND_ASSIGN(XmppLoginHandler); -}; - -} // namespace remoting - -#endif // REMOTING_SIGNALING_XMPP_LOGIN_HANDLER_H_ diff --git a/remoting/signaling/xmpp_login_handler_unittest.cc b/remoting/signaling/xmpp_login_handler_unittest.cc deleted file mode 100644 index d47ddaf117d87c..00000000000000 --- a/remoting/signaling/xmpp_login_handler_unittest.cc +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright 2015 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 "remoting/signaling/xmpp_login_handler.h" - -#include - -#include "base/base64.h" -#include "base/run_loop.h" -#include "base/test/scoped_task_environment.h" -#include "remoting/signaling/xmpp_stream_parser.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" - -#ifdef SendMessage -#undef SendMessage -#endif - -#ifdef ERROR -#undef ERROR -#endif - -namespace remoting { - -char kTestUsername[] = "testUsername@gmail.com"; -char kTestToken[] = "testToken"; - -class XmppLoginHandlerTest : public testing::Test, - public XmppLoginHandler::Delegate { - public: - XmppLoginHandlerTest() - : start_tls_called_(false), error_(SignalStrategy::OK) {} - - void TearDown() override { - login_handler_.reset(); - parser_.reset(); - base::RunLoop().RunUntilIdle(); - } - - void SendMessage(const std::string& message) override { - sent_data_ += message; - if (delete_login_handler_from_delegate_) - login_handler_.reset(); - } - - void StartTls() override { - start_tls_called_ = true; - if (delete_login_handler_from_delegate_) - login_handler_.reset(); - } - - void OnHandshakeDone(const std::string& jid, - std::unique_ptr parser) override { - jid_ = jid; - parser_ = std::move(parser); - if (delete_login_handler_from_delegate_) - login_handler_.reset(); - } - - void OnLoginHandlerError(SignalStrategy::Error error) override { - EXPECT_NE(error, SignalStrategy::OK); - error_ = error; - if (delete_login_handler_from_delegate_) - login_handler_.reset(); - } - - protected: - void HandshakeBase(); - - base::test::ScopedTaskEnvironment scoped_task_environment_; - - std::unique_ptr login_handler_; - std::string sent_data_; - bool start_tls_called_; - std::string jid_; - std::unique_ptr parser_; - SignalStrategy::Error error_; - bool delete_login_handler_from_delegate_ = false; -}; - -void XmppLoginHandlerTest::HandshakeBase() { - login_handler_.reset( - new XmppLoginHandler("google.com", kTestUsername, kTestToken, - XmppLoginHandler::TlsMode::WITHOUT_HANDSHAKE, this)); - login_handler_->Start(); - EXPECT_TRUE(start_tls_called_); - - login_handler_->OnTlsStarted(); - std::string cookie; - base::Base64Encode( - std::string("\0", 1) + kTestUsername + std::string("\0", 1) + kTestToken, - &cookie); - EXPECT_EQ( - sent_data_, - "" - "" + cookie + - ""); - sent_data_.clear(); - - login_handler_->OnDataReceived( - "" - "" - "" - "X-OAUTH2" - "X-GOOGLE-TOKEN" - "PLAIN" - "" - ""); -} - -TEST_F(XmppLoginHandlerTest, SuccessfulAuth) { - HandshakeBase(); - - login_handler_->OnDataReceived( - ""); - EXPECT_EQ( - sent_data_, - "" - "" - "" - "chromoting" - "" - "" - "" - "" - ""); - sent_data_.clear(); - - // |login_handler_| will call OnHandshakeDone() which will delete - // |login_handler_|. - delete_login_handler_from_delegate_ = true; - - login_handler_->OnDataReceived( - "" - "" - "" - "" - "" - "" - "" - "" + std::string(kTestUsername) + "/chromoting52B4920E" - "" - "" - ""); - - EXPECT_EQ(jid_, std::string(kTestUsername) + "/chromoting52B4920E"); - EXPECT_TRUE(parser_); - EXPECT_FALSE(login_handler_); -} - -TEST_F(XmppLoginHandlerTest, StartTlsHandshake) { - login_handler_.reset( - new XmppLoginHandler("google.com", kTestUsername, kTestToken, - XmppLoginHandler::TlsMode::WITH_HANDSHAKE, this)); - login_handler_->Start(); - EXPECT_FALSE(start_tls_called_); - - EXPECT_EQ(sent_data_, - "" - ""); - sent_data_.clear(); - - login_handler_->OnDataReceived( - "" - "" - "" - "" - "" - "" - "X-OAUTH2" - "X-GOOGLE-TOKEN" - "" - ""); - - login_handler_->OnDataReceived( - ""); - EXPECT_TRUE(start_tls_called_); -} - -TEST_F(XmppLoginHandlerTest, AuthError) { - HandshakeBase(); - - login_handler_->OnDataReceived( - "" - ""); - EXPECT_EQ(error_, SignalStrategy::AUTHENTICATION_FAILED); -} - -TEST_F(XmppLoginHandlerTest, NoTls) { - login_handler_.reset( - new XmppLoginHandler("google.com", kTestUsername, kTestToken, - XmppLoginHandler::TlsMode::NO_TLS, this)); - login_handler_->Start(); - - EXPECT_FALSE(start_tls_called_); - std::string cookie; - base::Base64Encode( - std::string("\0", 1) + kTestUsername + std::string("\0", 1) + kTestToken, - &cookie); - EXPECT_EQ( - sent_data_, - "" - "" + cookie + - ""); -} - -TEST_F(XmppLoginHandlerTest, StreamParseError) { - HandshakeBase(); - delete_login_handler_from_delegate_ = true; - login_handler_->OnDataReceived("BAD DATA"); - EXPECT_EQ(error_, SignalStrategy::PROTOCOL_ERROR); -} - -// Verify that LoginHandler doesn't crash when destroyed from -// Delegate::SendMessage(). -TEST_F(XmppLoginHandlerTest, DeleteInSendMessage) { - login_handler_.reset( - new XmppLoginHandler("google.com", kTestUsername, kTestToken, - XmppLoginHandler::TlsMode::WITHOUT_HANDSHAKE, this)); - login_handler_->Start(); - EXPECT_TRUE(start_tls_called_); - - delete_login_handler_from_delegate_ = true; - login_handler_->OnTlsStarted(); - EXPECT_FALSE(login_handler_); -} - -// Verify that LoginHandler doesn't crash when destroyed from -// Delegate::StartTls(). -TEST_F(XmppLoginHandlerTest, DeleteInStartTls) { - login_handler_.reset( - new XmppLoginHandler("google.com", kTestUsername, kTestToken, - XmppLoginHandler::TlsMode::WITHOUT_HANDSHAKE, this)); - delete_login_handler_from_delegate_ = true; - login_handler_->Start(); - EXPECT_TRUE(start_tls_called_); - EXPECT_FALSE(login_handler_); -} - -} // namespace remoting diff --git a/remoting/signaling/xmpp_signal_strategy.cc b/remoting/signaling/xmpp_signal_strategy.cc deleted file mode 100644 index c81452a20eb70c..00000000000000 --- a/remoting/signaling/xmpp_signal_strategy.cc +++ /dev/null @@ -1,594 +0,0 @@ -// Copyright 2014 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 "remoting/signaling/xmpp_signal_strategy.h" - -#include -#include - -#include "base/bind.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/observer_list.h" -#include "base/rand_util.h" -#include "base/single_thread_task_runner.h" -#include "base/strings/string_number_conversions.h" -#include "base/threading/thread_checker.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/time/time.h" -#include "base/timer/timer.h" -#include "net/cert/cert_verifier.h" -#include "net/cert/ct_policy_enforcer.h" -#include "net/cert/multi_log_ct_verifier.h" -#include "net/http/transport_security_state.h" -#include "net/socket/client_socket_factory.h" -#include "net/socket/ssl_client_socket.h" -#include "net/socket/stream_socket.h" -#include "net/traffic_annotation/network_traffic_annotation.h" -#include "net/url_request/url_request_context_getter.h" -#include "remoting/base/buffered_socket_writer.h" -#include "remoting/base/logging.h" -#include "remoting/signaling/signaling_address.h" -#include "remoting/signaling/xmpp_login_handler.h" -#include "remoting/signaling/xmpp_stream_parser.h" -#include "services/network/proxy_resolving_client_socket.h" -#include "services/network/proxy_resolving_client_socket_factory.h" -#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" - -// Use 50 seconds keep-alive interval, in case routers terminate -// connections that are idle for more than a minute. -const int kKeepAliveIntervalSeconds = 50; - -const int kReadBufferSize = 4096; - -const int kDefaultXmppPort = 5222; -const int kDefaultHttpsPort = 443; - -namespace remoting { - -XmppSignalStrategy::XmppServerConfig::XmppServerConfig() - : port(kDefaultXmppPort), use_tls(true) { -} - -XmppSignalStrategy::XmppServerConfig::XmppServerConfig( - const XmppServerConfig& other) = default; - -XmppSignalStrategy::XmppServerConfig::~XmppServerConfig() = default; - -class XmppSignalStrategy::Core : public XmppLoginHandler::Delegate { - public: - Core( - net::ClientSocketFactory* socket_factory, - const scoped_refptr& request_context_getter, - const XmppServerConfig& xmpp_server_config); - ~Core() override; - - void Connect(); - void Disconnect(); - State GetState() const; - Error GetError() const; - const SignalingAddress& GetLocalAddress() const; - void AddListener(Listener* listener); - void RemoveListener(Listener* listener); - bool SendStanza(std::unique_ptr stanza); - - void SetAuthInfo(const std::string& username, - const std::string& auth_token); - - private: - enum class TlsState { - // StartTls() hasn't been called. |socket_| is not encrypted. - NOT_REQUESTED, - - // StartTls() has been called. Waiting for |writer_| to finish writing - // data before starting TLS. - WAITING_FOR_FLUSH, - - // TLS has been started, waiting for TLS handshake to finish. - CONNECTING, - - // TLS is connected. - CONNECTED, - }; - - void OnSocketConnected(int result); - void OnTlsConnected(int result); - - void ReadSocket(); - void OnReadResult(int result); - void HandleReadResult(int result); - - // XmppLoginHandler::Delegate interface. - void SendMessage(const std::string& message) override; - void StartTls() override; - void OnHandshakeDone(const std::string& jid, - std::unique_ptr parser) override; - void OnLoginHandlerError(SignalStrategy::Error error) override; - - // Callback for BufferedSocketWriter. - void OnMessageSent(); - - // Event handlers for XmppStreamParser. - void OnStanza(const std::unique_ptr stanza); - void OnParserError(); - - void OnNetworkError(int error); - - void SendKeepAlive(); - - net::ClientSocketFactory* socket_factory_; - scoped_refptr request_context_getter_; - XmppServerConfig xmpp_server_config_; - - // Used by the |socket_|. - std::unique_ptr - proxy_resolving_socket_factory_; - std::unique_ptr cert_verifier_; - std::unique_ptr transport_security_state_; - std::unique_ptr cert_transparency_verifier_; - std::unique_ptr ct_policy_enforcer_; - - std::unique_ptr socket_; - std::unique_ptr writer_; - scoped_refptr read_buffer_; - bool read_pending_ = false; - - TlsState tls_state_ = TlsState::NOT_REQUESTED; - - std::unique_ptr login_handler_; - std::unique_ptr stream_parser_; - SignalingAddress local_address_; - - Error error_ = OK; - - base::ObserverList listeners_; - - base::RepeatingTimer keep_alive_timer_; - - base::ThreadChecker thread_checker_; - - DISALLOW_COPY_AND_ASSIGN(Core); -}; - -XmppSignalStrategy::Core::Core( - net::ClientSocketFactory* socket_factory, - const scoped_refptr& request_context_getter, - const XmppSignalStrategy::XmppServerConfig& xmpp_server_config) - : socket_factory_(socket_factory), - request_context_getter_(request_context_getter), - xmpp_server_config_(xmpp_server_config) { -#if defined(NDEBUG) - // Non-secure connections are allowed only for debugging. - CHECK(xmpp_server_config_.use_tls); -#endif - thread_checker_.DetachFromThread(); -} - -XmppSignalStrategy::Core::~Core() { - Disconnect(); -} - -void XmppSignalStrategy::Core::Connect() { - DCHECK(thread_checker_.CalledOnValidThread()); - - // Disconnect first if we are currently connected. - Disconnect(); - - error_ = OK; - - for (auto& observer : listeners_) - observer.OnSignalStrategyStateChange(CONNECTING); - - if (!proxy_resolving_socket_factory_) { - proxy_resolving_socket_factory_ = - std::make_unique( - request_context_getter_->GetURLRequestContext()); - } - socket_ = proxy_resolving_socket_factory_->CreateSocket( - GURL("https://" + - net::HostPortPair(xmpp_server_config_.host, xmpp_server_config_.port) - .ToString()), - false /*use_tls*/); - - int result = socket_->Connect(base::Bind( - &Core::OnSocketConnected, base::Unretained(this))); - - keep_alive_timer_.Start( - FROM_HERE, base::TimeDelta::FromSeconds(kKeepAliveIntervalSeconds), - base::Bind(&Core::SendKeepAlive, base::Unretained(this))); - - if (result != net::ERR_IO_PENDING) - OnSocketConnected(result); -} - -void XmppSignalStrategy::Core::Disconnect() { - DCHECK(thread_checker_.CalledOnValidThread()); - - if (socket_) { - login_handler_.reset(); - stream_parser_.reset(); - writer_.reset(); - socket_.reset(); - tls_state_ = TlsState::NOT_REQUESTED; - read_pending_ = false; - - for (auto& observer : listeners_) - observer.OnSignalStrategyStateChange(DISCONNECTED); - } -} - -SignalStrategy::State XmppSignalStrategy::Core::GetState() const { - DCHECK(thread_checker_.CalledOnValidThread()); - - if (stream_parser_) { - DCHECK(socket_); - return CONNECTED; - } else if (socket_) { - return CONNECTING; - } else { - return DISCONNECTED; - } -} - -SignalStrategy::Error XmppSignalStrategy::Core::GetError() const { - DCHECK(thread_checker_.CalledOnValidThread()); - return error_; -} - -const SignalingAddress& XmppSignalStrategy::Core::GetLocalAddress() const { - DCHECK(thread_checker_.CalledOnValidThread()); - return local_address_; -} - -void XmppSignalStrategy::Core::AddListener(Listener* listener) { - DCHECK(thread_checker_.CalledOnValidThread()); - listeners_.AddObserver(listener); -} - -void XmppSignalStrategy::Core::RemoveListener(Listener* listener) { - DCHECK(thread_checker_.CalledOnValidThread()); - listeners_.RemoveObserver(listener); -} - -bool XmppSignalStrategy::Core::SendStanza( - std::unique_ptr stanza) { - DCHECK(thread_checker_.CalledOnValidThread()); - - if (!stream_parser_) { - VLOG(0) << "Dropping signalling message because XMPP is not connected."; - return false; - } - - HOST_LOG << "Sending outgoing stanza:\n" - << stanza->Str() - << "\n========================================================="; - SendMessage(stanza->Str()); - - // Return false if the SendMessage() call above resulted in the SignalStrategy - // being disconnected. - return stream_parser_ != nullptr; -} - -void XmppSignalStrategy::Core::SetAuthInfo(const std::string& username, - const std::string& auth_token) { - DCHECK(thread_checker_.CalledOnValidThread()); - xmpp_server_config_.username = username; - xmpp_server_config_.auth_token = auth_token; -} - -void XmppSignalStrategy::Core::SendMessage(const std::string& message) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(tls_state_ == TlsState::NOT_REQUESTED || - tls_state_ == TlsState::CONNECTED); - - scoped_refptr buffer = - base::MakeRefCounted(message.size()); - memcpy(buffer->data(), message.data(), message.size()); - - net::NetworkTrafficAnnotationTag traffic_annotation = - net::DefineNetworkTrafficAnnotation("xmpp_signal_strategy", R"( - semantics { - sender: "Xmpp Signal Strategy" - description: - "This request is used for setting up the ICE connection between " - "the client and the host for Chrome Remote Desktop." - trigger: - "Initiating a Chrome Remote Desktop connection." - data: "No user data." - destination: OTHER - destination_other: - "The Chrome Remote Desktop client/host that user is connecting to." - } - policy { - cookies_allowed: NO - setting: - "This request cannot be stopped in settings, but will not be sent " - "if user does not use Chrome Remote Desktop." - policy_exception_justification: - "Not implemented. 'RemoteAccessHostClientDomainList' and " - "'RemoteAccessHostDomainList' policies can limit the domains to " - "which a connection can be made, but they cannot be used to block " - "the request to all domains. Please refer to help desk for other " - "approaches to manage this feature." - })"); - writer_->Write(buffer, - base::BindOnce(&Core::OnMessageSent, base::Unretained(this)), - traffic_annotation); -} - -void XmppSignalStrategy::Core::StartTls() { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(login_handler_); - DCHECK(tls_state_ == TlsState::NOT_REQUESTED || - tls_state_ == TlsState::WAITING_FOR_FLUSH); - - if (writer_->has_data_pending()) { - tls_state_ = TlsState::WAITING_FOR_FLUSH; - return; - } - - tls_state_ = TlsState::CONNECTING; - - // Reset the writer so we don't try to write to the raw socket anymore. - writer_.reset(); - - DCHECK(!read_pending_); - - cert_verifier_ = - net::CertVerifier::CreateDefault(/*cert_net_fetcher=*/nullptr); - transport_security_state_.reset(new net::TransportSecurityState()); - cert_transparency_verifier_.reset(new net::MultiLogCTVerifier()); - ct_policy_enforcer_.reset(new net::DefaultCTPolicyEnforcer()); - net::SSLClientSocketContext context; - context.cert_verifier = cert_verifier_.get(); - context.transport_security_state = transport_security_state_.get(); - context.cert_transparency_verifier = cert_transparency_verifier_.get(); - context.ct_policy_enforcer = ct_policy_enforcer_.get(); - - socket_ = socket_factory_->CreateSSLClientSocket( - std::move(socket_), - net::HostPortPair(xmpp_server_config_.host, kDefaultHttpsPort), - net::SSLConfig(), context); - - int result = socket_->Connect( - base::Bind(&Core::OnTlsConnected, base::Unretained(this))); - if (result != net::ERR_IO_PENDING) - OnTlsConnected(result); -} - -void XmppSignalStrategy::Core::OnHandshakeDone( - const std::string& jid, - std::unique_ptr parser) { - DCHECK(thread_checker_.CalledOnValidThread()); - - local_address_ = SignalingAddress(jid); - stream_parser_ = std::move(parser); - stream_parser_->SetCallbacks( - base::Bind(&Core::OnStanza, base::Unretained(this)), - base::Bind(&Core::OnParserError, base::Unretained(this))); - - // Don't need |login_handler_| anymore. - login_handler_.reset(); - - for (auto& observer : listeners_) - observer.OnSignalStrategyStateChange(CONNECTED); -} - -void XmppSignalStrategy::Core::OnLoginHandlerError( - SignalStrategy::Error error) { - DCHECK(thread_checker_.CalledOnValidThread()); - - error_ = error; - Disconnect(); -} - -void XmppSignalStrategy::Core::OnMessageSent() { - DCHECK(thread_checker_.CalledOnValidThread()); - - if (tls_state_ == TlsState::WAITING_FOR_FLUSH && - !writer_->has_data_pending()) { - StartTls(); - } -} - -void XmppSignalStrategy::Core::OnStanza( - const std::unique_ptr stanza) { - DCHECK(thread_checker_.CalledOnValidThread()); - - HOST_LOG << "Received incoming stanza:\n" - << stanza->Str() - << "\n========================================================="; - - for (auto& listener : listeners_) { - if (listener.OnSignalStrategyIncomingStanza(stanza.get())) - return; - } -} - -void XmppSignalStrategy::Core::OnParserError() { - DCHECK(thread_checker_.CalledOnValidThread()); - - error_ = NETWORK_ERROR; - Disconnect(); -} - -void XmppSignalStrategy::Core::OnSocketConnected(int result) { - DCHECK(thread_checker_.CalledOnValidThread()); - - if (result != net::OK) { - OnNetworkError(result); - return; - } - - writer_ = BufferedSocketWriter::CreateForSocket( - socket_.get(), base::Bind(&Core::OnNetworkError, base::Unretained(this))); - - XmppLoginHandler::TlsMode tls_mode; - if (xmpp_server_config_.use_tls) { - tls_mode = (xmpp_server_config_.port == kDefaultXmppPort) - ? XmppLoginHandler::TlsMode::WITH_HANDSHAKE - : XmppLoginHandler::TlsMode::WITHOUT_HANDSHAKE; - } else { - tls_mode = XmppLoginHandler::TlsMode::NO_TLS; - } - - // The server name is passed as to attribute in the . When connecting - // to talk.google.com it affects the certificate the server will use for TLS: - // talk.google.com uses gmail certificate when specified server is gmail.com - // or googlemail.com and google.com cert otherwise. In the same time it - // doesn't accept talk.google.com as target server. Here we use google.com - // server name when authenticating to talk.google.com. This ensures that the - // server will use google.com cert which will be accepted by the TLS - // implementation in Chrome (TLS API doesn't allow specifying domain other - // than the one that was passed to connect()). - std::string server = xmpp_server_config_.host; - if (server == "talk.google.com") - server = "google.com"; - - login_handler_.reset( - new XmppLoginHandler(server, xmpp_server_config_.username, - xmpp_server_config_.auth_token, tls_mode, this)); - login_handler_->Start(); - - ReadSocket(); -} - -void XmppSignalStrategy::Core::OnTlsConnected(int result) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(tls_state_ == TlsState::CONNECTING); - tls_state_ = TlsState::CONNECTED; - - if (result != net::OK) { - OnNetworkError(result); - return; - } - - writer_ = BufferedSocketWriter::CreateForSocket( - socket_.get(), base::Bind(&Core::OnNetworkError, base::Unretained(this))); - - login_handler_->OnTlsStarted(); - - ReadSocket(); -} - -void XmppSignalStrategy::Core::ReadSocket() { - DCHECK(thread_checker_.CalledOnValidThread()); - - while (socket_ && !read_pending_ && (tls_state_ == TlsState::NOT_REQUESTED || - tls_state_ == TlsState::CONNECTED)) { - read_buffer_ = base::MakeRefCounted(kReadBufferSize); - int result = socket_->Read( - read_buffer_.get(), kReadBufferSize, - base::Bind(&Core::OnReadResult, base::Unretained(this))); - HandleReadResult(result); - } -} - -void XmppSignalStrategy::Core::OnReadResult(int result) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(read_pending_); - read_pending_ = false; - HandleReadResult(result); - ReadSocket(); -} - -void XmppSignalStrategy::Core::HandleReadResult(int result) { - DCHECK(thread_checker_.CalledOnValidThread()); - - if (result == net::ERR_IO_PENDING) { - read_pending_ = true; - return; - } - - if (result < 0) { - OnNetworkError(result); - return; - } - - if (result == 0) { - // Connection was closed by the server. - error_ = OK; - Disconnect(); - return; - } - - if (stream_parser_) { - stream_parser_->AppendData(std::string(read_buffer_->data(), result)); - } else { - login_handler_->OnDataReceived(std::string(read_buffer_->data(), result)); - } -} - -void XmppSignalStrategy::Core::OnNetworkError(int error) { - DCHECK(thread_checker_.CalledOnValidThread()); - - LOG(ERROR) << "XMPP socket error " << error; - error_ = NETWORK_ERROR; - Disconnect(); -} - -void XmppSignalStrategy::Core::SendKeepAlive() { - DCHECK(thread_checker_.CalledOnValidThread()); - - if (GetState() == CONNECTED) - SendMessage(" "); -} - -XmppSignalStrategy::XmppSignalStrategy( - net::ClientSocketFactory* socket_factory, - const scoped_refptr& request_context_getter, - const XmppServerConfig& xmpp_server_config) - : core_(new Core(socket_factory, - request_context_getter, - xmpp_server_config)) { -} - -XmppSignalStrategy::~XmppSignalStrategy() { - // All listeners should be removed at this point, so it's safe to detach - // |core_|. - base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, core_.release()); -} - -void XmppSignalStrategy::Connect() { - core_->Connect(); -} - -void XmppSignalStrategy::Disconnect() { - core_->Disconnect(); -} - -SignalStrategy::State XmppSignalStrategy::GetState() const { - return core_->GetState(); -} - -SignalStrategy::Error XmppSignalStrategy::GetError() const { - return core_->GetError(); -} - -const SignalingAddress& XmppSignalStrategy::GetLocalAddress() const { - return core_->GetLocalAddress(); -} - -void XmppSignalStrategy::AddListener(Listener* listener) { - core_->AddListener(listener); -} - -void XmppSignalStrategy::RemoveListener(Listener* listener) { - core_->RemoveListener(listener); -} -bool XmppSignalStrategy::SendStanza(std::unique_ptr stanza) { - return core_->SendStanza(std::move(stanza)); -} - -std::string XmppSignalStrategy::GetNextId() { - return base::NumberToString(base::RandUint64()); -} - -void XmppSignalStrategy::SetAuthInfo(const std::string& username, - const std::string& auth_token) { - core_->SetAuthInfo(username, auth_token); -} - -} // namespace remoting diff --git a/remoting/signaling/xmpp_signal_strategy.h b/remoting/signaling/xmpp_signal_strategy.h deleted file mode 100644 index 97a5ef20ccaa70..00000000000000 --- a/remoting/signaling/xmpp_signal_strategy.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2014 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 REMOTING_SIGNALING_XMPP_SIGNAL_STRATEGY_H_ -#define REMOTING_SIGNALING_XMPP_SIGNAL_STRATEGY_H_ - -#include "remoting/signaling/signal_strategy.h" - -#include - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" - -namespace net { -class ClientSocketFactory; -class URLRequestContextGetter; -} // namespace net - -namespace remoting { - -// XmppSignalStrategy implements SignalStrategy using direct XMPP connection. -// This class can be created on a different thread from the one it is used (when -// Connect() is called). -class XmppSignalStrategy : public SignalStrategy { - public: - // XMPP Server configuration for XmppSignalStrategy. - struct XmppServerConfig { - XmppServerConfig(); - XmppServerConfig(const XmppServerConfig& other); - ~XmppServerConfig(); - - std::string host; - int port; - bool use_tls; - - std::string username; - std::string auth_token; - }; - - XmppSignalStrategy( - net::ClientSocketFactory* socket_factory, - const scoped_refptr& request_context_getter, - const XmppServerConfig& xmpp_server_config); - ~XmppSignalStrategy() override; - - // SignalStrategy interface. - void Connect() override; - void Disconnect() override; - State GetState() const override; - Error GetError() const override; - const SignalingAddress& GetLocalAddress() const override; - void AddListener(Listener* listener) override; - void RemoveListener(Listener* listener) override; - bool SendStanza(std::unique_ptr stanza) override; - std::string GetNextId() override; - - // This method is used to update the auth info (for example when the OAuth - // access token is renewed). It is OK to call this even when we are in the - // CONNECTED state. It will be used on the next Connect() call. - void SetAuthInfo(const std::string& username, - const std::string& auth_token); - - private: - // This ensures that even if a Listener deletes the current instance during - // OnSignalStrategyIncomingStanza(), we can delete |core_| asynchronously. - class Core; - - std::unique_ptr core_; - - DISALLOW_COPY_AND_ASSIGN(XmppSignalStrategy); -}; - -} // namespace remoting - -#endif // REMOTING_SIGNALING_XMPP_SIGNAL_STRATEGY_H_ diff --git a/remoting/signaling/xmpp_signal_strategy_unittest.cc b/remoting/signaling/xmpp_signal_strategy_unittest.cc deleted file mode 100644 index 96dcbfd1a855af..00000000000000 --- a/remoting/signaling/xmpp_signal_strategy_unittest.cc +++ /dev/null @@ -1,390 +0,0 @@ -// Copyright 2015 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 "remoting/signaling/xmpp_signal_strategy.h" - -#include -#include -#include - -#include "base/base64.h" -#include "base/run_loop.h" -#include "base/test/scoped_task_environment.h" -#include "net/socket/socket_test_util.h" -#include "net/socket/stream_socket.h" -#include "net/url_request/url_request_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" - -namespace remoting { - -namespace { - -class XmppSocketDataProvider : public net::SocketDataProvider { - public: - net::MockRead OnRead() override { - return net::MockRead(net::ASYNC, net::ERR_IO_PENDING); - } - - net::MockWriteResult OnWrite(const std::string& data) override { - if (write_error_ != net::OK) - return net::MockWriteResult(net::SYNCHRONOUS, write_error_); - - written_data_.append(data); - - if (use_async_write_) { - pending_write_size_ = data.size(); - return net::MockWriteResult(net::ASYNC, net::ERR_IO_PENDING); - } - - return net::MockWriteResult(net::SYNCHRONOUS, data.size()); - } - - void Reset() override {} - - bool AllReadDataConsumed() const override { - return true; - } - - bool AllWriteDataConsumed() const override { - return true; - } - - void ReceiveData(const std::string& text) { - socket()->OnReadComplete( - net::MockRead(net::ASYNC, text.data(), text.size())); - } - - void Close() { - ReceiveData(std::string()); - } - - void SimulateAsyncReadError() { - socket()->OnReadComplete( - net::MockRead(net::ASYNC, net::ERR_CONNECTION_RESET)); - } - - std::string GetAndClearWrittenData() { - std::string data; - data.swap(written_data_); - return data; - } - - void set_use_async_write(bool use_async_write) { - use_async_write_ = use_async_write; - } - - void set_write_error(net::Error error) { - write_error_ = error; - } - - void CompletePendingWrite() { - socket()->OnWriteComplete(pending_write_size_); - } - - private: - std::string written_data_; - bool use_async_write_ = false; - int pending_write_size_ = 0; - net::Error write_error_ = net::OK; -}; - -class MockClientSocketFactory : public net::MockClientSocketFactory { - public: - std::unique_ptr CreateSSLClientSocket( - std::unique_ptr stream_socket, - const net::HostPortPair& host_and_port, - const net::SSLConfig& ssl_config, - const net::SSLClientSocketContext& context) override { - ssl_socket_created_ = true; - return net::MockClientSocketFactory::CreateSSLClientSocket( - std::move(stream_socket), host_and_port, ssl_config, context); - } - - bool ssl_socket_created() const { return ssl_socket_created_; } - - private: - bool ssl_socket_created_ = false; -}; - -} // namespace - -const char kTestUsername[] = "test_username@example.com"; -const char kTestAuthToken[] = "test_auth_token"; -const int kDefaultPort = 443; - -class XmppSignalStrategyTest : public testing::Test, - public SignalStrategy::Listener { - public: - XmppSignalStrategyTest() - : scoped_task_environment_( - base::test::ScopedTaskEnvironment::MainThreadType::IO) {} - - void SetUp() override { - auto url_request_context = std::make_unique( - true /* delay_initialization */); - url_request_context->set_client_socket_factory(&client_socket_factory_); - url_request_context->Init(); - request_context_getter_ = new net::TestURLRequestContextGetter( - scoped_task_environment_.GetMainThreadTaskRunner(), - std::move(url_request_context)); - } - - void CreateSignalStrategy(int port) { - XmppSignalStrategy::XmppServerConfig config; - config.host = "talk.google.com"; - config.port = port; - config.username = kTestUsername; - config.auth_token = kTestAuthToken; - signal_strategy_.reset(new XmppSignalStrategy( - &client_socket_factory_, request_context_getter_, config)); - signal_strategy_->AddListener(this); - } - - void TearDown() override { - signal_strategy_->RemoveListener(this); - signal_strategy_.reset(); - base::RunLoop().RunUntilIdle(); - } - - void OnSignalStrategyStateChange(SignalStrategy::State state) override { - state_history_.push_back(state); - } - - bool OnSignalStrategyIncomingStanza(const jingle_xmpp::XmlElement* stanza) override { - received_messages_.push_back(std::make_unique(*stanza)); - return true; - } - - void Connect(bool success); - - protected: - base::test::ScopedTaskEnvironment scoped_task_environment_; - scoped_refptr request_context_getter_; - MockClientSocketFactory client_socket_factory_; - std::unique_ptr socket_data_provider_; - std::unique_ptr ssl_socket_data_provider_; - std::unique_ptr signal_strategy_; - - std::vector state_history_; - std::vector> received_messages_; -}; - -void XmppSignalStrategyTest::Connect(bool success) { - EXPECT_EQ(SignalStrategy::DISCONNECTED, signal_strategy_->GetState()); - state_history_.clear(); - - socket_data_provider_.reset(new XmppSocketDataProvider()); - socket_data_provider_->set_connect_data( - net::MockConnect(net::ASYNC, net::OK)); - client_socket_factory_.AddSocketDataProvider(socket_data_provider_.get()); - - ssl_socket_data_provider_.reset( - new net::SSLSocketDataProvider(net::ASYNC, net::OK)); - client_socket_factory_.AddSSLSocketDataProvider( - ssl_socket_data_provider_.get()); - - signal_strategy_->Connect(); - - EXPECT_EQ(SignalStrategy::CONNECTING, signal_strategy_->GetState()); - EXPECT_EQ(1U, state_history_.size()); - EXPECT_EQ(SignalStrategy::CONNECTING, state_history_[0]); - - // No data written before TLS. - EXPECT_EQ("", socket_data_provider_->GetAndClearWrittenData()); - - base::RunLoop().RunUntilIdle(); - - socket_data_provider_->ReceiveData( - "" - "" - "" - "X-OAUTH2" - "X-GOOGLE-TOKEN" - "PLAIN" - "" - ""); - - base::RunLoop().RunUntilIdle(); - - std::string cookie; - base::Base64Encode(std::string("\0", 1) + kTestUsername + - std::string("\0", 1) + kTestAuthToken, - &cookie); - // Expect auth message. - EXPECT_EQ( - "" - "" + cookie + - "", socket_data_provider_->GetAndClearWrittenData()); - - if (!success) { - socket_data_provider_->ReceiveData( - "" - ""); - EXPECT_EQ(2U, state_history_.size()); - EXPECT_EQ(SignalStrategy::DISCONNECTED, state_history_[1]); - EXPECT_EQ(SignalStrategy::AUTHENTICATION_FAILED, - signal_strategy_->GetError()); - return; - } - - socket_data_provider_->ReceiveData( - ""); - - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ( - "" - "" - "" - "chromoting" - "" - "" - "" - "" - "", - socket_data_provider_->GetAndClearWrittenData()); - socket_data_provider_->ReceiveData( - "" - "" - "" - "" - "" - "" - "" - "" + std::string(kTestUsername) + "/chromoting52B4920E" - "" - "" - ""); - - EXPECT_EQ(2U, state_history_.size()); - EXPECT_EQ(SignalStrategy::CONNECTED, state_history_[1]); -} - -TEST_F(XmppSignalStrategyTest, SendAndReceive) { - CreateSignalStrategy(kDefaultPort); - Connect(true); - - EXPECT_TRUE(signal_strategy_->SendStanza( - std::make_unique(jingle_xmpp::QName(std::string(), "hello")))); - EXPECT_EQ("", socket_data_provider_->GetAndClearWrittenData()); - - socket_data_provider_->ReceiveData(""); - EXPECT_EQ(1U, received_messages_.size()); - EXPECT_EQ("", received_messages_[0]->Str()); -} - -TEST_F(XmppSignalStrategyTest, AuthError) { - CreateSignalStrategy(kDefaultPort); - Connect(false); -} - -TEST_F(XmppSignalStrategyTest, ConnectionClosed) { - CreateSignalStrategy(kDefaultPort); - Connect(true); - - socket_data_provider_->Close(); - - EXPECT_EQ(3U, state_history_.size()); - EXPECT_EQ(SignalStrategy::DISCONNECTED, state_history_[2]); - EXPECT_EQ(SignalStrategy::DISCONNECTED, signal_strategy_->GetState()); - EXPECT_EQ(SignalStrategy::OK, signal_strategy_->GetError()); - - // Can't send messages anymore. - EXPECT_FALSE(signal_strategy_->SendStanza( - std::make_unique(jingle_xmpp::QName(std::string(), "hello")))); - - // Try connecting again. - Connect(true); -} - -TEST_F(XmppSignalStrategyTest, NetworkReadError) { - CreateSignalStrategy(kDefaultPort); - Connect(true); - - socket_data_provider_->SimulateAsyncReadError(); - - EXPECT_EQ(3U, state_history_.size()); - EXPECT_EQ(SignalStrategy::DISCONNECTED, state_history_[2]); - EXPECT_EQ(SignalStrategy::NETWORK_ERROR, signal_strategy_->GetError()); - - // Can't send messages anymore. - EXPECT_FALSE(signal_strategy_->SendStanza( - std::make_unique(jingle_xmpp::QName(std::string(), "hello")))); - - // Try connecting again. - Connect(true); -} - -TEST_F(XmppSignalStrategyTest, NetworkWriteError) { - CreateSignalStrategy(kDefaultPort); - Connect(true); - - socket_data_provider_->set_write_error(net::ERR_FAILED); - - // Next SendMessage() will call Write() which will fail. - EXPECT_FALSE(signal_strategy_->SendStanza( - std::make_unique(jingle_xmpp::QName(std::string(), "hello")))); - - EXPECT_EQ(3U, state_history_.size()); - EXPECT_EQ(SignalStrategy::DISCONNECTED, state_history_[2]); - EXPECT_EQ(SignalStrategy::NETWORK_ERROR, signal_strategy_->GetError()); - - // Try connecting again. - Connect(true); -} - -TEST_F(XmppSignalStrategyTest, StartTlsWithPendingWrite) { - // Use port 5222 so that XmppLoginHandler uses starttls/proceed handshake - // before starting TLS. - CreateSignalStrategy(5222); - - socket_data_provider_.reset(new XmppSocketDataProvider()); - socket_data_provider_->set_connect_data( - net::MockConnect(net::SYNCHRONOUS, net::OK)); - client_socket_factory_.AddSocketDataProvider(socket_data_provider_.get()); - - ssl_socket_data_provider_.reset( - new net::SSLSocketDataProvider(net::ASYNC, net::OK)); - client_socket_factory_.AddSSLSocketDataProvider( - ssl_socket_data_provider_.get()); - - // Make sure write is handled asynchronously. - socket_data_provider_->set_use_async_write(true); - - signal_strategy_->Connect(); - base::RunLoop().RunUntilIdle(); - - socket_data_provider_->ReceiveData( - "" - "" - "" - "" - ""); - - // Verify that SSL is connected only after write is finished. - EXPECT_FALSE(client_socket_factory_.ssl_socket_created()); - socket_data_provider_->CompletePendingWrite(); - EXPECT_TRUE(client_socket_factory_.ssl_socket_created()); -} - - - } // namespace remoting diff --git a/remoting/signaling/xmpp_stream_parser.cc b/remoting/signaling/xmpp_stream_parser.cc deleted file mode 100644 index 10ba038866f51a..00000000000000 --- a/remoting/signaling/xmpp_stream_parser.cc +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2015 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 "remoting/signaling/xmpp_stream_parser.h" - -#include "base/location.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" -#include "third_party/libjingle_xmpp/xmllite/xmlbuilder.h" -#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" -#include "third_party/libjingle_xmpp/xmllite/xmlparser.h" - -namespace remoting { - -class XmppStreamParser::Core : public jingle_xmpp::XmlParseHandler { - public: - typedef base::Callback stanza)> - OnStanzaCallback; - - Core(); - ~Core() override; - - void SetCallbacks(const OnStanzaCallback& on_stanza_callback, - const base::Closure& on_error_callback); - - void AppendData(const std::string& data); - - private: - // jingle_xmpp::XmlParseHandler interface. - void StartElement(jingle_xmpp::XmlParseContext* context, - const char* name, - const char** atts) override; - void EndElement(jingle_xmpp::XmlParseContext* context, const char* name) override; - void CharacterData(jingle_xmpp::XmlParseContext* context, - const char* text, - int len) override; - void Error(jingle_xmpp::XmlParseContext* context, XML_Error error_code) override; - - void ProcessError(); - - OnStanzaCallback on_stanza_callback_; - base::Closure on_error_callback_; - - jingle_xmpp::XmlParser parser_; - int depth_; - jingle_xmpp::XmlBuilder builder_; - - bool error_; - - DISALLOW_COPY_AND_ASSIGN(Core); -}; - -XmppStreamParser::Core::Core() - : parser_(this), - depth_(0), - error_(false) { -} - -XmppStreamParser::Core::~Core() = default; - -void XmppStreamParser::Core::SetCallbacks( - const OnStanzaCallback& on_stanza_callback, - const base::Closure& on_error_callback) { - on_stanza_callback_ = on_stanza_callback; - on_error_callback_ = on_error_callback; -} - -void XmppStreamParser::Core::AppendData(const std::string& data) { - if (error_) - return; - parser_.Parse(data.data(), data.size(), false); -} - -void XmppStreamParser::Core::StartElement(jingle_xmpp::XmlParseContext* context, - const char* name, - const char** atts) { - DCHECK(!error_); - - ++depth_; - if (depth_ == 1) { - std::unique_ptr header( - jingle_xmpp::XmlBuilder::BuildElement(context, name, atts)); - if (!header) { - LOG(ERROR) << "Failed to parse XMPP stream header."; - ProcessError(); - } - return; - } - - builder_.StartElement(context, name, atts); -} - -void XmppStreamParser::Core::EndElement(jingle_xmpp::XmlParseContext* context, - const char* name) { - DCHECK(!error_); - - --depth_; - if (depth_ == 0) { - LOG(ERROR) << "XMPP stream ended unexpectedly."; - ProcessError(); - return; - } - - builder_.EndElement(context, name); - - if (depth_ == 1) { - if (!on_stanza_callback_.is_null()) - on_stanza_callback_.Run(base::WrapUnique(builder_.CreateElement())); - } -} - -void XmppStreamParser::Core::CharacterData(jingle_xmpp::XmlParseContext* context, - const char* text, - int len) { - DCHECK(!error_); - - // Ignore data between stanzas. - if (depth_ <= 1) { - // Only whitespace is allowed outside of the stanzas. - bool all_spaces = true; - for (char c: std::string(text, len)) { - if (c != ' ') { - all_spaces = false; - break; - } - } - if (!all_spaces) { - LOG(ERROR) << "Received unexpected string: " << std::string(text, - text + len); - ProcessError(); - } - } else if (depth_ > 1) { - builder_.CharacterData(context, text, len); - } -} - -void XmppStreamParser::Core::Error(jingle_xmpp::XmlParseContext* context, - XML_Error error_code) { - LOG(ERROR) << "XMPP parser error: " << error_code; - ProcessError(); -} - -void XmppStreamParser::Core::ProcessError() { - error_ = true; - if (!on_error_callback_.is_null()) - on_error_callback_.Run(); -} - -XmppStreamParser::XmppStreamParser() : core_(new Core()) { -} - -XmppStreamParser::~XmppStreamParser() { - // Set null callbacks and delete |core_| asynchronously to make sure it's not - // deleted from a callback. - core_->SetCallbacks(OnStanzaCallback(), base::Closure()); - base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, core_.release()); -} - -void XmppStreamParser::SetCallbacks(const OnStanzaCallback& on_stanza_callback, - const base::Closure& on_error_callback) { - core_->SetCallbacks(on_stanza_callback, on_error_callback); -} - -void XmppStreamParser::AppendData(const std::string& data) { - core_->AppendData(data); -} - -} // namespace remoting diff --git a/remoting/signaling/xmpp_stream_parser.h b/remoting/signaling/xmpp_stream_parser.h deleted file mode 100644 index 1b45ba8d16f533..00000000000000 --- a/remoting/signaling/xmpp_stream_parser.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2015 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 REMOTING_SIGNALING_XMPP_STREAM_PARSER_H_ -#define REMOTING_SIGNALING_XMPP_STREAM_PARSER_H_ - -#include -#include - -#include "base/callback.h" -#include "base/macros.h" - -namespace jingle_xmpp { -class XmlElement; -} // namespace jingle_xmpp - -namespace remoting { - -// XmppStreamParser is used to parse XMPP stream. Data is fed to the parser -// using appendData() method and it calls |on_stanza_callback\ and -// |on_error_callback| specified using SetCallbacks(). -class XmppStreamParser { - public: - typedef base::Callback stanza)> - OnStanzaCallback; - - XmppStreamParser(); - ~XmppStreamParser(); - - void SetCallbacks(const OnStanzaCallback& on_stanza_callback, - const base::Closure& on_error_callback); - - void AppendData(const std::string& data); - - private: - class Core; - - std::unique_ptr core_; - - DISALLOW_COPY_AND_ASSIGN(XmppStreamParser); -}; - -} // namespace remoting - -#endif // REMOTING_SIGNALING_XMPP_STREAM_PARSER_H_ diff --git a/remoting/signaling/xmpp_stream_parser_unittest.cc b/remoting/signaling/xmpp_stream_parser_unittest.cc deleted file mode 100644 index 6922476cce2cbc..00000000000000 --- a/remoting/signaling/xmpp_stream_parser_unittest.cc +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2015 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 "remoting/signaling/xmpp_stream_parser.h" - -#include -#include -#include - -#include "base/bind.h" -#include "base/run_loop.h" -#include "base/test/scoped_task_environment.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" - -namespace remoting { - -class XmppStreamParserTest : public testing::Test { - public: - XmppStreamParserTest() : error_(false) {} - - void SetUp() override { - parser_.reset(new remoting::XmppStreamParser()); - parser_->SetCallbacks( - base::Bind(&XmppStreamParserTest::OnStanza, base::Unretained(this)), - base::Bind(&XmppStreamParserTest::OnError, base::Unretained(this))); - } - - void TearDown() override { - parser_.reset(); - base::RunLoop().RunUntilIdle(); - } - - void OnStanza(std::unique_ptr stanza) { - received_stanzas_.push_back(std::move(stanza)); - } - - void OnError() { - error_ = true; - } - - protected: - base::test::ScopedTaskEnvironment scoped_task_environment_; - - std::unique_ptr parser_; - std::vector> received_stanzas_; - bool error_; -}; - -TEST_F(XmppStreamParserTest, ParseXmppStream) { - parser_->AppendData("text"); - EXPECT_EQ(received_stanzas_[0]->Str(), "text"); -} - -TEST_F(XmppStreamParserTest, HandleMultipleIncomingStanzas) { - parser_->AppendData("textmore text"); - EXPECT_EQ(received_stanzas_[0]->Str(), "text"); - EXPECT_EQ(received_stanzas_[1]->Str(), "more text"); -} - -TEST_F(XmppStreamParserTest, IgnoreWhitespaceBetweenStanzas) { - parser_->AppendData(" text"); - EXPECT_EQ(received_stanzas_[0]->Str(), "text"); -} - -TEST_F(XmppStreamParserTest, AssembleMessagesFromChunks) { - parser_->AppendData("AppendData("q>"); - - // Split one UTF-8 sequence into two chunks - std::string data = "😃"; - parser_->AppendData(data.substr(0, 2)); - parser_->AppendData(data.substr(2)); - - parser_->AppendData(""); - - EXPECT_EQ(received_stanzas_[0]->Str(), "😃"); -} - -TEST_F(XmppStreamParserTest, StopParsingOnErrors) { - parser_->AppendData("text"); - EXPECT_TRUE(error_); - EXPECT_TRUE(received_stanzas_.empty()); -} - -TEST_F(XmppStreamParserTest, FailOnInvalidStreamHeader) { - parser_->AppendData(""); - EXPECT_TRUE(error_); -} - -TEST_F(XmppStreamParserTest, FailOnLooseText) { - parser_->AppendData("stream<"); - EXPECT_TRUE(error_); -} - -} // namespace remoting diff --git a/remoting/test/it2me_cli_host.cc b/remoting/test/it2me_cli_host.cc index f5dfa3463ead10..d43f2160c306f9 100644 --- a/remoting/test/it2me_cli_host.cc +++ b/remoting/test/it2me_cli_host.cc @@ -41,13 +41,10 @@ constexpr char kCRDDebugLog[] = "_debug_log"; // Connect message parameters: constexpr char kCRDConnectUserName[] = "userName"; constexpr char kCRDConnectAuth[] = "authServiceWithToken"; -constexpr char kCRDConnectXMPPServer[] = "xmppServerAddress"; -constexpr char kCRDConnectXMPPTLS[] = "xmppServerUseTls"; constexpr char kCRDConnectDirectoryBot[] = "directoryBotJid"; constexpr char kCRDConnectNoDialogs[] = "noDialogs"; // Connect message parameter values: -constexpr char kCRDConnectXMPPServerValue[] = "talk.google.com:443"; constexpr char kCRDConnectDirectoryBotValue[] = "remoting@bot.talk.google.com"; // CRD host states we care about: @@ -219,9 +216,6 @@ void It2MeCliHost::StartCRDHostAndGetCode(OAuthTokenGetter::Status status, connect_params.SetKey(kCRDConnectUserName, base::Value(user_email)); connect_params.SetKey(kCRDConnectAuth, base::Value("oauth2:" + access_token)); - connect_params.SetKey(kCRDConnectXMPPServer, - base::Value(kCRDConnectXMPPServerValue)); - connect_params.SetKey(kCRDConnectXMPPTLS, base::Value(true)); connect_params.SetKey(kCRDConnectDirectoryBot, base::Value(kCRDConnectDirectoryBotValue)); connect_params.SetKey(kCRDConnectNoDialogs, base::Value(true)); diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 28b4a02f88f596..98081a28f5ffb5 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml @@ -294,6 +294,5 @@ Refer to README.md for content description and update process. -