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 3 // found in the LICENSE file. 4 5 #include "mojo/core/ports/event.h" 6 7 #include <stdint.h> 8 #include <string.h> 9 10 #include "base/numerics/safe_math.h" 11 #include "mojo/core/ports/user_message.h" 12 13 namespace mojo { 14 namespace core { 15 namespace ports { 16 17 namespace { 18 19 const size_t kPortsMessageAlignment = 8; 20 21 #pragma pack(push, 1) 22 23 struct SerializedHeader { 24 Event::Type type; 25 uint32_t padding; 26 PortName port_name; 27 }; 28 29 struct UserMessageEventData { 30 uint64_t sequence_num; 31 uint32_t num_ports; 32 uint32_t padding; 33 }; 34 35 struct ObserveProxyEventData { 36 NodeName proxy_node_name; 37 PortName proxy_port_name; 38 NodeName proxy_target_node_name; 39 PortName proxy_target_port_name; 40 }; 41 42 struct ObserveProxyAckEventData { 43 uint64_t last_sequence_num; 44 }; 45 46 struct ObserveClosureEventData { 47 uint64_t last_sequence_num; 48 }; 49 50 struct MergePortEventData { 51 PortName new_port_name; 52 Event::PortDescriptor new_port_descriptor; 53 }; 54 55 #pragma pack(pop) 56 57 static_assert(sizeof(Event::PortDescriptor) % kPortsMessageAlignment == 0, 58 "Invalid PortDescriptor size."); 59 60 static_assert(sizeof(SerializedHeader) % kPortsMessageAlignment == 0, 61 "Invalid SerializedHeader size."); 62 63 static_assert(sizeof(UserMessageEventData) % kPortsMessageAlignment == 0, 64 "Invalid UserEventData size."); 65 66 static_assert(sizeof(ObserveProxyEventData) % kPortsMessageAlignment == 0, 67 "Invalid ObserveProxyEventData size."); 68 69 static_assert(sizeof(ObserveProxyAckEventData) % kPortsMessageAlignment == 0, 70 "Invalid ObserveProxyAckEventData size."); 71 72 static_assert(sizeof(ObserveClosureEventData) % kPortsMessageAlignment == 0, 73 "Invalid ObserveClosureEventData size."); 74 75 static_assert(sizeof(MergePortEventData) % kPortsMessageAlignment == 0, 76 "Invalid MergePortEventData size."); 77 78 } // namespace 79 80 Event::PortDescriptor::PortDescriptor() { 81 memset(padding, 0, sizeof(padding)); 82 } 83 84 Event::~Event() = default; 85 86 // static 87 ScopedEvent Event::Deserialize(const void* buffer, size_t num_bytes) { 88 if (num_bytes < sizeof(SerializedHeader)) 89 return nullptr; 90 91 const auto* header = static_cast<const SerializedHeader*>(buffer); 92 const PortName& port_name = header->port_name; 93 const size_t data_size = num_bytes - sizeof(*header); 94 switch (header->type) { 95 case Type::kUserMessage: 96 return UserMessageEvent::Deserialize(port_name, header + 1, data_size); 97 case Type::kPortAccepted: 98 return PortAcceptedEvent::Deserialize(port_name, header + 1, data_size); 99 case Type::kObserveProxy: 100 return ObserveProxyEvent::Deserialize(port_name, header + 1, data_size); 101 case Type::kObserveProxyAck: 102 return ObserveProxyAckEvent::Deserialize(port_name, header + 1, 103 data_size); 104 case Type::kObserveClosure: 105 return ObserveClosureEvent::Deserialize(port_name, header + 1, data_size); 106 case Type::kMergePort: 107 return MergePortEvent::Deserialize(port_name, header + 1, data_size); 108 default: 109 DVLOG(2) << "Ingoring unknown port event type: " 110 << static_cast<uint32_t>(header->type); 111 return nullptr; 112 } 113 } 114 115 Event::Event(Type type, const PortName& port_name) 116 : type_(type), port_name_(port_name) {} 117 118 size_t Event::GetSerializedSize() const { 119 return sizeof(SerializedHeader) + GetSerializedDataSize(); 120 } 121 122 void Event::Serialize(void* buffer) const { 123 auto* header = static_cast<SerializedHeader*>(buffer); 124 header->type = type_; 125 header->padding = 0; 126 header->port_name = port_name_; 127 SerializeData(header + 1); 128 } 129 130 ScopedEvent Event::Clone() const { 131 return nullptr; 132 } 133 134 UserMessageEvent::~UserMessageEvent() = default; 135 136 UserMessageEvent::UserMessageEvent(size_t num_ports) 137 : Event(Type::kUserMessage, kInvalidPortName) { 138 ReservePorts(num_ports); 139 } 140 141 void UserMessageEvent::AttachMessage(std::unique_ptr<UserMessage> message) { 142 DCHECK(!message_); 143 message_ = std::move(message); 144 } 145 146 void UserMessageEvent::ReservePorts(size_t num_ports) { 147 port_descriptors_.resize(num_ports); 148 ports_.resize(num_ports); 149 } 150 151 bool UserMessageEvent::NotifyWillBeRoutedExternally() { 152 DCHECK(message_); 153 return message_->WillBeRoutedExternally(); 154 } 155 156 // static 157 ScopedEvent UserMessageEvent::Deserialize(const PortName& port_name, 158 const void* buffer, 159 size_t num_bytes) { 160 if (num_bytes < sizeof(UserMessageEventData)) 161 return nullptr; 162 163 const auto* data = static_cast<const UserMessageEventData*>(buffer); 164 base::CheckedNumeric<size_t> port_data_size = data->num_ports; 165 port_data_size *= sizeof(PortDescriptor) + sizeof(PortName); 166 if (!port_data_size.IsValid()) 167 return nullptr; 168 169 base::CheckedNumeric<size_t> total_size = port_data_size.ValueOrDie(); 170 total_size += sizeof(UserMessageEventData); 171 if (!total_size.IsValid() || num_bytes < total_size.ValueOrDie()) 172 return nullptr; 173 174 auto event = 175 base::WrapUnique(new UserMessageEvent(port_name, data->sequence_num)); 176 event->ReservePorts(data->num_ports); 177 const auto* in_descriptors = 178 reinterpret_cast<const PortDescriptor*>(data + 1); 179 std::copy(in_descriptors, in_descriptors + data->num_ports, 180 event->port_descriptors()); 181 182 const auto* in_names = 183 reinterpret_cast<const PortName*>(in_descriptors + data->num_ports); 184 std::copy(in_names, in_names + data->num_ports, event->ports()); 185 return std::move(event); 186 } 187 188 UserMessageEvent::UserMessageEvent(const PortName& port_name, 189 uint64_t sequence_num) 190 : Event(Type::kUserMessage, port_name), sequence_num_(sequence_num) {} 191 192 size_t UserMessageEvent::GetSizeIfSerialized() const { 193 if (!message_) 194 return 0; 195 return message_->GetSizeIfSerialized(); 196 } 197 198 size_t UserMessageEvent::GetSerializedDataSize() const { 199 DCHECK_EQ(ports_.size(), port_descriptors_.size()); 200 base::CheckedNumeric<size_t> size = sizeof(UserMessageEventData); 201 base::CheckedNumeric<size_t> ports_size = 202 sizeof(PortDescriptor) + sizeof(PortName); 203 ports_size *= ports_.size(); 204 return (size + ports_size.ValueOrDie()).ValueOrDie(); 205 } 206 207 void UserMessageEvent::SerializeData(void* buffer) const { 208 DCHECK_EQ(ports_.size(), port_descriptors_.size()); 209 auto* data = static_cast<UserMessageEventData*>(buffer); 210 data->sequence_num = sequence_num_; 211 DCHECK(base::IsValueInRangeForNumericType<uint32_t>(ports_.size())); 212 data->num_ports = static_cast<uint32_t>(ports_.size()); 213 data->padding = 0; 214 215 auto* ports_data = reinterpret_cast<PortDescriptor*>(data + 1); 216 std::copy(port_descriptors_.begin(), port_descriptors_.end(), ports_data); 217 218 auto* port_names_data = 219 reinterpret_cast<PortName*>(ports_data + ports_.size()); 220 std::copy(ports_.begin(), ports_.end(), port_names_data); 221 } 222 223 PortAcceptedEvent::PortAcceptedEvent(const PortName& port_name) 224 : Event(Type::kPortAccepted, port_name) {} 225 226 PortAcceptedEvent::~PortAcceptedEvent() = default; 227 228 // static 229 ScopedEvent PortAcceptedEvent::Deserialize(const PortName& port_name, 230 const void* buffer, 231 size_t num_bytes) { 232 return std::make_unique<PortAcceptedEvent>(port_name); 233 } 234 235 size_t PortAcceptedEvent::GetSerializedDataSize() const { 236 return 0; 237 } 238 239 void PortAcceptedEvent::SerializeData(void* buffer) const {} 240 241 ObserveProxyEvent::ObserveProxyEvent(const PortName& port_name, 242 const NodeName& proxy_node_name, 243 const PortName& proxy_port_name, 244 const NodeName& proxy_target_node_name, 245 const PortName& proxy_target_port_name) 246 : Event(Type::kObserveProxy, port_name), 247 proxy_node_name_(proxy_node_name), 248 proxy_port_name_(proxy_port_name), 249 proxy_target_node_name_(proxy_target_node_name), 250 proxy_target_port_name_(proxy_target_port_name) {} 251 252 ObserveProxyEvent::~ObserveProxyEvent() = default; 253 254 // static 255 ScopedEvent ObserveProxyEvent::Deserialize(const PortName& port_name, 256 const void* buffer, 257 size_t num_bytes) { 258 if (num_bytes < sizeof(ObserveProxyEventData)) 259 return nullptr; 260 261 const auto* data = static_cast<const ObserveProxyEventData*>(buffer); 262 return std::make_unique<ObserveProxyEvent>( 263 port_name, data->proxy_node_name, data->proxy_port_name, 264 data->proxy_target_node_name, data->proxy_target_port_name); 265 } 266 267 size_t ObserveProxyEvent::GetSerializedDataSize() const { 268 return sizeof(ObserveProxyEventData); 269 } 270 271 void ObserveProxyEvent::SerializeData(void* buffer) const { 272 auto* data = static_cast<ObserveProxyEventData*>(buffer); 273 data->proxy_node_name = proxy_node_name_; 274 data->proxy_port_name = proxy_port_name_; 275 data->proxy_target_node_name = proxy_target_node_name_; 276 data->proxy_target_port_name = proxy_target_port_name_; 277 } 278 279 ScopedEvent ObserveProxyEvent::Clone() const { 280 return std::make_unique<ObserveProxyEvent>( 281 port_name(), proxy_node_name_, proxy_port_name_, proxy_target_node_name_, 282 proxy_target_port_name_); 283 } 284 285 ObserveProxyAckEvent::ObserveProxyAckEvent(const PortName& port_name, 286 uint64_t last_sequence_num) 287 : Event(Type::kObserveProxyAck, port_name), 288 last_sequence_num_(last_sequence_num) {} 289 290 ObserveProxyAckEvent::~ObserveProxyAckEvent() = default; 291 292 // static 293 ScopedEvent ObserveProxyAckEvent::Deserialize(const PortName& port_name, 294 const void* buffer, 295 size_t num_bytes) { 296 if (num_bytes < sizeof(ObserveProxyAckEventData)) 297 return nullptr; 298 299 const auto* data = static_cast<const ObserveProxyAckEventData*>(buffer); 300 return std::make_unique<ObserveProxyAckEvent>(port_name, 301 data->last_sequence_num); 302 } 303 304 size_t ObserveProxyAckEvent::GetSerializedDataSize() const { 305 return sizeof(ObserveProxyAckEventData); 306 } 307 308 void ObserveProxyAckEvent::SerializeData(void* buffer) const { 309 auto* data = static_cast<ObserveProxyAckEventData*>(buffer); 310 data->last_sequence_num = last_sequence_num_; 311 } 312 313 ScopedEvent ObserveProxyAckEvent::Clone() const { 314 return std::make_unique<ObserveProxyAckEvent>(port_name(), 315 last_sequence_num_); 316 } 317 318 ObserveClosureEvent::ObserveClosureEvent(const PortName& port_name, 319 uint64_t last_sequence_num) 320 : Event(Type::kObserveClosure, port_name), 321 last_sequence_num_(last_sequence_num) {} 322 323 ObserveClosureEvent::~ObserveClosureEvent() = default; 324 325 // static 326 ScopedEvent ObserveClosureEvent::Deserialize(const PortName& port_name, 327 const void* buffer, 328 size_t num_bytes) { 329 if (num_bytes < sizeof(ObserveClosureEventData)) 330 return nullptr; 331 332 const auto* data = static_cast<const ObserveClosureEventData*>(buffer); 333 return std::make_unique<ObserveClosureEvent>(port_name, 334 data->last_sequence_num); 335 } 336 337 size_t ObserveClosureEvent::GetSerializedDataSize() const { 338 return sizeof(ObserveClosureEventData); 339 } 340 341 void ObserveClosureEvent::SerializeData(void* buffer) const { 342 auto* data = static_cast<ObserveClosureEventData*>(buffer); 343 data->last_sequence_num = last_sequence_num_; 344 } 345 346 ScopedEvent ObserveClosureEvent::Clone() const { 347 return std::make_unique<ObserveClosureEvent>(port_name(), last_sequence_num_); 348 } 349 350 MergePortEvent::MergePortEvent(const PortName& port_name, 351 const PortName& new_port_name, 352 const PortDescriptor& new_port_descriptor) 353 : Event(Type::kMergePort, port_name), 354 new_port_name_(new_port_name), 355 new_port_descriptor_(new_port_descriptor) {} 356 357 MergePortEvent::~MergePortEvent() = default; 358 359 // static 360 ScopedEvent MergePortEvent::Deserialize(const PortName& port_name, 361 const void* buffer, 362 size_t num_bytes) { 363 if (num_bytes < sizeof(MergePortEventData)) 364 return nullptr; 365 366 const auto* data = static_cast<const MergePortEventData*>(buffer); 367 return std::make_unique<MergePortEvent>(port_name, data->new_port_name, 368 data->new_port_descriptor); 369 } 370 371 size_t MergePortEvent::GetSerializedDataSize() const { 372 return sizeof(MergePortEventData); 373 } 374 375 void MergePortEvent::SerializeData(void* buffer) const { 376 auto* data = static_cast<MergePortEventData*>(buffer); 377 data->new_port_name = new_port_name_; 378 data->new_port_descriptor = new_port_descriptor_; 379 } 380 381 } // namespace ports 382 } // namespace core 383 } // namespace mojo 384