OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // This file implements a standalone host process for Me2Me. | 5 // This file implements a standalone host process for Me2Me. |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 const char kWindowIdSwitchName[] = "window-id"; | 140 const char kWindowIdSwitchName[] = "window-id"; |
141 | 141 |
142 // Maximum time to wait for clean shutdown to occur, before forcing termination | 142 // Maximum time to wait for clean shutdown to occur, before forcing termination |
143 // of the process. | 143 // of the process. |
144 const int kShutdownTimeoutSeconds = 15; | 144 const int kShutdownTimeoutSeconds = 15; |
145 | 145 |
146 // Maximum time to wait for reporting host-offline-reason to the service, | 146 // Maximum time to wait for reporting host-offline-reason to the service, |
147 // before continuing normal process shutdown. | 147 // before continuing normal process shutdown. |
148 const int kHostOfflineReasonTimeoutSeconds = 10; | 148 const int kHostOfflineReasonTimeoutSeconds = 10; |
149 | 149 |
| 150 // Host offline reasons not associated with shutting down the host process |
| 151 // and therefore not expressible through HostExitCodes enum. |
| 152 const char kHostOfflineReasonPolicyReadError[] = "POLICY_READ_ERROR"; |
| 153 const char kHostOfflineReasonPolicyChangeRequiresRestart[] = |
| 154 "POLICY_CHANGE_REQUIRES_RESTART"; |
| 155 |
150 } // namespace | 156 } // namespace |
151 | 157 |
152 namespace remoting { | 158 namespace remoting { |
153 | 159 |
154 class HostProcess : public ConfigWatcher::Delegate, | 160 class HostProcess : public ConfigWatcher::Delegate, |
155 public HostSignalingManager::Listener, | 161 public HostSignalingManager::Listener, |
156 public HostChangeNotificationListener::Listener, | 162 public HostChangeNotificationListener::Listener, |
157 public IPC::Listener, | 163 public IPC::Listener, |
158 public base::RefCountedThreadSafe<HostProcess> { | 164 public base::RefCountedThreadSafe<HostProcess> { |
159 public: | 165 public: |
(...skipping 15 matching lines...) Expand all Loading... |
175 // HostChangeNotificationListener::Listener overrides. | 181 // HostChangeNotificationListener::Listener overrides. |
176 void OnHostDeleted() override; | 182 void OnHostDeleted() override; |
177 | 183 |
178 // Handler of the ChromotingDaemonNetworkMsg_InitializePairingRegistry IPC | 184 // Handler of the ChromotingDaemonNetworkMsg_InitializePairingRegistry IPC |
179 // message. | 185 // message. |
180 void OnInitializePairingRegistry( | 186 void OnInitializePairingRegistry( |
181 IPC::PlatformFileForTransit privileged_key, | 187 IPC::PlatformFileForTransit privileged_key, |
182 IPC::PlatformFileForTransit unprivileged_key); | 188 IPC::PlatformFileForTransit unprivileged_key); |
183 | 189 |
184 private: | 190 private: |
| 191 // See SetState method for a list of allowed state transitions. |
185 enum HostState { | 192 enum HostState { |
186 // Host process has just been started. Waiting for config and policies to be | 193 // Waiting for valid config and policies to be read from the disk. |
187 // read from the disk. | 194 // Either the host process has just been started, or it is trying to start |
188 HOST_INITIALIZING, | 195 // again after temporarily going offline due to policy change or error. |
| 196 HOST_STARTING, |
189 | 197 |
190 // Host is started and running. | 198 // Host is started and running. |
191 HOST_STARTED, | 199 HOST_STARTED, |
192 | 200 |
193 // Host is being stopped and will need to be started again. | 201 // Host is sending offline reason, before trying to restart. |
194 HOST_STOPPING_TO_RESTART, | 202 HOST_GOING_OFFLINE_TO_RESTART, |
195 | 203 |
196 // Host is being stopped. | 204 // Host is sending offline reason, before shutting down. |
197 HOST_STOPPING, | 205 HOST_GOING_OFFLINE_TO_STOP, |
198 | 206 |
199 // Host has been stopped. | 207 // Host has been stopped (host process will end soon). |
200 HOST_STOPPED, | 208 HOST_STOPPED, |
| 209 }; |
201 | 210 |
202 // Allowed state transitions: | 211 enum PolicyState { |
203 // INITIALIZING->STARTED | 212 // Cannot start the host, because a valid policy has not been read yet. |
204 // INITIALIZING->STOPPED | 213 POLICY_INITIALIZING, |
205 // STARTED->STOPPING_TO_RESTART | 214 |
206 // STARTED->STOPPING | 215 // Policy was loaded successfully. |
207 // STOPPING_TO_RESTART->STARTED | 216 POLICY_LOADED, |
208 // STOPPING_TO_RESTART->STOPPING | 217 |
209 // STOPPING->STOPPED | 218 // Policy error was detected, and we haven't yet sent out a |
210 // STOPPED->STARTED | 219 // host-offline-reason (i.e. because we haven't yet read the config). |
211 // | 220 POLICY_ERROR_REPORT_PENDING, |
212 // |host_| must be nullptr in INITIALIZING and STOPPED states and not | 221 |
213 // nullptr in all other states. | 222 // Policy error was detected, and we have sent out a host-offline-reason. |
| 223 POLICY_ERROR_REPORTED, |
214 }; | 224 }; |
215 | 225 |
216 friend class base::RefCountedThreadSafe<HostProcess>; | 226 friend class base::RefCountedThreadSafe<HostProcess>; |
217 ~HostProcess() override; | 227 ~HostProcess() override; |
218 | 228 |
| 229 void SetState(HostState target_state); |
| 230 |
219 void StartOnNetworkThread(); | 231 void StartOnNetworkThread(); |
220 | 232 |
221 #if defined(OS_POSIX) | 233 #if defined(OS_POSIX) |
222 // Callback passed to RegisterSignalHandler() to handle SIGTERM events. | 234 // Callback passed to RegisterSignalHandler() to handle SIGTERM events. |
223 void SigTermHandler(int signal_number); | 235 void SigTermHandler(int signal_number); |
224 #endif | 236 #endif |
225 | 237 |
226 // Called to initialize resources on the UI thread. | 238 // Called to initialize resources on the UI thread. |
227 void StartOnUiThread(); | 239 void StartOnUiThread(); |
228 | 240 |
229 // Initializes IPC control channel and config file path from |cmd_line|. | 241 // Initializes IPC control channel and config file path from |cmd_line|. |
230 // Called on the UI thread. | 242 // Called on the UI thread. |
231 bool InitWithCommandLine(const base::CommandLine* cmd_line); | 243 bool InitWithCommandLine(const base::CommandLine* cmd_line); |
232 | 244 |
233 // Called on the UI thread to start monitoring the configuration file. | 245 // Called on the UI thread to start monitoring the configuration file. |
234 void StartWatchingConfigChanges(); | 246 void StartWatchingConfigChanges(); |
235 | 247 |
236 // Called on the network thread to set the host's Authenticator factory. | 248 // Called on the network thread to set the host's Authenticator factory. |
237 void CreateAuthenticatorFactory(); | 249 void CreateAuthenticatorFactory(); |
238 | 250 |
239 // Tear down resources that run on the UI thread. | 251 // Tear down resources that run on the UI thread. |
240 void ShutdownOnUiThread(); | 252 void ShutdownOnUiThread(); |
241 | 253 |
242 // Applies the host config, returning true if successful. | 254 // Applies the host config, returning true if successful. |
243 bool ApplyConfig(const base::DictionaryValue& config); | 255 bool ApplyConfig(const base::DictionaryValue& config); |
244 | 256 |
245 // Handles policy updates, by calling On*PolicyUpdate methods. | 257 // Handles policy updates, by calling On*PolicyUpdate methods. |
246 void OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies); | 258 void OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies); |
247 void OnPolicyError(); | 259 void OnPolicyError(); |
| 260 void ReportPolicyErrorAndRestartHost(); |
248 void ApplyHostDomainPolicy(); | 261 void ApplyHostDomainPolicy(); |
249 void ApplyUsernamePolicy(); | 262 void ApplyUsernamePolicy(); |
250 bool OnHostDomainPolicyUpdate(base::DictionaryValue* policies); | 263 bool OnHostDomainPolicyUpdate(base::DictionaryValue* policies); |
251 bool OnUsernamePolicyUpdate(base::DictionaryValue* policies); | 264 bool OnUsernamePolicyUpdate(base::DictionaryValue* policies); |
252 bool OnNatPolicyUpdate(base::DictionaryValue* policies); | 265 bool OnNatPolicyUpdate(base::DictionaryValue* policies); |
253 bool OnRelayPolicyUpdate(base::DictionaryValue* policies); | 266 bool OnRelayPolicyUpdate(base::DictionaryValue* policies); |
254 bool OnUdpPortPolicyUpdate(base::DictionaryValue* policies); | 267 bool OnUdpPortPolicyUpdate(base::DictionaryValue* policies); |
255 bool OnCurtainPolicyUpdate(base::DictionaryValue* policies); | 268 bool OnCurtainPolicyUpdate(base::DictionaryValue* policies); |
256 bool OnHostTalkGadgetPrefixPolicyUpdate(base::DictionaryValue* policies); | 269 bool OnHostTalkGadgetPrefixPolicyUpdate(base::DictionaryValue* policies); |
257 bool OnHostTokenUrlPolicyUpdate(base::DictionaryValue* policies); | 270 bool OnHostTokenUrlPolicyUpdate(base::DictionaryValue* policies); |
258 bool OnPairingPolicyUpdate(base::DictionaryValue* policies); | 271 bool OnPairingPolicyUpdate(base::DictionaryValue* policies); |
259 bool OnGnubbyAuthPolicyUpdate(base::DictionaryValue* policies); | 272 bool OnGnubbyAuthPolicyUpdate(base::DictionaryValue* policies); |
260 | 273 |
261 scoped_ptr<HostSignalingManager> CreateHostSignalingManager(); | 274 scoped_ptr<HostSignalingManager> CreateHostSignalingManager(); |
262 | 275 |
263 void StartHostIfReady(); | 276 void StartHostIfReady(); |
264 void StartHost(); | 277 void StartHost(); |
265 | 278 |
266 // Overrides for HostSignalingManager::Listener interface. | 279 // Overrides for HostSignalingManager::Listener interface. |
267 void OnHeartbeatSuccessful() override; | 280 void OnHeartbeatSuccessful() override; |
268 void OnUnknownHostIdError() override; | 281 void OnUnknownHostIdError() override; |
269 void OnAuthFailed() override; | 282 void OnAuthFailed() override; |
270 | 283 |
271 void RestartHost(); | 284 void RestartHost(const std::string& host_offline_reason); |
272 | |
273 // Stops the host and shuts down the process with the specified |exit_code|. | |
274 void ShutdownHost(HostExitCodes exit_code); | 285 void ShutdownHost(HostExitCodes exit_code); |
275 | 286 |
276 // Private helper used by ShutdownHost method to initiate sending of | 287 // Helper methods doing the work needed by RestartHost and ShutdownHost. |
277 // host-offline-reason before continuing shutdown. | 288 void GoOffline(const std::string& host_offline_reason); |
278 void SendOfflineReasonAndShutdownOnNetworkThread(HostExitCodes exit_code); | 289 void OnHostOfflineReasonAck(bool success); |
279 | |
280 void ShutdownOnNetworkThread(); | |
281 | 290 |
282 #if defined(OS_WIN) | 291 #if defined(OS_WIN) |
283 // Initializes the pairing registry on Windows. This should be invoked on the | 292 // Initializes the pairing registry on Windows. This should be invoked on the |
284 // network thread. | 293 // network thread. |
285 void InitializePairingRegistry( | 294 void InitializePairingRegistry( |
286 IPC::PlatformFileForTransit privileged_key, | 295 IPC::PlatformFileForTransit privileged_key, |
287 IPC::PlatformFileForTransit unprivileged_key); | 296 IPC::PlatformFileForTransit unprivileged_key); |
288 #endif // defined(OS_WIN) | 297 #endif // defined(OS_WIN) |
289 | 298 |
290 // Crashes the process in response to a daemon's request. The daemon passes | 299 // Crashes the process in response to a daemon's request. The daemon passes |
(...skipping 27 matching lines...) Expand all Loading... |
318 scoped_refptr<RsaKeyPair> key_pair_; | 327 scoped_refptr<RsaKeyPair> key_pair_; |
319 std::string oauth_refresh_token_; | 328 std::string oauth_refresh_token_; |
320 std::string serialized_config_; | 329 std::string serialized_config_; |
321 std::string host_owner_; | 330 std::string host_owner_; |
322 std::string host_owner_email_; | 331 std::string host_owner_email_; |
323 bool use_service_account_; | 332 bool use_service_account_; |
324 bool enable_vp9_; | 333 bool enable_vp9_; |
325 int64_t frame_recorder_buffer_size_; | 334 int64_t frame_recorder_buffer_size_; |
326 | 335 |
327 scoped_ptr<PolicyWatcher> policy_watcher_; | 336 scoped_ptr<PolicyWatcher> policy_watcher_; |
328 bool policies_loaded_; | 337 PolicyState policy_state_; |
329 std::string host_domain_; | 338 std::string host_domain_; |
330 bool host_username_match_required_; | 339 bool host_username_match_required_; |
331 bool allow_nat_traversal_; | 340 bool allow_nat_traversal_; |
332 bool allow_relay_; | 341 bool allow_relay_; |
333 uint16 min_udp_port_; | 342 uint16 min_udp_port_; |
334 uint16 max_udp_port_; | 343 uint16 max_udp_port_; |
335 std::string talkgadget_prefix_; | 344 std::string talkgadget_prefix_; |
336 bool allow_pairing_; | 345 bool allow_pairing_; |
337 | 346 |
338 bool curtain_required_; | 347 bool curtain_required_; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 | 379 |
371 ShutdownWatchdog* shutdown_watchdog_; | 380 ShutdownWatchdog* shutdown_watchdog_; |
372 | 381 |
373 DISALLOW_COPY_AND_ASSIGN(HostProcess); | 382 DISALLOW_COPY_AND_ASSIGN(HostProcess); |
374 }; | 383 }; |
375 | 384 |
376 HostProcess::HostProcess(scoped_ptr<ChromotingHostContext> context, | 385 HostProcess::HostProcess(scoped_ptr<ChromotingHostContext> context, |
377 int* exit_code_out, | 386 int* exit_code_out, |
378 ShutdownWatchdog* shutdown_watchdog) | 387 ShutdownWatchdog* shutdown_watchdog) |
379 : context_(context.Pass()), | 388 : context_(context.Pass()), |
380 state_(HOST_INITIALIZING), | 389 state_(HOST_STARTING), |
381 use_service_account_(false), | 390 use_service_account_(false), |
382 enable_vp9_(false), | 391 enable_vp9_(false), |
383 frame_recorder_buffer_size_(0), | 392 frame_recorder_buffer_size_(0), |
384 policies_loaded_(false), | 393 policy_state_(POLICY_INITIALIZING), |
385 host_username_match_required_(false), | 394 host_username_match_required_(false), |
386 allow_nat_traversal_(true), | 395 allow_nat_traversal_(true), |
387 allow_relay_(true), | 396 allow_relay_(true), |
388 min_udp_port_(0), | 397 min_udp_port_(0), |
389 max_udp_port_(0), | 398 max_udp_port_(0), |
390 allow_pairing_(true), | 399 allow_pairing_(true), |
391 curtain_required_(false), | 400 curtain_required_(false), |
392 enable_gnubby_auth_(false), | 401 enable_gnubby_auth_(false), |
393 enable_window_capture_(false), | 402 enable_window_capture_(false), |
394 window_id_(0), | 403 window_id_(0), |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 ShutdownHost(kInvalidHostConfigurationExitCode); | 553 ShutdownHost(kInvalidHostConfigurationExitCode); |
545 return; | 554 return; |
546 } | 555 } |
547 | 556 |
548 if (!ApplyConfig(*config)) { | 557 if (!ApplyConfig(*config)) { |
549 LOG(ERROR) << "Failed to apply the configuration."; | 558 LOG(ERROR) << "Failed to apply the configuration."; |
550 ShutdownHost(kInvalidHostConfigurationExitCode); | 559 ShutdownHost(kInvalidHostConfigurationExitCode); |
551 return; | 560 return; |
552 } | 561 } |
553 | 562 |
554 if (state_ == HOST_INITIALIZING) { | 563 if (state_ == HOST_STARTING) { |
555 StartHostIfReady(); | 564 StartHostIfReady(); |
556 } else if (state_ == HOST_STARTED) { | 565 } else if (state_ == HOST_STARTED) { |
557 DCHECK(policies_loaded_); | |
558 | |
559 // Reapply policies that could be affected by a new config. | 566 // Reapply policies that could be affected by a new config. |
| 567 DCHECK_EQ(policy_state_, POLICY_LOADED); |
560 ApplyHostDomainPolicy(); | 568 ApplyHostDomainPolicy(); |
561 ApplyUsernamePolicy(); | 569 ApplyUsernamePolicy(); |
562 | 570 |
563 // TODO(sergeyu): Here we assume that PIN is the only part of the config | 571 // TODO(sergeyu): Here we assume that PIN is the only part of the config |
564 // that may change while the service is running. Change ApplyConfig() to | 572 // that may change while the service is running. Change ApplyConfig() to |
565 // detect other changes in the config and restart host if necessary here. | 573 // detect other changes in the config and restart host if necessary here. |
566 CreateAuthenticatorFactory(); | 574 CreateAuthenticatorFactory(); |
567 } | 575 } |
568 } | 576 } |
569 | 577 |
570 void HostProcess::OnConfigWatcherError() { | 578 void HostProcess::OnConfigWatcherError() { |
571 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 579 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
572 ShutdownHost(kInvalidHostConfigurationExitCode); | 580 ShutdownHost(kInvalidHostConfigurationExitCode); |
573 } | 581 } |
574 | 582 |
| 583 // Allowed state transitions (enforced via DCHECKs in SetState method): |
| 584 // STARTING->STARTED (once we have valid config + policy) |
| 585 // STARTING->GOING_OFFLINE_TO_STOP |
| 586 // STARTING->GOING_OFFLINE_TO_RESTART |
| 587 // STARTED->GOING_OFFLINE_TO_STOP |
| 588 // STARTED->GOING_OFFLINE_TO_RESTART |
| 589 // GOING_OFFLINE_TO_RESTART->GOING_OFFLINE_TO_STOP |
| 590 // GOING_OFFLINE_TO_RESTART->STARTING (after OnHostOfflineReasonAck) |
| 591 // GOING_OFFLINE_TO_STOP->STOPPED (after OnHostOfflineReasonAck) |
| 592 // |
| 593 // |host_| must be not-null in STARTED state and nullptr in all other states |
| 594 // (although this invariant can be temporarily violated when doing |
| 595 // synchronous processing on the networking thread). |
| 596 void HostProcess::SetState(HostState target_state) { |
| 597 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 598 |
| 599 // DCHECKs below enforce state allowed transitions listed in HostState. |
| 600 switch (state_) { |
| 601 case HOST_STARTING: |
| 602 DCHECK((target_state == HOST_STARTED) || |
| 603 (target_state == HOST_GOING_OFFLINE_TO_STOP) || |
| 604 (target_state == HOST_GOING_OFFLINE_TO_RESTART)) |
| 605 << state_ << " -> " << target_state; |
| 606 break; |
| 607 case HOST_STARTED: |
| 608 DCHECK((target_state == HOST_GOING_OFFLINE_TO_STOP) || |
| 609 (target_state == HOST_GOING_OFFLINE_TO_RESTART)) |
| 610 << state_ << " -> " << target_state; |
| 611 break; |
| 612 case HOST_GOING_OFFLINE_TO_RESTART: |
| 613 DCHECK((target_state == HOST_GOING_OFFLINE_TO_STOP) || |
| 614 (target_state == HOST_STARTING)) |
| 615 << state_ << " -> " << target_state; |
| 616 break; |
| 617 case HOST_GOING_OFFLINE_TO_STOP: |
| 618 DCHECK_EQ(target_state, HOST_STOPPED); |
| 619 break; |
| 620 case HOST_STOPPED: // HOST_STOPPED is a terminal state. |
| 621 default: |
| 622 NOTREACHED() << state_ << " -> " << target_state; |
| 623 break; |
| 624 } |
| 625 state_ = target_state; |
| 626 } |
| 627 |
575 void HostProcess::StartOnNetworkThread() { | 628 void HostProcess::StartOnNetworkThread() { |
576 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 629 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
577 | 630 |
578 #if !defined(REMOTING_MULTI_PROCESS) | 631 #if !defined(REMOTING_MULTI_PROCESS) |
579 if (host_config_path_ == base::FilePath(kStdinConfigPath)) { | 632 if (host_config_path_ == base::FilePath(kStdinConfigPath)) { |
580 // Process config we've read from stdin. | 633 // Process config we've read from stdin. |
581 OnConfigUpdated(host_config_); | 634 OnConfigUpdated(host_config_); |
582 } else { | 635 } else { |
583 // Start watching the host configuration file. | 636 // Start watching the host configuration file. |
584 config_watcher_.reset(new ConfigFileWatcher(context_->network_task_runner(), | 637 config_watcher_.reset(new ConfigFileWatcher(context_->network_task_runner(), |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 FROM_HERE, | 832 FROM_HERE, |
780 base::Bind(&HostProcess::StartOnNetworkThread, this)); | 833 base::Bind(&HostProcess::StartOnNetworkThread, this)); |
781 } | 834 } |
782 | 835 |
783 void HostProcess::ShutdownOnUiThread() { | 836 void HostProcess::ShutdownOnUiThread() { |
784 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); | 837 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
785 | 838 |
786 // Tear down resources that need to be torn down on the UI thread. | 839 // Tear down resources that need to be torn down on the UI thread. |
787 daemon_channel_.reset(); | 840 daemon_channel_.reset(); |
788 desktop_environment_factory_.reset(); | 841 desktop_environment_factory_.reset(); |
789 | |
790 policy_watcher_.reset(); | 842 policy_watcher_.reset(); |
791 | 843 |
792 // It is now safe for the HostProcess to be deleted. | 844 // It is now safe for the HostProcess to be deleted. |
793 self_ = nullptr; | 845 self_ = nullptr; |
794 | 846 |
795 #if defined(OS_LINUX) | 847 #if defined(OS_LINUX) |
796 // Cause the global AudioPipeReader to be freed, otherwise the audio | 848 // Cause the global AudioPipeReader to be freed, otherwise the audio |
797 // thread will remain in-use and prevent the process from exiting. | 849 // thread will remain in-use and prevent the process from exiting. |
798 // TODO(wez): DesktopEnvironmentFactory should own the pipe reader. | 850 // TODO(wez): DesktopEnvironmentFactory should own the pipe reader. |
799 // See crbug.com/161373 and crbug.com/104544. | 851 // See crbug.com/161373 and crbug.com/104544. |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
974 // Note: UsernamePolicyUpdate must run after OnCurtainPolicyUpdate. | 1026 // Note: UsernamePolicyUpdate must run after OnCurtainPolicyUpdate. |
975 restart_required |= OnUsernamePolicyUpdate(policies.get()); | 1027 restart_required |= OnUsernamePolicyUpdate(policies.get()); |
976 restart_required |= OnNatPolicyUpdate(policies.get()); | 1028 restart_required |= OnNatPolicyUpdate(policies.get()); |
977 restart_required |= OnRelayPolicyUpdate(policies.get()); | 1029 restart_required |= OnRelayPolicyUpdate(policies.get()); |
978 restart_required |= OnUdpPortPolicyUpdate(policies.get()); | 1030 restart_required |= OnUdpPortPolicyUpdate(policies.get()); |
979 restart_required |= OnHostTalkGadgetPrefixPolicyUpdate(policies.get()); | 1031 restart_required |= OnHostTalkGadgetPrefixPolicyUpdate(policies.get()); |
980 restart_required |= OnHostTokenUrlPolicyUpdate(policies.get()); | 1032 restart_required |= OnHostTokenUrlPolicyUpdate(policies.get()); |
981 restart_required |= OnPairingPolicyUpdate(policies.get()); | 1033 restart_required |= OnPairingPolicyUpdate(policies.get()); |
982 restart_required |= OnGnubbyAuthPolicyUpdate(policies.get()); | 1034 restart_required |= OnGnubbyAuthPolicyUpdate(policies.get()); |
983 | 1035 |
984 policies_loaded_ = true; | 1036 policy_state_ = POLICY_LOADED; |
985 | 1037 |
986 if (state_ == HOST_INITIALIZING) { | 1038 if (state_ == HOST_STARTING) { |
987 StartHostIfReady(); | 1039 StartHostIfReady(); |
988 } else if (state_ == HOST_STARTED) { | 1040 } else if (state_ == HOST_STARTED) { |
989 if (restart_required) | 1041 if (restart_required) |
990 RestartHost(); | 1042 RestartHost(kHostOfflineReasonPolicyChangeRequiresRestart); |
991 } | 1043 } |
992 } | 1044 } |
993 | 1045 |
994 void HostProcess::OnPolicyError() { | 1046 void HostProcess::OnPolicyError() { |
995 if (!context_->network_task_runner()->BelongsToCurrentThread()) { | 1047 if (!context_->network_task_runner()->BelongsToCurrentThread()) { |
996 context_->network_task_runner()->PostTask( | 1048 context_->network_task_runner()->PostTask( |
997 FROM_HERE, base::Bind(&HostProcess::OnPolicyError, this)); | 1049 FROM_HERE, base::Bind(&HostProcess::OnPolicyError, this)); |
998 return; | 1050 return; |
999 } | 1051 } |
1000 | 1052 |
1001 ShutdownHost(kInvalidHostConfigurationExitCode); | 1053 if (policy_state_ != POLICY_ERROR_REPORTED) { |
| 1054 policy_state_ = POLICY_ERROR_REPORT_PENDING; |
| 1055 if ((state_ == HOST_STARTED) || |
| 1056 (state_ == HOST_STARTING && !serialized_config_.empty())) { |
| 1057 ReportPolicyErrorAndRestartHost(); |
| 1058 } |
| 1059 } |
| 1060 } |
| 1061 |
| 1062 void HostProcess::ReportPolicyErrorAndRestartHost() { |
| 1063 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 1064 DCHECK(!serialized_config_.empty()); |
| 1065 |
| 1066 DCHECK_EQ(policy_state_, POLICY_ERROR_REPORT_PENDING); |
| 1067 policy_state_ = POLICY_ERROR_REPORTED; |
| 1068 |
| 1069 LOG(INFO) << "Restarting the host due to policy errors."; |
| 1070 RestartHost(kHostOfflineReasonPolicyReadError); |
1002 } | 1071 } |
1003 | 1072 |
1004 void HostProcess::ApplyHostDomainPolicy() { | 1073 void HostProcess::ApplyHostDomainPolicy() { |
1005 if (state_ != HOST_STARTED) | 1074 if (state_ != HOST_STARTED) |
1006 return; | 1075 return; |
1007 | 1076 |
1008 HOST_LOG << "Policy sets host domain: " << host_domain_; | 1077 HOST_LOG << "Policy sets host domain: " << host_domain_; |
1009 | 1078 |
1010 if (!host_domain_.empty()) { | 1079 if (!host_domain_.empty()) { |
1011 // If the user does not have a Google email, their client JID will not be | 1080 // If the user does not have a Google email, their client JID will not be |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1293 } | 1362 } |
1294 | 1363 |
1295 scoped_ptr<HostSignalingManager> HostProcess::CreateHostSignalingManager() { | 1364 scoped_ptr<HostSignalingManager> HostProcess::CreateHostSignalingManager() { |
1296 DCHECK(!host_id_.empty()); // |ApplyConfig| should already have been run. | 1365 DCHECK(!host_id_.empty()); // |ApplyConfig| should already have been run. |
1297 | 1366 |
1298 scoped_ptr<OAuthTokenGetter::OAuthCredentials> oauth_credentials( | 1367 scoped_ptr<OAuthTokenGetter::OAuthCredentials> oauth_credentials( |
1299 new OAuthTokenGetter::OAuthCredentials(xmpp_server_config_.username, | 1368 new OAuthTokenGetter::OAuthCredentials(xmpp_server_config_.username, |
1300 oauth_refresh_token_, | 1369 oauth_refresh_token_, |
1301 use_service_account_)); | 1370 use_service_account_)); |
1302 | 1371 |
1303 return HostSignalingManager::Create(this, context_->network_task_runner(), | 1372 return HostSignalingManager::Create( |
1304 context_->url_request_context_getter(), | 1373 this, context_->url_request_context_getter(), xmpp_server_config_, |
1305 xmpp_server_config_, talkgadget_prefix_, | 1374 talkgadget_prefix_, host_id_, key_pair_, directory_bot_jid_, |
1306 host_id_, key_pair_, directory_bot_jid_, | 1375 oauth_credentials.Pass()); |
1307 oauth_credentials.Pass()); | |
1308 } | 1376 } |
1309 | 1377 |
1310 void HostProcess::StartHostIfReady() { | 1378 void HostProcess::StartHostIfReady() { |
1311 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1379 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
1312 DCHECK_EQ(state_, HOST_INITIALIZING); | 1380 DCHECK_EQ(state_, HOST_STARTING); |
1313 | 1381 |
1314 // Start the host if both the config and the policies are loaded. | 1382 // Start the host if both the config and the policies are loaded. |
1315 if (!serialized_config_.empty() && policies_loaded_) | 1383 if (!serialized_config_.empty()) { |
1316 StartHost(); | 1384 if (policy_state_ == POLICY_LOADED) { |
| 1385 StartHost(); |
| 1386 } else if (policy_state_ == POLICY_ERROR_REPORT_PENDING) { |
| 1387 ReportPolicyErrorAndRestartHost(); |
| 1388 } |
| 1389 } |
1317 } | 1390 } |
1318 | 1391 |
1319 void HostProcess::StartHost() { | 1392 void HostProcess::StartHost() { |
1320 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1393 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
1321 DCHECK(!host_); | 1394 DCHECK(!host_); |
1322 DCHECK(!host_signaling_manager_); | 1395 DCHECK(!host_signaling_manager_); |
1323 | 1396 |
1324 DCHECK(state_ == HOST_INITIALIZING || state_ == HOST_STOPPING_TO_RESTART || | 1397 SetState(HOST_STARTED); |
1325 state_ == HOST_STOPPED) | |
1326 << "state_ = " << state_; | |
1327 state_ = HOST_STARTED; | |
1328 | 1398 |
1329 host_signaling_manager_ = CreateHostSignalingManager(); | 1399 host_signaling_manager_ = CreateHostSignalingManager(); |
1330 | 1400 |
1331 uint32 network_flags = 0; | 1401 uint32 network_flags = 0; |
1332 if (allow_nat_traversal_) { | 1402 if (allow_nat_traversal_) { |
1333 network_flags = NetworkSettings::NAT_TRAVERSAL_STUN | | 1403 network_flags = NetworkSettings::NAT_TRAVERSAL_STUN | |
1334 NetworkSettings::NAT_TRAVERSAL_OUTGOING; | 1404 NetworkSettings::NAT_TRAVERSAL_OUTGOING; |
1335 if (allow_relay_) | 1405 if (allow_relay_) |
1336 network_flags |= NetworkSettings::NAT_TRAVERSAL_RELAY; | 1406 network_flags |= NetworkSettings::NAT_TRAVERSAL_RELAY; |
1337 } | 1407 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1402 CreateAuthenticatorFactory(); | 1472 CreateAuthenticatorFactory(); |
1403 | 1473 |
1404 ApplyHostDomainPolicy(); | 1474 ApplyHostDomainPolicy(); |
1405 ApplyUsernamePolicy(); | 1475 ApplyUsernamePolicy(); |
1406 } | 1476 } |
1407 | 1477 |
1408 void HostProcess::OnAuthFailed() { | 1478 void HostProcess::OnAuthFailed() { |
1409 ShutdownHost(kInvalidOauthCredentialsExitCode); | 1479 ShutdownHost(kInvalidOauthCredentialsExitCode); |
1410 } | 1480 } |
1411 | 1481 |
1412 void HostProcess::RestartHost() { | 1482 void HostProcess::RestartHost(const std::string& host_offline_reason) { |
1413 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1483 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
1414 DCHECK_EQ(state_, HOST_STARTED); | 1484 DCHECK(!host_offline_reason.empty()); |
1415 | 1485 |
1416 state_ = HOST_STOPPING_TO_RESTART; | 1486 SetState(HOST_GOING_OFFLINE_TO_RESTART); |
1417 ShutdownOnNetworkThread(); | 1487 GoOffline(host_offline_reason); |
1418 } | |
1419 | |
1420 void HostProcess::SendOfflineReasonAndShutdownOnNetworkThread( | |
1421 HostExitCodes exit_code) { | |
1422 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | |
1423 DCHECK(host_signaling_manager_); | |
1424 host_signaling_manager_.release()->SendHostOfflineReasonAndDelete( | |
1425 ExitCodeToString(exit_code), | |
1426 base::TimeDelta::FromSeconds(kHostOfflineReasonTimeoutSeconds)); | |
1427 ShutdownOnNetworkThread(); | |
1428 } | 1488 } |
1429 | 1489 |
1430 void HostProcess::ShutdownHost(HostExitCodes exit_code) { | 1490 void HostProcess::ShutdownHost(HostExitCodes exit_code) { |
1431 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1491 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
1432 | 1492 |
1433 *exit_code_out_ = exit_code; | 1493 *exit_code_out_ = exit_code; |
1434 | 1494 |
1435 switch (state_) { | 1495 switch (state_) { |
1436 case HOST_INITIALIZING: | 1496 case HOST_STARTING: |
1437 state_ = HOST_STOPPING; | 1497 case HOST_STARTED: |
1438 DCHECK(!host_signaling_manager_); | 1498 SetState(HOST_GOING_OFFLINE_TO_STOP); |
1439 host_signaling_manager_ = CreateHostSignalingManager(); | 1499 GoOffline(ExitCodeToString(exit_code)); |
1440 SendOfflineReasonAndShutdownOnNetworkThread(exit_code); | |
1441 break; | 1500 break; |
1442 | 1501 |
1443 case HOST_STARTED: | 1502 case HOST_GOING_OFFLINE_TO_RESTART: |
1444 state_ = HOST_STOPPING; | 1503 SetState(HOST_GOING_OFFLINE_TO_STOP); |
1445 SendOfflineReasonAndShutdownOnNetworkThread(exit_code); | |
1446 break; | 1504 break; |
1447 | 1505 |
1448 case HOST_STOPPING_TO_RESTART: | 1506 case HOST_GOING_OFFLINE_TO_STOP: |
1449 state_ = HOST_STOPPING; | |
1450 break; | |
1451 | |
1452 case HOST_STOPPING: | |
1453 case HOST_STOPPED: | 1507 case HOST_STOPPED: |
1454 // Host is already stopped or being stopped. No action is required. | 1508 // Host is already stopped or being stopped. No action is required. |
1455 break; | 1509 break; |
1456 } | 1510 } |
1457 } | 1511 } |
1458 | 1512 |
1459 void HostProcess::ShutdownOnNetworkThread() { | 1513 void HostProcess::GoOffline(const std::string& host_offline_reason) { |
1460 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1514 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 1515 DCHECK(!host_offline_reason.empty()); |
| 1516 DCHECK((state_ == HOST_GOING_OFFLINE_TO_STOP) || |
| 1517 (state_ == HOST_GOING_OFFLINE_TO_RESTART)); |
1461 | 1518 |
| 1519 // Shut down everything except the HostSignalingManager. |
1462 host_.reset(); | 1520 host_.reset(); |
1463 host_event_logger_.reset(); | 1521 host_event_logger_.reset(); |
1464 host_status_logger_.reset(); | 1522 host_status_logger_.reset(); |
1465 host_signaling_manager_.reset(); | |
1466 host_change_notification_listener_.reset(); | 1523 host_change_notification_listener_.reset(); |
1467 | 1524 |
1468 if (state_ == HOST_STOPPING_TO_RESTART) { | 1525 // Before shutting down HostSignalingManager, send the |host_offline_reason| |
1469 StartHost(); | 1526 // if possible (i.e. if we have the config). |
1470 } else if (state_ == HOST_STOPPING) { | 1527 if (!serialized_config_.empty()) { |
1471 state_ = HOST_STOPPED; | 1528 if (!host_signaling_manager_) { |
| 1529 host_signaling_manager_ = CreateHostSignalingManager(); |
| 1530 } |
| 1531 |
| 1532 host_signaling_manager_->SendHostOfflineReason( |
| 1533 host_offline_reason, |
| 1534 base::TimeDelta::FromSeconds(kHostOfflineReasonTimeoutSeconds), |
| 1535 base::Bind(&HostProcess::OnHostOfflineReasonAck, this)); |
| 1536 return; // Shutdown will resume after OnHostOfflineReasonAck. |
| 1537 } |
| 1538 |
| 1539 // Continue the shutdown without sending the host offline reason. |
| 1540 HOST_LOG << "Can't send offline reason (" << host_offline_reason << ") " |
| 1541 << "without a valid host config."; |
| 1542 OnHostOfflineReasonAck(false); |
| 1543 } |
| 1544 |
| 1545 void HostProcess::OnHostOfflineReasonAck(bool success) { |
| 1546 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 1547 DCHECK(!host_); // Assert that the host is really offline at this point. |
| 1548 |
| 1549 HOST_LOG << "SendHostOfflineReason " << (success ? "succeeded." : "failed."); |
| 1550 host_signaling_manager_.reset(); |
| 1551 |
| 1552 if (state_ == HOST_GOING_OFFLINE_TO_RESTART) { |
| 1553 SetState(HOST_STARTING); |
| 1554 StartHostIfReady(); |
| 1555 } else if (state_ == HOST_GOING_OFFLINE_TO_STOP) { |
| 1556 SetState(HOST_STOPPED); |
1472 | 1557 |
1473 shutdown_watchdog_->SetExitCode(*exit_code_out_); | 1558 shutdown_watchdog_->SetExitCode(*exit_code_out_); |
1474 shutdown_watchdog_->Arm(); | 1559 shutdown_watchdog_->Arm(); |
1475 | 1560 |
1476 config_watcher_.reset(); | 1561 config_watcher_.reset(); |
1477 | 1562 |
1478 // Complete the rest of shutdown on the main thread. | 1563 // Complete the rest of shutdown on the main thread. |
1479 context_->ui_task_runner()->PostTask( | 1564 context_->ui_task_runner()->PostTask( |
1480 FROM_HERE, base::Bind(&HostProcess::ShutdownOnUiThread, this)); | 1565 FROM_HERE, base::Bind(&HostProcess::ShutdownOnUiThread, this)); |
1481 } else { | 1566 } else { |
1482 // This method is only called in STOPPING_TO_RESTART and STOPPING states. | |
1483 NOTREACHED(); | 1567 NOTREACHED(); |
1484 } | 1568 } |
1485 } | 1569 } |
1486 | 1570 |
1487 void HostProcess::OnCrash(const std::string& function_name, | 1571 void HostProcess::OnCrash(const std::string& function_name, |
1488 const std::string& file_name, | 1572 const std::string& file_name, |
1489 const int& line_number) { | 1573 const int& line_number) { |
1490 char message[1024]; | 1574 char message[1024]; |
1491 base::snprintf(message, sizeof(message), | 1575 base::snprintf(message, sizeof(message), |
1492 "Requested by %s at %s, line %d.", | 1576 "Requested by %s at %s, line %d.", |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1542 base::TimeDelta::FromSeconds(kShutdownTimeoutSeconds)); | 1626 base::TimeDelta::FromSeconds(kShutdownTimeoutSeconds)); |
1543 new HostProcess(context.Pass(), &exit_code, &shutdown_watchdog); | 1627 new HostProcess(context.Pass(), &exit_code, &shutdown_watchdog); |
1544 | 1628 |
1545 // Run the main (also UI) message loop until the host no longer needs it. | 1629 // Run the main (also UI) message loop until the host no longer needs it. |
1546 message_loop.Run(); | 1630 message_loop.Run(); |
1547 | 1631 |
1548 return exit_code; | 1632 return exit_code; |
1549 } | 1633 } |
1550 | 1634 |
1551 } // namespace remoting | 1635 } // namespace remoting |
OLD | NEW |