• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
PortDescriptor()80 Event::PortDescriptor::PortDescriptor() {
81   memset(padding, 0, sizeof(padding));
82 }
83 
84 Event::~Event() = default;
85 
86 // static
Deserialize(const void * buffer,size_t num_bytes)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 
Event(Type type,const PortName & port_name)115 Event::Event(Type type, const PortName& port_name)
116     : type_(type), port_name_(port_name) {}
117 
GetSerializedSize() const118 size_t Event::GetSerializedSize() const {
119   return sizeof(SerializedHeader) + GetSerializedDataSize();
120 }
121 
Serialize(void * buffer) const122 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 
Clone() const130 ScopedEvent Event::Clone() const {
131   return nullptr;
132 }
133 
134 UserMessageEvent::~UserMessageEvent() = default;
135 
UserMessageEvent(size_t num_ports)136 UserMessageEvent::UserMessageEvent(size_t num_ports)
137     : Event(Type::kUserMessage, kInvalidPortName) {
138   ReservePorts(num_ports);
139 }
140 
AttachMessage(std::unique_ptr<UserMessage> message)141 void UserMessageEvent::AttachMessage(std::unique_ptr<UserMessage> message) {
142   DCHECK(!message_);
143   message_ = std::move(message);
144 }
145 
ReservePorts(size_t num_ports)146 void UserMessageEvent::ReservePorts(size_t num_ports) {
147   port_descriptors_.resize(num_ports);
148   ports_.resize(num_ports);
149 }
150 
NotifyWillBeRoutedExternally()151 bool UserMessageEvent::NotifyWillBeRoutedExternally() {
152   DCHECK(message_);
153   return message_->WillBeRoutedExternally();
154 }
155 
156 // static
Deserialize(const PortName & port_name,const void * buffer,size_t num_bytes)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 
UserMessageEvent(const PortName & port_name,uint64_t sequence_num)188 UserMessageEvent::UserMessageEvent(const PortName& port_name,
189                                    uint64_t sequence_num)
190     : Event(Type::kUserMessage, port_name), sequence_num_(sequence_num) {}
191 
GetSizeIfSerialized() const192 size_t UserMessageEvent::GetSizeIfSerialized() const {
193   if (!message_)
194     return 0;
195   return message_->GetSizeIfSerialized();
196 }
197 
GetSerializedDataSize() const198 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 
SerializeData(void * buffer) const207 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 
PortAcceptedEvent(const PortName & port_name)223 PortAcceptedEvent::PortAcceptedEvent(const PortName& port_name)
224     : Event(Type::kPortAccepted, port_name) {}
225 
226 PortAcceptedEvent::~PortAcceptedEvent() = default;
227 
228 // static
Deserialize(const PortName & port_name,const void * buffer,size_t num_bytes)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 
GetSerializedDataSize() const235 size_t PortAcceptedEvent::GetSerializedDataSize() const {
236   return 0;
237 }
238 
SerializeData(void * buffer) const239 void PortAcceptedEvent::SerializeData(void* buffer) const {}
240 
ObserveProxyEvent(const PortName & port_name,const NodeName & proxy_node_name,const PortName & proxy_port_name,const NodeName & proxy_target_node_name,const PortName & proxy_target_port_name)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
Deserialize(const PortName & port_name,const void * buffer,size_t num_bytes)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 
GetSerializedDataSize() const267 size_t ObserveProxyEvent::GetSerializedDataSize() const {
268   return sizeof(ObserveProxyEventData);
269 }
270 
SerializeData(void * buffer) const271 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 
Clone() const279 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 
ObserveProxyAckEvent(const PortName & port_name,uint64_t last_sequence_num)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
Deserialize(const PortName & port_name,const void * buffer,size_t num_bytes)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 
GetSerializedDataSize() const304 size_t ObserveProxyAckEvent::GetSerializedDataSize() const {
305   return sizeof(ObserveProxyAckEventData);
306 }
307 
SerializeData(void * buffer) const308 void ObserveProxyAckEvent::SerializeData(void* buffer) const {
309   auto* data = static_cast<ObserveProxyAckEventData*>(buffer);
310   data->last_sequence_num = last_sequence_num_;
311 }
312 
Clone() const313 ScopedEvent ObserveProxyAckEvent::Clone() const {
314   return std::make_unique<ObserveProxyAckEvent>(port_name(),
315                                                 last_sequence_num_);
316 }
317 
ObserveClosureEvent(const PortName & port_name,uint64_t last_sequence_num)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
Deserialize(const PortName & port_name,const void * buffer,size_t num_bytes)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 
GetSerializedDataSize() const337 size_t ObserveClosureEvent::GetSerializedDataSize() const {
338   return sizeof(ObserveClosureEventData);
339 }
340 
SerializeData(void * buffer) const341 void ObserveClosureEvent::SerializeData(void* buffer) const {
342   auto* data = static_cast<ObserveClosureEventData*>(buffer);
343   data->last_sequence_num = last_sequence_num_;
344 }
345 
Clone() const346 ScopedEvent ObserveClosureEvent::Clone() const {
347   return std::make_unique<ObserveClosureEvent>(port_name(), last_sequence_num_);
348 }
349 
MergePortEvent(const PortName & port_name,const PortName & new_port_name,const PortDescriptor & new_port_descriptor)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
Deserialize(const PortName & port_name,const void * buffer,size_t num_bytes)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 
GetSerializedDataSize() const371 size_t MergePortEvent::GetSerializedDataSize() const {
372   return sizeof(MergePortEventData);
373 }
374 
SerializeData(void * buffer) const375 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