Home | History | Annotate | Download | only in ports
      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