15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/jingle_session.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/rand_util.h" 9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/single_thread_task_runner.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 115e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/thread_task_runner_handle.h" 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/base/constants.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/authenticator.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/channel_authenticator.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/channel_multiplexer.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/content_description.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/jingle_messages.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/jingle_session_manager.h" 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "remoting/protocol/pseudotcp_channel_factory.h" 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "remoting/protocol/secure_channel_factory.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/session_config.h" 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "remoting/protocol/stream_channel_factory.h" 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "remoting/signaling/iq_sender.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/libjingle/source/talk/p2p/base/candidate.h" 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using buzz::XmlElement; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protocol { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Delay after candidate creation before sending transport-info 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message. This is neccessary to be able to pack multiple candidates 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// into one transport-info messages. The value needs to be greater 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// than zero because ports are opened asynchronously in the browser 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// process. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTransportInfoSendDelayMs = 2; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// How long we should wait for a response from the other end. This value is used 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// for all requests except |transport-info|. 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kDefaultMessageTimeout = 10; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// During a reconnection, it usually takes longer for the peer to respond due to 475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// pending messages in the channel from the previous session. From experiment, 485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// it can take up to 20s for the session to reconnect. To make it safe, setting 495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// the timeout to 30s. 505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuconst int kSessionInitiateAndAcceptTimeout = kDefaultMessageTimeout * 3; 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Timeout for the transport-info messages. 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kTransportInfoTimeout = 10 * 60; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Name of the multiplexed channel. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kMuxChannelName[] = "mux"; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ErrorCode AuthRejectionReasonToErrorCode( 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Authenticator::RejectionReason reason) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (reason) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Authenticator::INVALID_CREDENTIALS: 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AUTHENTICATION_FAILED; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case Authenticator::PROTOCOL_ERROR: 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return INCOMPATIBLE_PROTOCOL; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UNKNOWN_ERROR; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JingleSession::JingleSession(JingleSessionManager* session_manager) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : session_manager_(session_manager), 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_handler_(NULL), 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_(INITIALIZING), 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_(OK), 77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch config_is_set_(false), 78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch weak_factory_(this) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JingleSession::~JingleSession() { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_multiplexer_.reset(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteContainerPointers(pending_requests_.begin(), 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_requests_.end()); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) STLDeleteContainerPointers(transport_info_requests_.begin(), 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transport_info_requests_.end()); 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(channels_.empty()); 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_manager_->SessionDestroyed(this); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::SetEventHandler(Session::EventHandler* event_handler) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(event_handler); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_handler_ = event_handler; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ErrorCode JingleSession::error() { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return error_; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::StartConnection( 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& peer_jid, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Authenticator> authenticator, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<CandidateSessionConfig> config) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(authenticator.get()); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(authenticator->state(), Authenticator::MESSAGE_READY); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) peer_jid_ = peer_jid; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) authenticator_ = authenticator.Pass(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_config_ = config.Pass(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate random session ID. There are usually not more than 1 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // concurrent session per host, so a random 64-bit integer provides 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // enough entropy. In the worst case connection will fail when two 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // clients generate the same session ID concurrently. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_id_ = base::Int64ToString(base::RandGenerator(kint64max)); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send session-initiate message. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JingleMessage message(peer_jid_, JingleMessage::SESSION_INITIATE, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_id_); 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch message.initiator = session_manager_->signal_strategy_->GetLocalJid(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message.description.reset( 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ContentDescription(candidate_config_->Clone(), 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) authenticator_->GetNextMessage())); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendMessage(message); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CONNECTING); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::InitializeIncomingConnection( 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const JingleMessage& initiate_message, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Authenticator> authenticator) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(initiate_message.description.get()); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(authenticator.get()); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(authenticator->state(), Authenticator::WAITING_MESSAGE); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) peer_jid_ = initiate_message.from; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) authenticator_ = authenticator.Pass(); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_id_ = initiate_message.sid; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_config_ = initiate_message.description->config()->Clone(); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetState(ACCEPTING); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::AcceptIncomingConnection( 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const JingleMessage& initiate_message) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(config_is_set_); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Process the first authentication message. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const buzz::XmlElement* first_auth_message = 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initiate_message.description->authenticator_message(); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!first_auth_message) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseInternal(INCOMPATIBLE_PROTOCOL); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |authenticator_| is owned, so Unretained() is safe here. 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) authenticator_->ProcessMessage(first_auth_message, base::Bind( 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &JingleSession::ContinueAcceptIncomingConnection, 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void JingleSession::ContinueAcceptIncomingConnection() { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(authenticator_->state(), Authenticator::PROCESSING_MESSAGE); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (authenticator_->state() == Authenticator::REJECTED) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseInternal(AuthRejectionReasonToErrorCode( 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) authenticator_->rejection_reason())); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send the session-accept message. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JingleMessage message(peer_jid_, JingleMessage::SESSION_ACCEPT, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_id_); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<buzz::XmlElement> auth_message; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (authenticator_->state() == Authenticator::MESSAGE_READY) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_message = authenticator_->GetNextMessage(); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message.description.reset( 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ContentDescription(CandidateSessionConfig::CreateFrom(config_), 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_message.Pass())); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendMessage(message); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update state. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CONNECTED); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (authenticator_->state() == Authenticator::ACCEPTED) { 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci OnAuthenticated(); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); 198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (authenticator_->started()) { 199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch SetState(AUTHENTICATING); 200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string& JingleSession::jid() { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return peer_jid_; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const CandidateSessionConfig* JingleSession::candidate_config() { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return candidate_config_.get(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SessionConfig& JingleSession::config() { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return config_; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::set_config(const SessionConfig& config) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!config_is_set_); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_ = config; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_is_set_ = true; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciStreamChannelFactory* JingleSession::GetTransportChannelFactory() { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return secure_channel_factory_.get(); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciStreamChannelFactory* JingleSession::GetMultiplexedChannelFactory() { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!channel_multiplexer_.get()) { 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci channel_multiplexer_.reset( 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new ChannelMultiplexer(GetTransportChannelFactory(), kMuxChannelName)); 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel_multiplexer_.get(); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::Close() { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseInternal(OK); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid JingleSession::AddPendingRemoteCandidates(Transport* channel, 2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& name) { 2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::list<JingleMessage::NamedCandidate>::iterator it = 2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pending_remote_candidates_.begin(); 2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch while(it != pending_remote_candidates_.end()) { 2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (it->name == name) { 2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch channel->AddRemoteCandidate(it->candidate); 2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch it = pending_remote_candidates_.erase(it); 2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ++it; 2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid JingleSession::CreateChannel(const std::string& name, 2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ChannelCreatedCallback& callback) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!channels_[name]); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<Transport> channel = 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci session_manager_->transport_factory_->CreateTransport(); 2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci channel->Connect(name, this, callback); 2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AddPendingRemoteCandidates(channel.get(), name); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channels_[name] = channel.release(); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::CancelChannelCreation(const std::string& name) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelsMap::iterator it = channels_.find(name); 2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (it != channels_.end()) { 2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!it->second->is_connected()); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete it->second; 2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(channels_.find(name) == channels_.end()); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::OnTransportCandidate(Transport* transport, 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const cricket::Candidate& candidate) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_candidates_.push_back(JingleMessage::NamedCandidate( 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transport->name(), candidate)); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!transport_infos_timer_.IsRunning()) { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delay sending the new candidates in case we get more candidates 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that we can send in one message. 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transport_infos_timer_.Start( 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::TimeDelta::FromMilliseconds(kTransportInfoSendDelayMs), 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, &JingleSession::SendTransportInfo); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::OnTransportRouteChange(Transport* transport, 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TransportRoute& route) { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_handler_) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_handler_->OnSessionRouteChange(transport->name(), route); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid JingleSession::OnTransportFailed(Transport* transport) { 301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CloseInternal(CHANNEL_CONNECTION_ERROR); 302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::OnTransportDeleted(Transport* transport) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelsMap::iterator it = channels_.find(transport->name()); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(it->second, transport); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channels_.erase(it); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::SendMessage(const JingleMessage& message) { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<IqRequest> request = session_manager_->iq_sender()->SendIq( 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message.ToXml(), 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&JingleSession::OnMessageResponse, 3145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Unretained(this), 3155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu message.action)); 3165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu int timeout = kDefaultMessageTimeout; 3185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (message.action == JingleMessage::SESSION_INITIATE || 3195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu message.action == JingleMessage::SESSION_ACCEPT) { 3205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu timeout = kSessionInitiateAndAcceptTimeout; 3215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (request) { 3235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu request->SetTimeout(base::TimeDelta::FromSeconds(timeout)); 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_requests_.insert(request.release()); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to send a " 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << JingleMessage::GetActionName(message.action) << " message"; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::OnMessageResponse( 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JingleMessage::ActionType request_type, 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IqRequest* request, 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const buzz::XmlElement* response) { 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Delete the request from the list of pending requests. 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_requests_.erase(request); 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete request; 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Ignore all responses after session was closed. 3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (state_ == CLOSED || state_ == FAILED) 3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string type_str = JingleMessage::GetActionName(request_type); 3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |response| will be NULL if the request timed out. 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response) { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << type_str << " request timed out."; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseInternal(SIGNALING_TIMEOUT); 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& type = 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) response->Attr(buzz::QName(std::string(), "type")); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type != "result") { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Received error in response to " << type_str 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " message: \"" << response->Str() 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "\". Terminating the session."; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(sergeyu): There may be different reasons for error 3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // here. Parse the response stanza to find failure reason. 3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CloseInternal(PEER_IS_OFFLINE); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void JingleSession::SendTransportInfo() { 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JingleMessage message(peer_jid_, JingleMessage::TRANSPORT_INFO, session_id_); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message.candidates.swap(pending_candidates_); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<IqRequest> request = session_manager_->iq_sender()->SendIq( 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message.ToXml(), 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&JingleSession::OnTransportInfoResponse, 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (request) { 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request->SetTimeout(base::TimeDelta::FromSeconds(kTransportInfoTimeout)); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transport_info_requests_.push_back(request.release()); 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Failed to send a transport-info message"; 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void JingleSession::OnTransportInfoResponse(IqRequest* request, 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const buzz::XmlElement* response) { 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!transport_info_requests_.empty()); 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Consider transport-info requests sent before this one lost and delete 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // corresponding IqRequest objects. 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (transport_info_requests_.front() != request) { 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete transport_info_requests_.front(); 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transport_info_requests_.pop_front(); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete the |request| itself. 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(request, transport_info_requests_.front()); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete request; 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) transport_info_requests_.pop_front(); 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ignore transport-info timeouts. 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!response) { 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "transport-info request has timed out."; 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& type = response->Attr(buzz::QName(std::string(), "type")); 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (type != "result") { 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Received error in response to transport-info message: \"" 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << response->Str() << "\". Terminating the session."; 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloseInternal(PEER_IS_OFFLINE); 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::OnIncomingMessage(const JingleMessage& message, 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ReplyCallback& reply_callback) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message.from != peer_jid_) { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ignore messages received from a different Jid. 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_callback.Run(JingleMessageReply::INVALID_SID); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (message.action) { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case JingleMessage::SESSION_ACCEPT: 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnAccept(message, reply_callback); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case JingleMessage::SESSION_INFO: 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnSessionInfo(message, reply_callback); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case JingleMessage::TRANSPORT_INFO: 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_callback.Run(JingleMessageReply::NONE); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessTransportInfo(message); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case JingleMessage::SESSION_TERMINATE: 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnTerminate(message, reply_callback); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::OnAccept(const JingleMessage& message, 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ReplyCallback& reply_callback) { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ != CONNECTING) { 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_callback.Run(JingleMessageReply::NONE); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const buzz::XmlElement* auth_message = 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message.description->authenticator_message(); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!auth_message) { 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DLOG(WARNING) << "Received session-accept without authentication message "; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseInternal(INCOMPATIBLE_PROTOCOL); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!InitializeConfigFromDescription(message.description.get())) { 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseInternal(INCOMPATIBLE_PROTOCOL); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In case there is transport information in the accept message. 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessTransportInfo(message); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CONNECTED); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) authenticator_->ProcessMessage(auth_message, base::Bind( 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &JingleSession::ProcessAuthenticationStep,base::Unretained(this))); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::OnSessionInfo(const JingleMessage& message, 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ReplyCallback& reply_callback) { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!message.info.get() || 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !Authenticator::IsAuthenticatorMessage(message.info.get())) { 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_callback.Run(JingleMessageReply::UNSUPPORTED_INFO); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 484c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if ((state_ != CONNECTED && state_ != AUTHENTICATING) || 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) authenticator_->state() != Authenticator::WAITING_MESSAGE) { 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Received unexpected authenticator message " 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << message.info->Str(); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseInternal(INCOMPATIBLE_PROTOCOL); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_callback.Run(JingleMessageReply::NONE); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) authenticator_->ProcessMessage(message.info.get(), base::Bind( 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &JingleSession::ProcessAuthenticationStep, base::Unretained(this))); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::ProcessTransportInfo(const JingleMessage& message) { 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::list<JingleMessage::NamedCandidate>::const_iterator it = 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message.candidates.begin(); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != message.candidates.end(); ++it) { 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelsMap::iterator channel = channels_.find(it->name); 5047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (channel != channels_.end()) { 5057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch channel->second->AddRemoteCandidate(it->candidate); 5067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 5077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Transport info was received before the channel was created. 5087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // This could happen due to messages being reordered on the wire. 5097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pending_remote_candidates_.push_back(*it); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::OnTerminate(const JingleMessage& message, 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ReplyCallback& reply_callback) { 516c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!is_session_active()) { 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Received unexpected session-terminate message."; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_callback.Run(JingleMessageReply::NONE); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (message.reason) { 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case JingleMessage::SUCCESS: 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == CONNECTING) { 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = SESSION_REJECTED; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = OK; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case JingleMessage::DECLINE: 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = AUTHENTICATION_FAILED; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case JingleMessage::CANCEL: 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = HOST_OVERLOAD; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case JingleMessage::GENERAL_ERROR: 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = CHANNEL_CONNECTION_ERROR; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case JingleMessage::INCOMPATIBLE_PARAMETERS: 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = INCOMPATIBLE_PROTOCOL; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = UNKNOWN_ERROR; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error_ != OK) { 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(FAILED); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CLOSED); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool JingleSession::InitializeConfigFromDescription( 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ContentDescription* description) { 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(description); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!description->config()->GetFinalConfig(&config_)) { 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "session-accept does not specify configuration"; 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!candidate_config()->IsSupported(config_)) { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "session-accept specifies an invalid configuration"; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::ProcessAuthenticationStep() { 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(CalledOnValidThread()); 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(authenticator_->state(), Authenticator::PROCESSING_MESSAGE); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (state_ != CONNECTED && state_ != AUTHENTICATING) { 576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(state_ == FAILED || state_ == CLOSED); 577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The remote host closed the connection while the authentication was being 578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // processed asynchronously, nothing to do. 579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (authenticator_->state() == Authenticator::MESSAGE_READY) { 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JingleMessage message(peer_jid_, JingleMessage::SESSION_INFO, session_id_); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message.info = authenticator_->GetNextMessage(); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(message.info.get()); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendMessage(message); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 590c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // The current JingleSession object can be destroyed by event_handler of 591c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // SetState(AUTHENTICATING) and cause subsequent dereferencing of the this 592c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // pointer to crash. To protect against it, we run ContinueAuthenticationStep 593c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // asychronously using a weak pointer. 594c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::ThreadTaskRunnerHandle::Get()->PostTask( 595c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FROM_HERE, 596c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Bind(&JingleSession::ContinueAuthenticationStep, 597c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch weak_factory_.GetWeakPtr())); 598c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 599c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (authenticator_->started()) { 600c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch SetState(AUTHENTICATING); 601c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 602c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 603c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 604c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid JingleSession::ContinueAuthenticationStep() { 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (authenticator_->state() == Authenticator::ACCEPTED) { 6061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci OnAuthenticated(); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (authenticator_->state() == Authenticator::REJECTED) { 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseInternal(AuthRejectionReasonToErrorCode( 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) authenticator_->rejection_reason())); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid JingleSession::OnAuthenticated() { 6141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pseudotcp_channel_factory_.reset(new PseudoTcpChannelFactory(this)); 6151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci secure_channel_factory_.reset( 6161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new SecureChannelFactory(pseudotcp_channel_factory_.get(), 6171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci authenticator_.get())); 6181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetState(AUTHENTICATED); 6201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 6211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::CloseInternal(ErrorCode error) { 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (is_session_active()) { 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send session-terminate message with the appropriate error code. 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JingleMessage::Reason reason; 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (error) { 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OK: 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reason = JingleMessage::SUCCESS; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SESSION_REJECTED: 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case AUTHENTICATION_FAILED: 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reason = JingleMessage::DECLINE; 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case INCOMPATIBLE_PROTOCOL: 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reason = JingleMessage::INCOMPATIBLE_PARAMETERS; 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case HOST_OVERLOAD: 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reason = JingleMessage::CANCEL; 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reason = JingleMessage::GENERAL_ERROR; 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JingleMessage message(peer_jid_, JingleMessage::SESSION_TERMINATE, 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_id_); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message.reason = reason; 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendMessage(message); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = error; 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ != FAILED && state_ != CLOSED) { 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error != OK) { 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(FAILED); 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetState(CLOSED); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleSession::SetState(State new_state) { 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_state != state_) { 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(state_, CLOSED); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(state_, FAILED); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = new_state; 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_handler_) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_handler_->OnSessionStateChange(new_state); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 676c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool JingleSession::is_session_active() { 677c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return state_ == CONNECTING || state_ == ACCEPTING || state_ == CONNECTED || 678c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state_ == AUTHENTICATING || state_ == AUTHENTICATED; 679c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 680c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace protocol 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 683