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