| 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 |