| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 DCHECK(CalledOnValidThread()); | 123 DCHECK(CalledOnValidThread()); |
| 124 DCHECK(initiate_message.description.get()); | 124 DCHECK(initiate_message.description.get()); |
| 125 DCHECK(authenticator.get()); | 125 DCHECK(authenticator.get()); |
| 126 DCHECK_EQ(authenticator->state(), Authenticator::WAITING_MESSAGE); | 126 DCHECK_EQ(authenticator->state(), Authenticator::WAITING_MESSAGE); |
| 127 | 127 |
| 128 peer_jid_ = initiate_message.from; | 128 peer_jid_ = initiate_message.from; |
| 129 authenticator_ = authenticator.Pass(); | 129 authenticator_ = authenticator.Pass(); |
| 130 session_id_ = initiate_message.sid; | 130 session_id_ = initiate_message.sid; |
| 131 candidate_config_ = initiate_message.description->config()->Clone(); | 131 candidate_config_ = initiate_message.description->config()->Clone(); |
| 132 | 132 |
| 133 SetState(CONNECTING); | 133 SetState(ACCEPTING); |
| 134 } | 134 } |
| 135 | 135 |
| 136 void JingleSession::AcceptIncomingConnection( | 136 void JingleSession::AcceptIncomingConnection( |
| 137 const JingleMessage& initiate_message) { | 137 const JingleMessage& initiate_message) { |
| 138 DCHECK(config_is_set_); | 138 DCHECK(config_is_set_); |
| 139 | 139 |
| 140 // Process the first authentication message. | 140 // Process the first authentication message. |
| 141 const buzz::XmlElement* first_auth_message = | 141 const buzz::XmlElement* first_auth_message = |
| 142 initiate_message.description->authenticator_message(); | 142 initiate_message.description->authenticator_message(); |
| 143 | 143 |
| 144 if (!first_auth_message) { | 144 if (!first_auth_message) { |
| 145 CloseInternal(INCOMPATIBLE_PROTOCOL); | 145 CloseInternal(INCOMPATIBLE_PROTOCOL); |
| 146 return; | 146 return; |
| 147 } | 147 } |
| 148 | 148 |
| 149 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); | 149 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); |
| 150 authenticator_->ProcessMessage(first_auth_message); | 150 // |this| outlives authenticator_, so using Unretained is safe here. |
| 151 authenticator_->ProcessMessage( |
| 152 base::Bind(&JingleSession::ContinueAcceptIncomingConnection, |
| 153 base::Unretained(this)), |
| 154 first_auth_message); |
| 155 } |
| 156 |
| 157 void JingleSession::ContinueAcceptIncomingConnection() { |
| 158 DCHECK_NE(authenticator_->state(), Authenticator::PROCESSING_MESSAGE); |
| 151 if (authenticator_->state() == Authenticator::REJECTED) { | 159 if (authenticator_->state() == Authenticator::REJECTED) { |
| 152 CloseInternal(AuthRejectionReasonToErrorCode( | 160 CloseInternal(AuthRejectionReasonToErrorCode( |
| 153 authenticator_->rejection_reason())); | 161 authenticator_->rejection_reason())); |
| 154 return; | 162 return; |
| 155 } | 163 } |
| 156 | 164 |
| 157 // Send the session-accept message. | 165 // Send the session-accept message. |
| 158 JingleMessage message(peer_jid_, JingleMessage::SESSION_ACCEPT, | 166 JingleMessage message(peer_jid_, JingleMessage::SESSION_ACCEPT, |
| 159 session_id_); | 167 session_id_); |
| 160 | 168 |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 | 436 |
| 429 const buzz::XmlElement* auth_message = | 437 const buzz::XmlElement* auth_message = |
| 430 message.description->authenticator_message(); | 438 message.description->authenticator_message(); |
| 431 if (!auth_message) { | 439 if (!auth_message) { |
| 432 DLOG(WARNING) << "Received session-accept without authentication message " | 440 DLOG(WARNING) << "Received session-accept without authentication message " |
| 433 << auth_message->Str(); | 441 << auth_message->Str(); |
| 434 CloseInternal(INCOMPATIBLE_PROTOCOL); | 442 CloseInternal(INCOMPATIBLE_PROTOCOL); |
| 435 return; | 443 return; |
| 436 } | 444 } |
| 437 | 445 |
| 438 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); | |
| 439 authenticator_->ProcessMessage(auth_message); | |
| 440 | |
| 441 if (!InitializeConfigFromDescription(message.description.get())) { | 446 if (!InitializeConfigFromDescription(message.description.get())) { |
| 442 CloseInternal(INCOMPATIBLE_PROTOCOL); | 447 CloseInternal(INCOMPATIBLE_PROTOCOL); |
| 443 return; | 448 return; |
| 444 } | 449 } |
| 445 | 450 |
| 446 // In case there is transport information in the accept message. | 451 // In case there is transport information in the accept message. |
| 447 ProcessTransportInfo(message); | 452 ProcessTransportInfo(message); |
| 448 | 453 |
| 449 SetState(CONNECTED); | 454 SetState(CONNECTED); |
| 450 | 455 |
| 451 // Process authentication. | 456 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); |
| 452 if (authenticator_->state() == Authenticator::ACCEPTED) { | 457 authenticator_->ProcessMessage( |
| 453 SetState(AUTHENTICATED); | 458 base::Bind(&JingleSession::ProcessAuthenticationStep, |
| 454 } else { | 459 base::Unretained(this)), |
| 455 ProcessAuthenticationStep(); | 460 auth_message); |
| 456 } | |
| 457 } | 461 } |
| 458 | 462 |
| 459 void JingleSession::OnSessionInfo(const JingleMessage& message, | 463 void JingleSession::OnSessionInfo(const JingleMessage& message, |
| 460 const ReplyCallback& reply_callback) { | 464 const ReplyCallback& reply_callback) { |
| 461 if (!message.info.get() || | 465 if (!message.info.get() || |
| 462 !Authenticator::IsAuthenticatorMessage(message.info.get())) { | 466 !Authenticator::IsAuthenticatorMessage(message.info.get())) { |
| 463 reply_callback.Run(JingleMessageReply::UNSUPPORTED_INFO); | 467 reply_callback.Run(JingleMessageReply::UNSUPPORTED_INFO); |
| 464 return; | 468 return; |
| 465 } | 469 } |
| 466 | 470 |
| 467 if (state_ != CONNECTED || | 471 if (state_ != CONNECTED || |
| 468 authenticator_->state() != Authenticator::WAITING_MESSAGE) { | 472 authenticator_->state() != Authenticator::WAITING_MESSAGE) { |
| 469 LOG(WARNING) << "Received unexpected authenticator message " | 473 LOG(WARNING) << "Received unexpected authenticator message " |
| 470 << message.info->Str(); | 474 << message.info->Str(); |
| 471 reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); | 475 reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); |
| 472 CloseInternal(INCOMPATIBLE_PROTOCOL); | 476 CloseInternal(INCOMPATIBLE_PROTOCOL); |
| 473 return; | 477 return; |
| 474 } | 478 } |
| 475 | 479 |
| 476 reply_callback.Run(JingleMessageReply::NONE); | 480 reply_callback.Run(JingleMessageReply::NONE); |
| 477 | 481 |
| 478 authenticator_->ProcessMessage(message.info.get()); | 482 authenticator_->ProcessMessage( |
| 479 ProcessAuthenticationStep(); | 483 base::Bind(&JingleSession::ProcessAuthenticationStep, |
| 484 base::Unretained(this)), |
| 485 message.info.get()); |
| 480 } | 486 } |
| 481 | 487 |
| 482 void JingleSession::ProcessTransportInfo(const JingleMessage& message) { | 488 void JingleSession::ProcessTransportInfo(const JingleMessage& message) { |
| 483 for (std::list<JingleMessage::NamedCandidate>::const_iterator it = | 489 for (std::list<JingleMessage::NamedCandidate>::const_iterator it = |
| 484 message.candidates.begin(); | 490 message.candidates.begin(); |
| 485 it != message.candidates.end(); ++it) { | 491 it != message.candidates.end(); ++it) { |
| 486 ChannelsMap::iterator channel = channels_.find(it->name); | 492 ChannelsMap::iterator channel = channels_.find(it->name); |
| 487 if (channel == channels_.end()) { | 493 if (channel == channels_.end()) { |
| 488 LOG(WARNING) << "Received candidate for unknown channel " << it->name; | 494 LOG(WARNING) << "Received candidate for unknown channel " << it->name; |
| 489 continue; | 495 continue; |
| 490 } | 496 } |
| 491 channel->second->AddRemoteCandidate(it->candidate); | 497 channel->second->AddRemoteCandidate(it->candidate); |
| 492 } | 498 } |
| 493 } | 499 } |
| 494 | 500 |
| 495 void JingleSession::OnTerminate(const JingleMessage& message, | 501 void JingleSession::OnTerminate(const JingleMessage& message, |
| 496 const ReplyCallback& reply_callback) { | 502 const ReplyCallback& reply_callback) { |
| 497 if (state_ != CONNECTING && state_ != CONNECTED && state_ != AUTHENTICATED) { | 503 if (state_ != CONNECTING && state_ != ACCEPTING && state_ != CONNECTED && |
| 504 state_ != AUTHENTICATED) { |
| 498 LOG(WARNING) << "Received unexpected session-terminate message."; | 505 LOG(WARNING) << "Received unexpected session-terminate message."; |
| 499 reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); | 506 reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); |
| 500 return; | 507 return; |
| 501 } | 508 } |
| 502 | 509 |
| 503 reply_callback.Run(JingleMessageReply::NONE); | 510 reply_callback.Run(JingleMessageReply::NONE); |
| 504 | 511 |
| 505 switch (message.reason) { | 512 switch (message.reason) { |
| 506 case JingleMessage::SUCCESS: | 513 case JingleMessage::SUCCESS: |
| 507 if (state_ == CONNECTING) { | 514 if (state_ == CONNECTING) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 543 } | 550 } |
| 544 if (!candidate_config()->IsSupported(config_)) { | 551 if (!candidate_config()->IsSupported(config_)) { |
| 545 LOG(ERROR) << "session-accept specifies an invalid configuration"; | 552 LOG(ERROR) << "session-accept specifies an invalid configuration"; |
| 546 return false; | 553 return false; |
| 547 } | 554 } |
| 548 | 555 |
| 549 return true; | 556 return true; |
| 550 } | 557 } |
| 551 | 558 |
| 552 void JingleSession::ProcessAuthenticationStep() { | 559 void JingleSession::ProcessAuthenticationStep() { |
| 560 DCHECK(CalledOnValidThread()); |
| 553 DCHECK_EQ(state_, CONNECTED); | 561 DCHECK_EQ(state_, CONNECTED); |
| 562 DCHECK_NE(authenticator_->state(), Authenticator::PROCESSING_MESSAGE); |
| 554 | 563 |
| 555 if (authenticator_->state() == Authenticator::MESSAGE_READY) { | 564 if (authenticator_->state() == Authenticator::MESSAGE_READY) { |
| 556 JingleMessage message(peer_jid_, JingleMessage::SESSION_INFO, session_id_); | 565 JingleMessage message(peer_jid_, JingleMessage::SESSION_INFO, session_id_); |
| 557 message.info = authenticator_->GetNextMessage(); | 566 message.info = authenticator_->GetNextMessage(); |
| 558 DCHECK(message.info.get()); | 567 DCHECK(message.info.get()); |
| 559 SendMessage(message); | 568 SendMessage(message); |
| 560 } | 569 } |
| 561 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); | 570 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); |
| 562 | 571 |
| 563 if (authenticator_->state() == Authenticator::ACCEPTED) { | 572 if (authenticator_->state() == Authenticator::ACCEPTED) { |
| 564 SetState(AUTHENTICATED); | 573 SetState(AUTHENTICATED); |
| 565 } else if (authenticator_->state() == Authenticator::REJECTED) { | 574 } else if (authenticator_->state() == Authenticator::REJECTED) { |
| 566 CloseInternal(AuthRejectionReasonToErrorCode( | 575 CloseInternal(AuthRejectionReasonToErrorCode( |
| 567 authenticator_->rejection_reason())); | 576 authenticator_->rejection_reason())); |
| 568 } | 577 } |
| 569 } | 578 } |
| 570 | 579 |
| 571 void JingleSession::CloseInternal(ErrorCode error) { | 580 void JingleSession::CloseInternal(ErrorCode error) { |
| 572 DCHECK(CalledOnValidThread()); | 581 DCHECK(CalledOnValidThread()); |
| 573 | 582 |
| 574 if (state_ == CONNECTING || state_ == CONNECTED || state_ == AUTHENTICATED) { | 583 if (state_ == CONNECTING || state_ == ACCEPTING || state_ == CONNECTED || |
| 584 state_ == AUTHENTICATED) { |
| 575 // Send session-terminate message with the appropriate error code. | 585 // Send session-terminate message with the appropriate error code. |
| 576 JingleMessage::Reason reason; | 586 JingleMessage::Reason reason; |
| 577 switch (error) { | 587 switch (error) { |
| 578 case OK: | 588 case OK: |
| 579 reason = JingleMessage::SUCCESS; | 589 reason = JingleMessage::SUCCESS; |
| 580 break; | 590 break; |
| 581 case SESSION_REJECTED: | 591 case SESSION_REJECTED: |
| 582 case AUTHENTICATION_FAILED: | 592 case AUTHENTICATION_FAILED: |
| 583 reason = JingleMessage::DECLINE; | 593 reason = JingleMessage::DECLINE; |
| 584 break; | 594 break; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 DCHECK_NE(state_, FAILED); | 627 DCHECK_NE(state_, FAILED); |
| 618 | 628 |
| 619 state_ = new_state; | 629 state_ = new_state; |
| 620 if (event_handler_) | 630 if (event_handler_) |
| 621 event_handler_->OnSessionStateChange(new_state); | 631 event_handler_->OnSessionStateChange(new_state); |
| 622 } | 632 } |
| 623 } | 633 } |
| 624 | 634 |
| 625 } // namespace protocol | 635 } // namespace protocol |
| 626 } // namespace remoting | 636 } // namespace remoting |
| OLD | NEW |