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 |