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

Side by Side Diff: remoting/host/plugin/host_script_object.cc

Issue 7599017: Framework to allow Chromoting host to respect NAT traversal policy in linux. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge with Sergey's MessageLoopProxy change Created 9 years, 4 months 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 | Annotate | Revision Log
OLDNEW
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/host/plugin/host_script_object.h" 5 #include "remoting/host/plugin/host_script_object.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/message_loop_proxy.h" 9 #include "base/message_loop_proxy.h"
10 #include "base/threading/platform_thread.h" 10 #include "base/threading/platform_thread.h"
11 #include "remoting/base/auth_token_util.h" 11 #include "remoting/base/auth_token_util.h"
12 #include "remoting/base/util.h" 12 #include "remoting/base/util.h"
13 #include "remoting/host/chromoting_host.h" 13 #include "remoting/host/chromoting_host.h"
14 #include "remoting/host/chromoting_host_context.h" 14 #include "remoting/host/chromoting_host_context.h"
15 #include "remoting/host/desktop_environment.h" 15 #include "remoting/host/desktop_environment.h"
16 #include "remoting/host/host_config.h" 16 #include "remoting/host/host_config.h"
17 #include "remoting/host/host_key_pair.h" 17 #include "remoting/host/host_key_pair.h"
18 #include "remoting/host/in_memory_host_config.h" 18 #include "remoting/host/in_memory_host_config.h"
19 #include "remoting/host/plugin/host_plugin_utils.h" 19 #include "remoting/host/plugin/host_plugin_utils.h"
20 #include "remoting/host/plugin/policy_hack/nat_policy.h"
20 #include "remoting/host/register_support_host_request.h" 21 #include "remoting/host/register_support_host_request.h"
21 #include "remoting/host/support_access_verifier.h" 22 #include "remoting/host/support_access_verifier.h"
22 23
23 namespace remoting { 24 namespace remoting {
24 25
25 // Supported Javascript interface: 26 // Supported Javascript interface:
26 // readonly attribute string accessCode; 27 // readonly attribute string accessCode;
27 // readonly attribute int accessCodeLifetime; 28 // readonly attribute int accessCodeLifetime;
28 // readonly attribute string client; 29 // readonly attribute string client;
29 // readonly attribute int state; 30 // readonly attribute int state;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 static logging::LogMessageHandlerFunction g_logging_old_handler = NULL; 77 static logging::LogMessageHandlerFunction g_logging_old_handler = NULL;
77 78
78 HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent) 79 HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent)
79 : plugin_(plugin), 80 : plugin_(plugin),
80 parent_(parent), 81 parent_(parent),
81 state_(kDisconnected), 82 state_(kDisconnected),
82 log_debug_info_func_(NULL), 83 log_debug_info_func_(NULL),
83 on_state_changed_func_(NULL), 84 on_state_changed_func_(NULL),
84 np_thread_id_(base::PlatformThread::CurrentId()), 85 np_thread_id_(base::PlatformThread::CurrentId()),
85 failed_login_attempts_(0), 86 failed_login_attempts_(0),
86 disconnected_event_(true, false) { 87 disconnected_event_(true, false),
88 nat_traversal_enabled_(false),
89 policy_received_(false) {
87 // Set up log message handler. 90 // Set up log message handler.
88 // Note that this approach doesn't quite support having multiple instances 91 // Note that this approach doesn't quite support having multiple instances
89 // of Chromoting running. In that case, the most recently opened tab will 92 // of Chromoting running. In that case, the most recently opened tab will
90 // grab all the debug log messages, and when any Chromoting tab is closed 93 // grab all the debug log messages, and when any Chromoting tab is closed
91 // the logging handler will go away. 94 // the logging handler will go away.
92 // Since having multiple Chromoting tabs is not a primary use case, and this 95 // Since having multiple Chromoting tabs is not a primary use case, and this
93 // is just debug logging, we're punting improving debug log support for that 96 // is just debug logging, we're punting improving debug log support for that
94 // case. 97 // case.
95 if (g_logging_old_handler == NULL) 98 if (g_logging_old_handler == NULL)
96 g_logging_old_handler = logging::GetLogMessageHandler(); 99 g_logging_old_handler = logging::GetLogMessageHandler();
97 logging::SetLogMessageHandler(&LogToUI); 100 logging::SetLogMessageHandler(&LogToUI);
98 g_logging_scriptable_object = this; 101 g_logging_scriptable_object = this;
99 102
100 VLOG(2) << "HostNPScriptObject"; 103 VLOG(2) << "HostNPScriptObject";
101 host_context_.SetUITaskPostFunction(base::Bind( 104 host_context_.SetUITaskPostFunction(base::Bind(
102 &HostNPScriptObject::PostTaskToNPThread, base::Unretained(this))); 105 &HostNPScriptObject::PostTaskToNPThread, base::Unretained(this)));
103 } 106 }
104 107
105 HostNPScriptObject::~HostNPScriptObject() { 108 HostNPScriptObject::~HostNPScriptObject() {
106 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); 109 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
107 110
108 // Shutdown DesktopEnvironment first so that it doesn't try to post 111 // Shutdown DesktopEnvironment first so that it doesn't try to post
109 // tasks on the UI thread while we are stopping the host. 112 // tasks on the UI thread while we are stopping the host.
110 desktop_environment_->Shutdown(); 113 desktop_environment_->Shutdown();
111 114
112 logging::SetLogMessageHandler(g_logging_old_handler); 115 logging::SetLogMessageHandler(g_logging_old_handler);
113 g_logging_old_handler = NULL; 116 g_logging_old_handler = NULL;
114 g_logging_scriptable_object = NULL; 117 g_logging_scriptable_object = NULL;
115 118
119 // Stop listening for policy updates.
120 if (nat_policy_.get()) {
121 base::WaitableEvent nat_policy_stopped_(true, false);
122 nat_policy_->StopWatching(&nat_policy_stopped_);
123 nat_policy_stopped_.Wait();
124 nat_policy_.reset();
125 }
126
116 // Disconnect synchronously. We cannot disconnect asynchronously 127 // Disconnect synchronously. We cannot disconnect asynchronously
117 // here because |host_context_| needs to be stopped on the plugin 128 // here because |host_context_| needs to be stopped on the plugin
118 // thread, but the plugin thread may not exist after the instance 129 // thread, but the plugin thread may not exist after the instance
119 // is destroyed. 130 // is destroyed.
120 destructing_.Set(); 131 destructing_.Set();
121 disconnected_event_.Reset(); 132 disconnected_event_.Reset();
122 DisconnectInternal(); 133 DisconnectInternal();
123 disconnected_event_.Wait(); 134 disconnected_event_.Wait();
124 135
125 // Stop all threads. 136 // Stop all threads.
126 host_context_.Stop(); 137 host_context_.Stop();
127 138
128 if (log_debug_info_func_) { 139 if (log_debug_info_func_) {
129 g_npnetscape_funcs->releaseobject(log_debug_info_func_); 140 g_npnetscape_funcs->releaseobject(log_debug_info_func_);
130 } 141 }
131 if (on_state_changed_func_) { 142 if (on_state_changed_func_) {
132 g_npnetscape_funcs->releaseobject(on_state_changed_func_); 143 g_npnetscape_funcs->releaseobject(on_state_changed_func_);
133 } 144 }
134 } 145 }
135 146
136 bool HostNPScriptObject::Init() { 147 bool HostNPScriptObject::Init() {
137 VLOG(2) << "Init"; 148 VLOG(2) << "Init";
138 // TODO(wez): This starts a bunch of threads, which might fail. 149 // TODO(wez): This starts a bunch of threads, which might fail.
139 host_context_.Start(); 150 host_context_.Start();
151 nat_policy_.reset(
152 policy_hack::NatPolicy::Create(host_context_.network_message_loop()));
153 nat_policy_->StartWatching(
154 base::Bind(&HostNPScriptObject::OnNatPolicyUpdate,
155 base::Unretained(this)));
140 return true; 156 return true;
141 } 157 }
142 158
143 bool HostNPScriptObject::HasMethod(const std::string& method_name) { 159 bool HostNPScriptObject::HasMethod(const std::string& method_name) {
144 VLOG(2) << "HasMethod " << method_name; 160 VLOG(2) << "HasMethod " << method_name;
145 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); 161 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_);
146 return (method_name == kFuncNameConnect || 162 return (method_name == kFuncNameConnect ||
147 method_name == kFuncNameDisconnect); 163 method_name == kFuncNameDisconnect);
148 } 164 }
149 165
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 std::string auth_service_with_token = StringFromNPVariant(args[1]); 387 std::string auth_service_with_token = StringFromNPVariant(args[1]);
372 std::string auth_token; 388 std::string auth_token;
373 std::string auth_service; 389 std::string auth_service;
374 ParseAuthTokenWithService(auth_service_with_token, &auth_token, 390 ParseAuthTokenWithService(auth_service_with_token, &auth_token,
375 &auth_service); 391 &auth_service);
376 if (auth_token.empty()) { 392 if (auth_token.empty()) {
377 SetException("connect: auth_service_with_token argument has empty token"); 393 SetException("connect: auth_service_with_token argument has empty token");
378 return false; 394 return false;
379 } 395 }
380 396
381 ConnectInternal(uid, auth_token, auth_service); 397 ReadPolicyAndConnect(uid, auth_token, auth_service);
382 398
383 return true; 399 return true;
384 } 400 }
385 401
386 void HostNPScriptObject::ConnectInternal( 402 void HostNPScriptObject::ReadPolicyAndConnect(const std::string& uid,
403 const std::string& auth_token,
404 const std::string& auth_service) {
405 if (MessageLoop::current() != host_context_.main_message_loop()) {
406 host_context_.main_message_loop()->PostTask(
407 FROM_HERE, base::Bind(
408 &HostNPScriptObject::ReadPolicyAndConnect, base::Unretained(this),
409 uid, auth_token, auth_service));
410 return;
411 }
412
413 // Only proceed to FinishConnect() if at least one policy update has been
414 // received.
415 if (policy_received_) {
416 FinishConnect(uid, auth_token, auth_service);
417 } else {
418 // Otherwise, create the policy watcher, and thunk the connect.
419 pending_connect_ =
420 base::Bind(&HostNPScriptObject::FinishConnect,
421 base::Unretained(this), uid, auth_token, auth_service);
422 }
423 }
424
425 void HostNPScriptObject::FinishConnect(
387 const std::string& uid, 426 const std::string& uid,
388 const std::string& auth_token, 427 const std::string& auth_token,
389 const std::string& auth_service) { 428 const std::string& auth_service) {
390 if (MessageLoop::current() != host_context_.main_message_loop()) { 429 if (MessageLoop::current() != host_context_.main_message_loop()) {
391 host_context_.main_message_loop()->PostTask( 430 host_context_.main_message_loop()->PostTask(
392 FROM_HERE, base::Bind( 431 FROM_HERE, base::Bind(
393 &HostNPScriptObject::ConnectInternal, base::Unretained(this), 432 &HostNPScriptObject::FinishConnect, base::Unretained(this),
394 uid, auth_token, auth_service)); 433 uid, auth_token, auth_service));
395 return; 434 return;
396 } 435 }
397 // Store the supplied user ID and token to the Host configuration. 436 // Store the supplied user ID and token to the Host configuration.
398 scoped_refptr<MutableHostConfig> host_config = new InMemoryHostConfig(); 437 scoped_refptr<MutableHostConfig> host_config = new InMemoryHostConfig();
399 host_config->SetString(kXmppLoginConfigPath, uid); 438 host_config->SetString(kXmppLoginConfigPath, uid);
400 host_config->SetString(kXmppAuthTokenConfigPath, auth_token); 439 host_config->SetString(kXmppAuthTokenConfigPath, auth_token);
401 host_config->SetString(kXmppAuthServiceConfigPath, auth_service); 440 host_config->SetString(kXmppAuthServiceConfigPath, auth_service);
402 441
403 // Create an access verifier and fetch the host secret. 442 // Create an access verifier and fetch the host secret.
(...skipping 19 matching lines...) Expand all
423 } 462 }
424 463
425 // Nothing went wrong, so lets save the host, config and request. 464 // Nothing went wrong, so lets save the host, config and request.
426 host_config_ = host_config; 465 host_config_ = host_config;
427 register_request_.reset(register_request.release()); 466 register_request_.reset(register_request.release());
428 467
429 // Create DesktopEnvironment. 468 // Create DesktopEnvironment.
430 desktop_environment_.reset(DesktopEnvironment::Create(&host_context_)); 469 desktop_environment_.reset(DesktopEnvironment::Create(&host_context_));
431 470
432 // Create the Host. 471 // Create the Host.
433 // TODO(sergeyu): Use firewall traversal policy settings here. 472 LOG(INFO) << "Connecting with NAT state: " << nat_traversal_enabled_;
434 host_ = ChromotingHost::Create( 473 host_ = ChromotingHost::Create(
435 &host_context_, host_config_, desktop_environment_.get(), 474 &host_context_, host_config_, desktop_environment_.get(),
436 access_verifier.release(), false); 475 access_verifier.release(), nat_traversal_enabled_);
437 host_->AddStatusObserver(this); 476 host_->AddStatusObserver(this);
438 host_->AddStatusObserver(register_request_.get()); 477 host_->AddStatusObserver(register_request_.get());
439 host_->set_it2me(true); 478 host_->set_it2me(true);
440 479
441 // Start the Host. 480 // Start the Host.
442 host_->Start(); 481 host_->Start();
443 482
444 OnStateChanged(kRequestedAccessCode); 483 OnStateChanged(kRequestedAccessCode);
445 return; 484 return;
446 } 485 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 517
479 void HostNPScriptObject::OnShutdownFinished() { 518 void HostNPScriptObject::OnShutdownFinished() {
480 DCHECK_EQ(MessageLoop::current(), host_context_.main_message_loop()); 519 DCHECK_EQ(MessageLoop::current(), host_context_.main_message_loop());
481 520
482 host_ = NULL; 521 host_ = NULL;
483 register_request_.reset(); 522 register_request_.reset();
484 host_config_ = NULL; 523 host_config_ = NULL;
485 disconnected_event_.Signal(); 524 disconnected_event_.Signal();
486 } 525 }
487 526
527 void HostNPScriptObject::OnNatPolicyUpdate(bool nat_traversal_enabled) {
528 if (MessageLoop::current() != host_context_.main_message_loop()) {
529 host_context_.main_message_loop()->PostTask(
530 FROM_HERE,
531 base::Bind(&HostNPScriptObject::OnNatPolicyUpdate,
532 base::Unretained(this), nat_traversal_enabled));
533 return;
534 }
535
536 VLOG(2) << "OnNatPolicyUpdate: " << nat_traversal_enabled;
537
538 // When transitioning from enabled to disabled, force disconnect any
539 // existing session.
540 if (nat_traversal_enabled_ && !nat_traversal_enabled) {
541 DisconnectInternal();
542 }
543
544 policy_received_ = true;
545 nat_traversal_enabled_ = nat_traversal_enabled;
546
547 if (!pending_connect_.is_null()) {
548 pending_connect_.Run();
549 pending_connect_.Reset();
550 }
551 }
552
488 void HostNPScriptObject::OnReceivedSupportID( 553 void HostNPScriptObject::OnReceivedSupportID(
489 SupportAccessVerifier* access_verifier, 554 SupportAccessVerifier* access_verifier,
490 bool success, 555 bool success,
491 const std::string& support_id, 556 const std::string& support_id,
492 const base::TimeDelta& lifetime) { 557 const base::TimeDelta& lifetime) {
493 CHECK_NE(base::PlatformThread::CurrentId(), np_thread_id_); 558 CHECK_NE(base::PlatformThread::CurrentId(), np_thread_id_);
494 559
495 if (!success) { 560 if (!success) {
496 // TODO(wez): Replace the success/fail flag with full error reporting. 561 // TODO(wez): Replace the success/fail flag with full error reporting.
497 DisconnectInternal(); 562 DisconnectInternal();
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 } 668 }
604 669
605 // static 670 // static
606 void HostNPScriptObject::NPTaskSpringboard(void* task) { 671 void HostNPScriptObject::NPTaskSpringboard(void* task) {
607 base::Closure* real_task = reinterpret_cast<base::Closure*>(task); 672 base::Closure* real_task = reinterpret_cast<base::Closure*>(task);
608 real_task->Run(); 673 real_task->Run();
609 delete real_task; 674 delete real_task;
610 } 675 }
611 676
612 } // namespace remoting 677 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/plugin/host_script_object.h ('k') | remoting/host/plugin/policy_hack/nat_policy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698