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