From 6c44b53b10ea8b759b8e209e107a197cc1d445e1 Mon Sep 17 00:00:00 2001 From: "sergeyu@chromium.org" Date: Fri, 24 Feb 2012 21:57:44 +0000 Subject: Rename PepperSession to JingleSession. After Transport interface has been added the PepperSession is not specific to Pepper anymore, so renaming it to JingleSession. Also removed some header files that were left from the previous refactoring, and are not used anymore. Review URL: https://chromiumcodereview.appspot.com/9428055 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123560 0039d316-1c4b-4281-b951-d872f2087c98 --- remoting/host/chromoting_host.cc | 4 +- remoting/protocol/connection_to_host.cc | 4 +- remoting/protocol/jingle_session.cc | 559 +++++++++++++++++++++++++++ remoting/protocol/jingle_session.h | 154 ++++++++ remoting/protocol/jingle_session_manager.cc | 183 +++++++++ remoting/protocol/jingle_session_manager.h | 109 ++++++ remoting/protocol/jingle_session_unittest.cc | 375 ++++++++++++++++++ remoting/protocol/pepper_channel.h | 56 --- remoting/protocol/pepper_session.cc | 559 --------------------------- remoting/protocol/pepper_session.h | 154 -------- remoting/protocol/pepper_session_manager.cc | 183 --------- remoting/protocol/pepper_session_manager.h | 107 ----- remoting/protocol/pepper_session_unittest.cc | 375 ------------------ remoting/protocol/pepper_stream_channel.h | 77 ---- remoting/remoting.gyp | 10 +- 15 files changed, 1389 insertions(+), 1520 deletions(-) create mode 100644 remoting/protocol/jingle_session.cc create mode 100644 remoting/protocol/jingle_session.h create mode 100644 remoting/protocol/jingle_session_manager.cc create mode 100644 remoting/protocol/jingle_session_manager.h create mode 100644 remoting/protocol/jingle_session_unittest.cc delete mode 100644 remoting/protocol/pepper_channel.h delete mode 100644 remoting/protocol/pepper_session.cc delete mode 100644 remoting/protocol/pepper_session.h delete mode 100644 remoting/protocol/pepper_session_manager.cc delete mode 100644 remoting/protocol/pepper_session_manager.h delete mode 100644 remoting/protocol/pepper_session_unittest.cc delete mode 100644 remoting/protocol/pepper_stream_channel.h (limited to 'remoting') diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc index 0b9ee8f..ab3478a 100644 --- a/remoting/host/chromoting_host.cc +++ b/remoting/host/chromoting_host.cc @@ -22,8 +22,8 @@ #include "remoting/protocol/client_stub.h" #include "remoting/protocol/host_stub.h" #include "remoting/protocol/input_stub.h" +#include "remoting/protocol/jingle_session_manager.h" #include "remoting/protocol/libjingle_transport_factory.h" -#include "remoting/protocol/pepper_session_manager.h" #include "remoting/protocol/session_config.h" using remoting::protocol::ConnectionToClient; @@ -70,7 +70,7 @@ void ChromotingHost::Start() { scoped_ptr transport_factory( new protocol::LibjingleTransportFactory()); session_manager_.reset( - new protocol::PepperSessionManager(transport_factory.Pass())); + new protocol::JingleSessionManager(transport_factory.Pass())); session_manager_->Init(signal_strategy_, this, network_settings_); } diff --git a/remoting/protocol/connection_to_host.cc b/remoting/protocol/connection_to_host.cc index 9352712..3e109336 100644 --- a/remoting/protocol/connection_to_host.cc +++ b/remoting/protocol/connection_to_host.cc @@ -16,7 +16,7 @@ #include "remoting/protocol/client_control_dispatcher.h" #include "remoting/protocol/client_event_dispatcher.h" #include "remoting/protocol/client_stub.h" -#include "remoting/protocol/pepper_session_manager.h" +#include "remoting/protocol/jingle_session_manager.h" #include "remoting/protocol/pepper_transport_factory.h" #include "remoting/protocol/video_reader.h" #include "remoting/protocol/video_stub.h" @@ -72,7 +72,7 @@ void ConnectionToHost::Connect(scoped_refptr xmpp_proxy, scoped_ptr transport_factory( new PepperTransportFactory(pp_instance_)); - session_manager_.reset(new PepperSessionManager(transport_factory.Pass())); + session_manager_.reset(new JingleSessionManager(transport_factory.Pass())); session_manager_->Init(signal_strategy_.get(), this, NetworkSettings(allow_nat_traversal_)); } diff --git a/remoting/protocol/jingle_session.cc b/remoting/protocol/jingle_session.cc new file mode 100644 index 0000000..61d4bc9 --- /dev/null +++ b/remoting/protocol/jingle_session.cc @@ -0,0 +1,559 @@ +// 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/protocol/jingle_session.h" + +#include "base/bind.h" +#include "base/rand_util.h" +#include "base/stl_util.h" +#include "base/string_number_conversions.h" +#include "remoting/base/constants.h" +#include "remoting/jingle_glue/iq_sender.h" +#include "remoting/protocol/authenticator.h" +#include "remoting/protocol/channel_authenticator.h" +#include "remoting/protocol/content_description.h" +#include "remoting/protocol/jingle_messages.h" +#include "remoting/protocol/jingle_session_manager.h" +#include "remoting/protocol/session_config.h" +#include "third_party/libjingle/source/talk/p2p/base/candidate.h" +#include "third_party/libjingle/source/talk/xmllite/xmlelement.h" + +using buzz::XmlElement; + +namespace remoting { +namespace protocol { + +namespace { +// Delay after candidate creation before sending transport-info +// message. This is neccessary to be able to pack multiple candidates +// into one transport-info messages. The value needs to be greater +// than zero because ports are opened asynchronously in the browser +// process. +const int kTransportInfoSendDelayMs = 2; + +Session::Error AuthRejectionReasonToError( + Authenticator::RejectionReason reason) { + switch (reason) { + case Authenticator::INVALID_CREDENTIALS: + return Session::AUTHENTICATION_FAILED; + case Authenticator::PROTOCOL_ERROR: + return Session::INCOMPATIBLE_PROTOCOL; + } + NOTREACHED(); + return Session::UNKNOWN_ERROR; +} + +} // namespace + +JingleSession::JingleSession(JingleSessionManager* session_manager) + : session_manager_(session_manager), + state_(INITIALIZING), + error_(OK), + config_is_set_(false) { +} + +JingleSession::~JingleSession() { + STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); + session_manager_->SessionDestroyed(this); +} + +void JingleSession::SetStateChangeCallback( + const StateChangeCallback& callback) { + DCHECK(CalledOnValidThread()); + DCHECK(!callback.is_null()); + state_change_callback_ = callback; +} + +void JingleSession::SetRouteChangeCallback( + const RouteChangeCallback& callback) { + DCHECK(CalledOnValidThread()); + route_change_callback_ = callback; +} + +Session::Error JingleSession::error() { + DCHECK(CalledOnValidThread()); + return error_; +} + +void JingleSession::StartConnection( + const std::string& peer_jid, + scoped_ptr authenticator, + scoped_ptr config, + const StateChangeCallback& state_change_callback) { + DCHECK(CalledOnValidThread()); + DCHECK(authenticator.get()); + DCHECK_EQ(authenticator->state(), Authenticator::MESSAGE_READY); + + peer_jid_ = peer_jid; + authenticator_ = authenticator.Pass(); + candidate_config_ = config.Pass(); + state_change_callback_ = state_change_callback; + + // Generate random session ID. There are usually not more than 1 + // concurrent session per host, so a random 64-bit integer provides + // enough entropy. In the worst case connection will fail when two + // clients generate the same session ID concurrently. + session_id_ = base::Int64ToString(base::RandGenerator(kint64max)); + + // Send session-initiate message. + JingleMessage message(peer_jid_, JingleMessage::SESSION_INITIATE, + session_id_); + message.description.reset( + new ContentDescription(candidate_config_->Clone(), + authenticator_->GetNextMessage())); + initiate_request_ = session_manager_->iq_sender()->SendIq( + message.ToXml(), + base::Bind(&JingleSession::OnSessionInitiateResponse, + base::Unretained(this))); + + SetState(CONNECTING); +} + +void JingleSession::InitializeIncomingConnection( + const JingleMessage& initiate_message, + scoped_ptr authenticator) { + DCHECK(CalledOnValidThread()); + DCHECK(initiate_message.description.get()); + DCHECK(authenticator.get()); + DCHECK_EQ(authenticator->state(), Authenticator::WAITING_MESSAGE); + + peer_jid_ = initiate_message.from; + authenticator_ = authenticator.Pass(); + session_id_ = initiate_message.sid; + candidate_config_ = initiate_message.description->config()->Clone(); + + SetState(CONNECTING); +} + +void JingleSession::AcceptIncomingConnection( + const JingleMessage& initiate_message) { + DCHECK(config_is_set_); + + // Process the first authentication message. + const buzz::XmlElement* first_auth_message = + initiate_message.description->authenticator_message(); + + if (!first_auth_message) { + CloseInternal(INCOMPATIBLE_PROTOCOL); + return; + } + + DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); + authenticator_->ProcessMessage(first_auth_message); + if (authenticator_->state() == Authenticator::REJECTED) { + CloseInternal(AuthRejectionReasonToError( + authenticator_->rejection_reason())); + return; + } + + // Send the session-accept message. + JingleMessage message(peer_jid_, JingleMessage::SESSION_ACCEPT, + session_id_); + + scoped_ptr auth_message; + if (authenticator_->state() == Authenticator::MESSAGE_READY) + auth_message = authenticator_->GetNextMessage(); + + message.description.reset( + new ContentDescription(CandidateSessionConfig::CreateFrom(config_), + auth_message.Pass())); + initiate_request_ = session_manager_->iq_sender()->SendIq( + message.ToXml(), + base::Bind(&JingleSession::OnSessionInitiateResponse, + base::Unretained(this))); + + // Update state. + SetState(CONNECTED); + + if (authenticator_->state() == Authenticator::ACCEPTED) { + SetState(AUTHENTICATED); + } else { + DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); + } + + return; +} + +void JingleSession::OnSessionInitiateResponse( + const buzz::XmlElement* response) { + const std::string& type = response->Attr(buzz::QName("", "type")); + if (type != "result") { + LOG(ERROR) << "Received error in response to session-initiate message: \"" + << response->Str() + << "\". Terminating the session."; + + // TODO(sergeyu): There may be different reasons for error + // here. Parse the response stanza to find failure reason. + CloseInternal(PEER_IS_OFFLINE); + } +} + +void JingleSession::CreateStreamChannel( + const std::string& name, + const StreamChannelCallback& callback) { + DCHECK(!channels_[name]); + + scoped_ptr channel_authenticator = + authenticator_->CreateChannelAuthenticator(); + scoped_ptr channel = + session_manager_->transport_factory_->CreateStreamTransport(); + channel->Initialize(name, session_manager_->transport_config_, + this, channel_authenticator.Pass()); + channel->Connect(callback); + channels_[name] = channel.release(); +} + +void JingleSession::CreateDatagramChannel( + const std::string& name, + const DatagramChannelCallback& callback) { + DCHECK(!channels_[name]); + + scoped_ptr channel_authenticator = + authenticator_->CreateChannelAuthenticator(); + scoped_ptr channel = + session_manager_->transport_factory_->CreateDatagramTransport(); + channel->Initialize(name, session_manager_->transport_config_, + this, channel_authenticator.Pass()); + channel->Connect(callback); + channels_[name] = channel.release(); +} + +void JingleSession::CancelChannelCreation(const std::string& name) { + ChannelsMap::iterator it = channels_.find(name); + if (it != channels_.end() && !it->second->is_connected()) { + delete it->second; + DCHECK(!channels_[name]); + } +} + +const std::string& JingleSession::jid() { + DCHECK(CalledOnValidThread()); + return peer_jid_; +} + +const CandidateSessionConfig* JingleSession::candidate_config() { + DCHECK(CalledOnValidThread()); + return candidate_config_.get(); +} + +const SessionConfig& JingleSession::config() { + DCHECK(CalledOnValidThread()); + return config_; +} + +void JingleSession::set_config(const SessionConfig& config) { + DCHECK(CalledOnValidThread()); + DCHECK(!config_is_set_); + config_ = config; + config_is_set_ = true; +} + +void JingleSession::Close() { + DCHECK(CalledOnValidThread()); + + CloseInternal(OK); +} + +void JingleSession::OnTransportCandidate(Transport* transport, + const cricket::Candidate& candidate) { + pending_candidates_.push_back(candidate); + + if (!transport_infos_timer_.IsRunning()) { + // Delay sending the new candidates in case we get more candidates + // that we can send in one message. + transport_infos_timer_.Start( + FROM_HERE, base::TimeDelta::FromMilliseconds(kTransportInfoSendDelayMs), + this, &JingleSession::SendTransportInfo); + } +} + +void JingleSession::OnTransportRouteChange(Transport* transport, + const TransportRoute& route) { + if (!route_change_callback_.is_null()) { + route_change_callback_.Run(transport->name(), route.remote_address, + route.local_address); + } +} + +void JingleSession::OnTransportDeleted(Transport* transport) { + ChannelsMap::iterator it = channels_.find(transport->name()); + DCHECK_EQ(it->second, transport); + channels_.erase(it); +} + +void JingleSession::OnIncomingMessage(const JingleMessage& message, + const ReplyCallback& reply_callback) { + DCHECK(CalledOnValidThread()); + + if (message.from != peer_jid_) { + // Ignore messages received from a different Jid. + reply_callback.Run(JingleMessageReply::INVALID_SID); + return; + } + + switch (message.action) { + case JingleMessage::SESSION_ACCEPT: + OnAccept(message, reply_callback); + break; + + case JingleMessage::SESSION_INFO: + OnSessionInfo(message, reply_callback); + break; + + case JingleMessage::TRANSPORT_INFO: + reply_callback.Run(JingleMessageReply::NONE); + ProcessTransportInfo(message); + break; + + case JingleMessage::SESSION_TERMINATE: + OnTerminate(message, reply_callback); + break; + + default: + reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); + } +} + +void JingleSession::OnAccept(const JingleMessage& message, + const ReplyCallback& reply_callback) { + if (state_ != CONNECTING) { + reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); + return; + } + + reply_callback.Run(JingleMessageReply::NONE); + + const buzz::XmlElement* auth_message = + message.description->authenticator_message(); + if (!auth_message) { + DLOG(WARNING) << "Received session-accept without authentication message " + << auth_message->Str(); + CloseInternal(INCOMPATIBLE_PROTOCOL); + return; + } + + DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); + authenticator_->ProcessMessage(auth_message); + + if (!InitializeConfigFromDescription(message.description.get())) { + CloseInternal(INCOMPATIBLE_PROTOCOL); + return; + } + + // In case there is transport information in the accept message. + ProcessTransportInfo(message); + + SetState(CONNECTED); + + // Process authentication. + if (authenticator_->state() == Authenticator::ACCEPTED) { + SetState(AUTHENTICATED); + } else { + ProcessAuthenticationStep(); + } +} + +void JingleSession::OnSessionInfo(const JingleMessage& message, + const ReplyCallback& reply_callback) { + if (!message.info.get() || + !Authenticator::IsAuthenticatorMessage(message.info.get())) { + reply_callback.Run(JingleMessageReply::UNSUPPORTED_INFO); + return; + } + + if (state_ != CONNECTED || + authenticator_->state() != Authenticator::WAITING_MESSAGE) { + LOG(WARNING) << "Received unexpected authenticator message " + << message.info->Str(); + reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); + CloseInternal(INCOMPATIBLE_PROTOCOL); + return; + } + + reply_callback.Run(JingleMessageReply::NONE); + + authenticator_->ProcessMessage(message.info.get()); + ProcessAuthenticationStep(); +} + +void JingleSession::ProcessTransportInfo(const JingleMessage& message) { + for (std::list::const_iterator it = + message.candidates.begin(); + it != message.candidates.end(); ++it) { + ChannelsMap::iterator channel = channels_.find(it->name()); + if (channel == channels_.end()) { + LOG(WARNING) << "Received candidate for unknown channel " << it->name(); + continue; + } + channel->second->AddRemoteCandidate(*it); + } +} + +void JingleSession::OnTerminate(const JingleMessage& message, + const ReplyCallback& reply_callback) { + if (state_ != CONNECTING && state_ != CONNECTED && state_ != AUTHENTICATED) { + LOG(WARNING) << "Received unexpected session-terminate message."; + reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); + return; + } + + reply_callback.Run(JingleMessageReply::NONE); + + switch (message.reason) { + case JingleMessage::SUCCESS: + if (state_ == CONNECTING) { + error_ = SESSION_REJECTED; + } else { + error_ = OK; + } + break; + case JingleMessage::DECLINE: + error_ = AUTHENTICATION_FAILED; + break; + case JingleMessage::GENERAL_ERROR: + error_ = CHANNEL_CONNECTION_ERROR; + break; + case JingleMessage::INCOMPATIBLE_PARAMETERS: + error_ = INCOMPATIBLE_PROTOCOL; + break; + default: + error_ = UNKNOWN_ERROR; + } + + if (error_ != OK) { + SetState(FAILED); + } else { + SetState(CLOSED); + } +} + +bool JingleSession::InitializeConfigFromDescription( + const ContentDescription* description) { + DCHECK(description); + + if (!description->config()->GetFinalConfig(&config_)) { + LOG(ERROR) << "session-accept does not specify configuration"; + return false; + } + if (!candidate_config()->IsSupported(config_)) { + LOG(ERROR) << "session-accept specifies an invalid configuration"; + return false; + } + + return true; +} + +void JingleSession::ProcessAuthenticationStep() { + DCHECK_EQ(state_, CONNECTED); + + if (authenticator_->state() == Authenticator::MESSAGE_READY) { + JingleMessage message(peer_jid_, JingleMessage::SESSION_INFO, session_id_); + message.info = authenticator_->GetNextMessage(); + DCHECK(message.info.get()); + + session_info_request_ = session_manager_->iq_sender()->SendIq( + message.ToXml(), base::Bind( + &JingleSession::OnSessionInfoResponse, + base::Unretained(this))); + } + DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); + + if (authenticator_->state() == Authenticator::ACCEPTED) { + SetState(AUTHENTICATED); + } else if (authenticator_->state() == Authenticator::REJECTED) { + CloseInternal(AuthRejectionReasonToError( + authenticator_->rejection_reason())); + } +} + +void JingleSession::OnSessionInfoResponse(const buzz::XmlElement* response) { + const std::string& type = response->Attr(buzz::QName("", "type")); + if (type != "result") { + LOG(ERROR) << "Received error in response to session-info message: \"" + << response->Str() + << "\". Terminating the session."; + CloseInternal(INCOMPATIBLE_PROTOCOL); + } +} + +void JingleSession::OnTransportInfoResponse(const buzz::XmlElement* response) { + const std::string& type = response->Attr(buzz::QName("", "type")); + if (type != "result") { + LOG(ERROR) << "Received error in response to session-initiate message: \"" + << response->Str() + << "\". Terminating the session."; + + if (state_ == CONNECTING) { + CloseInternal(PEER_IS_OFFLINE); + } else { + // Host has disconnected without sending session-terminate message. + CloseInternal(OK); + } + } +} + +void JingleSession::SendTransportInfo() { + JingleMessage message(peer_jid_, JingleMessage::TRANSPORT_INFO, session_id_); + message.candidates.swap(pending_candidates_); + transport_info_request_ = session_manager_->iq_sender()->SendIq( + message.ToXml(), base::Bind( + &JingleSession::OnTransportInfoResponse, + base::Unretained(this))); +} + + +void JingleSession::CloseInternal(Error error) { + DCHECK(CalledOnValidThread()); + + if (state_ == CONNECTING || state_ == CONNECTED || state_ == AUTHENTICATED) { + // Send session-terminate message with the appropriate error code. + JingleMessage::Reason reason; + switch (error) { + case OK: + reason = JingleMessage::SUCCESS; + break; + case SESSION_REJECTED: + case AUTHENTICATION_FAILED: + reason = JingleMessage::DECLINE; + break; + case INCOMPATIBLE_PROTOCOL: + reason = JingleMessage::INCOMPATIBLE_PARAMETERS; + break; + default: + reason = JingleMessage::GENERAL_ERROR; + } + + JingleMessage message(peer_jid_, JingleMessage::SESSION_TERMINATE, + session_id_); + message.reason = reason; + session_manager_->iq_sender()->SendIq( + message.ToXml(), IqSender::ReplyCallback()); + } + + error_ = error; + + if (state_ != FAILED && state_ != CLOSED) { + if (error != OK) { + SetState(FAILED); + } else { + SetState(CLOSED); + } + } +} + +void JingleSession::SetState(State new_state) { + DCHECK(CalledOnValidThread()); + + if (new_state != state_) { + DCHECK_NE(state_, CLOSED); + DCHECK_NE(state_, FAILED); + + state_ = new_state; + if (!state_change_callback_.is_null()) + state_change_callback_.Run(new_state); + } +} + +} // namespace protocol +} // namespace remoting diff --git a/remoting/protocol/jingle_session.h b/remoting/protocol/jingle_session.h new file mode 100644 index 0000000..f092402 --- /dev/null +++ b/remoting/protocol/jingle_session.h @@ -0,0 +1,154 @@ +// 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_PROTOCOL_PEPPER_SESSION_H_ +#define REMOTING_PROTOCOL_PEPPER_SESSION_H_ + +#include +#include +#include + +#include "base/memory/ref_counted.h" +#include "base/timer.h" +#include "crypto/rsa_private_key.h" +#include "net/base/completion_callback.h" +#include "remoting/protocol/authenticator.h" +#include "remoting/protocol/jingle_messages.h" +#include "remoting/protocol/session.h" +#include "remoting/protocol/session_config.h" +#include "remoting/protocol/transport.h" + +namespace net { +class Socket; +class StreamSocket; +} // namespace net + +namespace remoting { + +class IqRequest; + +namespace protocol { + +class JingleSessionManager; + +// JingleSessionManager and JingleSession implement the subset of the +// Jingle protocol used in Chromoting. Instances of this class are +// created by the JingleSessionManager. +class JingleSession : public Session, + public Transport::EventHandler { + public: + virtual ~JingleSession(); + + // Session interface. + virtual void SetStateChangeCallback( + const StateChangeCallback& callback) OVERRIDE; + virtual void SetRouteChangeCallback( + const RouteChangeCallback& callback) OVERRIDE; + virtual Error error() OVERRIDE; + virtual void CreateStreamChannel( + const std::string& name, + const StreamChannelCallback& callback) OVERRIDE; + virtual void CreateDatagramChannel( + const std::string& name, + const DatagramChannelCallback& callback) OVERRIDE; + virtual void CancelChannelCreation(const std::string& name) OVERRIDE; + virtual const std::string& jid() OVERRIDE; + virtual const CandidateSessionConfig* candidate_config() OVERRIDE; + virtual const SessionConfig& config() OVERRIDE; + virtual void set_config(const SessionConfig& config) OVERRIDE; + virtual void Close() OVERRIDE; + + // Transport::EventHandler interface. + virtual void OnTransportCandidate( + Transport* transport, + const cricket::Candidate& candidate) OVERRIDE; + virtual void OnTransportRouteChange(Transport* transport, + const TransportRoute& route) OVERRIDE; + virtual void OnTransportDeleted(Transport* transport) OVERRIDE; + + private: + friend class JingleSessionManager; + + typedef std::map ChannelsMap; + typedef base::Callback ReplyCallback; + + explicit JingleSession(JingleSessionManager* session_manager); + + // Start connection by sending session-initiate message. + void StartConnection(const std::string& peer_jid, + scoped_ptr authenticator, + scoped_ptr config, + const StateChangeCallback& state_change_callback); + + // Called by JingleSessionManager for incoming connections. + void InitializeIncomingConnection(const JingleMessage& initiate_message, + scoped_ptr authenticator); + void AcceptIncomingConnection(const JingleMessage& initiate_message); + + // Handler for session-initiate response. + void OnSessionInitiateResponse(const buzz::XmlElement* response); + + // Called by JingleSessionManager on incoming |message|. Must call + // |reply_callback| to send reply message before sending any other + // messages. + void OnIncomingMessage(const JingleMessage& message, + const ReplyCallback& reply_callback); + + // Message handlers for incoming messages. + void OnAccept(const JingleMessage& message, + const ReplyCallback& reply_callback); + void OnSessionInfo(const JingleMessage& message, + const ReplyCallback& reply_callback); + void OnTerminate(const JingleMessage& message, + const ReplyCallback& reply_callback); + void ProcessTransportInfo(const JingleMessage& message); + + // Called from OnAccept() to initialize session config. + bool InitializeConfigFromDescription(const ContentDescription* description); + + void ProcessAuthenticationStep(); + void OnSessionInfoResponse(const buzz::XmlElement* response); + + void SendTransportInfo(); + void OnTransportInfoResponse(const buzz::XmlElement* response); + + // Terminates the session and sends session-terminate if it is + // necessary. |error| specifies the error code in case when the + // session is being closed due to an error. + void CloseInternal(Error error); + + // Sets |state_| to |new_state| and calls state change callback. + void SetState(State new_state); + + JingleSessionManager* session_manager_; + std::string peer_jid_; + scoped_ptr candidate_config_; + StateChangeCallback state_change_callback_; + RouteChangeCallback route_change_callback_; + + std::string session_id_; + State state_; + Error error_; + + SessionConfig config_; + bool config_is_set_; + + scoped_ptr authenticator_; + + scoped_ptr initiate_request_; + scoped_ptr session_info_request_; + scoped_ptr transport_info_request_; + + ChannelsMap channels_; + + base::OneShotTimer transport_infos_timer_; + std::list pending_candidates_; + + DISALLOW_COPY_AND_ASSIGN(JingleSession); +}; + +} // namespace protocol +} // namespace remoting + +#endif // REMOTING_PROTOCOL_PEPPER_SESSION_H_ diff --git a/remoting/protocol/jingle_session_manager.cc b/remoting/protocol/jingle_session_manager.cc new file mode 100644 index 0000000..1735954 --- /dev/null +++ b/remoting/protocol/jingle_session_manager.cc @@ -0,0 +1,183 @@ +// 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/protocol/jingle_session_manager.h" + +#include "base/bind.h" +#include "remoting/jingle_glue/iq_sender.h" +#include "remoting/jingle_glue/jingle_info_request.h" +#include "remoting/jingle_glue/signal_strategy.h" +#include "remoting/protocol/authenticator.h" +#include "remoting/protocol/content_description.h" +#include "remoting/protocol/jingle_messages.h" +#include "remoting/protocol/jingle_session.h" +#include "third_party/libjingle/source/talk/base/socketaddress.h" +#include "third_party/libjingle/source/talk/xmllite/xmlelement.h" + +using buzz::QName; + +namespace remoting { +namespace protocol { + +JingleSessionManager::JingleSessionManager( + scoped_ptr transport_factory) + : transport_factory_(transport_factory.Pass()), + signal_strategy_(NULL), + listener_(NULL), + ready_(false) { +} + +JingleSessionManager::~JingleSessionManager() { + Close(); +} + +void JingleSessionManager::Init( + SignalStrategy* signal_strategy, + SessionManager::Listener* listener, + const NetworkSettings& network_settings) { + listener_ = listener; + signal_strategy_ = signal_strategy; + iq_sender_.reset(new IqSender(signal_strategy_)); + + transport_config_.nat_traversal = network_settings.allow_nat_traversal; + transport_config_.min_port = network_settings.min_port; + transport_config_.max_port = network_settings.max_port; + + signal_strategy_->AddListener(this); + + OnSignalStrategyStateChange(signal_strategy_->GetState()); +} + +void JingleSessionManager::OnJingleInfo( + const std::string& relay_token, + const std::vector& relay_hosts, + const std::vector& stun_hosts) { + DCHECK(CalledOnValidThread()); + + // TODO(sergeyu): Add support for multiple STUN/relay servers when + // it's implemented in libjingle and P2P Transport API. + transport_config_.stun_server = stun_hosts[0].ToString(); + transport_config_.relay_server = relay_hosts[0]; + transport_config_.relay_token = relay_token; + VLOG(1) << "STUN server: " << transport_config_.stun_server + << " Relay server: " << transport_config_.relay_server + << " Relay token: " << transport_config_.relay_token; + + if (!ready_) { + ready_ = true; + listener_->OnSessionManagerReady(); + } +} + +scoped_ptr JingleSessionManager::Connect( + const std::string& host_jid, + scoped_ptr authenticator, + scoped_ptr config, + const Session::StateChangeCallback& state_change_callback) { + scoped_ptr session(new JingleSession(this)); + session->StartConnection(host_jid, authenticator.Pass(), config.Pass(), + state_change_callback); + sessions_[session->session_id_] = session.get(); + return session.PassAs(); +} + +void JingleSessionManager::Close() { + DCHECK(CalledOnValidThread()); + + // Close() can be called only after all sessions are destroyed. + DCHECK(sessions_.empty()); + + listener_ = NULL; + jingle_info_request_.reset(); + + if (signal_strategy_) { + signal_strategy_->RemoveListener(this); + signal_strategy_ = NULL; + } +} + +void JingleSessionManager::set_authenticator_factory( + scoped_ptr authenticator_factory) { + DCHECK(CalledOnValidThread()); + authenticator_factory_ = authenticator_factory.Pass(); +} + +void JingleSessionManager::OnSignalStrategyStateChange( + SignalStrategy::State state) { + // If NAT traversal is enabled then we need to request STUN/Relay info. + if (state == SignalStrategy::CONNECTED) { + if (transport_config_.nat_traversal) { + jingle_info_request_.reset(new JingleInfoRequest(signal_strategy_)); + jingle_info_request_->Send(base::Bind(&JingleSessionManager::OnJingleInfo, + base::Unretained(this))); + } else if (!ready_) { + ready_ = true; + listener_->OnSessionManagerReady(); + } + } +} + +bool JingleSessionManager::OnSignalStrategyIncomingStanza( + const buzz::XmlElement* stanza) { + if (!JingleMessage::IsJingleMessage(stanza)) + return false; + + JingleMessage message; + std::string error; + if (!message.ParseXml(stanza, &error)) { + SendReply(stanza, JingleMessageReply::BAD_REQUEST); + return true; + } + + if (message.action == JingleMessage::SESSION_INITIATE) { + // Description must be present in session-initiate messages. + DCHECK(message.description.get()); + + SendReply(stanza, JingleMessageReply::NONE); + + scoped_ptr authenticator = + authenticator_factory_->CreateAuthenticator( + message.from, message.description->authenticator_message()); + + JingleSession* session = new JingleSession(this); + session->InitializeIncomingConnection(message, authenticator.Pass()); + sessions_[session->session_id_] = session; + + IncomingSessionResponse response = SessionManager::DECLINE; + listener_->OnIncomingSession(session, &response); + + if (response == SessionManager::ACCEPT) { + session->AcceptIncomingConnection(message); + } else { + session->Close(); + delete session; + DCHECK(sessions_.find(message.sid) == sessions_.end()); + } + + return true; + } + + SessionsMap::iterator it = sessions_.find(message.sid); + if (it == sessions_.end()) { + SendReply(stanza, JingleMessageReply::INVALID_SID); + return true; + } + + it->second->OnIncomingMessage(message, base::Bind( + &JingleSessionManager::SendReply, base::Unretained(this), stanza)); + return true; +} + +void JingleSessionManager::SendReply(const buzz::XmlElement* original_stanza, + JingleMessageReply::ErrorType error) { + signal_strategy_->SendStanza( + JingleMessageReply(error).ToXml(original_stanza)); +} + +void JingleSessionManager::SessionDestroyed(JingleSession* session) { + sessions_.erase(session->session_id_); +} + +} // namespace protocol +} // namespace remoting diff --git a/remoting/protocol/jingle_session_manager.h b/remoting/protocol/jingle_session_manager.h new file mode 100644 index 0000000..1c4ab51 --- /dev/null +++ b/remoting/protocol/jingle_session_manager.h @@ -0,0 +1,109 @@ +// 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_PROTOCOL_PEPPER_SESSION_MANAGER_H_ +#define REMOTING_PROTOCOL_PEPPER_SESSION_MANAGER_H_ + +#include +#include +#include + +#include "base/memory/ref_counted.h" +#include "net/base/x509_certificate.h" +#include "remoting/jingle_glue/signal_strategy.h" +#include "remoting/protocol/jingle_messages.h" +#include "remoting/protocol/session_manager.h" +#include "remoting/protocol/transport.h" +#include "remoting/protocol/transport_config.h" + +namespace pp { +class Instance; +} // namespace pp + +namespace buzz { +class XmlElement; +} // namespace buzz + +namespace talk_base { +class SocketAddress; +} // namespace talk_base + +namespace remoting { + +class IqSender; +class JingleInfoRequest; + +namespace protocol { + +class JingleSession; + +// JingleSessionManager and JingleSession implement the subset of the +// Jingle protocol used in Chromoting. JingleSessionManager provides +// the protocol::SessionManager interface for accepting incoming and +// creating outgoing sessions. +class JingleSessionManager : public SessionManager, + public SignalStrategy::Listener { + public: + explicit JingleSessionManager( + scoped_ptr transport_factory); + virtual ~JingleSessionManager(); + + // SessionManager interface. + virtual void Init(SignalStrategy* signal_strategy, + SessionManager::Listener* listener, + const NetworkSettings& network_settings) OVERRIDE; + virtual scoped_ptr Connect( + const std::string& host_jid, + scoped_ptr authenticator, + scoped_ptr config, + const Session::StateChangeCallback& state_change_callback) OVERRIDE; + virtual void Close() OVERRIDE; + virtual void set_authenticator_factory( + scoped_ptr authenticator_factory) OVERRIDE; + + // SignalStrategy::Listener interface. + virtual void OnSignalStrategyStateChange( + SignalStrategy::State state) OVERRIDE; + virtual bool OnSignalStrategyIncomingStanza( + const buzz::XmlElement* stanza) OVERRIDE; + + private: + friend class JingleSession; + + typedef std::map SessionsMap; + + void OnJingleInfo( + const std::string& relay_token, + const std::vector& relay_hosts, + const std::vector& stun_hosts); + + IqSender* iq_sender() { return iq_sender_.get(); } + void SendReply(const buzz::XmlElement* original_stanza, + JingleMessageReply::ErrorType error); + + // Called by JingleSession when it is being destroyed. + void SessionDestroyed(JingleSession* session); + + scoped_ptr transport_factory_; + + SignalStrategy* signal_strategy_; + scoped_ptr authenticator_factory_; + scoped_ptr iq_sender_; + SessionManager::Listener* listener_; + + bool ready_; + + TransportConfig transport_config_; + + scoped_ptr jingle_info_request_; + + SessionsMap sessions_; + + DISALLOW_COPY_AND_ASSIGN(JingleSessionManager); +}; + +} // namespace protocol +} // namespace remoting + +#endif // REMOTING_PROTOCOL_PEPPER_SESSION_MANAGER_H_ diff --git a/remoting/protocol/jingle_session_unittest.cc b/remoting/protocol/jingle_session_unittest.cc new file mode 100644 index 0000000..b5984aa --- /dev/null +++ b/remoting/protocol/jingle_session_unittest.cc @@ -0,0 +1,375 @@ +// 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/protocol/jingle_session.h" + +#include "base/bind.h" +#include "base/message_loop.h" +#include "base/time.h" +#include "base/test/test_timeouts.h" +#include "net/socket/socket.h" +#include "net/socket/stream_socket.h" +#include "remoting/base/constants.h" +#include "remoting/protocol/authenticator.h" +#include "remoting/protocol/channel_authenticator.h" +#include "remoting/protocol/connection_tester.h" +#include "remoting/protocol/fake_authenticator.h" +#include "remoting/protocol/jingle_session_manager.h" +#include "remoting/protocol/libjingle_transport_factory.h" +#include "remoting/jingle_glue/jingle_thread.h" +#include "remoting/jingle_glue/fake_signal_strategy.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; +using testing::AtMost; +using testing::DeleteArg; +using testing::DoAll; +using testing::InSequence; +using testing::Invoke; +using testing::InvokeWithoutArgs; +using testing::Return; +using testing::SaveArg; +using testing::SetArgumentPointee; +using testing::WithArg; + +namespace remoting { +namespace protocol { + +namespace { + +const char kHostJid[] = "host1@gmail.com/123"; +const char kClientJid[] = "host2@gmail.com/321"; + +// Send 100 messages 1024 bytes each. UDP messages are sent with 10ms delay +// between messages (about 1 second for 100 messages). +const int kMessageSize = 1024; +const int kMessages = 100; +const char kChannelName[] = "test_channel"; + +void QuitCurrentThread() { + MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); +} + +ACTION_P(QuitThreadOnCounter, counter) { + --(*counter); + EXPECT_GE(*counter, 0); + if (*counter == 0) + QuitCurrentThread(); +} + +class MockSessionManagerListener : public SessionManager::Listener { + public: + MOCK_METHOD0(OnSessionManagerReady, void()); + MOCK_METHOD2(OnIncomingSession, + void(Session*, + SessionManager::IncomingSessionResponse*)); +}; + +class MockSessionCallback { + public: + MOCK_METHOD1(OnStateChange, void(Session::State)); +}; + +class MockStreamChannelCallback { + public: + MOCK_METHOD1(OnDone, void(net::StreamSocket* socket)); +}; + +} // namespace + +class JingleSessionTest : public testing::Test { + public: + JingleSessionTest() + : message_loop_(talk_base::Thread::Current()) { + } + + // Helper method that handles OnIncomingSession(). + void SetHostSession(Session* session) { + DCHECK(session); + host_session_.reset(session); + host_session_->SetStateChangeCallback( + base::Bind(&MockSessionCallback::OnStateChange, + base::Unretained(&host_connection_callback_))); + + session->set_config(SessionConfig::GetDefault()); + } + + void OnClientChannelCreated(scoped_ptr socket) { + client_channel_callback_.OnDone(socket.get()); + client_socket_ = socket.Pass(); + } + + void OnHostChannelCreated(scoped_ptr socket) { + host_channel_callback_.OnDone(socket.get()); + host_socket_ = socket.Pass(); + } + + protected: + virtual void SetUp() { + } + + virtual void TearDown() { + CloseSessions(); + CloseSessionManager(); + message_loop_.RunAllPending(); + } + + void CloseSessions() { + host_socket_.reset(); + host_session_.reset(); + client_socket_.reset(); + client_session_.reset(); + } + + void CreateSessionManagers(int auth_round_trips, + FakeAuthenticator::Action auth_action) { + host_signal_strategy_.reset(new FakeSignalStrategy(kHostJid)); + client_signal_strategy_.reset(new FakeSignalStrategy(kClientJid)); + FakeSignalStrategy::Connect(host_signal_strategy_.get(), + client_signal_strategy_.get()); + + EXPECT_CALL(host_server_listener_, OnSessionManagerReady()) + .Times(1); + host_server_.reset(new JingleSessionManager( + scoped_ptr(new LibjingleTransportFactory()))); + host_server_->Init(host_signal_strategy_.get(), &host_server_listener_, + NetworkSettings(false)); + + scoped_ptr factory( + new FakeHostAuthenticatorFactory(auth_round_trips, auth_action, true)); + host_server_->set_authenticator_factory(factory.Pass()); + + EXPECT_CALL(client_server_listener_, OnSessionManagerReady()) + .Times(1); + client_server_.reset(new JingleSessionManager( + scoped_ptr(new LibjingleTransportFactory()))); + client_server_->Init(client_signal_strategy_.get(), + &client_server_listener_, NetworkSettings()); + } + + void CloseSessionManager() { + if (host_server_.get()) { + host_server_->Close(); + host_server_.reset(); + } + if (client_server_.get()) { + client_server_->Close(); + client_server_.reset(); + } + host_signal_strategy_.reset(); + client_signal_strategy_.reset(); + } + + void InitiateConnection(int auth_round_trips, + FakeAuthenticator::Action auth_action, + bool expect_fail) { + EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _)) + .WillOnce(DoAll( + WithArg<0>(Invoke(this, &JingleSessionTest::SetHostSession)), + SetArgumentPointee<1>(protocol::SessionManager::ACCEPT))); + + { + InSequence dummy; + + EXPECT_CALL(host_connection_callback_, + OnStateChange(Session::CONNECTED)) + .Times(AtMost(1)); + if (expect_fail) { + EXPECT_CALL(host_connection_callback_, + OnStateChange(Session::FAILED)) + .Times(1); + } else { + EXPECT_CALL(host_connection_callback_, + OnStateChange(Session::AUTHENTICATED)) + .Times(1); + // Expect that the connection will be closed eventually. + EXPECT_CALL(host_connection_callback_, + OnStateChange(Session::CLOSED)) + .Times(AtMost(1)); + } + } + + { + InSequence dummy; + + EXPECT_CALL(client_connection_callback_, + OnStateChange(Session::CONNECTING)) + .Times(1); + EXPECT_CALL(client_connection_callback_, + OnStateChange(Session::CONNECTED)) + .Times(AtMost(1)); + if (expect_fail) { + EXPECT_CALL(client_connection_callback_, + OnStateChange(Session::FAILED)) + .Times(1); + } else { + EXPECT_CALL(client_connection_callback_, + OnStateChange(Session::AUTHENTICATED)) + .Times(1); + // Expect that the connection will be closed eventually. + EXPECT_CALL(client_connection_callback_, + OnStateChange(Session::CLOSED)) + .Times(AtMost(1)); + } + } + + scoped_ptr authenticator(new FakeAuthenticator( + FakeAuthenticator::CLIENT, auth_round_trips, auth_action, true)); + + client_session_ = client_server_->Connect( + kHostJid, authenticator.Pass(), + CandidateSessionConfig::CreateDefault(), + base::Bind(&MockSessionCallback::OnStateChange, + base::Unretained(&client_connection_callback_))); + + message_loop_.RunAllPending(); + } + + void CreateChannel(bool expect_fail) { + client_session_->CreateStreamChannel(kChannelName, base::Bind( + &JingleSessionTest::OnClientChannelCreated, base::Unretained(this))); + host_session_->CreateStreamChannel(kChannelName, base::Bind( + &JingleSessionTest::OnHostChannelCreated, base::Unretained(this))); + + int counter = 2; + EXPECT_CALL(client_channel_callback_, OnDone(_)) + .WillOnce(QuitThreadOnCounter(&counter)); + EXPECT_CALL(host_channel_callback_, OnDone(_)) + .WillOnce(QuitThreadOnCounter(&counter)); + message_loop_.Run(); + + if (expect_fail) { + // At least one socket should fail to connect. + EXPECT_TRUE((!client_socket_.get()) || (!host_socket_.get())); + } else { + EXPECT_TRUE(client_socket_.get()); + EXPECT_TRUE(host_socket_.get()); + } + } + + JingleThreadMessageLoop message_loop_; + + scoped_ptr host_signal_strategy_; + scoped_ptr client_signal_strategy_; + + scoped_ptr host_server_; + MockSessionManagerListener host_server_listener_; + scoped_ptr client_server_; + MockSessionManagerListener client_server_listener_; + + scoped_ptr host_session_; + MockSessionCallback host_connection_callback_; + scoped_ptr client_session_; + MockSessionCallback client_connection_callback_; + + MockStreamChannelCallback client_channel_callback_; + MockStreamChannelCallback host_channel_callback_; + + scoped_ptr client_socket_; + scoped_ptr host_socket_; +}; + + +// Verify that we can create and destroy session managers without a +// connection. +TEST_F(JingleSessionTest, CreateAndDestoy) { + CreateSessionManagers(1, FakeAuthenticator::ACCEPT); +} + +// Verify that an incoming session can be rejected, and that the +// status of the connection is set to FAILED in this case. +TEST_F(JingleSessionTest, RejectConnection) { + CreateSessionManagers(1, FakeAuthenticator::ACCEPT); + + // Reject incoming session. + EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _)) + .WillOnce(SetArgumentPointee<1>(protocol::SessionManager::DECLINE)); + + { + InSequence dummy; + + EXPECT_CALL(client_connection_callback_, + OnStateChange(Session::CONNECTING)) + .Times(1); + EXPECT_CALL(client_connection_callback_, + OnStateChange(Session::FAILED)) + .Times(1); + } + + scoped_ptr authenticator(new FakeAuthenticator( + FakeAuthenticator::CLIENT, 1, FakeAuthenticator::ACCEPT, true)); + client_session_ = client_server_->Connect( + kHostJid, authenticator.Pass(), CandidateSessionConfig::CreateDefault(), + base::Bind(&MockSessionCallback::OnStateChange, + base::Unretained(&client_connection_callback_))); + + message_loop_.RunAllPending(); +} + +// Verify that we can connect two endpoints with single-step authentication. +TEST_F(JingleSessionTest, Connect) { + CreateSessionManagers(1, FakeAuthenticator::ACCEPT); + InitiateConnection(1, FakeAuthenticator::ACCEPT, false); +} + +// Verify that we can connect two endpoints with multi-step authentication. +TEST_F(JingleSessionTest, ConnectWithMultistep) { + CreateSessionManagers(3, FakeAuthenticator::ACCEPT); + InitiateConnection(3, FakeAuthenticator::ACCEPT, false); +} + +// Verify that connection is terminated when single-step auth fails. +TEST_F(JingleSessionTest, ConnectWithBadAuth) { + CreateSessionManagers(1, FakeAuthenticator::REJECT); + InitiateConnection(1, FakeAuthenticator::ACCEPT, true); +} + +// Verify that connection is terminated when multi-step auth fails. +TEST_F(JingleSessionTest, ConnectWithBadMultistepAuth) { + CreateSessionManagers(3, FakeAuthenticator::REJECT); + InitiateConnection(3, FakeAuthenticator::ACCEPT, true); +} + +// Verify that data can be sent over stream channel. +TEST_F(JingleSessionTest, TestStreamChannel) { + CreateSessionManagers(1, FakeAuthenticator::ACCEPT); + ASSERT_NO_FATAL_FAILURE( + InitiateConnection(1, FakeAuthenticator::ACCEPT, false)); + + ASSERT_NO_FATAL_FAILURE(CreateChannel(false)); + + StreamConnectionTester tester(host_socket_.get(), client_socket_.get(), + kMessageSize, kMessages); + tester.Start(); + message_loop_.Run(); + tester.CheckResults(); +} + +// Verify that we can connect channels with multistep auth. +TEST_F(JingleSessionTest, TestMultistepAuthStreamChannel) { + CreateSessionManagers(3, FakeAuthenticator::ACCEPT); + ASSERT_NO_FATAL_FAILURE( + InitiateConnection(3, FakeAuthenticator::ACCEPT, false)); + + ASSERT_NO_FATAL_FAILURE(CreateChannel(false)); + + StreamConnectionTester tester(host_socket_.get(), client_socket_.get(), + kMessageSize, kMessages); + tester.Start(); + message_loop_.Run(); + tester.CheckResults(); +} + +// Verify that we shutdown properly when channel authentication fails. +TEST_F(JingleSessionTest, TestFailedChannelAuth) { + CreateSessionManagers(1, FakeAuthenticator::ACCEPT); + ASSERT_NO_FATAL_FAILURE( + InitiateConnection(1, FakeAuthenticator::REJECT_CHANNEL, false)); + + ASSERT_NO_FATAL_FAILURE(CreateChannel(true)); +} + +} // namespace protocol +} // namespace remoting diff --git a/remoting/protocol/pepper_channel.h b/remoting/protocol/pepper_channel.h deleted file mode 100644 index c908d70..0000000 --- a/remoting/protocol/pepper_channel.h +++ /dev/null @@ -1,56 +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_PROTOCOL_PEPPER_CHANNEL_H_ -#define REMOTING_PROTOCOL_PEPPER_CHANNEL_H_ - -#include - -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "base/threading/non_thread_safe.h" - -namespace pp { -class Instance; -} // namespace pp - -namespace cricket { -class Candidate; -} // namespace cricket - -namespace remoting { -namespace protocol { - -class ChannelAuthenticator; -struct TransportConfig; - -// Interface for stream and datagram channels used by PepperSession. -class PepperChannel : public base::NonThreadSafe { - public: - PepperChannel() { } - virtual ~PepperChannel() { } - - // Connect the channel using specified |config|. The specified - // |authenticator| is used to authenticate the channel. - virtual void Connect(pp::Instance* pp_instance, - const TransportConfig& config, - scoped_ptr authenticator) = 0; - - // Adds |candidate| received from the peer. - virtual void AddRemoteCandidate(const cricket::Candidate& candidate) = 0; - - // Name of the channel. - virtual const std::string& name() const = 0; - - // Returns true if the channel is already connected. - virtual bool is_connected() const = 0; - - protected: - DISALLOW_COPY_AND_ASSIGN(PepperChannel); -}; - -} // namespace protocol -} // namespace remoting - -#endif // REMOTING_PROTOCOL_PEPPER_CHANNEL_H_ diff --git a/remoting/protocol/pepper_session.cc b/remoting/protocol/pepper_session.cc deleted file mode 100644 index 0fc8d06..0000000 --- a/remoting/protocol/pepper_session.cc +++ /dev/null @@ -1,559 +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/protocol/pepper_session.h" - -#include "base/bind.h" -#include "base/rand_util.h" -#include "base/stl_util.h" -#include "base/string_number_conversions.h" -#include "remoting/base/constants.h" -#include "remoting/jingle_glue/iq_sender.h" -#include "remoting/protocol/authenticator.h" -#include "remoting/protocol/channel_authenticator.h" -#include "remoting/protocol/content_description.h" -#include "remoting/protocol/jingle_messages.h" -#include "remoting/protocol/pepper_session_manager.h" -#include "remoting/protocol/session_config.h" -#include "third_party/libjingle/source/talk/p2p/base/candidate.h" -#include "third_party/libjingle/source/talk/xmllite/xmlelement.h" - -using buzz::XmlElement; - -namespace remoting { -namespace protocol { - -namespace { -// Delay after candidate creation before sending transport-info -// message. This is neccessary to be able to pack multiple candidates -// into one transport-info messages. The value needs to be greater -// than zero because ports are opened asynchronously in the browser -// process. -const int kTransportInfoSendDelayMs = 2; - -Session::Error AuthRejectionReasonToError( - Authenticator::RejectionReason reason) { - switch (reason) { - case Authenticator::INVALID_CREDENTIALS: - return Session::AUTHENTICATION_FAILED; - case Authenticator::PROTOCOL_ERROR: - return Session::INCOMPATIBLE_PROTOCOL; - } - NOTREACHED(); - return Session::UNKNOWN_ERROR; -} - -} // namespace - -PepperSession::PepperSession(PepperSessionManager* session_manager) - : session_manager_(session_manager), - state_(INITIALIZING), - error_(OK), - config_is_set_(false) { -} - -PepperSession::~PepperSession() { - STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); - session_manager_->SessionDestroyed(this); -} - -void PepperSession::SetStateChangeCallback( - const StateChangeCallback& callback) { - DCHECK(CalledOnValidThread()); - DCHECK(!callback.is_null()); - state_change_callback_ = callback; -} - -void PepperSession::SetRouteChangeCallback( - const RouteChangeCallback& callback) { - DCHECK(CalledOnValidThread()); - route_change_callback_ = callback; -} - -Session::Error PepperSession::error() { - DCHECK(CalledOnValidThread()); - return error_; -} - -void PepperSession::StartConnection( - const std::string& peer_jid, - scoped_ptr authenticator, - scoped_ptr config, - const StateChangeCallback& state_change_callback) { - DCHECK(CalledOnValidThread()); - DCHECK(authenticator.get()); - DCHECK_EQ(authenticator->state(), Authenticator::MESSAGE_READY); - - peer_jid_ = peer_jid; - authenticator_ = authenticator.Pass(); - candidate_config_ = config.Pass(); - state_change_callback_ = state_change_callback; - - // Generate random session ID. There are usually not more than 1 - // concurrent session per host, so a random 64-bit integer provides - // enough entropy. In the worst case connection will fail when two - // clients generate the same session ID concurrently. - session_id_ = base::Int64ToString(base::RandGenerator(kint64max)); - - // Send session-initiate message. - JingleMessage message(peer_jid_, JingleMessage::SESSION_INITIATE, - session_id_); - message.description.reset( - new ContentDescription(candidate_config_->Clone(), - authenticator_->GetNextMessage())); - initiate_request_ = session_manager_->iq_sender()->SendIq( - message.ToXml(), - base::Bind(&PepperSession::OnSessionInitiateResponse, - base::Unretained(this))); - - SetState(CONNECTING); -} - -void PepperSession::InitializeIncomingConnection( - const JingleMessage& initiate_message, - scoped_ptr authenticator) { - DCHECK(CalledOnValidThread()); - DCHECK(initiate_message.description.get()); - DCHECK(authenticator.get()); - DCHECK_EQ(authenticator->state(), Authenticator::WAITING_MESSAGE); - - peer_jid_ = initiate_message.from; - authenticator_ = authenticator.Pass(); - session_id_ = initiate_message.sid; - candidate_config_ = initiate_message.description->config()->Clone(); - - SetState(CONNECTING); -} - -void PepperSession::AcceptIncomingConnection( - const JingleMessage& initiate_message) { - DCHECK(config_is_set_); - - // Process the first authentication message. - const buzz::XmlElement* first_auth_message = - initiate_message.description->authenticator_message(); - - if (!first_auth_message) { - CloseInternal(INCOMPATIBLE_PROTOCOL); - return; - } - - DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); - authenticator_->ProcessMessage(first_auth_message); - if (authenticator_->state() == Authenticator::REJECTED) { - CloseInternal(AuthRejectionReasonToError( - authenticator_->rejection_reason())); - return; - } - - // Send the session-accept message. - JingleMessage message(peer_jid_, JingleMessage::SESSION_ACCEPT, - session_id_); - - scoped_ptr auth_message; - if (authenticator_->state() == Authenticator::MESSAGE_READY) - auth_message = authenticator_->GetNextMessage(); - - message.description.reset( - new ContentDescription(CandidateSessionConfig::CreateFrom(config_), - auth_message.Pass())); - initiate_request_ = session_manager_->iq_sender()->SendIq( - message.ToXml(), - base::Bind(&PepperSession::OnSessionInitiateResponse, - base::Unretained(this))); - - // Update state. - SetState(CONNECTED); - - if (authenticator_->state() == Authenticator::ACCEPTED) { - SetState(AUTHENTICATED); - } else { - DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); - } - - return; -} - -void PepperSession::OnSessionInitiateResponse( - const buzz::XmlElement* response) { - const std::string& type = response->Attr(buzz::QName("", "type")); - if (type != "result") { - LOG(ERROR) << "Received error in response to session-initiate message: \"" - << response->Str() - << "\". Terminating the session."; - - // TODO(sergeyu): There may be different reasons for error - // here. Parse the response stanza to find failure reason. - CloseInternal(PEER_IS_OFFLINE); - } -} - -void PepperSession::CreateStreamChannel( - const std::string& name, - const StreamChannelCallback& callback) { - DCHECK(!channels_[name]); - - scoped_ptr channel_authenticator = - authenticator_->CreateChannelAuthenticator(); - scoped_ptr channel = - session_manager_->transport_factory_->CreateStreamTransport(); - channel->Initialize(name, session_manager_->transport_config_, - this, channel_authenticator.Pass()); - channel->Connect(callback); - channels_[name] = channel.release(); -} - -void PepperSession::CreateDatagramChannel( - const std::string& name, - const DatagramChannelCallback& callback) { - DCHECK(!channels_[name]); - - scoped_ptr channel_authenticator = - authenticator_->CreateChannelAuthenticator(); - scoped_ptr channel = - session_manager_->transport_factory_->CreateDatagramTransport(); - channel->Initialize(name, session_manager_->transport_config_, - this, channel_authenticator.Pass()); - channel->Connect(callback); - channels_[name] = channel.release(); -} - -void PepperSession::CancelChannelCreation(const std::string& name) { - ChannelsMap::iterator it = channels_.find(name); - if (it != channels_.end() && !it->second->is_connected()) { - delete it->second; - DCHECK(!channels_[name]); - } -} - -const std::string& PepperSession::jid() { - DCHECK(CalledOnValidThread()); - return peer_jid_; -} - -const CandidateSessionConfig* PepperSession::candidate_config() { - DCHECK(CalledOnValidThread()); - return candidate_config_.get(); -} - -const SessionConfig& PepperSession::config() { - DCHECK(CalledOnValidThread()); - return config_; -} - -void PepperSession::set_config(const SessionConfig& config) { - DCHECK(CalledOnValidThread()); - DCHECK(!config_is_set_); - config_ = config; - config_is_set_ = true; -} - -void PepperSession::Close() { - DCHECK(CalledOnValidThread()); - - CloseInternal(OK); -} - -void PepperSession::OnTransportCandidate(Transport* transport, - const cricket::Candidate& candidate) { - pending_candidates_.push_back(candidate); - - if (!transport_infos_timer_.IsRunning()) { - // Delay sending the new candidates in case we get more candidates - // that we can send in one message. - transport_infos_timer_.Start( - FROM_HERE, base::TimeDelta::FromMilliseconds(kTransportInfoSendDelayMs), - this, &PepperSession::SendTransportInfo); - } -} - -void PepperSession::OnTransportRouteChange(Transport* transport, - const TransportRoute& route) { - if (!route_change_callback_.is_null()) { - route_change_callback_.Run(transport->name(), route.remote_address, - route.local_address); - } -} - -void PepperSession::OnTransportDeleted(Transport* transport) { - ChannelsMap::iterator it = channels_.find(transport->name()); - DCHECK_EQ(it->second, transport); - channels_.erase(it); -} - -void PepperSession::OnIncomingMessage(const JingleMessage& message, - const ReplyCallback& reply_callback) { - DCHECK(CalledOnValidThread()); - - if (message.from != peer_jid_) { - // Ignore messages received from a different Jid. - reply_callback.Run(JingleMessageReply::INVALID_SID); - return; - } - - switch (message.action) { - case JingleMessage::SESSION_ACCEPT: - OnAccept(message, reply_callback); - break; - - case JingleMessage::SESSION_INFO: - OnSessionInfo(message, reply_callback); - break; - - case JingleMessage::TRANSPORT_INFO: - reply_callback.Run(JingleMessageReply::NONE); - ProcessTransportInfo(message); - break; - - case JingleMessage::SESSION_TERMINATE: - OnTerminate(message, reply_callback); - break; - - default: - reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); - } -} - -void PepperSession::OnAccept(const JingleMessage& message, - const ReplyCallback& reply_callback) { - if (state_ != CONNECTING) { - reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); - return; - } - - reply_callback.Run(JingleMessageReply::NONE); - - const buzz::XmlElement* auth_message = - message.description->authenticator_message(); - if (!auth_message) { - DLOG(WARNING) << "Received session-accept without authentication message " - << auth_message->Str(); - CloseInternal(INCOMPATIBLE_PROTOCOL); - return; - } - - DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); - authenticator_->ProcessMessage(auth_message); - - if (!InitializeConfigFromDescription(message.description.get())) { - CloseInternal(INCOMPATIBLE_PROTOCOL); - return; - } - - // In case there is transport information in the accept message. - ProcessTransportInfo(message); - - SetState(CONNECTED); - - // Process authentication. - if (authenticator_->state() == Authenticator::ACCEPTED) { - SetState(AUTHENTICATED); - } else { - ProcessAuthenticationStep(); - } -} - -void PepperSession::OnSessionInfo(const JingleMessage& message, - const ReplyCallback& reply_callback) { - if (!message.info.get() || - !Authenticator::IsAuthenticatorMessage(message.info.get())) { - reply_callback.Run(JingleMessageReply::UNSUPPORTED_INFO); - return; - } - - if (state_ != CONNECTED || - authenticator_->state() != Authenticator::WAITING_MESSAGE) { - LOG(WARNING) << "Received unexpected authenticator message " - << message.info->Str(); - reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); - CloseInternal(INCOMPATIBLE_PROTOCOL); - return; - } - - reply_callback.Run(JingleMessageReply::NONE); - - authenticator_->ProcessMessage(message.info.get()); - ProcessAuthenticationStep(); -} - -void PepperSession::ProcessTransportInfo(const JingleMessage& message) { - for (std::list::const_iterator it = - message.candidates.begin(); - it != message.candidates.end(); ++it) { - ChannelsMap::iterator channel = channels_.find(it->name()); - if (channel == channels_.end()) { - LOG(WARNING) << "Received candidate for unknown channel " << it->name(); - continue; - } - channel->second->AddRemoteCandidate(*it); - } -} - -void PepperSession::OnTerminate(const JingleMessage& message, - const ReplyCallback& reply_callback) { - if (state_ != CONNECTING && state_ != CONNECTED && state_ != AUTHENTICATED) { - LOG(WARNING) << "Received unexpected session-terminate message."; - reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); - return; - } - - reply_callback.Run(JingleMessageReply::NONE); - - switch (message.reason) { - case JingleMessage::SUCCESS: - if (state_ == CONNECTING) { - error_ = SESSION_REJECTED; - } else { - error_ = OK; - } - break; - case JingleMessage::DECLINE: - error_ = AUTHENTICATION_FAILED; - break; - case JingleMessage::GENERAL_ERROR: - error_ = CHANNEL_CONNECTION_ERROR; - break; - case JingleMessage::INCOMPATIBLE_PARAMETERS: - error_ = INCOMPATIBLE_PROTOCOL; - break; - default: - error_ = UNKNOWN_ERROR; - } - - if (error_ != OK) { - SetState(FAILED); - } else { - SetState(CLOSED); - } -} - -bool PepperSession::InitializeConfigFromDescription( - const ContentDescription* description) { - DCHECK(description); - - if (!description->config()->GetFinalConfig(&config_)) { - LOG(ERROR) << "session-accept does not specify configuration"; - return false; - } - if (!candidate_config()->IsSupported(config_)) { - LOG(ERROR) << "session-accept specifies an invalid configuration"; - return false; - } - - return true; -} - -void PepperSession::ProcessAuthenticationStep() { - DCHECK_EQ(state_, CONNECTED); - - if (authenticator_->state() == Authenticator::MESSAGE_READY) { - JingleMessage message(peer_jid_, JingleMessage::SESSION_INFO, session_id_); - message.info = authenticator_->GetNextMessage(); - DCHECK(message.info.get()); - - session_info_request_ = session_manager_->iq_sender()->SendIq( - message.ToXml(), base::Bind( - &PepperSession::OnSessionInfoResponse, - base::Unretained(this))); - } - DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); - - if (authenticator_->state() == Authenticator::ACCEPTED) { - SetState(AUTHENTICATED); - } else if (authenticator_->state() == Authenticator::REJECTED) { - CloseInternal(AuthRejectionReasonToError( - authenticator_->rejection_reason())); - } -} - -void PepperSession::OnSessionInfoResponse(const buzz::XmlElement* response) { - const std::string& type = response->Attr(buzz::QName("", "type")); - if (type != "result") { - LOG(ERROR) << "Received error in response to session-info message: \"" - << response->Str() - << "\". Terminating the session."; - CloseInternal(INCOMPATIBLE_PROTOCOL); - } -} - -void PepperSession::OnTransportInfoResponse(const buzz::XmlElement* response) { - const std::string& type = response->Attr(buzz::QName("", "type")); - if (type != "result") { - LOG(ERROR) << "Received error in response to session-initiate message: \"" - << response->Str() - << "\". Terminating the session."; - - if (state_ == CONNECTING) { - CloseInternal(PEER_IS_OFFLINE); - } else { - // Host has disconnected without sending session-terminate message. - CloseInternal(OK); - } - } -} - -void PepperSession::SendTransportInfo() { - JingleMessage message(peer_jid_, JingleMessage::TRANSPORT_INFO, session_id_); - message.candidates.swap(pending_candidates_); - transport_info_request_ = session_manager_->iq_sender()->SendIq( - message.ToXml(), base::Bind( - &PepperSession::OnTransportInfoResponse, - base::Unretained(this))); -} - - -void PepperSession::CloseInternal(Error error) { - DCHECK(CalledOnValidThread()); - - if (state_ == CONNECTING || state_ == CONNECTED || state_ == AUTHENTICATED) { - // Send session-terminate message with the appropriate error code. - JingleMessage::Reason reason; - switch (error) { - case OK: - reason = JingleMessage::SUCCESS; - break; - case SESSION_REJECTED: - case AUTHENTICATION_FAILED: - reason = JingleMessage::DECLINE; - break; - case INCOMPATIBLE_PROTOCOL: - reason = JingleMessage::INCOMPATIBLE_PARAMETERS; - break; - default: - reason = JingleMessage::GENERAL_ERROR; - } - - JingleMessage message(peer_jid_, JingleMessage::SESSION_TERMINATE, - session_id_); - message.reason = reason; - session_manager_->iq_sender()->SendIq( - message.ToXml(), IqSender::ReplyCallback()); - } - - error_ = error; - - if (state_ != FAILED && state_ != CLOSED) { - if (error != OK) { - SetState(FAILED); - } else { - SetState(CLOSED); - } - } -} - -void PepperSession::SetState(State new_state) { - DCHECK(CalledOnValidThread()); - - if (new_state != state_) { - DCHECK_NE(state_, CLOSED); - DCHECK_NE(state_, FAILED); - - state_ = new_state; - if (!state_change_callback_.is_null()) - state_change_callback_.Run(new_state); - } -} - -} // namespace protocol -} // namespace remoting diff --git a/remoting/protocol/pepper_session.h b/remoting/protocol/pepper_session.h deleted file mode 100644 index 33cd554..0000000 --- a/remoting/protocol/pepper_session.h +++ /dev/null @@ -1,154 +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_PROTOCOL_PEPPER_SESSION_H_ -#define REMOTING_PROTOCOL_PEPPER_SESSION_H_ - -#include -#include -#include - -#include "base/memory/ref_counted.h" -#include "base/timer.h" -#include "crypto/rsa_private_key.h" -#include "net/base/completion_callback.h" -#include "remoting/protocol/authenticator.h" -#include "remoting/protocol/jingle_messages.h" -#include "remoting/protocol/session.h" -#include "remoting/protocol/session_config.h" -#include "remoting/protocol/transport.h" - -namespace net { -class Socket; -class StreamSocket; -} // namespace net - -namespace remoting { - -class IqRequest; - -namespace protocol { - -class PepperSessionManager; - -// Implements the protocol::Session interface using the Pepper P2P -// Transport API. Created by PepperSessionManager for incoming and -// outgoing connections. -class PepperSession : public Session, - public Transport::EventHandler { - public: - virtual ~PepperSession(); - - // Session interface. - virtual void SetStateChangeCallback( - const StateChangeCallback& callback) OVERRIDE; - virtual void SetRouteChangeCallback( - const RouteChangeCallback& callback) OVERRIDE; - virtual Error error() OVERRIDE; - virtual void CreateStreamChannel( - const std::string& name, - const StreamChannelCallback& callback) OVERRIDE; - virtual void CreateDatagramChannel( - const std::string& name, - const DatagramChannelCallback& callback) OVERRIDE; - virtual void CancelChannelCreation(const std::string& name) OVERRIDE; - virtual const std::string& jid() OVERRIDE; - virtual const CandidateSessionConfig* candidate_config() OVERRIDE; - virtual const SessionConfig& config() OVERRIDE; - virtual void set_config(const SessionConfig& config) OVERRIDE; - virtual void Close() OVERRIDE; - - // Transport::EventHandler interface. - virtual void OnTransportCandidate( - Transport* transport, - const cricket::Candidate& candidate) OVERRIDE; - virtual void OnTransportRouteChange(Transport* transport, - const TransportRoute& route) OVERRIDE; - virtual void OnTransportDeleted(Transport* transport) OVERRIDE; - - private: - friend class PepperSessionManager; - - typedef std::map ChannelsMap; - typedef base::Callback ReplyCallback; - - explicit PepperSession(PepperSessionManager* session_manager); - - // Start connection by sending session-initiate message. - void StartConnection(const std::string& peer_jid, - scoped_ptr authenticator, - scoped_ptr config, - const StateChangeCallback& state_change_callback); - - // Called by PepperSessionManager for incoming connections. - void InitializeIncomingConnection(const JingleMessage& initiate_message, - scoped_ptr authenticator); - void AcceptIncomingConnection(const JingleMessage& initiate_message); - - // Handler for session-initiate response. - void OnSessionInitiateResponse(const buzz::XmlElement* response); - - // Called by PepperSessionManager on incoming |message|. Must call - // |reply_callback| to send reply message before sending any other - // messages. - void OnIncomingMessage(const JingleMessage& message, - const ReplyCallback& reply_callback); - - // Message handlers for incoming messages. - void OnAccept(const JingleMessage& message, - const ReplyCallback& reply_callback); - void OnSessionInfo(const JingleMessage& message, - const ReplyCallback& reply_callback); - void OnTerminate(const JingleMessage& message, - const ReplyCallback& reply_callback); - void ProcessTransportInfo(const JingleMessage& message); - - // Called from OnAccept() to initialize session config. - bool InitializeConfigFromDescription(const ContentDescription* description); - - void ProcessAuthenticationStep(); - void OnSessionInfoResponse(const buzz::XmlElement* response); - - void SendTransportInfo(); - void OnTransportInfoResponse(const buzz::XmlElement* response); - - // Terminates the session and sends session-terminate if it is - // necessary. |error| specifies the error code in case when the - // session is being closed due to an error. - void CloseInternal(Error error); - - // Sets |state_| to |new_state| and calls state change callback. - void SetState(State new_state); - - PepperSessionManager* session_manager_; - std::string peer_jid_; - scoped_ptr candidate_config_; - StateChangeCallback state_change_callback_; - RouteChangeCallback route_change_callback_; - - std::string session_id_; - State state_; - Error error_; - - SessionConfig config_; - bool config_is_set_; - - scoped_ptr authenticator_; - - scoped_ptr initiate_request_; - scoped_ptr session_info_request_; - scoped_ptr transport_info_request_; - - ChannelsMap channels_; - - base::OneShotTimer transport_infos_timer_; - std::list pending_candidates_; - - DISALLOW_COPY_AND_ASSIGN(PepperSession); -}; - -} // namespace protocol -} // namespace remoting - -#endif // REMOTING_PROTOCOL_PEPPER_SESSION_H_ diff --git a/remoting/protocol/pepper_session_manager.cc b/remoting/protocol/pepper_session_manager.cc deleted file mode 100644 index 1024984..0000000 --- a/remoting/protocol/pepper_session_manager.cc +++ /dev/null @@ -1,183 +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/protocol/pepper_session_manager.h" - -#include "base/bind.h" -#include "remoting/jingle_glue/iq_sender.h" -#include "remoting/jingle_glue/jingle_info_request.h" -#include "remoting/jingle_glue/signal_strategy.h" -#include "remoting/protocol/authenticator.h" -#include "remoting/protocol/content_description.h" -#include "remoting/protocol/jingle_messages.h" -#include "remoting/protocol/pepper_session.h" -#include "third_party/libjingle/source/talk/base/socketaddress.h" -#include "third_party/libjingle/source/talk/xmllite/xmlelement.h" - -using buzz::QName; - -namespace remoting { -namespace protocol { - -PepperSessionManager::PepperSessionManager( - scoped_ptr transport_factory) - : transport_factory_(transport_factory.Pass()), - signal_strategy_(NULL), - listener_(NULL), - ready_(false) { -} - -PepperSessionManager::~PepperSessionManager() { - Close(); -} - -void PepperSessionManager::Init( - SignalStrategy* signal_strategy, - SessionManager::Listener* listener, - const NetworkSettings& network_settings) { - listener_ = listener; - signal_strategy_ = signal_strategy; - iq_sender_.reset(new IqSender(signal_strategy_)); - - transport_config_.nat_traversal = network_settings.allow_nat_traversal; - transport_config_.min_port = network_settings.min_port; - transport_config_.max_port = network_settings.max_port; - - signal_strategy_->AddListener(this); - - OnSignalStrategyStateChange(signal_strategy_->GetState()); -} - -void PepperSessionManager::OnJingleInfo( - const std::string& relay_token, - const std::vector& relay_hosts, - const std::vector& stun_hosts) { - DCHECK(CalledOnValidThread()); - - // TODO(sergeyu): Add support for multiple STUN/relay servers when - // it's implemented in libjingle and P2P Transport API. - transport_config_.stun_server = stun_hosts[0].ToString(); - transport_config_.relay_server = relay_hosts[0]; - transport_config_.relay_token = relay_token; - VLOG(1) << "STUN server: " << transport_config_.stun_server - << " Relay server: " << transport_config_.relay_server - << " Relay token: " << transport_config_.relay_token; - - if (!ready_) { - ready_ = true; - listener_->OnSessionManagerReady(); - } -} - -scoped_ptr PepperSessionManager::Connect( - const std::string& host_jid, - scoped_ptr authenticator, - scoped_ptr config, - const Session::StateChangeCallback& state_change_callback) { - scoped_ptr session(new PepperSession(this)); - session->StartConnection(host_jid, authenticator.Pass(), config.Pass(), - state_change_callback); - sessions_[session->session_id_] = session.get(); - return session.PassAs(); -} - -void PepperSessionManager::Close() { - DCHECK(CalledOnValidThread()); - - // Close() can be called only after all sessions are destroyed. - DCHECK(sessions_.empty()); - - listener_ = NULL; - jingle_info_request_.reset(); - - if (signal_strategy_) { - signal_strategy_->RemoveListener(this); - signal_strategy_ = NULL; - } -} - -void PepperSessionManager::set_authenticator_factory( - scoped_ptr authenticator_factory) { - DCHECK(CalledOnValidThread()); - authenticator_factory_ = authenticator_factory.Pass(); -} - -void PepperSessionManager::OnSignalStrategyStateChange( - SignalStrategy::State state) { - // If NAT traversal is enabled then we need to request STUN/Relay info. - if (state == SignalStrategy::CONNECTED) { - if (transport_config_.nat_traversal) { - jingle_info_request_.reset(new JingleInfoRequest(signal_strategy_)); - jingle_info_request_->Send(base::Bind(&PepperSessionManager::OnJingleInfo, - base::Unretained(this))); - } else if (!ready_) { - ready_ = true; - listener_->OnSessionManagerReady(); - } - } -} - -bool PepperSessionManager::OnSignalStrategyIncomingStanza( - const buzz::XmlElement* stanza) { - if (!JingleMessage::IsJingleMessage(stanza)) - return false; - - JingleMessage message; - std::string error; - if (!message.ParseXml(stanza, &error)) { - SendReply(stanza, JingleMessageReply::BAD_REQUEST); - return true; - } - - if (message.action == JingleMessage::SESSION_INITIATE) { - // Description must be present in session-initiate messages. - DCHECK(message.description.get()); - - SendReply(stanza, JingleMessageReply::NONE); - - scoped_ptr authenticator = - authenticator_factory_->CreateAuthenticator( - message.from, message.description->authenticator_message()); - - PepperSession* session = new PepperSession(this); - session->InitializeIncomingConnection(message, authenticator.Pass()); - sessions_[session->session_id_] = session; - - IncomingSessionResponse response = SessionManager::DECLINE; - listener_->OnIncomingSession(session, &response); - - if (response == SessionManager::ACCEPT) { - session->AcceptIncomingConnection(message); - } else { - session->Close(); - delete session; - DCHECK(sessions_.find(message.sid) == sessions_.end()); - } - - return true; - } - - SessionsMap::iterator it = sessions_.find(message.sid); - if (it == sessions_.end()) { - SendReply(stanza, JingleMessageReply::INVALID_SID); - return true; - } - - it->second->OnIncomingMessage(message, base::Bind( - &PepperSessionManager::SendReply, base::Unretained(this), stanza)); - return true; -} - -void PepperSessionManager::SendReply(const buzz::XmlElement* original_stanza, - JingleMessageReply::ErrorType error) { - signal_strategy_->SendStanza( - JingleMessageReply(error).ToXml(original_stanza)); -} - -void PepperSessionManager::SessionDestroyed(PepperSession* session) { - sessions_.erase(session->session_id_); -} - -} // namespace protocol -} // namespace remoting diff --git a/remoting/protocol/pepper_session_manager.h b/remoting/protocol/pepper_session_manager.h deleted file mode 100644 index bf1fb2b..0000000 --- a/remoting/protocol/pepper_session_manager.h +++ /dev/null @@ -1,107 +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_PROTOCOL_PEPPER_SESSION_MANAGER_H_ -#define REMOTING_PROTOCOL_PEPPER_SESSION_MANAGER_H_ - -#include -#include -#include - -#include "base/memory/ref_counted.h" -#include "net/base/x509_certificate.h" -#include "remoting/jingle_glue/signal_strategy.h" -#include "remoting/protocol/jingle_messages.h" -#include "remoting/protocol/session_manager.h" -#include "remoting/protocol/transport.h" -#include "remoting/protocol/transport_config.h" - -namespace pp { -class Instance; -} // namespace pp - -namespace buzz { -class XmlElement; -} // namespace buzz - -namespace talk_base { -class SocketAddress; -} // namespace talk_base - -namespace remoting { - -class IqSender; -class JingleInfoRequest; - -namespace protocol { - -class PepperSession; - -// This class implements SessionManager interface on top of the Pepper -// P2P Transport API. -class PepperSessionManager : public SessionManager, - public SignalStrategy::Listener { - public: - explicit PepperSessionManager( - scoped_ptr transport_factory); - virtual ~PepperSessionManager(); - - // SessionManager interface. - virtual void Init(SignalStrategy* signal_strategy, - SessionManager::Listener* listener, - const NetworkSettings& network_settings) OVERRIDE; - virtual scoped_ptr Connect( - const std::string& host_jid, - scoped_ptr authenticator, - scoped_ptr config, - const Session::StateChangeCallback& state_change_callback) OVERRIDE; - virtual void Close() OVERRIDE; - virtual void set_authenticator_factory( - scoped_ptr authenticator_factory) OVERRIDE; - - // SignalStrategy::Listener interface. - virtual void OnSignalStrategyStateChange( - SignalStrategy::State state) OVERRIDE; - virtual bool OnSignalStrategyIncomingStanza( - const buzz::XmlElement* stanza) OVERRIDE; - - private: - friend class PepperSession; - - typedef std::map SessionsMap; - - void OnJingleInfo( - const std::string& relay_token, - const std::vector& relay_hosts, - const std::vector& stun_hosts); - - IqSender* iq_sender() { return iq_sender_.get(); } - void SendReply(const buzz::XmlElement* original_stanza, - JingleMessageReply::ErrorType error); - - // Called by PepperSession when it is being destroyed. - void SessionDestroyed(PepperSession* session); - - scoped_ptr transport_factory_; - - SignalStrategy* signal_strategy_; - scoped_ptr authenticator_factory_; - scoped_ptr iq_sender_; - SessionManager::Listener* listener_; - - bool ready_; - - TransportConfig transport_config_; - - scoped_ptr jingle_info_request_; - - SessionsMap sessions_; - - DISALLOW_COPY_AND_ASSIGN(PepperSessionManager); -}; - -} // namespace protocol -} // namespace remoting - -#endif // REMOTING_PROTOCOL_PEPPER_SESSION_MANAGER_H_ diff --git a/remoting/protocol/pepper_session_unittest.cc b/remoting/protocol/pepper_session_unittest.cc deleted file mode 100644 index 1c18fba..0000000 --- a/remoting/protocol/pepper_session_unittest.cc +++ /dev/null @@ -1,375 +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/protocol/pepper_session.h" - -#include "base/bind.h" -#include "base/message_loop.h" -#include "base/time.h" -#include "base/test/test_timeouts.h" -#include "net/socket/socket.h" -#include "net/socket/stream_socket.h" -#include "remoting/base/constants.h" -#include "remoting/protocol/authenticator.h" -#include "remoting/protocol/channel_authenticator.h" -#include "remoting/protocol/connection_tester.h" -#include "remoting/protocol/fake_authenticator.h" -#include "remoting/protocol/pepper_session_manager.h" -#include "remoting/protocol/libjingle_transport_factory.h" -#include "remoting/jingle_glue/jingle_thread.h" -#include "remoting/jingle_glue/fake_signal_strategy.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::_; -using testing::AtMost; -using testing::DeleteArg; -using testing::DoAll; -using testing::InSequence; -using testing::Invoke; -using testing::InvokeWithoutArgs; -using testing::Return; -using testing::SaveArg; -using testing::SetArgumentPointee; -using testing::WithArg; - -namespace remoting { -namespace protocol { - -namespace { - -const char kHostJid[] = "host1@gmail.com/123"; -const char kClientJid[] = "host2@gmail.com/321"; - -// Send 100 messages 1024 bytes each. UDP messages are sent with 10ms delay -// between messages (about 1 second for 100 messages). -const int kMessageSize = 1024; -const int kMessages = 100; -const char kChannelName[] = "test_channel"; - -void QuitCurrentThread() { - MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); -} - -ACTION_P(QuitThreadOnCounter, counter) { - --(*counter); - EXPECT_GE(*counter, 0); - if (*counter == 0) - QuitCurrentThread(); -} - -class MockSessionManagerListener : public SessionManager::Listener { - public: - MOCK_METHOD0(OnSessionManagerReady, void()); - MOCK_METHOD2(OnIncomingSession, - void(Session*, - SessionManager::IncomingSessionResponse*)); -}; - -class MockSessionCallback { - public: - MOCK_METHOD1(OnStateChange, void(Session::State)); -}; - -class MockStreamChannelCallback { - public: - MOCK_METHOD1(OnDone, void(net::StreamSocket* socket)); -}; - -} // namespace - -class PepperSessionTest : public testing::Test { - public: - PepperSessionTest() - : message_loop_(talk_base::Thread::Current()) { - } - - // Helper method that handles OnIncomingSession(). - void SetHostSession(Session* session) { - DCHECK(session); - host_session_.reset(session); - host_session_->SetStateChangeCallback( - base::Bind(&MockSessionCallback::OnStateChange, - base::Unretained(&host_connection_callback_))); - - session->set_config(SessionConfig::GetDefault()); - } - - void OnClientChannelCreated(scoped_ptr socket) { - client_channel_callback_.OnDone(socket.get()); - client_socket_ = socket.Pass(); - } - - void OnHostChannelCreated(scoped_ptr socket) { - host_channel_callback_.OnDone(socket.get()); - host_socket_ = socket.Pass(); - } - - protected: - virtual void SetUp() { - } - - virtual void TearDown() { - CloseSessions(); - CloseSessionManager(); - message_loop_.RunAllPending(); - } - - void CloseSessions() { - host_socket_.reset(); - host_session_.reset(); - client_socket_.reset(); - client_session_.reset(); - } - - void CreateSessionManagers(int auth_round_trips, - FakeAuthenticator::Action auth_action) { - host_signal_strategy_.reset(new FakeSignalStrategy(kHostJid)); - client_signal_strategy_.reset(new FakeSignalStrategy(kClientJid)); - FakeSignalStrategy::Connect(host_signal_strategy_.get(), - client_signal_strategy_.get()); - - EXPECT_CALL(host_server_listener_, OnSessionManagerReady()) - .Times(1); - host_server_.reset(new PepperSessionManager( - scoped_ptr(new LibjingleTransportFactory()))); - host_server_->Init(host_signal_strategy_.get(), &host_server_listener_, - NetworkSettings(false)); - - scoped_ptr factory( - new FakeHostAuthenticatorFactory(auth_round_trips, auth_action, true)); - host_server_->set_authenticator_factory(factory.Pass()); - - EXPECT_CALL(client_server_listener_, OnSessionManagerReady()) - .Times(1); - client_server_.reset(new PepperSessionManager( - scoped_ptr(new LibjingleTransportFactory()))); - client_server_->Init(client_signal_strategy_.get(), - &client_server_listener_, NetworkSettings()); - } - - void CloseSessionManager() { - if (host_server_.get()) { - host_server_->Close(); - host_server_.reset(); - } - if (client_server_.get()) { - client_server_->Close(); - client_server_.reset(); - } - host_signal_strategy_.reset(); - client_signal_strategy_.reset(); - } - - void InitiateConnection(int auth_round_trips, - FakeAuthenticator::Action auth_action, - bool expect_fail) { - EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _)) - .WillOnce(DoAll( - WithArg<0>(Invoke(this, &PepperSessionTest::SetHostSession)), - SetArgumentPointee<1>(protocol::SessionManager::ACCEPT))); - - { - InSequence dummy; - - EXPECT_CALL(host_connection_callback_, - OnStateChange(Session::CONNECTED)) - .Times(AtMost(1)); - if (expect_fail) { - EXPECT_CALL(host_connection_callback_, - OnStateChange(Session::FAILED)) - .Times(1); - } else { - EXPECT_CALL(host_connection_callback_, - OnStateChange(Session::AUTHENTICATED)) - .Times(1); - // Expect that the connection will be closed eventually. - EXPECT_CALL(host_connection_callback_, - OnStateChange(Session::CLOSED)) - .Times(AtMost(1)); - } - } - - { - InSequence dummy; - - EXPECT_CALL(client_connection_callback_, - OnStateChange(Session::CONNECTING)) - .Times(1); - EXPECT_CALL(client_connection_callback_, - OnStateChange(Session::CONNECTED)) - .Times(AtMost(1)); - if (expect_fail) { - EXPECT_CALL(client_connection_callback_, - OnStateChange(Session::FAILED)) - .Times(1); - } else { - EXPECT_CALL(client_connection_callback_, - OnStateChange(Session::AUTHENTICATED)) - .Times(1); - // Expect that the connection will be closed eventually. - EXPECT_CALL(client_connection_callback_, - OnStateChange(Session::CLOSED)) - .Times(AtMost(1)); - } - } - - scoped_ptr authenticator(new FakeAuthenticator( - FakeAuthenticator::CLIENT, auth_round_trips, auth_action, true)); - - client_session_ = client_server_->Connect( - kHostJid, authenticator.Pass(), - CandidateSessionConfig::CreateDefault(), - base::Bind(&MockSessionCallback::OnStateChange, - base::Unretained(&client_connection_callback_))); - - message_loop_.RunAllPending(); - } - - void CreateChannel(bool expect_fail) { - client_session_->CreateStreamChannel(kChannelName, base::Bind( - &PepperSessionTest::OnClientChannelCreated, base::Unretained(this))); - host_session_->CreateStreamChannel(kChannelName, base::Bind( - &PepperSessionTest::OnHostChannelCreated, base::Unretained(this))); - - int counter = 2; - EXPECT_CALL(client_channel_callback_, OnDone(_)) - .WillOnce(QuitThreadOnCounter(&counter)); - EXPECT_CALL(host_channel_callback_, OnDone(_)) - .WillOnce(QuitThreadOnCounter(&counter)); - message_loop_.Run(); - - if (expect_fail) { - // At least one socket should fail to connect. - EXPECT_TRUE((!client_socket_.get()) || (!host_socket_.get())); - } else { - EXPECT_TRUE(client_socket_.get()); - EXPECT_TRUE(host_socket_.get()); - } - } - - JingleThreadMessageLoop message_loop_; - - scoped_ptr host_signal_strategy_; - scoped_ptr client_signal_strategy_; - - scoped_ptr host_server_; - MockSessionManagerListener host_server_listener_; - scoped_ptr client_server_; - MockSessionManagerListener client_server_listener_; - - scoped_ptr host_session_; - MockSessionCallback host_connection_callback_; - scoped_ptr client_session_; - MockSessionCallback client_connection_callback_; - - MockStreamChannelCallback client_channel_callback_; - MockStreamChannelCallback host_channel_callback_; - - scoped_ptr client_socket_; - scoped_ptr host_socket_; -}; - - -// Verify that we can create and destroy session managers without a -// connection. -TEST_F(PepperSessionTest, CreateAndDestoy) { - CreateSessionManagers(1, FakeAuthenticator::ACCEPT); -} - -// Verify that an incoming session can be rejected, and that the -// status of the connection is set to FAILED in this case. -TEST_F(PepperSessionTest, RejectConnection) { - CreateSessionManagers(1, FakeAuthenticator::ACCEPT); - - // Reject incoming session. - EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _)) - .WillOnce(SetArgumentPointee<1>(protocol::SessionManager::DECLINE)); - - { - InSequence dummy; - - EXPECT_CALL(client_connection_callback_, - OnStateChange(Session::CONNECTING)) - .Times(1); - EXPECT_CALL(client_connection_callback_, - OnStateChange(Session::FAILED)) - .Times(1); - } - - scoped_ptr authenticator(new FakeAuthenticator( - FakeAuthenticator::CLIENT, 1, FakeAuthenticator::ACCEPT, true)); - client_session_ = client_server_->Connect( - kHostJid, authenticator.Pass(), CandidateSessionConfig::CreateDefault(), - base::Bind(&MockSessionCallback::OnStateChange, - base::Unretained(&client_connection_callback_))); - - message_loop_.RunAllPending(); -} - -// Verify that we can connect two endpoints with single-step authentication. -TEST_F(PepperSessionTest, Connect) { - CreateSessionManagers(1, FakeAuthenticator::ACCEPT); - InitiateConnection(1, FakeAuthenticator::ACCEPT, false); -} - -// Verify that we can connect two endpoints with multi-step authentication. -TEST_F(PepperSessionTest, ConnectWithMultistep) { - CreateSessionManagers(3, FakeAuthenticator::ACCEPT); - InitiateConnection(3, FakeAuthenticator::ACCEPT, false); -} - -// Verify that connection is terminated when single-step auth fails. -TEST_F(PepperSessionTest, ConnectWithBadAuth) { - CreateSessionManagers(1, FakeAuthenticator::REJECT); - InitiateConnection(1, FakeAuthenticator::ACCEPT, true); -} - -// Verify that connection is terminated when multi-step auth fails. -TEST_F(PepperSessionTest, ConnectWithBadMultistepAuth) { - CreateSessionManagers(3, FakeAuthenticator::REJECT); - InitiateConnection(3, FakeAuthenticator::ACCEPT, true); -} - -// Verify that data can be sent over stream channel. -TEST_F(PepperSessionTest, TestStreamChannel) { - CreateSessionManagers(1, FakeAuthenticator::ACCEPT); - ASSERT_NO_FATAL_FAILURE( - InitiateConnection(1, FakeAuthenticator::ACCEPT, false)); - - ASSERT_NO_FATAL_FAILURE(CreateChannel(false)); - - StreamConnectionTester tester(host_socket_.get(), client_socket_.get(), - kMessageSize, kMessages); - tester.Start(); - message_loop_.Run(); - tester.CheckResults(); -} - -// Verify that we can connect channels with multistep auth. -TEST_F(PepperSessionTest, TestMultistepAuthStreamChannel) { - CreateSessionManagers(3, FakeAuthenticator::ACCEPT); - ASSERT_NO_FATAL_FAILURE( - InitiateConnection(3, FakeAuthenticator::ACCEPT, false)); - - ASSERT_NO_FATAL_FAILURE(CreateChannel(false)); - - StreamConnectionTester tester(host_socket_.get(), client_socket_.get(), - kMessageSize, kMessages); - tester.Start(); - message_loop_.Run(); - tester.CheckResults(); -} - -// Verify that we shutdown properly when channel authentication fails. -TEST_F(PepperSessionTest, TestFailedChannelAuth) { - CreateSessionManagers(1, FakeAuthenticator::ACCEPT); - ASSERT_NO_FATAL_FAILURE( - InitiateConnection(1, FakeAuthenticator::REJECT_CHANNEL, false)); - - ASSERT_NO_FATAL_FAILURE(CreateChannel(true)); -} - -} // namespace protocol -} // namespace remoting diff --git a/remoting/protocol/pepper_stream_channel.h b/remoting/protocol/pepper_stream_channel.h deleted file mode 100644 index 693b643..0000000 --- a/remoting/protocol/pepper_stream_channel.h +++ /dev/null @@ -1,77 +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_PROTOCOL_PEPPER_STREAM_CHANNEL_H_ -#define REMOTING_PROTOCOL_PEPPER_STREAM_CHANNEL_H_ - -#include - -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "net/base/completion_callback.h" -#include "remoting/protocol/channel_authenticator.h" -#include "remoting/protocol/pepper_channel.h" -#include "remoting/protocol/pepper_transport_socket_adapter.h" -#include "remoting/protocol/session.h" - -namespace net { -class CertVerifier; -class StreamSocket; -class SSLClientSocket; -} // namespace net - -namespace remoting { -namespace protocol { - -class PepperSession; - -class PepperStreamChannel : public PepperChannel, - public PepperTransportSocketAdapter::Observer { - public: - PepperStreamChannel(PepperSession* session, - const std::string& name, - const Session::StreamChannelCallback& callback); - virtual ~PepperStreamChannel(); - - // PepperChannel implementation. - virtual void Connect(pp::Instance* pp_instance, - const TransportConfig& transport_config, - scoped_ptr authenticator) OVERRIDE; - virtual void AddRemoteCandidate(const cricket::Candidate& candidate) OVERRIDE; - virtual const std::string& name() const OVERRIDE; - virtual bool is_connected() const OVERRIDE; - - // PepperTransportSocketAdapter implementation. - virtual void OnChannelDeleted() OVERRIDE; - virtual void OnChannelNewLocalCandidate( - const std::string& candidate) OVERRIDE; - - private: - void OnP2PConnect(int result); - void OnAuthenticationDone(net::Error error, - scoped_ptr socket); - - void NotifyConnected(scoped_ptr socket); - void NotifyConnectFailed(); - - PepperSession* session_; - std::string name_; - Session::StreamChannelCallback callback_; - scoped_ptr authenticator_; - - // We own |channel_| until it is connected. After that - // |authenticator_| owns it. - scoped_ptr owned_channel_; - PepperTransportSocketAdapter* channel_; - - // Indicates that we've finished connecting. - bool connected_; - - DISALLOW_COPY_AND_ASSIGN(PepperStreamChannel); -}; - -} // namespace protocol -} // namespace remoting - -#endif // REMOTING_PROTOCOL_PEPPER_STREAM_CHANNEL_H_ diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 6207cc7..74c4c3f 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -800,6 +800,10 @@ 'protocol/it2me_host_authenticator_factory.h', 'protocol/jingle_messages.cc', 'protocol/jingle_messages.h', + 'protocol/jingle_session.cc', + 'protocol/jingle_session.h', + 'protocol/jingle_session_manager.cc', + 'protocol/jingle_session_manager.h', 'protocol/key_event_tracker.cc', 'protocol/key_event_tracker.h', 'protocol/libjingle_transport_factory.cc', @@ -812,10 +816,6 @@ 'protocol/message_reader.h', 'protocol/negotiating_authenticator.cc', 'protocol/negotiating_authenticator.h', - 'protocol/pepper_session.cc', - 'protocol/pepper_session.h', - 'protocol/pepper_session_manager.cc', - 'protocol/pepper_session_manager.h', 'protocol/pepper_transport_factory.cc', 'protocol/pepper_transport_factory.h', 'protocol/pepper_transport_socket_adapter.cc', @@ -952,11 +952,11 @@ 'protocol/fake_session.cc', 'protocol/fake_session.h', 'protocol/jingle_messages_unittest.cc', + 'protocol/jingle_session_unittest.cc', 'protocol/key_event_tracker_unittest.cc', 'protocol/message_decoder_unittest.cc', 'protocol/message_reader_unittest.cc', 'protocol/negotiating_authenticator_unittest.cc', - 'protocol/pepper_session_unittest.cc', 'protocol/protocol_mock_objects.cc', 'protocol/protocol_mock_objects.h', 'protocol/ppapi_module_stub.cc', -- cgit v1.1