| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |