Chromium Code Reviews| 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 } | 50 } |
| 49 | 51 |
| 50 JingleSession::~JingleSession() { | 52 JingleSession::~JingleSession() { |
| 51 // Reset the callback so that it's not called from Close(). | 53 // Reset the callback so that it's not called from Close(). |
| 52 state_change_callback_.Reset(); | 54 state_change_callback_.Reset(); |
| 53 Close(); | 55 Close(); |
| 54 jingle_session_manager_->SessionDestroyed(this); | 56 jingle_session_manager_->SessionDestroyed(this); |
| 55 DCHECK(channel_connectors_.empty()); | 57 DCHECK(channel_connectors_.empty()); |
| 56 } | 58 } |
| 57 | 59 |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 237 BaseSession* session, BaseSession::Error error) { | 239 BaseSession* session, BaseSession::Error error) { |
| 238 DCHECK(CalledOnValidThread()); | 240 DCHECK(CalledOnValidThread()); |
| 239 DCHECK_EQ(cricket_session_, session); | 241 DCHECK_EQ(cricket_session_, session); |
| 240 | 242 |
| 241 if (error != cricket::Session::ERROR_NONE) { | 243 if (error != cricket::Session::ERROR_NONE) { |
| 242 // TODO(sergeyu): Report different errors depending on |error|. | 244 // TODO(sergeyu): Report different errors depending on |error|. |
| 243 CloseInternal(net::ERR_CONNECTION_ABORTED, CHANNEL_CONNECTION_ERROR); | 245 CloseInternal(net::ERR_CONNECTION_ABORTED, CHANNEL_CONNECTION_ERROR); |
| 244 } | 246 } |
| 245 } | 247 } |
| 246 | 248 |
| 249 void JingleSession::OnSessionInfoMessage(cricket::Session* session, | |
| 250 const buzz::XmlElement* message) { | |
| 251 DCHECK_EQ(cricket_session_,session); | |
| 252 | |
| 253 const buzz::XmlElement* auth_message = | |
| 254 Authenticator::FindAuthenticatorMessage(message); | |
| 255 if (auth_message) { | |
| 256 if (state_ != CONNECTED || | |
|
Wez
2011/12/03 00:21:05
It might be clearer to have AUTHENTICATING and CON
Sergey Ulanov
2011/12/06 19:37:07
I agree, but it is not related to this CL.
| |
| 257 authenticator_->state() != Authenticator::WAITING_MESSAGE) { | |
| 258 LOG(WARNING) << "Received unexpected authenticator message " | |
| 259 << auth_message->Str(); | |
| 260 return; | |
| 261 } | |
| 262 | |
| 263 authenticator_->ProcessMessage(auth_message); | |
| 264 ProcessAuthenticationStep(); | |
| 265 } | |
| 266 } | |
| 267 | |
| 247 void JingleSession::OnInitiate() { | 268 void JingleSession::OnInitiate() { |
| 248 DCHECK(CalledOnValidThread()); | 269 DCHECK(CalledOnValidThread()); |
| 249 jid_ = cricket_session_->remote_name(); | 270 jid_ = cricket_session_->remote_name(); |
| 250 | 271 |
| 251 if (cricket_session_->initiator()) { | 272 if (cricket_session_->initiator()) { |
| 252 // Set state to CONNECTING if this is an outgoing message. We need | 273 // Set state to CONNECTING if this is an outgoing message. We need |
| 253 // to post this task because channel creation works only after we | 274 // to post this task because channel creation works only after we |
| 254 // return from this method. This is because | 275 // return from this method. This is because |
| 255 // JingleChannelConnector::Connect() needs to call | 276 // JingleChannelConnector::Connect() needs to call |
| 256 // set_incoming_only() on P2PTransportChannel, but | 277 // set_incoming_only() on P2PTransportChannel, but |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 280 | 301 |
| 281 // Process authenticator message. | 302 // Process authenticator message. |
| 282 const buzz::XmlElement* auth_message = | 303 const buzz::XmlElement* auth_message = |
| 283 content_description->authenticator_message(); | 304 content_description->authenticator_message(); |
| 284 if (!auth_message) { | 305 if (!auth_message) { |
| 285 DLOG(WARNING) << "Received session-accept without authentication message " | 306 DLOG(WARNING) << "Received session-accept without authentication message " |
| 286 << auth_message->Str(); | 307 << auth_message->Str(); |
| 287 return false; | 308 return false; |
| 288 } | 309 } |
| 289 | 310 |
| 290 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); | 311 DCHECK_EQ(authenticator_->state(), Authenticator::WAITING_MESSAGE); |
| 291 authenticator_->ProcessMessage(auth_message); | 312 authenticator_->ProcessMessage(auth_message); |
| 292 // Support for more than two auth message is not implemented yet. | |
| 293 DCHECK(authenticator_->state() != Authenticator::WAITING_MESSAGE && | |
| 294 authenticator_->state() != Authenticator::MESSAGE_READY); | |
| 295 | 313 |
| 296 if (authenticator_->state() != Authenticator::ACCEPTED) { | 314 // Initialize session configuration. |
| 297 return false; | |
| 298 } | |
| 299 | |
| 300 SessionConfig config; | 315 SessionConfig config; |
| 301 if (!content_description->config()->GetFinalConfig(&config)) { | 316 if (!content_description->config()->GetFinalConfig(&config)) { |
| 302 LOG(ERROR) << "Connection response does not specify configuration"; | 317 LOG(ERROR) << "Connection response does not specify configuration"; |
| 303 return false; | 318 return false; |
| 304 } | 319 } |
| 305 if (!candidate_config()->IsSupported(config)) { | 320 if (!candidate_config()->IsSupported(config)) { |
| 306 LOG(ERROR) << "Connection response specifies an invalid configuration"; | 321 LOG(ERROR) << "Connection response specifies an invalid configuration"; |
| 307 return false; | 322 return false; |
| 308 } | 323 } |
| 309 | 324 |
| 310 set_config(config); | 325 set_config(config); |
| 311 return true; | 326 return true; |
| 312 } | 327 } |
| 313 | 328 |
| 314 void JingleSession::OnAccept() { | 329 void JingleSession::OnAccept() { |
| 315 DCHECK(CalledOnValidThread()); | 330 DCHECK(CalledOnValidThread()); |
| 316 | 331 |
| 317 // If we initiated the session, store the candidate configuration that the | 332 // If we initiated the session, store the candidate configuration that the |
| 318 // host responded with, to refer to later. | 333 // host responded with, to refer to later. |
| 319 if (cricket_session_->initiator()) { | 334 if (cricket_session_->initiator()) { |
| 320 if (!InitializeConfigFromDescription( | 335 if (!InitializeConfigFromDescription( |
| 321 cricket_session_->remote_description())) { | 336 cricket_session_->remote_description())) { |
| 322 CloseInternal(net::ERR_CONNECTION_FAILED, INCOMPATIBLE_PROTOCOL); | 337 CloseInternal(net::ERR_CONNECTION_FAILED, INCOMPATIBLE_PROTOCOL); |
| 323 return; | 338 return; |
| 324 } | 339 } |
| 325 } | 340 } |
| 326 | 341 |
| 327 SetState(CONNECTED); | 342 SetState(CONNECTED); |
| 328 | 343 |
| 329 if (authenticator_->state() == Authenticator::ACCEPTED) | 344 // Process authentication. |
| 345 if (authenticator_->state() == Authenticator::ACCEPTED) { | |
| 330 SetState(AUTHENTICATED); | 346 SetState(AUTHENTICATED); |
| 347 } else { | |
| 348 ProcessAuthenticationStep(); | |
| 349 } | |
| 331 } | 350 } |
| 332 | 351 |
| 333 void JingleSession::OnTerminate() { | 352 void JingleSession::OnTerminate() { |
| 334 DCHECK(CalledOnValidThread()); | 353 DCHECK(CalledOnValidThread()); |
| 335 CloseInternal(net::ERR_CONNECTION_ABORTED, OK); | 354 CloseInternal(net::ERR_CONNECTION_ABORTED, OK); |
| 336 } | 355 } |
| 337 | 356 |
| 338 void JingleSession::AcceptConnection() { | 357 void JingleSession::AcceptConnection() { |
| 339 SetState(CONNECTING); | 358 SetState(CONNECTING); |
| 340 | 359 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 375 | 394 |
| 376 authenticator_.reset( | 395 authenticator_.reset( |
| 377 jingle_session_manager_->CreateAuthenticator(jid(), auth_message)); | 396 jingle_session_manager_->CreateAuthenticator(jid(), auth_message)); |
| 378 if (!authenticator_.get()) { | 397 if (!authenticator_.get()) { |
| 379 CloseInternal(net::ERR_CONNECTION_FAILED, INCOMPATIBLE_PROTOCOL); | 398 CloseInternal(net::ERR_CONNECTION_FAILED, INCOMPATIBLE_PROTOCOL); |
| 380 return; | 399 return; |
| 381 } | 400 } |
| 382 | 401 |
| 383 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); | 402 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); |
| 384 authenticator_->ProcessMessage(auth_message); | 403 authenticator_->ProcessMessage(auth_message); |
| 385 // Support for more than two auth message is not implemented yet. | |
| 386 DCHECK(authenticator_->state() != Authenticator::WAITING_MESSAGE); | |
| 387 if (authenticator_->state() == Authenticator::REJECTED) { | 404 if (authenticator_->state() == Authenticator::REJECTED) { |
| 388 CloseInternal(net::ERR_CONNECTION_FAILED, AUTHENTICATION_FAILED); | 405 CloseInternal(net::ERR_CONNECTION_FAILED, AUTHENTICATION_FAILED); |
| 389 return; | 406 return; |
| 390 } | 407 } |
| 391 | 408 |
| 392 // Connection must be configured by the AcceptConnection() callback. | 409 // Connection must be configured by the AcceptConnection() callback. |
| 393 CandidateSessionConfig* candidate_config = | 410 CandidateSessionConfig* candidate_config = |
| 394 CandidateSessionConfig::CreateFrom(config()); | 411 CandidateSessionConfig::CreateFrom(config()); |
| 395 | 412 |
| 396 buzz::XmlElement* auth_reply = NULL; | 413 buzz::XmlElement* auth_reply = NULL; |
| 397 if (authenticator_->state() == Authenticator::MESSAGE_READY) | 414 if (authenticator_->state() == Authenticator::MESSAGE_READY) |
| 398 auth_reply = authenticator_->GetNextMessage(); | 415 auth_reply = authenticator_->GetNextMessage(); |
| 399 DCHECK_EQ(authenticator_->state(), Authenticator::ACCEPTED); | 416 DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); |
| 400 cricket_session_->Accept( | 417 cricket_session_->Accept( |
| 401 CreateSessionDescription(candidate_config, auth_reply)); | 418 CreateSessionDescription(candidate_config, auth_reply)); |
| 402 } | 419 } |
| 403 | 420 |
| 421 void JingleSession::ProcessAuthenticationStep() { | |
| 422 DCHECK_EQ(state_, CONNECTED); | |
| 423 | |
| 424 while (authenticator_->state() == Authenticator::MESSAGE_READY) { | |
| 425 buzz::XmlElement* auth_message = authenticator_->GetNextMessage(); | |
| 426 cricket::XmlElements message; | |
| 427 message.push_back(auth_message); | |
| 428 cricket_session_->SendInfoMessage(message); | |
| 429 } | |
| 430 | |
| 431 if (authenticator_->state() == Authenticator::ACCEPTED) { | |
| 432 SetState(AUTHENTICATED); | |
| 433 } else if (authenticator_->state() == Authenticator::REJECTED) { | |
| 434 CloseInternal(net::ERR_CONNECTION_ABORTED, AUTHENTICATION_FAILED); | |
| 435 } | |
| 436 } | |
| 437 | |
| 404 void JingleSession::AddChannelConnector( | 438 void JingleSession::AddChannelConnector( |
| 405 const std::string& name, JingleChannelConnector* connector) { | 439 const std::string& name, JingleChannelConnector* connector) { |
| 406 DCHECK(channel_connectors_.find(name) == channel_connectors_.end()); | 440 DCHECK(channel_connectors_.find(name) == channel_connectors_.end()); |
| 407 | 441 |
| 408 const std::string& content_name = GetContentInfo()->name; | 442 const std::string& content_name = GetContentInfo()->name; |
| 409 cricket::TransportChannel* raw_channel = | 443 cricket::TransportChannel* raw_channel = |
| 410 cricket_session_->CreateChannel(content_name, name); | 444 cricket_session_->CreateChannel(content_name, name); |
| 411 | 445 |
| 412 if (!jingle_session_manager_->allow_nat_traversal_ && | 446 if (!jingle_session_manager_->allow_nat_traversal_ && |
| 413 !cricket_session_->initiator()) { | 447 !cricket_session_->initiator()) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 468 const buzz::XmlElement* authenticator_message) { | 502 const buzz::XmlElement* authenticator_message) { |
| 469 cricket::SessionDescription* desc = new cricket::SessionDescription(); | 503 cricket::SessionDescription* desc = new cricket::SessionDescription(); |
| 470 desc->AddContent( | 504 desc->AddContent( |
| 471 ContentDescription::kChromotingContentName, kChromotingXmlNamespace, | 505 ContentDescription::kChromotingContentName, kChromotingXmlNamespace, |
| 472 new ContentDescription(config, authenticator_message)); | 506 new ContentDescription(config, authenticator_message)); |
| 473 return desc; | 507 return desc; |
| 474 } | 508 } |
| 475 | 509 |
| 476 } // namespace protocol | 510 } // namespace protocol |
| 477 } // namespace remoting | 511 } // namespace remoting |
| OLD | NEW |