Chromium Code Reviews| 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(), |
| 67 authenticator_->GetNextMessage()).release()); | |
|
Wez
2012/01/19 23:23:41
Is this another up-cast issue, or should this be a
Sergey Ulanov
2012/01/19 23:50:26
No, cricket::Session::Initiate() is in libjingle,
Wez
2012/01/19 23:56:57
Yes, of course; I mis-counted the brackets...
| |
| 67 } | 68 } |
| 68 | 69 |
| 69 void JingleSession::CloseInternal(int result, Error error) { | 70 void JingleSession::CloseInternal(int result, Error error) { |
| 70 DCHECK(CalledOnValidThread()); | 71 DCHECK(CalledOnValidThread()); |
| 71 | 72 |
| 72 if (state_ != FAILED && state_ != CLOSED && !closing_) { | 73 if (state_ != FAILED && state_ != CLOSED && !closing_) { |
| 73 closing_ = true; | 74 closing_ = true; |
| 74 | 75 |
| 75 // Tear down the cricket session, including the cricket transport channels. | 76 // Tear down the cricket session, including the cricket transport channels. |
| 76 if (cricket_session_) { | 77 if (cricket_session_) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 165 return jid_; | 166 return jid_; |
| 166 } | 167 } |
| 167 | 168 |
| 168 const CandidateSessionConfig* JingleSession::candidate_config() { | 169 const CandidateSessionConfig* JingleSession::candidate_config() { |
| 169 DCHECK(CalledOnValidThread()); | 170 DCHECK(CalledOnValidThread()); |
| 170 DCHECK(candidate_config_.get()); | 171 DCHECK(candidate_config_.get()); |
| 171 return candidate_config_.get(); | 172 return candidate_config_.get(); |
| 172 } | 173 } |
| 173 | 174 |
| 174 void JingleSession::set_candidate_config( | 175 void JingleSession::set_candidate_config( |
| 175 const CandidateSessionConfig* candidate_config) { | 176 scoped_ptr<CandidateSessionConfig> candidate_config) { |
| 176 DCHECK(CalledOnValidThread()); | 177 DCHECK(CalledOnValidThread()); |
| 177 DCHECK(!candidate_config_.get()); | 178 DCHECK(!candidate_config_.get()); |
| 178 DCHECK(candidate_config); | 179 DCHECK(candidate_config.get()); |
| 179 candidate_config_.reset(candidate_config); | 180 candidate_config_ = candidate_config.Pass(); |
| 180 } | 181 } |
| 181 | 182 |
| 182 const SessionConfig& JingleSession::config() { | 183 const SessionConfig& JingleSession::config() { |
| 183 DCHECK(CalledOnValidThread()); | 184 DCHECK(CalledOnValidThread()); |
| 184 DCHECK(config_set_); | 185 DCHECK(config_set_); |
| 185 return config_; | 186 return config_; |
| 186 } | 187 } |
| 187 | 188 |
| 188 void JingleSession::set_config(const SessionConfig& config) { | 189 void JingleSession::set_config(const SessionConfig& config) { |
| 189 DCHECK(CalledOnValidThread()); | 190 DCHECK(CalledOnValidThread()); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 377 SetState(CONNECTING); | 378 SetState(CONNECTING); |
| 378 | 379 |
| 379 const cricket::SessionDescription* session_description = | 380 const cricket::SessionDescription* session_description = |
| 380 cricket_session_->remote_description(); | 381 cricket_session_->remote_description(); |
| 381 const cricket::ContentInfo* content = | 382 const cricket::ContentInfo* content = |
| 382 session_description->FirstContentByType(kChromotingXmlNamespace); | 383 session_description->FirstContentByType(kChromotingXmlNamespace); |
| 383 | 384 |
| 384 CHECK(content); | 385 CHECK(content); |
| 385 const ContentDescription* content_description = | 386 const ContentDescription* content_description = |
| 386 static_cast<const ContentDescription*>(content->description); | 387 static_cast<const ContentDescription*>(content->description); |
| 387 candidate_config_.reset(content_description->config()->Clone()); | 388 candidate_config_ = content_description->config()->Clone(); |
| 388 | 389 |
| 389 SessionManager::IncomingSessionResponse response = | 390 SessionManager::IncomingSessionResponse response = |
| 390 jingle_session_manager_->AcceptConnection(this); | 391 jingle_session_manager_->AcceptConnection(this); |
| 391 if (response != SessionManager::ACCEPT) { | 392 if (response != SessionManager::ACCEPT) { |
| 392 if (response == SessionManager::INCOMPATIBLE) { | 393 if (response == SessionManager::INCOMPATIBLE) { |
| 393 cricket_session_->TerminateWithReason( | 394 cricket_session_->TerminateWithReason( |
| 394 cricket::STR_TERMINATE_INCOMPATIBLE_PARAMETERS); | 395 cricket::STR_TERMINATE_INCOMPATIBLE_PARAMETERS); |
| 395 } else { | 396 } else { |
| 396 cricket_session_->TerminateWithReason(cricket::STR_TERMINATE_DECLINE); | 397 cricket_session_->TerminateWithReason(cricket::STR_TERMINATE_DECLINE); |
| 397 } | 398 } |
| 398 Close(); | 399 Close(); |
| 399 // Release session so that JingleSessionManager::SessionDestroyed() | 400 // Release session so that JingleSessionManager::SessionDestroyed() |
| 400 // doesn't try to call cricket::SessionManager::DestroySession() for it. | 401 // doesn't try to call cricket::SessionManager::DestroySession() for it. |
| 401 ReleaseSession(); | 402 ReleaseSession(); |
| 402 delete this; | 403 delete this; |
| 403 return; | 404 return; |
| 404 } | 405 } |
| 405 | 406 |
| 406 const buzz::XmlElement* auth_message = | 407 const buzz::XmlElement* auth_message = |
| 407 content_description->authenticator_message(); | 408 content_description->authenticator_message(); |
| 408 if (!auth_message) { | 409 if (!auth_message) { |
| 409 DLOG(WARNING) << "Received session-initiate without authenticator message."; | 410 DLOG(WARNING) << "Received session-initiate without authenticator message."; |
| 410 CloseInternal(net::ERR_CONNECTION_FAILED, INCOMPATIBLE_PROTOCOL); | 411 CloseInternal(net::ERR_CONNECTION_FAILED, INCOMPATIBLE_PROTOCOL); |
| 411 return; | 412 return; |
| 412 } | 413 } |
| 413 | 414 |
| 414 authenticator_.reset( | 415 authenticator_ = |
| 415 jingle_session_manager_->CreateAuthenticator(jid(), auth_message)); | 416 jingle_session_manager_->CreateAuthenticator(jid(), auth_message); |
| 416 if (!authenticator_.get()) { | 417 if (!authenticator_.get()) { |
| 417 CloseInternal(net::ERR_CONNECTION_FAILED, INCOMPATIBLE_PROTOCOL); | 418 CloseInternal(net::ERR_CONNECTION_FAILED, INCOMPATIBLE_PROTOCOL); |
| 418 return; | 419 return; |
| 419 } | 420 } |
| 420 | 421 |
| 421 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); | 422 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); |
| 422 authenticator_->ProcessMessage(auth_message); | 423 authenticator_->ProcessMessage(auth_message); |
| 423 if (authenticator_->state() == Authenticator::REJECTED) { | 424 if (authenticator_->state() == Authenticator::REJECTED) { |
| 424 CloseInternal(net::ERR_CONNECTION_FAILED, AUTHENTICATION_FAILED); | 425 CloseInternal(net::ERR_CONNECTION_FAILED, AUTHENTICATION_FAILED); |
| 425 return; | 426 return; |
| 426 } | 427 } |
| 427 | 428 |
| 428 // Connection must be configured by the AcceptConnection() callback. | 429 // Connection must be configured by the AcceptConnection() callback. |
| 429 CandidateSessionConfig* candidate_config = | 430 scoped_ptr<CandidateSessionConfig> candidate_config = |
| 430 CandidateSessionConfig::CreateFrom(config()); | 431 CandidateSessionConfig::CreateFrom(config()); |
| 431 | 432 |
| 432 buzz::XmlElement* auth_reply = NULL; | 433 scoped_ptr<buzz::XmlElement> auth_reply; |
| 433 if (authenticator_->state() == Authenticator::MESSAGE_READY) | 434 if (authenticator_->state() == Authenticator::MESSAGE_READY) |
| 434 auth_reply = authenticator_->GetNextMessage(); | 435 auth_reply = authenticator_->GetNextMessage(); |
| 435 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); | 436 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); |
| 436 cricket_session_->Accept( | 437 cricket_session_->Accept( |
| 437 CreateSessionDescription(candidate_config, auth_reply)); | 438 CreateSessionDescription(candidate_config.Pass(), |
| 439 auth_reply.Pass()).release()); | |
| 438 } | 440 } |
| 439 | 441 |
| 440 void JingleSession::ProcessAuthenticationStep() { | 442 void JingleSession::ProcessAuthenticationStep() { |
| 441 DCHECK_EQ(state_, CONNECTED); | 443 DCHECK_EQ(state_, CONNECTED); |
| 442 | 444 |
| 443 if (authenticator_->state() == Authenticator::MESSAGE_READY) { | 445 if (authenticator_->state() == Authenticator::MESSAGE_READY) { |
| 444 buzz::XmlElement* auth_message = authenticator_->GetNextMessage(); | 446 scoped_ptr<buzz::XmlElement> auth_message = |
| 447 authenticator_->GetNextMessage(); | |
| 445 cricket::XmlElements message; | 448 cricket::XmlElements message; |
| 446 message.push_back(auth_message); | 449 message.push_back(auth_message.release()); |
| 447 cricket_session_->SendInfoMessage(message); | 450 cricket_session_->SendInfoMessage(message); |
| 448 } | 451 } |
| 449 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); | 452 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); |
| 450 | 453 |
| 451 if (authenticator_->state() == Authenticator::ACCEPTED) { | 454 if (authenticator_->state() == Authenticator::ACCEPTED) { |
| 452 SetState(AUTHENTICATED); | 455 SetState(AUTHENTICATED); |
| 453 } else if (authenticator_->state() == Authenticator::REJECTED) { | 456 } else if (authenticator_->state() == Authenticator::REJECTED) { |
| 454 CloseInternal(net::ERR_CONNECTION_ABORTED, AUTHENTICATION_FAILED); | 457 CloseInternal(net::ERR_CONNECTION_ABORTED, AUTHENTICATION_FAILED); |
| 455 } | 458 } |
| 456 } | 459 } |
| 457 | 460 |
| 458 void JingleSession::AddChannelConnector( | 461 void JingleSession::AddChannelConnector( |
| 459 const std::string& name, JingleChannelConnector* connector) { | 462 const std::string& name, JingleChannelConnector* connector) { |
| 460 DCHECK(channel_connectors_.find(name) == channel_connectors_.end()); | 463 DCHECK(channel_connectors_.find(name) == channel_connectors_.end()); |
| 461 | 464 |
| 462 const std::string& content_name = GetContentInfo()->name; | 465 const std::string& content_name = GetContentInfo()->name; |
| 463 cricket::TransportChannel* raw_channel = | 466 cricket::TransportChannel* raw_channel = |
| 464 cricket_session_->CreateChannel(content_name, name); | 467 cricket_session_->CreateChannel(content_name, name); |
| 465 | 468 |
| 466 if (!jingle_session_manager_->allow_nat_traversal_ && | 469 if (!jingle_session_manager_->allow_nat_traversal_ && |
| 467 !cricket_session_->initiator()) { | 470 !cricket_session_->initiator()) { |
| 468 // Don't make outgoing connections from the host to client when | 471 // Don't make outgoing connections from the host to client when |
| 469 // NAT traversal is disabled. | 472 // NAT traversal is disabled. |
| 470 raw_channel->GetP2PChannel()->set_incoming_only(true); | 473 raw_channel->GetP2PChannel()->set_incoming_only(true); |
| 471 } | 474 } |
| 472 | 475 |
| 473 channel_connectors_[name] = connector; | 476 channel_connectors_[name] = connector; |
| 474 ChannelAuthenticator* authenticator = | 477 scoped_ptr<ChannelAuthenticator> authenticator = |
| 475 authenticator_->CreateChannelAuthenticator(); | 478 authenticator_->CreateChannelAuthenticator(); |
| 476 connector->Connect(authenticator, raw_channel); | 479 connector->Connect(authenticator.Pass(), raw_channel); |
| 477 | 480 |
| 478 // Workaround bug in libjingle - it doesn't connect channels if they | 481 // Workaround bug in libjingle - it doesn't connect channels if they |
| 479 // are created after the session is accepted. See crbug.com/89384. | 482 // are created after the session is accepted. See crbug.com/89384. |
| 480 // TODO(sergeyu): Fix the bug and remove this line. | 483 // TODO(sergeyu): Fix the bug and remove this line. |
| 481 cricket_session_->GetTransport(content_name)->ConnectChannels(); | 484 cricket_session_->GetTransport(content_name)->ConnectChannels(); |
| 482 } | 485 } |
| 483 | 486 |
| 484 void JingleSession::OnChannelConnectorFinished( | 487 void JingleSession::OnChannelConnectorFinished( |
| 485 const std::string& name, JingleChannelConnector* connector) { | 488 const std::string& name, JingleChannelConnector* connector) { |
| 486 DCHECK(CalledOnValidThread()); | 489 DCHECK(CalledOnValidThread()); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 510 DCHECK_NE(state_, CLOSED); | 513 DCHECK_NE(state_, CLOSED); |
| 511 DCHECK_NE(state_, FAILED); | 514 DCHECK_NE(state_, FAILED); |
| 512 | 515 |
| 513 state_ = new_state; | 516 state_ = new_state; |
| 514 if (!state_change_callback_.is_null()) | 517 if (!state_change_callback_.is_null()) |
| 515 state_change_callback_.Run(new_state); | 518 state_change_callback_.Run(new_state); |
| 516 } | 519 } |
| 517 } | 520 } |
| 518 | 521 |
| 519 // static | 522 // static |
| 520 cricket::SessionDescription* JingleSession::CreateSessionDescription( | 523 scoped_ptr<cricket::SessionDescription> JingleSession::CreateSessionDescription( |
| 521 const CandidateSessionConfig* config, | 524 scoped_ptr<CandidateSessionConfig> config, |
| 522 const buzz::XmlElement* authenticator_message) { | 525 scoped_ptr<buzz::XmlElement> authenticator_message) { |
| 523 cricket::SessionDescription* desc = new cricket::SessionDescription(); | 526 scoped_ptr<cricket::SessionDescription> desc( |
| 527 new cricket::SessionDescription()); | |
| 524 desc->AddContent( | 528 desc->AddContent( |
| 525 ContentDescription::kChromotingContentName, kChromotingXmlNamespace, | 529 ContentDescription::kChromotingContentName, kChromotingXmlNamespace, |
| 526 new ContentDescription(config, authenticator_message)); | 530 new ContentDescription(config.Pass(), authenticator_message.Pass())); |
| 527 return desc; | 531 return desc.Pass(); |
| 528 } | 532 } |
| 529 | 533 |
| 530 } // namespace protocol | 534 } // namespace protocol |
| 531 } // namespace remoting | 535 } // namespace remoting |
| OLD | NEW |