| 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 20 matching lines...) Expand all Loading... |
| 31 // into one transport-info messages. The value needs to be greater | 31 // into one transport-info messages. The value needs to be greater |
| 32 // than zero because ports are opened asynchronously in the browser | 32 // than zero because ports are opened asynchronously in the browser |
| 33 // process. | 33 // process. |
| 34 const int kTransportInfoSendDelayMs = 2; | 34 const int kTransportInfoSendDelayMs = 2; |
| 35 | 35 |
| 36 // How long we should wait for a response from the other end. This | 36 // How long we should wait for a response from the other end. This |
| 37 // value is used for all requests include |session-initiate| and | 37 // value is used for all requests include |session-initiate| and |
| 38 // |transport-info|. | 38 // |transport-info|. |
| 39 const int kMessageResponseTimeoutSeconds = 10; | 39 const int kMessageResponseTimeoutSeconds = 10; |
| 40 | 40 |
| 41 Session::Error AuthRejectionReasonToError( | 41 ErrorCode AuthRejectionReasonToErrorCode( |
| 42 Authenticator::RejectionReason reason) { | 42 Authenticator::RejectionReason reason) { |
| 43 switch (reason) { | 43 switch (reason) { |
| 44 case Authenticator::INVALID_CREDENTIALS: | 44 case Authenticator::INVALID_CREDENTIALS: |
| 45 return Session::AUTHENTICATION_FAILED; | 45 return AUTHENTICATION_FAILED; |
| 46 case Authenticator::PROTOCOL_ERROR: | 46 case Authenticator::PROTOCOL_ERROR: |
| 47 return Session::INCOMPATIBLE_PROTOCOL; | 47 return INCOMPATIBLE_PROTOCOL; |
| 48 } | 48 } |
| 49 NOTREACHED(); | 49 NOTREACHED(); |
| 50 return Session::UNKNOWN_ERROR; | 50 return UNKNOWN_ERROR; |
| 51 } | 51 } |
| 52 | 52 |
| 53 } // namespace | 53 } // namespace |
| 54 | 54 |
| 55 JingleSession::JingleSession(JingleSessionManager* session_manager) | 55 JingleSession::JingleSession(JingleSessionManager* session_manager) |
| 56 : session_manager_(session_manager), | 56 : session_manager_(session_manager), |
| 57 state_(INITIALIZING), | 57 state_(INITIALIZING), |
| 58 error_(OK), | 58 error_(OK), |
| 59 config_is_set_(false) { | 59 config_is_set_(false) { |
| 60 } | 60 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 72 DCHECK(!callback.is_null()); | 72 DCHECK(!callback.is_null()); |
| 73 state_change_callback_ = callback; | 73 state_change_callback_ = callback; |
| 74 } | 74 } |
| 75 | 75 |
| 76 void JingleSession::SetRouteChangeCallback( | 76 void JingleSession::SetRouteChangeCallback( |
| 77 const RouteChangeCallback& callback) { | 77 const RouteChangeCallback& callback) { |
| 78 DCHECK(CalledOnValidThread()); | 78 DCHECK(CalledOnValidThread()); |
| 79 route_change_callback_ = callback; | 79 route_change_callback_ = callback; |
| 80 } | 80 } |
| 81 | 81 |
| 82 Session::Error JingleSession::error() { | 82 ErrorCode JingleSession::error() { |
| 83 DCHECK(CalledOnValidThread()); | 83 DCHECK(CalledOnValidThread()); |
| 84 return error_; | 84 return error_; |
| 85 } | 85 } |
| 86 | 86 |
| 87 void JingleSession::StartConnection( | 87 void JingleSession::StartConnection( |
| 88 const std::string& peer_jid, | 88 const std::string& peer_jid, |
| 89 scoped_ptr<Authenticator> authenticator, | 89 scoped_ptr<Authenticator> authenticator, |
| 90 scoped_ptr<CandidateSessionConfig> config, | 90 scoped_ptr<CandidateSessionConfig> config, |
| 91 const StateChangeCallback& state_change_callback) { | 91 const StateChangeCallback& state_change_callback) { |
| 92 DCHECK(CalledOnValidThread()); | 92 DCHECK(CalledOnValidThread()); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 initiate_message.description->authenticator_message(); | 141 initiate_message.description->authenticator_message(); |
| 142 | 142 |
| 143 if (!first_auth_message) { | 143 if (!first_auth_message) { |
| 144 CloseInternal(INCOMPATIBLE_PROTOCOL); | 144 CloseInternal(INCOMPATIBLE_PROTOCOL); |
| 145 return; | 145 return; |
| 146 } | 146 } |
| 147 | 147 |
| 148 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); | 148 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); |
| 149 authenticator_->ProcessMessage(first_auth_message); | 149 authenticator_->ProcessMessage(first_auth_message); |
| 150 if (authenticator_->state() == Authenticator::REJECTED) { | 150 if (authenticator_->state() == Authenticator::REJECTED) { |
| 151 CloseInternal(AuthRejectionReasonToError( | 151 CloseInternal(AuthRejectionReasonToErrorCode( |
| 152 authenticator_->rejection_reason())); | 152 authenticator_->rejection_reason())); |
| 153 return; | 153 return; |
| 154 } | 154 } |
| 155 | 155 |
| 156 // Send the session-accept message. | 156 // Send the session-accept message. |
| 157 JingleMessage message(peer_jid_, JingleMessage::SESSION_ACCEPT, | 157 JingleMessage message(peer_jid_, JingleMessage::SESSION_ACCEPT, |
| 158 session_id_); | 158 session_id_); |
| 159 | 159 |
| 160 scoped_ptr<buzz::XmlElement> auth_message; | 160 scoped_ptr<buzz::XmlElement> auth_message; |
| 161 if (authenticator_->state() == Authenticator::MESSAGE_READY) | 161 if (authenticator_->state() == Authenticator::MESSAGE_READY) |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 } else { | 283 } else { |
| 284 LOG(ERROR) << "Failed to send a " | 284 LOG(ERROR) << "Failed to send a " |
| 285 << JingleMessage::GetActionName(message.action) << " message"; | 285 << JingleMessage::GetActionName(message.action) << " message"; |
| 286 } | 286 } |
| 287 } | 287 } |
| 288 | 288 |
| 289 void JingleSession::OnMessageResponse( | 289 void JingleSession::OnMessageResponse( |
| 290 JingleMessage::ActionType request_type, | 290 JingleMessage::ActionType request_type, |
| 291 IqRequest* request, | 291 IqRequest* request, |
| 292 const buzz::XmlElement* response) { | 292 const buzz::XmlElement* response) { |
| 293 Error error = OK; | |
| 294 | |
| 295 std::string type_str = JingleMessage::GetActionName(request_type); | 293 std::string type_str = JingleMessage::GetActionName(request_type); |
| 294 CleanupPendingRequests(request); |
| 296 | 295 |
| 297 if (!response) { | 296 if (!response) { |
| 298 LOG(ERROR) << type_str << " request timed out."; | 297 LOG(ERROR) << type_str << " request timed out."; |
| 299 // Most likely the session-initiate timeout indicates a problem | 298 CloseInternal(SIGNALING_TIMEOUT); |
| 300 // with the signaling. | |
| 301 error = UNKNOWN_ERROR; | |
| 302 } else { | 299 } else { |
| 303 const std::string& type = response->Attr(buzz::QName("", "type")); | 300 const std::string& type = response->Attr(buzz::QName("", "type")); |
| 304 if (type != "result") { | 301 if (type != "result") { |
| 305 LOG(ERROR) << "Received error in response to " << type_str | 302 LOG(ERROR) << "Received error in response to " << type_str |
| 306 << " message: \"" << response->Str() | 303 << " message: \"" << response->Str() |
| 307 << "\". Terminating the session."; | 304 << "\". Terminating the session."; |
| 308 | 305 |
| 309 switch (request_type) { | 306 switch (request_type) { |
| 310 case JingleMessage::SESSION_INFO: | 307 case JingleMessage::SESSION_INFO: |
| 311 // session-info is used for the new authentication protocol, | 308 // session-info is used for the new authentication protocol, |
| 312 // and wasn't previously supported. | 309 // and wasn't previously supported. |
| 313 error = INCOMPATIBLE_PROTOCOL; | 310 CloseInternal(INCOMPATIBLE_PROTOCOL); |
| 311 break; |
| 314 | 312 |
| 315 default: | 313 default: |
| 316 // TODO(sergeyu): There may be different reasons for error | 314 // TODO(sergeyu): There may be different reasons for error |
| 317 // here. Parse the response stanza to find failure reason. | 315 // here. Parse the response stanza to find failure reason. |
| 318 error = PEER_IS_OFFLINE; | 316 CloseInternal(PEER_IS_OFFLINE); |
| 319 } | 317 } |
| 320 } | 318 } |
| 321 } | 319 } |
| 322 | |
| 323 CleanupPendingRequests(request); | |
| 324 | |
| 325 if (error != OK) { | |
| 326 CloseInternal(error); | |
| 327 } | |
| 328 } | 320 } |
| 329 | 321 |
| 330 void JingleSession::CleanupPendingRequests(IqRequest* request) { | 322 void JingleSession::CleanupPendingRequests(IqRequest* request) { |
| 331 DCHECK(!pending_requests_.empty()); | 323 DCHECK(!pending_requests_.empty()); |
| 332 DCHECK(request); | 324 DCHECK(request); |
| 333 | 325 |
| 334 // This method is called whenever a response to |request| is | 326 // This method is called whenever a response to |request| is |
| 335 // received. Here we delete that request and all requests that were | 327 // received. Here we delete that request and all requests that were |
| 336 // sent before it. The idea here is that if we send messages A, B | 328 // sent before it. The idea here is that if we send messages A, B |
| 337 // and C and then suddenly receive response to C then it means that | 329 // and C and then suddenly receive response to C then it means that |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 JingleMessage message(peer_jid_, JingleMessage::SESSION_INFO, session_id_); | 513 JingleMessage message(peer_jid_, JingleMessage::SESSION_INFO, session_id_); |
| 522 message.info = authenticator_->GetNextMessage(); | 514 message.info = authenticator_->GetNextMessage(); |
| 523 DCHECK(message.info.get()); | 515 DCHECK(message.info.get()); |
| 524 SendMessage(message); | 516 SendMessage(message); |
| 525 } | 517 } |
| 526 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); | 518 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); |
| 527 | 519 |
| 528 if (authenticator_->state() == Authenticator::ACCEPTED) { | 520 if (authenticator_->state() == Authenticator::ACCEPTED) { |
| 529 SetState(AUTHENTICATED); | 521 SetState(AUTHENTICATED); |
| 530 } else if (authenticator_->state() == Authenticator::REJECTED) { | 522 } else if (authenticator_->state() == Authenticator::REJECTED) { |
| 531 CloseInternal(AuthRejectionReasonToError( | 523 CloseInternal(AuthRejectionReasonToErrorCode( |
| 532 authenticator_->rejection_reason())); | 524 authenticator_->rejection_reason())); |
| 533 } | 525 } |
| 534 } | 526 } |
| 535 | 527 |
| 536 void JingleSession::SendTransportInfo() { | 528 void JingleSession::SendTransportInfo() { |
| 537 JingleMessage message(peer_jid_, JingleMessage::TRANSPORT_INFO, session_id_); | 529 JingleMessage message(peer_jid_, JingleMessage::TRANSPORT_INFO, session_id_); |
| 538 message.candidates.swap(pending_candidates_); | 530 message.candidates.swap(pending_candidates_); |
| 539 SendMessage(message); | 531 SendMessage(message); |
| 540 } | 532 } |
| 541 | 533 |
| 542 void JingleSession::CloseInternal(Error error) { | 534 void JingleSession::CloseInternal(ErrorCode error) { |
| 543 DCHECK(CalledOnValidThread()); | 535 DCHECK(CalledOnValidThread()); |
| 544 | 536 |
| 545 if (state_ == CONNECTING || state_ == CONNECTED || state_ == AUTHENTICATED) { | 537 if (state_ == CONNECTING || state_ == CONNECTED || state_ == AUTHENTICATED) { |
| 546 // Send session-terminate message with the appropriate error code. | 538 // Send session-terminate message with the appropriate error code. |
| 547 JingleMessage::Reason reason; | 539 JingleMessage::Reason reason; |
| 548 switch (error) { | 540 switch (error) { |
| 549 case OK: | 541 case OK: |
| 550 reason = JingleMessage::SUCCESS; | 542 reason = JingleMessage::SUCCESS; |
| 551 break; | 543 break; |
| 552 case SESSION_REJECTED: | 544 case SESSION_REJECTED: |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 DCHECK_NE(state_, FAILED); | 577 DCHECK_NE(state_, FAILED); |
| 586 | 578 |
| 587 state_ = new_state; | 579 state_ = new_state; |
| 588 if (!state_change_callback_.is_null()) | 580 if (!state_change_callback_.is_null()) |
| 589 state_change_callback_.Run(new_state); | 581 state_change_callback_.Run(new_state); |
| 590 } | 582 } |
| 591 } | 583 } |
| 592 | 584 |
| 593 } // namespace protocol | 585 } // namespace protocol |
| 594 } // namespace remoting | 586 } // namespace remoting |
| OLD | NEW |