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 |