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

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

Powered by Google App Engine
This is Rietveld 408576698