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 27 matching lines...) Expand all Loading... |
38 authenticator_(authenticator), | 38 authenticator_(authenticator), |
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(task_factory_(this)) { | 44 ALLOW_THIS_IN_INITIALIZER_LIST(task_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( |
| 49 this, &JingleSession::OnSessionInfoMessage); |
48 cricket_session_->SignalReceivedTerminateReason.connect( | 50 cricket_session_->SignalReceivedTerminateReason.connect( |
49 this, &JingleSession::OnTerminateReason); | 51 this, &JingleSession::OnTerminateReason); |
50 } | 52 } |
51 | 53 |
52 JingleSession::~JingleSession() { | 54 JingleSession::~JingleSession() { |
53 // Reset the callback so that it's not called from Close(). | 55 // Reset the callback so that it's not called from Close(). |
54 state_change_callback_.Reset(); | 56 state_change_callback_.Reset(); |
55 Close(); | 57 Close(); |
56 jingle_session_manager_->SessionDestroyed(this); | 58 jingle_session_manager_->SessionDestroyed(this); |
57 DCHECK(channel_connectors_.empty()); | 59 DCHECK(channel_connectors_.empty()); |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 BaseSession* session, BaseSession::Error error) { | 241 BaseSession* session, BaseSession::Error error) { |
240 DCHECK(CalledOnValidThread()); | 242 DCHECK(CalledOnValidThread()); |
241 DCHECK_EQ(cricket_session_, session); | 243 DCHECK_EQ(cricket_session_, session); |
242 | 244 |
243 if (error != cricket::Session::ERROR_NONE) { | 245 if (error != cricket::Session::ERROR_NONE) { |
244 // TODO(sergeyu): Report different errors depending on |error|. | 246 // TODO(sergeyu): Report different errors depending on |error|. |
245 CloseInternal(net::ERR_CONNECTION_ABORTED, CHANNEL_CONNECTION_ERROR); | 247 CloseInternal(net::ERR_CONNECTION_ABORTED, CHANNEL_CONNECTION_ERROR); |
246 } | 248 } |
247 } | 249 } |
248 | 250 |
| 251 void JingleSession::OnSessionInfoMessage(cricket::Session* session, |
| 252 const buzz::XmlElement* message) { |
| 253 DCHECK_EQ(cricket_session_,session); |
| 254 |
| 255 const buzz::XmlElement* auth_message = |
| 256 Authenticator::FindAuthenticatorMessage(message); |
| 257 if (auth_message) { |
| 258 if (state_ != CONNECTED || |
| 259 authenticator_->state() != Authenticator::WAITING_MESSAGE) { |
| 260 LOG(WARNING) << "Received unexpected authenticator message " |
| 261 << auth_message->Str(); |
| 262 return; |
| 263 } |
| 264 |
| 265 authenticator_->ProcessMessage(auth_message); |
| 266 ProcessAuthenticationStep(); |
| 267 } |
| 268 } |
| 269 |
249 void JingleSession::OnTerminateReason(cricket::Session* session, | 270 void JingleSession::OnTerminateReason(cricket::Session* session, |
250 const std::string& reason) { | 271 const std::string& reason) { |
251 terminate_reason_ = reason; | 272 terminate_reason_ = reason; |
252 } | 273 } |
253 | 274 |
254 void JingleSession::OnInitiate() { | 275 void JingleSession::OnInitiate() { |
255 DCHECK(CalledOnValidThread()); | 276 DCHECK(CalledOnValidThread()); |
256 jid_ = cricket_session_->remote_name(); | 277 jid_ = cricket_session_->remote_name(); |
257 | 278 |
258 if (cricket_session_->initiator()) { | 279 if (cricket_session_->initiator()) { |
(...skipping 28 matching lines...) Expand all Loading... |
287 | 308 |
288 // Process authenticator message. | 309 // Process authenticator message. |
289 const buzz::XmlElement* auth_message = | 310 const buzz::XmlElement* auth_message = |
290 content_description->authenticator_message(); | 311 content_description->authenticator_message(); |
291 if (!auth_message) { | 312 if (!auth_message) { |
292 DLOG(WARNING) << "Received session-accept without authentication message " | 313 DLOG(WARNING) << "Received session-accept without authentication message " |
293 << auth_message->Str(); | 314 << auth_message->Str(); |
294 return false; | 315 return false; |
295 } | 316 } |
296 | 317 |
297 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); | 318 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); |
298 authenticator_->ProcessMessage(auth_message); | 319 authenticator_->ProcessMessage(auth_message); |
299 // Support for more than two auth message is not implemented yet. | |
300 DCHECK(authenticator_->state() != Authenticator::WAITING_MESSAGE && | |
301 authenticator_->state() != Authenticator::MESSAGE_READY); | |
302 | 320 |
303 if (authenticator_->state() != Authenticator::ACCEPTED) { | 321 // Initialize session configuration. |
304 return false; | |
305 } | |
306 | |
307 SessionConfig config; | 322 SessionConfig config; |
308 if (!content_description->config()->GetFinalConfig(&config)) { | 323 if (!content_description->config()->GetFinalConfig(&config)) { |
309 LOG(ERROR) << "Connection response does not specify configuration"; | 324 LOG(ERROR) << "Connection response does not specify configuration"; |
310 return false; | 325 return false; |
311 } | 326 } |
312 if (!candidate_config()->IsSupported(config)) { | 327 if (!candidate_config()->IsSupported(config)) { |
313 LOG(ERROR) << "Connection response specifies an invalid configuration"; | 328 LOG(ERROR) << "Connection response specifies an invalid configuration"; |
314 return false; | 329 return false; |
315 } | 330 } |
316 | 331 |
317 set_config(config); | 332 set_config(config); |
318 return true; | 333 return true; |
319 } | 334 } |
320 | 335 |
321 void JingleSession::OnAccept() { | 336 void JingleSession::OnAccept() { |
322 DCHECK(CalledOnValidThread()); | 337 DCHECK(CalledOnValidThread()); |
323 | 338 |
324 // If we initiated the session, store the candidate configuration that the | 339 // If we initiated the session, store the candidate configuration that the |
325 // host responded with, to refer to later. | 340 // host responded with, to refer to later. |
326 if (cricket_session_->initiator()) { | 341 if (cricket_session_->initiator()) { |
327 if (!InitializeConfigFromDescription( | 342 if (!InitializeConfigFromDescription( |
328 cricket_session_->remote_description())) { | 343 cricket_session_->remote_description())) { |
329 CloseInternal(net::ERR_CONNECTION_FAILED, INCOMPATIBLE_PROTOCOL); | 344 CloseInternal(net::ERR_CONNECTION_FAILED, INCOMPATIBLE_PROTOCOL); |
330 return; | 345 return; |
331 } | 346 } |
332 } | 347 } |
333 | 348 |
334 SetState(CONNECTED); | 349 SetState(CONNECTED); |
335 | 350 |
336 if (authenticator_->state() == Authenticator::ACCEPTED) | 351 // Process authentication. |
| 352 if (authenticator_->state() == Authenticator::ACCEPTED) { |
337 SetState(AUTHENTICATED); | 353 SetState(AUTHENTICATED); |
| 354 } else { |
| 355 ProcessAuthenticationStep(); |
| 356 } |
338 } | 357 } |
339 | 358 |
340 void JingleSession::OnTerminate() { | 359 void JingleSession::OnTerminate() { |
341 DCHECK(CalledOnValidThread()); | 360 DCHECK(CalledOnValidThread()); |
342 | 361 |
343 if (terminate_reason_ == "success") { | 362 if (terminate_reason_ == "success") { |
344 CloseInternal(net::ERR_CONNECTION_ABORTED, OK); | 363 CloseInternal(net::ERR_CONNECTION_ABORTED, OK); |
345 } else if (terminate_reason_ == "decline") { | 364 } else if (terminate_reason_ == "decline") { |
346 CloseInternal(net::ERR_CONNECTION_ABORTED, AUTHENTICATION_FAILED); | 365 CloseInternal(net::ERR_CONNECTION_ABORTED, AUTHENTICATION_FAILED); |
347 } else if (terminate_reason_ == "incompatible-protocol") { | 366 } else if (terminate_reason_ == "incompatible-protocol") { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 | 410 |
392 authenticator_.reset( | 411 authenticator_.reset( |
393 jingle_session_manager_->CreateAuthenticator(jid(), auth_message)); | 412 jingle_session_manager_->CreateAuthenticator(jid(), auth_message)); |
394 if (!authenticator_.get()) { | 413 if (!authenticator_.get()) { |
395 CloseInternal(net::ERR_CONNECTION_FAILED, INCOMPATIBLE_PROTOCOL); | 414 CloseInternal(net::ERR_CONNECTION_FAILED, INCOMPATIBLE_PROTOCOL); |
396 return; | 415 return; |
397 } | 416 } |
398 | 417 |
399 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); | 418 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); |
400 authenticator_->ProcessMessage(auth_message); | 419 authenticator_->ProcessMessage(auth_message); |
401 // Support for more than two auth message is not implemented yet. | |
402 DCHECK(authenticator_->state() != Authenticator::WAITING_MESSAGE); | |
403 if (authenticator_->state() == Authenticator::REJECTED) { | 420 if (authenticator_->state() == Authenticator::REJECTED) { |
404 CloseInternal(net::ERR_CONNECTION_FAILED, AUTHENTICATION_FAILED); | 421 CloseInternal(net::ERR_CONNECTION_FAILED, AUTHENTICATION_FAILED); |
405 return; | 422 return; |
406 } | 423 } |
407 | 424 |
408 // Connection must be configured by the AcceptConnection() callback. | 425 // Connection must be configured by the AcceptConnection() callback. |
409 CandidateSessionConfig* candidate_config = | 426 CandidateSessionConfig* candidate_config = |
410 CandidateSessionConfig::CreateFrom(config()); | 427 CandidateSessionConfig::CreateFrom(config()); |
411 | 428 |
412 buzz::XmlElement* auth_reply = NULL; | 429 buzz::XmlElement* auth_reply = NULL; |
413 if (authenticator_->state() == Authenticator::MESSAGE_READY) | 430 if (authenticator_->state() == Authenticator::MESSAGE_READY) |
414 auth_reply = authenticator_->GetNextMessage(); | 431 auth_reply = authenticator_->GetNextMessage(); |
415 DCHECK_EQ(authenticator_->state(), Authenticator::ACCEPTED); | 432 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); |
416 cricket_session_->Accept( | 433 cricket_session_->Accept( |
417 CreateSessionDescription(candidate_config, auth_reply)); | 434 CreateSessionDescription(candidate_config, auth_reply)); |
418 } | 435 } |
419 | 436 |
| 437 void JingleSession::ProcessAuthenticationStep() { |
| 438 DCHECK_EQ(state_, CONNECTED); |
| 439 |
| 440 if (authenticator_->state() == Authenticator::MESSAGE_READY) { |
| 441 buzz::XmlElement* auth_message = authenticator_->GetNextMessage(); |
| 442 cricket::XmlElements message; |
| 443 message.push_back(auth_message); |
| 444 cricket_session_->SendInfoMessage(message); |
| 445 } |
| 446 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); |
| 447 |
| 448 if (authenticator_->state() == Authenticator::ACCEPTED) { |
| 449 SetState(AUTHENTICATED); |
| 450 } else if (authenticator_->state() == Authenticator::REJECTED) { |
| 451 CloseInternal(net::ERR_CONNECTION_ABORTED, AUTHENTICATION_FAILED); |
| 452 } |
| 453 } |
| 454 |
420 void JingleSession::AddChannelConnector( | 455 void JingleSession::AddChannelConnector( |
421 const std::string& name, JingleChannelConnector* connector) { | 456 const std::string& name, JingleChannelConnector* connector) { |
422 DCHECK(channel_connectors_.find(name) == channel_connectors_.end()); | 457 DCHECK(channel_connectors_.find(name) == channel_connectors_.end()); |
423 | 458 |
424 const std::string& content_name = GetContentInfo()->name; | 459 const std::string& content_name = GetContentInfo()->name; |
425 cricket::TransportChannel* raw_channel = | 460 cricket::TransportChannel* raw_channel = |
426 cricket_session_->CreateChannel(content_name, name); | 461 cricket_session_->CreateChannel(content_name, name); |
427 | 462 |
428 if (!jingle_session_manager_->allow_nat_traversal_ && | 463 if (!jingle_session_manager_->allow_nat_traversal_ && |
429 !cricket_session_->initiator()) { | 464 !cricket_session_->initiator()) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 const buzz::XmlElement* authenticator_message) { | 519 const buzz::XmlElement* authenticator_message) { |
485 cricket::SessionDescription* desc = new cricket::SessionDescription(); | 520 cricket::SessionDescription* desc = new cricket::SessionDescription(); |
486 desc->AddContent( | 521 desc->AddContent( |
487 ContentDescription::kChromotingContentName, kChromotingXmlNamespace, | 522 ContentDescription::kChromotingContentName, kChromotingXmlNamespace, |
488 new ContentDescription(config, authenticator_message)); | 523 new ContentDescription(config, authenticator_message)); |
489 return desc; | 524 return desc; |
490 } | 525 } |
491 | 526 |
492 } // namespace protocol | 527 } // namespace protocol |
493 } // namespace remoting | 528 } // namespace remoting |
OLD | NEW |