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

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

Issue 2043713004: Mojo: Add NotifyBadMessage API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 void NodeController::SetIOTaskRunner( 134 void NodeController::SetIOTaskRunner(
135 scoped_refptr<base::TaskRunner> task_runner) { 135 scoped_refptr<base::TaskRunner> task_runner) {
136 io_task_runner_ = task_runner; 136 io_task_runner_ = task_runner;
137 ThreadDestructionObserver::Create( 137 ThreadDestructionObserver::Create(
138 io_task_runner_, 138 io_task_runner_,
139 base::Bind(&NodeController::DropAllPeers, base::Unretained(this))); 139 base::Bind(&NodeController::DropAllPeers, base::Unretained(this)));
140 } 140 }
141 141
142 void NodeController::ConnectToChild(base::ProcessHandle process_handle, 142 void NodeController::ConnectToChild(base::ProcessHandle process_handle,
143 ScopedPlatformHandle platform_handle, 143 ScopedPlatformHandle platform_handle,
144 const std::string& child_token) { 144 const std::string& child_token,
145 const base::Closure& bad_message_callback) {
145 // Generate the temporary remote node name here so that it can be associated 146 // Generate the temporary remote node name here so that it can be associated
146 // with the embedder's child_token. If an error occurs in the child process 147 // with the embedder's child_token. If an error occurs in the child process
147 // after it is launched, but before any reserved ports are connected, this can 148 // after it is launched, but before any reserved ports are connected, this can
148 // be used to clean up any dangling ports. 149 // be used to clean up any dangling ports.
149 ports::NodeName node_name; 150 ports::NodeName node_name;
150 GenerateRandomName(&node_name); 151 GenerateRandomName(&node_name);
151 152
152 { 153 {
153 base::AutoLock lock(reserved_ports_lock_); 154 base::AutoLock lock(reserved_ports_lock_);
154 bool inserted = pending_child_tokens_.insert( 155 bool inserted = pending_child_tokens_.insert(
155 std::make_pair(node_name, child_token)).second; 156 std::make_pair(node_name, child_token)).second;
156 DCHECK(inserted); 157 DCHECK(inserted);
157 } 158 }
158 159
159 io_task_runner_->PostTask( 160 io_task_runner_->PostTask(
160 FROM_HERE, 161 FROM_HERE,
161 base::Bind(&NodeController::ConnectToChildOnIOThread, 162 base::Bind(&NodeController::ConnectToChildOnIOThread,
162 base::Unretained(this), 163 base::Unretained(this),
163 process_handle, 164 process_handle,
164 base::Passed(&platform_handle), 165 base::Passed(&platform_handle),
165 node_name)); 166 node_name,
167 bad_message_callback));
166 } 168 }
167 169
168 void NodeController::CloseChildPorts(const std::string& child_token) { 170 void NodeController::CloseChildPorts(const std::string& child_token) {
169 std::vector<ports::PortRef> ports_to_close; 171 std::vector<ports::PortRef> ports_to_close;
170 { 172 {
171 std::vector<std::string> port_tokens; 173 std::vector<std::string> port_tokens;
172 base::AutoLock lock(reserved_ports_lock_); 174 base::AutoLock lock(reserved_ports_lock_);
173 for (const auto& port : reserved_ports_) { 175 for (const auto& port : reserved_ports_) {
174 if (port.second.child_token == child_token) { 176 if (port.second.child_token == child_token) {
175 DVLOG(1) << "Closing reserved port " << port.second.port.name(); 177 DVLOG(1) << "Closing reserved port " << port.second.port.name();
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 void NodeController::RequestShutdown(const base::Closure& callback) { 305 void NodeController::RequestShutdown(const base::Closure& callback) {
304 { 306 {
305 base::AutoLock lock(shutdown_lock_); 307 base::AutoLock lock(shutdown_lock_);
306 shutdown_callback_ = callback; 308 shutdown_callback_ = callback;
307 shutdown_callback_flag_.Set(true); 309 shutdown_callback_flag_.Set(true);
308 } 310 }
309 311
310 AttemptShutdownIfRequested(); 312 AttemptShutdownIfRequested();
311 } 313 }
312 314
315 void NodeController::NotifyBadMessageFrom(const ports::NodeName& source_node) {
316 scoped_refptr<NodeChannel> peer = GetPeerChannel(source_node);
317 peer->NotifyBadMessage();
Anand Mistry (off Chromium) 2016/06/10 10:28:20 Check peer != nullptr. The peer could have closed
318 }
319
313 void NodeController::ConnectToChildOnIOThread( 320 void NodeController::ConnectToChildOnIOThread(
314 base::ProcessHandle process_handle, 321 base::ProcessHandle process_handle,
315 ScopedPlatformHandle platform_handle, 322 ScopedPlatformHandle platform_handle,
316 ports::NodeName token) { 323 ports::NodeName token,
324 const base::Closure& bad_message_callback) {
317 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 325 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
318 326
319 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_NACL) 327 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_NACL)
320 PlatformChannelPair node_channel; 328 PlatformChannelPair node_channel;
321 // BrokerHost owns itself. 329 // BrokerHost owns itself.
322 BrokerHost* broker_host = new BrokerHost(std::move(platform_handle)); 330 BrokerHost* broker_host = new BrokerHost(std::move(platform_handle));
323 broker_host->SendChannel(node_channel.PassClientHandle()); 331 broker_host->SendChannel(node_channel.PassClientHandle());
324 scoped_refptr<NodeChannel> channel = NodeChannel::Create( 332 scoped_refptr<NodeChannel> channel = NodeChannel::Create(
325 this, node_channel.PassServerHandle(), io_task_runner_); 333 this, node_channel.PassServerHandle(), io_task_runner_,
334 bad_message_callback);
326 #else 335 #else
327 scoped_refptr<NodeChannel> channel = 336 scoped_refptr<NodeChannel> channel =
328 NodeChannel::Create(this, std::move(platform_handle), io_task_runner_); 337 NodeChannel::Create(this, std::move(platform_handle), io_task_runner_,
338 bad_message_callback);
329 #endif 339 #endif
330 340
331 // We set up the child channel with a temporary name so it can be identified 341 // We set up the child channel with a temporary name so it can be identified
332 // as a pending child if it writes any messages to the channel. We may start 342 // as a pending child if it writes any messages to the channel. We may start
333 // receiving messages from it (though we shouldn't) as soon as Start() is 343 // receiving messages from it (though we shouldn't) as soon as Start() is
334 // called below. 344 // called below.
335 345
336 pending_children_.insert(std::make_pair(token, channel)); 346 pending_children_.insert(std::make_pair(token, channel));
337 RecordPendingChildCount(pending_children_.size()); 347 RecordPendingChildCount(pending_children_.size());
338 348
339 channel->SetRemoteNodeName(token); 349 channel->SetRemoteNodeName(token);
340 channel->SetRemoteProcessHandle(process_handle); 350 channel->SetRemoteProcessHandle(process_handle);
341 channel->Start(); 351 channel->Start();
342 352
343 channel->AcceptChild(name_, token); 353 channel->AcceptChild(name_, token);
344 } 354 }
345 355
346 void NodeController::ConnectToParentOnIOThread( 356 void NodeController::ConnectToParentOnIOThread(
347 ScopedPlatformHandle platform_handle) { 357 ScopedPlatformHandle platform_handle) {
348 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 358 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
349 359
350 { 360 {
351 base::AutoLock lock(parent_lock_); 361 base::AutoLock lock(parent_lock_);
352 DCHECK(parent_name_ == ports::kInvalidNodeName); 362 DCHECK(parent_name_ == ports::kInvalidNodeName);
353 363
354 // At this point we don't know the parent's name, so we can't yet insert it 364 // At this point we don't know the parent's name, so we can't yet insert it
355 // into our |peers_| map. That will happen as soon as we receive an 365 // into our |peers_| map. That will happen as soon as we receive an
356 // AcceptChild message from them. 366 // AcceptChild message from them.
357 bootstrap_parent_channel_ = 367 bootstrap_parent_channel_ =
358 NodeChannel::Create(this, std::move(platform_handle), io_task_runner_); 368 NodeChannel::Create(this, std::move(platform_handle), io_task_runner_,
369 base::Closure());
359 } 370 }
360 bootstrap_parent_channel_->Start(); 371 bootstrap_parent_channel_->Start();
361 } 372 }
362 373
363 scoped_refptr<NodeChannel> NodeController::GetPeerChannel( 374 scoped_refptr<NodeChannel> NodeController::GetPeerChannel(
364 const ports::NodeName& name) { 375 const ports::NodeName& name) {
365 base::AutoLock lock(peers_lock_); 376 base::AutoLock lock(peers_lock_);
366 auto it = peers_.find(name); 377 auto it = peers_.find(name);
367 if (it == peers_.end()) 378 if (it == peers_.end())
368 return nullptr; 379 return nullptr;
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 } 760 }
750 761
751 if (GetPeerChannel(client_name)) { 762 if (GetPeerChannel(client_name)) {
752 DLOG(ERROR) << "Ignoring AddBrokerClient for known client."; 763 DLOG(ERROR) << "Ignoring AddBrokerClient for known client.";
753 DropPeer(from_node); 764 DropPeer(from_node);
754 return; 765 return;
755 } 766 }
756 767
757 PlatformChannelPair broker_channel; 768 PlatformChannelPair broker_channel;
758 scoped_refptr<NodeChannel> client = NodeChannel::Create( 769 scoped_refptr<NodeChannel> client = NodeChannel::Create(
759 this, broker_channel.PassServerHandle(), io_task_runner_); 770 this, broker_channel.PassServerHandle(), io_task_runner_,
771 base::Closure());
760 772
761 #if defined(OS_WIN) 773 #if defined(OS_WIN)
762 // The broker must have a working handle to the client process in order to 774 // The broker must have a working handle to the client process in order to
763 // properly copy other handles to and from the client. 775 // properly copy other handles to and from the client.
764 if (!scoped_process_handle.is_valid()) { 776 if (!scoped_process_handle.is_valid()) {
765 DLOG(ERROR) << "Broker rejecting client with invalid process handle."; 777 DLOG(ERROR) << "Broker rejecting client with invalid process handle.";
766 return; 778 return;
767 } 779 }
768 client->SetRemoteProcessHandle(scoped_process_handle.release().handle); 780 client->SetRemoteProcessHandle(scoped_process_handle.release().handle);
769 #else 781 #else
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 838
827 // It's now possible to add both the broker and the parent as peers. 839 // It's now possible to add both the broker and the parent as peers.
828 // Note that the broker and parent may be the same node. 840 // Note that the broker and parent may be the same node.
829 scoped_refptr<NodeChannel> broker; 841 scoped_refptr<NodeChannel> broker;
830 if (broker_name == parent_name) { 842 if (broker_name == parent_name) {
831 DCHECK(!broker_channel.is_valid()); 843 DCHECK(!broker_channel.is_valid());
832 broker = parent; 844 broker = parent;
833 } else { 845 } else {
834 DCHECK(broker_channel.is_valid()); 846 DCHECK(broker_channel.is_valid());
835 broker = NodeChannel::Create(this, std::move(broker_channel), 847 broker = NodeChannel::Create(this, std::move(broker_channel),
836 io_task_runner_); 848 io_task_runner_, base::Closure());
837 AddPeer(broker_name, broker, true /* start_channel */); 849 AddPeer(broker_name, broker, true /* start_channel */);
838 } 850 }
839 851
840 AddPeer(parent_name, parent, false /* start_channel */); 852 AddPeer(parent_name, parent, false /* start_channel */);
841 853
842 { 854 {
843 // Complete any port merge requests we have waiting for the parent. 855 // Complete any port merge requests we have waiting for the parent.
844 base::AutoLock lock(pending_port_merges_lock_); 856 base::AutoLock lock(pending_port_merges_lock_);
845 for (const auto& request : pending_port_merges_) 857 for (const auto& request : pending_port_merges_)
846 parent->RequestPortMerge(request.second.name(), request.first); 858 parent->RequestPortMerge(request.second.name(), request.first);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
888 if (!ports::Message::Parse(data, 900 if (!ports::Message::Parse(data,
889 num_data_bytes, 901 num_data_bytes,
890 &num_header_bytes, 902 &num_header_bytes,
891 &num_payload_bytes, 903 &num_payload_bytes,
892 &num_ports_bytes)) { 904 &num_ports_bytes)) {
893 DropPeer(from_node); 905 DropPeer(from_node);
894 return; 906 return;
895 } 907 }
896 908
897 CHECK(channel_message); 909 CHECK(channel_message);
898 ports::ScopedMessage message( 910 std::unique_ptr<PortsMessage> ports_message(
899 new PortsMessage(num_header_bytes, 911 new PortsMessage(num_header_bytes,
900 num_payload_bytes, 912 num_payload_bytes,
901 num_ports_bytes, 913 num_ports_bytes,
902 std::move(channel_message))); 914 std::move(channel_message)));
903 915 ports_message->set_source_node(from_node);
904 node_->AcceptMessage(std::move(message)); 916 node_->AcceptMessage(ports::ScopedMessage(ports_message.release()));
905 AcceptIncomingMessages(); 917 AcceptIncomingMessages();
906 } 918 }
907 919
908 void NodeController::OnRequestPortMerge( 920 void NodeController::OnRequestPortMerge(
909 const ports::NodeName& from_node, 921 const ports::NodeName& from_node,
910 const ports::PortName& connector_port_name, 922 const ports::PortName& connector_port_name,
911 const std::string& token) { 923 const std::string& token) {
912 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 924 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
913 925
914 DVLOG(2) << "Node " << name_ << " received RequestPortMerge for token " 926 DVLOG(2) << "Node " << name_ << " received RequestPortMerge for token "
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 if (!channel_handle.is_valid()) { 974 if (!channel_handle.is_valid()) {
963 node_->LostConnectionToNode(name); 975 node_->LostConnectionToNode(name);
964 976
965 DLOG(ERROR) << "Could not be introduced to peer " << name; 977 DLOG(ERROR) << "Could not be introduced to peer " << name;
966 base::AutoLock lock(peers_lock_); 978 base::AutoLock lock(peers_lock_);
967 pending_peer_messages_.erase(name); 979 pending_peer_messages_.erase(name);
968 return; 980 return;
969 } 981 }
970 982
971 scoped_refptr<NodeChannel> channel = 983 scoped_refptr<NodeChannel> channel =
972 NodeChannel::Create(this, std::move(channel_handle), io_task_runner_); 984 NodeChannel::Create(this, std::move(channel_handle), io_task_runner_,
985 base::Closure());
973 986
974 DVLOG(1) << "Adding new peer " << name << " via parent introduction."; 987 DVLOG(1) << "Adding new peer " << name << " via parent introduction.";
975 AddPeer(name, channel, true /* start_channel */); 988 AddPeer(name, channel, true /* start_channel */);
976 } 989 }
977 990
978 #if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS)) 991 #if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
979 void NodeController::OnRelayPortsMessage(const ports::NodeName& from_node, 992 void NodeController::OnRelayPortsMessage(const ports::NodeName& from_node,
980 base::ProcessHandle from_process, 993 base::ProcessHandle from_process,
981 const ports::NodeName& destination, 994 const ports::NodeName& destination,
982 Channel::MessagePtr message) { 995 Channel::MessagePtr message) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 #endif // defined(OS_WIN) 1042 #endif // defined(OS_WIN)
1030 1043
1031 if (destination == name_) { 1044 if (destination == name_) {
1032 // Great, we can deliver this message locally. 1045 // Great, we can deliver this message locally.
1033 OnPortsMessage(from_node, std::move(message)); 1046 OnPortsMessage(from_node, std::move(message));
1034 return; 1047 return;
1035 } 1048 }
1036 1049
1037 scoped_refptr<NodeChannel> peer = GetPeerChannel(destination); 1050 scoped_refptr<NodeChannel> peer = GetPeerChannel(destination);
1038 if (peer) 1051 if (peer)
1039 peer->PortsMessage(std::move(message)); 1052 peer->PortsMessageFromRelay(from_node, std::move(message));
1040 else 1053 else
1041 DLOG(ERROR) << "Dropping relay message for unknown node " << destination; 1054 DLOG(ERROR) << "Dropping relay message for unknown node " << destination;
1042 } 1055 }
1056
1057 void NodeController::OnPortsMessageFromRelay(const ports::NodeName& from_node,
1058 const ports::NodeName& source_node,
1059 Channel::MessagePtr message) {
1060 if (GetPeerChannel(from_node) != GetBrokerChannel()) {
1061 LOG(ERROR) << "Refusing relayed message from non-broker node.";
1062 DropPeer(from_node);
1063 return;
1064 }
1065
1066 OnPortsMessage(source_node, std::move(message));
1067 }
1043 #endif 1068 #endif
1044 1069
1045 void NodeController::OnChannelError(const ports::NodeName& from_node) { 1070 void NodeController::OnChannelError(const ports::NodeName& from_node) {
1046 if (io_task_runner_->RunsTasksOnCurrentThread()) { 1071 if (io_task_runner_->RunsTasksOnCurrentThread()) {
1047 DropPeer(from_node); 1072 DropPeer(from_node);
1048 // DropPeer may have caused local port closures, so be sure to process any 1073 // DropPeer may have caused local port closures, so be sure to process any
1049 // pending local messages. 1074 // pending local messages.
1050 AcceptIncomingMessages(); 1075 AcceptIncomingMessages();
1051 } else { 1076 } else {
1052 io_task_runner_->PostTask( 1077 io_task_runner_->PostTask(
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 shutdown_callback_flag_.Set(false); 1118 shutdown_callback_flag_.Set(false);
1094 } 1119 }
1095 1120
1096 DCHECK(!callback.is_null()); 1121 DCHECK(!callback.is_null());
1097 1122
1098 callback.Run(); 1123 callback.Run();
1099 } 1124 }
1100 1125
1101 } // namespace edk 1126 } // namespace edk
1102 } // namespace mojo 1127 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698