blob: d9be5f820f4097cb0bcde4a3be33418907818520 [file] [log] [blame]
// 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 <string>
#include <vector>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/thread_checker.h"
#include "base/timer/timer.h"
#include "crypto/rsa_private_key.h"
#include "net/base/completion_callback.h"
#include "remoting/protocol/authenticator.h"
#include "remoting/protocol/datagram_channel_factory.h"
#include "remoting/protocol/jingle_messages.h"
#include "remoting/protocol/session.h"
#include "remoting/protocol/session_config.h"
#include "remoting/signaling/iq_sender.h"
namespace remoting {
namespace protocol {
class JingleSessionManager;
class Transport;
// 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 {
~JingleSession() override;
// Session interface.
void SetEventHandler(Session::EventHandler* event_handler) override;
ErrorCode error() override;
const std::string& jid() override;
const SessionConfig& config() override;
void SetTransport(Transport* transport) override;
void Close(protocol::ErrorCode error) override;
void AddPlugin(SessionPlugin* plugin) override;
friend class JingleSessionManager;
typedef base::Callback<void(JingleMessageReply::ErrorType)> ReplyCallback;
explicit JingleSession(JingleSessionManager* session_manager);
// Start connection by sending session-initiate message.
void StartConnection(const SignalingAddress& peer_address,
std::unique_ptr<Authenticator> authenticator);
// Called by JingleSessionManager for incoming connections.
void InitializeIncomingConnection(
const std::string& message_id,
const JingleMessage& initiate_message,
std::unique_ptr<Authenticator> authenticator);
void AcceptIncomingConnection(const JingleMessage& initiate_message);
// Callback for Transport interface to send transport-info messages.
void SendTransportInfo(std::unique_ptr<buzz::XmlElement> transport_info);
// Sends |message| to the peer. The session is closed if the send fails or no
// response is received within a reasonable time. All other responses are
// ignored.
void SendMessage(std::unique_ptr<JingleMessage> message);
// Iq response handler.
void OnMessageResponse(JingleMessage::ActionType request_type,
IqRequest* request,
const buzz::XmlElement* response);
// Response handler for transport-info responses. Transport-info timeouts are
// ignored and don't terminate connection.
void OnTransportInfoResponse(IqRequest* request,
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 std::string& id,
std::unique_ptr<JingleMessage> message,
const ReplyCallback& reply_callback);
// Called by OnIncomingMessage() to process the incoming Jingle messages
// in the same order that they are sent.
void ProcessIncomingMessage(std::unique_ptr<JingleMessage> message,
const ReplyCallback& reply_callback);
// Message handlers for incoming messages.
void OnAccept(std::unique_ptr<JingleMessage> message,
const ReplyCallback& reply_callback);
void OnSessionInfo(std::unique_ptr<JingleMessage> message,
const ReplyCallback& reply_callback);
void OnTransportInfo(std::unique_ptr<JingleMessage> message,
const ReplyCallback& reply_callback);
void OnTerminate(std::unique_ptr<JingleMessage> message,
const ReplyCallback& reply_callback);
// Called from OnAccept() to initialize session config.
bool InitializeConfigFromDescription(const ContentDescription* description);
// Called after the initial incoming authenticator message is processed.
void ContinueAcceptIncomingConnection();
// Called after subsequent authenticator messages are processed.
void ProcessAuthenticationStep();
// Called when authentication is finished.
void OnAuthenticated();
// Sets |state_| to |new_state| and calls state change callback.
void SetState(State new_state);
// Returns true if the state of the session is not CLOSED or FAILED
bool is_session_active();
// Executes all plugins against incoming JingleMessage.
void ProcessIncomingPluginMessage(const JingleMessage& message);
// Executes all plugins against outgoing JingleMessage.
void AddPluginAttachments(JingleMessage* message);
// Sends session-initiate message.
void SendSessionInitiateMessage();
// Returns the value of the ID attribute of the next outgoing set IQ with the
// sequence ID encoded.
std::string GetNextOutgoingId();
base::ThreadChecker thread_checker_;
JingleSessionManager* session_manager_;
SignalingAddress peer_address_;
Session::EventHandler* event_handler_;
std::string session_id_;
State state_;
ErrorCode error_;
std::unique_ptr<SessionConfig> config_;
std::unique_ptr<Authenticator> authenticator_;
Transport* transport_ = nullptr;
// Pending Iq requests. Used for all messages except transport-info.
std::vector<std::unique_ptr<IqRequest>> pending_requests_;
// Pending transport-info requests.
std::vector<std::unique_ptr<IqRequest>> transport_info_requests_;
struct PendingMessage {
PendingMessage(PendingMessage&& moved);
PendingMessage(std::unique_ptr<JingleMessage> message,
const ReplyCallback& reply_callback);
PendingMessage& operator=(PendingMessage&& moved);
std::unique_ptr<JingleMessage> message;
ReplyCallback reply_callback;
// A message queue to guarantee the incoming messages are processed in order.
class OrderedMessageQueue;
std::unique_ptr<OrderedMessageQueue> message_queue_;
// This prefix is necessary to disambiguate between the ID's sent from the
// client and the ID's sent from the host.
std::string outgoing_id_prefix_ = base::NumberToString(base::RandUint64());
int next_outgoing_id_ = 0;
// Transport info messages that are received while the session is being
// authenticated.
std::vector<PendingMessage> pending_transport_info_;
// The SessionPlugins attached to this session.
std::vector<SessionPlugin*> plugins_;
base::WeakPtrFactory<JingleSession> weak_factory_;
} // namespace protocol
} // namespace remoting