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

Side by Side Diff: remoting/host/win/worker_process_launcher.cc

Issue 10855249: [Chromoting] The daemon process now starts the networking process and passes the host configuration… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added missing signal.h Created 8 years, 3 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) 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 #include "remoting/host/win/worker_process_launcher.h" 5 #include "remoting/host/win/worker_process_launcher.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <sddl.h> 8 #include <sddl.h>
9 #include <limits> 9 #include <limits>
10 10
11 #include "base/base_switches.h" 11 #include "base/base_switches.h"
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/bind_helpers.h" 13 #include "base/bind_helpers.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/single_thread_task_runner.h" 15 #include "base/single_thread_task_runner.h"
16 #include "base/process_util.h" 16 #include "base/process_util.h"
17 #include "base/rand_util.h" 17 #include "base/rand_util.h"
18 #include "base/stringprintf.h" 18 #include "base/stringprintf.h"
19 #include "base/time.h" 19 #include "base/time.h"
20 #include "base/utf_string_conversions.h" 20 #include "base/utf_string_conversions.h"
21 #include "base/win/scoped_handle.h" 21 #include "base/win/scoped_handle.h"
22 #include "ipc/ipc_channel_proxy.h" 22 #include "ipc/ipc_channel_proxy.h"
23 #include "ipc/ipc_message.h" 23 #include "ipc/ipc_message.h"
24 #include "remoting/host/worker_process_ipc_delegate.h"
24 25
25 using base::win::ScopedHandle; 26 using base::win::ScopedHandle;
26 27
27 namespace { 28 namespace {
28 29
29 // Match the pipe name prefix used by Chrome IPC channels so that the client 30 // Match the pipe name prefix used by Chrome IPC channels so that the client
30 // could use Chrome IPC APIs instead of connecting manually. 31 // could use Chrome IPC APIs instead of connecting manually.
31 const char kChromePipeNamePrefix[] = "\\\\.\\pipe\\chrome."; 32 const char kChromePipeNamePrefix[] = "\\\\.\\pipe\\chrome.";
32 33
33 } // namespace 34 } // namespace
34 35
35 namespace remoting { 36 namespace remoting {
36 37
37 WorkerProcessLauncher::Delegate::~Delegate() { 38 WorkerProcessLauncher::Delegate::~Delegate() {
38 } 39 }
39 40
40 WorkerProcessLauncher::WorkerProcessLauncher( 41 WorkerProcessLauncher::WorkerProcessLauncher(
41 Delegate* delegate, 42 Delegate* launcher_delegate,
43 WorkerProcessIpcDelegate* worker_delegate,
42 const base::Closure& stopped_callback, 44 const base::Closure& stopped_callback,
43 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, 45 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
44 scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner) 46 scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner)
45 : Stoppable(main_task_runner, stopped_callback), 47 : Stoppable(main_task_runner, stopped_callback),
46 delegate_(delegate), 48 launcher_delegate_(launcher_delegate),
49 worker_delegate_(worker_delegate),
47 main_task_runner_(main_task_runner), 50 main_task_runner_(main_task_runner),
48 ipc_task_runner_(ipc_task_runner) { 51 ipc_task_runner_(ipc_task_runner) {
49 } 52 }
50 53
51 WorkerProcessLauncher::~WorkerProcessLauncher() { 54 WorkerProcessLauncher::~WorkerProcessLauncher() {
52 DCHECK(main_task_runner_->BelongsToCurrentThread()); 55 DCHECK(main_task_runner_->BelongsToCurrentThread());
53 } 56 }
54 57
55 void WorkerProcessLauncher::Start(const std::string& pipe_sddl) { 58 void WorkerProcessLauncher::Start(const std::string& pipe_sddl) {
56 DCHECK(main_task_runner_->BelongsToCurrentThread()); 59 DCHECK(main_task_runner_->BelongsToCurrentThread());
57 DCHECK(ipc_channel_.get() == NULL); 60 DCHECK(ipc_channel_.get() == NULL);
58 DCHECK(!pipe_.IsValid()); 61 DCHECK(!pipe_.IsValid());
59 DCHECK(!process_exit_event_.IsValid()); 62 DCHECK(!process_exit_event_.IsValid());
60 DCHECK(process_watcher_.GetWatchedObject() == NULL); 63 DCHECK(process_watcher_.GetWatchedObject() == NULL);
61 64
62 std::string channel_name = GenerateRandomChannelId(); 65 std::string channel_name = GenerateRandomChannelId();
63 if (CreatePipeForIpcChannel(channel_name, pipe_sddl, &pipe_)) { 66 if (CreatePipeForIpcChannel(channel_name, pipe_sddl, &pipe_)) {
64 // Wrap the pipe into an IPC channel. 67 // Wrap the pipe into an IPC channel.
65 ipc_channel_.reset(new IPC::ChannelProxy( 68 ipc_channel_.reset(new IPC::ChannelProxy(
66 IPC::ChannelHandle(pipe_), 69 IPC::ChannelHandle(pipe_),
67 IPC::Channel::MODE_SERVER, 70 IPC::Channel::MODE_SERVER,
68 this, 71 this,
69 ipc_task_runner_)); 72 ipc_task_runner_));
70 73
71 // Launch the process and attach an object watcher to the returned process 74 // Launch the process and attach an object watcher to the returned process
72 // handle so that we get notified if the process terminates. 75 // handle so that we get notified if the process terminates.
73 if (delegate_->DoLaunchProcess(channel_name, &process_exit_event_)) { 76 if (launcher_delegate_->DoLaunchProcess(channel_name,
77 &process_exit_event_)) {
74 if (process_watcher_.StartWatching(process_exit_event_, this)) { 78 if (process_watcher_.StartWatching(process_exit_event_, this)) {
75 return; 79 return;
76 } 80 }
77 81
78 delegate_->DoKillProcess(CONTROL_C_EXIT); 82 launcher_delegate_->DoKillProcess(CONTROL_C_EXIT);
79 } 83 }
80 } 84 }
81 85
82 Stop(); 86 Stop();
83 } 87 }
84 88
85 void WorkerProcessLauncher::Send(IPC::Message* message) { 89 void WorkerProcessLauncher::Send(IPC::Message* message) {
86 DCHECK(main_task_runner_->BelongsToCurrentThread()); 90 DCHECK(main_task_runner_->BelongsToCurrentThread());
87 91
88 ipc_channel_->Send(message); 92 if (ipc_channel_.get()) {
93 ipc_channel_->Send(message);
94 } else {
95 delete message;
96 }
89 } 97 }
90 98
91 void WorkerProcessLauncher::OnObjectSignaled(HANDLE object) { 99 void WorkerProcessLauncher::OnObjectSignaled(HANDLE object) {
92 DCHECK(main_task_runner_->BelongsToCurrentThread()); 100 DCHECK(main_task_runner_->BelongsToCurrentThread());
93 DCHECK(process_watcher_.GetWatchedObject() == NULL); 101 DCHECK(process_watcher_.GetWatchedObject() == NULL);
94 102
95 Stop(); 103 Stop();
96 } 104 }
97 105
98 bool WorkerProcessLauncher::OnMessageReceived(const IPC::Message& message) { 106 bool WorkerProcessLauncher::OnMessageReceived(const IPC::Message& message) {
99 DCHECK(main_task_runner_->BelongsToCurrentThread()); 107 DCHECK(main_task_runner_->BelongsToCurrentThread());
100 DCHECK(ipc_channel_.get() != NULL); 108 DCHECK(ipc_channel_.get() != NULL);
101 DCHECK(pipe_.IsValid()); 109 DCHECK(pipe_.IsValid());
102 DCHECK(process_exit_event_.IsValid()); 110 DCHECK(process_exit_event_.IsValid());
103 111
104 return delegate_->OnMessageReceived(message); 112 return worker_delegate_->OnMessageReceived(message);
105 } 113 }
106 114
107 void WorkerProcessLauncher::OnChannelConnected(int32 peer_pid) { 115 void WorkerProcessLauncher::OnChannelConnected(int32 peer_pid) {
108 DCHECK(main_task_runner_->BelongsToCurrentThread()); 116 DCHECK(main_task_runner_->BelongsToCurrentThread());
109 DCHECK(ipc_channel_.get() != NULL); 117 DCHECK(ipc_channel_.get() != NULL);
110 DCHECK(pipe_.IsValid()); 118 DCHECK(pipe_.IsValid());
111 DCHECK(process_exit_event_.IsValid()); 119 DCHECK(process_exit_event_.IsValid());
112 120
113 // |peer_pid| is send by the client and cannot be trusted. 121 // |peer_pid| is send by the client and cannot be trusted.
114 // GetNamedPipeClientProcessId() is not available on XP. The pipe's security 122 // GetNamedPipeClientProcessId() is not available on XP. The pipe's security
115 // descriptor is the only protection we currently have against malicious 123 // descriptor is the only protection we currently have against malicious
116 // clients. 124 // clients.
117 // 125 //
118 // If we'd like to be able to launch low-privileged workers and let them 126 // If we'd like to be able to launch low-privileged workers and let them
119 // connect back, the pipe handle should be passed to the worker instead of 127 // connect back, the pipe handle should be passed to the worker instead of
120 // the pipe name. 128 // the pipe name.
121 delegate_->OnChannelConnected(); 129 worker_delegate_->OnChannelConnected();
122 } 130 }
123 131
124 void WorkerProcessLauncher::OnChannelError() { 132 void WorkerProcessLauncher::OnChannelError() {
125 DCHECK(main_task_runner_->BelongsToCurrentThread()); 133 DCHECK(main_task_runner_->BelongsToCurrentThread());
126 DCHECK(ipc_channel_.get() != NULL); 134 DCHECK(ipc_channel_.get() != NULL);
127 DCHECK(pipe_.IsValid()); 135 DCHECK(pipe_.IsValid());
128 DCHECK(process_exit_event_.IsValid()); 136 DCHECK(process_exit_event_.IsValid());
129 137
130 // Schedule a delayed termination of the worker process. Usually, the pipe is 138 // Schedule a delayed termination of the worker process. Usually, the pipe is
131 // disconnected when the worker process is about to exit. Waiting a little bit 139 // disconnected when the worker process is about to exit. Waiting a little bit
132 // here allows the worker to exit completely and so, notify 140 // here allows the worker to exit completely and so, notify
133 // |process_watcher_|. As the result DoKillProcess() will not be called and 141 // |process_watcher_|. As the result DoKillProcess() will not be called and
134 // the original exit code reported by the worker process will be retrieved. 142 // the original exit code reported by the worker process will be retrieved.
135 ipc_error_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(5), 143 ipc_error_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(5),
136 this, &WorkerProcessLauncher::Stop); 144 this, &WorkerProcessLauncher::Stop);
137 } 145 }
138 146
139 void WorkerProcessLauncher::DoStop() { 147 void WorkerProcessLauncher::DoStop() {
140 DCHECK(main_task_runner_->BelongsToCurrentThread()); 148 DCHECK(main_task_runner_->BelongsToCurrentThread());
141 149
142 ipc_channel_.reset(); 150 ipc_channel_.reset();
143 pipe_.Close(); 151 pipe_.Close();
144 152
145 // Kill the process if it has been started already. 153 // Kill the process if it has been started already.
146 if (process_watcher_.GetWatchedObject() != NULL) { 154 if (process_watcher_.GetWatchedObject() != NULL) {
147 delegate_->DoKillProcess(CONTROL_C_EXIT); 155 launcher_delegate_->DoKillProcess(CONTROL_C_EXIT);
148 return; 156 return;
149 } 157 }
150 158
151 ipc_error_timer_.Stop(); 159 ipc_error_timer_.Stop();
152 160
153 DCHECK(ipc_channel_.get() == NULL); 161 DCHECK(ipc_channel_.get() == NULL);
154 DCHECK(!pipe_.IsValid()); 162 DCHECK(!pipe_.IsValid());
155 DCHECK(process_watcher_.GetWatchedObject() == NULL); 163 DCHECK(process_watcher_.GetWatchedObject() == NULL);
156 164
157 process_exit_event_.Close(); 165 process_exit_event_.Close();
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 } 218 }
211 219
212 // N.B. Copied from src/content/common/child_process_host_impl.cc 220 // N.B. Copied from src/content/common/child_process_host_impl.cc
213 std::string WorkerProcessLauncher::GenerateRandomChannelId() { 221 std::string WorkerProcessLauncher::GenerateRandomChannelId() {
214 return base::StringPrintf("%d.%p.%d", 222 return base::StringPrintf("%d.%p.%d",
215 base::GetCurrentProcId(), this, 223 base::GetCurrentProcId(), this,
216 base::RandInt(0, std::numeric_limits<int>::max())); 224 base::RandInt(0, std::numeric_limits<int>::max()));
217 } 225 }
218 226
219 } // namespace remoting 227 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/win/worker_process_launcher.h ('k') | remoting/host/win/wts_session_process_launcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698