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

Side by Side Diff: mojo/edk/system/node_controller.cc

Issue 1685183004: Bootstrap Mojo IPC independent of Chrome IPC (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: and fix posix Created 4 years, 10 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "mojo/edk/system/node_controller.h" 5 #include "mojo/edk/system/node_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 109
110 void NodeController::SetIOTaskRunner( 110 void NodeController::SetIOTaskRunner(
111 scoped_refptr<base::TaskRunner> task_runner) { 111 scoped_refptr<base::TaskRunner> task_runner) {
112 io_task_runner_ = task_runner; 112 io_task_runner_ = task_runner;
113 ThreadDestructionObserver::Create( 113 ThreadDestructionObserver::Create(
114 io_task_runner_, 114 io_task_runner_,
115 base::Bind(&NodeController::DropAllPeers, base::Unretained(this))); 115 base::Bind(&NodeController::DropAllPeers, base::Unretained(this)));
116 } 116 }
117 117
118 void NodeController::ConnectToChild(base::ProcessHandle process_handle, 118 void NodeController::ConnectToChild(base::ProcessHandle process_handle,
119 ScopedPlatformHandle platform_handle) { 119 ScopedPlatformHandle platform_handle,
120 const std::string& secret) {
121 #if !defined(OS_WIN)
122 // We don't require or support secret validation on non-Windows platforms.
123 CHECK(secret.empty());
124 #endif
120 io_task_runner_->PostTask( 125 io_task_runner_->PostTask(
121 FROM_HERE, 126 FROM_HERE,
122 base::Bind(&NodeController::ConnectToChildOnIOThread, 127 base::Bind(&NodeController::ConnectToChildOnIOThread,
123 base::Unretained(this), 128 base::Unretained(this), process_handle,
124 process_handle, 129 base::Passed(&platform_handle), secret));
125 base::Passed(&platform_handle)));
126 } 130 }
127 131
128 void NodeController::ConnectToParent(ScopedPlatformHandle platform_handle) { 132 void NodeController::ConnectToParent(ScopedPlatformHandle platform_handle,
133 const std::string& secret) {
134 #if !defined(OS_WIN)
135 // We don't require or support secret validation on non-Windows platforms.
136 CHECK(secret.empty());
137 #endif
138
129 // TODO(amistry): Consider the need for a broker on Windows. 139 // TODO(amistry): Consider the need for a broker on Windows.
130 #if defined(OS_POSIX) 140 #if defined(OS_POSIX)
131 // On posix, use the bootstrap channel for the broker and receive the node's 141 // On posix, use the bootstrap channel for the broker and receive the node's
132 // channel synchronously as the first message from the broker. 142 // channel synchronously as the first message from the broker.
133 broker_.reset(new Broker(std::move(platform_handle))); 143 broker_.reset(new Broker(std::move(platform_handle)));
134 platform_handle = broker_->GetParentPlatformHandle(); 144 platform_handle = broker_->GetParentPlatformHandle();
135 #endif 145 #endif
136 146
137 io_task_runner_->PostTask( 147 io_task_runner_->PostTask(
138 FROM_HERE, 148 FROM_HERE,
139 base::Bind(&NodeController::ConnectToParentOnIOThread, 149 base::Bind(&NodeController::ConnectToParentOnIOThread,
140 base::Unretained(this), 150 base::Unretained(this), base::Passed(&platform_handle),
141 base::Passed(&platform_handle))); 151 secret));
142 } 152 }
143 153
144 void NodeController::SetPortObserver( 154 void NodeController::SetPortObserver(
145 const ports::PortRef& port, 155 const ports::PortRef& port,
146 const scoped_refptr<PortObserver>& observer) { 156 const scoped_refptr<PortObserver>& observer) {
147 node_->SetUserData(port, observer); 157 node_->SetUserData(port, observer);
148 } 158 }
149 159
150 void NodeController::ClosePort(const ports::PortRef& port) { 160 void NodeController::ClosePort(const ports::PortRef& port) {
151 SetPortObserver(port, nullptr); 161 SetPortObserver(port, nullptr);
(...skipping 21 matching lines...) Expand all
173 DVLOG(2) << "Reserving port " << port.name() << "@" << name_ << " for token " 183 DVLOG(2) << "Reserving port " << port.name() << "@" << name_ << " for token "
174 << token; 184 << token;
175 185
176 base::AutoLock lock(reserved_ports_lock_); 186 base::AutoLock lock(reserved_ports_lock_);
177 auto result = reserved_ports_.insert(std::make_pair(token, port)); 187 auto result = reserved_ports_.insert(std::make_pair(token, port));
178 DCHECK(result.second); 188 DCHECK(result.second);
179 } 189 }
180 190
181 void NodeController::MergePortIntoParent(const std::string& token, 191 void NodeController::MergePortIntoParent(const std::string& token,
182 const ports::PortRef& port) { 192 const ports::PortRef& port) {
193 {
194 // This request may be coming from within the process that reserved the
195 // "parent" side (e.g. for Chrome single-process mode), so if this token is
196 // reserved locally, merge locally instead.
197 base::AutoLock lock(reserved_ports_lock_);
198 auto it = reserved_ports_.find(token);
199 if (it != reserved_ports_.end()) {
200 node_->MergePorts(port, name_, it->second.name());
201 reserved_ports_.erase(it);
202 return;
203 }
204 }
205
183 scoped_refptr<NodeChannel> parent = GetParentChannel(); 206 scoped_refptr<NodeChannel> parent = GetParentChannel();
184 if (parent) { 207 if (parent) {
185 parent->RequestPortMerge(port.name(), token); 208 parent->RequestPortMerge(port.name(), token);
186 return; 209 return;
187 } 210 }
188 211
189 base::AutoLock lock(pending_port_merges_lock_); 212 base::AutoLock lock(pending_port_merges_lock_);
190 pending_port_merges_.push_back(std::make_pair(token, port)); 213 pending_port_merges_.push_back(std::make_pair(token, port));
191 } 214 }
192 215
(...skipping 15 matching lines...) Expand all
208 { 231 {
209 base::AutoLock lock(shutdown_lock_); 232 base::AutoLock lock(shutdown_lock_);
210 shutdown_callback_ = callback; 233 shutdown_callback_ = callback;
211 } 234 }
212 235
213 AttemptShutdownIfRequested(); 236 AttemptShutdownIfRequested();
214 } 237 }
215 238
216 void NodeController::ConnectToChildOnIOThread( 239 void NodeController::ConnectToChildOnIOThread(
217 base::ProcessHandle process_handle, 240 base::ProcessHandle process_handle,
218 ScopedPlatformHandle platform_handle) { 241 ScopedPlatformHandle platform_handle,
242 const std::string& secret) {
219 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 243 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
220 244
221 #if defined(OS_POSIX) 245 #if defined(OS_POSIX)
222 PlatformChannelPair node_channel; 246 PlatformChannelPair node_channel;
223 // BrokerHost owns itself. 247 // BrokerHost owns itself.
224 BrokerHost* broker_host = new BrokerHost(std::move(platform_handle)); 248 BrokerHost* broker_host = new BrokerHost(std::move(platform_handle));
225 broker_host->SendChannel(node_channel.PassClientHandle()); 249 broker_host->SendChannel(node_channel.PassClientHandle());
226 scoped_refptr<NodeChannel> channel = NodeChannel::Create( 250 scoped_refptr<NodeChannel> channel = NodeChannel::Create(
227 this, node_channel.PassServerHandle(), io_task_runner_); 251 this, node_channel.PassServerHandle(), io_task_runner_);
228 #else 252 #else
229 scoped_refptr<NodeChannel> channel = 253 scoped_refptr<NodeChannel> channel =
230 NodeChannel::Create(this, std::move(platform_handle), io_task_runner_); 254 NodeChannel::Create(this, std::move(platform_handle), io_task_runner_);
231 #endif 255 #endif
232 256
233 // We set up the child channel with a temporary name so it can be identified 257 // We set up the child channel with a temporary name so it can be identified
234 // as a pending child if it writes any messages to the channel. We may start 258 // as a pending child if it writes any messages to the channel. We may start
235 // receiving messages from it (though we shouldn't) as soon as Start() is 259 // receiving messages from it (though we shouldn't) as soon as Start() is
236 // called below. 260 // called below.
237 ports::NodeName token; 261 ports::NodeName token;
238 GenerateRandomName(&token); 262 GenerateRandomName(&token);
239 263
240 pending_children_.insert(std::make_pair(token, channel)); 264 pending_children_.insert(std::make_pair(token, channel));
241 RecordPendingChildCount(pending_children_.size()); 265 RecordPendingChildCount(pending_children_.size());
242 266
243 channel->SetRemoteNodeName(token); 267 channel->SetRemoteNodeName(token);
244 channel->SetRemoteProcessHandle(process_handle); 268 channel->SetRemoteProcessHandle(process_handle);
269 channel->SetExpectedSecret(secret);
245 channel->Start(); 270 channel->Start();
246 271
247 channel->AcceptChild(name_, token); 272 channel->AcceptChild(name_, token);
248 } 273 }
249 274
250 void NodeController::ConnectToParentOnIOThread( 275 void NodeController::ConnectToParentOnIOThread(
251 ScopedPlatformHandle platform_handle) { 276 ScopedPlatformHandle platform_handle,
277 const std::string& secret) {
252 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 278 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
253 279
254 base::AutoLock lock(parent_lock_); 280 base::AutoLock lock(parent_lock_);
255 DCHECK(parent_name_ == ports::kInvalidNodeName); 281 DCHECK(parent_name_ == ports::kInvalidNodeName);
256 282
257 // At this point we don't know the parent's name, so we can't yet insert it 283 // At this point we don't know the parent's name, so we can't yet insert it
258 // into our |peers_| map. That will happen as soon as we receive an 284 // into our |peers_| map. That will happen as soon as we receive an
259 // AcceptChild message from them. 285 // AcceptChild message from them.
260 bootstrap_parent_channel_ = 286 bootstrap_parent_channel_ =
261 NodeChannel::Create(this, std::move(platform_handle), io_task_runner_); 287 NodeChannel::Create(this, std::move(platform_handle), io_task_runner_);
262 bootstrap_parent_channel_->Start(); 288 bootstrap_parent_channel_->Start();
289
290 if (!secret.empty()) {
291 // On Windows we start out by sending a secret token to the parent process
292 // which it will use to authenticate our end of the pipe.
293 #if !defined(OS_WIN)
294 // We don't ever want to send a secret on non-Windows.
295 NOTREACHED();
296 #endif
297 bootstrap_parent_channel_->SendSecret(secret);
298 }
263 } 299 }
264 300
265 scoped_refptr<NodeChannel> NodeController::GetPeerChannel( 301 scoped_refptr<NodeChannel> NodeController::GetPeerChannel(
266 const ports::NodeName& name) { 302 const ports::NodeName& name) {
267 base::AutoLock lock(peers_lock_); 303 base::AutoLock lock(peers_lock_);
268 auto it = peers_.find(name); 304 auto it = peers_.find(name);
269 if (it == peers_.end()) 305 if (it == peers_.end())
270 return nullptr; 306 return nullptr;
271 return it->second; 307 return it->second;
272 } 308 }
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 shutdown_callback_.Reset(); 906 shutdown_callback_.Reset();
871 } 907 }
872 908
873 DCHECK(!callback.is_null()); 909 DCHECK(!callback.is_null());
874 910
875 callback.Run(); 911 callback.Run();
876 } 912 }
877 913
878 } // namespace edk 914 } // namespace edk
879 } // namespace mojo 915 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698