Chromium Code Reviews| Index: remoting/host/plugin/host_script_object.cc |
| diff --git a/remoting/host/plugin/host_script_object.cc b/remoting/host/plugin/host_script_object.cc |
| index 460458dccc1089567b9370b021c6b679baab5d32..ec1d8fb9cdec9e4f51a95edd8e7881f6538cfd22 100644 |
| --- a/remoting/host/plugin/host_script_object.cc |
| +++ b/remoting/host/plugin/host_script_object.cc |
| @@ -16,6 +16,7 @@ |
| #include "remoting/host/host_key_pair.h" |
| #include "remoting/host/in_memory_host_config.h" |
| #include "remoting/host/plugin/host_plugin_utils.h" |
| +#include "remoting/host/plugin/policy_hack/nat_policy.h" |
| #include "remoting/host/register_support_host_request.h" |
| #include "remoting/host/support_access_verifier.h" |
| @@ -82,7 +83,8 @@ HostNPScriptObject::HostNPScriptObject(NPP plugin, NPObject* parent) |
| on_state_changed_func_(NULL), |
| np_thread_id_(base::PlatformThread::CurrentId()), |
| failed_login_attempts_(0), |
| - disconnected_event_(true, false) { |
| + disconnected_event_(true, false), |
| + policy_received_(false) { |
| // Set up log message handler. |
| // Note that this approach doesn't quite support having multiple instances |
| // of Chromoting running. In that case, the most recently opened tab will |
| @@ -112,6 +114,14 @@ HostNPScriptObject::~HostNPScriptObject() { |
| g_logging_old_handler = NULL; |
| g_logging_scriptable_object = NULL; |
| + // Stop listening for policy updates. |
| + if (nat_policy_) { |
| + base::WaitableEvent nat_policy_stopped_(true, false); |
| + nat_policy_->StopWatching(&nat_policy_stopped_); |
| + nat_policy_stopped_.Wait(); |
| + nat_policy_ = NULL; |
| + } |
| + |
| // Disconnect synchronously. We cannot disconnect asynchronously |
| // here because |host_context_| needs to be stopped on the plugin |
| // thread, but the plugin thread may not exist after the instance |
| @@ -136,6 +146,9 @@ bool HostNPScriptObject::Init() { |
| VLOG(2) << "Init"; |
| // TODO(wez): This starts a bunch of threads, which might fail. |
| host_context_.Start(); |
| + host_context_.network_message_loop()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&HostNPScriptObject::InitNatPolicy, base::Unretained(this))); |
| return true; |
| } |
| @@ -377,11 +390,42 @@ bool HostNPScriptObject::Connect(const NPVariant* args, |
| return false; |
| } |
| - ConnectInternal(uid, auth_token, auth_service); |
| + ReadPolicyAndConnect(uid, auth_token, auth_service); |
| return true; |
| } |
| +void HostNPScriptObject::ReadPolicyAndConnect(const std::string& uid, |
| + const std::string& auth_token, |
| + const std::string& auth_service) { |
| + if (MessageLoop::current() != host_context_.main_message_loop()) { |
| + host_context_.main_message_loop()->PostTask( |
| + FROM_HERE, base::Bind( |
| + &HostNPScriptObject::ReadPolicyAndConnect, base::Unretained(this), |
| + uid, auth_token, auth_service)); |
| + return; |
| + } |
| + |
| + // Only proceed to ConnectInternal() if at least one policy update has been |
| + // received. |
| + if (policy_received_) { |
| + ConnectInternal(uid, auth_token, auth_service); |
| + } else { |
| + // Otherwise, create the policy watcher, and thunk the connect. |
| + pending_connect_ = |
| + base::Bind(&HostNPScriptObject::ConnectInternal, |
| + base::Unretained(this), uid, auth_token, auth_service); |
| + } |
| +} |
| + |
| +void HostNPScriptObject::InitNatPolicy() { |
| + DCHECK_EQ(MessageLoop::current(), host_context_.network_message_loop()); |
| + nat_policy_ = policy_hack::NatPolicy::Create( |
| + base::Bind(&HostNPScriptObject::OnNatPolicyUpdate, |
| + base::Unretained(this))); |
| + nat_policy_->StartWatching(); |
| +} |
| + |
| void HostNPScriptObject::ConnectInternal( |
| const std::string& uid, |
| const std::string& auth_token, |
| @@ -432,7 +476,7 @@ void HostNPScriptObject::ConnectInternal( |
| // 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.
|
| host_ = ChromotingHost::Create( |
| &host_context_, host_config_, desktop_environment_.get(), |
| - access_verifier.release(), false); |
| + access_verifier.release(), nat_traversal_enabled_); |
| host_->AddStatusObserver(this); |
| host_->AddStatusObserver(register_request_.get()); |
| host_->set_it2me(true); |
| @@ -484,6 +528,32 @@ void HostNPScriptObject::OnShutdownFinished() { |
| disconnected_event_.Signal(); |
| } |
| +void HostNPScriptObject::OnNatPolicyUpdate(bool nat_traversal_enabled) { |
| + if (MessageLoop::current() != host_context_.main_message_loop()) { |
| + host_context_.main_message_loop()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&HostNPScriptObject::OnNatPolicyUpdate, |
| + base::Unretained(this), nat_traversal_enabled)); |
| + return; |
| + } |
| + |
| + VLOG(2) << "OnNatPolicyUpdate: " << nat_traversal_enabled; |
| + |
| + // When transitioning from true to false, force a disconnect. |
| + if (nat_traversal_enabled_ && !nat_traversal_enabled) { |
| + // TODO(ajwong): Do we need to do any weird synchronization? |
| + DisconnectInternal(); |
| + } |
| + |
| + policy_received_ = true; |
| + nat_traversal_enabled_ = nat_traversal_enabled; |
| + |
| + if (!pending_connect_.is_null()) { |
| + pending_connect_.Run(); |
| + pending_connect_.Reset(); |
| + } |
| +} |
| + |
| void HostNPScriptObject::OnReceivedSupportID( |
| SupportAccessVerifier* access_verifier, |
| bool success, |