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 |