Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(517)

Side by Side Diff: remoting/host/it2me/it2me_host.cc

Issue 1458323002: Simplify It2Me host shutdown (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « remoting/host/it2me/it2me_host.h ('k') | remoting/host/it2me/it2me_native_messaging_host.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/host/it2me/it2me_host.h" 5 #include "remoting/host/it2me/it2me_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback_helpers.h" 8 #include "base/callback_helpers.h"
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "base/threading/platform_thread.h" 10 #include "base/threading/platform_thread.h"
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 policy_watcher_->StartWatching( 75 policy_watcher_->StartWatching(
76 base::Bind(&It2MeHost::OnPolicyUpdate, this), 76 base::Bind(&It2MeHost::OnPolicyUpdate, this),
77 base::Bind(&It2MeHost::OnPolicyError, this)); 77 base::Bind(&It2MeHost::OnPolicyError, this));
78 78
79 // Switch to the network thread to start the actual connection. 79 // Switch to the network thread to start the actual connection.
80 host_context_->network_task_runner()->PostTask( 80 host_context_->network_task_runner()->PostTask(
81 FROM_HERE, base::Bind(&It2MeHost::ShowConfirmationPrompt, this)); 81 FROM_HERE, base::Bind(&It2MeHost::ShowConfirmationPrompt, this));
82 } 82 }
83 83
84 void It2MeHost::Disconnect() { 84 void It2MeHost::Disconnect() {
85 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { 85 DCHECK(task_runner_->BelongsToCurrentThread());
86 DCHECK(task_runner_->BelongsToCurrentThread()); 86 host_context_->network_task_runner()->PostTask(
87 host_context_->network_task_runner()->PostTask( 87 FROM_HERE, base::Bind(&It2MeHost::Shutdown, this));
88 FROM_HERE, base::Bind(&It2MeHost::Disconnect, this)); 88 }
89 return; 89
90 void It2MeHost::Shutdown() {
91 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread());
92
93 confirmation_dialog_proxy_.reset();
94
95 host_event_logger_.reset();
96 if (host_) {
97 host_->RemoveStatusObserver(this);
98 host_.reset();
90 } 99 }
91 100
92 switch (state_) { 101 register_request_.reset();
93 case kDisconnected: 102 host_status_logger_.reset();
94 ShutdownOnNetworkThread(); 103 signal_strategy_.reset();
95 return;
96 104
97 case kStarting: 105 // Post tasks to delete UI objects on the UI thread.
98 SetState(kDisconnecting, ""); 106 host_context_->ui_task_runner()->DeleteSoon(
99 SetState(kDisconnected, ""); 107 FROM_HERE, desktop_environment_factory_.release());
100 ShutdownOnNetworkThread(); 108 host_context_->ui_task_runner()->DeleteSoon(FROM_HERE,
101 return; 109 policy_watcher_.release());
102 110
103 case kDisconnecting: 111 SetState(kDisconnected, "");
104 return;
105
106 default:
107 SetState(kDisconnecting, "");
108
109 if (!host_) {
110 SetState(kDisconnected, "");
111 ShutdownOnNetworkThread();
112 return;
113 }
114
115 // Deleting the host destroys SignalStrategy synchronously, but
116 // SignalStrategy::Listener handlers are not allowed to destroy
117 // SignalStrategy, so post task to destroy the host later.
118 host_context_->network_task_runner()->PostTask(
119 FROM_HERE, base::Bind(&It2MeHost::ShutdownOnNetworkThread, this));
120 return;
121 }
122 } 112 }
123 113
124 void It2MeHost::RequestNatPolicy() { 114 void It2MeHost::RequestNatPolicy() {
125 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { 115 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) {
126 DCHECK(task_runner_->BelongsToCurrentThread()); 116 DCHECK(task_runner_->BelongsToCurrentThread());
127 host_context_->network_task_runner()->PostTask( 117 host_context_->network_task_runner()->PostTask(
128 FROM_HERE, base::Bind(&It2MeHost::RequestNatPolicy, this)); 118 FROM_HERE, base::Bind(&It2MeHost::RequestNatPolicy, this));
129 return; 119 return;
130 } 120 }
131 121
(...skipping 23 matching lines...) Expand all
155 base::Bind(&It2MeHost::OnConfirmationResult, base::Unretained(this))); 145 base::Bind(&It2MeHost::OnConfirmationResult, base::Unretained(this)));
156 } 146 }
157 147
158 void It2MeHost::OnConfirmationResult(It2MeConfirmationDialog::Result result) { 148 void It2MeHost::OnConfirmationResult(It2MeConfirmationDialog::Result result) {
159 switch (result) { 149 switch (result) {
160 case It2MeConfirmationDialog::Result::OK: 150 case It2MeConfirmationDialog::Result::OK:
161 ReadPolicyAndConnect(); 151 ReadPolicyAndConnect();
162 break; 152 break;
163 153
164 case It2MeConfirmationDialog::Result::CANCEL: 154 case It2MeConfirmationDialog::Result::CANCEL:
165 Disconnect(); 155 Shutdown();
166 break; 156 break;
167 157
168 default: 158 default:
169 NOTREACHED(); 159 NOTREACHED();
170 return; 160 return;
171 } 161 }
172 } 162 }
173 163
174 void It2MeHost::ReadPolicyAndConnect() { 164 void It2MeHost::ReadPolicyAndConnect() {
175 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); 165 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread());
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 HostEventLogger::Create(host_->AsWeakPtr(), kApplicationName); 255 HostEventLogger::Create(host_->AsWeakPtr(), kApplicationName);
266 256
267 // Connect signaling and start the host. 257 // Connect signaling and start the host.
268 signal_strategy_->Connect(); 258 signal_strategy_->Connect();
269 host_->Start(xmpp_server_config_.username); 259 host_->Start(xmpp_server_config_.username);
270 260
271 SetState(kRequestedAccessCode, ""); 261 SetState(kRequestedAccessCode, "");
272 return; 262 return;
273 } 263 }
274 264
275 void It2MeHost::ShutdownOnNetworkThread() {
276 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread());
277 DCHECK(state_ == kDisconnecting || state_ == kDisconnected);
278
279 confirmation_dialog_proxy_.reset();
280
281 if (state_ == kDisconnecting) {
282 host_event_logger_.reset();
283 host_->RemoveStatusObserver(this);
284 host_.reset();
285
286 register_request_.reset();
287 host_status_logger_.reset();
288 signal_strategy_.reset();
289 SetState(kDisconnected, "");
290 }
291
292 host_context_->ui_task_runner()->PostTask(
293 FROM_HERE, base::Bind(&It2MeHost::ShutdownOnUiThread, this));
294 }
295
296 void It2MeHost::ShutdownOnUiThread() {
297 DCHECK(host_context_->ui_task_runner()->BelongsToCurrentThread());
298
299 // Destroy the DesktopEnvironmentFactory, to free thread references.
300 desktop_environment_factory_.reset();
301
302 // Stop listening for policy updates.
303 policy_watcher_.reset();
304 }
305
306 void It2MeHost::OnAccessDenied(const std::string& jid) { 265 void It2MeHost::OnAccessDenied(const std::string& jid) {
307 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); 266 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread());
308 267
309 ++failed_login_attempts_; 268 ++failed_login_attempts_;
310 if (failed_login_attempts_ == kMaxLoginAttempts) { 269 if (failed_login_attempts_ == kMaxLoginAttempts) {
311 Disconnect(); 270 Shutdown();
312 } 271 }
313 } 272 }
314 273
315 void It2MeHost::OnClientAuthenticated(const std::string& jid) { 274 void It2MeHost::OnClientConnected(const std::string& jid) {
316 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); 275 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread());
317 276
318 if (state_ == kDisconnecting) { 277 // ChromotingHost doesn't allow multiple concurrent connection and the
319 // Ignore the new connection if we are disconnecting. 278 // host is destroyed in OnClientDisconnected() after the first connection.
320 return; 279 CHECK_NE(state_, kConnected);
321 }
322 if (state_ == kConnected) {
323 // If we already connected another client then one of the connections may be
324 // an attacker, so both are suspect and we have to reject the second
325 // connection and shutdown the host.
326 host_->RejectAuthenticatingClient();
327 Disconnect();
328 return;
329 }
330 280
331 std::string client_username = jid; 281 std::string client_username = jid;
332 size_t pos = client_username.find('/'); 282 size_t pos = client_username.find('/');
333 if (pos != std::string::npos) 283 if (pos != std::string::npos)
334 client_username.replace(pos, std::string::npos, ""); 284 client_username.replace(pos, std::string::npos, "");
335 285
336 HOST_LOG << "Client " << client_username << " connected."; 286 HOST_LOG << "Client " << client_username << " connected.";
337 287
338 // Pass the client user name to the script object before changing state. 288 // Pass the client user name to the script object before changing state.
339 task_runner_->PostTask( 289 task_runner_->PostTask(
340 FROM_HERE, base::Bind(&It2MeHost::Observer::OnClientAuthenticated, 290 FROM_HERE, base::Bind(&It2MeHost::Observer::OnClientAuthenticated,
341 observer_, client_username)); 291 observer_, client_username));
342 292
343 SetState(kConnected, ""); 293 SetState(kConnected, "");
344 } 294 }
345 295
346 void It2MeHost::OnClientDisconnected(const std::string& jid) { 296 void It2MeHost::OnClientDisconnected(const std::string& jid) {
347 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); 297 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread());
348 298
349 Disconnect(); 299 Shutdown();
350 } 300 }
351 301
352 void It2MeHost::OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies) { 302 void It2MeHost::OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies) {
353 // The policy watcher runs on the |ui_task_runner|. 303 // The policy watcher runs on the |ui_task_runner|.
354 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) { 304 if (!host_context_->network_task_runner()->BelongsToCurrentThread()) {
355 host_context_->network_task_runner()->PostTask( 305 host_context_->network_task_runner()->PostTask(
356 FROM_HERE, 306 FROM_HERE,
357 base::Bind(&It2MeHost::OnPolicyUpdate, this, base::Passed(&policies))); 307 base::Bind(&It2MeHost::OnPolicyUpdate, this, base::Passed(&policies)));
358 return; 308 return;
359 } 309 }
(...skipping 21 matching lines...) Expand all
381 } 331 }
382 332
383 void It2MeHost::UpdateNatPolicy(bool nat_traversal_enabled) { 333 void It2MeHost::UpdateNatPolicy(bool nat_traversal_enabled) {
384 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); 334 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread());
385 335
386 VLOG(2) << "UpdateNatPolicy: " << nat_traversal_enabled; 336 VLOG(2) << "UpdateNatPolicy: " << nat_traversal_enabled;
387 337
388 // When transitioning from enabled to disabled, force disconnect any 338 // When transitioning from enabled to disabled, force disconnect any
389 // existing session. 339 // existing session.
390 if (nat_traversal_enabled_ && !nat_traversal_enabled && IsConnected()) { 340 if (nat_traversal_enabled_ && !nat_traversal_enabled && IsConnected()) {
391 Disconnect(); 341 Shutdown();
392 } 342 }
393 343
394 nat_traversal_enabled_ = nat_traversal_enabled; 344 nat_traversal_enabled_ = nat_traversal_enabled;
395 345
396 // Notify the web-app of the policy setting. 346 // Notify the web-app of the policy setting.
397 task_runner_->PostTask( 347 task_runner_->PostTask(
398 FROM_HERE, base::Bind(&It2MeHost::Observer::OnNatPolicyChanged, 348 FROM_HERE, base::Bind(&It2MeHost::Observer::OnNatPolicyChanged,
399 observer_, nat_traversal_enabled_)); 349 observer_, nat_traversal_enabled_));
400 } 350 }
401 351
402 void It2MeHost::UpdateHostDomainPolicy(const std::string& host_domain) { 352 void It2MeHost::UpdateHostDomainPolicy(const std::string& host_domain) {
403 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); 353 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread());
404 354
405 VLOG(2) << "UpdateHostDomainPolicy: " << host_domain; 355 VLOG(2) << "UpdateHostDomainPolicy: " << host_domain;
406 356
407 // When setting a host domain policy, force disconnect any existing session. 357 // When setting a host domain policy, force disconnect any existing session.
408 if (!host_domain.empty() && IsConnected()) { 358 if (!host_domain.empty() && IsConnected()) {
409 Disconnect(); 359 Shutdown();
410 } 360 }
411 361
412 required_host_domain_ = host_domain; 362 required_host_domain_ = host_domain;
413 } 363 }
414 364
415 It2MeHost::~It2MeHost() { 365 It2MeHost::~It2MeHost() {
416 // Check that resources that need to be torn down on the UI thread are gone. 366 // Check that resources that need to be torn down on the UI thread are gone.
417 DCHECK(!desktop_environment_factory_.get()); 367 DCHECK(!desktop_environment_factory_.get());
418 DCHECK(!policy_watcher_.get()); 368 DCHECK(!policy_watcher_.get());
419 } 369 }
420 370
421 void It2MeHost::SetState(It2MeHostState state, 371 void It2MeHost::SetState(It2MeHostState state,
422 const std::string& error_message) { 372 const std::string& error_message) {
423 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); 373 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread());
424 374
425 switch (state_) { 375 switch (state_) {
426 case kDisconnected: 376 case kDisconnected:
427 DCHECK(state == kStarting || 377 DCHECK(state == kStarting ||
428 state == kError) << state; 378 state == kError) << state;
429 break; 379 break;
430 case kStarting: 380 case kStarting:
431 DCHECK(state == kRequestedAccessCode || 381 DCHECK(state == kRequestedAccessCode ||
432 state == kDisconnecting || 382 state == kDisconnected ||
433 state == kError || 383 state == kError ||
434 state == kInvalidDomainError) << state; 384 state == kInvalidDomainError) << state;
435 break; 385 break;
436 case kRequestedAccessCode: 386 case kRequestedAccessCode:
437 DCHECK(state == kReceivedAccessCode || 387 DCHECK(state == kReceivedAccessCode ||
438 state == kDisconnecting || 388 state == kDisconnected ||
439 state == kError) << state; 389 state == kError) << state;
440 break; 390 break;
441 case kReceivedAccessCode: 391 case kReceivedAccessCode:
442 DCHECK(state == kConnected || 392 DCHECK(state == kConnected ||
443 state == kDisconnecting || 393 state == kDisconnected ||
444 state == kError) << state; 394 state == kError) << state;
445 break; 395 break;
446 case kConnected: 396 case kConnected:
447 DCHECK(state == kDisconnecting || 397 DCHECK(state == kDisconnected ||
448 state == kDisconnected ||
449 state == kError) << state; 398 state == kError) << state;
450 break; 399 break;
451 case kDisconnecting: 400 case kError:
452 DCHECK(state == kDisconnected) << state; 401 DCHECK(state == kDisconnected) << state;
453 break; 402 break;
454 case kError:
455 DCHECK(state == kDisconnecting) << state;
456 break;
457 case kInvalidDomainError: 403 case kInvalidDomainError:
458 DCHECK(state == kDisconnecting) << state; 404 DCHECK(state == kDisconnected) << state;
459 break; 405 break;
460 }; 406 };
461 407
462 state_ = state; 408 state_ = state;
463 409
464 // Post a state-change notification to the web-app. 410 // Post a state-change notification to the web-app.
465 task_runner_->PostTask( 411 task_runner_->PostTask(
466 FROM_HERE, base::Bind(&It2MeHost::Observer::OnStateChanged, 412 FROM_HERE, base::Bind(&It2MeHost::Observer::OnStateChanged,
467 observer_, state, error_message)); 413 observer_, state, error_message));
468 } 414 }
469 415
470 bool It2MeHost::IsConnected() const { 416 bool It2MeHost::IsConnected() const {
471 return state_ == kRequestedAccessCode || state_ == kReceivedAccessCode || 417 return state_ == kRequestedAccessCode || state_ == kReceivedAccessCode ||
472 state_ == kConnected; 418 state_ == kConnected;
473 } 419 }
474 420
475 void It2MeHost::OnReceivedSupportID( 421 void It2MeHost::OnReceivedSupportID(
476 const std::string& support_id, 422 const std::string& support_id,
477 const base::TimeDelta& lifetime, 423 const base::TimeDelta& lifetime,
478 const std::string& error_message) { 424 const std::string& error_message) {
479 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread()); 425 DCHECK(host_context_->network_task_runner()->BelongsToCurrentThread());
480 426
481 if (!error_message.empty()) { 427 if (!error_message.empty()) {
482 SetState(kError, error_message); 428 SetState(kError, error_message);
483 Disconnect(); 429 Shutdown();
484 return; 430 return;
485 } 431 }
486 432
487 std::string host_secret = GenerateSupportHostSecret(); 433 std::string host_secret = GenerateSupportHostSecret();
488 std::string access_code = support_id + host_secret; 434 std::string access_code = support_id + host_secret;
489 435
490 std::string local_certificate = host_key_pair_->GenerateCertificate(); 436 std::string local_certificate = host_key_pair_->GenerateCertificate();
491 if (local_certificate.empty()) { 437 if (local_certificate.empty()) {
492 std::string error_message = "Failed to generate host certificate."; 438 std::string error_message = "Failed to generate host certificate.";
493 LOG(ERROR) << error_message; 439 LOG(ERROR) << error_message;
494 SetState(kError, error_message); 440 SetState(kError, error_message);
495 Disconnect(); 441 Shutdown();
496 return; 442 return;
497 } 443 }
498 444
499 scoped_ptr<protocol::AuthenticatorFactory> factory( 445 scoped_ptr<protocol::AuthenticatorFactory> factory(
500 new protocol::It2MeHostAuthenticatorFactory( 446 new protocol::It2MeHostAuthenticatorFactory(
501 local_certificate, host_key_pair_, access_code)); 447 local_certificate, host_key_pair_, access_code));
502 host_->SetAuthenticatorFactory(factory.Pass()); 448 host_->SetAuthenticatorFactory(factory.Pass());
503 449
504 // Pass the Access Code to the script object before changing state. 450 // Pass the Access Code to the script object before changing state.
505 task_runner_->PostTask( 451 task_runner_->PostTask(
(...skipping 25 matching lines...) Expand all
531 scoped_ptr<It2MeConfirmationDialogFactory> confirmation_dialog_factory( 477 scoped_ptr<It2MeConfirmationDialogFactory> confirmation_dialog_factory(
532 new It2MeConfirmationDialogFactory()); 478 new It2MeConfirmationDialogFactory());
533 scoped_ptr<PolicyWatcher> policy_watcher = 479 scoped_ptr<PolicyWatcher> policy_watcher =
534 PolicyWatcher::Create(policy_service_, context->file_task_runner()); 480 PolicyWatcher::Create(policy_service_, context->file_task_runner());
535 return new It2MeHost(context.Pass(), policy_watcher.Pass(), 481 return new It2MeHost(context.Pass(), policy_watcher.Pass(),
536 confirmation_dialog_factory.Pass(), 482 confirmation_dialog_factory.Pass(),
537 observer, xmpp_server_config, directory_bot_jid); 483 observer, xmpp_server_config, directory_bot_jid);
538 } 484 }
539 485
540 } // namespace remoting 486 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/it2me/it2me_host.h ('k') | remoting/host/it2me/it2me_native_messaging_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698