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

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

Powered by Google App Engine
This is Rietveld 408576698