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 |