| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/protocol/jingle_session.h" | 5 #include "remoting/protocol/jingle_session.h" |
| 6 | 6 |
| 7 #include "base/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/message_loop_proxy.h" | 10 #include "base/message_loop_proxy.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include "third_party/libjingle/source/talk/p2p/base/transport.h" | 26 #include "third_party/libjingle/source/talk/p2p/base/transport.h" |
| 27 | 27 |
| 28 using cricket::BaseSession; | 28 using cricket::BaseSession; |
| 29 | 29 |
| 30 namespace remoting { | 30 namespace remoting { |
| 31 namespace protocol { | 31 namespace protocol { |
| 32 | 32 |
| 33 JingleSession::JingleSession( | 33 JingleSession::JingleSession( |
| 34 JingleSessionManager* jingle_session_manager, | 34 JingleSessionManager* jingle_session_manager, |
| 35 cricket::Session* cricket_session, | 35 cricket::Session* cricket_session, |
| 36 Authenticator* authenticator) | 36 scoped_ptr<Authenticator> authenticator) |
| 37 : jingle_session_manager_(jingle_session_manager), | 37 : jingle_session_manager_(jingle_session_manager), |
| 38 authenticator_(authenticator), | 38 authenticator_(authenticator.Pass()), |
| 39 state_(INITIALIZING), | 39 state_(INITIALIZING), |
| 40 error_(OK), | 40 error_(OK), |
| 41 closing_(false), | 41 closing_(false), |
| 42 cricket_session_(cricket_session), | 42 cricket_session_(cricket_session), |
| 43 config_set_(false), | 43 config_set_(false), |
| 44 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | 44 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
| 45 jid_ = cricket_session_->remote_name(); | 45 jid_ = cricket_session_->remote_name(); |
| 46 cricket_session_->SignalState.connect(this, &JingleSession::OnSessionState); | 46 cricket_session_->SignalState.connect(this, &JingleSession::OnSessionState); |
| 47 cricket_session_->SignalError.connect(this, &JingleSession::OnSessionError); | 47 cricket_session_->SignalError.connect(this, &JingleSession::OnSessionError); |
| 48 cricket_session_->SignalInfoMessage.connect( | 48 cricket_session_->SignalInfoMessage.connect( |
| 49 this, &JingleSession::OnSessionInfoMessage); | 49 this, &JingleSession::OnSessionInfoMessage); |
| 50 cricket_session_->SignalReceivedTerminateReason.connect( | 50 cricket_session_->SignalReceivedTerminateReason.connect( |
| 51 this, &JingleSession::OnTerminateReason); | 51 this, &JingleSession::OnTerminateReason); |
| 52 } | 52 } |
| 53 | 53 |
| 54 JingleSession::~JingleSession() { | 54 JingleSession::~JingleSession() { |
| 55 // Reset the callback so that it's not called from Close(). | 55 // Reset the callback so that it's not called from Close(). |
| 56 state_change_callback_.Reset(); | 56 state_change_callback_.Reset(); |
| 57 Close(); | 57 Close(); |
| 58 jingle_session_manager_->SessionDestroyed(this); | 58 jingle_session_manager_->SessionDestroyed(this); |
| 59 DCHECK(channel_connectors_.empty()); | 59 DCHECK(channel_connectors_.empty()); |
| 60 } | 60 } |
| 61 | 61 |
| 62 void JingleSession::SendSessionInitiate() { | 62 void JingleSession::SendSessionInitiate() { |
| 63 DCHECK_EQ(authenticator_->state(), Authenticator::MESSAGE_READY); | 63 DCHECK_EQ(authenticator_->state(), Authenticator::MESSAGE_READY); |
| 64 cricket_session_->Initiate( | 64 cricket_session_->Initiate( |
| 65 jid_, CreateSessionDescription(candidate_config()->Clone(), | 65 jid_, CreateSessionDescription( |
| 66 authenticator_->GetNextMessage())); | 66 candidate_config()->Clone(), authenticator_->GetNextMessage())); |
| 67 } | 67 } |
| 68 | 68 |
| 69 void JingleSession::CloseInternal(int result, Error error) { | 69 void JingleSession::CloseInternal(int result, Error error) { |
| 70 DCHECK(CalledOnValidThread()); | 70 DCHECK(CalledOnValidThread()); |
| 71 | 71 |
| 72 if (state_ != FAILED && state_ != CLOSED && !closing_) { | 72 if (state_ != FAILED && state_ != CLOSED && !closing_) { |
| 73 closing_ = true; | 73 closing_ = true; |
| 74 | 74 |
| 75 // Tear down the cricket session, including the cricket transport channels. | 75 // Tear down the cricket session, including the cricket transport channels. |
| 76 if (cricket_session_) { | 76 if (cricket_session_) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 return jid_; | 165 return jid_; |
| 166 } | 166 } |
| 167 | 167 |
| 168 const CandidateSessionConfig* JingleSession::candidate_config() { | 168 const CandidateSessionConfig* JingleSession::candidate_config() { |
| 169 DCHECK(CalledOnValidThread()); | 169 DCHECK(CalledOnValidThread()); |
| 170 DCHECK(candidate_config_.get()); | 170 DCHECK(candidate_config_.get()); |
| 171 return candidate_config_.get(); | 171 return candidate_config_.get(); |
| 172 } | 172 } |
| 173 | 173 |
| 174 void JingleSession::set_candidate_config( | 174 void JingleSession::set_candidate_config( |
| 175 const CandidateSessionConfig* candidate_config) { | 175 scoped_ptr<CandidateSessionConfig> candidate_config) { |
| 176 DCHECK(CalledOnValidThread()); | 176 DCHECK(CalledOnValidThread()); |
| 177 DCHECK(!candidate_config_.get()); | 177 DCHECK(!candidate_config_.get()); |
| 178 DCHECK(candidate_config); | 178 DCHECK(candidate_config.get()); |
| 179 candidate_config_.reset(candidate_config); | 179 candidate_config_ = candidate_config.Pass(); |
| 180 } | 180 } |
| 181 | 181 |
| 182 const SessionConfig& JingleSession::config() { | 182 const SessionConfig& JingleSession::config() { |
| 183 DCHECK(CalledOnValidThread()); | 183 DCHECK(CalledOnValidThread()); |
| 184 DCHECK(config_set_); | 184 DCHECK(config_set_); |
| 185 return config_; | 185 return config_; |
| 186 } | 186 } |
| 187 | 187 |
| 188 void JingleSession::set_config(const SessionConfig& config) { | 188 void JingleSession::set_config(const SessionConfig& config) { |
| 189 DCHECK(CalledOnValidThread()); | 189 DCHECK(CalledOnValidThread()); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 SetState(CONNECTING); | 377 SetState(CONNECTING); |
| 378 | 378 |
| 379 const cricket::SessionDescription* session_description = | 379 const cricket::SessionDescription* session_description = |
| 380 cricket_session_->remote_description(); | 380 cricket_session_->remote_description(); |
| 381 const cricket::ContentInfo* content = | 381 const cricket::ContentInfo* content = |
| 382 session_description->FirstContentByType(kChromotingXmlNamespace); | 382 session_description->FirstContentByType(kChromotingXmlNamespace); |
| 383 | 383 |
| 384 CHECK(content); | 384 CHECK(content); |
| 385 const ContentDescription* content_description = | 385 const ContentDescription* content_description = |
| 386 static_cast<const ContentDescription*>(content->description); | 386 static_cast<const ContentDescription*>(content->description); |
| 387 candidate_config_.reset(content_description->config()->Clone()); | 387 candidate_config_ = content_description->config()->Clone(); |
| 388 | 388 |
| 389 SessionManager::IncomingSessionResponse response = | 389 SessionManager::IncomingSessionResponse response = |
| 390 jingle_session_manager_->AcceptConnection(this); | 390 jingle_session_manager_->AcceptConnection(this); |
| 391 if (response != SessionManager::ACCEPT) { | 391 if (response != SessionManager::ACCEPT) { |
| 392 if (response == SessionManager::INCOMPATIBLE) { | 392 if (response == SessionManager::INCOMPATIBLE) { |
| 393 cricket_session_->TerminateWithReason( | 393 cricket_session_->TerminateWithReason( |
| 394 cricket::STR_TERMINATE_INCOMPATIBLE_PARAMETERS); | 394 cricket::STR_TERMINATE_INCOMPATIBLE_PARAMETERS); |
| 395 } else { | 395 } else { |
| 396 cricket_session_->TerminateWithReason(cricket::STR_TERMINATE_DECLINE); | 396 cricket_session_->TerminateWithReason(cricket::STR_TERMINATE_DECLINE); |
| 397 } | 397 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 419 } | 419 } |
| 420 | 420 |
| 421 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); | 421 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); |
| 422 authenticator_->ProcessMessage(auth_message); | 422 authenticator_->ProcessMessage(auth_message); |
| 423 if (authenticator_->state() == Authenticator::REJECTED) { | 423 if (authenticator_->state() == Authenticator::REJECTED) { |
| 424 CloseInternal(net::ERR_CONNECTION_FAILED, AUTHENTICATION_FAILED); | 424 CloseInternal(net::ERR_CONNECTION_FAILED, AUTHENTICATION_FAILED); |
| 425 return; | 425 return; |
| 426 } | 426 } |
| 427 | 427 |
| 428 // Connection must be configured by the AcceptConnection() callback. | 428 // Connection must be configured by the AcceptConnection() callback. |
| 429 CandidateSessionConfig* candidate_config = | 429 scoped_ptr<CandidateSessionConfig> candidate_config = |
| 430 CandidateSessionConfig::CreateFrom(config()); | 430 CandidateSessionConfig::CreateFrom(config()); |
| 431 | 431 |
| 432 buzz::XmlElement* auth_reply = NULL; | 432 scoped_ptr<buzz::XmlElement> auth_reply; |
| 433 if (authenticator_->state() == Authenticator::MESSAGE_READY) | 433 if (authenticator_->state() == Authenticator::MESSAGE_READY) |
| 434 auth_reply = authenticator_->GetNextMessage(); | 434 auth_reply = authenticator_->GetNextMessage(); |
| 435 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); | 435 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); |
| 436 cricket_session_->Accept( | 436 cricket_session_->Accept( |
| 437 CreateSessionDescription(candidate_config, auth_reply)); | 437 CreateSessionDescription(candidate_config.Pass(), auth_reply.Pass())); |
| 438 } | 438 } |
| 439 | 439 |
| 440 void JingleSession::ProcessAuthenticationStep() { | 440 void JingleSession::ProcessAuthenticationStep() { |
| 441 DCHECK_EQ(state_, CONNECTED); | 441 DCHECK_EQ(state_, CONNECTED); |
| 442 | 442 |
| 443 if (authenticator_->state() == Authenticator::MESSAGE_READY) { | 443 if (authenticator_->state() == Authenticator::MESSAGE_READY) { |
| 444 buzz::XmlElement* auth_message = authenticator_->GetNextMessage(); | 444 scoped_ptr<buzz::XmlElement> auth_message = |
| 445 authenticator_->GetNextMessage(); |
| 445 cricket::XmlElements message; | 446 cricket::XmlElements message; |
| 446 message.push_back(auth_message); | 447 message.push_back(auth_message.release()); |
| 447 cricket_session_->SendInfoMessage(message); | 448 cricket_session_->SendInfoMessage(message); |
| 448 } | 449 } |
| 449 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); | 450 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); |
| 450 | 451 |
| 451 if (authenticator_->state() == Authenticator::ACCEPTED) { | 452 if (authenticator_->state() == Authenticator::ACCEPTED) { |
| 452 SetState(AUTHENTICATED); | 453 SetState(AUTHENTICATED); |
| 453 } else if (authenticator_->state() == Authenticator::REJECTED) { | 454 } else if (authenticator_->state() == Authenticator::REJECTED) { |
| 454 CloseInternal(net::ERR_CONNECTION_ABORTED, AUTHENTICATION_FAILED); | 455 CloseInternal(net::ERR_CONNECTION_ABORTED, AUTHENTICATION_FAILED); |
| 455 } | 456 } |
| 456 } | 457 } |
| 457 | 458 |
| 458 void JingleSession::AddChannelConnector( | 459 void JingleSession::AddChannelConnector( |
| 459 const std::string& name, JingleChannelConnector* connector) { | 460 const std::string& name, JingleChannelConnector* connector) { |
| 460 DCHECK(channel_connectors_.find(name) == channel_connectors_.end()); | 461 DCHECK(channel_connectors_.find(name) == channel_connectors_.end()); |
| 461 | 462 |
| 462 const std::string& content_name = GetContentInfo()->name; | 463 const std::string& content_name = GetContentInfo()->name; |
| 463 cricket::TransportChannel* raw_channel = | 464 cricket::TransportChannel* raw_channel = |
| 464 cricket_session_->CreateChannel(content_name, name); | 465 cricket_session_->CreateChannel(content_name, name); |
| 465 | 466 |
| 466 if (!jingle_session_manager_->allow_nat_traversal_ && | 467 if (!jingle_session_manager_->allow_nat_traversal_ && |
| 467 !cricket_session_->initiator()) { | 468 !cricket_session_->initiator()) { |
| 468 // Don't make outgoing connections from the host to client when | 469 // Don't make outgoing connections from the host to client when |
| 469 // NAT traversal is disabled. | 470 // NAT traversal is disabled. |
| 470 raw_channel->GetP2PChannel()->set_incoming_only(true); | 471 raw_channel->GetP2PChannel()->set_incoming_only(true); |
| 471 } | 472 } |
| 472 | 473 |
| 473 channel_connectors_[name] = connector; | 474 channel_connectors_[name] = connector; |
| 474 ChannelAuthenticator* authenticator = | 475 scoped_ptr<ChannelAuthenticator> authenticator = |
| 475 authenticator_->CreateChannelAuthenticator(); | 476 authenticator_->CreateChannelAuthenticator(); |
| 476 connector->Connect(authenticator, raw_channel); | 477 connector->Connect(authenticator.Pass(), raw_channel); |
| 477 | 478 |
| 478 // Workaround bug in libjingle - it doesn't connect channels if they | 479 // Workaround bug in libjingle - it doesn't connect channels if they |
| 479 // are created after the session is accepted. See crbug.com/89384. | 480 // are created after the session is accepted. See crbug.com/89384. |
| 480 // TODO(sergeyu): Fix the bug and remove this line. | 481 // TODO(sergeyu): Fix the bug and remove this line. |
| 481 cricket_session_->GetTransport(content_name)->ConnectChannels(); | 482 cricket_session_->GetTransport(content_name)->ConnectChannels(); |
| 482 } | 483 } |
| 483 | 484 |
| 484 void JingleSession::OnChannelConnectorFinished( | 485 void JingleSession::OnChannelConnectorFinished( |
| 485 const std::string& name, JingleChannelConnector* connector) { | 486 const std::string& name, JingleChannelConnector* connector) { |
| 486 DCHECK(CalledOnValidThread()); | 487 DCHECK(CalledOnValidThread()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 511 DCHECK_NE(state_, FAILED); | 512 DCHECK_NE(state_, FAILED); |
| 512 | 513 |
| 513 state_ = new_state; | 514 state_ = new_state; |
| 514 if (!state_change_callback_.is_null()) | 515 if (!state_change_callback_.is_null()) |
| 515 state_change_callback_.Run(new_state); | 516 state_change_callback_.Run(new_state); |
| 516 } | 517 } |
| 517 } | 518 } |
| 518 | 519 |
| 519 // static | 520 // static |
| 520 cricket::SessionDescription* JingleSession::CreateSessionDescription( | 521 cricket::SessionDescription* JingleSession::CreateSessionDescription( |
| 521 const CandidateSessionConfig* config, | 522 scoped_ptr<CandidateSessionConfig> config, |
| 522 const buzz::XmlElement* authenticator_message) { | 523 scoped_ptr<buzz::XmlElement> authenticator_message) { |
| 523 cricket::SessionDescription* desc = new cricket::SessionDescription(); | 524 cricket::SessionDescription* desc = new cricket::SessionDescription(); |
| 524 desc->AddContent( | 525 desc->AddContent( |
| 525 ContentDescription::kChromotingContentName, kChromotingXmlNamespace, | 526 ContentDescription::kChromotingContentName, kChromotingXmlNamespace, |
| 526 new ContentDescription(config, authenticator_message)); | 527 new ContentDescription(config.Pass(), authenticator_message.Pass())); |
| 527 return desc; | 528 return desc; |
| 528 } | 529 } |
| 529 | 530 |
| 530 } // namespace protocol | 531 } // namespace protocol |
| 531 } // namespace remoting | 532 } // namespace remoting |
| OLD | NEW |